CCCL latest requires CUDA 12+, corex is 10.2. Device-level CUB headers
(DeviceRadixSort etc) pull in thrust/detail/type_traits.h which conflicts
with corex's thrust/complex.h namespace.
Rewrite to use block-level CUB BlockScan only (same pattern as the proven
corex_moe_index_combine.cu): histogram + prefix_sum + scatter.
No extra_include_paths needed — uses corex's built-in cub/block/block_scan.cuh.
CoreX CUDACachingAllocator does not support expandable_segments.
Setting it causes ASSERT failure at startup:
'expandable_segments:True not supported on corex CUDACachingAllocator'
Replace with max_split_size_mb:512 only.
CUB CachingDeviceAllocator::DeviceAllocate calls cudaMalloc internally
on cache miss. Without a guard, our intercepted cudaMalloc recurses
into DeviceAllocate → cudaMalloc → DeviceAllocate → segfault.
thread_local g_in_allocator flag detects reentrant calls and forwards
them directly to the real cudaMalloc/cudaFree via dlsym(RTLD_NEXT).
CUB_DISABLE_NAMESPACE_MAGIC requires CUB_WRAPPED_NAMESPACE.
CUB_WRAPPED_NAMESPACE=cccl_preload wraps cub into cccl_preload::cub.
Source must use cccl_preload::cub::CachingDeviceAllocator.
CUB_WRAPPED_NAMESPACE=cccl_preload wraps cub into cccl_preload::cub
but cccl_allocator_preload.cu uses bare cub:: — compilation fails.
_CCCL_COMPILER_GCC=1 conflicts with CCCL auto-detection (redefined warning).
Drop both. CUB_DISABLE_NAMESPACE_MAGIC alone is sufficient.
Route C: replace PyTorch's cudaMalloc/cudaFree with CCCL CUB's
CachingDeviceAllocator via LD_PRELOAD. Eliminates driver-level allocation
overhead by reusing freed GPU memory from a bin-based cache.
Based on cccl_upstream/cub/cub/util_allocator.cuh (901 lines).
Self-contained .so with no CCCL header dependencies at compile time.
Files:
- cccl_preload_allocator.cu: the allocator (405 lines)
- build_cccl_preload_allocator.sh: build script (corex clang++ or g++ fallback)
- test_cccl_preload.sh: smoke test suite for BI-V100
- patch_ops.sh: build during docker build
- computility-run.yaml: LD_PRELOAD env var for runtime
Config via env:
CCCL_ALLOC_BIN_GROWTH=8, MIN_BIN=3, MAX_BIN=13, MAX_CACHED_MB=4096
Test on real machine:
cd qwen3_6_scripts && bash test_cccl_preload.sh
Route C: replace PyTorch's cudaMalloc/cudaFree with CCCL CUB's
CachingDeviceAllocator via LD_PRELOAD. Eliminates driver-level allocation
overhead by reusing freed GPU memory from a bin-based cache.
Based on cccl_upstream/cub/cub/util_allocator.cuh (901 lines).
Self-contained .so with no CCCL header dependencies at compile time.
Files:
- cccl_preload_allocator.cu: the allocator (405 lines)
- build_cccl_preload_allocator.sh: build script (corex clang++ or g++ fallback)
- test_cccl_preload.sh: smoke test suite for BI-V100
- patch_ops.sh: build during docker build
- computility-run.yaml: LD_PRELOAD env var for runtime
Config via env:
CCCL_ALLOC_BIN_GROWTH=8, MIN_BIN=3, MAX_BIN=13, MAX_CACHED_MB=4096
Test on real machine:
cd qwen3_6_scripts && bash test_cccl_preload.sh
Route C: replace PyTorch's cudaMalloc/cudaFree with CCCL CUB's
CachingDeviceAllocator via LD_PRELOAD. Eliminates driver-level allocation
overhead by reusing freed GPU memory from a bin-based cache.
Based on cccl_upstream/cub/cub/util_allocator.cuh (901 lines).
Self-contained .so with no CCCL header dependencies at compile time.
Files:
- cccl_preload_allocator.cu: the allocator (405 lines)
- build_cccl_preload_allocator.sh: build script (corex clang++ or g++ fallback)
- test_cccl_preload.sh: smoke test suite for BI-V100
- patch_ops.sh: build during docker build
- computility-run.yaml: LD_PRELOAD env var for runtime
Config via env:
CCCL_ALLOC_BIN_GROWTH=8, MIN_BIN=3, MAX_BIN=13, MAX_CACHED_MB=4096
Test on real machine:
cd qwen3_6_scripts && bash test_cccl_preload.sh
- patch_ops.sh: build corex_gdn_chunk_recurrent.so alongside moe_index_combine
- qwen3_5.py: import corex_gdn_chunk_recurrent, use C++ version for prefill
chunks instead of Python _torch_chunk_gated_delta_rule
- C++ version from xllm upstream avoids Python loop overhead and has proper
fp32 accumulation (key for NaN prevention on BI-V100)
- Falls back to Python version if .so not available
Verified on real BI-V100:
flash_attn_func works with head_dim=256 (diff < 0.004, no NaN)
flash_attn_varlen_func works for variable-length batching
seq=1024: 1.7x faster than PyTorch matmul
The profiling-stage _run_sdpa_fallback now tries flash_attn_varlen_func
first, falls back to Python Q-tiling only on exception.
This addresses the 10-50x attention slowdown identified in the analysis:
Python Q-tiling: O(L^2) per-tile matmul in Python loop
flash_attn: fused kernel, O(L) memory, hardware-optimized
flash_attn_func WORKS with head_dim=256 on BI-V100!
This is the path to 10-50x attention speedup.
Tests: correctness vs ref, GQA, long seq, varlen, paged decode, perf.
The 10-50x slowdown is from bypassing ixformer SDPA and using Python
matmul fallback. Test if ixformer actually crashes on head_dim=256
or if the bypass was premature.
Extracted torch_chunk_gated_delta_rule and torch_recurrent_gated_delta_rule
from xllm_latest/core/layers/npu_torch/qwen3_gated_delta_net_base.cpp.
Pure PyTorch C++ — no NPU/ACL deps, no custom CUDA kernels.
Same algorithm as our Python _torch_chunk_gated_delta_rule but
avoids Python interpreter overhead in the chunk loop.
Verify on real BI-V100: python3 verify_gdn_cpp.py
Verified on real BI-V100:
moe_compute_index: 11.48x speedup (0.035ms vs 0.397ms)
moe_combine_result: 2.66x speedup (0.022ms vs 0.059ms)
Integration:
- qwen3_5.py: import corex_moe_index_combine, use in prefill path
with _USE_COREX_MOE_INDEX_COMBINE flag (env BI100_MOE_COREX_INDEX_COMBINE)
Falls back to PyTorch argsort+bincount if .so unavailable
- patch_ops.sh: compile corex_moe_index_combine.cu during docker build
verify_topk_softmax.py results:
IDs match: True (0/32 mismatches)
Max weight diff: 0.00000003
Speedup: 2.54x vs PyTorch (0.025ms vs 0.064ms)
Previous disable was based on speculation, not measurement.