grid_sample problem

Hello experts
There is the following code in my model, but we do not support grid_sample.

features = []
        for fm in feature_maps:
            print("111111111111",fm.shape,points_2d.shape)
            features.append(
                torch.nn.functional.grid_sample(
                    fm.flatten(end_dim=1), points_2d
                )
            )
            print("222222222222222",torch.nn.functional.grid_sample(
                    fm.flatten(end_dim=1), points_2d
                ).shape)

111111111111 torch.Size([1, 6, 256, 64, 176]) torch.Size([6, 900, 13, 2])
222222222222222 torch.Size([6, 256, 900, 13])

This question has been bothering me for a long time.Do you have any suggestions regarding the replacement of grid_sample?Looking forward to your reply.

Hey @chenyao ,

This is indeed a common challenge when deploying models to environments with limited operator support. Based on your tensor shapes and use case i recommend the following :

Analysis of Your Current Setup

From your debug output, I can see you’re working with:

  • Feature maps: (1, 6, 256, 64, 176) → flattened to (6, 256, 64, 176)
  • Sampling points: (6, 900, 13, 2) in normalized coordinates [-1, 1]
  • Output shape: (6, 256, 900, 13)

Our primary recommendation is to replace grid_sample with a custom bilinear interpolation implementation using only basic tensor operations. This approach maintains mathematical equivalence while ensuring broader deployment compatibility.

import torch

def _normalize_to_img_coords(grid, H, W, align_corners=False):
    """Convert normalized grid coordinates [-1,1] to image pixel coordinates"""
    x = grid[..., 0]
    y = grid[..., 1]
    if align_corners:
        x = 0.5 * (x + 1) * (W - 1)
        y = 0.5 * (y + 1) * (H - 1)
    else:
        # PyTorch default behavior
        x = ((x + 1) * W - 1) * 0.5
        y = ((y + 1) * H - 1) * 0.5
    return x, y

def bilinear_sample_2d(x, grid, align_corners=False):
    """
    Bilinear sampling implementation equivalent to grid_sample
    Args:
        x: (N, C, H, W) feature tensor
        grid: (N, Hout, Wout, 2) sampling coordinates in [-1, 1]
        align_corners: coordinate alignment mode
    Returns:
        (N, C, Hout, Wout) sampled features
    """
    N, C, H, W = x.shape
    Hout, Wout = grid.shape[1], grid.shape[2]

    # Convert to pixel coordinates
    gx, gy = _normalize_to_img_coords(grid, H, W, align_corners)

    # Find neighboring pixels
    x0 = torch.floor(gx).long()
    y0 = torch.floor(gy).long()
    x1 = x0 + 1
    y1 = y0 + 1

    # Clamp coordinates for safe indexing
    x0c = x0.clamp(0, W - 1)
    x1c = x1.clamp(0, W - 1)
    y0c = y0.clamp(0, H - 1)
    y1c = y1.clamp(0, H - 1)

    # Calculate interpolation weights
    wx1 = (gx - x0.float()).clamp(0, 1)
    wy1 = (gy - y0.float()).clamp(0, 1)
    wx0 = 1 - wx1
    wy0 = 1 - wy1

    # Bilinear weights for four corners
    w00 = (wx0 * wy0).unsqueeze(1)
    w01 = (wx0 * wy1).unsqueeze(1)
    w10 = (wx1 * wy0).unsqueeze(1)
    w11 = (wx1 * wy1).unsqueeze(1)

    # Flatten for efficient gathering
    x_flat = x.view(N, C, H * W)

    def gather_at(ix, iy):
        idx = (iy * W + ix).view(N, 1, -1).expand(N, C, -1)
        return torch.gather(x_flat, 2, idx).view(N, C, Hout, Wout)

    # Sample at four corners
    v00 = gather_at(x0c, y0c)
    v01 = gather_at(x0c, y1c)
    v10 = gather_at(x1c, y0c)
    v11 = gather_at(x1c, y1c)

    # Bilinear interpolation
    out = w00 * v00 + w01 * v01 + w10 * v10 + w11 * v11

    # Apply boundary mask (padding_mode='zeros' equivalent)
    mask = (x0 >= 0) & (x1 < W) & (y0 >= 0) & (y1 < H)
    out = out * mask.unsqueeze(1).to(out.dtype)

    return out

Integration with Your Existing Code

Replace your current implementation as follows:

features = []
for fm in feature_maps:
    print("Feature map shape:", fm.shape, "Points shape:", points_2d.shape)
    
    # Replace grid_sample with custom bilinear sampling
    sampled = bilinear_sample_2d(
        fm.flatten(end_dim=1), 
        points_2d, 
        align_corners=False  # Match PyTorch default
    )
    features.append(sampled)
    
    print("Output shape:", sampled.shape)

Hope this helps !

Hello, thank you for your reply. After I made the changes, I still received many unsupported operators. Do you have any suggestions for modification?

 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_5: Failed to determine type of layer to create in node /head/layers.0/Reshape_5
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_15: Failed to determine type of layer to create in node /head/layers.0/Reshape_15
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_25: Failed to determine type of layer to create in node /head/layers.0/Reshape_25
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_35: Failed to determine type of layer to create in node /head/layers.0/Reshape_35
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_7: Unexpected node /head/layers.0/Unsqueeze_7 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_3: Unexpected node /head/layers.0/Unsqueeze_3 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.0/GatherElements: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_1: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_2: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_3: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_4: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_5: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_6: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_7: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_10: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_11: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_8: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_9: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_12: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_13: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_14: GatherElements operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GatherElements_15: GatherElements operation is unsupported
 UnexpectedNodeError in op /head/layers.0/Squeeze: Unexpected node /head/layers.0/Squeeze (Squeeze)
 UnsupportedSliceLayerError in op /head/layers.0/Slice_1: Failed to create slice layer at vertex /head/layers.0/Slice_1. Slice on axis 4 is not supported
 UnsupportedSliceLayerError in op /head/layers.0/Slice_2: Failed to create slice layer at vertex /head/layers.0/Slice_2. Slice on axis 4 is not supported
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_3: Failed to determine type of layer to create in node /head/layers.0/Reshape_3
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_28: Unexpected node /head/layers.0/Unsqueeze_28 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_29: Unexpected node /head/layers.0/Unsqueeze_29 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_30: Unexpected node /head/layers.0/Unsqueeze_30 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_31: Unexpected node /head/layers.0/Unsqueeze_31 (Unsqueeze)
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_44: Failed to determine type of layer to create in node /head/layers.0/Reshape_44
 UnsupportedShuffleLayerError in op /head/layers.0/Transpose: Failed to determine type of layer to create in node /head/layers.0/Transpose
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_45: Failed to determine type of layer to create in node /head/layers.0/Reshape_45
 UnsupportedOperationError in op /head/layers.0/GreaterOrEqual: GreaterOrEqual operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GreaterOrEqual_2: GreaterOrEqual operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GreaterOrEqual_4: GreaterOrEqual operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GreaterOrEqual_6: GreaterOrEqual operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GreaterOrEqual_3: GreaterOrEqual operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GreaterOrEqual_1: GreaterOrEqual operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GreaterOrEqual_5: GreaterOrEqual operation is unsupported
 UnsupportedOperationError in op /head/layers.0/GreaterOrEqual_7: GreaterOrEqual operation is unsupported
 UnsupportedOperationError in op /head/layers.0/And: And operation is unsupported
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_10: Unexpected node /head/layers.0/Unsqueeze_10 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_11: Unexpected node /head/layers.0/Unsqueeze_11 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.0/And_3: And operation is unsupported
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_15: Unexpected node /head/layers.0/Unsqueeze_15 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_16: Unexpected node /head/layers.0/Unsqueeze_16 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.0/And_6: And operation is unsupported
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_20: Unexpected node /head/layers.0/Unsqueeze_20 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_21: Unexpected node /head/layers.0/Unsqueeze_21 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.0/And_9: And operation is unsupported
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_25: Unexpected node /head/layers.0/Unsqueeze_25 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_26: Unexpected node /head/layers.0/Unsqueeze_26 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.0/And_4: And operation is unsupported
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_14: Unexpected node /head/layers.0/Unsqueeze_14 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.0/And_1: And operation is unsupported
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_9: Unexpected node /head/layers.0/Unsqueeze_9 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.0/And_7: And operation is unsupported
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_19: Unexpected node /head/layers.0/Unsqueeze_19 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.0/And_10: And operation is unsupported
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_24: Unexpected node /head/layers.0/Unsqueeze_24 (Unsqueeze)
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_46: Failed to determine type of layer to create in node /head/layers.0/Reshape_46
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_6: Failed to determine type of layer to create in node /head/layers.0/Reshape_6
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_8: Failed to determine type of layer to create in node /head/layers.0/Reshape_8
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_8: Unexpected node /head/layers.0/Unsqueeze_8 (Unsqueeze)
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_16: Failed to determine type of layer to create in node /head/layers.0/Reshape_16
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_18: Failed to determine type of layer to create in node /head/layers.0/Reshape_18
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_13: Unexpected node /head/layers.0/Unsqueeze_13 (Unsqueeze)
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_26: Failed to determine type of layer to create in node /head/layers.0/Reshape_26
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_28: Failed to determine type of layer to create in node /head/layers.0/Reshape_28
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_18: Unexpected node /head/layers.0/Unsqueeze_18 (Unsqueeze)
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_36: Failed to determine type of layer to create in node /head/layers.0/Reshape_36
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_38: Failed to determine type of layer to create in node /head/layers.0/Reshape_38
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_23: Unexpected node /head/layers.0/Unsqueeze_23 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.0/And_5: And operation is unsupported
 UnsupportedOperationError in op /head/layers.0/And_2: And operation is unsupported
 UnsupportedOperationError in op /head/layers.0/And_8: And operation is unsupported
 UnsupportedOperationError in op /head/layers.0/And_11: And operation is unsupported
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_10: Failed to determine type of layer to create in node /head/layers.0/Reshape_10
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_12: Failed to determine type of layer to create in node /head/layers.0/Reshape_12
 UnexpectedNodeError in op /head/layers.0/Expand: Unexpected node /head/layers.0/Expand (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_1: Unexpected node /head/layers.0/Expand_1 (Expand)
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_20: Failed to determine type of layer to create in node /head/layers.0/Reshape_20
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_22: Failed to determine type of layer to create in node /head/layers.0/Reshape_22
 UnexpectedNodeError in op /head/layers.0/Expand_4: Unexpected node /head/layers.0/Expand_4 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_5: Unexpected node /head/layers.0/Expand_5 (Expand)
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_30: Failed to determine type of layer to create in node /head/layers.0/Reshape_30
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_32: Failed to determine type of layer to create in node /head/layers.0/Reshape_32
 UnexpectedNodeError in op /head/layers.0/Expand_8: Unexpected node /head/layers.0/Expand_8 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_9: Unexpected node /head/layers.0/Expand_9 (Expand)
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_40: Failed to determine type of layer to create in node /head/layers.0/Reshape_40
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_42: Failed to determine type of layer to create in node /head/layers.0/Reshape_42
 UnexpectedNodeError in op /head/layers.0/Expand_12: Unexpected node /head/layers.0/Expand_12 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_13: Unexpected node /head/layers.0/Expand_13 (Expand)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_17: Unexpected node /head/layers.0/Unsqueeze_17 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_12: Unexpected node /head/layers.0/Unsqueeze_12 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_22: Unexpected node /head/layers.0/Unsqueeze_22 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_27: Unexpected node /head/layers.0/Unsqueeze_27 (Unsqueeze)
 UnexpectedNodeError in op /head/layers.0/Expand_2: Unexpected node /head/layers.0/Expand_2 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_3: Unexpected node /head/layers.0/Expand_3 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_6: Unexpected node /head/layers.0/Expand_6 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_7: Unexpected node /head/layers.0/Expand_7 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_10: Unexpected node /head/layers.0/Expand_10 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_11: Unexpected node /head/layers.0/Expand_11 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_14: Unexpected node /head/layers.0/Expand_14 (Expand)
 UnexpectedNodeError in op /head/layers.0/Expand_15: Unexpected node /head/layers.0/Expand_15 (Expand)
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_1: Unexpected node /head/layers.0/Unsqueeze_1 (Unsqueeze)
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_1: Failed to determine type of layer to create in node /head/layers.0/Reshape_1
 UnsupportedShuffleLayerError in op /head/layers.0/Reshape_2: Failed to determine type of layer to create in node /head/layers.0/Reshape_2
 UnexpectedNodeError in op /head/layers.0/Unsqueeze_32: Unexpected node /head/layers.0/Unsqueeze_32 (Unsqueeze)
 UnsupportedOperationError in op /head/layers.3/ScatterND: ScatterND operation is unsupported
 UnsupportedShuffleLayerError in op /head/layers.3/Transpose: Failed to determine type of layer to create in node /head/layers.3/Transpose
 UnsupportedShuffleLayerError in op /head/layers.3/Transpose_1: Failed to determine type of layer to create in node /head/layers.3/Transpose_1
 UnsupportedOperationError in op /head/layers.3/ScatterND_1: ScatterND operation is unsupported
Please try to parse the model again, using these start node names: /head/layers.0/GatherElements_14, /head/layers.0/GatherElements_1, /head/layers.0/GatherElements, /head/layers.0/GatherElements_5, /head/layers.0/GatherElements_11, /head/layers.0/GatherElements_6, /head/layers.0/GatherElements_9, /head/layers.0/GatherElements_3, /head/layers.0/GatherElements_12, /head/layers.0/GatherElements_8, /head/layers.0/MatMul, /head/layers.0/GatherElements_7, /head/layers.0/GatherElements_13, /head/layers.0/Div_1, /head/layers.0/GatherElements_2, /head/layers.0/GatherElements_10, /head/layers.0/GatherElements_15, /head/layers.0/GatherElements_4
Please try to parse the model again, using these end node names: /head/layers.0/MatMul, /head/layers.0/camera_encoder/camera_encoder.5/Add_1