pytorch/test/cpp/jit
Elias Ellison de4fe7a38c Add Initial NNC Dynamic Shapes Flow (#66136)
Summary:
Pull Request resolved: https://github.com/pytorch/pytorch/pull/66136

FOR REVIEWERS: this is ready to review, test failures comes from somewhere else in stack..

Takes in a TensorExprGraph of static shapes and generalizes the input shapes
to symbolic dimensions. Dimensions of value 1 will be preserved, otherwise
dimensions with the same value will be bucketed to the same symbolic shape.

E.g. `Tensor(5, 3), Tensor(3, 1) -> Tensor(SS(-1), SS(-2)), Tensor(SS(-2), 1)`

From there, runs symbolic shape inference on the graph, and creates a
versioning if in the graph with prim::TensorExprDynamicGuard checking if
the inputs at runtime match the Generalized Symbolic Shapes that are inputs
to the TE Kernel. The computate to calculate all symbolic dimensions is
inlined in to the if block with the TE Kernel. All Sym Dim Value* are
appended to the end of the TE Kernel Graph/Node inputs, and the Node is
augmented with a integer list attr `symbolic_shape_inputs` that gives the
mapping from Value * -> Symbolic Shape int64_t value. For more lengthy IR
examples and walkthrough look at ShapeAnalysisTest.DynamicShapesFusion in
`test_shape_analysis` Returns True on Success, False on Failure, can fail if
shape propagation fails to propagate # of dims or if complete shapes on
inputs not set.

Example transformation
```
graph(%x_inp : Float(10, 5, strides=[5, 1], requires_grad=0, device=cpu),
      %y_inp : Float(4, 5, strides=[5, 1], requires_grad=0, device=cpu),
      %z_inp : Float(1, 1, strides=[1, 1], requires_grad=0, device=cpu)):
  %3 : Tensor = prim::TensorExprGroup_0(%x_inp, %y_inp, %z_inp)
  return ()
with prim::TensorExprGroup_0 = graph(%x.1 : Float(10, 5, strides=[5, 1], requires_grad=0, device=cpu),
      %y.1 : Float(4, 5, strides=[5, 1], requires_grad=0, device=cpu),
      %z : Float(1, 1, strides=[1, 1], requires_grad=0, device=cpu)):
  %3 : int = prim::Constant[value=0]()
  %4 : Tensor = aten::tanh(%x.1)
  %5 : Tensor = aten::erf(%4)
  %6 : Tensor = aten::relu(%y.1)
  %7 : Tensor[] = prim::ListConstruct(%5, %6)
  %8 : Tensor = aten::cat(%7, %3)
  %9 : Tensor = aten::hardswish(%8)
  %10 : Tensor = aten::mul(%9, %z)
  return (%9)
```
->

```
  graph(%x_inp : Float(10, 5, strides=[5, 1], requires_grad=0, device=cpu),
      %y_inp : Float(4, 5, strides=[5, 1], requires_grad=0, device=cpu),
      %z_inp : Float(1, 1, strides=[1, 1], requires_grad=0, device=cpu)):
  %4 : bool = prim::TensorExprDynamicGuard[types=[Float(SS(-2), SS(-3), strides=[5, 1], requires_grad=0, device=cpu), Float(SS(-4), SS(-3), strides=[5, 1], requires_grad=0, device=cpu), Float(1, 1, strides=[1, 1], requires_grad=0, device=cpu)]](%x_inp, %y_inp, %z_inp)
  %5 : Tensor = prim::If(%4)
    block0():
      %15 : int[] = aten::size(%x_inp)
      %16 : int[] = aten::size(%y_inp)
      %17 : int = prim::Constant[value=1]()
      %18 : int = prim::Constant[value=0]()
      %elem.3 : int = aten::__getitem__(%15, %18) # <string>:40:10
      %elem.5 : int = aten::__getitem__(%15, %17) # <string>:40:10
      %elem.11 : int = aten::__getitem__(%16, %18) # <string>:40:10
      %cat_dim_size.48 : int = aten::add(%elem.3, %elem.11) # <string>:321:29
      %3 : Tensor = prim::TensorExprGroup_0[symbolic_shape_inputs=[-5, -4, -3, -2]](%x_inp, %y_inp, %z_inp, %cat_dim_size.48, %elem.11, %elem.5, %elem.3)
      -> (%3)
    block1():
      %14 : Tensor = prim::FallbackGraph_1(%x_inp, %y_inp, %z_inp)
      -> (%14)
  return ()
  with prim::TensorExprGroup_0 = graph(%x.1 : Float(SS(-2), SS(-3), strides=[5, 1], requires_grad=0, device=cpu),
        %y.1 : Float(SS(-4), SS(-3), strides=[5, 1], requires_grad=0, device=cpu),
        %z : Float(1, 1, strides=[1, 1], requires_grad=0, device=cpu),
        %SS_5 : int,
        %SS_4 : int,
        %SS_3 : int,
        %SS_2 : int):
    %3 : int = prim::Constant[value=0]()
    %4 : Tensor(SS(-2), SS(-3)) = aten::tanh(%x.1)
    %5 : Tensor(SS(-2), SS(-3)) = aten::erf(%4)
    %6 : Tensor(SS(-4), SS(-3)) = aten::relu(%y.1)
    %7 : Tensor[] = prim::ListConstruct(%5, %6)
    %8 : Tensor(SS(-5), SS(-3)) = aten::cat(%7, %3)
    %9 : Tensor(SS(-5), SS(-3)) = aten::hardswish(%8)
    %10 : Tensor(SS(-5), SS(-3)) = aten::mul(%9, %z)
    return (%9)
```

Test Plan: Imported from OSS

Reviewed By: navahgar

Differential Revision: D31732414

Pulled By: eellison

fbshipit-source-id: 290a94a667c20467717202a43c60e4f9ca4c00e2
2021-10-19 16:41:49 -07:00
..
__init__.py
CMakeLists.txt Add Initial NNC Dynamic Shapes Flow (#66136) 2021-10-19 16:41:49 -07:00
README.md
script_module_v4.ptl
script_module_v5.ptl
script_module_v6.ptl
test_alias_analysis.cpp [JIT] Selectively enable precise alias analysis for TupleConstruct (#66025) 2021-10-01 20:42:22 -07:00
test_argument_spec.cpp
test_autodiff.cpp
test_backend.cpp [PyTorch] Add tuple inline storage (#64066) 2021-10-15 12:16:51 -07:00
test_backend_compiler_lib.cpp Back out "Revert D30710710: [Pytorch Edge] Support profiling kineto events from external source" (#66421) 2021-10-12 10:55:29 -07:00
test_backend_compiler_preprocess.cpp
test_backend_lib.cpp
test_class_import.cpp Add SourceView which doesn't own source text as base class of Source (#65309) 2021-10-18 23:17:22 -07:00
test_class_parser.cpp Add SourceView which doesn't own source text as base class of Source (#65309) 2021-10-18 23:17:22 -07:00
test_class_type.cpp
test_cleanup_passes.cpp
test_code_template.cpp
test_concat_opt.cpp [JIT] Move UseVariadicCat internals (#63577) 2021-08-23 17:30:36 -07:00
test_constant_pooling.cpp
test_create_autodiff_subgraphs.cpp
test_cs_debug_info_serialization.cpp
test_custom_class.cpp
test_custom_class_registrations.cpp
test_custom_class_registrations.h
test_custom_operators.cpp [jit] Reduce refcounting of Types (#65345) 2021-10-08 09:03:04 -07:00
test_dce.cpp
test_fuser.cpp
test_gpu.cpp Revert "Revert D30752939: [pytorch][PR] nvfuser update" (#65137) 2021-09-22 04:54:51 -07:00
test_gpu_shift.cpp Revert "Revert D30752939: [pytorch][PR] nvfuser update" (#65137) 2021-09-22 04:54:51 -07:00
test_gpu_validator.h Revert "Revert D30752939: [pytorch][PR] nvfuser update" (#65137) 2021-09-22 04:54:51 -07:00
test_graph_executor.cpp
test_graph_iterator.cpp
test_inliner.cpp
test_interface.cpp Add SourceView which doesn't own source text as base class of Source (#65309) 2021-10-18 23:17:22 -07:00
test_interpreter.cpp [PyTorch Edge] Backport function for defaults args with out args, flag on (#63651) 2021-09-20 22:50:30 -07:00
test_interpreter_async.pt
test_ir.cpp
test_irparser.cpp [jit] Reduce refcounting of Types (#65345) 2021-10-08 09:03:04 -07:00
test_jit_logging_levels.cpp Added jit log stream changing function and some refactor (#65768) 2021-09-30 23:25:11 -07:00
test_jit_type.cpp [jit] Reduce refcounting of Types (#65345) 2021-10-08 09:03:04 -07:00
test_lite_interpreter.cpp Add relative and absolute tolerances for matrix_rank, pinv (#63102) 2021-10-17 22:15:42 -07:00
test_lite_trainer.cpp
test_memory_dag.cpp
test_misc.cpp [jit] Reduce refcounting of Types (#65345) 2021-10-08 09:03:04 -07:00
test_mobile_type_parser.cpp
test_module_api.cpp Add SourceView which doesn't own source text as base class of Source (#65309) 2021-10-18 23:17:22 -07:00
test_peephole_optimize.cpp
test_qualified_name.cpp
test_save_load.cpp [PyTorch] Add tuple inline storage (#64066) 2021-10-15 12:16:51 -07:00
test_schema_matching.cpp [jit] Make operation call accept Stack& instead Stack* (#63414) 2021-08-30 11:49:20 -07:00
test_script_profile.cpp
test_shape_analysis.cpp Add Initial NNC Dynamic Shapes Flow (#66136) 2021-10-19 16:41:49 -07:00
test_stack_opt.cpp [JIT] Add variadic stack op (#63578) 2021-08-24 08:20:54 -07:00
test_subgraph_matcher.cpp
test_subgraph_rewriter.cpp keep output type after calling SubgraphRewriter (#65453) 2021-09-24 11:07:40 -07:00
test_subgraph_utils.cpp
test_union.cpp [jit] Reduce refcounting of Types (#65345) 2021-10-08 09:03:04 -07:00
test_utils.cpp [jit] Make operation call accept Stack& instead Stack* (#63414) 2021-08-30 11:49:20 -07:00
test_utils.h Enhancement for smart serialization for out schemas (#63096) 2021-08-28 11:46:27 -07:00
tests_setup.py Revert D30279364: [codemod][lint][fbcode/c*] Enable BLACK by default 2021-08-12 11:45:01 -07:00
torch_python_test.cpp

JIT C++ Tests

Adding a new test

First, create a new test file. Test files should have be placed in this directory, with a name that starts with test_, like test_foo.cpp.

In general a single test suite

Add your test file to the JIT_TEST_SRCS list in test/cpp/jit/CMakeLists.txt.

A test file may look like:

#include <gtest/gtest.h>

using namespace ::torch::jit

TEST(FooTest, BarBaz) {
   // ...
}

// Append '_CUDA' to the test case name will automatically filter it out if CUDA
// is not compiled.
TEST(FooTest, NeedsAGpu_CUDA) {
   // ...
}

// Similarly, if only one GPU is detected, tests with `_MultiCUDA` at the end
// will not be run.
TEST(FooTest, NeedsMultipleGpus_MultiCUDA) {
   // ...
}

Building and running the tests

The following commands assume you are in PyTorch root.

# ... Build PyTorch from source, e.g.
python setup.py develop
# (re)build just the binary
ninja -C build bin/test_jit
# run tests
build/bin/test_jit --gtest_filter='glob_style_filter*'