Skip to content

cuda: sigmoidf_, softplusf_, silu and silu_grad in common/act.cuh, SASS unchanged - #1556

Merged
ashhart merged 5 commits into
ashhart:mainfrom
jschmied:prims-1409-step4
Oct 29, 2026
Merged

ashhart merged 5 commits into
ashhart:mainfrom
jschmied:prims-1409-step4

Conversation

@jschmied

Copy link
Copy Markdown
Contributor

What

Step 4 of #1409. It is independent of #1550 and #1555, with no shared files. It is a pure refactor: cuobjdump -sass is identical for every function of every image that includes a touched file.

The activation copies whose text is the same move into tf_common in a new header, common/act.cuh:

  • sigmoidf_ (1 / (1 + expf(-x))): gdn_train.cu, drama3_common.cuh and glm_kda.cu. It also replaces the file-local sigm of attn_train.cu, train_attn.cu, flashnext_train.cu, qwen27_train.cu and train_q4.cu, which is the same function under another name, renamed at its call sites in those files;
  • softplusf_ (x > 20 ? x : log1pf(expf(x))): gdn_train.cu and drama3_common.cuh;
  • silu (v / (1 + expf(-v))): flashnext_train.cu, qwen27_train.cu, train_q4.cu and train.cu;
  • silu_grad: gdn_train.cu, flashnext_train.cu, qwen27_train.cu, train_q4.cu and train.cu. train.cu wrote the sigmoid inline.

Each file takes them through a using declaration. glm_kda.cu's gradient-serving pin takes the new bytes.

11 files (with the new header), +52 / −40.

Left alone on purpose

  • flashnext_gdn.cu, qwen4_gdn.cu and flashnext_batch.cu also hold sigmoidf_ and softplusf_ copies. cuda: flashnext_batch, flashnext_gdn and qwen4_gdn take tf_common::warp_sum, SASS unchanged #1550 edits these files and qwen4_gdn's CPU twin, so they come after it lands.
  • qwen4_gdn.cu's sigmoidf_ is the overflow-safe form (expf(-fabsf(x))).
  • act_l2.cuh's silu divides with __fdiv_rn.
  • drama3's siluf_ and train.cu's softplus keep their own names. siluf_ is used across the drama3 files, and train_mixers.cuh calls softplus.
  • deepseek_v41/pointwise.cu's silu is documented as torch's, in its own namespace.

Verification

  • SASS: base main dd0a9cc5e, head f19336386, nvcc 13.0, sm_80/86/89/120/121. The 9 images are attn_train, drama3, flashnext_train, gdn_train, glm_kda, qwen27_train, train, train_attn and train_q4. All 635 functions: 0 changed, 0 added, 0 removed, 0 unstable (tools: cuda_sass_identity.py rebuilds a differing image and fails on an unstable build #1532's rebuild check).
    python3 tools/zig/cuda_sass_identity.py --repo . -j 3 --receipt sass.tsv origin/main HEAD
    
  • Planted control: a reversed warp_sum butterfly changes 250 functions in 9 of 9 images. The fp4pair control cannot be planted, because none of these images includes common/qmm_frag.cuh. The tool exits 1 on that line alone.
  • lean: 425 problems, 425 on the base, 0 new.
  • zig build test -Dnvcc=/usr/local/cuda/bin/nvcc: passes (RC 0).

Part of #1409.

jschmied and others added 5 commits October 29, 2026 12:07
…rp_sum, SASS unchanged

The three remaining float warp_sum copies (xor butterfly 16..1) give way to common/reduce.cuh through a using
declaration, as in ashhart#1440. qwen4_gdn.cu is the checked-in text Gdn.cuda generates from flashnext_gdn.cu
(source_test), so both change together. qwen4_gdn_cuda_host.zig, which builds that text for the CPU, now strips
the include and the using declaration instead of the deleted function. flashnext_gdn.cu's gradient-serving pin
takes the new bytes; flashnext_batch.cu's two pins already differ on main and are left as they are.

cuobjdump -sass is identical for every function of the three images (65 functions, sm_80/86/89/120/121) with
nvcc 13.0 and 13.2, base prims-1409.
Step 3 of ashhart#1409. The text-identical copies move to tf_common in one header:
- fp4pair (E2M1 pair to bf16x2): qmm_frag.cuh, prompt16, nvfp4_experts and nvfp4_experts_tile;
- fp8pair (two adjacent E4M3 bytes to bf16x2): drama3_fp8 and fp8_experts;
- e4m3f (E4M3 scale to float): nvfp4_experts and nvfp4_experts_tile.

Each file takes them by a using-declaration, so no call site changes. qmm_frag keeps qmm_frag::fp4pair the same way.
Left out because their text differs: qmmf's fp8pair (bytes spread first) and e4m3f(uint8_t), and prompt16's
fp8pair with a unit argument.

cuda_sass_identity.py's fp4pair-constant control now plants in common/fp_pairs.cuh, where the constant lives.
…ytes fp_pairs.cuh leaves

Both pins matched main before this branch. fp8_experts.cu's and nvfp4_experts.cu's pins already differ on main and are left as they are, as ashhart#1550 does for flashnext_batch.cu.
…SS unchanged

Step 4 of ashhart#1409. The same-text activation copies move to tf_common in one header:
- sigmoidf_: gdn_train, drama3_common.cuh, glm_kda, and the file-local sigm of attn_train, train_attn,
  flashnext_train, qwen27_train and train_q4 (renamed at their call sites);
- softplusf_: gdn_train and drama3_common.cuh;
- silu: flashnext_train, qwen27_train, train_q4 and train;
- silu_grad: gdn_train, flashnext_train, qwen27_train, train_q4 and train (train's spelled the sigmoid inline).

Each file takes them by a using-declaration. glm_kda.cu's gradient-serving pin takes the new bytes.
Left out: flashnext_gdn, qwen4_gdn and flashnext_batch (ashhart#1550 edits them and qwen4_gdn's CPU twin), qwen4_gdn's
stable sigmoid, act_l2's __fdiv_rn silu, drama3's siluf_ and train's softplus (other names used elsewhere or not at
all), and deepseek_v41/pointwise's torch silu.
@ashhart
ashhart merged commit 5b6c254 into ashhart:main Oct 29, 2026
9 checks passed
@ashhart

ashhart commented Oct 29, 2026

Copy link
Copy Markdown
Owner

Thanks @jschmied, landed with #1550, #1555 and #1556 together on main (changelog in 5b6c254). We rebuilt every CUDA image from main and from the stack at sm_121 and sm_80: all 1,866 functions in the 104 images compile to identical SASS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants