tracel-ai/burn · error

ctc_loss: 2 * max_target_len + 1 = {} exceeds the kernel's s

Error message

ctc_loss: 2 * max_target_len + 1 = {} exceeds the kernel's shared-memory alpha capacity ({}). Reduce target length or raise SHARED_ALPHA_CAPACITY.

What it means

AsyncPolicy::load_record is intentionally unimplemented. An AsyncPolicy spawns a background inference worker holding a clone of the inner policy's state, so a record cannot be loaded directly on the async wrapper; the message tells you to load the record on the inner policy first and then wrap it.

Source

Thrown at crates/burn-cubecl/src/kernel/ctc.rs:307

) -> CubeTensor {
    // Manual stride indexing below requires a contiguous physical layout;
    // fusion-produced tensors may arrive with layouts that break that
    // assumption. No-op when already contiguous.
    let log_probs = into_contiguous(log_probs);
    let targets = into_contiguous(targets);
    let input_lengths = into_contiguous(input_lengths);
    let target_lengths = into_contiguous(target_lengths);

    let log_probs_shape = log_probs.shape();
    let [_t, batch_size, _c] = log_probs_shape.dims::<3>();
    let target_shape = targets.shape();
    let max_target_len = target_shape.dims::<2>()[1];
    let max_l_prime = 2 * max_target_len + 1;

    assert!(
        max_l_prime as u32 <= SHARED_ALPHA_CAPACITY,
        "ctc_loss: 2 * max_target_len + 1 = {} exceeds the kernel's shared-memory \
         alpha capacity ({}). Reduce target length or raise SHARED_ALPHA_CAPACITY.",
        max_l_prime,
        SHARED_ALPHA_CAPACITY,
    );

    // Pick a thread count that fits the runtime's per-cube limit. We don't
    // need one thread per s position - threads stride over s.
    let hw_max = log_probs.client.properties().hardware.max_cube_dim.0;
    let cube_dim_x = (max_l_prime as u32).min(hw_max).min(256);

    let client = log_probs.client.clone();
    let device = log_probs.device.clone();
    let f_dtype = log_probs.dtype;
    let i_dtype = targets.dtype;
    let output = empty_device_dtype(client.clone(), device, Shape::new([batch_size]), f_dtype);

    let cube_count = CubeCount::Static(batch_size as u32, 1, 1);
    let cube_dim = CubeDim::new_1d(cube_dim_x);

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Load the record on the inner policy BEFORE constructing the AsyncPolicy: build the base policy, call policy.load_record(record), then wrap it with AsyncPolicy::new.
  2. Refactor the caller to keep a handle to the inner policy so record loading never goes through the async wrapper.
  3. If you need post-hoc state updates, file/upstream an issue; the only in-library path is the pre-load pattern.

Example fix

// before
let policy = AsyncPolicy::new(base_policy);
let policy = policy.load_record(record); // panics: unimplemented!
// after
let policy = base_policy.load_record(record);
let policy = AsyncPolicy::new(policy);
Defensive patterns

Strategy: validation

Validate before calling

fn load_record_safe<P: Policy>(policy: &P, record: &P::Record) -> Result<(), &'static str> {
    if std::any::TypeId::of::<P>() == std::any::TypeId::of::<crate::policy::AsyncPolicy<()>>() {
        return Err("load_record is unimplemented on AsyncPolicy; load on the inner policy first");
    }
    Ok(())
}

Type guard

fn is_async_policy_marker(msg: &str) -> bool {
    msg.contains("load the record on the inner policy")
}

Try / catch

// Rust panics are not catchable idiomatically; guard by construction:
let inner = base_policy.load_record(record);
let policy = AsyncPolicy::new(inner);

Prevention

When it happens

Trigger: Calling load_record on an AsyncPolicy (e.g. when restoring a checkpointed policy from a saved record through a generic Policy trait object that happens to be an AsyncPolicy).

Common situations: Checkpoint restore/finetuning workflows where code is polymorphic over Policy and does not special-case AsyncPolicy; serializing a training run and resuming with the policy already wrapped for async inference.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/2d90c97bb9ee521c. Report an issue: GitHub.