{"record":{"id":"2d90c97bb9ee521c","repo":"tracel-ai/burn","slug":"ctc-loss-2-max-target-len-1-exceeds-the","errorCode":null,"errorMessage":"ctc_loss: 2 * max_target_len + 1 = {} exceeds the kernel's shared-memory alpha capacity ({}). Reduce target length or raise SHARED_ALPHA_CAPACITY.","messagePattern":"ctc_loss: 2 \\* max_target_len \\+ 1 = (.+?) exceeds the kernel's shared-memory alpha capacity \\((.+?)\\)\\. Reduce target length or raise SHARED_ALPHA_CAPACITY\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-cubecl/src/kernel/ctc.rs","lineNumber":307,"sourceCode":") -> CubeTensor {\n    // Manual stride indexing below requires a contiguous physical layout;\n    // fusion-produced tensors may arrive with layouts that break that\n    // assumption. No-op when already contiguous.\n    let log_probs = into_contiguous(log_probs);\n    let targets = into_contiguous(targets);\n    let input_lengths = into_contiguous(input_lengths);\n    let target_lengths = into_contiguous(target_lengths);\n\n    let log_probs_shape = log_probs.shape();\n    let [_t, batch_size, _c] = log_probs_shape.dims::<3>();\n    let target_shape = targets.shape();\n    let max_target_len = target_shape.dims::<2>()[1];\n    let max_l_prime = 2 * max_target_len + 1;\n\n    assert!(\n        max_l_prime as u32 <= SHARED_ALPHA_CAPACITY,\n        \"ctc_loss: 2 * max_target_len + 1 = {} exceeds the kernel's shared-memory \\\n         alpha capacity ({}). Reduce target length or raise SHARED_ALPHA_CAPACITY.\",\n        max_l_prime,\n        SHARED_ALPHA_CAPACITY,\n    );\n\n    // Pick a thread count that fits the runtime's per-cube limit. We don't\n    // need one thread per s position - threads stride over s.\n    let hw_max = log_probs.client.properties().hardware.max_cube_dim.0;\n    let cube_dim_x = (max_l_prime as u32).min(hw_max).min(256);\n\n    let client = log_probs.client.clone();\n    let device = log_probs.device.clone();\n    let f_dtype = log_probs.dtype;\n    let i_dtype = targets.dtype;\n    let output = empty_device_dtype(client.clone(), device, Shape::new([batch_size]), f_dtype);\n\n    let cube_count = CubeCount::Static(batch_size as u32, 1, 1);\n    let cube_dim = CubeDim::new_1d(cube_dim_x);\n","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-cubecl/src/kernel/ctc.rs#L289-L325","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["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.","Refactor the caller to keep a handle to the inner policy so record loading never goes through the async wrapper.","If you need post-hoc state updates, file/upstream an issue; the only in-library path is the pre-load pattern."],"exampleFix":"// before\nlet policy = AsyncPolicy::new(base_policy);\nlet policy = policy.load_record(record); // panics: unimplemented!\n// after\nlet policy = base_policy.load_record(record);\nlet policy = AsyncPolicy::new(policy);","handlingStrategy":"validation","validationCode":"fn load_record_safe<P: Policy>(policy: &P, record: &P::Record) -> Result<(), &'static str> {\n    if std::any::TypeId::of::<P>() == std::any::TypeId::of::<crate::policy::AsyncPolicy<()>>() {\n        return Err(\"load_record is unimplemented on AsyncPolicy; load on the inner policy first\");\n    }\n    Ok(())\n}","typeGuard":"fn is_async_policy_marker(msg: &str) -> bool {\n    msg.contains(\"load the record on the inner policy\")\n}","tryCatchPattern":"// Rust panics are not catchable idiomatically; guard by construction:\nlet inner = base_policy.load_record(record);\nlet policy = AsyncPolicy::new(inner);","preventionTips":["Always restore records on the base policy before wrapping in AsyncPolicy.","Keep a reference to the inner policy alongside the AsyncPolicy for checkpoint ops.","Grep your code for `.load_record(` calls reachable from generic `Policy` trait objects.","Add a debug_assert or unit test that exercises your restore path."],"tags":["rust","burn-rl","unimplemented","checkpoint-restore"],"backgroundTag":"unimplemented-api-stub","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}