tracel-ai/burn · error

Channels must be divisible by the number of groups. Got chan

Error message

Channels must be divisible by the number of groups. Got channels_in={}, offset_groups={}

What it means

DeformConv2d requires the input channel count to be divisible by `offset_groups`, because offsets are predicted per group of input channels. In `DeformConv2dConfig::init`, after the generic grouped-conv check, a separate check panics when `channels[0] % offset_groups != 0`.

Source

Thrown at crates/burn-nn/src/modules/conv/deform_conv2d.rs:85

    pub dilation: [usize; 2],
    /// Controls the connections between input and output channels.
    pub weight_groups: usize,
    /// Offset groups.
    pub offset_groups: usize,
    /// The padding configuration.
    #[module(skip)]
    pub padding: PaddingConfig2d,
}

impl DeformConv2dConfig {
    /// Initialize a new [DeformConv2d](DeformConv2d) module.
    pub fn init(&self, device: &Device) -> DeformConv2d {
        checks::checks_channels_div_groups(self.channels[0], self.channels[1], self.weight_groups);
        if self.padding == PaddingConfig2d::Same {
            checks::check_same_padding_support(&self.kernel_size);
        }
        if !self.channels[0].is_multiple_of(self.offset_groups) {
            panic!(
                "Channels must be divisible by the number of groups. Got \
                 channels_in={}, offset_groups={}",
                self.channels[0], self.offset_groups
            );
        }

        let shape = [
            self.channels[1],
            self.channels[0] / self.weight_groups,
            self.kernel_size[0],
            self.kernel_size[1],
        ];

        let k = self.kernel_size.iter().product::<usize>();
        let fan_in = self.channels[0] / self.weight_groups * k;
        let fan_out = self.channels[1] / self.weight_groups * k;

        let weight = self

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Set `offset_groups` to a divisor of channels_in (common values: 1, 4, 8 with channels_in a multiple of them).
  2. Change the input channel count (e.g. via an initial conv) so it is divisible by offset_groups.
  3. Set offset_groups = 1 to use a single offset group.
  4. Also ensure channels_in/channels_out are divisible by `weight_groups` (separate check that runs first).

Example fix

// before
let config = DeformConv2dConfig { channels: [3, 64], offset_groups: 8, ..Default::default() }; // 3 % 8 != 0
// after
let config = DeformConv2dConfig { channels: [3, 64], offset_groups: 1, ..Default::default() };
Defensive patterns

Strategy: validation

Validate before calling

fn validate_deform_conv(config: &DeformConv2dConfig) {
    assert!(config.channels[0].is_multiple_of(config.offset_groups),
        "channels_in={} not divisible by offset_groups={}", config.channels[0], config.offset_groups);
    assert!(config.channels[0].is_multiple_of(config.weight_groups));
    assert!(config.channels[1].is_multiple_of(config.weight_groups));
}
validate_deform_conv(&config);

Type guard

fn deform_groups_valid(channels_in: usize, channels_out: usize, offset_groups: usize, weight_groups: usize) -> bool {
    channels_in.is_multiple_of(offset_groups)
        && channels_in.is_multiple_of(weight_groups)
        && channels_out.is_multiple_of(weight_groups)
}

Try / catch

let result = std::panic::catch_unwind(|| config.init(&device));
match result {
    Ok(layer) => layer,
    Err(_) => {
        let mut c = config;
        c.offset_groups = 1;
        c.init(&device)
    }
}

Prevention

When it happens

Trigger: Building a `DeformConv2d` via `DeformConv2dConfig::init(&device)` where `channels[0]` (in channels) is not a multiple of `offset_groups`, e.g. channels=[3, 64] with offset_groups=8.

Common situations: Copying a config that used offset_groups=8 with 256-channel inputs onto an RGB 3-channel input; tuning offset_groups without updating channels; default configs mismatched with a new first layer.

Related errors


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