tracel-ai/burn · error

Invalid ref layout

Error message

Invalid ref layout

What it means

`MatmulVectorSizes` derives vectorization widths for lhs/rhs/out. When the output's `RefLayout::Concrete` wraps something other than `FuseArg::Input` or `FuseArg::Output`, the vector size cannot be resolved and the code panics — a structural invariant of the fusion optimizer.

Source

Thrown at crates/burn-cubecl-fusion/src/optim/matmul/optimization.rs:429

        if matrix_batch_layout(&lhs_strides, lhs_scheme) == MatrixBatchLayout::HighlyPermuted {
            return Err(FusedMatmulError::InvalidInput(
                "Lhs needs to be contiguous, but can't when fusing.",
            ));
        }
        if matrix_batch_layout(&rhs_strides, rhs_scheme) == MatrixBatchLayout::HighlyPermuted {
            return Err(FusedMatmulError::InvalidInput(
                "Rhs needs to be contiguous, but can't when fusing.",
            ));
        }

        let mut vector_sizes = MatmulVectorSizes {
            lhs: inputs.vector_size(self.matmul.lhs.data()),
            rhs: inputs.vector_size(self.matmul.rhs.data()),
            out: match &config.ref_layout {
                RefLayout::Concrete(arg) => match arg {
                    FuseArg::Input(..) => inputs.vector_size(arg),
                    FuseArg::Output(..) => outputs.vector_size(arg),
                    _ => panic!("Invalid ref layout"),
                },
                RefLayout::Virtual(_) => 1,
            },
        };

        let address_type = inputs
            .required_address_type()
            .max(outputs.required_address_type());

        if vector_sizes.out == 1 && (vector_sizes.lhs > 1 || vector_sizes.rhs > 1) {
            return Err(FusedMatmulError::InvalidInput(
                "Output vector size of 1 removes the gain from fusion",
            ));
        }

        if let MatmulArg::Quantized { scheme, .. } = self.matmul.lhs {
            vector_sizes.lhs *= scheme.num_quants();
        }

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Ensure the matmul output arg's ref_layout is Concrete over FuseArg::Output (or Input)
  2. Audit custom provider code that sets RefLayout for the output tensor
  3. Keep all burn crates on the same version; report internal-trigger cases upstream

Example fix

// before
RefLayout::Concrete(FuseArg::Constant(..))
// after
RefLayout::Concrete(FuseArg::Output(out_pos, ..))
Defensive patterns

Strategy: validation

Validate before calling

if let RefLayout::Concrete(a) = &config.ref_layout {
    assert!(matches!(a, FuseArg::Input(..) | FuseArg::Output(..)));
}

Type guard

fn valid_vector_size_layout(l: &RefLayout) -> bool {
    matches!(l, RefLayout::Concrete(FuseArg::Input(..) | FuseArg::Output(..)) | RefLayout::Virtual(_))
}

Prevention

When it happens

Trigger: Building/running a fused matmul whose `ref_layout` is Concrete over an unexpected FuseArg variant (neither Input nor Output).

Common situations: Custom matmul optimization providers mislabeling their output arg; restored fusion states from incompatible burn versions.

Related errors


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