Skip to content

1D inputs fail on DataLayer #25070

@Abdurrahheem

Description

@Abdurrahheem

System Information

OpenCV version: 5.x
Operating System / Platform: MacOS

Detailed description

DataLayer::forward in layer_internal.hpp file

   166              bool singleMean = true;
-> 167              for (int j = 1; j < std::min(4, inputsData[i].size[1]) && singleMean; ++j)
   168              {
   169                  singleMean = mean[j] == mean[j - 1];
   170              }

When inputs are 1D this part fails inputsData[i].size[1] due to wrong memory access

Steps to reproduce

import cv2
import torch
import torch.nn as nn
import numpy as np
import torch
import torch.nn as nn

class CustomScatter(nn.Module):
    def __init__(self, dim):
        super(CustomScatter, self).__init__()
        self.dim = dim

    def forward(self, src, indices, output):
        return torch.scatter(output, self.dim, indices, src)

if __name__ == '__main__':
    name = "CustomScatter"

    # Indices tensor and source tensor
    src = torch.tensor([3])  # Source values to scatter
    indices = torch.tensor([0])  # Indices where src will be scattered
    output = torch.zeros((1), dtype=src.dtype)  # Example size

    dim = 0 # Dimension along which to scatter

    model = CustomScatter(dim=dim)

    # Note: For scatter, inputs are indices and src
    inputs = [src, indices, output]
    outputs = [model(src, indices, output)]

    print("src: ", src, "\t src shape: ", src.shape)
    print("indices: ", indices, "\t indices shape: ", indices.shape)
    print("output_size: ", output.shape , "\t dim: ", dim)
    print("output: ", outputs[0], "\t output shape: ", outputs[0].shape)

    print("\n\t\t **** TORCH INFERENCE END ****\n\n")
    # Export the model to ONNX
    torch.onnx.export(
        model,
        (src, indices, output),  # Pass both indices and src as inputs to the model
        f"{name}.onnx",
        verbose=True,
        input_names=[f"input_{i}" for i in range(len(inputs))],
        output_names=["output"],
        # dynamic_axes={'indices': {0: 'batch_size'}, 'src': {0: 'batch_size'}, 'output': {0: 'batch_size'}}
    )

    print("\n\t\t **** EXPORTED ONNX ****\n\n")


    net = cv2.dnn.readNetFromONNX(f"{name}.onnx");
    print("\n\t\t **** CV2 MODEL PARSED ****\n\n")

    for i in range(len(inputs)):
        inputs[i] = inputs[i].detach().numpy()
        inputs[i] = cv2.Mat(inputs[i])

    ## set inputs
    for i in range(len(inputs)):
        net.setInput(inputs[i], f"input_{i}")

    print("\n\t\t **** CV2 INPUTS SET ****\n\n")

    ## forward
    output_cv = net.forward()
    print("\n\t\t **** CV2 FORWARD END ****\n\n")

    # Adjust for output shape differences
    # output_cv = output_cv.reshape(outputs[0].shape)
    print("output_cv: ", output_cv, "\t output_cv shape: ", output_cv.shape)
    print("torch output: ", outputs[0], "\t torch output shape: ", outputs[0].shape)

    if np.allclose(output_cv, outputs[0], atol=1e-6):
        print("\033[92m\t\t **** TEST PASSED ****\n\n")
    else:
        print("\033[91m\t\t **** TEST FAILED ****\n\n")

Issue submission checklist

  • I report the issue, it's not a question
  • I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
  • I updated to the latest OpenCV version and the issue is still there
  • There is reproducer code and related data files (videos, images, onnx, etc)

Metadata

Metadata

Labels

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions