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
65 changes: 64 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,70 @@

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

## Unreleased
## 0.4.0 - 2026-08-05

### Added

- Canonical uint32 subset-zeta/Mobius and superset-zeta/Mobius operators across
temporal, hierarchical, online-reorder, warp-hybrid, and stage-pipeline
mappings, including radix-2/4/8 and CPU references.
- A parameterized FP32/FP64 structured-2x2 operator with broadcast or per-stage
matrices, validated local inversion, device-resident coefficients, radix
fusion, CLI/CSV representation, and CPU/GPU regression targets.
- A 762-sample V100 structured-2x2 length/precision mapping scan, matched FWHT
control, forward/inverse best-point verification, and focused NCU A/B script.
- Structured/FWHT counter attribution and an alternating-order `logN=20`
confirmation that rejects a frequency-sensitive sequential-scan advantage.
- A generated FP32 Structured 2x2 warp-register core for `logN=3..15`, with
broadcast/per-stage matrices, inverse and strided/in-place coverage, and a
V100 register-versus-shared/FWHT performance study.
- Refreshed Structured/FWHT NCU attribution showing the generated `logN=12`
matrix core cuts DRAM traffic by 3.02x and base-clock time by 2.64x; its
remaining same-transport gap is dense arithmetic and register pressure.
- Separate generated Structured coefficient policies for one-matrix broadcast
register reuse and arbitrary per-stage tables, with equivalent-semantics V100
A/B timing and compiled register/spill evidence.
- NCU coefficient-policy attribution confirming broadcast reuse preserves the
FP32 work while reducing registers, long-scoreboard stalls, and base-clock
time relative to the per-stage table path.
- Portable per-candidate residency/cliff feature extraction, hardware/resource
profiles, and resource-aware sweep annotations for register, shared, thread,
warp, occupancy, grid-wave, and temporal-state search signals.
- An operator catalog defining transform semantics, the legacy `xor-zeta`
compatibility behavior, mapping coverage, and the next operator candidates.
- Allocation-free asynchronous device-pointer execution for common butterfly
and NTT plans, with caller-selected CUDA streams and queryable workspaces.
- Installable CMake package metadata exposing the
`cuButterfly::cuButterfly` target and a standalone device API example.
- Device API lifecycle, memory, placement, type, and concurrency documentation.
- Product-oriented programming guide, public C++ API reference, error model,
capability/compatibility matrix, and task-oriented example index.
- Build-checked basic FFT and asynchronous NTT examples alongside the common
butterfly device-pointer example.
- A unified V100 runtime selector for FFT, NTT, FWHT, and XOR-zeta plans, with
resolved configurations, prediction confidence, and auditable reasons.
- Build-time generation of runtime latency anchors from the archived scaling
summary, plus selector generation and mapping-crossover regression tests.

### Changed

- Host-vector execution now submits through the same stream-aware kernel path
as the application API and lazily creates its private staging buffers.

### Current Evidence Boundary

- The generated register core makes resident FP32 Structured 2x2 transforms
1.208x-3.108x faster than the best measured shared-core controls at
`logN=8/10/12/15`; the coefficient policy adds up to another 1.107x.
- On V100, the Structured register path enters a shared-memory resource cliff
at `logN=13`, a register-limited region at `logN=14`, and the one-CTA/SM
boundary at `logN=15`. These are measured single-GPU boundaries, not fixed
architectural constants.
- The public device API, package target, examples, and V100 runtime selector
are functional and regression tested. Unsupported contracts remain explicit.
- The next research phase conditions mapping preference and resource cliffs on
numeric representation and workload shape before attempting cross-GPU
transfer. Cross-GPU profiles remain placeholders only.

## 0.3.0 - 2026-08-02

Expand Down
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.3.0
date-released: 2026-08-02
version: 0.4.0
date-released: 2026-08-05
keywords:
- butterfly computation
- GPU
Expand Down
83 changes: 81 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 70 CACHE STRING "CUDA architectures to compile for")
endif()

project(cuButterfly VERSION 0.3.0 LANGUAGES CXX CUDA)
project(cuButterfly VERSION 0.4.0 LANGUAGES CXX CUDA)

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -40,6 +43,8 @@ set(CUBUTTERFLY_FFT_PIPELINE_CANDIDATES "${CMAKE_CURRENT_SOURCE_DIR}/config/v100
"Generated FFT pipeline candidate manifest")
set(CUBUTTERFLY_FFT_DISPATCH_SPEC "${CMAKE_CURRENT_SOURCE_DIR}/config/v100_fft_dispatch.json" CACHE FILEPATH
"Measured FFT mapping dispatch table")
set(CUBUTTERFLY_RUNTIME_SELECTOR_SUMMARY "${CMAKE_CURRENT_SOURCE_DIR}/results/v100_scaling_full_summary.csv" CACHE FILEPATH
"Measured scaling summary used to generate runtime selector latency anchors")
set(CUNTT_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CUNTT_DESIGN_SPEC}"
Expand All @@ -49,6 +54,7 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CUBUTTERFLY_FFT_PIPELINE_SPEC}"
"${CUBUTTERFLY_FFT_PIPELINE_CANDIDATES}"
"${CUBUTTERFLY_FFT_DISPATCH_SPEC}"
"${CUBUTTERFLY_RUNTIME_SELECTOR_SUMMARY}"
"${CMAKE_CURRENT_SOURCE_DIR}/config/v100_comprehensive_suite.json"
"${CMAKE_CURRENT_SOURCE_DIR}/config/v100_scaling_space.json"
"${CMAKE_CURRENT_SOURCE_DIR}/config/v100_scaling_suite.json"
Expand All @@ -57,6 +63,7 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_fft_codegen.py"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_fft_pipeline.py"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_fft_dispatch.py"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_runtime_selector.py"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_scaling_suite.py"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_design_points.py")
file(MAKE_DIRECTORY "${CUNTT_GENERATED_DIR}")
Expand Down Expand Up @@ -128,11 +135,21 @@ execute_process(
if(NOT CUBUTTERFLY_FFT_DISPATCH_RESULT EQUAL 0)
message(FATAL_ERROR "cuButterfly FFT dispatch generation failed: ${CUBUTTERFLY_FFT_DISPATCH_ERROR}")
endif()
execute_process(
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_runtime_selector.py"
--summary "${CUBUTTERFLY_RUNTIME_SELECTOR_SUMMARY}"
--header "${CUNTT_GENERATED_DIR}/generated_runtime_selector.hpp"
RESULT_VARIABLE CUBUTTERFLY_RUNTIME_SELECTOR_RESULT
ERROR_VARIABLE CUBUTTERFLY_RUNTIME_SELECTOR_ERROR)
if(NOT CUBUTTERFLY_RUNTIME_SELECTOR_RESULT EQUAL 0)
message(FATAL_ERROR "cuButterfly runtime selector generation failed: ${CUBUTTERFLY_RUNTIME_SELECTOR_ERROR}")
endif()
include("${CUNTT_GENERATED_DIR}/design_points.cmake")

add_library(cuntt STATIC
src/butterfly.cu
src/butterfly_reference.cpp
src/mapping_selector.cpp
src/ntt.cu
src/reference.cpp)
target_sources(cuntt PRIVATE ${CUNTT_GENERATED_SOURCES})
Expand Down Expand Up @@ -167,7 +184,8 @@ endif()

target_include_directories(cuntt
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${CUNTT_GENERATED_DIR})
Expand All @@ -180,9 +198,25 @@ target_compile_options(cuntt
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-Wall,-Wextra>)

set_target_properties(cuntt PROPERTIES
EXPORT_NAME cuButterfly
CUDA_SEPARABLE_COMPILATION OFF
POSITION_INDEPENDENT_CODE ON)

option(CUBUTTERFLY_BUILD_EXAMPLES "Build cuButterfly API examples" ON)
if(CUBUTTERFLY_BUILD_EXAMPLES)
add_executable(cubutterfly_device_api_example examples/device_api.cpp)
target_link_libraries(cubutterfly_device_api_example PRIVATE cuntt)
target_compile_options(cubutterfly_device_api_example PRIVATE -Wall -Wextra -Wpedantic)

add_executable(cubutterfly_basic_fft_example examples/basic_fft.cpp)
target_link_libraries(cubutterfly_basic_fft_example PRIVATE cuntt)
target_compile_options(cubutterfly_basic_fft_example PRIVATE -Wall -Wextra -Wpedantic)

add_executable(cuntt_device_api_example examples/ntt_device_api.cpp)
target_link_libraries(cuntt_device_api_example PRIVATE cuntt)
target_compile_options(cuntt_device_api_example PRIVATE -Wall -Wextra -Wpedantic)
endif()

add_executable(cuntt_bench apps/cuntt_bench.cpp)
target_link_libraries(cuntt_bench PRIVATE cuntt)
target_compile_options(cuntt_bench PRIVATE -Wall -Wextra -Wpedantic)
Expand All @@ -198,6 +232,10 @@ 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)

add_executable(cubutterfly_structured_reference_tests tests/test_structured_reference.cpp)
target_link_libraries(cubutterfly_structured_reference_tests PRIVATE cuntt)
target_compile_options(cubutterfly_structured_reference_tests PRIVATE -Wall -Wextra -Wpedantic)
if(CUBUTTERFLY_ENABLE_CUFFTDX)
target_compile_definitions(cubutterfly_tests PRIVATE CUBUTTERFLY_TEST_CUFFTDX=1)
endif()
Expand Down Expand Up @@ -228,10 +266,13 @@ include(CTest)
if(BUILD_TESTING)
add_test(NAME cuntt_correctness COMMAND cuntt_tests)
add_test(NAME cubutterfly_correctness COMMAND cubutterfly_tests)
add_test(NAME cubutterfly_structured_reference COMMAND cubutterfly_structured_reference_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 design_point_generator
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_design_point_generator.py")
add_test(NAME comprehensive_suite
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_comprehensive_suite.py")
add_test(NAME scaling_suite
Expand All @@ -242,6 +283,12 @@ if(BUILD_TESTING)
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_external_baseline_suite.py")
add_test(NAME scaling_ncu_analysis
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_scaling_ncu_analysis.py")
add_test(NAME structured_2x2_ncu_analysis
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_structured_2x2_ncu.py")
add_test(NAME structured_coefficient_policy_summary
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_structured_coefficient_policies.py")
add_test(NAME residency_features
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_residency_features.py")
add_test(NAME fft_vectorized_ncu_analysis
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_fft_vectorized_ncu.py")
add_test(NAME fp64_fft_ncu_analysis
Expand All @@ -256,6 +303,13 @@ if(BUILD_TESTING)
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_fft_pipeline_model.py")
add_test(NAME fft_dispatch_generator
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_fft_dispatch_generator.py")
add_test(NAME installed_package_consumer
COMMAND "${CMAKE_COMMAND}"
-DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-DBUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}
-P "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_install_package.cmake")
add_test(NAME runtime_selector_generator
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_runtime_selector_generator.py")
if(CUBUTTERFLY_ENABLE_CUFFTDX)
add_test(NAME fft_fp64_cufftdx_block_correctness
COMMAND cubutterfly_bench --operator fft --precision fp64 --backend temporal-tile
Expand Down Expand Up @@ -388,3 +442,28 @@ if(BUILD_TESTING)
--warmup 1 --repeat 1 --verify)
endif()
endif()

install(TARGETS cuntt
EXPORT cuButterflyTargets
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(DIRECTORY include/cuntt DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")

configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cuButterflyConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cuButterflyConfig.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cuButterfly")
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/cuButterflyConfigVersion.cmake"
VERSION "${PROJECT_VERSION}"
COMPATIBILITY SameMajorVersion)

install(EXPORT cuButterflyTargets
FILE cuButterflyTargets.cmake
NAMESPACE cuButterfly::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cuButterfly")
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/cuButterflyConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cuButterflyConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/cuButterfly")
58 changes: 51 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)

cuButterfly is a CUDA research prototype for mapping regular layered transforms
onto a GPU. Its central observation is that FFT, NTT, FWHT, and XOR-zeta differ
onto a GPU. Its central observation is that FFT, NTT, FWHT, and subset/superset zeta differ
in arithmetic but expose the same two-dimensional scheduling problem: many
independent data groups must pass through an ordered sequence of butterfly
stages. The project describes how both dimensions are unfolded in space and
Expand Down Expand Up @@ -79,6 +79,13 @@ Methodology](docs/hardware_mapping_methodology.md) gives the resource equations
and counter-driven selection procedure, while [Complete Butterfly Design
Space](docs/butterfly_design_space.md) specifies the full mapping descriptor:

Search candidates also carry portable residency features derived from the
target GPU and compiled core: temporal state/thread, allocated registers and
shared bytes/CTA, resource-specific CTA limits, resident warps, occupancy upper
bound, grid waves, limiting resource, and adjacent-point resource cliffs. Only
hardware-infeasible points are pruned automatically; a cliff triggers nearby
`Td`, decomposition, thread/EPT, and processing-unit alternatives.

```text
M = (Us, Ts, Ud, Td, Ub, Tb, Hs, Rs, Rd, Rb, L, F, Q)
```
Expand All @@ -90,7 +97,12 @@ M = (Us, Ts, Ud, Td, Ub, Tb, Hs, Rs, Rd, Rb, L, F, Q)
| NTT | 32/64-bit words, compatible primes below `2^63` | radix-2/4/8, Shoup, Barrett, fused coset twiddles | baseline, local tile, Hybrid2D, compact stage, stage pipeline |
| FFT | FP32, FP64, FP16 input with FP32 accumulation | radix-2/4/8, four-multiply, Gauss-3, thread/CTA/WMMA DFT8, FP32/FP64 cuFFTDx | temporal tile, hierarchical, online reorder, warp hybrid, stage pipeline |
| FWHT | FP32, FP64 | radix-2/4/8, shared and warp-register exchange | temporal tile, hierarchical, online reorder, warp hybrid, stage pipeline |
| XOR-zeta | uint32 | radix-2/4/8 | temporal tile, hierarchical, online reorder, warp hybrid, stage pipeline |
| Subset/superset zeta and Mobius | uint32 | asymmetric radix-2/4/8 | temporal tile, hierarchical, online reorder, warp hybrid, stage pipeline |
| Structured 2x2 | FP32, FP64 stage matrices | parameterized radix-2/4/8; generated FP32 warp-register matrix core | temporal tile, hierarchical, online reorder, warp hybrid, stage pipeline |

The historical `xor-zeta` API name is retained as a compatibility spelling for
its original subset-zeta behavior. See the [Operator
Catalog](docs/operator_catalog.md) for exact semantics and expansion priorities.

Power-of-two lengths, batches, forward/inverse execution, normalization,
in-place/out-of-place placement, padded batches, and strided elements are
Expand Down Expand Up @@ -203,6 +215,30 @@ cmake --build build -j
cmake --build build --target test
```

Install and link from another CMake project:

```bash
cmake --install build --prefix "$HOME/.local"
```

```cmake
find_package(cuButterfly CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE cuButterfly::cuButterfly)
```

`ButterflyPlan` and NTT `Plan` accept caller-owned device pointers, CUDA
streams, and optional external workspaces through allocation-free
`execute_async` calls. Start with the [Programming
Guide](docs/programming_guide.md), [C++ API
Reference](docs/api_reference.md), and build-checked [Examples](docs/examples.md).
The [Capability and Compatibility Matrix](docs/support_matrix.md) distinguishes
compiled support from V100-calibrated automatic selection.

Setting `auto_select = true` resolves a covered semantic workload to a measured
V100 mapping and exposes the decision through `plan.selection()`. The selector
fails outside its calibrated hardware and semantic range; see [Runtime Mapping
Selector](docs/runtime_selector.md).

Run representative verified workloads:

```bash
Expand All @@ -215,6 +251,11 @@ Run representative verified workloads:
--local-exchange warp-register --precision fp32 \
--logN 15 --batch 128 --verify

# Structured 2x2: same generated transport, arbitrary stage matrix
./build/cubutterfly_bench --operator structured-2x2 --backend temporal-tile \
--local-exchange warp-register --precision fp32 \
--stage-matrix 1,0.25,-0.5,1 --logN 12 --batch 1024 --verify

# FFT: generated CTA DFT8 mapping
./build/cubutterfly_bench --operator fft --backend temporal-tile \
--fft-core cta-dft8 --precision fp32 --compute-unit radix8 \
Expand Down Expand Up @@ -247,7 +288,7 @@ the hardware model, complete design-space contract, and research-status report.
| `include/cuntt/` | public NTT and common butterfly plan APIs |
| `src/` | CUDA runtime, mappings, processing units, and CPU references |
| `config/`, `configs/` | generated-unit choices, GPU profiles, and mapping descriptors |
| `apps/` | benchmark and hardware microbenchmark executables |
| `apps/`, `examples/` | benchmark executables and application API examples |
| `tests/` | correctness and semantic coverage |
| `scripts/` | sweeps, summarizers, plotting, NCU, and Nsight Systems workflows |
| `results/` | measured V100 CSV data and counter analyses |
Expand All @@ -259,9 +300,12 @@ 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). The v0.3.0
research milestone, acceptance criteria, and deferred cross-GPU work are in
[v0.3.0 Mapping-Selection Milestone](docs/next_phase_v0.3.md).
Versioned changes are recorded in [`CHANGELOG.md`](CHANGELOG.md). The completed
v0.3.0 mapping-selection milestone is archived in
[v0.3.0 Mapping-Selection Milestone](docs/next_phase_v0.3.md). The next study
conditions resource cliffs and mapping preference on numeric representation,
length, batch, layout, and processing-unit cost; its hypotheses and completion
criteria are in [Numeric-Regime Mapping Study](docs/next_phase_numeric_regimes.md).

## Evidence Boundary

Expand Down Expand Up @@ -293,7 +337,7 @@ software release as:
author = {TruNcat3},
title = {cuButterfly: Hardware-Mapped Space-Time Parallelism for Butterfly Computations on GPUs},
year = {2026},
version = {0.3.0},
version = {0.4.0},
url = {https://github.com/TruNcat3/cuButterfly}
}
```
Expand Down
Loading
Loading