Skip to content

Close the AndOr/Bitwise gap vs TropicalNumbers.jl: wire AndOr onto GPU + add TropicalBitwise (bit-packed) #44

Description

@isPANN

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

  1. 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).
  2. 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.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions