Skip to content

prune admits a space at --cc 7.5 for a crate whose device code cannot lower for sm_75 (needs_cc is unchecked) #32

Description

@vyncint

Summary

launchbound prune --cc 7.5 admitted all 12 candidates of a kernel crate whose device code cannot be compiled for sm_75 at all. The gate answers the convergence question correctly; it has no view of instruction availability, and needs_cc in kernel.toml is taken on trust. That is probably by design — but the verdict line reads as "this kernel is fine at cc 7.5", and it was not.

Reproduction (launchbound 2.0.0, reconverge 0.4.0, cuda-oxide a766fc26, nightly-2026-04-03)

Kernel crate: vyncint/oxmera at 992d5ab, research/oxmera-cuda. Its vec_sigmoid used the catalog intrinsic float::ex2_approx_f32, whose entry in cuda-intrinsics/src/generated/abi_v1.rs reads:

/// Catalog ID: `ex2_approx_f32`. ... expects PTX `ex2.approx.f32 <register>, <register>;`.
/// Available on `sm_80+` targets from PTX 7.0.

kernel.toml declares needs_cc = "7.5".

$ launchbound prune --cc 7.5 .
oxmera-cuda (cc 7.5):
  => 12 clean, 0 with caveats, 0 refused, 0 tool errors

Same tree, in a container with CUDA 13.2 and cargo-oxide 0.2.1:

$ cargo oxide inspect --arch sm_75
error: [rustc_codegen_cuda] Device codegen failed: PTX generation failed: CUDA target sm_75 cannot lower generated intrinsic `ex2_approx_f32` (`v1:i0819`); requires sm_80 or newer (target from CUDA_OXIDE_TARGET)

--arch sm_86 builds, and the PTX assembles with ptxas -arch=sm_86.

Minimal kernel:

#[kernel]
#[launch_bounds(256)]
#[launch_contract(domain = 1, coordinates = u32)]
pub fn vec_sigmoid(a: &[f32], mut out: DisjointSlice<f32>) {
    let i = (thread::blockIdx_x() * thread::blockDim_x() + thread::threadIdx_x()) as usize;
    if i < a.len() && i < out.len() {
        let e = float::ex2_approx_f32(-a[i] * core::f32::consts::LOG2_E);
        unsafe { *out.as_mut_ptr().add(i) = 1.0 / (1.0 + e) };
    }
}

with [kernel] needs_cc = "7.5" and any [dims].

Why it matters for this tool specifically

Every float intrinsic in cuda-oxide's catalog at this rev (ex2, lg2, rcp, tanh approx variants) is sm_80+. A kernel author targeting a T4/7.5 will reach for them, see a fully-admitted space at --cc 7.5, and only learn otherwise when something finally compiles to PTX for that part.

Possible shapes of a fix (your call)

  • A per-candidate cargo oxide build --arch sm_XY probe when a toolkit is present, reported as a caveat or tool error when it is not (keeps plain runners toolkit-free).
  • Or, cheaper: a static scan of the crate for cuda_device::float::* (and other catalog IDs) against the catalog's Available on sm_NN+ lines, refused/caveated when below --cc.
  • Or simply a sentence in prune --cc's help and the verdict table: the gate verifies convergence and shared-memory capacity, not instruction availability — needs_cc is the author's claim.

What I did on my side

Replaced the intrinsics with plain-arithmetic exp/tanh (range reduction + polynomial), so the crate lowers for both sm_75 and sm_86 (ptxas-verified) and needs_cc = "7.5" is now true. Happy to contribute a corpus kernel for this if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions