Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Changelog

All notable repository and research-artifact changes are recorded here.

## 0.2.0 - 2026-07-24

### Added

- Operator-independent butterfly and FFT architecture-space specifications,
validation, exploration, and generated-code selection tools.
- Optional cuFFTDx, TurboFFT, and VkFFT integration boundaries.
- A controlled 37-case V100 comprehensive suite with correctness preflight,
randomized trials, stability classification, raw records, and detailed
length/batch tables.
- FFT architecture sweeps, processing-unit comparisons, and resident-kernel
Nsight Compute evidence.

### Changed

- Extended FFT, FWHT, NTT, and XOR-zeta configuration and capability coverage.
- Updated the architecture, hardware-mapping, processing-unit, experiment, and
reproducibility documentation to distinguish fresh comprehensive results
from focused historical protocols.
- Defined the next phase as an orthogonal length/batch scan, refreshed external
baselines, and targeted profiling of long FP32 and FP64 FFT gaps.

### Current Evidence Boundary

- V100 remains the only comprehensively measured GPU.
- Measured FP32 FFT reaches cuFFT parity at selected lengths, while FP32
`logN=20` and FP64 `logN=16` remain open performance gaps.
- Dao-AILab FHT and GPU-NTT results were not rerun under the comprehensive
protocol and remain contextual evidence.

## 0.1.0 - 2026-07-23

- Initial public cuButterfly research artifact with the common space-time
mapping model, NTT/FFT/FWHT/XOR-zeta kernels, V100 measurements, and
reproducibility documentation.
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ authors:
- name: "TruNcat3"
repository-code: "https://github.com/TruNcat3/cuButterfly"
url: "https://github.com/TruNcat3/cuButterfly"
version: 0.1.0
date-released: 2026-07-23
version: 0.2.0
date-released: 2026-07-24
keywords:
- butterfly computation
- GPU
Expand Down
111 changes: 110 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 70 CACHE STRING "CUDA architectures to compile for")
endif()

project(cuButterfly VERSION 0.1.0 LANGUAGES CXX CUDA)
project(cuButterfly VERSION 0.2.0 LANGUAGES CXX CUDA)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand All @@ -16,11 +16,34 @@ set(CMAKE_CUDA_EXTENSIONS OFF)
find_package(CUDAToolkit REQUIRED)
find_package(Python3 REQUIRED COMPONENTS Interpreter)

option(CUBUTTERFLY_ENABLE_VKFFT "Build the optional VkFFT comparison benchmark" OFF)
set(CUBUTTERFLY_VKFFT_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/external/VkFFT" CACHE PATH
"Path to a VkFFT source checkout")
option(CUBUTTERFLY_ENABLE_CUFFTDX "Enable the optional cuFFTDx block FFT processing unit" OFF)
set(CUBUTTERFLY_MATHDX_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/external/mathdx/nvidia/mathdx" CACHE PATH
"Path to an NVIDIA MathDx package")
option(CUBUTTERFLY_ENABLE_TURBOFFT "Enable the optional TurboFFT generated processing unit" OFF)
set(CUBUTTERFLY_TURBOFFT_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/external/TurboFFT/TurboFFT" CACHE PATH
"Path to a TurboFFT source checkout")

set(CUNTT_DESIGN_SPEC "${CMAKE_CURRENT_SOURCE_DIR}/config/v100_design_points.json" CACHE FILEPATH
"JSON file selecting generated cuButterfly design points")
set(CUBUTTERFLY_FFT_SPACE_SPEC "${CMAKE_CURRENT_SOURCE_DIR}/config/fft_architecture_space.json" CACHE FILEPATH
"Canonical two-dimensional FFT architecture-space specification")
set(CUBUTTERFLY_ARCHITECTURE_SPACE_SPEC "${CMAKE_CURRENT_SOURCE_DIR}/config/butterfly_architecture_space.json" CACHE FILEPATH
"Canonical operator-independent butterfly architecture-space specification")
set(CUBUTTERFLY_FFT_CODEGEN_SPEC "${CMAKE_CURRENT_SOURCE_DIR}/config/v100_fft_codegen.json" CACHE FILEPATH
"Selected FFT template points compiled into this build")
set(CUNTT_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CUNTT_DESIGN_SPEC}"
"${CUBUTTERFLY_FFT_SPACE_SPEC}"
"${CUBUTTERFLY_ARCHITECTURE_SPACE_SPEC}"
"${CUBUTTERFLY_FFT_CODEGEN_SPEC}"
"${CMAKE_CURRENT_SOURCE_DIR}/config/v100_comprehensive_suite.json"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/fft_design_space.py"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/butterfly_design_space.py"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_fft_codegen.py"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_design_points.py")
file(MAKE_DIRECTORY "${CUNTT_GENERATED_DIR}")
execute_process(
Expand All @@ -31,6 +54,37 @@ execute_process(
if(NOT CUNTT_GENERATOR_RESULT EQUAL 0)
message(FATAL_ERROR "cuButterfly design-point generation failed: ${CUNTT_GENERATOR_ERROR}")
endif()
execute_process(
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/butterfly_design_space.py"
--spec "${CUBUTTERFLY_ARCHITECTURE_SPACE_SPEC}"
--fft-spec "${CUBUTTERFLY_FFT_SPACE_SPEC}" --validate-only
RESULT_VARIABLE CUBUTTERFLY_ARCHITECTURE_SPACE_RESULT
ERROR_VARIABLE CUBUTTERFLY_ARCHITECTURE_SPACE_ERROR)
if(NOT CUBUTTERFLY_ARCHITECTURE_SPACE_RESULT EQUAL 0)
message(FATAL_ERROR "cuButterfly architecture-space validation failed: ${CUBUTTERFLY_ARCHITECTURE_SPACE_ERROR}")
endif()
configure_file("${CUBUTTERFLY_ARCHITECTURE_SPACE_SPEC}"
"${CUNTT_GENERATED_DIR}/butterfly_architecture_space.json" COPYONLY)
execute_process(
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/fft_design_space.py"
--spec "${CUBUTTERFLY_FFT_SPACE_SPEC}" --validate-only
RESULT_VARIABLE CUBUTTERFLY_FFT_SPACE_RESULT
ERROR_VARIABLE CUBUTTERFLY_FFT_SPACE_ERROR)
if(NOT CUBUTTERFLY_FFT_SPACE_RESULT EQUAL 0)
message(FATAL_ERROR "cuButterfly FFT architecture-space validation failed: ${CUBUTTERFLY_FFT_SPACE_ERROR}")
endif()
configure_file("${CUBUTTERFLY_FFT_SPACE_SPEC}"
"${CUNTT_GENERATED_DIR}/fft_architecture_space.json" COPYONLY)
execute_process(
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_fft_codegen.py"
--space-spec "${CUBUTTERFLY_FFT_SPACE_SPEC}"
--selection "${CUBUTTERFLY_FFT_CODEGEN_SPEC}"
--output-dir "${CUNTT_GENERATED_DIR}"
RESULT_VARIABLE CUBUTTERFLY_FFT_CODEGEN_RESULT
ERROR_VARIABLE CUBUTTERFLY_FFT_CODEGEN_ERROR)
if(NOT CUBUTTERFLY_FFT_CODEGEN_RESULT EQUAL 0)
message(FATAL_ERROR "cuButterfly FFT code generation failed: ${CUBUTTERFLY_FFT_CODEGEN_ERROR}")
endif()
include("${CUNTT_GENERATED_DIR}/design_points.cmake")

add_library(cuntt STATIC
Expand All @@ -40,6 +94,34 @@ add_library(cuntt STATIC
src/reference.cpp)
target_sources(cuntt PRIVATE ${CUNTT_GENERATED_SOURCES})

if(CUBUTTERFLY_ENABLE_CUFFTDX)
if(NOT EXISTS "${CUBUTTERFLY_MATHDX_ROOT}/include/cufftdx.hpp")
message(FATAL_ERROR
"cuFFTDx headers were not found under ${CUBUTTERFLY_MATHDX_ROOT}. "
"Run scripts/install_cufftdx.sh or set CUBUTTERFLY_MATHDX_ROOT.")
endif()
target_sources(cuntt PRIVATE src/cufftdx_fft.cu)
target_include_directories(cuntt SYSTEM PRIVATE "${CUBUTTERFLY_MATHDX_ROOT}/include")
target_compile_definitions(cuntt PRIVATE CUBUTTERFLY_HAS_CUFFTDX=1)
else()
target_sources(cuntt PRIVATE src/cufftdx_fft_stub.cpp)
endif()

if(CUBUTTERFLY_ENABLE_TURBOFFT)
foreach(LOG_N RANGE 7 10)
if(NOT EXISTS "${CUBUTTERFLY_TURBOFFT_ROOT}/include/code_gen/generated/float2/fft_radix_2_logN_${LOG_N}_upload_0.cuh")
message(FATAL_ERROR
"TurboFFT logN=${LOG_N} generated header was not found under ${CUBUTTERFLY_TURBOFFT_ROOT}. "
"Run scripts/install_turbofft.sh or set CUBUTTERFLY_TURBOFFT_ROOT.")
endif()
endforeach()
target_sources(cuntt PRIVATE src/turbofft_fft.cu)
target_include_directories(cuntt SYSTEM PRIVATE "${CUBUTTERFLY_TURBOFFT_ROOT}/include")
target_compile_definitions(cuntt PRIVATE CUBUTTERFLY_HAS_TURBOFFT=1)
else()
target_sources(cuntt PRIVATE src/turbofft_fft_stub.cpp)
endif()

target_include_directories(cuntt
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
Expand Down Expand Up @@ -73,13 +155,40 @@ target_compile_options(cuntt_tests PRIVATE -Wall -Wextra -Wpedantic)
add_executable(cubutterfly_tests tests/test_butterfly.cpp)
target_link_libraries(cubutterfly_tests PRIVATE cuntt)
target_compile_options(cubutterfly_tests PRIVATE -Wall -Wextra -Wpedantic)
if(CUBUTTERFLY_ENABLE_CUFFTDX)
target_compile_definitions(cubutterfly_tests PRIVATE CUBUTTERFLY_TEST_CUFFTDX=1)
endif()
if(CUBUTTERFLY_ENABLE_TURBOFFT)
target_compile_definitions(cubutterfly_tests PRIVATE CUBUTTERFLY_TEST_TURBOFFT=1)
endif()

add_executable(cuntt_hardware_microbench apps/hardware_microbench.cu)
target_link_libraries(cuntt_hardware_microbench PRIVATE CUDA::cudart)
target_compile_options(cuntt_hardware_microbench PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-Wall,-Wextra>)

if(CUBUTTERFLY_ENABLE_VKFFT)
set(CUBUTTERFLY_VKFFT_INCLUDE "${CUBUTTERFLY_VKFFT_ROOT}/vkFFT")
if(NOT EXISTS "${CUBUTTERFLY_VKFFT_INCLUDE}/vkFFT.h")
message(FATAL_ERROR
"VkFFT headers were not found under ${CUBUTTERFLY_VKFFT_ROOT}. "
"Run scripts/install_vkfft.sh or set CUBUTTERFLY_VKFFT_ROOT.")
endif()

add_executable(vkfft_bench apps/vkfft_bench.cu)
target_include_directories(vkfft_bench SYSTEM PRIVATE "${CUBUTTERFLY_VKFFT_INCLUDE}")
target_compile_definitions(vkfft_bench PRIVATE VKFFT_BACKEND=1)
target_link_libraries(vkfft_bench PRIVATE CUDA::cudart CUDA::cuda_driver CUDA::nvrtc CUDA::cufft)
target_compile_options(vkfft_bench PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-Wall,-Wextra>)
endif()

include(CTest)
if(BUILD_TESTING)
add_test(NAME cuntt_correctness COMMAND cuntt_tests)
add_test(NAME cubutterfly_correctness COMMAND cubutterfly_tests)
add_test(NAME fft_design_space
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_fft_design_space.py")
add_test(NAME butterfly_design_space
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_butterfly_design_space.py")
add_test(NAME comprehensive_suite
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_comprehensive_suite.py")
endif()
39 changes: 28 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![Release](https://img.shields.io/github/v/release/TruNcat3/cuButterfly)](https://github.com/TruNcat3/cuButterfly/releases/latest)
[![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)

cuButterfly is a CUDA research prototype that generalizes the
cuButterfly is a CUDA research prototype that generalizes the
space-time parallel paradigm from NTT to regular layered transforms. It keeps
the architecture-level mapping independent of the local arithmetic core, so
FFT, NTT, FWHT, and XOR-zeta can share one mapping vocabulary while selecting
Expand All @@ -23,12 +23,13 @@ A regular butterfly graph exposes two logical dimensions: stage and independent
data unit. cuButterfly unfolds both dimensions in space and time:

```text
M = (Us, Ts, Ud, Td, Hs, Rs, Rd, L, F, Q)
M = (Us, Ts, Ud, Td, Ub, Tb, Hs, Rs, Rd, Rb, L, F, Q)

Us, Ts stage-space and stage-time unfolding
Ud, Td data-space and data-time unfolding
Ub, Tb batch-space and batch-time unfolding
Hs physical service for spatial stage edges
Rs, Rd residence across stage-time and data-time folds
Rs/Rd/Rb residence across stage, data, and batch folds
L input, intermediate, and output layout policy
F, Q kernel family and hardware realization parameters
```
Expand All @@ -42,7 +43,8 @@ The processing unit may change without changing the paradigm. Conversely, a
good codelet does not determine its block shape, residency, permutation policy,
or cross-kernel schedule. These are searched against the current GPU.

Read [Design Overview](docs/design_overview.md) for the model and
Read [Complete Butterfly Design Space](docs/butterfly_design_space.md) for the
canonical model, [Design Overview](docs/design_overview.md) for the concise view, and
[Hardware Mapping Methodology](docs/hardware_mapping_methodology.md) for the
resource equations and counter-driven selection procedure.

Expand All @@ -67,28 +69,40 @@ All values below are resident kernel times measured on one Tesla
V100-SXM2-16GB with CUDA 11.8. Each comparison matches the documented shape,
precision, direction, layout, and warmup protocol. Ratios above `1.0x` mean
cuButterfly has higher throughput. They must not be generalized to other GPUs.
For the latest controlled cross-workload protocol and its complete evidence
boundary, use the [V100 Comprehensive Results](docs/comprehensive_v100_results.md);
the focused rows below retain their original experiment protocols.

### Same-Machine Library Comparisons

| Workload | cuButterfly | Reference | Throughput ratio | Evidence |
|:--|--:|--:|--:|:--|
| FP32 DFT8, `2^22` total points | 0.093420 ms | cuFFT 0.086323 ms | 0.924x | generated CTA DFT8 |
| FP32 FFT, `logN=12`, `2^22` total points | 0.088934 ms | cuFFT 0.089989 ms | 1.012x | contiguous cuFFTDx direct unit |
| FP32 FFT, `logN=14`, `2^22` total points | 0.131543 ms | cuFFT 0.135383 ms | 1.029x | contiguous cuFFTDx direct unit |
| FP32 FFT, `logN=18`, `2^22` total points | 0.212019 ms | cuFFT 0.226877 ms | 1.070x | `9+9`, independently tuned 256/256-thread dimensions |
| FP32 FFT, `logN=20`, `2^22` total points | 0.235971 ms | cuFFT 0.209521 ms | 0.888x | cuFFTDx two-pass composition |
| FP32 FWHT, `logN=8` | 0.043131 ms | Dao FHT 0.043172 ms | 1.001x | integrated register unit |
| FP32 FWHT, `logN=15` | 0.069243 ms | Dao FHT 0.063949 ms | 0.924x | register-pressure boundary |
| 60-bit NTT, `logN=16`, natural order | 0.274104 ms | GPU-NTT 0.291133 ms | 1.062x | fused Hybrid2D |
| 60-bit NTT, `logN=20`, native bit-reversed | 0.341320 ms | GPU-NTT 0.396186 ms | 1.161x | compact-stage mapping |

The FFT result is close only for the small generated codelet workload. For
large resident FFTs, the current online-reorder path reaches 33.0%-47.4% of
cuFFT throughput at `logN=12..20`. This remaining gap is an explicit research
target, not hidden by the headline table.
The generated local core and tiled two-pass composition raise long FFT
throughput from 32.7%-47.4% to 41.9%-88.8% of cuFFT. Whole-transform cuFFTDx
units at `logN=11..14` isolate the local-unit ceiling: the contiguous paths at
`logN=11,12,14` reach 1.006x, 1.012x, and 1.029x cuFFT throughput, while
`logN=13` reaches 0.965x. Independently tuning the two long-transform dimensions
also raises `logN=18` from 0.881x in the fixed-512 mapping experiment to 1.070x.
Processing-unit granularity and each dimension's CTA shape are therefore explicit
hardware-mapping axes rather than fixed properties of the paradigm.

### Online Reorder at `logN=20`

| Operator | Hierarchical | Online reorder | Speedup |
|:--|--:|--:|--:|
| FWHT FP32 | 0.488264 ms | 0.319795 ms | 1.527x |
| FFT FP32 | 1.199616 ms | 0.640174 ms | 1.874x |
| FFT FP32, cuFFTDx core | 1.199616 ms | 0.235971 ms | 5.084x |
| XOR-zeta uint32 | 0.487004 ms | 0.319519 ms | 1.524x |

The permutation is fused into an already-required boundary store. It is not
Expand Down Expand Up @@ -160,13 +174,16 @@ units and future implementation paths are catalogued in
[Candidate Implementations](docs/implementation_candidates.md).
Development priorities are tracked in [`ROADMAP.md`](ROADMAP.md), and evidence
requirements for contributions are in [`CONTRIBUTING.md`](CONTRIBUTING.md).
Versioned changes are recorded in [`CHANGELOG.md`](CHANGELOG.md).

## Evidence Boundary

- V100 is the only fully measured GPU generation in this revision. A100, H100,
and RTX 4090 entries are placeholders, not performance claims.
- FFT does not yet match cuFFT for long transforms; Tensor Core DFT8 helps the
local unit but does not remove layout, synchronization, and composition costs.
- FP32 FFT is at cuFFT parity for the measured `logN=8,14,18` shapes, but the
measured `logN=20` path and FP64 `logN=16` path remain behind. Tensor Core
DFT8 helps the local unit but does not remove layout, synchronization, and
composition costs.
- FWHT closely tracks Dao FHT after importing its validated local register
hierarchy. This demonstrates processing-unit reuse, not independent invention
of that core.
Expand All @@ -187,7 +204,7 @@ software release as:
author = {TruNcat3},
title = {cuButterfly: Hardware-Mapped Space-Time Parallelism for Butterfly Computations on GPUs},
year = {2026},
version = {0.1.0},
version = {0.2.0},
url = {https://github.com/TruNcat3/cuButterfly}
}
```
Expand Down
16 changes: 11 additions & 5 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ research claim. Ordering may change after profiling or access to new hardware.

## Near Term

- Profile the generated CTA DFT8 mappings at representative local lengths and
attribute the `N>=128` crossover to barriers, bank conflicts, occupancy, and
coefficient traffic.
- Compose an established long-FFT local core with cuButterfly online-reorder
scheduling instead of extending scalar butterflies indefinitely.
- Run an orthogonal `(logN, batch)` sweep instead of coupling all comparisons
through constant total points; identify launch-limited, saturation, and
throughput regions for every operator.
- Refresh Dao-AILab FHT and GPU-NTT under the comprehensive-suite clock,
correctness, modulus, output-order, and trial protocol.
- Profile the remaining FP32 `logN=20` and FP64 `logN=16` FFT gaps against
cuFFT, separating local-core, permutation, coefficient, and launch costs.
- Convert the measured architecture space into a calibrated selector and
evaluate top-k prediction accuracy before exhaustive timing.
- Add a device-pointer and CUDA-stream execution API without weakening the
current typed semantic contract.
- Reduce template warning volume and record compiled resource envelopes as
Expand Down Expand Up @@ -40,6 +44,8 @@ portable across GPU generations.

## Paper Artifact

- Preserve the V100 comprehensive suite as the single-GPU baseline and keep
focused historical protocols separate from its cross-workload tables.
- Freeze a versioned multi-GPU measurement matrix.
- Publish scripts and container/toolchain metadata for every main table.
- Separate architecture ablations, core-only comparisons, resident transforms,
Expand Down
Loading
Loading