open-mmlab/mmdetection · error · ValueError

grid_points must be a square number

Error message

grid_points must be a square number

What it means

GridHead computes an integer grid_size = sqrt(grid_points) and requires grid_points to be a perfect square (>=4), e.g. 9 for a 3x3 grid. A non-square value like 8 or 12 raises ValueError in __init__.

Source

Thrown at mmdet/models/roi_heads/mask_heads/grid_head.py:88

    ) -> None:
        super().__init__(init_cfg=init_cfg)
        self.grid_points = grid_points
        self.num_convs = num_convs
        self.roi_feat_size = roi_feat_size
        self.in_channels = in_channels
        self.conv_kernel_size = conv_kernel_size
        self.point_feat_channels = point_feat_channels
        self.conv_out_channels = self.point_feat_channels * self.grid_points
        self.class_agnostic = class_agnostic
        self.conv_cfg = conv_cfg
        self.norm_cfg = norm_cfg
        if isinstance(norm_cfg, dict) and norm_cfg['type'] == 'GN':
            assert self.conv_out_channels % norm_cfg['num_groups'] == 0

        assert self.grid_points >= 4
        self.grid_size = int(np.sqrt(self.grid_points))
        if self.grid_size * self.grid_size != self.grid_points:
            raise ValueError('grid_points must be a square number')

        # the predicted heatmap is half of whole_map_size
        if not isinstance(self.roi_feat_size, int):
            raise ValueError('Only square RoIs are supporeted in Grid R-CNN')
        self.whole_map_size = self.roi_feat_size * 4

        # compute point-wise sub-regions
        self.sub_regions = self.calc_sub_regions()

        self.convs = []
        for i in range(self.num_convs):
            in_channels = (
                self.in_channels if i == 0 else self.conv_out_channels)
            stride = 2 if i == 0 else 1
            padding = (self.conv_kernel_size - 1) // 2
            self.convs.append(
                ConvModule(
                    in_channels,

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Use a perfect square >= 4: 4, 9, 16, 25 (default is 9)
  2. Adjust grid coverage via other params (e.g. num_convs, roi_feat_size) instead of non-square point counts

Example fix

# before
grid_head=dict(type='GridHead', grid_points=12)
# after
grid_head=dict(type='GridHead', grid_points=9)
Defensive patterns

Strategy: validation

Validate before calling

import math
n = cfg['grid_points']; assert math.isqrt(n) ** 2 == n and n >= 4

Type guard

def is_square_ge4(n: int) -> bool: import math; r = math.isqrt(n); return r*r == n and n >= 4

Prevention

When it happens

Trigger: grid_head=dict(type='GridHead', grid_points=8) or any grid_points whose sqrt truncation does not multiply back to itself.

Common situations: Tuning Grid R-CNN density parameters without knowing the square-number constraint; configs ported from papers using non-square grids.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27). Data as JSON: /api/errors/1992d7d152c13eef. Report an issue: GitHub.