Skip to content

feat/cuda: I3 - elementwise/norm/activation/embedding CUDA kernels - #23

Open
magiodev wants to merge 9 commits into
antirez:mainfrom
magiodev:cuda/03-elementwise
Open

feat/cuda: I3 - elementwise/norm/activation/embedding CUDA kernels#23
magiodev wants to merge 9 commits into
antirez:mainfrom
magiodev:cuda/03-elementwise

Conversation

@magiodev

Copy link
Copy Markdown

Stacked PR 3/3, on top of #20 (I1) and #21 (I2). Once those merge this diff narrows to I3 only.

I3: real CUDA kernels, Metal formulas mirrored exactly:

  • activations: silu (f32/bf16), gelu (approx/exact), geglu, swiglu (f32/bf16), silu_mul
  • casts f32<->bf16 (round-to-nearest-even, matches Metal), clip
  • add/sub bf16, add_scaled f32
  • norms: rms/layer_norm (f32/bf16, block-per-row reduction), head_rms_norm, weight_norm
  • embedding, scale_add, gate bf16; copy f32/bf16 (device->device)
    BF16 helpers device with CUDA intrinsics. 50 compute ops remain stubs.

Build-gated on DGX Spark: make cuda-spark clean.

…l, 100 op stubs)

- Add h3_cuda.cu: implements the existing plain-C h3_gpu.h API against CUDA/cuBLAS.
  h3_cuda_probe + h3_gpu_create/free/error real; all compute ops are stubs returning
  'not yet implemented'. Metal backend (h3_gpu.m/h3_shaders.metal) preserved untouched.
- Add h3_cuda.h (probe decl); h3.c probes via H3_CUDA guard.
- Add h3_tokenizer.c C stub (Linux has no Foundation; Metal keeps h3_tokenizer.m).
- h3_host.c: vImage high-quality scale guarded, portable bilinear fallback for CUDA build.
- h3.c/h3_cli.c/h3_ffmpeg.c: Linux portability guards (st_mtimespec->st_mtim,
  arc4random_buf->getrandom, SSIZE_MAX define).
- Makefile: cuda-spark/cuda-generic/cuda targets (nvcc + cuBLAS, .cuda.o objects,
  CUDA_ARCH=sm_121 for DGX Spark GB10), mirroring ds4's pattern.
…h in h3_cuda.cu

nvcc compiles .cu as C++; without C linkage the GPU API symbols were mangled
and the host C objects could not link. extern "C" guards are compile-time
only and inert for the Metal build (.c/.m never define __cplusplus).
… command-buffer no-ops, stats

- h3_gpu_tensor_new/from_*: cudaMalloc + host->device copy (f32/bf16/i8/u32)
- h3_gpu_tensor_load_bf16/f32 + read_file_bf16/stream_file_bf16: chunked pread ->
  host staging -> device (1MB chunks; no host double-buffer of big weights)
- h3_gpu_tensor_read/write_*: device<->host cudaMemcpy with bounds checks
- h3_gpu_begin/continue/submit: no-ops (CUDA has no explicit command buffer)
- h3_gpu_get_stats: allocated/live/peak bytes + tensor_allocations tracking
- tensor_free: cudaFree + stats decrement; tensor struct carries owner
- capability flags (is_m5/has_int8_mlp/has_nax_mlp) still return 0 (no int8/nax fast paths yet)
Real CUDA kernels (Metal formulas mirrored exactly):
- activations: silu (f32/bf16), gelu (approx/exact, tanh/erf), geglu, swiglu (f32/bf16), silu_mul
- casts: f32<->bf16 (round-to-nearest-even, matches Metal), clip
- arithmetic: add/sub bf16, add_scaled f32
- norms: rms_norm/layer_norm (f32/bf16, block-per-row shared reduction), head_rms_norm, weight_norm
- embedding bf16, scale_add f32, gate bf16
- copy f32/bf16 (device->device cudaMemcpy)
BF16 helpers implemented to match Metal bit-for-bit. 50 compute ops remain stubs.
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.

1 participant