Repository: opencv
Issue: Tests are not validatable due to ONNXRuntime not supporting layout attiribute in LSTM
Labels: bug,category: dnn,category: dnn (onnx)

### System Information
Operating System / Platform: MacOS

### Detailed description


ONNXRuntime does not support `layout=1` inference. We have two tests that are designed to check funtionality of layout attribute see [[1](https://github.com/opencv/opencv/blob/67f07b16cbf7e556bc2d2861d8a586fe9e0f3fab/modules/dnn/test/test_onnx_importer.cpp#L1459)], [[2](https://github.com/opencv/opencv/blob/67f07b16cbf7e556bc2d2861d8a586fe9e0f3fab/modules/dnn/test/test_onnx_importer.cpp#L1466)]. The way these data and models for these test are generated using custom created LSTM class [[3](https://github.com/opencv/opencv_extra/blob/c2a02f61432621871112ba33c47fb0f24062d48a/testdata/dnn/onnx/generate_onnx_models.py#L1283)], which might differ form official ONNX implementation. As ONNXRuntime can not make inference, it is not obvious how to validete againts ONNXRuntime if the OpenCV performs well, as we do not have assess to reference from ONNXRutime. 



```Error log 
2024-11-13 16:23:06.229386 [E:onnxruntime:, inference_session.cc:2044 operator()] Exception during initialization: /Users/runner/work/1/s/onnxruntime/core/providers/cpu/rnn/lstm_base.h:53 onnxruntime::LSTMBase::LSTMBase(const onnxruntime::OpKernelInfo &) layout_ == 0 was false. Batchwise recurrent operations (layout == 1) are not supported. If you need support create a github issue with justification.

```

### Steps to reproduce

```python 
mport numpy as np
import onnx
from onnx import helper


if __name__ == "__main__":

    input = np.array([[[1.0, 2.0]], [[3.0, 4.0]], [[5.0, 6.0]]]).astype(np.float32)

    input_size = 2
    hidden_size = 7
    weight_scale = 0.3
    number_of_gates = 4
    layout = 1

    # Create LSTM node
    node = onnx.helper.make_node(
        "LSTM",
        inputs=["X", "W", "R"],
        outputs=["Y", "Y_h"],
        hidden_size=hidden_size,
        layout=layout,
    )

    # Create input tensors
    X = helper.make_tensor_value_info("X", onnx.TensorProto.FLOAT, [3, 1, input_size])
    W = helper.make_tensor_value_info("W", onnx.TensorProto.FLOAT, [1, number_of_gates * hidden_size, input_size])
    R = helper.make_tensor_value_info("R", onnx.TensorProto.FLOAT, [1, number_of_gates * hidden_size, hidden_size])

    # Create output tensors
    Y = helper.make_tensor_value_info("Y", onnx.TensorProto.FLOAT, [3, 1, hidden_size])
    Y_h = helper.make_tensor_value_info("Y_h", onnx.TensorProto.FLOAT, [1, 1, hidden_size])

    # Generate random weights
    W_data = (np.random.rand(1, number_of_gates * hidden_size, input_size) * weight_scale).astype(np.float32)
    R_data = (np.random.rand(1, number_of_gates * hidden_size, hidden_size) * weight_scale).astype(np.float32)

    # Create initializers for weights
    W_tensor = helper.make_tensor(
        name="W",
        data_type=onnx.TensorProto.FLOAT,
        dims=[1, number_of_gates * hidden_size, input_size],
        vals=W_data.flatten().tolist()
    )

    R_tensor = helper.make_tensor(
        name="R",
        data_type=onnx.TensorProto.FLOAT,
        dims=[1, number_of_gates * hidden_size, hidden_size],
        vals=R_data.flatten().tolist()
    )

    # Create graph with initializers
    graph = helper.make_graph(
        [node],
        "lstm_test",
        [X, W, R],
        [Y, Y_h],
        initializer=[W_tensor, R_tensor]
    )

    # Create model with specific opset version
    model = helper.make_model(
        graph,
        producer_name="lstm_layout_1",
        opset_imports=[helper.make_operatorsetid("", 14)]  # Using opset 14 which is stable
    )

    # Verify the model
    onnx.checker.check_model(model)

    # Save the model
    onnx.save(model, "lstm_layout_1.onnx")

    # Run the model using ONNX Runtime
    import onnxruntime as ort
    session = ort.InferenceSession("lstm_layout_1.onnx")
    outputs = session.run(None, {"X": input})
    print("Output sequence:", outputs[0])
    print("Final hidden state:", outputs[1])
```

### Issue submission checklist

- [X] I report the issue, it's not a question
- [X] I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
- [X] I updated to the latest OpenCV version and the issue is still there
- [X] There is reproducer code and related data files (videos, images, onnx, etc)