Summary
This issue is rescoped. The original proposal sketched a new TropicalBoolean
bit-packed semiring and a cuBLAS CUDA_R_1B path. After checking the Julia
inspiration and our own tree, the real situation is different and simpler:
TropicalAndOr already exists in this repo on CPU (types/and_or.rs,
stored as bool) — but is not available on GPU (tropical-gemm-cuda
registers only MaxPlus/MinPlus/MaxMul). CuTropicalGEMM.jl does accelerate
TropicalAndOr on GPU, so our CUDA backend is actually behind the Julia
original here.
- The bit-packed type the original issue reinvented already has a name and a
definition upstream: TropicalBitwise (int, |, &, 0, ~0) in
TropicalNumbers.jl. We have it on neither CPU nor GPU.
So the work is "close a migration gap", not "design a new semiring".
Current coverage (AndOr / Bitwise only)
| Type |
Julia CPU |
Julia GPU |
Our CPU |
Our GPU |
TropicalAndOr ([T,F], ∨, ∧, F, T) |
✅ |
✅ |
✅ (bool) |
❌ |
TropicalBitwise (int, |, &, 0, ~0) |
✅ |
❌ |
❌ |
❌ |
Why this is cheap (kernel reuse, not new kernels)
The semiring is plugged into a shared GEMM; only (zero, ⊕, ⊗) change.
- CPU:
core/gemm.rs::tropical_gemm_inner<T: TropicalSemiring, K> is generic
over the semiring; the portable microkernel just calls tropical_add/
tropical_mul. TropicalAndOr already runs through it. A new
TropicalBitwise<u32/u64> is a new scalar type plus a bitwise SIMD
microkernel for speed.
- CUDA:
kernels/tropical_gemm.cu is macro-templated —
TROPICAL_GEMM_F32(NAME, INIT_VAL, COMPARE_FN, MUL_OP). Each semiring is one
line (e.g. TROPICAL_GEMM_F32(tropical_maxplus_f32_nn, NEG_INF_F32, fmaxf, +)).
Adding AndOr / Bitwise = one (maybe two) macro instantiations with or/and
ops + one registration row in kernels.rs, mirroring how i32/i64 MaxMul were
added. No new GEMM algorithm.
The bit-packing actually on offer
TropicalBitwise<u32> packs 32 independent boolean problems into the bit
lanes of one word. A single GEMM over u32 matrices then computes 32 boolean
matmuls at once (bit-slicing) through the unchanged tiling kernel — ⊕ = |,
⊗ = &, no horizontal reduction, no popcount. That is the 32× density/throughput
win, for near-zero new code.
Out of scope (separate future issue): hardware 1-bit tensor-core GEMM
(CUTLASS b1 / bmma / popcount) for a single dense boolean product packed
along the contraction axis. That needs a genuinely different kernel and Ampere+
for the AND op, and does not reuse the template above. Tracking it separately.
Proposed scope
- GPU
TropicalAndOr (regression vs Julia): add or/and kernel
instantiation in tropical_gemm.cu, register CudaKernel for TropicalAndOr
in kernels.rs. Validate on HPC (A40/A800).
TropicalBitwise<u32> (and u64):
- CPU: new scalar type + bitwise SIMD microkernel; flows through the existing
generic driver.
- GPU:
TROPICAL_GEMM_U32 macro (copy of the i32 macro, unsigned int) +
or_u32/and_u32, register the kernel.
- argmax semantics: bit-slice argmax is per-lane; document or defer.
- Tests: a boolean-matmul correctness check that reuses the existing GEMM and
cross-checks against MaxPlus on {0, -∞}.
Naming
Adopt the upstream name TropicalBitwise (not TropicalBoolean) to stay
aligned with TropicalNumbers.jl.
Related, but out of this issue's scope
Broader coverage gaps vs TropicalNumbers.jl — TropicalMaxMin (missing on both
CPU and GPU) and f16/half element types — are tracked separately.
Summary
This issue is rescoped. The original proposal sketched a new
TropicalBooleanbit-packed semiring and a cuBLAS
CUDA_R_1Bpath. After checking the Juliainspiration and our own tree, the real situation is different and simpler:
TropicalAndOralready exists in this repo on CPU (types/and_or.rs,stored as
bool) — but is not available on GPU (tropical-gemm-cudaregisters only MaxPlus/MinPlus/MaxMul). CuTropicalGEMM.jl does accelerate
TropicalAndOron GPU, so our CUDA backend is actually behind the Juliaoriginal here.
definition upstream:
TropicalBitwise(int, |, &, 0, ~0)inTropicalNumbers.jl. We have it on neither CPU nor GPU.
So the work is "close a migration gap", not "design a new semiring".
Current coverage (AndOr / Bitwise only)
TropicalAndOr([T,F], ∨, ∧, F, T)bool)TropicalBitwise(int, |, &, 0, ~0)Why this is cheap (kernel reuse, not new kernels)
The semiring is plugged into a shared GEMM; only
(zero, ⊕, ⊗)change.core/gemm.rs::tropical_gemm_inner<T: TropicalSemiring, K>is genericover the semiring; the portable microkernel just calls
tropical_add/tropical_mul.TropicalAndOralready runs through it. A newTropicalBitwise<u32/u64>is a new scalar type plus a bitwise SIMDmicrokernel for speed.
kernels/tropical_gemm.cuis macro-templated —TROPICAL_GEMM_F32(NAME, INIT_VAL, COMPARE_FN, MUL_OP). Each semiring is oneline (e.g.
TROPICAL_GEMM_F32(tropical_maxplus_f32_nn, NEG_INF_F32, fmaxf, +)).Adding AndOr / Bitwise = one (maybe two) macro instantiations with
or/andops + one registration row in
kernels.rs, mirroring how i32/i64 MaxMul wereadded. No new GEMM algorithm.
The bit-packing actually on offer
TropicalBitwise<u32>packs 32 independent boolean problems into the bitlanes of one word. A single GEMM over
u32matrices then computes 32 booleanmatmuls at once (bit-slicing) through the unchanged tiling kernel —
⊕ = |,⊗ = &, no horizontal reduction, no popcount. That is the 32× density/throughputwin, for near-zero new code.
Out of scope (separate future issue): hardware 1-bit tensor-core GEMM
(CUTLASS
b1/bmma/ popcount) for a single dense boolean product packedalong the contraction axis. That needs a genuinely different kernel and Ampere+
for the AND op, and does not reuse the template above. Tracking it separately.
Proposed scope
TropicalAndOr(regression vs Julia): addor/andkernelinstantiation in
tropical_gemm.cu, registerCudaKernel for TropicalAndOrin
kernels.rs. Validate on HPC (A40/A800).TropicalBitwise<u32>(andu64):generic driver.
TROPICAL_GEMM_U32macro (copy of the i32 macro,unsigned int) +or_u32/and_u32, register the kernel.cross-checks against
MaxPluson{0, -∞}.Naming
Adopt the upstream name
TropicalBitwise(notTropicalBoolean) to stayaligned with TropicalNumbers.jl.
Related, but out of this issue's scope
Broader coverage gaps vs TropicalNumbers.jl —
TropicalMaxMin(missing on bothCPU and GPU) and f16/half element types — are tracked separately.