Skip to content

Conversation

@stbaione
Copy link
Contributor

@stbaione stbaione commented Oct 7, 2024

Description

Implementation of the op for torch.aten.unfold: TorchToLinalg Op Support #347

Documentation of op can be found here: PyTorch Docs

For this op, we apply a sliding window of some size along a single dimension, with step in between iterations.

Declaration: aten::unfold(Tensor(a) self, int dimension, int size, int step) -> Tensor(a)

The resulting unfolded tensor modifies the shape of dimension to be equal to the number of blocks that the sliding windows extracts/inserts, with an additional dimension of size appended (the number of cols of the output tensor directly translates from the size of the sliding window).

So if we had a tensor of rank 3 (A x B x C), with dimension = 1, size = 2 and step = 2:

(A x B x C) |=> (A x (B - size) // step + 1 x C x size)

After extracting the window from the input tensor, we insert the (1 x size) slice into the output tensor. We can make this simpler by mapping the output indices from the input indices, like they do in the official implementation:

PyTorch Code

Receiving error related to `torch_static_info_cast` causing the test to fail:
```torch_mlir.compiler_utils.TorchMlirCompilerError: Lowering TorchScript IR -> Torch Backend IR failed with the following diagnostics:
        error: unsupported by backend contract: tensor with unknown rank
        note: see current operation: %2 = "torch.tensor_static_info_cast"(%arg0) : (!torch.vtensor<[?,?],f32>) -> !torch.vtensor
        note: this is likely due to a missing transfer function in abstract_interp_lib_gen.py```
Move unfold from Linear.cpp -> DataMovement.cpp,
Add `AtenUnfoldOp` to isViewLikeOp in Utils.cpp,
Extend test cases for shape function,
Move test from slice_like.py to reshape_like.py,
Add test case for larger ranked tensor and negative indexing `(PASSING)`,
Add test case for dynamically sized tensor `(FAILING)`
Add support for rank-zero tensor
@stbaione stbaione marked this pull request as ready for review October 7, 2024 23:59
@renxida
Copy link
Collaborator

renxida commented Oct 8, 2024

Looks good to me! Fix the CI?

@renxida
Copy link
Collaborator

renxida commented Oct 8, 2024

CI failure, included for your convenience ``` ****** Failed tests - 3 tests FAIL - "Unfold_Module_Dynamic_basic" Compilation error: Traceback (most recent call last): File "/_work/torch-mlir/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/framework.py", line 332, in compile_and_run_test compiled = config.compile(test.program_factory(), verbose=verbose) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/_work/torch-mlir/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/configs/onnx_backend.py", line 153, in compile onnx_module = convert_onnx(program, example_args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/_work/torch-mlir/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/configs/onnx_backend.py", line 81, in convert_onnx torch.onnx.export( File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 551, in export _export( File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 1648, in _export graph, params_dict, torch_out = _model_to_graph( ^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 1170, in _model_to_graph graph, params, torch_out, module = _create_jit_graph(model, args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 1046, in _create_jit_graph graph, torch_out = _trace_and_get_graph_from_model(model, args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 950, in _trace_and_get_graph_from_model trace_graph, torch_out, inputs_states = torch.jit._get_trace_graph( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/jit/_trace.py", line 1497, in _get_trace_graph outs = ONNXTracedModule( ^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/nn/modules/module.py", line 1553, in _wrapped_call_impl return self._call_impl(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/nn/modules/module.py", line 1562, in _call_impl return forward_call(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/jit/_trace.py", line 141, in forward graph, out = torch._C._create_graph_by_tracing( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/jit/_trace.py", line 132, in wrapper outs.append(self.inner(*trace_inputs)) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/nn/modules/module.py", line 1553, in _wrapped_call_impl return self._call_impl(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/nn/modules/module.py", line 1562, in _call_impl return forward_call(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/nn/modules/module.py", line 1543, in _slow_forward result = self.forward(*input, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/_work/torch-mlir/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/test_suite/reshape_like.py", line 1725, in forward return x.unfold(1, 2, 1) ^^^^^^^^^^^^^^^^^ RuntimeError: maximum size for tensor at dimension 1 is 1 but size is 2
  FAIL - "Unfold_Module_Rank_4"
      @ trace item #0 - call to "forward"
      @ output of call to "forward"
      ERROR: shape (torch.Size([6, 4, 4, 2, 3])) is not equal to golden shape (torch.Size([6, 4, 4, 3, 2]))

  FAIL - "Unfold_Module_Rank_Zero_basic"
      Compilation error: Traceback (most recent call last):
        File "/_work/torch-mlir/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/framework.py", line 332, in compile_and_run_test
          compiled = config.compile(test.program_factory(), verbose=verbose)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/_work/torch-mlir/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/configs/onnx_backend.py", line 153, in compile
          onnx_module = convert_onnx(program, example_args)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/_work/torch-mlir/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/configs/onnx_backend.py", line 81, in convert_onnx
          torch.onnx.export(
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 551, in export
          _export(
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 1648, in _export
          graph, params_dict, torch_out = _model_to_graph(
                                          ^^^^^^^^^^^^^^^^
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 1174, in _model_to_graph
          graph = _optimize_graph(
                  ^^^^^^^^^^^^^^^^
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 714, in _optimize_graph
          graph = _C._jit_pass_onnx(graph, operator_export_type)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/utils.py", line 1997, in _run_symbolic_function
          return symbolic_fn(graph_context, *inputs, **attrs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/symbolic_helper.py", line 292, in wrapper
          return fn(g, *args, **kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^^
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/symbolic_opset12.py", line 332, in unfold
          return opset9.unfold(g, input, dimension, const_size, const_step)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/symbolic_helper.py", line 292, in wrapper
          return fn(g, *args, **kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^^
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/symbolic_opset9.py", line 3047, in unfold
          return symbolic_helper._unimplemented(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/symbolic_helper.py", line 598, in _unimplemented
          _onnx_unsupported(f"{op}, {msg}", value)
        File "/opt/python/cp311-cp311/lib/python3.11/site-packages/torch/onnx/symbolic_helper.py", line 609, in _onnx_unsupported
          raise errors.SymbolicValueError(
      torch.onnx.errors.SymbolicValueError: Unsupported: ONNX export of operator Unfold, input size not accessible. Please feel free to request support or submit a pull request on PyTorch GitHub: https://github.com/pytorch/pytorch/issues  [Caused by the value '0 defined in (%0 : Float(requires_grad=0, device=cpu) = prim::Param()
      )' (type 'Tensor') in the TorchScript graph. The containing node has kind 'prim::Param'.] 

          Inputs:
              Empty
          Outputs:
              #0: 0 defined in (%0 : Float(requires_grad=0, device=cpu) = prim::Param()
          )  (type 'Tensor')

Summary:
Passed: 879
Failed: 3
Expectedly Failed: 546

</details>

@renxida
Copy link
Collaborator

renxida commented Oct 8, 2024

(from a quick glance this is probably more an issue with onnx than us. Probably just xfail the onnx related failures?)

Copy link
Collaborator

@zjgarvey zjgarvey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach looks good. Let's try to figure out what is going on with the onnx e2e test path.

@stbaione
Copy link
Contributor Author

stbaione commented Oct 8, 2024

(from a quick glance this is probably more an issue with onnx than us. Probably just xfail the onnx related failures?)

Yeah, I'm looking through them and I think it's onnx related. For example, one of the tests fail when using a negative dimension in GH action, but if I change it locally to target the last dimension with a positive int and re-run with -c onnx option, it passes fine

Clean up `DataMovement.cpp` and handle rank = 0 with size = 0 case,
Add test for rank = 0 with size = 0,
Add shape tests for Rank-Zero case
@stbaione stbaione requested a review from zjgarvey October 8, 2024 20:41
@stbaione
Copy link
Contributor Author

stbaione commented Oct 8, 2024

(from a quick glance this is probably more an issue with onnx than us. Probably just xfail the onnx related failures?)

Verified it's an issue with onnx and added related failures to xfail

@renxida renxida enabled auto-merge (squash) October 8, 2024 20:53
@renxida renxida disabled auto-merge October 8, 2024 20:53
@renxida renxida enabled auto-merge (squash) October 8, 2024 21:02
@renxida renxida merged commit d49eabb into llvm:main Oct 8, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants