Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions crates/cubecl-core/src/runtime_tests/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,29 +283,36 @@ macro_rules! testgen_branch {
}

#[$crate::runtime_tests::test_log::test]
fn test_if_literal_u8_true() {
fn test_switch_const() {
let client = TestRuntime::client(&Default::default());
cubecl_core::runtime_tests::branch::test_if_literal_u8::<TestRuntime>(client, true);
cubecl_core::runtime_tests::branch::test_switch_const::<TestRuntime, FloatType>(client);
}

#[$crate::runtime_tests::test_log::test]
fn test_if_literal_u8_false() {
fn test_for_loop_with_break() {
let client = TestRuntime::client(&Default::default());
cubecl_core::runtime_tests::branch::test_if_literal_u8::<TestRuntime>(client, false);
cubecl_core::runtime_tests::branch::test_for_loop_with_break::<TestRuntime, FloatType>(
client,
);
}
};
}

#[allow(missing_docs)]
#[macro_export]
macro_rules! testgen_branch_u8 {
(u8) => {
#[$crate::runtime_tests::test_log::test]
fn test_switch_const() {
fn test_if_literal_u8_true() {
let client = TestRuntime::client(&Default::default());
cubecl_core::runtime_tests::branch::test_switch_const::<TestRuntime, FloatType>(client);
cubecl_core::runtime_tests::branch::test_if_literal_u8::<TestRuntime>(client, true);
}

#[$crate::runtime_tests::test_log::test]
fn test_for_loop_with_break() {
fn test_if_literal_u8_false() {
let client = TestRuntime::client(&Default::default());
cubecl_core::runtime_tests::branch::test_for_loop_with_break::<TestRuntime, FloatType>(
client,
);
cubecl_core::runtime_tests::branch::test_if_literal_u8::<TestRuntime>(client, false);
}
};
($uint:ident) => {};
}
1 change: 1 addition & 0 deletions crates/cubecl-core/src/runtime_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ macro_rules! testgen_all {
type UintType = $uint;

$crate::testgen_uint!();
$crate::testgen_branch_u8!($uint);
})*
}
$crate::testgen_untyped!();
Expand Down
62 changes: 62 additions & 0 deletions docs/superpowers/plans/2026-07-19-gate-u8-branch-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Gate `u8` Branch Runtime Tests Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Generate the `u8` branch runtime tests only for backends whose existing test type list includes `u8`.

**Architecture:** Add a token-matching test macro beside the branch tests and invoke it from unsigned-type modules generated by `testgen_all!`. The backend type lists remain the single capability declaration.

**Tech Stack:** Rust, declarative macros, Cargo tests, CubeCL WGPU runtime tests.

## Global Constraints

- Do not implement or emulate `u8` in WGSL.
- Preserve the two runtime assertions on backends that list `u8`.
- Keep the fork delta backend-agnostic and minimal.

---

### Task 1: Capability-gated test generation

**Files:**
- Modify: `crates/cubecl-core/src/runtime_tests/branch.rs`
- Modify: `crates/cubecl-core/src/runtime_tests/mod.rs`

**Interfaces:**
- Consumes: the unsigned type tokens already passed to `testgen_all!`.
- Produces: `testgen_branch_u8!(type_token)`, generating tests only for `u8`.

- [ ] **Step 1: Verify the existing regression test fails**

Run: `cargo test -p t4a-cubecl-wgpu --lib test_if_literal_u8 -- --nocapture`

Expected: four failures ending in `U8 is not a valid WgpuElement`.

- [ ] **Step 2: Add the selective macro**

Move `test_if_literal_u8_true` and `test_if_literal_u8_false` out of
`testgen_branch!` and into `testgen_branch_u8!`, with a `(u8)` arm containing
the tests and a catch-all arm expanding to nothing.

- [ ] **Step 3: Connect it to unsigned type generation**

After each `$crate::testgen_uint!()` invocation inside the parameterized
`testgen_all!`, add `$crate::testgen_branch_u8!($uint);`.

- [ ] **Step 4: Verify the focused WGPU regression**

Run: `cargo test -p t4a-cubecl-wgpu --lib test_if_literal_u8 -- --nocapture`

Expected: zero matching tests, exit status 0.

- [ ] **Step 5: Verify formatting, compilation, and the WGPU library suite**

Run `cargo fmt --check`, `cargo check -p t4a-cubecl-core`, and
`cargo test -p t4a-cubecl-wgpu --lib`.

Expected: all commands exit with status 0.

- [ ] **Step 6: Commit**

Stage only the two source files and these design documents, then commit as
`test(core): gate u8 branch tests by backend types`.
28 changes: 28 additions & 0 deletions docs/superpowers/specs/2026-07-19-gate-u8-branch-tests-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Gate `u8` Branch Runtime Tests by Supported Types

## Problem

`testgen_branch!` generates the `u8` literal branch tests once for every
floating-point test module. WGSL does not support `u8`, so the WGPU test suite
generates four runtime tests that can only panic in the WGSL compiler.

## Design

Keep the shared `u8` kernel and runtime assertion, but move test generation to
a new helper macro that accepts one unsigned type token. The macro generates
the two tests only for the `u8` token and expands to nothing for other unsigned
types. `testgen_all!` invokes this helper from each generated unsigned-type
module.

This uses each backend's existing unsigned-type list as the capability source:
CPU, CUDA, and SPIR-V retain one true/false pair under `u8_ty`, while WGSL and
MSL generate no `u8` runtime tests. No backend-specific conditionals or `u8`
emulation are introduced.

## Verification

- Before the change, the focused WGPU command must reproduce four failures.
- After the change, the same filter must find zero WGPU tests and exit cleanly.
- Macro expansion must compile for both a list containing `u8` and a list that
omits it.
- The full WGPU library suite must pass on the local Metal backend.
Loading