{"record":{"id":"4bf1bad7ae9dc441","repo":"tracel-ai/burn","slug":"reshape-would-split-a-block-across-multiple-rows","errorCode":null,"errorMessage":"Reshape would split a block across multiple rows.","messagePattern":"Reshape would split a block across multiple rows\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-cubecl/src/ops/base.rs","lineNumber":410,"sourceCode":"                    unimplemented!(\n                        \"Split reshape of ND block-quantized tensor is not yet supported.\"\n                    );\n                }\n            }\n            other => unreachable!(\"Reshape analysis {other:?} should not update strides.\"),\n        }\n    }\n\n    let shape_last = *shape.last().unwrap();\n\n    // The per-tensor scale is a scalar in its own region, so only the block grid moves.\n    let shape_scales = match scheme.block_size() {\n        None => scales.meta.shape().clone(), // always [1], invariant under reshape\n        Some(block_size) if block_size.len() == 1 && shape_last < (block_size[0] as usize) => {\n            // If the new last dimension is smaller than the block size,\n            // it means a single block now spans across multiple rows.\n            if scales.meta.shape().num_elements() > 1 {\n                unimplemented!(\"Reshape would split a block across multiple rows.\");\n            }\n            // Exception: allow if there is exactly 1 block total (essentially per-tensor quantization)\n            scales.meta.shape().clone()\n        }\n        Some(_) => {\n            // ND blocks: derive scales shape from the new tensor shape\n            params_shape(&shape, &scheme)\n        }\n    };\n\n    let action_scales = reshape_action(scales.meta.shape(), scales.meta.strides(), &shape_scales);\n\n    match (action_values, action_scales) {\n        (\n            ReshapeAction::UpdateStrides { strides },\n            ReshapeAction::UpdateStrides {\n                strides: scales_strides,\n            },","sourceCodeStart":392,"sourceCodeEnd":428,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-cubecl/src/ops/base.rs#L392-L428","documentation":"For 1D block-quantized tensors, if the reshaped last dimension becomes smaller than the block size, one quantization block would span multiple rows, which cannot be represented by per-row scales unless there is only a single block overall. When scales hold more than one block, the op panics.","triggerScenarios":"Reshaping a per-block (1D block_size, e.g. 64) quantized tensor so its last dimension shrinks below the block size (e.g. [4,256] -> [4,32] with block 64) while scales contain multiple blocks.","commonSituations":"Downsizing the feature dimension of block-quantized weights/activations; folding dimensions in custom layers that bypass quantization-aware shape planning.","solutions":["Keep the last dimension a multiple of (or >=) the block size when reshaping","Dequantize, reshape, and re-quantize with a suitable block size","Re-quantize with a smaller block size matching the new last dimension","Use per-tensor quantization if heavy reshaping is required"],"exampleFix":"// before\nlet y = x.reshape([4, 32]); // block_size=64, scales>1 -> panic\n// after\nlet y = x.dequantize().reshape([4, 32]); // or keep dim >= 64","handlingStrategy":"validation","validationCode":"fn last_dim_keeps_block(new_last: usize, block_size: Option<&[usize]>) -> bool {\n    block_size.map_or(true, |b| new_last >= b[0] as usize || new_last == 0)\n}","typeGuard":"fn block_fits_in_last_dim(new_shape: &[usize], scheme: &QuantScheme) -> bool {\n    scheme.block_size().map_or(true, |b| {\n        *new_shape.last().unwrap() >= b[0] as usize\n    })\n}","tryCatchPattern":"// Guard:\nif block_fits_in_last_dim(&new_shape, &scheme) { x.reshape(new_shape) } else { x.dequantize().reshape(new_shape) }","preventionTips":["Keep the last dim >= block size when reshaping block-quantized tensors","Re-quantize with a smaller block size after shrinking dims","Dequantize for shape-heavy transformations"],"tags":["quantization","reshape","block-quantization","unimplemented"],"backgroundTag":"reshape-splits-quantization-block","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"}