From 4c3d026ea64bd646a840bf174ef9d1818f10c20f Mon Sep 17 00:00:00 2001 From: Naren Dasan Date: Tue, 13 Feb 2024 17:42:49 -0800 Subject: [PATCH] chore: documentation for release Signed-off-by: Naren Dasan Signed-off-by: Naren Dasan --- docs/v2.2.0/.nojekyll | 0 .../classtorch__tensorrt_1_1DataType.html | 942 ++ ...rch__tensorrt_1_1Device_1_1DeviceType.html | 879 ++ .../classtorch__tensorrt_1_1TensorFormat.html | 911 ++ ...ensorrt_1_1ptq_1_1Int8CacheCalibrator.html | 875 ++ ...ch__tensorrt_1_1ptq_1_1Int8Calibrator.html | 885 ++ ...8h_1a18d295a837ac71add5578860b55e5502.html | 770 + ...8h_1a282fd3c0b1c3a215148ae372070e1268.html | 770 + ...8h_1a31398a6d4d27e28817afb0f0139e909e.html | 770 + ...8h_1a35703561b26b1a9d2738ad7d58b27827.html | 770 + ...8h_1abd1465eb38256d3f22cc1426b23d516b.html | 770 + ...8h_1abe87b341f562fd1cf40b7672e4d759da.html | 770 + ...8h_1ad19939408f7be171a74a89928b36eb59.html | 770 + ...8h_1adad592a7b1b7eed529cdf6acd584c883.html | 770 + docs/v2.2.0/_cpp_api/dir_cpp.html | 753 + docs/v2.2.0/_cpp_api/dir_cpp_include.html | 754 + .../dir_cpp_include_torch_tensorrt.html | 757 + ...8h_1a130f65408ad8cbaee060f05e8db69558.html | 808 + ...8h_1a3fbe5d72e4fc624dbd038853079620eb.html | 787 + ..._cpp_include_torch_tensorrt_logging.h.html | 809 + ...e_cpp_include_torch_tensorrt_macros.h.html | 795 + ...file_cpp_include_torch_tensorrt_ptq.h.html | 806 + ...clude_torch_tensorrt_torch_tensorrt.h.html | 821 + ...8h_1a0593f776f469c20469e2f729fc7861a3.html | 770 + ...8h_1a0c012cb374addd90eb1f42eaec570650.html | 776 + ...8h_1a56e110feaaba2c3fd44bd201fd21a76a.html | 776 + ...8h_1a7cb50492421ea9de4e3db895819df6f2.html | 776 + ...8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.html | 779 + ...8h_1ad2efd47b6c3689e58ccc595680579ae5.html | 776 + ...8h_1af8f3443813315af7901903d25dd495cc.html | 770 + ...8h_1a226e3c83379d1012cde8578c1c86b16c.html | 785 + ...8h_1a6186e305f47c1d94b6130ef6c7f7e178.html | 791 + ...8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.html | 785 + ...8h_1a6e19490a08fb1553c9dd347a5ae79db9.html | 785 + ...8h_1a81f9783517335dda877d8cfcf38987c9.html | 791 + ...8h_1ac4ab8313ae72c2c899ea31548b528528.html | 776 + ...8h_1ad1acd06eaeaffbbcf6e7ebf426891384.html | 776 + ...8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.html | 771 + ...8h_1ae8d56472106eeef37fbe51ff7f40c9b2.html | 785 + docs/v2.2.0/_cpp_api/namespace_torch.html | 756 + .../_cpp_api/namespace_torch_tensorrt.html | 804 + .../namespace_torch_tensorrt__logging.html | 785 + .../namespace_torch_tensorrt__ptq.html | 781 + ...namespace_torch_tensorrt__torchscript.html | 782 + ..._cpp_include_torch_tensorrt_logging.h.html | 785 + ...e_cpp_include_torch_tensorrt_macros.h.html | 784 + ...file_cpp_include_torch_tensorrt_ptq.h.html | 924 ++ ...clude_torch_tensorrt_torch_tensorrt.h.html | 1088 ++ .../structtorch__tensorrt_1_1Device.html | 927 ++ .../structtorch__tensorrt_1_1GraphInputs.html | 785 + .../structtorch__tensorrt_1_1Input.html | 1106 ++ ...ensorrt_1_1torchscript_1_1CompileSpec.html | 945 ++ docs/v2.2.0/_cpp_api/torch_tensort_cpp.html | 1152 ++ docs/v2.2.0/_cpp_api/unabridged_orphan.html | 842 ++ .../torch_compile_resnet_example.ipynb | 158 + .../torch_compile_advanced_usage.py | 107 + .../yi_jing_01_chien.jpg | Bin 0 -> 6614 bytes .../torch_compile_stable_diffusion.py | 55 + .../_rendered_examples_jupyter.zip | Bin 0 -> 18798 bytes .../_rendered_examples_python.zip | Bin 0 -> 10824 bytes .../torch_compile_advanced_usage.ipynb | 144 + .../torch_compile_stable_diffusion.ipynb | 68 + .../torch_compile_transformers_example.ipynb | 158 + .../torch_compile_resnet_example.py | 93 + .../torch_compile_transformers_example.py | 109 + docs/v2.2.0/_images/majestic_castle.png | Bin 0 -> 505948 bytes ...glr_torch_compile_advanced_usage_thumb.png | Bin 0 -> 26794 bytes ...glr_torch_compile_resnet_example_thumb.png | Bin 0 -> 26794 bytes ...r_torch_compile_stable_diffusion_thumb.png | Bin 0 -> 26794 bytes ...rch_compile_transformers_example_thumb.png | Bin 0 -> 26794 bytes docs/v2.2.0/_images/yi_jing_01_chien.jpg | Bin 0 -> 6614 bytes docs/v2.2.0/_modules/index.html | 752 + .../_modules/torch_tensorrt/_Device.html | 904 ++ .../_modules/torch_tensorrt/_Input.html | 1183 ++ .../_modules/torch_tensorrt/_compile.html | 1065 ++ .../_modules/torch_tensorrt/_utils.html | 776 + .../torch_tensorrt/dynamo/_SourceIR.html | 759 + .../torch_tensorrt/dynamo/_compiler.html | 1098 ++ .../torch_tensorrt/dynamo/_exporter.html | 1085 ++ .../torch_tensorrt/dynamo/_settings.html | 829 + .../torch_tensorrt/dynamo/_tracer.html | 822 + .../_modules/torch_tensorrt/fx/fx2trt.html | 1123 ++ .../torch_tensorrt/fx/input_tensor_spec.html | 981 ++ .../_modules/torch_tensorrt/fx/lower.html | 1056 ++ .../torch_tensorrt/fx/trt_module.html | 984 ++ .../_modules/torch_tensorrt/logging.html | 953 ++ docs/v2.2.0/_modules/torch_tensorrt/ptq.html | 955 ++ .../torch_tensorrt/ts/_compile_spec.html | 1211 ++ .../_modules/torch_tensorrt/ts/_compiler.html | 1077 ++ .../classtorch__tensorrt_1_1DataType.rst.txt | 17 + ...__tensorrt_1_1Device_1_1DeviceType.rst.txt | 23 + ...asstorch__tensorrt_1_1TensorFormat.rst.txt | 17 + ...orrt_1_1ptq_1_1Int8CacheCalibrator.rst.txt | 26 + ..._tensorrt_1_1ptq_1_1Int8Calibrator.rst.txt | 26 + ...1a18d295a837ac71add5578860b55e5502.rst.txt | 14 + ...1a282fd3c0b1c3a215148ae372070e1268.rst.txt | 14 + ...1a31398a6d4d27e28817afb0f0139e909e.rst.txt | 14 + ...1a35703561b26b1a9d2738ad7d58b27827.rst.txt | 14 + ...1abd1465eb38256d3f22cc1426b23d516b.rst.txt | 14 + ...1abe87b341f562fd1cf40b7672e4d759da.rst.txt | 14 + ...1ad19939408f7be171a74a89928b36eb59.rst.txt | 14 + ...1adad592a7b1b7eed529cdf6acd584c883.rst.txt | 14 + docs/v2.2.0/_sources/_cpp_api/dir_cpp.rst.txt | 16 + .../_sources/_cpp_api/dir_cpp_include.rst.txt | 20 + .../dir_cpp_include_torch_tensorrt.rst.txt | 23 + ...1a130f65408ad8cbaee060f05e8db69558.rst.txt | 14 + ...1a3fbe5d72e4fc624dbd038853079620eb.rst.txt | 14 + ...p_include_torch_tensorrt_logging.h.rst.txt | 80 + ...pp_include_torch_tensorrt_macros.h.rst.txt | 71 + ...e_cpp_include_torch_tensorrt_ptq.h.rst.txt | 84 + ...de_torch_tensorrt_torch_tensorrt.h.rst.txt | 105 + ...1a0593f776f469c20469e2f729fc7861a3.rst.txt | 14 + ...1a0c012cb374addd90eb1f42eaec570650.rst.txt | 14 + ...1a56e110feaaba2c3fd44bd201fd21a76a.rst.txt | 14 + ...1a7cb50492421ea9de4e3db895819df6f2.rst.txt | 14 + ...1ac46ac0901cb97e3ae6e93b45f24e90b8.rst.txt | 14 + ...1ad2efd47b6c3689e58ccc595680579ae5.rst.txt | 14 + ...1af8f3443813315af7901903d25dd495cc.rst.txt | 14 + ...1a226e3c83379d1012cde8578c1c86b16c.rst.txt | 14 + ...1a6186e305f47c1d94b6130ef6c7f7e178.rst.txt | 14 + ...1a5b405fd3bf3c8fc2e2a54cbbab979797.rst.txt | 14 + ...1a6e19490a08fb1553c9dd347a5ae79db9.rst.txt | 14 + ...1a81f9783517335dda877d8cfcf38987c9.rst.txt | 14 + ...1ac4ab8313ae72c2c899ea31548b528528.rst.txt | 14 + ...1ad1acd06eaeaffbbcf6e7ebf426891384.rst.txt | 14 + ...1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.rst.txt | 14 + ...1ae8d56472106eeef37fbe51ff7f40c9b2.rst.txt | 14 + .../_sources/_cpp_api/namespace_torch.rst.txt | 13 + .../_cpp_api/namespace_torch_tensorrt.rst.txt | 59 + .../namespace_torch_tensorrt__logging.rst.txt | 39 + .../namespace_torch_tensorrt__ptq.rst.txt | 31 + ...espace_torch_tensorrt__torchscript.rst.txt | 33 + ...p_include_torch_tensorrt_logging.h.rst.txt | 51 + ...pp_include_torch_tensorrt_macros.h.rst.txt | 50 + ...e_cpp_include_torch_tensorrt_ptq.h.rst.txt | 190 + ...de_torch_tensorrt_torch_tensorrt.h.rst.txt | 354 + .../structtorch__tensorrt_1_1Device.rst.txt | 27 + ...ructtorch__tensorrt_1_1GraphInputs.rst.txt | 17 + .../structtorch__tensorrt_1_1Input.rst.txt | 26 + ...orrt_1_1torchscript_1_1CompileSpec.rst.txt | 17 + .../_cpp_api/torch_tensort_cpp.rst.txt | 10 + .../_cpp_api/unabridged_orphan.rst.txt | 48 + docs/v2.2.0/_sources/cli/torchtrtc.rst.txt | 149 + .../_sources/contributors/conversion.rst.txt | 53 + .../contributors/dynamo_converters.rst.txt | 131 + .../_sources/contributors/lowering.rst.txt | 214 + .../contributors/partitioning.rst.txt | 241 + .../_sources/contributors/phases.rst.txt | 46 + .../_sources/contributors/runtime.rst.txt | 85 + .../contributors/system_overview.rst.txt | 29 + .../contributors/ts_converters.rst.txt | 129 + .../contributors/useful_links.rst.txt | 34 + ...riting_dynamo_aten_lowering_passes.rst.txt | 109 + .../_sources/dynamo/dynamo_export.rst.txt | 75 + .../_sources/dynamo/torch_compile.rst.txt | 110 + .../fx/getting_started_with_fx_path.rst.txt | 333 + .../getting_started_with_windows.rst.txt | 147 + .../getting_started/installation.rst.txt | 317 + docs/v2.2.0/_sources/index.rst.txt | 210 + .../_sources/indices/supported_ops.rst.txt | 285 + docs/v2.2.0/_sources/py_api/dynamo.rst.txt | 36 + docs/v2.2.0/_sources/py_api/fx.rst.txt | 31 + docs/v2.2.0/_sources/py_api/logging.rst.txt | 13 + docs/v2.2.0/_sources/py_api/ptq.rst.txt | 27 + .../_sources/py_api/torch_tensorrt.rst.txt | 65 + docs/v2.2.0/_sources/py_api/ts.rst.txt | 27 + .../docs/changelog.rst.txt | 6 + .../docs/configuring.rst.txt | 108 + .../docs/demo/api.rst.txt | 53 + .../docs/demo/demo.rst.txt | 475 + .../docs/demo/lists_tables.rst.txt | 302 + .../docs/demo/long.rst.txt | 214 + .../docs/demo/structure.rst.txt | 101 + .../pytorch-sphinx-theme/docs/index.rst.txt | 27 + .../docs/installing.rst.txt | 17 + ...ating_torchscript_module_in_python.rst.txt | 140 + .../ts/getting_started_with_cpp_api.rst.txt | 340 + .../getting_started_with_python_api.rst.txt | 82 + .../torchscript_frontend_from_pytorch.rst.txt | 64 + .../_rendered_examples/dynamo/index.rst.txt | 105 + .../torch_compile_advanced_usage.rst.txt | 197 + .../torch_compile_resnet_example.rst.txt | 187 + .../torch_compile_stable_diffusion.rst.txt | 116 + ...torch_compile_transformers_example.rst.txt | 203 + .../_rendered_examples/index.rst.txt | 139 + .../_sources/tutorials/notebooks.rst.txt | 154 + ...serving_torch_tensorrt_with_triton.rst.txt | 216 + .../user_guide/dynamic_shapes.rst.txt | 209 + docs/v2.2.0/_sources/user_guide/ptq.rst.txt | 205 + .../_sources/user_guide/runtime.rst.txt | 70 + .../_sources/user_guide/saving_models.rst.txt | 101 + .../_sources/user_guide/using_dla.rst.txt | 47 + docs/v2.2.0/_static/basic.css | 906 ++ docs/v2.2.0/_static/binder_badge_logo.svg | 1 + docs/v2.2.0/_static/broken_example.png | Bin 0 -> 21404 bytes .../_static/collapsible-lists/LICENSE.md | 7 + .../collapsible-lists/css/button-closed.png | Bin 0 -> 256 bytes .../collapsible-lists/css/button-open.png | Bin 0 -> 240 bytes .../_static/collapsible-lists/css/button.png | Bin 0 -> 230 bytes .../css/list-item-contents.png | Bin 0 -> 147 bytes .../css/list-item-last-open.png | Bin 0 -> 161 bytes .../collapsible-lists/css/list-item-last.png | Bin 0 -> 160 bytes .../collapsible-lists/css/list-item-open.png | Bin 0 -> 160 bytes .../collapsible-lists/css/list-item-root.png | Bin 0 -> 145 bytes .../collapsible-lists/css/list-item.png | Bin 0 -> 157 bytes .../collapsible-lists/css/tree_view.css | 61 + .../js/CollapsibleLists.compressed.js | 83 + .../js/apply-collapsible-lists.js | 3 + docs/v2.2.0/_static/css/custom.css | 8 + docs/v2.2.0/_static/css/pytorch_theme.css | 127 + docs/v2.2.0/_static/css/theme.css | 12483 ++++++++++++++++ docs/v2.2.0/_static/doctools.js | 358 + docs/v2.2.0/_static/documentation_options.js | 14 + docs/v2.2.0/_static/file.png | Bin 0 -> 286 bytes .../FreightSans/freight-sans-bold-italic.woff | Bin 0 -> 39560 bytes .../freight-sans-bold-italic.woff2 | Bin 0 -> 31812 bytes .../fonts/FreightSans/freight-sans-bold.woff | Bin 0 -> 32396 bytes .../fonts/FreightSans/freight-sans-bold.woff2 | Bin 0 -> 25672 bytes .../FreightSans/freight-sans-book-italic.woff | Bin 0 -> 33944 bytes .../freight-sans-book-italic.woff2 | Bin 0 -> 26832 bytes .../fonts/FreightSans/freight-sans-book.woff | Bin 0 -> 31612 bytes .../fonts/FreightSans/freight-sans-book.woff2 | Bin 0 -> 25120 bytes .../freight-sans-light-italic.woff | Bin 0 -> 29304 bytes .../freight-sans-light-italic.woff2 | Bin 0 -> 22720 bytes .../fonts/FreightSans/freight-sans-light.woff | Bin 0 -> 26908 bytes .../FreightSans/freight-sans-light.woff2 | Bin 0 -> 21012 bytes .../freight-sans-medium-italic.woff | Bin 0 -> 19420 bytes .../freight-sans-medium-italic.woff2 | Bin 0 -> 16000 bytes .../FreightSans/freight-sans-medium.woff | Bin 0 -> 32072 bytes .../FreightSans/freight-sans-medium.woff2 | Bin 0 -> 25460 bytes .../fonts/IBMPlexMono/IBMPlexMono-Light.woff | Bin 0 -> 50680 bytes .../fonts/IBMPlexMono/IBMPlexMono-Light.woff2 | Bin 0 -> 35916 bytes .../fonts/IBMPlexMono/IBMPlexMono-Medium.woff | Bin 0 -> 51872 bytes .../IBMPlexMono/IBMPlexMono-Medium.woff2 | Bin 0 -> 36648 bytes .../IBMPlexMono/IBMPlexMono-Regular.woff | Bin 0 -> 50664 bytes .../IBMPlexMono/IBMPlexMono-Regular.woff2 | Bin 0 -> 35536 bytes .../IBMPlexMono/IBMPlexMono-SemiBold.woff | Bin 0 -> 52936 bytes .../IBMPlexMono/IBMPlexMono-SemiBold.woff2 | Bin 0 -> 37592 bytes .../_static/images/arrow-down-orange.svg | 19 + .../_static/images/arrow-right-with-tail.svg | 19 + .../_static/images/chevron-down-black.svg | 16 + .../_static/images/chevron-down-grey.svg | 18 + .../_static/images/chevron-down-orange.svg | 16 + .../_static/images/chevron-down-white.svg | 16 + .../_static/images/chevron-right-orange.svg | 17 + .../_static/images/chevron-right-white.svg | 17 + .../_static/images/home-footer-background.jpg | Bin 0 -> 38907 bytes docs/v2.2.0/_static/images/icon-close.svg | 21 + .../_static/images/icon-menu-dots-dark.svg | 42 + docs/v2.2.0/_static/images/logo-dark.svg | 30 + .../_static/images/logo-facebook-dark.svg | 8 + docs/v2.2.0/_static/images/logo-icon.svg | 12 + .../_static/images/logo-twitter-dark.svg | 16 + .../_static/images/logo-youtube-dark.svg | 21 + docs/v2.2.0/_static/images/logo.svg | 31 + docs/v2.2.0/_static/images/pytorch-colab.svg | 24 + .../_static/images/pytorch-download.svg | 10 + docs/v2.2.0/_static/images/pytorch-github.svg | 15 + docs/v2.2.0/_static/images/pytorch-x.svg | 10 + docs/v2.2.0/_static/images/search-icon.svg | 19 + .../_static/images/view-page-source-icon.svg | 13 + docs/v2.2.0/_static/jquery-3.5.1.js | 10872 ++++++++++++++ docs/v2.2.0/_static/jquery.js | 2 + docs/v2.2.0/_static/js/modernizr.min.js | 4 + docs/v2.2.0/_static/js/theme.js | 1128 ++ docs/v2.2.0/_static/js/vendor/anchor.min.js | 9 + .../v2.2.0/_static/js/vendor/bootstrap.min.js | 7 + docs/v2.2.0/_static/js/vendor/popper.min.js | 5 + .../v2.2.0/_static/jupyterlite_badge_logo.svg | 3 + docs/v2.2.0/_static/language_data.js | 297 + docs/v2.2.0/_static/minus.png | Bin 0 -> 90 bytes docs/v2.2.0/_static/no_image.png | Bin 0 -> 4315 bytes docs/v2.2.0/_static/plus.png | Bin 0 -> 90 bytes docs/v2.2.0/_static/pygments.css | 75 + docs/v2.2.0/_static/searchtools.js | 525 + docs/v2.2.0/_static/sg_gallery-binder.css | 11 + docs/v2.2.0/_static/sg_gallery-dataframe.css | 46 + .../_static/sg_gallery-rendered-html.css | 224 + docs/v2.2.0/_static/sg_gallery.css | 342 + docs/v2.2.0/_static/underscore-1.13.1.js | 2042 +++ docs/v2.2.0/_static/underscore.js | 6 + docs/v2.2.0/cli/torchtrtc.html | 893 ++ docs/v2.2.0/contributors/conversion.html | 813 + .../contributors/dynamo_converters.html | 880 ++ docs/v2.2.0/contributors/lowering.html | 983 ++ docs/v2.2.0/contributors/partitioning.html | 980 ++ docs/v2.2.0/contributors/phases.html | 781 + docs/v2.2.0/contributors/runtime.html | 833 ++ docs/v2.2.0/contributors/system_overview.html | 817 + docs/v2.2.0/contributors/ts_converters.html | 888 ++ docs/v2.2.0/contributors/useful_links.html | 798 + .../writing_dynamo_aten_lowering_passes.html | 852 ++ docs/v2.2.0/dynamo/dynamo_export.html | 823 + docs/v2.2.0/dynamo/torch_compile.html | 903 ++ .../fx/getting_started_with_fx_path.html | 1058 ++ docs/v2.2.0/genindex.html | 1338 ++ .../getting_started_with_windows.html | 917 ++ docs/v2.2.0/getting_started/installation.html | 1086 ++ docs/v2.2.0/index.html | 901 ++ docs/v2.2.0/indices/supported_ops.html | 1044 ++ docs/v2.2.0/objects.inv | Bin 0 -> 28629 bytes docs/v2.2.0/py-modindex.html | 778 + docs/v2.2.0/py_api/dynamo.html | 952 ++ docs/v2.2.0/py_api/fx.html | 831 + docs/v2.2.0/py_api/logging.html | 957 ++ docs/v2.2.0/py_api/ptq.html | 876 ++ docs/v2.2.0/py_api/torch_tensorrt.html | 1135 ++ docs/v2.2.0/py_api/ts.html | 1028 ++ docs/v2.2.0/search.html | 751 + docs/v2.2.0/searchindex.js | 1 + .../pytorch-sphinx-theme/docs/changelog.html | 744 + .../docs/configuring.html | 847 ++ .../pytorch-sphinx-theme/docs/demo/api.html | 798 + .../pytorch-sphinx-theme/docs/demo/demo.html | 1354 ++ .../docs/demo/lists_tables.html | 1329 ++ .../pytorch-sphinx-theme/docs/demo/long.html | 1008 ++ .../docs/demo/structure.html | 877 ++ .../src/pytorch-sphinx-theme/docs/index.html | 834 ++ .../pytorch-sphinx-theme/docs/installing.html | 756 + ...creating_torchscript_module_in_python.html | 871 ++ .../ts/getting_started_with_cpp_api.html | 1047 ++ .../ts/getting_started_with_python_api.html | 824 + .../ts/torchscript_frontend_from_pytorch.html | 791 + .../_rendered_examples/dynamo/index.html | 765 + .../dynamo/torch_compile_advanced_usage.html | 871 ++ .../dynamo/torch_compile_resnet_example.html | 859 ++ .../torch_compile_stable_diffusion.html | 816 + .../torch_compile_transformers_example.html | 874 ++ .../tutorials/_rendered_examples/index.html | 782 + docs/v2.2.0/tutorials/notebooks.html | 906 ++ .../serving_torch_tensorrt_with_triton.html | 937 ++ docs/v2.2.0/user_guide/dynamic_shapes.html | 943 ++ docs/v2.2.0/user_guide/ptq.html | 932 ++ docs/v2.2.0/user_guide/runtime.html | 820 + docs/v2.2.0/user_guide/saving_models.html | 844 ++ docs/v2.2.0/user_guide/using_dla.html | 788 + py/ci/Dockerfile.ci | 4 +- py/ci/soname_excludes.params | 3 + .../WORKSPACE.x86_64.cu118.release.rhel | 8 +- .../WORKSPACE.x86_64.cu121.release.rhel | 8 +- 340 files changed, 148758 insertions(+), 10 deletions(-) create mode 100644 docs/v2.2.0/.nojekyll create mode 100644 docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1DataType.html create mode 100644 docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType.html create mode 100644 docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1TensorFormat.html create mode 100644 docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator.html create mode 100644 docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator.html create mode 100644 docs/v2.2.0/_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502.html create mode 100644 docs/v2.2.0/_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268.html create mode 100644 docs/v2.2.0/_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e.html create mode 100644 docs/v2.2.0/_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827.html create mode 100644 docs/v2.2.0/_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b.html create mode 100644 docs/v2.2.0/_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da.html create mode 100644 docs/v2.2.0/_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59.html create mode 100644 docs/v2.2.0/_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883.html create mode 100644 docs/v2.2.0/_cpp_api/dir_cpp.html create mode 100644 docs/v2.2.0/_cpp_api/dir_cpp_include.html create mode 100644 docs/v2.2.0/_cpp_api/dir_cpp_include_torch_tensorrt.html create mode 100644 docs/v2.2.0/_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558.html create mode 100644 docs/v2.2.0/_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb.html create mode 100644 docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_logging.h.html create mode 100644 docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_macros.h.html create mode 100644 docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_ptq.h.html create mode 100644 docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h.html create mode 100644 docs/v2.2.0/_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3.html create mode 100644 docs/v2.2.0/_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650.html create mode 100644 docs/v2.2.0/_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a.html create mode 100644 docs/v2.2.0/_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2.html create mode 100644 docs/v2.2.0/_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.html create mode 100644 docs/v2.2.0/_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5.html create mode 100644 docs/v2.2.0/_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc.html create mode 100644 docs/v2.2.0/_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c.html create mode 100644 docs/v2.2.0/_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178.html create mode 100644 docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.html create mode 100644 docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9.html create mode 100644 docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9.html create mode 100644 docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528.html create mode 100644 docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384.html create mode 100644 docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.html create mode 100644 docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2.html create mode 100644 docs/v2.2.0/_cpp_api/namespace_torch.html create mode 100644 docs/v2.2.0/_cpp_api/namespace_torch_tensorrt.html create mode 100644 docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__logging.html create mode 100644 docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__ptq.html create mode 100644 docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__torchscript.html create mode 100644 docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h.html create mode 100644 docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h.html create mode 100644 docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h.html create mode 100644 docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.html create mode 100644 docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1Device.html create mode 100644 docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1GraphInputs.html create mode 100644 docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1Input.html create mode 100644 docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec.html create mode 100644 docs/v2.2.0/_cpp_api/torch_tensort_cpp.html create mode 100644 docs/v2.2.0/_cpp_api/unabridged_orphan.html create mode 100644 docs/v2.2.0/_downloads/0daf1d0af656cac7b808856b71e6616f/torch_compile_resnet_example.ipynb create mode 100644 docs/v2.2.0/_downloads/0e30a6276601af7e5fc4d5166e2e3d37/torch_compile_advanced_usage.py create mode 100644 docs/v2.2.0/_downloads/26d49aeeb9c710e27197fda28b7c3516/yi_jing_01_chien.jpg create mode 100644 docs/v2.2.0/_downloads/46b3e6febaab06324aa2715896895544/torch_compile_stable_diffusion.py create mode 100644 docs/v2.2.0/_downloads/6a6052d9668b2cb8332d349d328e21c1/_rendered_examples_jupyter.zip create mode 100644 docs/v2.2.0/_downloads/798cda8f83bd9f5e2cc93f329a04332c/_rendered_examples_python.zip create mode 100644 docs/v2.2.0/_downloads/b35883282793ac3413933fdb22d00d81/torch_compile_advanced_usage.ipynb create mode 100644 docs/v2.2.0/_downloads/b776287bc876f7ce24942b82a66beb05/torch_compile_stable_diffusion.ipynb create mode 100644 docs/v2.2.0/_downloads/ce102e287ddb5744f0a1364e8c0c7f68/torch_compile_transformers_example.ipynb create mode 100644 docs/v2.2.0/_downloads/d6e1bb6ec5f884994554d9d12e37a0f6/torch_compile_resnet_example.py create mode 100644 docs/v2.2.0/_downloads/dfa60e8f9850fd7761f3e7da81304d32/torch_compile_transformers_example.py create mode 100644 docs/v2.2.0/_images/majestic_castle.png create mode 100644 docs/v2.2.0/_images/sphx_glr_torch_compile_advanced_usage_thumb.png create mode 100644 docs/v2.2.0/_images/sphx_glr_torch_compile_resnet_example_thumb.png create mode 100644 docs/v2.2.0/_images/sphx_glr_torch_compile_stable_diffusion_thumb.png create mode 100644 docs/v2.2.0/_images/sphx_glr_torch_compile_transformers_example_thumb.png create mode 100644 docs/v2.2.0/_images/yi_jing_01_chien.jpg create mode 100644 docs/v2.2.0/_modules/index.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/_Device.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/_Input.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/_compile.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/_utils.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/dynamo/_SourceIR.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/dynamo/_compiler.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/dynamo/_exporter.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/dynamo/_settings.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/dynamo/_tracer.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/fx/fx2trt.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/fx/input_tensor_spec.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/fx/lower.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/fx/trt_module.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/logging.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/ptq.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/ts/_compile_spec.html create mode 100644 docs/v2.2.0/_modules/torch_tensorrt/ts/_compiler.html create mode 100644 docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1DataType.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1TensorFormat.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/dir_cpp.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/dir_cpp_include.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/dir_cpp_include_torch_tensorrt.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_logging.h.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_macros.h.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_ptq.h.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/namespace_torch.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__logging.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__ptq.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__torchscript.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1Device.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1GraphInputs.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1Input.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/torch_tensort_cpp.rst.txt create mode 100644 docs/v2.2.0/_sources/_cpp_api/unabridged_orphan.rst.txt create mode 100644 docs/v2.2.0/_sources/cli/torchtrtc.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/conversion.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/dynamo_converters.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/lowering.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/partitioning.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/phases.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/runtime.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/system_overview.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/ts_converters.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/useful_links.rst.txt create mode 100644 docs/v2.2.0/_sources/contributors/writing_dynamo_aten_lowering_passes.rst.txt create mode 100644 docs/v2.2.0/_sources/dynamo/dynamo_export.rst.txt create mode 100644 docs/v2.2.0/_sources/dynamo/torch_compile.rst.txt create mode 100644 docs/v2.2.0/_sources/fx/getting_started_with_fx_path.rst.txt create mode 100644 docs/v2.2.0/_sources/getting_started/getting_started_with_windows.rst.txt create mode 100644 docs/v2.2.0/_sources/getting_started/installation.rst.txt create mode 100644 docs/v2.2.0/_sources/index.rst.txt create mode 100644 docs/v2.2.0/_sources/indices/supported_ops.rst.txt create mode 100644 docs/v2.2.0/_sources/py_api/dynamo.rst.txt create mode 100644 docs/v2.2.0/_sources/py_api/fx.rst.txt create mode 100644 docs/v2.2.0/_sources/py_api/logging.rst.txt create mode 100644 docs/v2.2.0/_sources/py_api/ptq.rst.txt create mode 100644 docs/v2.2.0/_sources/py_api/torch_tensorrt.rst.txt create mode 100644 docs/v2.2.0/_sources/py_api/ts.rst.txt create mode 100644 docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/changelog.rst.txt create mode 100644 docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/configuring.rst.txt create mode 100644 docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/api.rst.txt create mode 100644 docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/demo.rst.txt create mode 100644 docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/lists_tables.rst.txt create mode 100644 docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/long.rst.txt create mode 100644 docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/structure.rst.txt create mode 100644 docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/index.rst.txt create mode 100644 docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/installing.rst.txt create mode 100644 docs/v2.2.0/_sources/ts/creating_torchscript_module_in_python.rst.txt create mode 100644 docs/v2.2.0/_sources/ts/getting_started_with_cpp_api.rst.txt create mode 100644 docs/v2.2.0/_sources/ts/getting_started_with_python_api.rst.txt create mode 100644 docs/v2.2.0/_sources/ts/torchscript_frontend_from_pytorch.rst.txt create mode 100644 docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/index.rst.txt create mode 100644 docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.rst.txt create mode 100644 docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.rst.txt create mode 100644 docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.rst.txt create mode 100644 docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.rst.txt create mode 100644 docs/v2.2.0/_sources/tutorials/_rendered_examples/index.rst.txt create mode 100644 docs/v2.2.0/_sources/tutorials/notebooks.rst.txt create mode 100644 docs/v2.2.0/_sources/tutorials/serving_torch_tensorrt_with_triton.rst.txt create mode 100644 docs/v2.2.0/_sources/user_guide/dynamic_shapes.rst.txt create mode 100644 docs/v2.2.0/_sources/user_guide/ptq.rst.txt create mode 100644 docs/v2.2.0/_sources/user_guide/runtime.rst.txt create mode 100644 docs/v2.2.0/_sources/user_guide/saving_models.rst.txt create mode 100644 docs/v2.2.0/_sources/user_guide/using_dla.rst.txt create mode 100644 docs/v2.2.0/_static/basic.css create mode 100644 docs/v2.2.0/_static/binder_badge_logo.svg create mode 100644 docs/v2.2.0/_static/broken_example.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/LICENSE.md create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/button-closed.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/button-open.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/button.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/list-item-contents.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/list-item-last-open.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/list-item-last.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/list-item-open.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/list-item-root.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/list-item.png create mode 100644 docs/v2.2.0/_static/collapsible-lists/css/tree_view.css create mode 100644 docs/v2.2.0/_static/collapsible-lists/js/CollapsibleLists.compressed.js create mode 100644 docs/v2.2.0/_static/collapsible-lists/js/apply-collapsible-lists.js create mode 100644 docs/v2.2.0/_static/css/custom.css create mode 100644 docs/v2.2.0/_static/css/pytorch_theme.css create mode 100644 docs/v2.2.0/_static/css/theme.css create mode 100644 docs/v2.2.0/_static/doctools.js create mode 100644 docs/v2.2.0/_static/documentation_options.js create mode 100644 docs/v2.2.0/_static/file.png create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-bold-italic.woff create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-bold-italic.woff2 create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-bold.woff create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-bold.woff2 create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-book-italic.woff create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-book-italic.woff2 create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-book.woff create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-book.woff2 create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-light-italic.woff create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-light-italic.woff2 create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-light.woff create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-light.woff2 create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium-italic.woff create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium-italic.woff2 create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium.woff create mode 100644 docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium.woff2 create mode 100644 docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Light.woff create mode 100644 docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Light.woff2 create mode 100644 docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Medium.woff create mode 100644 docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Medium.woff2 create mode 100644 docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Regular.woff create mode 100644 docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Regular.woff2 create mode 100644 docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff create mode 100644 docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff2 create mode 100644 docs/v2.2.0/_static/images/arrow-down-orange.svg create mode 100644 docs/v2.2.0/_static/images/arrow-right-with-tail.svg create mode 100644 docs/v2.2.0/_static/images/chevron-down-black.svg create mode 100644 docs/v2.2.0/_static/images/chevron-down-grey.svg create mode 100644 docs/v2.2.0/_static/images/chevron-down-orange.svg create mode 100644 docs/v2.2.0/_static/images/chevron-down-white.svg create mode 100644 docs/v2.2.0/_static/images/chevron-right-orange.svg create mode 100644 docs/v2.2.0/_static/images/chevron-right-white.svg create mode 100644 docs/v2.2.0/_static/images/home-footer-background.jpg create mode 100644 docs/v2.2.0/_static/images/icon-close.svg create mode 100644 docs/v2.2.0/_static/images/icon-menu-dots-dark.svg create mode 100644 docs/v2.2.0/_static/images/logo-dark.svg create mode 100644 docs/v2.2.0/_static/images/logo-facebook-dark.svg create mode 100644 docs/v2.2.0/_static/images/logo-icon.svg create mode 100644 docs/v2.2.0/_static/images/logo-twitter-dark.svg create mode 100644 docs/v2.2.0/_static/images/logo-youtube-dark.svg create mode 100644 docs/v2.2.0/_static/images/logo.svg create mode 100644 docs/v2.2.0/_static/images/pytorch-colab.svg create mode 100644 docs/v2.2.0/_static/images/pytorch-download.svg create mode 100644 docs/v2.2.0/_static/images/pytorch-github.svg create mode 100644 docs/v2.2.0/_static/images/pytorch-x.svg create mode 100644 docs/v2.2.0/_static/images/search-icon.svg create mode 100644 docs/v2.2.0/_static/images/view-page-source-icon.svg create mode 100644 docs/v2.2.0/_static/jquery-3.5.1.js create mode 100644 docs/v2.2.0/_static/jquery.js create mode 100644 docs/v2.2.0/_static/js/modernizr.min.js create mode 100644 docs/v2.2.0/_static/js/theme.js create mode 100644 docs/v2.2.0/_static/js/vendor/anchor.min.js create mode 100644 docs/v2.2.0/_static/js/vendor/bootstrap.min.js create mode 100644 docs/v2.2.0/_static/js/vendor/popper.min.js create mode 100644 docs/v2.2.0/_static/jupyterlite_badge_logo.svg create mode 100644 docs/v2.2.0/_static/language_data.js create mode 100644 docs/v2.2.0/_static/minus.png create mode 100644 docs/v2.2.0/_static/no_image.png create mode 100644 docs/v2.2.0/_static/plus.png create mode 100644 docs/v2.2.0/_static/pygments.css create mode 100644 docs/v2.2.0/_static/searchtools.js create mode 100644 docs/v2.2.0/_static/sg_gallery-binder.css create mode 100644 docs/v2.2.0/_static/sg_gallery-dataframe.css create mode 100644 docs/v2.2.0/_static/sg_gallery-rendered-html.css create mode 100644 docs/v2.2.0/_static/sg_gallery.css create mode 100644 docs/v2.2.0/_static/underscore-1.13.1.js create mode 100644 docs/v2.2.0/_static/underscore.js create mode 100644 docs/v2.2.0/cli/torchtrtc.html create mode 100644 docs/v2.2.0/contributors/conversion.html create mode 100644 docs/v2.2.0/contributors/dynamo_converters.html create mode 100644 docs/v2.2.0/contributors/lowering.html create mode 100644 docs/v2.2.0/contributors/partitioning.html create mode 100644 docs/v2.2.0/contributors/phases.html create mode 100644 docs/v2.2.0/contributors/runtime.html create mode 100644 docs/v2.2.0/contributors/system_overview.html create mode 100644 docs/v2.2.0/contributors/ts_converters.html create mode 100644 docs/v2.2.0/contributors/useful_links.html create mode 100644 docs/v2.2.0/contributors/writing_dynamo_aten_lowering_passes.html create mode 100644 docs/v2.2.0/dynamo/dynamo_export.html create mode 100644 docs/v2.2.0/dynamo/torch_compile.html create mode 100644 docs/v2.2.0/fx/getting_started_with_fx_path.html create mode 100644 docs/v2.2.0/genindex.html create mode 100644 docs/v2.2.0/getting_started/getting_started_with_windows.html create mode 100644 docs/v2.2.0/getting_started/installation.html create mode 100644 docs/v2.2.0/index.html create mode 100644 docs/v2.2.0/indices/supported_ops.html create mode 100644 docs/v2.2.0/objects.inv create mode 100644 docs/v2.2.0/py-modindex.html create mode 100644 docs/v2.2.0/py_api/dynamo.html create mode 100644 docs/v2.2.0/py_api/fx.html create mode 100644 docs/v2.2.0/py_api/logging.html create mode 100644 docs/v2.2.0/py_api/ptq.html create mode 100644 docs/v2.2.0/py_api/torch_tensorrt.html create mode 100644 docs/v2.2.0/py_api/ts.html create mode 100644 docs/v2.2.0/search.html create mode 100644 docs/v2.2.0/searchindex.js create mode 100644 docs/v2.2.0/src/pytorch-sphinx-theme/docs/changelog.html create mode 100644 docs/v2.2.0/src/pytorch-sphinx-theme/docs/configuring.html create mode 100644 docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/api.html create mode 100644 docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/demo.html create mode 100644 docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/lists_tables.html create mode 100644 docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/long.html create mode 100644 docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/structure.html create mode 100644 docs/v2.2.0/src/pytorch-sphinx-theme/docs/index.html create mode 100644 docs/v2.2.0/src/pytorch-sphinx-theme/docs/installing.html create mode 100644 docs/v2.2.0/ts/creating_torchscript_module_in_python.html create mode 100644 docs/v2.2.0/ts/getting_started_with_cpp_api.html create mode 100644 docs/v2.2.0/ts/getting_started_with_python_api.html create mode 100644 docs/v2.2.0/ts/torchscript_frontend_from_pytorch.html create mode 100644 docs/v2.2.0/tutorials/_rendered_examples/dynamo/index.html create mode 100644 docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.html create mode 100644 docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.html create mode 100644 docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.html create mode 100644 docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.html create mode 100644 docs/v2.2.0/tutorials/_rendered_examples/index.html create mode 100644 docs/v2.2.0/tutorials/notebooks.html create mode 100644 docs/v2.2.0/tutorials/serving_torch_tensorrt_with_triton.html create mode 100644 docs/v2.2.0/user_guide/dynamic_shapes.html create mode 100644 docs/v2.2.0/user_guide/ptq.html create mode 100644 docs/v2.2.0/user_guide/runtime.html create mode 100644 docs/v2.2.0/user_guide/saving_models.html create mode 100644 docs/v2.2.0/user_guide/using_dla.html diff --git a/docs/v2.2.0/.nojekyll b/docs/v2.2.0/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1DataType.html b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1DataType.html new file mode 100644 index 0000000000..d8bdf08d20 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1DataType.html @@ -0,0 +1,942 @@ + + + + + + + + + + + + + Class DataType — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Class DataType

+ +
+

Class Documentation

+
+
+class torch_tensorrt::DataType
+

Supported Data Types that can be used with TensorRT engines

+

This class is compatable with c10::DataTypes (but will check for TRT support) so there should not be a reason that you need to use this type explictly.

+
+

Public Types

+
+
+enum Value
+

Underlying enum class to support the DataType Class

+

In the case that you need to use the DataType class itself, interface using this enum vs. normal instatination

+

ex. torch_tensorrt::DataType type = DataType::kFloat;

+

Values:

+
+
+enumerator kLong
+

INT64.

+
+ +
+
+enumerator kDouble
+

FP64.

+
+ +
+
+enumerator kFloat
+

FP32.

+
+ +
+
+enumerator kHalf
+

FP16.

+
+ +
+
+enumerator kChar
+

INT8.

+
+ +
+
+enumerator kInt
+

INT.

+
+ +
+
+enumerator kBool
+

Bool.

+
+ +
+
+enumerator kUnknown
+

Sentinel value.

+
+ +
+ +
+
+

Public Functions

+
+
+DataType() = default
+

Construct a new Data Type object.

+
+ +
+
+inline constexpr DataType(Value t)
+

DataType constructor from enum.

+
+ +
+
+TORCHTRT_API DataType(c10::ScalarType t)
+

Construct a new Data Type object from torch type enums.

+
+
Parameters
+

t

+
+
+
+ +
+
+inline operator Value() const
+

Get the enum value of the DataType object.

+
+
Returns
+

Value

+
+
+
+ +
+
+explicit operator bool() = delete
+
+ +
+
+inline constexpr bool operator==(DataType other) const
+

Comparision operator for DataType.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+inline constexpr bool operator==(DataType::Value other) const
+

Comparision operator for DataType.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+inline constexpr bool operator!=(DataType other) const
+

Comparision operator for DataType.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+inline constexpr bool operator!=(DataType::Value other) const
+

Comparision operator for DataType.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType.html b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType.html new file mode 100644 index 0000000000..d1a6b52c26 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType.html @@ -0,0 +1,879 @@ + + + + + + + + + + + + + Class Device::DeviceType — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Class Device::DeviceType

+ +
+

Nested Relationships

+

This class is a nested type of Struct Device.

+
+
+

Class Documentation

+
+
+class torch_tensorrt::Device::DeviceType
+

Supported Device Types that can be used with TensorRT engines

+

This class is compatable with c10::DeviceTypes (but will check for TRT support) but the only applicable value is at::kCUDA, which maps to DeviceType::kGPU

+

To use the DataType class itself, interface using the enum vs. normal instatination

+

ex. torch_tensorrt::DeviceType type = DeviceType::kGPU;

+
+

Public Types

+
+
+enum Value
+

Underlying enum class to support the DeviceType Class

+

In the case that you need to use the DeviceType class itself, interface using this enum vs. normal instatination

+

ex. torch_tensorrt::DeviceType type = DeviceType::kGPU;

+

Values:

+
+
+enumerator kGPU
+

Target GPU to run engine.

+
+ +
+
+enumerator kDLA
+

Target DLA to run engine.

+
+ +
+ +
+
+

Public Functions

+
+
+DeviceType() = default
+

Construct a new Device Type object.

+
+ +
+
+inline constexpr DeviceType(Value t)
+

Construct a new Device Type object from internal enum.

+
+ +
+
+DeviceType(c10::DeviceType t)
+

Construct a new Device Type object from torch device enums Note: The only valid value is torch::kCUDA (torch::kCPU is not supported)

+
+
Parameters
+

t

+
+
+
+ +
+
+inline operator Value() const
+

Get the internal value from the Device object.

+
+
Returns
+

Value

+
+
+
+ +
+
+explicit operator bool() = delete
+
+ +
+
+inline constexpr bool operator==(DeviceType other) const
+

Comparison operator for DeviceType.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+inline constexpr bool operator!=(DeviceType other) const
+

Comparison operator for DeviceType.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1TensorFormat.html b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1TensorFormat.html new file mode 100644 index 0000000000..14a42c1cb2 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1TensorFormat.html @@ -0,0 +1,911 @@ + + + + + + + + + + + + + Class TensorFormat — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Class TensorFormat

+ +
+

Class Documentation

+
+
+class torch_tensorrt::TensorFormat
+

TensorFormat is an enum class which defines the memeory layout used to store Tensor Data.

+
+

Public Types

+
+
+enum Value
+

Underlying enum class to support the TensorFormat Class

+

In the case that you need to use the TensorFormat class itself, interface using this enum vs. normal instatination

+

ex. torch_tensorrt::TensorFormat type = TensorFormat::kContiguous;

+

Values:

+
+
+enumerator kContiguous
+

Contiguous / NCHW / Linear.

+
+ +
+
+enumerator kChannelsLast
+

Channel Last / NHWC.

+
+ +
+
+enumerator kUnknown
+

Sentinel value.

+
+ +
+ +
+
+

Public Functions

+
+
+TensorFormat() = default
+

Construct a new TensorFormat object.

+
+ +
+
+inline constexpr TensorFormat(Value t)
+

TensorFormat constructor from enum.

+
+ +
+
+TORCHTRT_API TensorFormat(at::MemoryFormat t)
+

Construct a new TensorFormat object from torch type enums.

+
+
Parameters
+

t

+
+
+
+ +
+
+inline operator Value() const
+

Get the enum value of the TensorFormat object.

+
+
Returns
+

Value

+
+
+
+ +
+
+explicit operator bool() = delete
+
+ +
+
+inline constexpr bool operator==(TensorFormat other) const
+

Comparision operator for TensorFormat.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+inline constexpr bool operator==(TensorFormat::Value other) const
+

Comparision operator for TensorFormat.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+inline constexpr bool operator!=(TensorFormat other) const
+

Comparision operator for TensorFormat.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+inline constexpr bool operator!=(TensorFormat::Value other) const
+

Comparision operator for TensorFormat.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator.html b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator.html new file mode 100644 index 0000000000..f6b985e863 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator.html @@ -0,0 +1,875 @@ + + + + + + + + + + + + + Template Class Int8CacheCalibrator — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Template Class Int8CacheCalibrator

+ +
+

Inheritance Relationships

+
+

Base Type

+
    +
  • private Algorithm

  • +
+
+
+
+

Class Documentation

+
+
+template<typename Algorithm>
class torch_tensorrt::ptq::Int8CacheCalibrator : private Algorithm
+

Generic Int8Calibrator implementation based on a specified TensorRT calibration algorithm that only reads from a calibration file.

+
+
Template Parameters
+

Algorithm – class nvinfer1::IInt8Calibrator (Default: nvinfer1::IInt8EntropyCalibrator2) - Algorithm to use

+
+
+
+

Public Functions

+
+
+inline Int8CacheCalibrator(const std::string &cache_file_path)
+

Construct a new Int 8 Cache Calibrator object.

+
+
Parameters
+

cache_file_path

+
+
+
+ +
+
+inline int getBatchSize() const noexcept override
+

Get the Batch Size for the next batch (always 1 due to issues with TRT and explicit batch)

+
+
Returns
+

int

+
+
+
+ +
+
+inline bool getBatch(void *bindings[], const char *names[], int nbBindings) noexcept override
+

Get the next Batch.

+

Not used always returns false

+
+
Parameters
+
    +
  • bindings – void*[] - An array of binding pointers (fed in from TensorRT calibrator), these buffers should be filed with batch data for each input

  • +
  • names – const char*[] - Names of bindings

  • +
  • nbBindings – int - Number of bindings

  • +
+
+
Returns
+

false

+
+
+
+ +
+
+inline const void *readCalibrationCache(size_t &length) noexcept override
+

Read calibration cache.

+

How to read from the calibration cache, only enabled if use_cache is set

+
+
Parameters
+

length

+
+
Returns
+

const void* - Pointer to cache data

+
+
+
+ +
+
+inline void writeCalibrationCache(const void *cache, size_t length) noexcept override
+

Write calibration cache.

+

Write a the calibration cache provided by TensorRT to a specified file

+
+
Parameters
+
    +
  • cache – const void* - cache data

  • +
  • length – size_t - length of cache

  • +
+
+
+
+ +
+
+inline operator nvinfer1::IInt8Calibrator*()
+

operator to cast to nvinfer1::IInt8Calibrator*

+

Convience function to convert to a IInt8Calibrator* to easily be assigned to the ptq_calibrator field in CompileSpec

+
+
Returns
+

nvinfer1::IInt8Calibrator*

+
+
+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator.html b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator.html new file mode 100644 index 0000000000..7a9c4ac5ea --- /dev/null +++ b/docs/v2.2.0/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator.html @@ -0,0 +1,885 @@ + + + + + + + + + + + + + Template Class Int8Calibrator — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Template Class Int8Calibrator

+ +
+

Inheritance Relationships

+
+

Base Type

+
    +
  • private Algorithm

  • +
+
+
+
+

Class Documentation

+
+
+template<typename Algorithm, typename DataLoaderUniquePtr>
class torch_tensorrt::ptq::Int8Calibrator : private Algorithm
+

Generic Int8Calibrator implementation based on a specified TensorRT calibration algorithm and a LibTorch DataLoader.

+
+
Template Parameters
+
    +
  • Algorithm – class nvinfer1::IInt8Calibrator (Default: nvinfer1::IInt8EntropyCalibrator2) - Algorithm to use

  • +
  • DataLoaderUniquePtr – std::unique_ptr<torch::data::DataLoader> - DataLoader type

  • +
+
+
+
+

Public Functions

+
+
+inline Int8Calibrator(DataLoaderUniquePtr dataloader, const std::string &cache_file_path, bool use_cache)
+

Construct a new Int8Calibrator object.

+

Using the provided DataLoader, construct a calibrator that can be used for PTQ with Torch-TensorRT

+
+
Parameters
+
    +
  • dataloader – std::unqiue_ptr<torch::data::DataLoader> - A unique pointer to the DataLoader, should be what is returned from the make_data_loader factory

  • +
  • cache_file_path – const std::string& - A path to store / find the calibration cache

  • +
  • use_cache – : bool - Whether to use the cache (if it exists)

  • +
+
+
+
+ +
+
+inline int getBatchSize() const noexcept override
+

Get the Batch Size for the next batch (always 1 due to issues with TRT and explicit batch)

+
+
Returns
+

int

+
+
+
+ +
+
+inline bool getBatch(void *bindings[], const char *names[], int nbBindings) noexcept override
+

Get the next Batch.

+
+
Parameters
+
    +
  • bindings – void*[] - An array of binding pointers (fed in from TensorRT calibrator), these buffers should be filed with batch data for each input

  • +
  • names – const char*[] - Names of bindings

  • +
  • nbBindings – int - Number of bindings

  • +
+
+
Returns
+

true - There is a new batch for the calibrator to consume

+
+
Returns
+

false - There is not a new batch for the calibrator to consume

+
+
+
+ +
+
+inline const void *readCalibrationCache(size_t &length) noexcept override
+

Read calibration cache.

+

How to read from the calibration cache, only enabled if use_cache is set

+
+
Parameters
+

length

+
+
Returns
+

const void* - Pointer to cache data

+
+
+
+ +
+
+inline void writeCalibrationCache(const void *cache, size_t length) noexcept override
+

Write calibration cache.

+

Write a the calibration cache provided by TensorRT to a specified file

+
+
Parameters
+
    +
  • cache – const void* - cache data

  • +
  • length – size_t - length of cache

  • +
+
+
+
+ +
+
+inline operator nvinfer1::IInt8Calibrator*()
+

operator to cast to nvinfer1::IInt8Calibrator*

+

Convience function to convert to a IInt8Calibrator* to easily be assigned to the ptq_calibrator field in CompileSpec

+
+
Returns
+

nvinfer1::IInt8Calibrator*

+
+
+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502.html b/docs/v2.2.0/_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502.html new file mode 100644 index 0000000000..2adcb7260a --- /dev/null +++ b/docs/v2.2.0/_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Define STR — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Define STR

+ +
+

Define Documentation

+
+
+STR(x)
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268.html b/docs/v2.2.0/_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268.html new file mode 100644 index 0000000000..5b4051a6c6 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Define TORCH_TENSORRT_PATCH_VERSION — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Define TORCH_TENSORRT_PATCH_VERSION

+ +
+

Define Documentation

+
+
+TORCH_TENSORRT_PATCH_VERSION
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e.html b/docs/v2.2.0/_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e.html new file mode 100644 index 0000000000..197b6ca5c5 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Define TORCH_TENSORRT_MAJOR_VERSION — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Define TORCH_TENSORRT_MAJOR_VERSION

+ +
+

Define Documentation

+
+
+TORCH_TENSORRT_MAJOR_VERSION
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827.html b/docs/v2.2.0/_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827.html new file mode 100644 index 0000000000..c531797737 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Define TORCH_TENSORRT_MINOR_VERSION — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Define TORCH_TENSORRT_MINOR_VERSION

+ +
+

Define Documentation

+
+
+TORCH_TENSORRT_MINOR_VERSION
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b.html b/docs/v2.2.0/_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b.html new file mode 100644 index 0000000000..6d33bf1626 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Define TORCHTRT_API — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Define TORCHTRT_API

+ +
+

Define Documentation

+
+
+TORCHTRT_API
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da.html b/docs/v2.2.0/_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da.html new file mode 100644 index 0000000000..ba61a680da --- /dev/null +++ b/docs/v2.2.0/_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Define XSTR — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Define XSTR

+ +
+

Define Documentation

+
+
+XSTR(x)
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59.html b/docs/v2.2.0/_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59.html new file mode 100644 index 0000000000..aaa7e89c54 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Define TORCHTRT_HIDDEN — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Define TORCHTRT_HIDDEN

+ +
+

Define Documentation

+
+
+TORCHTRT_HIDDEN
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883.html b/docs/v2.2.0/_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883.html new file mode 100644 index 0000000000..7652fb8e21 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Define TORCH_TENSORRT_VERSION — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Define TORCH_TENSORRT_VERSION

+ +
+

Define Documentation

+
+
+TORCH_TENSORRT_VERSION
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/dir_cpp.html b/docs/v2.2.0/_cpp_api/dir_cpp.html new file mode 100644 index 0000000000..1043214cec --- /dev/null +++ b/docs/v2.2.0/_cpp_api/dir_cpp.html @@ -0,0 +1,753 @@ + + + + + + + + + + + + + Directory cpp — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+ + +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/dir_cpp_include.html b/docs/v2.2.0/_cpp_api/dir_cpp_include.html new file mode 100644 index 0000000000..68043f49de --- /dev/null +++ b/docs/v2.2.0/_cpp_api/dir_cpp_include.html @@ -0,0 +1,754 @@ + + + + + + + + + + + + + Directory include — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Directory include
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+ + +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/dir_cpp_include_torch_tensorrt.html b/docs/v2.2.0/_cpp_api/dir_cpp_include_torch_tensorrt.html new file mode 100644 index 0000000000..1787e3e3dd --- /dev/null +++ b/docs/v2.2.0/_cpp_api/dir_cpp_include_torch_tensorrt.html @@ -0,0 +1,757 @@ + + + + + + + + + + + + + Directory torch_tensorrt — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Directory torch_tensorrt
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+ + +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558.html b/docs/v2.2.0/_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558.html new file mode 100644 index 0000000000..f84591a317 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558.html @@ -0,0 +1,808 @@ + + + + + + + + + + + + + Enum Level — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Enum Level

+ +
+

Enum Documentation

+
+
+enum torch_tensorrt::logging::Level
+

Emum for setting message severity

+

Values:

+
+
+enumerator kINTERNAL_ERROR
+

Only print messages for internal errors.

+
+ +
+
+enumerator kERROR
+

Print all internal errors and errors (default)

+
+ +
+
+enumerator kWARNING
+

Print warnings and errors.

+
+ +
+
+enumerator kINFO
+

Print all info, warnings and errors.

+
+ +
+
+enumerator kDEBUG
+

Print all debug info, info, warnings and errors.

+
+ +
+
+enumerator kGRAPH
+

Print everything including the intermediate graphs of the lowering phase.

+
+ +
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb.html b/docs/v2.2.0/_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb.html new file mode 100644 index 0000000000..6d140b0101 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb.html @@ -0,0 +1,787 @@ + + + + + + + + + + + + + Enum EngineCapability — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Enum EngineCapability

+ +
+

Enum Documentation

+
+
+enum class torch_tensorrt::EngineCapability : int8_t
+

Emum for selecting engine capability

+

Values:

+
+
+enumerator kSTANDARD
+
+ +
+
+enumerator kSAFETY
+
+ +
+
+enumerator kDLA_STANDALONE
+
+ +
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_logging.h.html b/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_logging.h.html new file mode 100644 index 0000000000..0cf41754ef --- /dev/null +++ b/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_logging.h.html @@ -0,0 +1,809 @@ + + + + + + + + + + + + + File logging.h — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

File logging.h

+

Parent directory (cpp/include/torch_tensorrt)

+ +
+

Definition (cpp/include/torch_tensorrt/logging.h)

+ +
+
+

Includes

+ +
+
+

Included By

+ +
+
+

Namespaces

+ +
+
+

Enums

+ +
+
+

Functions

+ +
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_macros.h.html b/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_macros.h.html new file mode 100644 index 0000000000..0a173d9eab --- /dev/null +++ b/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_macros.h.html @@ -0,0 +1,795 @@ + + + + + + + + + + + + + File macros.h — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

File macros.h

+

Parent directory (cpp/include/torch_tensorrt)

+ +
+

Definition (cpp/include/torch_tensorrt/macros.h)

+ +
+
+

Included By

+ +
+
+

Namespaces

+ +
+
+

Defines

+ +
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_ptq.h.html b/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_ptq.h.html new file mode 100644 index 0000000000..25f36fccfa --- /dev/null +++ b/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_ptq.h.html @@ -0,0 +1,806 @@ + + + + + + + + + + + + + File ptq.h — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

File ptq.h

+

Parent directory (cpp/include/torch_tensorrt)

+ +
+

Definition (cpp/include/torch_tensorrt/ptq.h)

+ +
+
+

Includes

+
    +
  • NvInfer.h

  • +
  • fstream

  • +
  • iostream

  • +
  • iterator

  • +
  • memory

  • +
  • sstream

  • +
  • string

  • +
  • torch/torch.h

  • +
  • torch_tensorrt/logging.h (File logging.h)

  • +
  • torch_tensorrt/macros.h (File macros.h)

  • +
  • vector

  • +
+
+
+

Namespaces

+ +
+
+

Classes

+ +
+
+

Functions

+ +
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h.html b/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h.html new file mode 100644 index 0000000000..2c5ac3beb7 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h.html @@ -0,0 +1,821 @@ + + + + + + + + + + + + + File torch_tensorrt.h — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • File torch_tensorrt.h
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

File torch_tensorrt.h

+

Parent directory (cpp/include/torch_tensorrt)

+ +
+

Definition (cpp/include/torch_tensorrt/torch_tensorrt.h)

+ +
+
+

Includes

+
    +
  • cuda_runtime.h

  • +
  • iostream

  • +
  • memory

  • +
  • set

  • +
  • string

  • +
  • torch/custom_class.h

  • +
  • torch_tensorrt/macros.h (File macros.h)

  • +
  • vector

  • +
+
+
+

Namespaces

+ +
+
+

Classes

+ +
+
+

Enums

+ +
+
+

Functions

+ +
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3.html b/docs/v2.2.0/_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3.html new file mode 100644 index 0000000000..e3fa844bbf --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Function torch_tensorrt::logging::get_logging_prefix — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::logging::get_logging_prefix

+ +
+

Function Documentation

+
+
+TORCHTRT_API std::string torch_tensorrt::logging::get_logging_prefix()
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650.html b/docs/v2.2.0/_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650.html new file mode 100644 index 0000000000..c9a366f47c --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650.html @@ -0,0 +1,776 @@ + + + + + + + + + + + + + Function torch_tensorrt::logging::get_reportable_log_level — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::logging::get_reportable_log_level

+ +
+

Function Documentation

+
+
+TORCHTRT_API Level torch_tensorrt::logging::get_reportable_log_level()
+

Get the current reportable log level.

+
+
Returns
+

TORCHTRT_API get_reportable_log_level

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a.html b/docs/v2.2.0/_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a.html new file mode 100644 index 0000000000..90adb16467 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a.html @@ -0,0 +1,776 @@ + + + + + + + + + + + + + Function torch_tensorrt::logging::get_is_colored_output_on — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::logging::get_is_colored_output_on

+ +
+

Function Documentation

+
+
+TORCHTRT_API bool torch_tensorrt::logging::get_is_colored_output_on()
+

Is colored output enabled?

+
+
Returns
+

TORCHTRT_API get_is_colored_output_on

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2.html b/docs/v2.2.0/_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2.html new file mode 100644 index 0000000000..bed2dff062 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2.html @@ -0,0 +1,776 @@ + + + + + + + + + + + + + Function torch_tensorrt::logging::set_reportable_log_level — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::logging::set_reportable_log_level

+ +
+

Function Documentation

+
+
+TORCHTRT_API void torch_tensorrt::logging::set_reportable_log_level(Level lvl)
+

Sets the level that logging information needs to be to be added to the log.

+
+
Parameters
+

lvl – torch_tensorrt::logging::Level - Level that messages need to be at or above to be added to the log

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.html b/docs/v2.2.0/_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.html new file mode 100644 index 0000000000..cd6cd65cac --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.html @@ -0,0 +1,779 @@ + + + + + + + + + + + + + Function torch_tensorrt::logging::log — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::logging::log

+ +
+

Function Documentation

+
+
+TORCHTRT_API void torch_tensorrt::logging::log(Level lvl, std::string msg)
+

Adds a message to the global log.

+
+
Parameters
+
    +
  • lvl – torch_tensorrt::logging::Level - Severity of the message

  • +
  • msg – std::string - Message to be logged

  • +
+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5.html b/docs/v2.2.0/_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5.html new file mode 100644 index 0000000000..a89afecf2f --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5.html @@ -0,0 +1,776 @@ + + + + + + + + + + + + + Function torch_tensorrt::logging::set_is_colored_output_on — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::logging::set_is_colored_output_on

+ +
+

Function Documentation

+
+
+TORCHTRT_API void torch_tensorrt::logging::set_is_colored_output_on(bool colored_output_on)
+

Sets if logging prefix will be colored (helpful when debugging but not always supported by terminal)

+
+
Parameters
+

colored_output_on – bool - If the output will be colored or not

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc.html b/docs/v2.2.0/_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc.html new file mode 100644 index 0000000000..480c4317bb --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc.html @@ -0,0 +1,770 @@ + + + + + + + + + + + + + Function torch_tensorrt::logging::set_logging_prefix — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::logging::set_logging_prefix

+ +
+

Function Documentation

+
+
+TORCHTRT_API void torch_tensorrt::logging::set_logging_prefix(std::string prefix)
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c.html b/docs/v2.2.0/_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c.html new file mode 100644 index 0000000000..526462beea --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c.html @@ -0,0 +1,785 @@ + + + + + + + + + + + + + Template Function torch_tensorrt::ptq::make_int8_cache_calibrator — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Template Function torch_tensorrt::ptq::make_int8_cache_calibrator

+ +
+

Function Documentation

+
+
+template<typename Algorithm = nvinfer1::IInt8EntropyCalibrator2>
inline Int8CacheCalibrator<Algorithm> torch_tensorrt::ptq::make_int8_cache_calibrator(const std::string &cache_file_path)
+

A factory to build a post training quantization calibrator from a torch dataloader that only uses the calibration cache.

+

Creates a calibrator to use for post training quantization which reads from a previously created calibration cache, therefore you can have a calibration cache generating program that requires a dataloader and a dataset, then save the cache to use later in a different program that needs to calibrate from scratch and not have the dataset dependency. However, the network should also be recalibrated if its structure changes, or the input data set changes, and it is the responsibility of the application to ensure this.

+

By default the returned calibrator uses TensorRT Entropy v2 algorithm to perform calibration. This is recommended for feed forward networks You can override the algorithm selection (such as to use the MinMax Calibrator recomended for NLP tasks) by calling make_int8_calibrator with the calibrator class as a template parameter.

+

e.g. torch_tensorrt::ptq::make_int8_cache_calibrator<nvinfer1::IInt8MinMaxCalibrator>(calibration_cache_file);

+
+
Template Parameters
+

Algorithm – class nvinfer1::IInt8Calibrator (Default: nvinfer1::IInt8EntropyCalibrator2) - Algorithm to use

+
+
Parameters
+

cache_file_path – const std::string& - Path to read/write calibration cache

+
+
Returns
+

Int8CacheCalibrator<Algorithm>

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178.html b/docs/v2.2.0/_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178.html new file mode 100644 index 0000000000..300429977f --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178.html @@ -0,0 +1,791 @@ + + + + + + + + + + + + + Template Function torch_tensorrt::ptq::make_int8_calibrator — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Template Function torch_tensorrt::ptq::make_int8_calibrator

+ +
+

Function Documentation

+
+
+template<typename Algorithm = nvinfer1::IInt8EntropyCalibrator2, typename DataLoader>
inline Int8Calibrator<Algorithm, DataLoader> torch_tensorrt::ptq::make_int8_calibrator(DataLoader dataloader, const std::string &cache_file_path, bool use_cache)
+

A factory to build a post training quantization calibrator from a torch dataloader.

+

Creates a calibrator to use for post training quantization. By default the returned calibrator uses TensorRT Entropy v2 algorithm to perform calibration. This is recommended for feed forward networks. You can override the algorithm selection (such as to use the MinMax Calibrator recomended for NLP tasks) by calling make_int8_calibrator with the calibrator class as a template parameter.

+

e.g. torch_tensorrt::ptq::make_int8_calibrator<nvinfer1::IInt8MinMaxCalibrator>(std::move(calibration_dataloader), calibration_cache_file, use_cache);

+
+
Template Parameters
+
    +
  • Algorithm – class nvinfer1::IInt8Calibrator (Default: nvinfer1::IInt8EntropyCalibrator2) - Algorithm to use

  • +
  • DataLoader – std::unique_ptr<torch::data::DataLoader> - DataLoader type

  • +
+
+
Parameters
+
    +
  • dataloader – std::unique_ptr<torch::data::DataLoader> - DataLoader containing data

  • +
  • cache_file_path – const std::string& - Path to read/write calibration cache

  • +
  • use_cache – bool - use calibration cache

  • +
+
+
Returns
+

Int8Calibrator<Algorithm, DataLoader>

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.html b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.html new file mode 100644 index 0000000000..e74f1a4ba8 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.html @@ -0,0 +1,785 @@ + + + + + + + + + + + + + Function torch_tensorrt::torchscript::check_method_operator_support — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::torchscript::check_method_operator_support

+ +
+

Function Documentation

+
+
+TORCHTRT_API bool torch_tensorrt::torchscript::check_method_operator_support(const torch::jit::Module &module, std::string method_name)
+

Check to see if a module is fully supported by the compiler.

+

+Takes a module and a method name and checks if the method graph contains purely convertable operators

+

Will print out a list of unsupported operators if the graph is unsupported

+
+
Parameters
+
    +
  • module – torch::jit::script::Module - Existing TorchScript module

  • +
  • method_name – std::string - Name of method to compile

  • +
+
+
Returns
+

bool: Method is supported by Torch-TensorRT.TorchScript

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9.html b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9.html new file mode 100644 index 0000000000..c4391ae405 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9.html @@ -0,0 +1,785 @@ + + + + + + + + + + + + + Function torch_tensorrt::torchscript::compile — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::torchscript::compile

+ +
+

Function Documentation

+
+
+TORCHTRT_API torch::jit::Module torch_tensorrt::torchscript::compile(const torch::jit::Module &module, CompileSpec info)
+

Compile a TorchScript module for NVIDIA GPUs using TensorRT.

+

+Takes a existing TorchScript module and a set of settings to configure the compiler and will convert methods to JIT Graphs which call equivalent TensorRT engines

+

Converts specifically the forward method of a TorchScript Module

+
+
Parameters
+
    +
  • module – torch::jit::Module - Existing TorchScript module

  • +
  • info – torch_tensorrt::CompileSpec - Compilation settings

  • +
+
+
Returns
+

: A new module trageting a TensorRT engine

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9.html b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9.html new file mode 100644 index 0000000000..da90067b58 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9.html @@ -0,0 +1,791 @@ + + + + + + + + + + + + + Function torch_tensorrt::torchscript::embed_engine_in_new_module — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::torchscript::embed_engine_in_new_module

+ +
+

Function Documentation

+
+
+TORCHTRT_API torch::jit::Module torch_tensorrt::torchscript::embed_engine_in_new_module(const std::string &engine, Device device, const std::vector<std::string> &input_binding_names = std::vector<std::string>(), const std::vector<std::string> &output_binding_names = std::vector<std::string>())
+

Take a previously created TensorRT engine and embed it in in a TorchScript module.

+

+Takes a pre-built serialized TensorRT engine and embeds it in a TorchScript module. Registers execution of the engine as the forward method of the module Forward is defined as: forward(Tensor[]) -> Tensor[]

+

If binding names not specified TensorRT bindings must have names with the following format:

    +
  • [symbol].[index in input / output array] ex.

  • +
  • [x.0, x.1, x.2] -> [y.0]

  • +
+

+
+
Parameters
+
    +
  • engine – std::string - Pre-built serialized TensorRT engine

  • +
  • device – CompileSepc::Device - Device information

  • +
  • input_binding_names – std::vector<std::string> - Name of TensorRT bindings in order passed in by original PyTorch function (defaults to assuming convention below)

  • +
  • output_binding_names – std::vector<std::string> - Name of TensorRT bindings in order returned by original PyTorch function (defaults to assuming convention below)

  • +
+
+
Returns
+

: A new module targeting a TensorRT engine

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528.html b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528.html new file mode 100644 index 0000000000..ee3748a6e9 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528.html @@ -0,0 +1,776 @@ + + + + + + + + + + + + + Function torch_tensorrt::get_build_info — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::get_build_info

+ +
+

Function Documentation

+
+
+TORCHTRT_API std::string torch_tensorrt::get_build_info()
+

Get the build information for the library including the dependency versions.

+
+
Returns
+

std::string

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384.html b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384.html new file mode 100644 index 0000000000..dbc727750a --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384.html @@ -0,0 +1,776 @@ + + + + + + + + + + + + + Function torch_tensorrt::set_device — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::set_device

+ +
+

Function Documentation

+
+
+TORCHTRT_API void torch_tensorrt::set_device(const int gpu_id)
+

Set gpu device id.

+
+
Parameters
+

gpu_id – Sets gpu id using cudaSetDevice

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.html b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.html new file mode 100644 index 0000000000..1117e18475 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.html @@ -0,0 +1,771 @@ + + + + + + + + + + + + + Function torch_tensorrt::dump_build_info — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::dump_build_info

+ +
+

Function Documentation

+
+
+TORCHTRT_API void torch_tensorrt::dump_build_info()
+

Dump the version information for Torch-TensorRT including base libtorch and TensorRT versions to stdout.

+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2.html b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2.html new file mode 100644 index 0000000000..a6729dcdc4 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2.html @@ -0,0 +1,785 @@ + + + + + + + + + + + + + Function torch_tensorrt::torchscript::convert_method_to_trt_engine — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Function torch_tensorrt::torchscript::convert_method_to_trt_engine

+ +
+

Function Documentation

+
+
+TORCHTRT_API std::string torch_tensorrt::torchscript::convert_method_to_trt_engine(const torch::jit::Module &module, std::string method_name, CompileSpec info)
+

Compile a TorchScript method for NVIDIA GPUs using TensorRT.

+

+Takes a existing TorchScript module and a set of settings to configure the compiler and will convert selected method to a serialized TensorRT engine which can be run with TensorRT

+
+
Parameters
+
    +
  • module – torch::jit::Module - Existing TorchScript module

  • +
  • method_name – std::string - Name of method to compile

  • +
  • info – torch_tensorrt::CompileSpec - Compilation settings

  • +
+
+
Returns
+

: std::string: Serialized TensorRT engine equivilant to the method graph

+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/namespace_torch.html b/docs/v2.2.0/_cpp_api/namespace_torch.html new file mode 100644 index 0000000000..b9a90c2f7b --- /dev/null +++ b/docs/v2.2.0/_cpp_api/namespace_torch.html @@ -0,0 +1,756 @@ + + + + + + + + + + + + + Namespace torch — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Namespace torch

+
+ + +
+ +
+ + +
+
+ +
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt.html b/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt.html new file mode 100644 index 0000000000..93f5099ff6 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt.html @@ -0,0 +1,804 @@ + + + + + + + + + + + + + Namespace torch_tensorrt — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Namespace torch_tensorrt

+
+

Contents

+ +
+
+

Namespaces

+ +
+
+

Classes

+ +
+
+

Enums

+ +
+
+

Functions

+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__logging.html b/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__logging.html new file mode 100644 index 0000000000..91b37c7628 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__logging.html @@ -0,0 +1,785 @@ + + + + + + + + + + + + + Namespace torch_tensorrt::logging — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__ptq.html b/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__ptq.html new file mode 100644 index 0000000000..d43935e1e5 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__ptq.html @@ -0,0 +1,781 @@ + + + + + + + + + + + + + Namespace torch_tensorrt::ptq — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+ + +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__torchscript.html b/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__torchscript.html new file mode 100644 index 0000000000..1003eb01ca --- /dev/null +++ b/docs/v2.2.0/_cpp_api/namespace_torch_tensorrt__torchscript.html @@ -0,0 +1,782 @@ + + + + + + + + + + + + + Namespace torch_tensorrt::torchscript — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+ + +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h.html b/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h.html new file mode 100644 index 0000000000..1cd95336d1 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h.html @@ -0,0 +1,785 @@ + + + + + + + + + + + + + Program Listing for File logging.h — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Program Listing for File logging.h
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Program Listing for File logging.h

+

Return to documentation for file (cpp/include/torch_tensorrt/logging.h)

+
/*
+ * Copyright (c) NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * This library is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+#pragma once
+
+#include <string>
+#include "torch_tensorrt/macros.h"
+
+namespace torch_tensorrt {
+namespace logging {
+enum Level {
+  kINTERNAL_ERROR,
+  kERROR,
+  kWARNING,
+  kINFO,
+  kDEBUG,
+  kGRAPH,
+};
+
+// Are these ones necessary for the user?
+TORCHTRT_API std::string get_logging_prefix();
+TORCHTRT_API void set_logging_prefix(std::string prefix);
+
+TORCHTRT_API void set_reportable_log_level(Level lvl);
+
+TORCHTRT_API void set_is_colored_output_on(bool colored_output_on);
+
+TORCHTRT_API Level get_reportable_log_level();
+
+TORCHTRT_API bool get_is_colored_output_on();
+
+// Dont know if we want this?
+TORCHTRT_API void log(Level lvl, std::string msg);
+} // namespace logging
+} // namespace torch_tensorrt
+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h.html b/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h.html new file mode 100644 index 0000000000..48d4ceb41a --- /dev/null +++ b/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h.html @@ -0,0 +1,784 @@ + + + + + + + + + + + + + Program Listing for File macros.h — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Program Listing for File macros.h
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Program Listing for File macros.h

+

Return to documentation for file (cpp/include/torch_tensorrt/macros.h)

+
/*
+ * Copyright (c) NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * This library is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+#pragma once
+
+#if defined(USE_CMAKE_GENERATED_EXPORT_HEADER)
+#include <torch_tensorrt_export.h>
+#else
+#if defined(__GNUC__)
+#define TORCHTRT_API __attribute__((__visibility__("default")))
+#define TORCHTRT_HIDDEN __attribute__((__visibility__("hidden")))
+#else
+#define TORCHTRT_API
+#define TORCHTRT_HIDDEN
+#endif // defined(__GNUC__)
+#endif // defined(USE_CMAKE_GENERATED_EXPORT_HEADER)
+
+// Does this need to be gaurded or something?
+#define XSTR(x) #x
+#define STR(x) XSTR(x)
+
+#define TORCH_TENSORRT_MAJOR_VERSION 2
+#define TORCH_TENSORRT_MINOR_VERSION 2
+#define TORCH_TENSORRT_PATCH_VERSION 0
+#define TORCH_TENSORRT_VERSION      \
+  STR(TORCH_TENSORRT_MAJOR_VERSION) \
+  "." STR(TORCH_TENSORRT_MINOR_VERSION) "." STR(TORCH_TENSORRT_PATCH_VERSION)
+
+// Setup namespace aliases for ease of use
+namespace torch_tensorrt {
+namespace torchscript {}
+namespace ts = torchscript;
+} // namespace torch_tensorrt
+namespace torchtrt = torch_tensorrt;
+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h.html b/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h.html new file mode 100644 index 0000000000..0a6153558f --- /dev/null +++ b/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h.html @@ -0,0 +1,924 @@ + + + + + + + + + + + + + Program Listing for File ptq.h — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Program Listing for File ptq.h
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Program Listing for File ptq.h

+

Return to documentation for file (cpp/include/torch_tensorrt/ptq.h)

+
/*
+ * Copyright (c) NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * This library is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+#pragma once
+
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "NvInfer.h"
+#include "torch/torch.h"
+#include "torch_tensorrt/logging.h"
+#include "torch_tensorrt/macros.h"
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+namespace nvinfer1 {
+class IInt8Calibrator;
+class IInt8EntropyCalibrator2;
+} // namespace nvinfer1
+
+namespace torch_tensorrt {
+namespace ptq {
+TORCHTRT_API bool get_batch_impl(void* bindings[], const char* names[], int nbBindings, torch::Tensor& data);
+}
+} // namespace torch_tensorrt
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+
+namespace torch_tensorrt {
+namespace ptq {
+
+template <typename Algorithm, typename DataLoaderUniquePtr>
+class Int8Calibrator : Algorithm {
+  using DataLoader = typename DataLoaderUniquePtr::element_type;
+  using Batch = typename DataLoader::super::BatchType;
+
+ public:
+  Int8Calibrator(DataLoaderUniquePtr dataloader, const std::string& cache_file_path, bool use_cache)
+      : dataloader_(dataloader.get()), cache_file_path_(cache_file_path), use_cache_(use_cache) {
+    for (auto batch : *dataloader_) {
+      batched_data_.push_back(batch.data);
+    }
+    it_ = batched_data_.begin();
+  }
+
+  int getBatchSize() const noexcept override {
+    // HACK: Torch-TensorRT only uses explict batch sizing, INT8 Calibrator does not
+    // work when reporting the batch size here and having explicity batching.
+    // So we just report batch size 1 (warnings will still be printed out).
+    return 1;
+    // return static_cast<int>(dataloader_->options().batch_size);
+  }
+
+  bool getBatch(void* bindings[], const char* names[], int nbBindings) noexcept override {
+    if (it_ != batched_data_.end()) {
+      auto status = get_batch_impl(bindings, names, nbBindings, *it_);
+      it_ = ++it_;
+      return status;
+    } else {
+      // Reset iterator if incase calibrator is going to be used again
+      it_ = batched_data_.begin();
+      return false;
+    }
+  }
+
+  const void* readCalibrationCache(size_t& length) noexcept override {
+    if (use_cache_) {
+      std::stringstream ss;
+      ss << "Reading Calibration Cache from " << cache_file_path_;
+      logging::log(logging::Level::kINFO, ss.str());
+
+      cache_.clear();
+      std::ifstream input(cache_file_path_, std::ios::binary);
+      input >> std::noskipws;
+      if (input.good()) {
+        std::copy(std::istream_iterator<char>(input), std::istream_iterator<char>(), std::back_inserter(cache_));
+        logging::log(logging::Level::kDEBUG, "Cache read");
+      }
+      length = cache_.size();
+      return length ? cache_.data() : nullptr;
+    }
+    return nullptr;
+  }
+
+  void writeCalibrationCache(const void* cache, size_t length) noexcept override {
+    std::ofstream cache_file(cache_file_path_, std::ios::binary);
+    cache_file.write(reinterpret_cast<const char*>(cache), length);
+    std::stringstream ss;
+    ss << "Saved Calibration Cache to " << cache_file_path_;
+    logging::log(logging::Level::kINFO, ss.str());
+  }
+
+  operator nvinfer1::IInt8Calibrator*() {
+    return reinterpret_cast<nvinfer1::IInt8Calibrator*>(this);
+  }
+
+ private:
+  DataLoader* dataloader_;
+  const std::string& cache_file_path_;
+  size_t cache_size_ = 0;
+  bool use_cache_;
+  std::vector<char> cache_;
+  std::vector<torch::Tensor> batched_data_;
+  std::vector<torch::Tensor>::iterator it_;
+};
+
+template <typename Algorithm>
+class Int8CacheCalibrator : Algorithm {
+ public:
+  Int8CacheCalibrator(const std::string& cache_file_path) : cache_file_path_(cache_file_path) {}
+
+  int getBatchSize() const noexcept override {
+    // HACK: Torch-TensorRT only uses explict batch sizing, INT8 Calibrator does not
+    // work when reporting the batch size here and having explicity batching.
+    // So we just report batch size 1 (warnings will still be printed out).
+    return 1;
+  }
+
+  bool getBatch(void* bindings[], const char* names[], int nbBindings) noexcept override {
+    return false;
+  }
+
+  const void* readCalibrationCache(size_t& length) noexcept override {
+    std::stringstream ss;
+    ss << "Reading Calibration Cache from " << cache_file_path_;
+    logging::log(logging::Level::kINFO, ss.str());
+
+    cache_.clear();
+    std::ifstream input(cache_file_path_, std::ios::binary);
+    input >> std::noskipws;
+    if (input.good()) {
+      std::copy(std::istream_iterator<char>(input), std::istream_iterator<char>(), std::back_inserter(cache_));
+      logging::log(logging::Level::kDEBUG, "Cache read");
+    }
+    length = cache_.size();
+    return length ? cache_.data() : nullptr;
+  }
+
+  void writeCalibrationCache(const void* cache, size_t length) noexcept override {
+    std::ofstream cache_file(cache_file_path_, std::ios::binary);
+    cache_file.write(reinterpret_cast<const char*>(cache), length);
+    std::stringstream ss;
+    ss << "Saved Calibration Cache to " << cache_file_path_;
+    logging::log(logging::Level::kINFO, ss.str());
+  }
+
+  operator nvinfer1::IInt8Calibrator*() {
+    return reinterpret_cast<nvinfer1::IInt8Calibrator*>(this);
+  }
+
+ private:
+  const std::string& cache_file_path_;
+  size_t cache_size_ = 0;
+  std::vector<char> cache_;
+};
+
+template <typename Algorithm = nvinfer1::IInt8EntropyCalibrator2, typename DataLoader>
+inline Int8Calibrator<Algorithm, DataLoader> make_int8_calibrator(
+    DataLoader dataloader,
+    const std::string& cache_file_path,
+    bool use_cache) {
+  return Int8Calibrator<Algorithm, DataLoader>(std::move(dataloader), cache_file_path, use_cache);
+}
+
+template <typename Algorithm = nvinfer1::IInt8EntropyCalibrator2>
+inline Int8CacheCalibrator<Algorithm> make_int8_cache_calibrator(const std::string& cache_file_path) {
+  return Int8CacheCalibrator<Algorithm>(cache_file_path);
+}
+
+} // namespace ptq
+} // namespace torch_tensorrt
+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.html b/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.html new file mode 100644 index 0000000000..5d228e8422 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.html @@ -0,0 +1,1088 @@ + + + + + + + + + + + + + Program Listing for File torch_tensorrt.h — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Program Listing for File torch_tensorrt.h
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Program Listing for File torch_tensorrt.h

+

Return to documentation for file (cpp/include/torch_tensorrt/torch_tensorrt.h)

+
/*
+ * Copyright (c) NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * This library is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+#pragma once
+
+#include <cuda_runtime.h>
+#include <iostream>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+#include "torch/custom_class.h"
+
+#include "torch_tensorrt/macros.h"
+
+// Just include the .h?
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+namespace torch {
+namespace jit {
+struct Graph;
+struct Module;
+} // namespace jit
+} // namespace torch
+
+namespace c10 {
+enum class DeviceType : int8_t;
+enum class ScalarType : int8_t;
+template <class>
+class ArrayRef;
+} // namespace c10
+
+namespace nvinfer1 {
+class IInt8Calibrator;
+}
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+
+namespace torch_tensorrt {
+class DataType {
+ public:
+  enum Value : int8_t {
+    kLong,
+    kDouble,
+    kFloat,
+    kHalf,
+    kChar,
+    kInt,
+    kBool,
+    kUnknown
+  };
+
+  DataType() = default;
+  constexpr DataType(Value t) : value(t) {}
+  TORCHTRT_API DataType(c10::ScalarType t);
+  operator Value() const {
+    return value;
+  }
+  explicit operator bool() = delete;
+  constexpr bool operator==(DataType other) const {
+    return value == other.value;
+  }
+  constexpr bool operator==(DataType::Value other) const {
+    return value == other;
+  }
+  constexpr bool operator!=(DataType other) const {
+    return value != other.value;
+  }
+  constexpr bool operator!=(DataType::Value other) const {
+    return value != other;
+  }
+
+ private:
+  friend TORCHTRT_API std::ostream& operator<<(std::ostream& os, const DataType& dtype);
+  Value value;
+};
+
+struct Device {
+  class DeviceType {
+   public:
+    enum Value : int8_t {
+      kGPU,
+      kDLA,
+    };
+
+    DeviceType() = default;
+    constexpr DeviceType(Value t) : value(t) {}
+    DeviceType(c10::DeviceType t);
+    operator Value() const {
+      return value;
+    }
+    explicit operator bool() = delete;
+    constexpr bool operator==(DeviceType other) const {
+      return value == other.value;
+    }
+    constexpr bool operator!=(DeviceType other) const {
+      return value != other.value;
+    }
+
+   private:
+    Value value;
+  };
+
+  DeviceType device_type;
+
+  /*
+   * Target gpu id
+   */
+  int64_t gpu_id;
+
+  /*
+   * When using DLA core on NVIDIA AGX platforms gpu_id should be set as Xavier device
+   */
+  int64_t dla_core;
+
+  bool allow_gpu_fallback;
+
+  Device() : device_type(DeviceType::kGPU), gpu_id(0), dla_core(0), allow_gpu_fallback(false) {}
+};
+
+enum class EngineCapability : int8_t {
+  kSTANDARD,
+  kSAFETY,
+  kDLA_STANDALONE,
+};
+
+class TensorFormat {
+ public:
+  enum Value : int8_t {
+    kContiguous,
+    kChannelsLast,
+    kUnknown,
+  };
+
+  TensorFormat() = default;
+  constexpr TensorFormat(Value t) : value(t) {}
+  TORCHTRT_API TensorFormat(at::MemoryFormat t);
+  operator Value() const {
+    return value;
+  }
+  explicit operator bool() = delete;
+  constexpr bool operator==(TensorFormat other) const {
+    return value == other.value;
+  }
+  constexpr bool operator==(TensorFormat::Value other) const {
+    return value == other;
+  }
+  constexpr bool operator!=(TensorFormat other) const {
+    return value != other.value;
+  }
+  constexpr bool operator!=(TensorFormat::Value other) const {
+    return value != other;
+  }
+
+ private:
+  friend TORCHTRT_API std::ostream& operator<<(std::ostream& os, const TensorFormat& format);
+  Value value;
+};
+
+struct Input : torch::CustomClassHolder {
+  std::vector<int64_t> min_shape;
+  std::vector<int64_t> opt_shape;
+  std::vector<int64_t> max_shape;
+  std::vector<int64_t> shape;
+  DataType dtype;
+  TensorFormat format;
+  std::vector<double> tensor_domain;
+
+  Input() {}
+  TORCHTRT_API Input(std::vector<int64_t> shape, TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      std::vector<int64_t> shape,
+      std::vector<double> tensor_domain,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(std::vector<int64_t> shape, DataType dtype, TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      std::vector<int64_t> shape,
+      DataType dtype,
+      std::vector<double> tensor_domain,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(c10::ArrayRef<int64_t> shape, TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      c10::ArrayRef<int64_t> shape,
+      std::vector<double> tensor_domain,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(c10::ArrayRef<int64_t> shape, DataType dtype, TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      c10::ArrayRef<int64_t> shape,
+      DataType dtype,
+      std::vector<double> tensor_domain,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      std::vector<int64_t> min_shape,
+      std::vector<int64_t> opt_shape,
+      std::vector<int64_t> max_shape,
+      TensorFormat format = TensorFormat::kContiguous);
+  TORCHTRT_API Input(
+      std::vector<int64_t> min_shape,
+      std::vector<int64_t> opt_shape,
+      std::vector<int64_t> max_shape,
+      std::vector<double> tensor_domain,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      std::vector<int64_t> min_shape,
+      std::vector<int64_t> opt_shape,
+      std::vector<int64_t> max_shape,
+      DataType dtype,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      std::vector<int64_t> min_shape,
+      std::vector<int64_t> opt_shape,
+      std::vector<int64_t> max_shape,
+      DataType dtype,
+      std::vector<double> tensor_domain,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      c10::ArrayRef<int64_t> min_shape,
+      c10::ArrayRef<int64_t> opt_shape,
+      c10::ArrayRef<int64_t> max_shape,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      c10::ArrayRef<int64_t> min_shape,
+      c10::ArrayRef<int64_t> opt_shape,
+      c10::ArrayRef<int64_t> max_shape,
+      std::vector<double> tensor_domain,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      c10::ArrayRef<int64_t> min_shape,
+      c10::ArrayRef<int64_t> opt_shape,
+      c10::ArrayRef<int64_t> max_shape,
+      DataType dtype,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(
+      c10::ArrayRef<int64_t> min_shape,
+      c10::ArrayRef<int64_t> opt_shape,
+      c10::ArrayRef<int64_t> max_shape,
+      DataType dtype,
+      std::vector<double> tensor_domain,
+      TensorFormat format = TensorFormat::kContiguous);
+
+  TORCHTRT_API Input(at::Tensor tensor);
+
+ private:
+  friend TORCHTRT_API std::ostream& operator<<(std::ostream& os, const Input& input);
+  bool input_is_dynamic;
+};
+
+struct GraphInputs {
+  torch::jit::IValue input_signature; // nested Input, full input spec
+  std::vector<Input> inputs; // flatten input spec
+};
+
+TORCHTRT_API std::string get_build_info();
+
+TORCHTRT_API void dump_build_info();
+
+TORCHTRT_API void set_device(const int gpu_id);
+
+namespace torchscript {
+struct CompileSpec {
+  TORCHTRT_API CompileSpec(std::vector<std::vector<int64_t>> fixed_sizes);
+
+  TORCHTRT_API CompileSpec(std::vector<c10::ArrayRef<int64_t>> fixed_sizes);
+
+  TORCHTRT_API CompileSpec(std::vector<Input> inputs);
+
+  TORCHTRT_API CompileSpec(torch::jit::IValue input_signature);
+  // Defaults should reflect TensorRT defaults for BuilderConfig
+
+  GraphInputs graph_inputs;
+  std::set<DataType> enabled_precisions = {DataType::kFloat};
+
+  bool disable_tf32 = false;
+
+  bool sparse_weights = false;
+
+  bool refit = false;
+
+  bool debug = false;
+
+  bool truncate_long_and_double = false;
+
+  bool allow_shape_tensors = false;
+
+  Device device;
+
+  EngineCapability capability = EngineCapability::kSTANDARD;
+
+  uint64_t num_avg_timing_iters = 1;
+
+  uint64_t workspace_size = 0;
+
+  uint64_t dla_sram_size = 1048576;
+
+  uint64_t dla_local_dram_size = 1073741824;
+
+  uint64_t dla_global_dram_size = 536870912;
+
+  nvinfer1::IInt8Calibrator* ptq_calibrator = nullptr;
+
+  bool require_full_compilation = false;
+
+  uint64_t min_block_size = 3;
+
+  std::vector<std::string> torch_executed_ops;
+
+  std::vector<std::string> torch_executed_modules;
+};
+
+TORCHTRT_API bool check_method_operator_support(const torch::jit::Module& module, std::string method_name);
+
+TORCHTRT_API torch::jit::Module compile(const torch::jit::Module& module, CompileSpec info);
+
+TORCHTRT_API std::string convert_method_to_trt_engine(
+    const torch::jit::Module& module,
+    std::string method_name,
+    CompileSpec info);
+
+TORCHTRT_API torch::jit::Module embed_engine_in_new_module(
+    const std::string& engine,
+    Device device,
+    const std::vector<std::string>& input_binding_names = std::vector<std::string>(),
+    const std::vector<std::string>& output_binding_names = std::vector<std::string>());
+} // namespace torchscript
+} // namespace torch_tensorrt
+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1Device.html b/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1Device.html new file mode 100644 index 0000000000..24844a3053 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1Device.html @@ -0,0 +1,927 @@ + + + + + + + + + + + + + Struct Device — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Struct Device

+ +
+

Nested Relationships

+
+

Nested Types

+ +
+
+
+

Struct Documentation

+
+
+struct torch_tensorrt::Device
+

Setting data structure for Target device.

+
+

Public Functions

+
+
+inline Device()
+

Constructor for Device structure

+
+ +
+
+

Public Members

+
+
+DeviceType device_type
+

Setting data structure for device This struct will hold Target device related parameters such as device_type, gpu_id, dla_core.

+
+ +
+
+int64_t gpu_id
+
+ +
+
+int64_t dla_core
+
+ +
+
+bool allow_gpu_fallback
+

(Only used when targeting DLA (device)) Lets engine run layers on GPU if they are not supported on DLA

+
+ +
+
+
+class DeviceType
+

Supported Device Types that can be used with TensorRT engines

+

This class is compatable with c10::DeviceTypes (but will check for TRT support) but the only applicable value is at::kCUDA, which maps to DeviceType::kGPU

+

To use the DataType class itself, interface using the enum vs. normal instatination

+

ex. torch_tensorrt::DeviceType type = DeviceType::kGPU;

+
+

Public Types

+
+
+enum Value
+

Underlying enum class to support the DeviceType Class

+

In the case that you need to use the DeviceType class itself, interface using this enum vs. normal instatination

+

ex. torch_tensorrt::DeviceType type = DeviceType::kGPU;

+

Values:

+
+
+enumerator kGPU
+

Target GPU to run engine.

+
+ +
+
+enumerator kDLA
+

Target DLA to run engine.

+
+ +
+ +
+
+

Public Functions

+
+
+DeviceType() = default
+

Construct a new Device Type object.

+
+ +
+
+inline constexpr DeviceType(Value t)
+

Construct a new Device Type object from internal enum.

+
+ +
+
+DeviceType(c10::DeviceType t)
+

Construct a new Device Type object from torch device enums Note: The only valid value is torch::kCUDA (torch::kCPU is not supported)

+
+
Parameters
+

t

+
+
+
+ +
+
+inline operator Value() const
+

Get the internal value from the Device object.

+
+
Returns
+

Value

+
+
+
+ +
+
+explicit operator bool() = delete
+
+ +
+
+inline constexpr bool operator==(DeviceType other) const
+

Comparison operator for DeviceType.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+inline constexpr bool operator!=(DeviceType other) const
+

Comparison operator for DeviceType.

+
+
Parameters
+

other

+
+
Returns
+

true

+
+
Returns
+

false

+
+
+
+ +
+
+ +
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1GraphInputs.html b/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1GraphInputs.html new file mode 100644 index 0000000000..266d4519bf --- /dev/null +++ b/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1GraphInputs.html @@ -0,0 +1,785 @@ + + + + + + + + + + + + + Struct GraphInputs — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Struct GraphInputs

+ +
+

Struct Documentation

+
+
+struct torch_tensorrt::GraphInputs
+

A struct to hold complex inputs.

+

This struct can either hold a complex inputs of shape or a flattened one,

+
+

Public Members

+
+
+torch::jit::IValue input_signature
+
+ +
+
+std::vector<Input> inputs
+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1Input.html b/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1Input.html new file mode 100644 index 0000000000..299953a6df --- /dev/null +++ b/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1Input.html @@ -0,0 +1,1106 @@ + + + + + + + + + + + + + Struct Input — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Struct Input

+ +
+

Inheritance Relationships

+
+

Base Type

+
    +
  • public torch::CustomClassHolder

  • +
+
+
+
+

Struct Documentation

+
+
+struct torch_tensorrt::Input : public torch::CustomClassHolder
+

A struct to hold an input range (used by TensorRT Optimization profile)

+

This struct can either hold a single vector representing an input shape, signifying a static input shape or a set of three input shapes representing the min, optiminal and max input shapes allowed for the engine.

+
+

Public Functions

+
+
+inline Input()
+
+ +
+
+TORCHTRT_API Input(std::vector<int64_t> shape, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for static input size from vector, optional arguments allow the user to configure expected input shape tensor format. dtype (Expected data type for the input) defaults to PyTorch / traditional TRT convection (FP32 for FP32 only, FP16 for FP32 and FP16, FP32 for Int8)

+
+
Parameters
+
    +
  • shapeInput tensor shape

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(std::vector<int64_t> shape, std::vector<double> tensor_domain, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for static input size from c10::ArrayRef (the type produced by tensor.sizes()), vector, optional arguments allow the user to configure expected input shape tensor format dtype (Expected data type for the input) defaults to PyTorch / traditional TRT convection (FP32 for FP32 only, FP16 for FP32 and FP16, FP32 for Int8)

+
+
Parameters
+
    +
  • shapeInput tensor shape

  • +
  • tensor_domain – Allowed range for tensor inputs [low, high)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(std::vector<int64_t> shape, DataType dtype, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for static input size from vector, optional arguments allow the user to configure expected input shape tensor format.

+
+
Parameters
+
    +
  • shapeInput tensor shape

  • +
  • dtype – Expected data type for the input (Defaults to the type of the weights in the first tensor calculation if detectable else Float32)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(std::vector<int64_t> shape, DataType dtype, std::vector<double> tensor_domain, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for static input size from vector, optional arguments allow the user to configure expected input shape tensor format.

+
+
Parameters
+
    +
  • shapeInput tensor shape

  • +
  • dtype – Expected data type for the input (Defaults to the type of the weights in the first tensor calculation if detectable else Float32)

  • +
  • tensor_domain – Allowed range for tensor inputs [low, high)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(c10::ArrayRef<int64_t> shape, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for static input size from c10::ArrayRef (the type produced by tensor.sizes()), vector, optional arguments allow the user to configure expected input shape tensor format dtype (Expected data type for the input) defaults to PyTorch / traditional TRT convection (FP32 for FP32 only, FP16 for FP32 and FP16, FP32 for Int8)

+
+
Parameters
+
    +
  • shapeInput tensor shape

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(c10::ArrayRef<int64_t> shape, std::vector<double> tensor_domain, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for static input size from c10::ArrayRef (the type produced by tensor.sizes()), vector, optional arguments allow the user to configure expected input shape tensor format dtype (Expected data type for the input) defaults to PyTorch / traditional TRT convection (FP32 for FP32 only, FP16 for FP32 and FP16, FP32 for Int8)

+
+
Parameters
+
    +
  • shapeInput tensor shape

  • +
  • tensor_domain – Allowed range for tensor inputs [low, high)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(c10::ArrayRef<int64_t> shape, DataType dtype, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for static input size from c10::ArrayRef (the type produced by tensor.sizes()), vector, optional arguments allow the user to configure expected input shape tensor format.

+
+
Parameters
+
    +
  • shapeInput tensor shape

  • +
  • dtype – Expected data type for the input (Defaults to the type of the weights in the first tensor calculation if detectable else Float32)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(c10::ArrayRef<int64_t> shape, DataType dtype, std::vector<double> tensor_domain, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for static input size from c10::ArrayRef (the type produced by tensor.sizes()), vector, optional arguments allow the user to configure expected input shape tensor format.

+
+
Parameters
+
    +
  • shapeInput tensor shape

  • +
  • dtype – Expected data type for the input (Defaults to the type of the weights in the first tensor calculation if detectable else Float32)

  • +
  • tensor_domain – Allowed range for tensor inputs [low, high)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(std::vector<int64_t> min_shape, std::vector<int64_t> opt_shape, std::vector<int64_t> max_shape, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object dynamic input size from c10::ArrayRef (the type produced by tensor.sizes()) for min, opt, and max supported sizes. dtype (Expected data type for the input) defaults to PyTorch / traditional TRT convection (FP32 for FP32 only, FP16 for FP32 and FP16, FP32 for Int8)

+
+
Parameters
+
    +
  • min_shape – Minimum shape for input tensor

  • +
  • opt_shape – Target optimization shape for input tensor

  • +
  • max_shape – Maximum acceptible shape for input tensor

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(std::vector<int64_t> min_shape, std::vector<int64_t> opt_shape, std::vector<int64_t> max_shape, std::vector<double> tensor_domain, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object dynamic input size from c10::ArrayRef (the type produced by tensor.sizes()) for min, opt, and max supported sizes. dtype (Expected data type for the input) defaults to PyTorch / traditional TRT convection (FP32 for FP32 only, FP16 for FP32 and FP16, FP32 for Int8)

+
+
Parameters
+
    +
  • min_shape – Minimum shape for input tensor

  • +
  • opt_shape – Target optimization shape for input tensor

  • +
  • max_shape – Maximum acceptible shape for input tensor

  • +
  • tensor_domain – Allowed range for tensor inputs [low, high)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(std::vector<int64_t> min_shape, std::vector<int64_t> opt_shape, std::vector<int64_t> max_shape, DataType dtype, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for a dynamic input size from vectors for minimum shape, optimal shape, and max shape supported sizes optional arguments allow the user to configure expected input shape tensor format.

+
+
Parameters
+
    +
  • min_shape – Minimum shape for input tensor

  • +
  • opt_shape – Target optimization shape for input tensor

  • +
  • max_shape – Maximum acceptible shape for input tensor

  • +
  • dtype – Expected data type for the input (Defaults to the type of the weights in the first tensor calculation if detectable else Float32)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(std::vector<int64_t> min_shape, std::vector<int64_t> opt_shape, std::vector<int64_t> max_shape, DataType dtype, std::vector<double> tensor_domain, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object for a dynamic input size from vectors for minimum shape, optimal shape, and max shape supported sizes optional arguments allow the user to configure expected input shape tensor format.

+
+
Parameters
+
    +
  • min_shape – Minimum shape for input tensor

  • +
  • opt_shape – Target optimization shape for input tensor

  • +
  • max_shape – Maximum acceptible shape for input tensor

  • +
  • dtype – Expected data type for the input (Defaults to the type of the weights in the first tensor calculation if detectable else Float32)

  • +
  • tensor_domain – Allowed range for tensor inputs [low, high)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(c10::ArrayRef<int64_t> min_shape, c10::ArrayRef<int64_t> opt_shape, c10::ArrayRef<int64_t> max_shape, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object dynamic input size from c10::ArrayRef (the type produced by tensor.sizes()) for min, opt, and max supported sizes. dtype (Expected data type for the input) defaults to PyTorch / traditional TRT convection (FP32 for FP32 only, FP16 for FP32 and FP16, FP32 for Int8)

+
+
Parameters
+
    +
  • min_shape – Minimum shape for input tensor

  • +
  • opt_shape – Target optimization shape for input tensor

  • +
  • max_shape – Maximum acceptible shape for input tensor

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(c10::ArrayRef<int64_t> min_shape, c10::ArrayRef<int64_t> opt_shape, c10::ArrayRef<int64_t> max_shape, std::vector<double> tensor_domain, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object dynamic input size from c10::ArrayRef (the type produced by tensor.sizes()) for min, opt, and max supported sizes. dtype (Expected data type for the input) defaults to PyTorch / traditional TRT convection (FP32 for FP32 only, FP16 for FP32 and FP16, FP32 for Int8)

+
+
Parameters
+
    +
  • min_shape – Minimum shape for input tensor

  • +
  • opt_shape – Target optimization shape for input tensor

  • +
  • max_shape – Maximum acceptible shape for input tensor

  • +
  • tensor_domain – Allowed range for tensor inputs [low, high)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(c10::ArrayRef<int64_t> min_shape, c10::ArrayRef<int64_t> opt_shape, c10::ArrayRef<int64_t> max_shape, DataType dtype, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object dynamic input size from c10::ArrayRef (the type produced by tensor.sizes()) for min, opt, and max supported sizes.

+
+
Parameters
+
    +
  • min_shape – Minimum shape for input tensor

  • +
  • opt_shape – Target optimization shape for input tensor

  • +
  • max_shape – Maximum acceptible shape for input tensor

  • +
  • dtype – Expected data type for the input (Defaults to the type of the weights in the first tensor calculation if detectable else Float32)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(c10::ArrayRef<int64_t> min_shape, c10::ArrayRef<int64_t> opt_shape, c10::ArrayRef<int64_t> max_shape, DataType dtype, std::vector<double> tensor_domain, TensorFormat format = TensorFormat::kContiguous)
+

Construct a new Input spec object dynamic input size from c10::ArrayRef (the type produced by tensor.sizes()) for min, opt, and max supported sizes.

+
+
Parameters
+
    +
  • min_shape – Minimum shape for input tensor

  • +
  • opt_shape – Target optimization shape for input tensor

  • +
  • max_shape – Maximum acceptible shape for input tensor

  • +
  • dtype – Expected data type for the input (Defaults to the type of the weights in the first tensor calculation if detectable else Float32)

  • +
  • tensor_domain – Allowed range for tensor inputs [low, high)

  • +
  • format – Expected tensor format for the input (Defaults to contiguous)

  • +
+
+
+
+ +
+
+TORCHTRT_API Input(at::Tensor tensor)
+

Construct a new Input spec object using a torch tensor as an example The tensor’s shape, type and layout inform the spec’s values.

+

Note: You cannot set dynamic shape through this method, you must use an alternative constructor

+
+
Parameters
+

tensor – Reference tensor to set shape, type and layout

+
+
+
+ +
+
+

Public Members

+
+
+std::vector<int64_t> min_shape
+

Minimum acceptable input size into the engine.

+
+ +
+
+std::vector<int64_t> opt_shape
+

Optimal input size into the engine (size optimized for given kernels accept any size in min max range)

+
+ +
+
+std::vector<int64_t> max_shape
+

Maximum acceptable input size into the engine.

+
+ +
+
+std::vector<int64_t> shape
+

Input shape to be fed to TensorRT, in the event of a dynamic shape, -1’s will hold the place of variable dimensions

+
+ +
+
+DataType dtype
+

Expected data type for the input.

+
+ +
+
+TensorFormat format
+

Expected tensor format for the input.

+
+ +
+
+std::vector<double> tensor_domain
+

Expected allowed domain for tensor input.

+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec.html b/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec.html new file mode 100644 index 0000000000..f74862cf68 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec.html @@ -0,0 +1,945 @@ + + + + + + + + + + + + + Struct CompileSpec — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Struct CompileSpec

+ +
+

Struct Documentation

+
+
+struct torch_tensorrt::torchscript::CompileSpec
+

Settings data structure for Torch-TensorRT TorchScript compilation

+
+

Public Functions

+
+
+TORCHTRT_API CompileSpec(std::vector<std::vector<int64_t>> fixed_sizes)
+

Construct a new Compile Spec object Convienence constructor to set fixed input size from vectors describing size of input tensors. Each entry in the vector represents a input and should be provided in call order.

+

This constructor should be use as a convience in the case that all inputs are static sized and you are okay with default input dtype and formats (FP32 for FP32 and INT8 weights, FP16 for FP16 weights, contiguous)

+
+
Parameters
+

fixed_sizes

+
+
+
+ +
+
+TORCHTRT_API CompileSpec(std::vector<c10::ArrayRef<int64_t>> fixed_sizes)
+

Construct a new Compile Spec object Convienence constructor to set fixed input size from c10::ArrayRef’s (the output of tensor.sizes()) describing size of input tensors. Each entry in the vector represents a input and should be provided in call order.

+

This constructor should be use as a convience in the case that all inputs are static sized and you are okay with default input dtype and formats (FP32 for FP32 and INT8 weights, FP16 for FP16 weights, contiguous)

+
+
Parameters
+

fixed_sizes

+
+
+
+ +
+
+TORCHTRT_API CompileSpec(std::vector<Input> inputs)
+

Construct a new Compile Spec object from input ranges. Each entry in the vector represents a input and should be provided in call order.

+

Use this constructor to define inputs with dynamic shape, specific input types or tensor formats

+
+
Parameters
+

inputs

+
+
+
+ +
+
+TORCHTRT_API CompileSpec(torch::jit::IValue input_signature)
+

Construct a new Compile Spec object from IValue which represents the nesting of input tensors for a module.

+
+
Parameters
+

input_signature

+
+
+
+ +
+
+

Public Members

+
+
+GraphInputs graph_inputs
+

Specifications for inputs to the engine, can store a IValue which has stored complex Input or a flatened Input.

+
+ +
+
+std::set<DataType> enabled_precisions = {DataType::kFloat}
+

The set of precisions TensorRT is allowed to use for kernels during compilation.

+
+ +
+
+bool disable_tf32 = false
+

Prevent Float32 layers from using TF32 data format

+

TF32 computes inner products by rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas. This is the behavior of FP32 layers by default.

+
+ +
+
+bool sparse_weights = false
+

Enable sparsity for weights of conv and FC layers

+
+ +
+
+bool refit = false
+

Build a refitable engine

+
+ +
+
+bool debug = false
+

Build a debugable engine

+
+ +
+
+bool truncate_long_and_double = false
+

Truncate long/double type to int/float type

+
+ +
+
+bool allow_shape_tensors = false
+

Allow shape tensors (from IShape layer) in the graph

+
+ +
+
+Device device
+

Target Device

+
+ +
+
+EngineCapability capability = EngineCapability::kSTANDARD
+

Sets the restrictions for the engine (CUDA Safety)

+
+ +
+
+uint64_t num_avg_timing_iters = 1
+

Number of averaging timing iterations used to select kernels

+
+ +
+
+uint64_t workspace_size = 0
+

Maximum size of workspace given to TensorRT

+
+ +
+
+uint64_t dla_sram_size = 1048576
+

Fast software managed RAM used by DLA to communicate within a layer.

+
+ +
+
+uint64_t dla_local_dram_size = 1073741824
+

Host RAM used by DLA to share intermediate tensor data across operations

+
+ +
+
+uint64_t dla_global_dram_size = 536870912
+

host RAM used by DLA to store weights and metadata for execution

+
+ +
+
+nvinfer1::IInt8Calibrator *ptq_calibrator = nullptr
+

Calibration dataloaders for each input for post training quantizatiom

+
+ +
+
+bool require_full_compilation = false
+

Require the full module be compiled to TensorRT instead of potentially running unsupported operations in PyTorch

+
+ +
+
+uint64_t min_block_size = 3
+

Minimum number of contiguous supported operators to compile a subgraph to TensorRT

+
+ +
+
+std::vector<std::string> torch_executed_ops
+

List of aten operators that must be run in PyTorch. An error will be thrown if this list is not empty but require_full_compilation is True

+
+ +
+
+std::vector<std::string> torch_executed_modules
+

List of modules that must be run in PyTorch. An error will be thrown if this list is not empty but require_full_compilation is True

+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/torch_tensort_cpp.html b/docs/v2.2.0/_cpp_api/torch_tensort_cpp.html new file mode 100644 index 0000000000..4ed5a44972 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/torch_tensort_cpp.html @@ -0,0 +1,1152 @@ + + + + + + + + + + + + + Torch-TensorRT C++ API — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Torch-TensorRT C++ API
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Torch-TensorRT C++ API

+
+

Class Hierarchy

+
+
+

File Hierarchy

+
+
+

Full API

+
+

Namespaces

+ + + + + +
+
+

Classes and Structs

+ + + + + + + + + +
+
+

Enums

+ + +
+
+

Functions

+ + + + + + + + + + + + + + + + +
+
+

Defines

+ + + + + + + + +
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_cpp_api/unabridged_orphan.html b/docs/v2.2.0/_cpp_api/unabridged_orphan.html new file mode 100644 index 0000000000..b354a76b69 --- /dev/null +++ b/docs/v2.2.0/_cpp_api/unabridged_orphan.html @@ -0,0 +1,842 @@ + + + + + + + + + + + + + Full API — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+ + +
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_downloads/0daf1d0af656cac7b808856b71e6616f/torch_compile_resnet_example.ipynb b/docs/v2.2.0/_downloads/0daf1d0af656cac7b808856b71e6616f/torch_compile_resnet_example.ipynb new file mode 100644 index 0000000000..2aa89e8169 --- /dev/null +++ b/docs/v2.2.0/_downloads/0daf1d0af656cac7b808856b71e6616f/torch_compile_resnet_example.ipynb @@ -0,0 +1,158 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n\n# Compiling ResNet using the Torch-TensorRT `torch.compile` Backend\n\nThis interactive script is intended as a sample of the Torch-TensorRT workflow with `torch.compile` on a ResNet model.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports and Model Definition\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import torch\nimport torch_tensorrt\nimport torchvision.models as models" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Initialize model with half precision and sample inputs\nmodel = models.resnet18(pretrained=True).half().eval().to(\"cuda\")\ninputs = [torch.randn((1, 3, 224, 224)).to(\"cuda\").half()]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Optional Input Arguments to `torch_tensorrt.compile`\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Enabled precision for TensorRT optimization\nenabled_precisions = {torch.half}\n\n# Whether to print verbose logs\ndebug = True\n\n# Workspace size for TensorRT\nworkspace_size = 20 << 30\n\n# Maximum number of TRT Engines\n# (Lower value allows more graph segmentation)\nmin_block_size = 7\n\n# Operations to Run in Torch, regardless of converter support\ntorch_executed_ops = {}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compilation with `torch_tensorrt.compile`\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Build and compile the model with torch.compile, using Torch-TensorRT backend\noptimized_model = torch_tensorrt.compile(\n model,\n ir=\"torch_compile\",\n inputs=inputs,\n enabled_precisions=enabled_precisions,\n debug=debug,\n workspace_size=workspace_size,\n min_block_size=min_block_size,\n torch_executed_ops=torch_executed_ops,\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Equivalently, we could have run the above via the torch.compile frontend, as so:\n`optimized_model = torch.compile(model, backend=\"torch_tensorrt\", options={\"enabled_precisions\": enabled_precisions, ...}); optimized_model(*inputs)`\n\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inference\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Does not cause recompilation (same batch size as input)\nnew_inputs = [torch.randn((1, 3, 224, 224)).half().to(\"cuda\")]\nnew_outputs = optimized_model(*new_inputs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Does cause recompilation (new batch size)\nnew_batch_size_inputs = [torch.randn((8, 3, 224, 224)).half().to(\"cuda\")]\nnew_batch_size_outputs = optimized_model(*new_batch_size_inputs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cleanup\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Finally, we use Torch utilities to clean up the workspace\ntorch._dynamo.reset()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cuda Driver Error Note\n\nOccasionally, upon exiting the Python runtime after Dynamo compilation with `torch_tensorrt`,\none may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052\nand can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in::\n\n if __name__ == '__main__':\n compile_engine_and_infer()\n\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/v2.2.0/_downloads/0e30a6276601af7e5fc4d5166e2e3d37/torch_compile_advanced_usage.py b/docs/v2.2.0/_downloads/0e30a6276601af7e5fc4d5166e2e3d37/torch_compile_advanced_usage.py new file mode 100644 index 0000000000..8ebedab111 --- /dev/null +++ b/docs/v2.2.0/_downloads/0e30a6276601af7e5fc4d5166e2e3d37/torch_compile_advanced_usage.py @@ -0,0 +1,107 @@ +""" +.. _torch_compile_advanced_usage: + +Torch Compile Advanced Usage +====================================================== + +This interactive script is intended as an overview of the process by which `torch_tensorrt.compile(..., ir="torch_compile", ...)` works, and how it integrates with the `torch.compile` API.""" + +# %% +# Imports and Model Definition +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +import torch +import torch_tensorrt + +# %% + + +# We begin by defining a model +class Model(torch.nn.Module): + def __init__(self) -> None: + super().__init__() + self.relu = torch.nn.ReLU() + + def forward(self, x: torch.Tensor, y: torch.Tensor): + x_out = self.relu(x) + y_out = self.relu(y) + x_y_out = x_out + y_out + return torch.mean(x_y_out) + + +# %% +# Compilation with `torch.compile` Using Default Settings +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Define sample float inputs and initialize model +sample_inputs = [torch.rand((5, 7)).cuda(), torch.rand((5, 7)).cuda()] +model = Model().eval().cuda() + +# %% + +# Next, we compile the model using torch.compile +# For the default settings, we can simply call torch.compile +# with the backend "torch_tensorrt", and run the model on an +# input to cause compilation, as so: +optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False) +optimized_model(*sample_inputs) + +# %% +# Compilation with `torch.compile` Using Custom Settings +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# First, we use Torch utilities to clean up the workspace +# after the previous compile invocation +torch._dynamo.reset() + +# Define sample half inputs and initialize model +sample_inputs_half = [ + torch.rand((5, 7)).half().cuda(), + torch.rand((5, 7)).half().cuda(), +] +model_half = Model().eval().cuda() + +# %% + +# If we want to customize certain options in the backend, +# but still use the torch.compile call directly, we can provide +# custom options to the backend via the "options" keyword +# which takes in a dictionary mapping options to values. +# +# For accepted backend options, see the CompilationSettings dataclass: +# py/torch_tensorrt/dynamo/_settings.py +backend_kwargs = { + "enabled_precisions": {torch.half}, + "debug": True, + "min_block_size": 2, + "torch_executed_ops": {"torch.ops.aten.sub.Tensor"}, + "optimization_level": 4, + "use_python_runtime": False, +} + +# Run the model on an input to cause compilation, as so: +optimized_model_custom = torch.compile( + model_half, + backend="torch_tensorrt", + options=backend_kwargs, + dynamic=False, +) +optimized_model_custom(*sample_inputs_half) + +# %% +# Cleanup +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Finally, we use Torch utilities to clean up the workspace +torch._dynamo.reset() + +# %% +# Cuda Driver Error Note +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# Occasionally, upon exiting the Python runtime after Dynamo compilation with `torch_tensorrt`, +# one may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052 +# and can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in:: +# +# if __name__ == '__main__': +# compile_engine_and_infer() diff --git a/docs/v2.2.0/_downloads/26d49aeeb9c710e27197fda28b7c3516/yi_jing_01_chien.jpg b/docs/v2.2.0/_downloads/26d49aeeb9c710e27197fda28b7c3516/yi_jing_01_chien.jpg new file mode 100644 index 0000000000000000000000000000000000000000..523dc2b8b868fa53e3b960d7017908dae486eecb GIT binary patch literal 6614 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_downloads/46b3e6febaab06324aa2715896895544/torch_compile_stable_diffusion.py b/docs/v2.2.0/_downloads/46b3e6febaab06324aa2715896895544/torch_compile_stable_diffusion.py new file mode 100644 index 0000000000..0511e5a363 --- /dev/null +++ b/docs/v2.2.0/_downloads/46b3e6febaab06324aa2715896895544/torch_compile_stable_diffusion.py @@ -0,0 +1,55 @@ +""" +.. _torch_compile_stable_diffusion: + +Torch Compile Stable Diffusion +====================================================== + +This interactive script is intended as a sample of the Torch-TensorRT workflow with `torch.compile` on a Stable Diffusion model. A sample output is featured below: + +.. image:: /tutorials/images/majestic_castle.png + :width: 512px + :height: 512px + :scale: 50 % + :align: right +""" + +# %% +# Imports and Model Definition +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +import torch +from diffusers import DiffusionPipeline + +import torch_tensorrt + +model_id = "CompVis/stable-diffusion-v1-4" +device = "cuda:0" + +# Instantiate Stable Diffusion Pipeline with FP16 weights +pipe = DiffusionPipeline.from_pretrained( + model_id, revision="fp16", torch_dtype=torch.float16 +) +pipe = pipe.to(device) + +backend = "torch_tensorrt" + +# Optimize the UNet portion with Torch-TensorRT +pipe.unet = torch.compile( + pipe.unet, + backend=backend, + options={ + "truncate_long_and_double": True, + "precision": torch.float16, + }, + dynamic=False, +) + +# %% +# Inference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +prompt = "a majestic castle in the clouds" +image = pipe(prompt).images[0] + +image.save("images/majestic_castle.png") +image.show() diff --git a/docs/v2.2.0/_downloads/6a6052d9668b2cb8332d349d328e21c1/_rendered_examples_jupyter.zip b/docs/v2.2.0/_downloads/6a6052d9668b2cb8332d349d328e21c1/_rendered_examples_jupyter.zip new file mode 100644 index 0000000000000000000000000000000000000000..92d2e60a37ddb76bf82616477d1e659d1a43dce7 GIT binary patch literal 18798 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_downloads/798cda8f83bd9f5e2cc93f329a04332c/_rendered_examples_python.zip b/docs/v2.2.0/_downloads/798cda8f83bd9f5e2cc93f329a04332c/_rendered_examples_python.zip new file mode 100644 index 0000000000000000000000000000000000000000..baee9e53e57d9c067404ce12eb4d4d4094205ac9 GIT binary patch literal 10824 zcmeHN&2QYs72h;&4{Q%T1U(cz3@EtSbyr+T{z$OR7O*V~5FFcrBPRg@hvJg6yR5h* z%OO|V7(V3QYyW|sdMwcVH3iy3{)ryj-+MFUlKWxFGUDdoH6(dCGjHC!d7r<>qlfQb z`=CXiU;X*fmxurT>)-!jwOaJ^TRaQqu{TY6d6M}P*H5Nt7)dviDweq`&%J3HNhh7# zwrx3%aMw-iTh@JE7sg}pRI0}^7looP`9z9iBD{SpW0ho2kHra7aLh(0;-2T9$~dqF zSN>Sm@g!6tjB}ZJejd)GP<|GsxiC-TKnB87!V`**Ba+cN&d!qTbQC3L;w;Q3D|{v~ z)|USXRiZ1xu#!#m!l4 zS>AX$3l+#Z%muboLjTV&L)_5DUKD;K^^iW%#EV8E&7{xEnN=f?FiwkHSxiO@3^_;Z z!0yLwtjRMkjAbx5&I;Lah*G=b$e9=6PoA`GzX&|LV`)Ml@s+;i4DyKE?cJ`p*%f!8m>4iQLo&6%{gVmGMnF|6o8JjQ(} zjJH2c&hQ*pQApuM&|lJrOp0;lr4ym#n8e5D>R8h-c85{opO!m)L|Z&bVK{Vf7V^^~ zhAnBc?TSo}y)1~NQna<7#5g7FOsFCyjkj1R@DtK6av8Wu%A#Tcv0-S(z|`w@b+tRZ zSA-EP88&9z2b-~0TQ*vKMP{&ToX~O80S%4AF*gpTOTE`;DNU}_uC^uc;W=IYZDiJ5S@Vx@24rj`NPwRIZ?o{FwxevP|D~AMlyN(shGgt3? zv2!%ub>UW@^YWy~$xCDXk~rHp7SzjoELmO4CZ^Z8)XXv0>=icg`SG$7-@s>$(giHn zW|~{6F6DkCy|_p(b0r5MqJ_~_x|3rvcTwbFgdm99f`9gjnkZ6M*UFHz?{Zw708zM; zdAk(gmbj0QCiXL=6Pb9BWe66Jll)>O*#gf`eBYxGt@$ca;?`bmty?#-e1FiuK)keaNp>j<3|DTTm*Oem9)2NzB9nB;k? z`n}#5iB2&jGweP7{BZy9Zm*1oy^xlv-rmmbJ#5G>7a|;z%Bv)rfzEI)&JbeK@>DfT z=!Kj1M8PuL$EloCP-1pKv5x7n!MaT`?Gl4_$YP z6vTBuB#*NA7#HkH4u~!`fd0auagj%jwD-~Xt*w7uYqjX7y(#TgIVA~h5ROJ*6FJtV z#CLfjQedrj_jLj-K4VH^zoc}<{Pr#8w#yvrkmrcIRo2W7h*W7Ly}Zas2PE{2KvmDzpa33=Ul9=G8?Wg{h2?do{E6Dxa}*7VU-s z9JNi_@Oh|uT3xm)z1p7bZr`$zB+f!)gqTSAbAN~HiNhGP;Td48D_SJV-E}T?aI|{| zA)2J2tQ3ra)C!{x9f(p{lf&2Y8E{D%o~|bb_9)%GgJ8??+zs-1Ds`^lpepk6-8;w< z%qH}Q@_u~)_)HVJ=_q=66}-u%KhepxWdHk&%0tQ>$suso#+Fl6h`fhWp!@_iCRXJM zoPP1%G^`VxGHEb>^}{M(;1%R8>>TdahfLiliO1|Gf~0`4BYmJ8U9aPrRo0Ioy}voX zp7T=w;iwV%g9B(fRxjelYvdCtZU$v4gyzAYYb$|6Br74uNvW0}B}JfY)PFE9%%sz! zAft61M;q8zJE)%czm7td*0wj>9hGQA$WfEzY{f<1`UaOQTY_Eq3Dv~Q+#zwW8vkn)>cS#t&xmO1gv{k;zdRP%8!bK1{tRFK7!58!ng?LjGqVzT=xc7@o zKLYfqykoqwk*J@_IjRaE6D3$>)skWN^bF4#7GV{?bP20xGa`UUR6_>rs)XT!4TH@G z+7#?29DrHP2WA#qOas6v!(QWI*J5>h8wgB!E44&L^IC@b=VlPWb=6jN)QG)?dwoN`4tB{}=|Uygp! zYSGWeE}|FAJh;NZEff_Uo4}Ojv=u1juAw5H5tSJ^r-_#|PsH7$ z!?#;M=p>k;;1@`DBpOY0@__r9Krm6Nat+}}9%RDxL|dobaqQr05y?)U-6WO(!=o;! z>$a7QMjf&J2cW32)Z-MQ(MKY%&Z*{gcqtEI1yI?jsBi#m@Kk>Kj6hnNK=e_GBE1Tj zd{>;86}v7SyJFsaU>Kvt=M*wPnfT&e+UJX{=PQHr#o)PH4r>~}6a2m68%Rr$p?c?f zb_(RVZB~G7En7Hbh6z_--o>pyEOU#J{l=IdzBL6|9hL9f?K zL63mj7<5$t&}Ly$sH#gF#skdZuU%sJNYpu)E@zw#`;2I@0 zttz9&mz-sEx+H#qVjqsES$YQKmQ{u&Pdz{%FbEnKWi5h3u{u|9<(3%24*?&KB3OWi zNc9Pf5^2p2Li8G|mMqjBL1`8Sq~yN7WmD|X?sN&I#+O}M+l<@7RI6kj9L;j?6!8aq zd4RpSPvd2C;E}quQzOgo7$}FEG-Q^Z@5_{0O66W=ZWm5fAEc(Ir4ow3%RP=AlzF6c z^Wsri6ZP04lAc@IIkJWlUA|l;U4Ku*)VO60y#RVwi{rgl)x$5e-*E7HgM(-tI|^+x z9b;^R2eW+3H%Qz_&SZo_`j(-Jn{`ue`?;p=hd~1!b7B3|wAO1b=n4+VHM+1CIA_wV z&6+85Ypd;cwhwcc12fCWUaxF;tu>{zVWWMc;l6n5nh$$dlf0`*-nhm4-cLSwfAhPI zXkzf^yKm`_aV_j!H^1q4^sq^DxpAy1wp!nP`yaePxt6AG_chwc%T$+pEeoo@{^bU$ sbx6O~d0D2sT$wE>AN*zm literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_downloads/b35883282793ac3413933fdb22d00d81/torch_compile_advanced_usage.ipynb b/docs/v2.2.0/_downloads/b35883282793ac3413933fdb22d00d81/torch_compile_advanced_usage.ipynb new file mode 100644 index 0000000000..1d2c305b62 --- /dev/null +++ b/docs/v2.2.0/_downloads/b35883282793ac3413933fdb22d00d81/torch_compile_advanced_usage.ipynb @@ -0,0 +1,144 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n\n# Torch Compile Advanced Usage\n\nThis interactive script is intended as an overview of the process by which `torch_tensorrt.compile(..., ir=\"torch_compile\", ...)` works, and how it integrates with the `torch.compile` API.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports and Model Definition\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import torch\nimport torch_tensorrt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# We begin by defining a model\nclass Model(torch.nn.Module):\n def __init__(self) -> None:\n super().__init__()\n self.relu = torch.nn.ReLU()\n\n def forward(self, x: torch.Tensor, y: torch.Tensor):\n x_out = self.relu(x)\n y_out = self.relu(y)\n x_y_out = x_out + y_out\n return torch.mean(x_y_out)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compilation with `torch.compile` Using Default Settings\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Define sample float inputs and initialize model\nsample_inputs = [torch.rand((5, 7)).cuda(), torch.rand((5, 7)).cuda()]\nmodel = Model().eval().cuda()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Next, we compile the model using torch.compile\n# For the default settings, we can simply call torch.compile\n# with the backend \"torch_tensorrt\", and run the model on an\n# input to cause compilation, as so:\noptimized_model = torch.compile(model, backend=\"torch_tensorrt\", dynamic=False)\noptimized_model(*sample_inputs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compilation with `torch.compile` Using Custom Settings\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# First, we use Torch utilities to clean up the workspace\n# after the previous compile invocation\ntorch._dynamo.reset()\n\n# Define sample half inputs and initialize model\nsample_inputs_half = [\n torch.rand((5, 7)).half().cuda(),\n torch.rand((5, 7)).half().cuda(),\n]\nmodel_half = Model().eval().cuda()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# If we want to customize certain options in the backend,\n# but still use the torch.compile call directly, we can provide\n# custom options to the backend via the \"options\" keyword\n# which takes in a dictionary mapping options to values.\n#\n# For accepted backend options, see the CompilationSettings dataclass:\n# py/torch_tensorrt/dynamo/_settings.py\nbackend_kwargs = {\n \"enabled_precisions\": {torch.half},\n \"debug\": True,\n \"min_block_size\": 2,\n \"torch_executed_ops\": {\"torch.ops.aten.sub.Tensor\"},\n \"optimization_level\": 4,\n \"use_python_runtime\": False,\n}\n\n# Run the model on an input to cause compilation, as so:\noptimized_model_custom = torch.compile(\n model_half,\n backend=\"torch_tensorrt\",\n options=backend_kwargs,\n dynamic=False,\n)\noptimized_model_custom(*sample_inputs_half)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cleanup\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Finally, we use Torch utilities to clean up the workspace\ntorch._dynamo.reset()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cuda Driver Error Note\n\nOccasionally, upon exiting the Python runtime after Dynamo compilation with `torch_tensorrt`,\none may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052\nand can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in::\n\n if __name__ == '__main__':\n compile_engine_and_infer()\n\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/v2.2.0/_downloads/b776287bc876f7ce24942b82a66beb05/torch_compile_stable_diffusion.ipynb b/docs/v2.2.0/_downloads/b776287bc876f7ce24942b82a66beb05/torch_compile_stable_diffusion.ipynb new file mode 100644 index 0000000000..cceefefcc1 --- /dev/null +++ b/docs/v2.2.0/_downloads/b776287bc876f7ce24942b82a66beb05/torch_compile_stable_diffusion.ipynb @@ -0,0 +1,68 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n\n# Torch Compile Stable Diffusion\n\nThis interactive script is intended as a sample of the Torch-TensorRT workflow with `torch.compile` on a Stable Diffusion model. A sample output is featured below:\n\n\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports and Model Definition\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import torch\nfrom diffusers import DiffusionPipeline\n\nimport torch_tensorrt\n\nmodel_id = \"CompVis/stable-diffusion-v1-4\"\ndevice = \"cuda:0\"\n\n# Instantiate Stable Diffusion Pipeline with FP16 weights\npipe = DiffusionPipeline.from_pretrained(\n model_id, revision=\"fp16\", torch_dtype=torch.float16\n)\npipe = pipe.to(device)\n\nbackend = \"torch_tensorrt\"\n\n# Optimize the UNet portion with Torch-TensorRT\npipe.unet = torch.compile(\n pipe.unet,\n backend=backend,\n options={\n \"truncate_long_and_double\": True,\n \"precision\": torch.float16,\n },\n dynamic=False,\n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inference\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "prompt = \"a majestic castle in the clouds\"\nimage = pipe(prompt).images[0]\n\nimage.save(\"images/majestic_castle.png\")\nimage.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/v2.2.0/_downloads/ce102e287ddb5744f0a1364e8c0c7f68/torch_compile_transformers_example.ipynb b/docs/v2.2.0/_downloads/ce102e287ddb5744f0a1364e8c0c7f68/torch_compile_transformers_example.ipynb new file mode 100644 index 0000000000..6a649f6b38 --- /dev/null +++ b/docs/v2.2.0/_downloads/ce102e287ddb5744f0a1364e8c0c7f68/torch_compile_transformers_example.ipynb @@ -0,0 +1,158 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n\n# Compiling a Transformer using torch.compile and TensorRT\n\nThis interactive script is intended as a sample of the Torch-TensorRT workflow with `torch.compile` on a transformer-based model.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports and Model Definition\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import torch\nimport torch_tensorrt\nfrom transformers import BertModel" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Initialize model with float precision and sample inputs\nmodel = BertModel.from_pretrained(\"bert-base-uncased\").eval().to(\"cuda\")\ninputs = [\n torch.randint(0, 2, (1, 14), dtype=torch.int32).to(\"cuda\"),\n torch.randint(0, 2, (1, 14), dtype=torch.int32).to(\"cuda\"),\n]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Optional Input Arguments to `torch_tensorrt.compile`\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Enabled precision for TensorRT optimization\nenabled_precisions = {torch.float}\n\n# Whether to print verbose logs\ndebug = True\n\n# Workspace size for TensorRT\nworkspace_size = 20 << 30\n\n# Maximum number of TRT Engines\n# (Lower value allows more graph segmentation)\nmin_block_size = 7\n\n# Operations to Run in Torch, regardless of converter support\ntorch_executed_ops = {}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Compilation with `torch.compile`\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Define backend compilation keyword arguments\ncompilation_kwargs = {\n \"enabled_precisions\": enabled_precisions,\n \"debug\": debug,\n \"workspace_size\": workspace_size,\n \"min_block_size\": min_block_size,\n \"torch_executed_ops\": torch_executed_ops,\n}\n\n# Build and compile the model with torch.compile, using Torch-TensorRT backend\noptimized_model = torch.compile(\n model,\n backend=\"torch_tensorrt\",\n dynamic=False,\n options=compilation_kwargs,\n)\noptimized_model(*inputs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Equivalently, we could have run the above via the convenience frontend, as so:\n`torch_tensorrt.compile(model, ir=\"torch_compile\", inputs=inputs, **compilation_kwargs)`\n\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Inference\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Does not cause recompilation (same batch size as input)\nnew_inputs = [\n torch.randint(0, 2, (1, 14), dtype=torch.int32).to(\"cuda\"),\n torch.randint(0, 2, (1, 14), dtype=torch.int32).to(\"cuda\"),\n]\nnew_outputs = optimized_model(*new_inputs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Does cause recompilation (new batch size)\nnew_inputs = [\n torch.randint(0, 2, (4, 14), dtype=torch.int32).to(\"cuda\"),\n torch.randint(0, 2, (4, 14), dtype=torch.int32).to(\"cuda\"),\n]\nnew_outputs = optimized_model(*new_inputs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cleanup\n\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Finally, we use Torch utilities to clean up the workspace\ntorch._dynamo.reset()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cuda Driver Error Note\n\nOccasionally, upon exiting the Python runtime after Dynamo compilation with `torch_tensorrt`,\none may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052\nand can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in::\n\n if __name__ == '__main__':\n compile_engine_and_infer()\n\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/v2.2.0/_downloads/d6e1bb6ec5f884994554d9d12e37a0f6/torch_compile_resnet_example.py b/docs/v2.2.0/_downloads/d6e1bb6ec5f884994554d9d12e37a0f6/torch_compile_resnet_example.py new file mode 100644 index 0000000000..9015538fec --- /dev/null +++ b/docs/v2.2.0/_downloads/d6e1bb6ec5f884994554d9d12e37a0f6/torch_compile_resnet_example.py @@ -0,0 +1,93 @@ +""" +.. _torch_compile_resnet: + +Compiling ResNet using the Torch-TensorRT `torch.compile` Backend +========================================================== + +This interactive script is intended as a sample of the Torch-TensorRT workflow with `torch.compile` on a ResNet model.""" + +# %% +# Imports and Model Definition +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +import torch +import torch_tensorrt +import torchvision.models as models + +# %% + +# Initialize model with half precision and sample inputs +model = models.resnet18(pretrained=True).half().eval().to("cuda") +inputs = [torch.randn((1, 3, 224, 224)).to("cuda").half()] + +# %% +# Optional Input Arguments to `torch_tensorrt.compile` +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Enabled precision for TensorRT optimization +enabled_precisions = {torch.half} + +# Whether to print verbose logs +debug = True + +# Workspace size for TensorRT +workspace_size = 20 << 30 + +# Maximum number of TRT Engines +# (Lower value allows more graph segmentation) +min_block_size = 7 + +# Operations to Run in Torch, regardless of converter support +torch_executed_ops = {} + +# %% +# Compilation with `torch_tensorrt.compile` +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Build and compile the model with torch.compile, using Torch-TensorRT backend +optimized_model = torch_tensorrt.compile( + model, + ir="torch_compile", + inputs=inputs, + enabled_precisions=enabled_precisions, + debug=debug, + workspace_size=workspace_size, + min_block_size=min_block_size, + torch_executed_ops=torch_executed_ops, +) + +# %% +# Equivalently, we could have run the above via the torch.compile frontend, as so: +# `optimized_model = torch.compile(model, backend="torch_tensorrt", options={"enabled_precisions": enabled_precisions, ...}); optimized_model(*inputs)` + +# %% +# Inference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Does not cause recompilation (same batch size as input) +new_inputs = [torch.randn((1, 3, 224, 224)).half().to("cuda")] +new_outputs = optimized_model(*new_inputs) + +# %% + +# Does cause recompilation (new batch size) +new_batch_size_inputs = [torch.randn((8, 3, 224, 224)).half().to("cuda")] +new_batch_size_outputs = optimized_model(*new_batch_size_inputs) + +# %% +# Cleanup +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Finally, we use Torch utilities to clean up the workspace +torch._dynamo.reset() + +# %% +# Cuda Driver Error Note +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# Occasionally, upon exiting the Python runtime after Dynamo compilation with `torch_tensorrt`, +# one may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052 +# and can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in:: +# +# if __name__ == '__main__': +# compile_engine_and_infer() diff --git a/docs/v2.2.0/_downloads/dfa60e8f9850fd7761f3e7da81304d32/torch_compile_transformers_example.py b/docs/v2.2.0/_downloads/dfa60e8f9850fd7761f3e7da81304d32/torch_compile_transformers_example.py new file mode 100644 index 0000000000..01d46e96f6 --- /dev/null +++ b/docs/v2.2.0/_downloads/dfa60e8f9850fd7761f3e7da81304d32/torch_compile_transformers_example.py @@ -0,0 +1,109 @@ +""" +.. _torch_compile_transformer: + +Compiling a Transformer using torch.compile and TensorRT +============================================================== + +This interactive script is intended as a sample of the Torch-TensorRT workflow with `torch.compile` on a transformer-based model.""" + +# %% +# Imports and Model Definition +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +import torch +import torch_tensorrt +from transformers import BertModel + +# %% + +# Initialize model with float precision and sample inputs +model = BertModel.from_pretrained("bert-base-uncased").eval().to("cuda") +inputs = [ + torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"), + torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"), +] + + +# %% +# Optional Input Arguments to `torch_tensorrt.compile` +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Enabled precision for TensorRT optimization +enabled_precisions = {torch.float} + +# Whether to print verbose logs +debug = True + +# Workspace size for TensorRT +workspace_size = 20 << 30 + +# Maximum number of TRT Engines +# (Lower value allows more graph segmentation) +min_block_size = 7 + +# Operations to Run in Torch, regardless of converter support +torch_executed_ops = {} + +# %% +# Compilation with `torch.compile` +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Define backend compilation keyword arguments +compilation_kwargs = { + "enabled_precisions": enabled_precisions, + "debug": debug, + "workspace_size": workspace_size, + "min_block_size": min_block_size, + "torch_executed_ops": torch_executed_ops, +} + +# Build and compile the model with torch.compile, using Torch-TensorRT backend +optimized_model = torch.compile( + model, + backend="torch_tensorrt", + dynamic=False, + options=compilation_kwargs, +) +optimized_model(*inputs) + +# %% +# Equivalently, we could have run the above via the convenience frontend, as so: +# `torch_tensorrt.compile(model, ir="torch_compile", inputs=inputs, **compilation_kwargs)` + +# %% +# Inference +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Does not cause recompilation (same batch size as input) +new_inputs = [ + torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"), + torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"), +] +new_outputs = optimized_model(*new_inputs) + +# %% + +# Does cause recompilation (new batch size) +new_inputs = [ + torch.randint(0, 2, (4, 14), dtype=torch.int32).to("cuda"), + torch.randint(0, 2, (4, 14), dtype=torch.int32).to("cuda"), +] +new_outputs = optimized_model(*new_inputs) + +# %% +# Cleanup +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +# Finally, we use Torch utilities to clean up the workspace +torch._dynamo.reset() + +# %% +# Cuda Driver Error Note +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# Occasionally, upon exiting the Python runtime after Dynamo compilation with `torch_tensorrt`, +# one may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052 +# and can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in:: +# +# if __name__ == '__main__': +# compile_engine_and_infer() diff --git a/docs/v2.2.0/_images/majestic_castle.png b/docs/v2.2.0/_images/majestic_castle.png new file mode 100644 index 0000000000000000000000000000000000000000..bac6073a90ffd98c9818efb9d54640c62139070d GIT binary patch literal 505948 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

!8v@c6 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 z%0D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

(OV4@CISIHFyilq)9%?fT`|mNb*$U1aB-yU? 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%0DM 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

Zwyc^`2_{_NjLxqDEoG#eL+z{pY1Es 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

WMX%%y}I7e?#0Y4U3iB{@d1X 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_images/sphx_glr_torch_compile_resnet_example_thumb.png b/docs/v2.2.0/_images/sphx_glr_torch_compile_resnet_example_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..8a5fed589d17fe6ee62d6a9788519dba471fbd65 GIT binary patch literal 26794 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_images/sphx_glr_torch_compile_stable_diffusion_thumb.png b/docs/v2.2.0/_images/sphx_glr_torch_compile_stable_diffusion_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..8a5fed589d17fe6ee62d6a9788519dba471fbd65 GIT binary patch literal 26794 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_images/sphx_glr_torch_compile_transformers_example_thumb.png b/docs/v2.2.0/_images/sphx_glr_torch_compile_transformers_example_thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..8a5fed589d17fe6ee62d6a9788519dba471fbd65 GIT binary patch literal 26794 zcmd3N^;cV6&~zU%f(#fBBGMqQ6{mHpumQ z^~%~w0VJvEnR)nlooKF`yb|H}xA|C<^cUE&K&!B{#ar*%RrUI{fOnuSCL$03!--#| zXbLuXBIIR=G00EgrNBb5!{Wg0L?-(}Cu?Haf+0F7%3dlH!I7q$mL$Yecj9<`jSzfT z^D5Zgt0)_Z#Ecth&8aB^q#^tt+jp*g;+l3Kuta%Af{32Sylxr^V1hg&jmnR}mkXfv zAbI2;{|#XPvE=`E0PeA)C<&;HFH;EcKm_ss4Tt~~BwnThPbCg5(+AS2SjXlQXBFG6FYU#Fiz_d=HGDi{5xv>!;RVHaotlES;Y{+4GrXjSnu(wiwX$)Rm{msq2XKT(PDE-xEgi z_(VivIE9l($F=w;5%X502cyd9S;o)?@*@IUt%-#RKi)is3GxWf#e9B1a0p}-K^GkH zE#RcLH-hEomo}wtS-`xST`geg^-vL1i@Xk;hL(*ihFVL8OfGro z7;=ZwLXX%~LDV&-I)%f^Zc@iBUPr)DOdL&SY8Fe4jRr0M^?OY#0}B$nzJ&L1In9Al zQOK9T4G@xxBY?1&=&}M<$uJ+xfTKBW>PRAN(VR;B>we1G_F=pv`)g>`Z^uYRx_jEF zLgunT}hWZL=J)o}-tSc-H43?kvu z2VGc#wT9ESOGB&rE@vy9Zz3|&#)3Ae*}ua?Sht~cbom|GLpPlTSm&X z8g90~9$!qLFeLh!xc`P0$(R$Ja&h&6EezoO__ACMkpyr*-p^zc6Sxuga|EOJ~>i$53|i zk3uPR?4WZH-H$~ya%J$=ipQkS-owRa4tw(P{%YPDc|taynH>AT=I|^o0}49wU~C{J zauK2=H85m@3Fzliq*hcd5LX*{uUE#$CpBIVU20AE#`cp-cs73fa2V=^W|F4HJO04v zh?+`+`1w}s-C)?|2Q&Bi)%tp}=My{T_L}AL?X!5%*(mp1+HX=ICa0VpGHL53#n?|w zrsVN!1h2aM0663#mGa+wr{K=E&1QL;2u+|ml4!Vcv|H~i8eectf>jNDUkq^angTdW z)#m!O%sOuC%7f^!Qht!qCw#tfe81zkyyL#c-mQq;u_=hU8Y&X0P3ZX%SuC=j%cBp_ zr)IOhDL^juo$ys}!om$%Q`tjo6J*I-hLpYq;KY(EwP$7&><+R6Cs-uf#l&-#?&}Uc z2}fsB6#K32O!O58@ksbMFteP}G2(2lnU(Xx0EQ{|6Fyl`z1ErflfT{pGkLUjTO->; z)k=c&e_nqG{-=f;xxac&YcIobydWM*>-WCPDRj}<`M?J$>U-1W=e@wPjOqn`WB6h3 zK~jXSxO+anw%MV<(bYq5#QL@?&$9}E9mOt!yYPhfLyOPk<($)-DALZ(Z<${Ys2e!I zEf@cqbht`&4b(^c=S@?tyU^-%7nsg>47yyUusdaMN|9?WoX_ry|GMNc@rE*&1ZWvhRi z_S3m-n`bk(@O+$m8Kp&CbTqx#!3Ro^Y+#WD0wD>iyApzndvKsR&ejCNHW0D$L?Y{& z-+!(ex(HR2t+z8ezJ13p%e#_pEzeK4BMasjYdnwJ?s{s>RYi;(GFI&ez1i>3C&Ca}f(#daZAeX;DyOc))i?10TL3cyU9coSu% z)362xbDc4*fSbB%;E}Qhj(t3Y;h0y44|>PJ{Wnh8tcJHxpgfb*cWZ`3JyR%I1eX@D zhJN6ES7k-g^nBRA6+Lz{hr;f=v9U%{mDsRr?D`_~Bl#>!q2hGpQrdVLN8GXyT@?Oz z+7-##Pu6db%j-<<)!r^-I*w+`UXXo=8fYr1;~kdxDdbuG7#=k3gnwVoy*Pse*8?CP{EM4h zidh=Lh5n)*Bd=X5LAxl_{94L7yp5$zMl^#3{EGwW`CdAsJZjClo-A{sUr5=r94uSOqPi$Bx2XqwJ0Xj>oqW`wvg3e07J z)B$YP_^e2>9eu-`H$Ilmv=_G3H|}OW)AT=Y3o&4{OAN>c@maT9IRH=16i5c13XIbq z?_;?AkC)0lxBghxk!|c14fTiYk`u>n>GBPA8g4GyLuofED1?CZ_ogTPNTn=*7Rz>` ztYLiEcuec^&_!PYFq(!2r=O|z#Ft@!biey30#@bucj&Ux#$iwD(4dukXbV1&1KhNt zqjE7f0?G2qOI$YC4rS^$^olhr+rM>-n6e_o=%}lSws$wIa?!a=?|&NpC0eU;zsWc{ zKWScWoG(_FP6kwvxFXl0Buq*6*?NA&t1N%CNhYQxAHE>%%=x@2fFKMkfr^ZzsGxgw zHOYm3bg4i(w(q;Sv}7U`6Pvh6Lm7Ptpx?d8)x>^1RQ1|vuG zD|M?Wx8nh#9<4K3^p^ z+tzr;24w)=wRU5Hn4~bhvixzHRwBbhqo*XVUm->z)SC1la7x*{$-z(_ak+M#+ZP-g zeJQP$k`X`41*d?oW^%4JZH z`2Ld2K6XjjT~MILbr{_xL>OfMd9;zSl*--#DwbWDM4Mp%J~N_%)nv|~hmH9@ z)4zT59opehPLJ^KJ6=VVO6Ho)jzT3gR98(NX*61GGVm56{>rj2M18)d^HhPG&iNrA zw3~jo&)!0v{GJE>iXI;ylLdla?z?dM+T(hzjWMg#Y7nngVIY8XR3%u9|L|1IzJP2% ztaEj&!l5_dWLvR#((N&`TQ%Z_aD4=0dIY1oPwr0rTMp@~krDj&qrOo>N7s>&+3e2# zj!pO%Q}P>}{K5VvO(@IX)|C%9o-~d!1M>GPa$u9}~ znp>y9i{nXjS1MjmdxDO!=)mKBA}-}mBp?edtY>D#G4~`p;ncc6ZCuu^9162{V`}LD z1V6Z{i6Rj#_U_ZbKJm)mqBY>vgDo5E5hb5`g#UiRW{W{;Yv3BoGE+jQunVS36Np2enN*G1C~E`p6Rz z{j*O=Hr16UEyfQtZjl0gr^mQuLw~P`!;^`G!)B$eL?HKwuJHg*Av%bEfp+&rI#S6h3Du-ZF@PZN*czynUs7CxrIzi<4CKW$DVUDZp4t@iHd(8;)$gN|7tcwXZ*}bVfvjelr52^Z_wbOI56$NP(NgU%iVHE zF4%~Q^N)t*gCUrPDQc6o=jm9zod2D$s=kAl9(4KKJVtQbESUEoxkjYn)gw9Hf$ zxkomp*C}$oszKqQn1bcxZ?n$jcvSPa-%+!QHfnAo#hP0@4Eu7#;_sn^YAFm}a5$kj zR>ve*17@Gze8vcL$w+E@`m5(=Qy*Q~>OI;1*l|C1v1PMWOw3eL9{)(8=9b%IM}6!U zMcHwGU&b-gd%E#WWQ1W&us{G=3v*Gczbd>nU~XA+RYmPvAK8xKIjItpke-|6DHLM? zV^m(Trt~H3n8Djvl-rxNw5%%KO97+CBR|c6-1xk!_MSCj{y-=Tl)@CO+~o2vmxWhz zY)tX$O0oEU#QKS|IP#9wssiTL8{ zJD#*5d^it313T$)w|h}CIq*lseFB}(#~)6PjENhpg?^8Xm3F>+oFgAQ0$j`746Z8! z4T=vRkY=AQ@V*?NvGxTdbw)Lbpeb#Hwn$jEkRl=kfxy_mFdnIZZ|v?Bk47e(MA6iu z=n4|Yw5OvgD)#Z`yIX8TL)kRf#j_X&X!Xre9^FbrGeT&ua~Ez z;L~rWd6P4b4BJHLCtjp5IQbK@Yn5nt(u(A%E*th>PWT9zmg#$i405 z1u)h5>|%j;2S6YL!d+3OTS>AcGo{_X_PRbtC^cZ~OZKy980j48DF6mKe0`ShOy)%)$Gpx&xYS;yMa=?0Luop+4>{HHg<+3oxDAZ>#%N{Z}PF z*y2V1MAwfF%&zQdI+R~N;zar?o(NK19$nQ&-1jXxMS(~iDLANz^Z7LflHO0Vw(S<{ z-&6fR1v zwYJ=7+&AQJkPZmGr9o>Y;3Dk51T1!Wny3eOhpSrVHP)r8j)n->0clR9O!IoX`MucX z^Zwiy9^o(E6WZ-Mwy{?YbRia8Hzm{^kdB^~ULyM{?&zV&+;rnvab{}4=iyZAU08O5 z@MV3_6vpe|{fU%r_^adQ-fn4Eqe6TqJ&VNr&47I)qv~~M_?mkg8<^CFz(S?YiNc&J zF8sSlt6VZ89ZVI=m8J2(?|e_Ih#V2_^euv=$5qy@pDZ&CU`?d!{!Xjfsm*EywtUo{ z7M`bz>Lm*;&#qzeUCS&pM&I|_VXXi>@ekIJ%6OP-srY6;NEm+rQ*Vm2SP=dpg`9v=8of0 zhOkW8VtL8ieYY31ECO7=oqO;@Z;1Kzm!dv@X`5}nJ?l8#I_`)#C(=D2%+*Mp=89va z5suRsE0+)2#jpPQZ^r2U4e8Tn0Artnx(_PB{~E_^f3atL)FN~J89#@h6>YEJ)SkOU zkVI-6t3OWeJfD)pik~F|nR+pV9ikPTcqm+4>0E|mxI>`U=jt6gulFW~I2NBxSomP5IND~h{YMxG>1blL@4eF^{6 zk#UK;tX9dPQL#jH$V)FC!y~DdwEKH`o^W&`SzLFoKY%L61$Od-y6mNtoA!97 zb$UD;2B^}_laB+luIKy^Uxf-;n)u=5i3a`beLsWhyI-)zg6gb&zCf*CjB)ffyJji% zQ#_YU?1e#Jdx!n7Hh(Ev_|i!PMx4H_`%&raZn?l8`iT!XKN5a0UHxpS!xGFhTNf+u zxpL3g?fDyTpaY9;=4WvgLgnhu2&s^lz|K2HyQC6^rpuT~EyYofcy)zpZBfmg;sx&O zRGn#3W%*3Vl+k#uA^Ks&Nc5APO_6`soi1jM35BHy;tl(LIhwN&a^a`% zJuR6vsJ;uQlY9qsuOj!Xa9BQ;(SH{l%NmW8PkWZ6_$5iF;!BonGJlTSxyBnademO^ z=BG6}B=bz`T7Vp#E}gK#fA=$pv=-a?p8toJvm3oLf8KYg@E~;oi^ZJM)2> z@1e%vtsSw=PX_(a0OjVZhHr*B{g*Z;W~=k%vO2VPhKypEAzx81pO<(tom_IjrLqcK z@zif`H$2E)oZV2FE-3#8Buc{2P?839y z#~{t0*VWy@2eH+)q@uti{*C6u-6YLDb<8RHk){z#wL@!tX{(Ia1#tU zO(0i6^t)Ueq*UJ0(u~F1x&}Xc`0a@7^&Z~y#d7ER`@Xo6>+bhoC<@-^DTsWJz$8O@ zE6q6A|0WUD9M91pzApN8$^s8ZUZ_$??^mFi= z)P@l=?Y7Lm!mt}6Km%zR(K8vzVwM*Cph$R+Xh-GcA2iO3omIER78s5{b=pAhf9(?R z=jTLCaD?TmqKr8OI!4VC|q!DCP=dfL9nazg#oyW^g{NeK5d*yo|ECkDoA zntQ_k_T^y$F%++7ZZFRcq6{D9EFXT)`{k$vq&&@tPha9Z|9HA1$islU8DzR5%*4N_ z8DoCrp?%1ld;gLWA)zb^F16gFV+?4T=W$cQrr1dXp6_NT3tcXsDig~m+Mf7k+r5{4 zaX`hIACv4>RGTPbo0)OUixoJ^mShV!I=(iQq{0#r8*6Kg8efTj75)X$kJM+F@I}UK zUT6J1kRe_tI*P!@&+7A20@t?a1+@I_mNWPu$Azzu(L~LJHNe5}vc>A0`ZhB2cvGWA zAP_fmED`+(u^vqY)Gl~k>@lkPE7s{N6Gk9+#3TqD@!RmIUBVFrL?mpY%{jeTz>Ul# z^|pRz2~Co5>*5Vwzu~?e8!^P_RU&lWU@N*MZCSemvk~1wkWh+dwBQK1rWMVqOV=%v zyWG(np@yt5?UDMjtFamAdo2)+Vqc~!LSR~pYD@3!kZumq_zz#BBQJsnet2!E?A{p`ONN@Od?Dfmf(G#Pe1^hkYDJ<6WdPOs0PO-=ay0Yv^)oC(`N1#}Xo#K?6jVUH7&Y zt>ZCkQuHIG`z{jqel&L+J&lkI(N??MwcMzEWwuRE z#tsWN%OvjLGsAyYLoMu0+RDt)d<{d{D_#C6oX)J(P(ujhKG$ds$ObrB+81&6HEUZK z6)Ny?G2BiOc@i>AX>0zY@kpJT=631_c&}0lHb_-=K+_#y@r3`Ov!QI~A~_f2I%EKS zJ7emxmhe7MD5eWcXU=kDb2?}pJ=Z2ixgDeUC)Cr0Dgk+Xip@@Z?fW>sIrSfsd3iKl zA^E2N1so#Rx-^RoLChMgcI*of<7Fc`lfSl9eUto$^I#>M(!@{8#<(NM6gWSTnNcQu z#F(n@U$X%u^XVuNW%;9#eG{+J3*S0eDbzOK*JU^!PFZiL;WG-ghu)JglFs-`?gx{0 zg^83973w0~@wfomO4tTCaGoAw5ySDvK+M&*B-%3F6upN6405V@Led1c)Ncz<5n^(< zPiF~QP0i%xt-8+Ans2bE6p^{j(LYwh4VMN%1BUMdM~=lxfRktQVj7Tbz4GRfJ5l**g7#AP{Ll zg26O4>0syPBWE01LOh{Vto8R|+hzwxjMgaa+4w4znI|@APC}4r- z_j-3kt^W!$v8L)O)(h**BQ`G7xTp5~*cIxL$Cbd!4BDqq1iG#K=~9AS9TqsXP_zV8f-mKeyL`)N8UjxE6ah@%CHBRjiYY zIAN$UE$g3x=1lf{!xt1ZRgVcz_({~_;ON4pN2KG(x>7`@%V6tAaX}iC*iEyNuh{Z< zP4>B7WT23ha(YzwOadZ+-><%ECjXix zzBw)Eg|m*luIPw7+s=KKGbMdlsp~TSU^^P?aC>~6uI9b%gV=r|dD=H2?R4lgxOouS z4y$=lE(0JSD=3f=cism*huq^ph>fl#eruAl&Qgel9&OAcjRk)uVWD_8t)s7{ATQEaE!nr^~>g=%(4pS8+Bu z5=G_(yS2XmS6Y<<>th8PL}|H=vh_+`rF++VgzfHwF?)POOi$iLaTu-X)KFZf9*u?T z?)}Bqv}%JriAp(#fdiklAyZx}iL7=i?Yhzm53*70oyBuUiOR%j>5$SfU;Qg4%7qnxL^X zxI~FR3wjB?`nEIEh!feQ?EB5fxl_Xbb9SubMyRuRRP*Q$EOTP&drs zY?gCRJmNK?Yq1V9fe#~p=K6_U2~;O55mu0P&seC38CLy+tv~Wp-x`q#x&>ZM7-Q3m zW4eD3)V})uA3+zGj}#kgL19Tb|B00v_HN*#OGe|6oD8pH=^tCuMly2~^7SO4!t)?g zy6@oxDL?L3C~3=371z7zURp$Z`m{P~37?4aXWtd&fX+CBi)^dH8Pk?Ah@fkZ()!`) z1X0mZu{ka}gkauYDfc*`#Qvobr##rtiB{U4PY809iCvoe)JrGm!V8g_?{9}sjEN0= zJ7$GABFPts7amvF?Wxg3FuLN{L~fQO2Ji_C{H?Zr zfx1Mn>%xiT^c%1j?7^kj&;Ai(5oLtxTKUAKq*cME;>S!-zWFU`$Q5Qp+Y6LFt-d-* zI|Yi&1D5sozyVt6Io*3Y(QbMUH6Zt&!WxBbM#)2%rL4sK&J$q7R-gKw`9Ij&^fvO1 zmLCl&t)>E;}-txS})rj3hexI>&3B9Lw&HJr;em;dp7)6hFSx)BpE zDm*>V;wiw)K?Qc**$GE$ELU6tzKjmkL)s zu`UM#;VDh!tL`#Wf4#+=lYGrdZfsUx$JbO|r4oTwXfXkrg4`=3V%Izv8Kj(cTDGhf z58eQ=^xq<-^r*F|u>!{;_Em2^J)jAy{&s94JOl#v*YHux@HFrJNuq_KMj{cd4B!GI zyQy%L+U#GslYhy*L&uRMJLVUA4D-9ylSREQjKgNu|8-2>jqtiW+McHya%Ket_zkuj zm3$1|$Ks(pmrP4EkMi}jCyvG+`NH5bpZ;|q0Y&){coHggK%;uf=ygA9Gjg@-z<06? z?Ix4=xt4ntSo@+9oy6cjU5elzD4ubWSy9ggSr6AII%4s~kygw*$EfUf zCY$#?+H2MPU7Dk3nKJ$X=vT#P&+45%*v>a)aJH8>pmXiNa08~ z#uSsyGl@a`R z?7#3vi8E>bKryMKl1od9W2}*q@jjedoHB;K~H? z;h{>mbHAOQ?yR})5R|r$vm|$Ig$ZnnL#t*8KK5}E+@@Kv8^(9yG?EfT5PU1;lin{4 zLSUjS%c8>N;~$k2tlzG=zm*BM6jW_WNrM*T)#Gz|3{UBi_BFO`gWIeuu7`n7qJ7!+ zoB49j8dB$kFYl%CkKkQAyfMq60G`QsWATY0(n^Qq0MqRiwat%l{@qJH_O!Wp|2ASV zp~0AbnKEINW-+Zod_NkA)8QUU3OqKkv6{WUv7umiWmN6w4y`-SB|;BV;-wz#^2nX) z8^1f-0CkHspK8Awr2)AoVa;dY`-(cwmj-#a^qWnY@txS1{hgb=G>2m7{0c%!)H zbs=y!>P=MRpDu#0WZhGe0hmuS$N;@)mS|*4E~72mu{YNq`RZI2l38VG; z&9cBZbIPwX$TSBPKN?k&W?cZIRHxaR)9Ch}tUXnw4yeb9w9Y0HH=?rzg6qU0_kXX& zikwQyBcGjclOqS5tHEx2(=0Eyz4ua<7wa614t|PXbnX@1^gG5j4}b>F?#wG?KKQUL z>D3%@JC#ak1x48sS1KpB=kC_yJ!7{-np@4coMInIt48ux_LJd7=zo%8N)@-)@Mqn? zCB{TDMLie03HEs~sahW1-369Q7k;$b8PLlKc|e60hl^hIV7!27_os@JOqQ{&^m@It zOU+BY&Kd1I<4B8XNEOGQ1fxpfLKZXxc`gJZVp(4YLUrlS#O3!F;mrX!*VfOSO6<2k839IE#ij3B6`Z33p3V1pDGW)z||*)hzf4| z#5U$te~Ik~F3J|qKe`0sb25<>Dt`sQv!b)&q;?!Q=CJ{$~>URp+ihe!Y>>%EQdotYO8c58TuoTLmkppGqebiz(tbA&68SL)Ym2PBh`wyUU1P7^o-V&xxQ%&I z1`AGU3bH%$YNuf^IXQ&0!Tdb$I7(3)vaau0-GLq!gUc*E{8a*|5H8aRMZy`Da}U;Q zk0R&2Y^ra(MQ4s*7$;THElm5vNno7%&0ev8lfW&rjt8_-k;O9IROA2H67|DhXL*}G z{w0f8xhpks8E$F1j1p#xIWiXZjBfJ5^IaMxafGqW`53v4sVk*MQwPMFnyS<{K}hw@ zd!wvxfN`sRTTVb-x;RGfyoA$6%2mq}{0gGHfQRm0M9P^IUVT{HFSh1`bO^0`(macn znI;iM@Bp<>s_2kCwF=JY z&PSrL)N>3YjsOL_gI3lipNJ2XrOul1Wkw+f?&ac$$3qPNi@V_?<6r^H*bU;p$q=>> z1HvZjJge#_N_vj=kpT^tx;Xz>wFlov3AYhs1rZwWA82QuRk~@988N#nN1&YOzQHa3 zdf&p06k#ycU~rClDyg|%s8er0F|}lCP@)Z{v-VzuK5T>5<=`+i$=M^zg~GidW{KUn8}&u^k7nksXyJs5{jRl`tHwI4aOs5*?ya1z}BK`rSbW4Osuwk zzP!7-44zPQ)BpsgLeCxhiNT!Za_>?f*CXJ;7qQ8#<^K=Qzj13VkbE1||LKI?N#Dgz zIi7fmv}!*%-MEm8-?F^f%-T%3{*>l+mq_<~HYo0Jb>M|QdT}F~I?YSYm@dv}bQ}pW zFz@r0I@tf#7ANC?Q{`j!@F@?F3h&0m;LY#5vfPc>xE`I4U`@X&vyP-}ERVw+47+d* z8XbB2sGh5Hd+{W*%UR)T5f#vG^F8`sWtR@~8)B#C?QQLfjP@T}EoZ+c4rjM1ZjGme zhKp}sp}+!o1JpBW<=)Fa2TtF_-3=QXVIC2VH8rTfxH&^ZfK)EC-4LZ7vc)gt$j;&B zE7W-upbGnrXAHR~IRB-K{$r25*hy70%I93yIb>rw9p~$V7vkmchY;zmv47Gi0=ZcH zG-@I9F(-ru^j;GAl76&@L6#uC9|fE$kv7K>zz5BI7}0z>OgtK##ulGp-w47^V_Q0# zHuCjpJ4->8o$~7oo7i0@Y29LCCw36}NAQbYir!Nzr3tMo>~3U^4m{^j8Rl_h?YAiE zyhGp#8%ummkQ_Q>=-qTpeH?NTNV6{LaTjc#b_*38J~BuhbgN0&^W0t-1FuH~#hhC1 zMn{OGvG&h*`xt>KB~YjZM>i)`Nsmwxb)F$$rXEa__@Kz+APMRe*11R#?(&0!_hWIB<((OfR`TY$wQ>BK1O&x$6u zr8b-zG`lss-&MNJ83H{XmrzrxLCXP3zx616s_fK!t~=CSlew@PbyMR61D!a| zsLmv7%{S${Gp_IQYMXWX0v;SV?H^Pci3At^G0=Y~46@dK00jSvyO&zMzs`y%Yr2nYu6#9Y z*YTghKFZCC2=D}K1OtgE7My;a;3 zsO4r0%Bicd7q4#W5 zm+Xvgm|hj6LwVVX7t5zeMTOVcpsaPSw)$>PxMkvdb`kyB?G;aGW z#kZjiTUtq)U|p}b)@9@V#PZn`{gD1Td0g|}}0wF!xU=e0hy zHyG}uiLnRu=sn7Bh;pjoG`}Fdv!-#0vnYegTi{ni^fepVyOqj1R+r>Tla9W>4-K)UAhR`x5(nWp0izSdW$kHF1DHoWrOr2;ljn~@&VXv z!;to}?n^_JyK~TjZwrA8#KSX8dc!BRrSBlPOK7p;OZB1NX&jQUu>3+zhyr%DF>>dQ*Vj_VXb;zX( zIo_JSRUrlqS!=a;rg_c(E}I>bRiUcdPKf);b;qbq#k^^jYshOCbOAWZUqIUnQ9fUKBEK$&)hXv1&qdgv{1eugEQ%@G{a2OG^*wXuG3b~$Zv(2H3pToh28)cr zYev{el;D$^5k5A9V}#~b=H}vTS^YGz0)O@*21Z`O0#~2 zm-{BE`O_B3P}xZhi&+@oFrY>(h+qjmQno+gN&jLJZ+iW2Lp5>J!M6k+iEQybApKr0+#up4UogAeoM;JMHEB#{VVG0Br(~t z;o<{@RWdi)*lYX)(Ellg;`^QWQ~uKqQPcgOc8HPgMHiIdN%#N6MK-MwOPxW=U$AsA z6hD+|C?>Sb{SdlDXTqSEA{YPm#r(u&eVOc1!~;E`A@Ii?TO5jMV6eX7U#3^=(KbJw z)X$50!WpsTP5Ivi;dG`1(Q1Mn-iO$?#VW{dUm|NOB$ja@QE>~Ph#-mNJ6c1`0#bL8 zb^;qmJmr$E@2Yme^?T-@OSlKhpe$oGY@`wSL5|#*;yAw8FZzoULOkIY8Pjn%67i)} z{l}6W>Jt9?%jS@lTQ|d>jTNm#PJF*w6sHB{j<*k-*5Fdj_2a$#24~eH=jC%yHg2!H z2%3x{t~SIdKK>vjhfqvt_1%^QjO=(dj%>Ar?0bGs(A!D$zPa)z8Xsv49exN|7Z+O6 zQRUPUKl+X}fXYb+dctaPfkRo?R%^7-e7>~5?UUu~$KcRYt<>l?;Xf7hVW&f)4q zKa7KyF0KN+?^GbTpU)om1euxNw5TZ^rg5oVeTlQIZ`^tJb~Uv$0s|b;q%9c&;>51e z`c$)xs>`*eJ`x%qvrd4^9+drc4!I@NZrA_@HNnBsw{F1nVkF8z@ec`yiSEx14LDqy z(CcM#uu}3QSi0JRtqHAV&yzQlJ+KM6c}f*i3M;DrmHQUjI^~nLX$wx^x;4UaN$FVt z&Pmm5(XnW;jlm;3k}hAJAQFW@KVom}CA#H78GhaYQ}k-~GuPz3;-Eyv;kR5brwy=B zfR_?_yPB`{N!wjgu_j5w7@JOz2OZGu;OL@xz{Q;*pimlR!y=pCB{#+t5AL z32+inpvA+yi-KRXMGWNP^XPZAp}vroYP!sQG4E;+EVla%vHfn| z#|EaX2j^1(GZJzEND26^KBVP~l=+=c^IXE0_g9ivk#n7S?_xastD0^LpRc#-hdV_0 z{hMS2L%wspFLfHM`AppRfmS04pWmTbkzSqy*eo0l65!CmA7^`)_Abq90Nw2}UpR@b zjs1LC*2a%m*M;*QVbo&1a^QSx7#|CBpliq@NG4%{O(l;%KbSXgE&km>;pUK}O#LY7 z=hKdHY$ZPGW{US;_!1p?0+d#mw!Ifo*>HlFQT4NYKK3Xx=%8w}&z^)%lHyL5sH{iV zQlF5F9w7Upp0rr!ed-P?%I&>cfx#jb4Y6>zdKeJ+1*oh}oS%=)jNbSgBl(?h{7G(h z3mkpT=d=<%WB8h)flTzOV9O;(hB8mL9kMwruOktKJSwJobi9HGFIkOasl_Se(vrzI z%21W_{aWwfkgZ?Y-lndle*~}utqX+WJJEhlYJk+i+X|(+ms~(05=ByP)FJUvJ{*@t zA0UuB_vEcydLk(s6&v~4(`h))Cc`&Un_zxPiYeT<0))7e6|JO%vqVKb!nHdzRPQar^O`$jL}9z zcyBLNT;7G_UWPng87D7{$!@~X$jtVVDcw-^!O--QX8KHDsde0RJpzB=Dl8CGTWVX; z@z}4;-=5e^MKO4ZMW5ZX8QNt)v*|Dr=8Jk=B(Ie^;aW$=do+aqxqxHb|3JavGWra5 zNAiX(4t5fh7us?>RPI#)^Zbo>R|As>Q{=BSGd7fKNt-!1Ld6HSL-vHePI$O@TM*k}5G zq^A`yH&o-#vlckF*uR?APTJx>E?Zt)SPk|+!z72N4GVeicTyS;X^jnzEuc?(yP3P> zlN08Op$ef~naLYyYId-keedgm&K9%#VT>(izue;kL43eqt%)>!v%o88*#7LwDY|8_^$tgu9%gq<`i_mHPkDUVII;Qtw_RB+^7)5mC zCO)~}!GYsE*TkmRB3s_G>oXw8BYs`AY5sg;!geCmo1pHIex)aefr2!DvA#Du%ja7g zDT(m(jrA81Ja0NuFR4?npk#SW=Tgxj>f>|w4$m(>3*rxA$Nt%CR|a@Y`UTlmzk=`{ zlJa_LK&$aMpOzv$X4@i{)S2$*P^*VjVyi`d>`~!zR2>ac!W2?GYJ3BA%brp-`1T-|#o!YMKf7{>+eEb0 z!+5L{^jYlE?$bB4;fJkXuVVT8R&evJ-b|1^3j?y}_DNB@Qmhb~hIpqim9aAH5+>c)Y#7rpKts zZ(aG`MU5}{u>`^kuxaA4s219GVYtPiXZkO2mN)&g2(3*85 zekL#c#|vwqsPkYpbh%Qbr(NbNcExY?J_YDh8Z^w7#{*G;43yA?l`OC2K^dy!{v6SH zps#MZGnK;JmJV?nmvaY@bw2t4~(UEcWEs7l%MB_4?CHKX#Q!hWaXl6K6-TZ5uZ=I^?gOjBz|5}r&69B4}z_Tzld}wGy z?b%1(T+-Xdvq{HW@~S}iyt|ILpxD5FIltHoy%AD(m<*-9OrjE#=`&No~h z&a5kP)IFE8-cJKe!KPQ3n0;~FRcZ(VX?#sEJ~^5!nlJ&J+T5a$c0~u#e_WY-)+gKH z{YZ+(zrN=FbSpBh_D&uHpO)o?oyPXOrEcIeidyH1wR_`PpE?ueekOtlSq zD?*Um=U0_Q!WP0HmHr;0IDH($;EznIm)1y;*Uw?!R{{+X&=}A!?<5WRid`iRdZFm& zs+(j3E{U~_ZlOKp%p!IEGLh?yA26aZ^Jr+5KW(&=>FBfk$ha?qWhR^MGpKL!pMKr$ z7H_L>>D%j8#_jS#U#seThtMgb!S$HNFps~D>K6`Rg~$(tc6ZusJL_?`wc1}j9}iJbfaut)2sEk--+ z=k|Oi_(_-E>o54eBAm;1UF`l>4h<9QdG{*Q0M!SAvrL_28w3V~MH0;eJIaZKp0v29 z&8L=>zYp8bg30W+;VutS>>Hof2%kjM&0lXT{-?6DY-;oS+IEp5#jUsnEAH+Nh2lYq z6{p2DxVr_~QrtbbyA>}E#e;i+;BI$*|C#3lJTLPmbIoM!wXeO`ah$Pjy|bz4_Md;~ z1pC@Ph0t7v#4(dWv8uN^bN0A5tHRbFqD*Fu_d=(_{>f6i@-qE|xqU7m}YZ4OB1(@)vk7l|OabbzUsXrP!g8cW9xZUgV;}&7FRAIGETMG4Qrc z@Rcqr_DE;dhCVJEZw@J!9ZD-9!<^q9?2uEH5}_nyZc=qL*#3$=-TZa@m4Q!GdR6EU zY4dEtdO*_8qNu$V?|#l`$KVS~E7m$SZ(prQt+X8QNkep)GiGJi&2G26{L^daEZycT z0URxTOx4*qHtXF&(amaJTQ(5U6R32nkJcNKyGF-aYJi~Z%rhUGfjt8)G*Wh_n4ye| zZ5=c1H%zCvqvVahp$pm$Mk{QSf!7M&wdCw*V-Q<*DX?w&RYHw_PTRtKRD@@Cq(zii zt?u$wxSHhJF;K4=a%UZOB&L8KibDYJ`ufhIDyMtYH6BaRStSfkIWkwNG4l&t(SxYJ zQLQF`xN_vv{wyCaZ3~tpf^SRmTuiH&-0V_x6!%xw6rX|$3ILYPtUHWr;FSzYX&~@n6+zWdPH@-*=_8Us~~T#}hK z@N*_gzQ2b^ zx|WPHq$4pL3fGtHr0?`l)0fV5ivu;yzAajO`U^J&U;4RYQ!5P{U%oY7%`9|Wu8HJR z(-Gzn&XqZwD{+HyJ~^i-OJi@j#631hjddE()`yHmt57~FEo>vS_;W7Y*7Lb0Gi9*k zn6ht=38plebV1|SSqhBbd_+mA=y(3l&F!asQT$W6(CKy$(Z6pXFhQ1N`5w<2w)15j z9odK{jC;(c*JjE&C%`l3cN!Le0fv>-!1OqU$tH*A(E5nr5y;}!?O8NyN;W%q`bp56 zU+>u<+@g=_-?kcDzZ^l_9i(>K7B!WJfCp&eEp4?|?8Okn+GS zT>@*2p4(bjyL&ZTzw2()&PmDGE;^QvR2&Le553=b5P>jB87lho$Vtn?l+lg~B_KxR z%i|BP(Tzs6D+sv*OVrpQ)s;aY6pdCX&P7H}O~-L`b=Z(tWHAO; z0SjPieNi@v_gnd&TD;`@&{MWwPoa7#qokn6N#O3+-VD&~dsROYw)rA29lkd|5CR?R z(!8zwUPV>1syn!rUoQL%UwMJqj8@iI;X5^}PCrMF*a9p@%>$|C_N5b0vDn?GY5L>x`NI|S=4kN8UhC-(u8?-#qWPk>GvY!hTsQ3>$elCyZ1wiFoM=6^zt53mj_xLUqaDdBI*2;&ndxKcbao6CnTY5RGuXUdiv!~|-l`MzV}lS+#5;zJ-IVr*U%&TC*u|K0^ zf}G~(aVqCOX;9?~8S=Gm%SmpysOc;p#n2FFL+_-qi6T)j0v^vhY97Ye|3{p8cC3X>-o}cd&TX9WRcHtwxh2 ze~ZRP9M;=crn5a~#rp#|M{`;hwOYO^_%dziUVV)v8hoIco9tODo1YCDXl76J4dkHs zJH|uIgFy6&y2vc=8okc|G~xbf@a2A>Qf0xX(+!2Zk80(AxF-L5UPvX<_+d%5TpcgA zqP!(O(--EWZ=7YKE7&jl`82e-2$#Mk=OIx_xb!V}a)k5)RX6E|4p?EoHZNl`{meSf zElFi(<2+}sSK$)C+7E*{(ZZzzZS(WOzBm*IT!+MBAvn<76h#vfH7~=|ALqjKjTES@TEU0!YgbU~Rgb@O-&BENqDu=QN24{s@~={eReNU6E4=aQBoJ zzI1Eo9rrzlHmvAQ_pT8W)21an2KAa{)?y|A9Zk|x!u5+hSi>x1juF3}FZ0^t#hMmC zTk?1Rl`0FN@ZeBs%}*q{pq``Yw4`h#`F;oqqW#>abcnmkW{@bmgRNqTdHaKWnv?Tp zi<)ShZ8BM%r9)_kR^mH7aE)~=mmKIomZ5(N1(F&ceUC9UU;u$?qz?Ai4JImr~!Cdmrn(% zu2>#`Z36A`a6A`pZ(gfeo5zzY_B*8_>1=Lqr=v;|31BZsE;nqdPa^0o;xzjW-b08E z47SBlhPGEj5|*c#eE35?#=v_aeN<$j4l4(6aT zV&CYNpDouTGUyjCi1~8B)6iSIvL3A4GX(q={PrkFOw>mrUyHOm+EBK(61DJlxa}Y= zvpU3;AD4pDx3XhMir#gllFyHPVBc%u< zIh0{{Q4)H6;%620zIBt{BW8Mru zG0#P>RK_T=)G^~KMfa>G_|GE;A7Ur_*1uo1drGF38p_<^QW3E@9}!zoGx1zVLFb-K zHy13$*N*>Fr3O2qj}Vp>9|2}$wy{d$r|=3x*aCzS9Hh&~kS6BdE*riDGG1ni$r0zd ze<-U=Y|AifYm)6-Eo)bqks@)j6Y`?jS8~tbvd~zfuO)y#p99oYEMYrOrVxuTKXkq% zdQ(gA)Yawm!!m77y7@&vM%W&6u2*-YH5aIZ)MSx_SwZiSXxb0S_J@S_V~BL@<_2(% zkVMalhm5@ruCOY%ErBRG&ASCDhgov5@S83%31k&=CA#qzFb$Y8gbK&gCJP?ur+n6j zScb?LO@*dr>ImjWXMO>#pm{~#CnB(8MdF)1=^*bI3CS#>z+%>Byr~@v=zrpf04!XI zpK=_lh{0lECh@VP*o-AD@r)(1tWldjgD#k zK}+*BMMMV%5!m_}!(R44G`0JHo9DMNDUT~4yOG|iC?^WL^W<wRcpCpbZ&tw1EYJ#W=mWT|tW?TCwVq%jHJ zZ5KS~_XlicZ_m(Ff<)Eoc0DP3&ouUna3KCA;!{(JC%^V#j@Ed2+jk$ox}cAWLT!99 zV{S6`Sf5E!pbkhSHnkJeY92(9pB&KAeQ|F$V7FrHKUySb>|r7t@3da`;o2QjYJ2-E zl0eP3xq|9^GmNV)WVzfw{1vw%PvvYEccJ>Gs@sPY-40sv7BDqlLtb5#lERvjv2ldvj|V@y1W4oI5q?6foBgkH zDYz9~77WRA3H2zcWY}o{$s6S{99wPto*QrJpn(T6L<$P;6w-mrj^)^~3HEc<$@Ar# zu1BGaCecg=ii9d_l>Il^PFOmd`>1Qb~ z3pRU>UF}qc89%|)49*uDH*dNz!cq)(u{KS#VmiE! z#z$qe#Kt&K+kHG1Um>#0Piq}wKO=`$y!#L z5HC`{Dt5pvJN{Q(&OJYw_BM@;#1qD%k!V==&6QG%_nQBu7E_mv2C|uqtcIY9)u)?u z5sMY0Mfw`Z@GsxhOV(Q6|9WU)zdO;8+(8lH8ZB*5YiQ-W8*FdZMDP=0dd^~WiJm*= zt~Pt=;N_Vj$9W{M!4vHQ`Or;(Pp*_=$=ODDBkM23%0^kMV@2tJ)=W7|KG%?Vh5QM~ zBj=eVy1zJvbxCgG*l|2zr?j|uzMwrE+R?2008;tk7UB*)p8qn#u z=9A~A=hKKPEt8%IZ3FM0FhuPIo5z8pGu~ccK>W+co^5~{Mp86<2`P0( zkvNV<88MPGlZyLr@fBNZEM3R{2{76PN$I^S*wI1vKvJB^%mra3@5vK!Vs5)Qz zKxPI(x%&x-3=2WCh;6hn0N5$<-9|5mWU`)a+#XO$g{YP!XE_8PCpi{~AdTh5f5M_O z<*Dk791XVh6f68NJVB?GLtFtlxQp?<{#8(I>vpkiIj+uXRt@t;heRS#P;ovb%XpWa zdJ30Pu{=JH(2$iHQWjNI824mVzTe)$?T-J1fKX*KY)`TS+`t;+iqol z;mIsxo+5kX)byt1*akU;m|zZjd(20OcPS>rCAaW{cUnf6CRwPR2=+ewrIo2y7W-VF zFS7;ROoKQKJNuVuOz-*04Uk0oNVFL3Gs&2L8Gh=7oE5ir@4{k%K!#b1l0~(2u0FP# zRfF1t6rL-;Vpogd0$)qGX)Z3?W*d+_errbl^3cWsSyyFJ2TWMw9<}NIV~* ziQ$ZD{ys+0Bst9nhuif+JFy#Wo^0?g5Y3&j?IsouNsM;Z`kKNO1HtFxceUu1Kd~|^xTRhcc#Vb;5k~SsfFAZZxddhLo0G} z3XQ~ZBoc-(SrF)~O4ph4UCZZ*ti_wXrY-J2jmOlhiis*74U^XGDF#o|;_$zr)y@`6 zw8?qBzn>RP5rBm6&UEAVOJscQxOX$9`!*+qW8l9X zl5jG0%>Q@h5l6c*)llUKpMT03e3@C%=U3Jh3r`HSr_QCkk)ozTX`djmh^}FCtR8ZG zR+$m09T<-8{%9MBmt0E=zEEQ%PkR|m(%sfdJkBxhXuIFF-ULoL!_6H$65z-;kZK!_ z1a9-*N96h_x>)h%1)TQ=r(d)K=^~jl86(6e6q79lPbq~DD9ExIoj{%4*L6b|9@16X zgV|}qEQj`+s8Tw1M}1<0ERG>reUIxh_04_#vknTAnY0br@_k|l!!<*`sA<3Lsk}U! z@UkCvjE;sa=?oLjDp?*_9iegDH>;F$iE8D6Z{!H^dd(}?mLaV<>&K5c>C$U%^qoD!jRaumQ)@)(XA$Dkz zT(^4T&z~#)WDnRDwi%qp4jcf1$$LhSF%#wxlY8}q2Bw6@OQdw8t9G^Y4RJ+9nT-Y6 z%O1u2;bw>3cGDkqMzqvv&h@`@i&zkP*uSDfu@mtLPZfv!NzXCNJ2|zh{CQRV-Lr3M z;Wdz@&=+h5z76>Bb5e|ZO-N`7ZT+cNYk$-(xkE(rpgMI)(I^#%)(-tkDB*fTcPXhp zWvU_bZ*%x?;7BvzwN;Zn+nzX3P)`);;cv~*ed&MKE?5$&W8?2sBO-h#U z`lPO986`baZ#KaN@%x(30G!*1gOlu~1wG&M#uUBg056Bpl^@=B7zSsPAADrwOX|h? z%==Mq`?o=+f0Y>lA=aeN0Z!%Q&y!LnBGVHP0*irT+o@UU`+OPh<7o+Ou`%iv#h|kW z>rLj=$8^D8fw7SK=;7J-+X&I~J{6!$SfdwNi{UOzQ2vT2(#g=~yxi>SjQ?|_q{{q5 z`(FbAoJULXX$^7Sl_^O-myl|I3$tfb>NGU(2xK?Z=KSN7f(@{Lx>MY=MO;G7F>K!z z-Dcl#iD@YGCE^3Y!`V6p4%P_b5{`a{7g`dB{IWl$iz2o|JuJUm%mzTSZ+2dV>L zQEWu8EL9JzW@1$jlXLDdjKH{?Wk)I-;(;o8Q~5Pi!XcEv5Ii zLotVmMB92J%aVoMyogWLL7dnwcfP$mi?8L{hk_~P7fPHD^@5_@hHP|J4WZt}On=i9 zQ%CstnpM(7#dutJlU61^2=elpvTXWQxmp2+<3lTr_E$E4ROWJGg9^c%@OMmNBHc<{ zU%|z;JF8#oEw%{2c-Eoc7O|@&k5f)`zriTO=`BbF2evcx?_>0iIKAimc}4GL zC#NJXniI{}M4=wMb|iedDvu{l?4W@C2L*l}13n4ks6cvT6Er}i ztbj9P%Qkq}1%O40*57v0tMK*wI{r_$dkv)k{N=2RD>8_LDw5s?hpI>D|x;Z$>2{`J`HFhlE-+GF!3m0x2SB_RP1;euJ+`AzN7xNlP#=50gBf~U_7@K{1mI2 z%l-*CsG7lZe?0Vc%nxxy7ubgq_LWae`ohJ+c_|(vIpgQvEO`-UXFKqDq-cE2M|)>m zzL*-%68p9`aaS7UeRc*GKG#jPo!trmsL6+%57dvN1a;4YFHWv`UX~7PJMQ~!&v`9c zGe<(GfF#s6E!3dzZ|fvA`9y;)nQSTiLg$wuS5BF4t$Uh#)CWugKj!wJ13Z+|pW#7e z^IqR_I?SjjS)ji8b#ONdmf}3o-ZU98-y1XE%b4fkvuLpn{y-rujITk4K-N1!D&I^F z2X}VEH>}(xtMXATDh5|O(Fs|QK{`!DR^1N#C|^e$_Z0Zdfx`AJE6KSJY7yNoHOZ#p z+*+C0Y`^QJwY_hiW#DU7{6@s;)ZvIdz*H~r&gZx~PI>-;B+u*Jh?*!*bw2wDO8D&< zis|h{r$JM8TD5)7v*=M{=h%6>m8Skx;#@my@P{oN zedyIcBCmG;^A9>O{?BgRP`{gm>^`q)nAc!Rc55tlI8Sw_CQ9AfAR%hYen|OCA`+(a zgl=SidR`qiAW#GpGdr~@r(DyH_FVyW_>VS+bq!R?fz%R7suiHW@xz{ z8CIvW51-`xL?0(B#qw+|BTTtYii*ml&&Ra*-%ZV$i@9Kl?{#I1i$fnj1<|;AOjut6 zg}a$irou3fbij@gEUR6u`zQr;Mlk=ATDe`mlpPbqRV{iLog(BP2|V{2AFmSLeT!x% z;Z{TE*7G zKtgA&5zq=-5h;Mal$0cS zR=;iPz&p#?@PR*1kXBO`ZKU*9etEeQ~p5yf^s1rwyc+V@2!>n4x#3^on?vQ1R;{;!(WHM2(v8>E>0~5u=l*uyjU@q z0%VeEVryW-eGNHWQ07XoAFmroP^W$4C<;n=9t*ihNb9PdNY7cj^j(A(`FcgoePUj9> zdPOl%N)P2ev>9A5M;(aUkGf68?n!gQC(&)6yz+2s6er7&7QHkT=k@ zAv#aC?b@|MG z^jL1#?NMpCTavL<2H;9ASBLzgA1s8Zeo+NTZ~!b4z#CdL$as|leV<&2rR+s9rnq%f zpiRyOAiutW1s4O*G_ZdG@}d0w_6%fHH1??TDDZjgPM!K2(Q9K{mezFk-yxGhT1sp` z5+&=+J{6R)wQnqC2r(nus{Sv0+nn~AgGglM%nf9-B#N2}e><&ezl8`obK*`0VG>(y zY~Yt=VPZb%07yc|V|lcEi7*>)|V$PmwLm zbN=#(XnC+0j572(e}1m50%Ul<`{n9eN1T9T826Ck_}2{I*~|#(O)p0^#{8It5^pFF zb&?q-ai=CnK|F1gD3hD_k3kJHU7j{SUn^007#_v0QO<9CFrq5_?qTZMRT<7-YHpJ) zT8+_pVKgI(^@+=(wal$=_oA4hN}w+#fJt(Z3=3aOpeXlQEDx_v`w1?9h+wX`m+ivb z+)ZTY>t}c9n-fNE`Jm+73>4iCCV59~xd%SAO!1LyGDEF>;QIW|_rDAl-l`WA1Vg57 z^xneX7r@l_5@Qrcs`J8^7UDb$-WeK4m+XtJ3&KZ7S6+^$NZ>!&X`PU!KTz#P_GAY} zUxpQ}?a#t%EUg?CV!M87FVE7`zVtM28Ws)SA`7AtOq~2ECaAz`qv_?F~C3qSUCUM{7shv@F07{vSkdl;zdrs${-|{2xkbS>yl! literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_images/yi_jing_01_chien.jpg b/docs/v2.2.0/_images/yi_jing_01_chien.jpg new file mode 100644 index 0000000000000000000000000000000000000000..523dc2b8b868fa53e3b960d7017908dae486eecb GIT binary patch literal 6614 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_modules/index.html b/docs/v2.2.0/_modules/index.html new file mode 100644 index 0000000000..3522c21b9e --- /dev/null +++ b/docs/v2.2.0/_modules/index.html @@ -0,0 +1,752 @@ + + + + + + + + + + + + Overview: module code — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+ + +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/_Device.html b/docs/v2.2.0/_modules/torch_tensorrt/_Device.html new file mode 100644 index 0000000000..a4ed07ff93 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/_Device.html @@ -0,0 +1,904 @@ + + + + + + + + + + + + torch_tensorrt._Device — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt._Device

+import sys
+from typing import Any, Optional, Tuple
+
+if sys.version_info >= (3, 11):
+    from typing import Self
+else:
+    from typing_extensions import Self
+
+import warnings
+
+# from torch_tensorrt import _enums
+import tensorrt as trt
+import torch
+from torch_tensorrt import logging
+
+try:
+    from torch_tensorrt import _C
+except ImportError:
+    warnings.warn(
+        "Unable to import torchscript frontend core and torch-tensorrt runtime. Some dependent features may be unavailable."
+    )
+
+
+
[docs]class Device(object): + """ + Defines a device that can be used to specify target devices for engines + + Attributes: + device_type (torch_tensorrt.DeviceType): Target device type (GPU or DLA). Set implicitly based on if dla_core is specified. + gpu_id (int): Device ID for target GPU + dla_core (int): Core ID for target DLA core + allow_gpu_fallback (bool): Whether falling back to GPU if DLA cannot support an op should be allowed + """ + + device_type: Optional[trt.DeviceType] = ( + None #: Target device type (GPU or DLA). Set implicitly based on if dla_core is specified. + ) + gpu_id: int = -1 #: Device ID for target GPU + dla_core: int = -1 #: Core ID for target DLA core + allow_gpu_fallback: bool = ( + False #: Whether falling back to GPU if DLA cannot support an op should be allowed + ) + +
[docs] def __init__(self, *args: Any, **kwargs: Any): + """__init__ Method for torch_tensorrt.Device + + Device accepts one of a few construction patterns + + Args: + spec (str): String with device spec e.g. "dla:0" for dla, core_id 0 + + Keyword Arguments: + gpu_id (int): ID of target GPU (will get overrided if dla_core is specified to the GPU managing DLA). If specified, no positional arguments should be provided + dla_core (int): ID of target DLA core. If specified, no positional arguments should be provided. + allow_gpu_fallback (bool): Allow TensorRT to schedule operations on GPU if they are not supported on DLA (ignored if device type is not DLA) + + Examples: + - Device("gpu:1") + - Device("cuda:1") + - Device("dla:0", allow_gpu_fallback=True) + - Device(gpu_id=0, dla_core=0, allow_gpu_fallback=True) + - Device(dla_core=0, allow_gpu_fallback=True) + - Device(gpu_id=1) + """ + if len(args) == 1: + if not isinstance(args[0], str): + raise TypeError( + "When specifying Device through positional argument, argument must be str" + ) + else: + (self.device_type, id) = Device._parse_device_str(args[0]) + if self.device_type == trt.DeviceType.GPU: + self.gpu_id = id + else: + self.dla_core = id + self.gpu_id = 0 + logging.log( + logging.Level.Warning, + "Setting GPU id to 0 for device because device 0 manages DLA on Xavier", + ) + + elif len(args) == 0: + if "gpu_id" in kwargs or "dla_core" in kwargs: + if "dla_core" in kwargs: + self.device_type = trt.DeviceType.DLA + self.dla_core = kwargs["dla_core"] + if "gpu_id" in kwargs: + self.gpu_id = kwargs["gpu_id"] + else: + self.gpu_id = 0 + logging.log( + logging.Level.Warning, + "Setting GPU id to 0 for device because device 0 manages DLA on Xavier", + ) + else: + self.gpu_id = kwargs["gpu_id"] + self.device_type = trt.DeviceType.GPU + else: + raise ValueError( + "Either gpu_id or dla_core or both must be defined if no string with device specs is provided as an arg" + ) + + else: + raise ValueError( + "Unexpected number of positional arguments for class Device \n Found {} arguments, expected either zero or a single positional arguments".format( + len(args) + ) + ) + + if "allow_gpu_fallback" in kwargs: + if not isinstance(kwargs["allow_gpu_fallback"], bool): + raise TypeError("allow_gpu_fallback must be a bool") + self.allow_gpu_fallback = kwargs["allow_gpu_fallback"]
+ + def __str__(self) -> str: + return ( + "Device(type={}, gpu_id={}".format(self.device_type, self.gpu_id) + ")" + if self.device_type == trt.DeviceType.GPU + else ", dla_core={}, allow_gpu_fallback={}".format( + self.dla_core, self.allow_gpu_fallback + ) + ) + + def __repr__(self) -> str: + return self.__str__() + + def _to_internal(self) -> _C.Device: + internal_dev = _C.Device() + if self.device_type == trt.DeviceType.GPU: + internal_dev.device_type = _C.DeviceType.GPU + elif self.device_type == trt.DeviceType.DLA: + internal_dev.device_type = _C.DeviceType.DLA + else: + raise ValueError( + "Invalid DeviceType detected while parsing the Device class" + ) + + internal_dev.gpu_id = self.gpu_id + internal_dev.dla_core = self.dla_core + internal_dev.allow_gpu_fallback = self.allow_gpu_fallback + return internal_dev + + def _to_serialized_rt_device(self) -> str: + internal_dev = self._to_internal() + serialized_rt_device: str = internal_dev._to_serialized_rt_device() + return serialized_rt_device + + @classmethod + def _from_torch_device(cls, torch_dev: torch.device) -> Self: + if torch_dev.type != "cuda": + raise ValueError('Torch Device specs must have type "cuda"') + gpu_id = torch_dev.index + return cls(gpu_id=gpu_id) + + @classmethod + def _current_device(cls) -> Self: + dev = _C._get_current_device() + return cls(gpu_id=dev.gpu_id) + + @staticmethod + def _parse_device_str(s: str) -> Tuple[trt.DeviceType, int]: + s = s.lower() + spec = s.split(":") + if spec[0] == "gpu" or spec[0] == "cuda": + return (trt.DeviceType.GPU, int(spec[1])) + elif spec[0] == "dla": + return (trt.DeviceType.DLA, int(spec[1])) + else: + raise ValueError(f"Unknown device type {spec[0]}")
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/_Input.html b/docs/v2.2.0/_modules/torch_tensorrt/_Input.html new file mode 100644 index 0000000000..21d96c0fe3 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/_Input.html @@ -0,0 +1,1183 @@ + + + + + + + + + + + + torch_tensorrt._Input — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt._Input

+from __future__ import annotations
+
+from enum import Enum
+from typing import Any, Dict, List, Optional, Sequence, Tuple
+
+import torch
+from torch_tensorrt import _enums
+
+
+
[docs]class Input(object): + """ + Defines an input to a module in terms of expected shape, data type and tensor format. + + Attributes: + shape_mode (torch_tensorrt.Input._ShapeMode): Is input statically or dynamically shaped + shape (Tuple or Dict): Either a single Tuple or a dict of tuples defining the input shape. + Static shaped inputs will have a single tuple. Dynamic inputs will have a dict of the form + ``{ + "min_shape": Tuple, + "opt_shape": Tuple, + "max_shape": Tuple + }`` + dtype (torch_tensorrt.dtype): The expected data type of the input tensor (default: torch_tensorrt.dtype.float32) + format (torch_tensorrt.TensorFormat): The expected format of the input tensor (default: torch_tensorrt.TensorFormat.NCHW) + """ + + class _ShapeMode(Enum): + STATIC = 0 + DYNAMIC = 1 + + shape_mode: Optional[_ShapeMode] = ( + None #: Is input statically or dynamically shaped + ) + shape: Optional[Tuple[int, ...] | Dict[str, Tuple[int, ...]]] = ( + None #: Either a single Tuple or a dict of tuples defining the input shape. Static shaped inputs will have a single tuple. Dynamic inputs will have a dict of the form ``{ "min_shape": Tuple, "opt_shape": Tuple, "max_shape": Tuple }`` + ) + dtype: _enums.dtype = ( + _enums.dtype.unknown + ) #: The expected data type of the input tensor (default: torch_tensorrt.dtype.float32) + _explicit_set_dtype: bool = False + format: _enums.TensorFormat = ( + _enums.TensorFormat.contiguous + ) #: The expected format of the input tensor (default: torch_tensorrt.TensorFormat.NCHW) + + DOMAIN_OFFSET: float = 2.0 + low_tensor_domain_incl: float = 0.0 + high_tensor_domain_excl: float = low_tensor_domain_incl + DOMAIN_OFFSET + torch_dtype: torch.dtype = torch.float32 + torch_tensor: torch.Tensor = None + name: str = "" + +
[docs] def __init__(self, *args: Any, **kwargs: Any) -> None: + """__init__ Method for torch_tensorrt.Input + + Input accepts one of a few construction patterns + + Args: + shape (Tuple or List, optional): Static shape of input tensor + + Keyword Arguments: + shape (Tuple or List, optional): Static shape of input tensor + min_shape (Tuple or List, optional): Min size of input tensor's shape range + Note: All three of min_shape, opt_shape, max_shape must be provided, there must be no positional arguments, shape must not be defined and implictly this sets Input's shape_mode to DYNAMIC + opt_shape (Tuple or List, optional): Opt size of input tensor's shape range + Note: All three of min_shape, opt_shape, max_shape must be provided, there must be no positional arguments, shape must not be defined and implictly this sets Input's shape_mode to DYNAMIC + max_shape (Tuple or List, optional): Max size of input tensor's shape range + Note: All three of min_shape, opt_shape, max_shape must be provided, there must be no positional arguments, shape must not be defined and implictly this sets Input's shape_mode to DYNAMIC + dtype (torch.dtype or torch_tensorrt.dtype): Expected data type for input tensor (default: torch_tensorrt.dtype.float32) + format (torch.memory_format or torch_tensorrt.TensorFormat): The expected format of the input tensor (default: torch_tensorrt.TensorFormat.NCHW) + tensor_domain (Tuple(float, float), optional): The domain of allowed values for the tensor, as interval notation: [tensor_domain[0], tensor_domain[1]). + Note: Entering "None" (or not specifying) will set the bound to [0, 2) + torch_tensor (torch.Tensor): Holds a corresponding torch tensor with this Input. + name (str, optional): Name of this input in the input nn.Module's forward function. Used to specify dynamic shapes for the corresponding input in dynamo tracer. + Examples: + - Input([1,3,32,32], dtype=torch.float32, format=torch.channel_last) + - Input(shape=(1,3,32,32), dtype=torch_tensorrt.dtype.int32, format=torch_tensorrt.TensorFormat.NCHW) + - Input(min_shape=(1,3,32,32), opt_shape=[2,3,32,32], max_shape=(3,3,32,32)) #Implicitly dtype=torch_tensorrt.dtype.float32, format=torch_tensorrt.TensorFormat.NCHW + """ + # Compatibility code for switching over from InputTensorSpec + if "shape" in kwargs and "shape_ranges" in kwargs: + assert ( + len(kwargs["shape_ranges"]) == 1 and len(kwargs["shape_ranges"][0]) == 3 + ) + del kwargs["shape"] + + kwargs["min_shape"] = kwargs["shape_ranges"][0][0] + kwargs["opt_shape"] = kwargs["shape_ranges"][0][1] + kwargs["max_shape"] = kwargs["shape_ranges"][0][2] + + if len(args) == 1: + if not Input._supported_input_size_type(args[0]): + raise TypeError( + "Input shape specifications for inputs are required to be a List, tuple or torch.Size, found type: " + + str(type(args[0])) + ) + if any(k in kwargs for k in ["min_shape", "opt_shape", "max_shape"]): + raise ValueError( + "Found that both shape (as a positional argument), and one or more of min_shape, opt_shape, max_shape were specified\nclass Input expects that only either shape or all three of min_shape, opt_shape, max_shape are defined" + ) + self.shape = tuple(args[0]) + self.shape_mode = Input._ShapeMode.STATIC + + elif len(args) == 0: + if "shape" not in kwargs and not ( + all(k in kwargs for k in ["min_shape", "opt_shape", "max_shape"]) + ): + raise ValueError( + "Missing required arguments for class Input\nEither shape or all three of min_shape, opt_shape, max_shape must be defined" + ) + elif ("shape" in kwargs) and all( + k in kwargs for k in ["min_shape", "opt_shape", "max_shape"] + ): + raise ValueError( + "Found that both shape, and one or more of min_shape, opt_shape, max_shape were specified\nclass Input expects that only either shape or all three of min_shape, opt_shape, max_shape are defined" + ) + + if "shape" in kwargs: + if not Input._supported_input_size_type(kwargs["shape"]): + raise TypeError( + "Input shape specifications for inputs are required to be a List, tuple or torch.Size, found type: " + + str(type(kwargs["shape"])) + ) + self.shape = tuple(kwargs["shape"]) + self.shape_mode = Input._ShapeMode.STATIC + else: + if not Input._supported_input_size_type(kwargs["min_shape"]): + raise TypeError( + "Input shape specifications for inputs are required to be a List, tuple or torch.Size, found type: " + + str(type(kwargs["min_shape"])) + + " for min_shape" + ) + if not Input._supported_input_size_type(kwargs["opt_shape"]): + raise TypeError( + "Input shape specifications for inputs are required to be a List, tuple or torch.Size, found type: " + + str(type(kwargs["opt_shape"])) + + " for opt_shape" + ) + if not Input._supported_input_size_type(kwargs["max_shape"]): + raise TypeError( + "Input shape specifications for inputs are required to be a List, tuple or torch.Size, found type: " + + str(type(kwargs["max_shape"])) + + " for max_shape" + ) + + self.shape = { + "min_shape": tuple(kwargs["min_shape"]), + "opt_shape": tuple(kwargs["opt_shape"]), + "max_shape": tuple(kwargs["max_shape"]), + } + self.shape_mode = Input._ShapeMode.DYNAMIC + + else: + raise ValueError( + "Unexpected number of positional arguments for class Input \n Found {} arguments, expected either zero or a single positional arguments".format( + len(args) + ) + ) + + if "dtype" in kwargs: + if isinstance(kwargs["dtype"], torch.dtype): + self.torch_dtype = kwargs["dtype"] + + self.dtype = Input._parse_dtype(kwargs["dtype"]) + self.torch_dtype = Input._to_torch_dtype(self.dtype) + self._explicit_set_dtype = True + + if "format" in kwargs: + self.format = Input._parse_format(kwargs["format"]) + + if "tensor_domain" in kwargs: + domain = kwargs["tensor_domain"] + else: + domain = None + + self.tensor_domain = Input._parse_tensor_domain(domain) + + if "torch_tensor" in kwargs: + self.torch_tensor = kwargs["torch_tensor"] + else: + if self.shape_mode == Input._ShapeMode.DYNAMIC: + self.torch_tensor = self.example_tensor("opt_shape") + else: + self.torch_tensor = self.example_tensor() + + if "name" in kwargs: + self.name = kwargs["name"]
+ + def __str__(self) -> str: + if self.shape_mode == Input._ShapeMode.STATIC: + return "Input(shape={}, dtype={}, format={}, domain=[{}, {}))".format( + self.shape, + str(self.dtype), + str(self.format), + str(self.tensor_domain[0]), + str(self.tensor_domain[1]), + ) + elif self.shape_mode == Input._ShapeMode.DYNAMIC: + if isinstance(self.shape, dict): + return "Input(min_shape={}, opt_shape={}, max_shape={}, dtype={}, format={}, domain=[{}, {}))".format( + self.shape["min_shape"], + self.shape["opt_shape"], + self.shape["max_shape"], + str(self.dtype), + str(self.format), + str(self.tensor_domain[0]), + str(self.tensor_domain[1]), + ) + else: + raise RuntimeError( + f"Input shape is dynamic but shapes are not provided as dictionary (found: {self.shape})" + ) + else: + raise RuntimeError("Unknown input shape mode") + + @staticmethod + def _supported_input_size_type(input_size: Any) -> bool: + if isinstance(input_size, torch.Size): + return True + elif isinstance(input_size, tuple): + return True + elif isinstance(input_size, list): + return True + else: + return False + + @staticmethod + def _parse_dtype(dtype: Any) -> _enums.dtype: + if isinstance(dtype, torch.dtype): + if dtype == torch.long: + return _enums.dtype.long + elif dtype == torch.int32: + return _enums.dtype.int32 + elif dtype == torch.half: + return _enums.dtype.half + elif dtype == torch.float: + return _enums.dtype.float + elif dtype == torch.float64: + return _enums.dtype.double + elif dtype == torch.bool: + return _enums.dtype.bool + else: + raise TypeError( + "Provided an unsupported data type as an input data type (support: bool, int32, long, half, float), got: " + + str(dtype) + ) + + elif isinstance(dtype, _enums.dtype): + return dtype + + else: + raise TypeError( + "Input data type needs to be specified with a torch.dtype or a torch_tensorrt.dtype, got: " + + str(type(dtype)) + ) + + @staticmethod + def _to_torch_dtype(dtype: _enums.dtype) -> torch.dtype: + if dtype == _enums.dtype.long: + return torch.long + elif dtype == _enums.dtype.int32: + return torch.int32 + elif dtype == _enums.dtype.half: + return torch.half + elif dtype == _enums.dtype.float: + return torch.float + elif dtype == _enums.dtype.bool: + return torch.bool + elif dtype == _enums.dtype.double: + return torch.float64 + else: + # Default torch_dtype used in FX path + return torch.float32 + + def is_trt_dtype(self) -> bool: + return bool(self.dtype != _enums.dtype.long) + + @staticmethod + def _parse_format(format: Any) -> _enums.TensorFormat: + if isinstance(format, torch.memory_format): + if format == torch.contiguous_format: + return _enums.TensorFormat.contiguous + elif format == torch.channels_last: + return _enums.TensorFormat.channels_last + else: + raise ValueError( + "Provided an unsupported tensor format (support: NCHW/contiguous_format, NHWC/channel_last)" + ) + + elif isinstance(format, _enums.TensorFormat): + return format + + else: + raise TypeError( + "Tensor format needs to be specified with either torch.memory_format or torch_tensorrt.TensorFormat" + ) + + @staticmethod + def _parse_tensor_domain( + domain: Optional[Tuple[float, float]] + ) -> Tuple[float, float]: + """ + Produce a tuple of integers which specifies a tensor domain in the interval format: [lo, hi) + + Args: + domain (Tuple[int, int]): A tuple of integers (or NoneTypes) to verify + + Returns: + A tuple of two int32_t-valid integers + """ + if domain is None: + result_domain = ( + Input.low_tensor_domain_incl, + Input.high_tensor_domain_excl, + ) + + elif len(domain) == 2: + domain_lo, domain_hi = domain + + # Validate type and provided values for domain + valid_type_lo = isinstance(domain_lo, (int, float)) + valid_type_hi = isinstance(domain_hi, (int, float)) + + if not valid_type_lo: + raise ValueError( + f"Expected value for tensor domain low specifier, got {domain_lo}" + ) + elif not valid_type_hi: + raise ValueError( + f"Expected value for tensor domain high specifier, got {domain_hi}" + ) + + if domain_hi <= domain_lo: + raise ValueError( + "Expected provided integer range to have low tensor domain value " + + f"< high tensor domain value, got invalid range [{domain_lo}, {domain_hi})" + ) + result_domain = (float(domain_lo), float(domain_hi)) + else: + raise ValueError( + f"Expected 2 values for domain, got {len(domain)}: {domain}" + ) + + return result_domain + +
[docs] @classmethod + def from_tensor( + cls, t: torch.Tensor, disable_memory_format_check: bool = False + ) -> "Input": + """ + Produce a Input which contains the information of the given PyTorch tensor. + + Args: + tensor (torch.Tensor): A PyTorch tensor. + disable_memory_format_check (bool): Whether to validate the memory formats of input tensors + + Returns: + A Input object. + """ + if not ( + disable_memory_format_check + or t.is_contiguous(memory_format=torch.contiguous_format) + or t.is_contiguous(memory_format=torch.channels_last) + ): + raise ValueError( + "Tensor does not have a supported memory format, supported formats are contiguous or channel_last" + ) + frmt = ( + torch.contiguous_format + if ( + disable_memory_format_check + or t.is_contiguous(memory_format=torch.contiguous_format) + ) + else torch.channels_last + ) + return cls(shape=t.shape, dtype=t.dtype, format=frmt, torch_tensor=t)
+ +
[docs] @classmethod + def from_tensors( + cls, ts: Sequence[torch.Tensor], disable_memory_format_check: bool = False + ) -> List["Input"]: + """ + Produce a list of Inputs which contain + the information of all the given PyTorch tensors. + + Args: + tensors (Iterable[torch.Tensor]): A list of PyTorch tensors. + disable_memory_format_check (bool): Whether to validate the memory formats of input tensors + + Returns: + A list of Inputs. + """ + + assert isinstance(ts, (list, tuple)) + return [ + cls.from_tensor(t, disable_memory_format_check=disable_memory_format_check) + for t in ts + ]
+ +
[docs] def example_tensor( + self, optimization_profile_field: Optional[str] = None + ) -> torch.Tensor: + """ + Get an example tensor of the shape specified by the Input object + + Args: + optimization_profile_field (Optional(str)): Name of the field to use for shape in the case the Input is dynamically shaped + + Returns: + A PyTorch Tensor + """ + if self.shape_mode == Input._ShapeMode.STATIC: + if optimization_profile_field is not None: + raise ValueError( + "Specified a optimization profile field but the input is static" + ) + else: + if isinstance(self.shape, tuple): + return torch.rand(self.shape).to(dtype=self.torch_dtype) + else: + RuntimeError( + f"Input shape is dynamic but shapes are not provided as sequence (found: {self.shape})" + ) + else: + if optimization_profile_field is not None: + try: + assert any( + optimization_profile_field == field_name + for field_name in ["min_shape", "opt_shape", "max_shape"] + ) + except AssertionError: + raise ValueError( + "Invalid field name, expected one of min_shape, opt_shape, max_shape" + ) + + if isinstance(self.shape, dict): + return torch.rand(self.shape[optimization_profile_field]).to( + dtype=self.torch_dtype + ) + else: + raise RuntimeError( + f"Input shape is dynamic but shapes are not provided as dictionary (found: {self.shape})" + ) + + else: + raise ValueError( + "Requested an example tensor from a dynamic shaped input but did not specific which profile field to use." + ) + raise
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/_compile.html b/docs/v2.2.0/_modules/torch_tensorrt/_compile.html new file mode 100644 index 0000000000..fbcee62d7d --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/_compile.html @@ -0,0 +1,1065 @@ + + + + + + + + + + + + torch_tensorrt._compile — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt._compile

+from __future__ import annotations
+
+import logging
+from enum import Enum
+from typing import Any, Callable, List, Optional, Sequence, Set
+
+import torch
+import torch.fx
+import torch_tensorrt.ts
+from torch_tensorrt._enums import dtype
+from torch_tensorrt._Input import Input
+from torch_tensorrt._utils import sanitized_torch_version
+from torch_tensorrt.fx import InputTensorSpec
+from torch_tensorrt.fx.lower import compile as fx_compile
+from torch_tensorrt.fx.utils import LowerPrecision
+from torch_tensorrt.ts._compiler import compile as torchscript_compile
+from typing_extensions import TypeGuard
+
+from packaging import version
+
+DYNAMO_ENABLED = version.parse(sanitized_torch_version()) >= version.parse("2.1.dev")
+
+if DYNAMO_ENABLED:
+    from torch._export import ExportedProgram
+    from torch_tensorrt.dynamo._compiler import compile as dynamo_compile
+
+logger = logging.getLogger(__name__)
+
+__all__ = [
+    "compile",
+    "convert_method_to_trt_engine",
+]
+
+
+def _non_fx_input_interface(
+    inputs: Sequence[Input | torch.Tensor | InputTensorSpec],
+) -> TypeGuard[List[Input | torch.Tensor]]:
+    return all(isinstance(i, (torch.Tensor, Input)) for i in inputs)
+
+
+def _fx_input_interface(
+    inputs: Sequence[Input | torch.Tensor | InputTensorSpec],
+) -> TypeGuard[List[InputTensorSpec | torch.Tensor]]:
+    return all(isinstance(i, (torch.Tensor, InputTensorSpec)) for i in inputs)
+
+
+class _IRType(Enum):
+    """Enum to determine the type of IR selected for model compilation"""
+
+    ts = 0
+    fx = 1
+    dynamo = 2
+    torch_compile = 3
+    exported_program = 4
+
+
+class _ModuleType(Enum):
+    """Enum to determine the type of model provided as input"""
+
+    nn = 0
+    ts = 1
+    fx = 2
+    ep = 3
+
+
+def _parse_module_type(module: Any) -> _ModuleType:
+    if any(
+        isinstance(module, t)
+        for t in [torch.jit.ScriptModule, torch.jit.ScriptFunction]
+    ):
+        return _ModuleType.ts
+    elif isinstance(module, torch.fx.GraphModule):
+        return _ModuleType.fx
+    elif DYNAMO_ENABLED and isinstance(module, ExportedProgram):
+        return _ModuleType.ep
+    elif isinstance(module, torch.nn.Module):
+        return _ModuleType.nn
+    else:
+        raise RuntimeError("Module is an unknown format")
+
+
+def _get_target_ir(module_type: _ModuleType, ir: str) -> _IRType:
+    module_is_tsable = any(module_type == t for t in [_ModuleType.nn, _ModuleType.ts])
+    module_is_fxable = any(module_type == t for t in [_ModuleType.nn, _ModuleType.fx])
+    module_is_exportable = module_type == _ModuleType.ep
+
+    ir_targets_torchscript = any(ir == opt for opt in ["torchscript", "ts"])
+    ir_targets_fx = ir == "fx"
+    ir_targets_dynamo = ir == "dynamo"
+    ir_targets_torch_compile = ir == "torch_compile"
+
+    if module_is_tsable and ir_targets_torchscript:
+        return _IRType.ts
+    elif module_is_fxable and ir_targets_fx:
+        return _IRType.fx
+    elif module_is_fxable and ir_targets_dynamo:
+        return _IRType.dynamo
+    elif module_is_fxable and ir_targets_torch_compile:
+        return _IRType.torch_compile
+    else:
+        if ir == "default":
+            # Options are listed in order of preference
+            if DYNAMO_ENABLED and module_is_fxable:
+                logger.info("ir was set to default, using dynamo as ir")
+                return _IRType.dynamo
+            elif module_is_tsable:
+                if DYNAMO_ENABLED:
+                    logger.warning(
+                        "Input graph is a Torchscript module but the ir provided is default (dynamo). Please set ir=torchscript to suppress the warning. Compiling the module with ir=torchscript"
+                    )
+                return _IRType.ts
+            elif module_is_exportable:
+                raise ValueError(
+                    "Input graph is an ExportedProgram which is not currently supported. Please provide torch.nn.Module or torch.fx.GraphModule as input."
+                )
+            else:
+                raise ValueError("Module was provided in an unsupported format")
+        elif ir == "exported_program":
+            raise ValueError(
+                "ir=exported_program is not currently supported. Supported ir options : ts|fx|dynamo"
+            )
+        else:
+            raise ValueError("Unknown ir was requested")
+
+
+
[docs]def compile( + module: Any, + ir: str = "default", + inputs: Optional[Sequence[Input | torch.Tensor | InputTensorSpec]] = None, + enabled_precisions: Optional[Set[torch.dtype | dtype]] = None, + **kwargs: Any, +) -> ( + torch.nn.Module | torch.jit.ScriptModule | torch.fx.GraphModule | Callable[..., Any] +): + """Compile a PyTorch module for NVIDIA GPUs using TensorRT + + Takes a existing PyTorch module and a set of settings to configure the compiler + and using the path specified in ``ir`` lower and compile the module to TensorRT + returning a PyTorch Module back + + Converts specifically the forward method of a Module + + Arguments: + module (Union(torch.nn.Module,torch.jit.ScriptModule): Source module + + Keyword Arguments: + inputs (List[Union(torch_tensorrt.Input, torch.Tensor)]): **Required** List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using + torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum + to select device type. :: + + input=[ + torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1 + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ), # Dynamic input shape for input #2 + torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings + ] + + enabled_precision (Set(Union(torch.dtype, torch_tensorrt.dtype))): The set of datatypes that TensorRT can use when selecting kernels + ir (str): The requested strategy to compile. (Options: default - Let Torch-TensorRT decide, ts - TorchScript with scripting path) + **kwargs: Additional settings for the specific requested strategy (See submodules for more info) + + Returns: + torch.nn.Module: Compiled Module, when run it will execute via TensorRT + """ + input_list = inputs if inputs is not None else [] + enabled_precisions_set = ( + enabled_precisions if enabled_precisions is not None else {torch.float} + ) + + module_type = _parse_module_type(module) + target_ir = _get_target_ir(module_type, ir) + if target_ir == _IRType.ts: + ts_mod = module + if module_type == _ModuleType.nn: + logger.info( + "Module was provided as a torch.nn.Module, trying to script the module with torch.jit.script. In the event of a failure please preconvert your module to TorchScript" + ) + ts_mod = torch.jit.script(module) + assert _non_fx_input_interface(input_list) + compiled_ts_module: torch.jit.ScriptModule = torchscript_compile( + ts_mod, + inputs=input_list, + enabled_precisions=enabled_precisions_set, + **kwargs, + ) + return compiled_ts_module + elif target_ir == _IRType.fx: + if ( + torch.float16 in enabled_precisions_set + or torch_tensorrt.dtype.half in enabled_precisions_set + ): + lower_precision = LowerPrecision.FP16 + elif ( + torch.float32 in enabled_precisions_set + or torch_tensorrt.dtype.float in enabled_precisions_set + ): + lower_precision = LowerPrecision.FP32 + else: + raise ValueError(f"Precision {enabled_precisions_set} not supported on FX") + + assert _fx_input_interface(input_list) + compiled_fx_module: torch.nn.Module = fx_compile( + module, + input_list, + lower_precision=lower_precision, + explicit_batch_dimension=True, + dynamic_batch=False, + **kwargs, + ) + return compiled_fx_module + elif target_ir == _IRType.dynamo: + # Prepare torch and torchtrt inputs + import collections.abc + + from torch_tensorrt.dynamo.utils import prepare_inputs + + if not isinstance(input_list, collections.abc.Sequence): + input_list = [input_list] + + # Export the module + torchtrt_inputs = prepare_inputs(input_list) + exp_program = torch_tensorrt.dynamo.trace(module, torchtrt_inputs, **kwargs) + trt_graph_module = dynamo_compile( + exp_program, + inputs=torchtrt_inputs, + enabled_precisions=enabled_precisions_set, + **kwargs, + ) + return trt_graph_module + elif target_ir == _IRType.torch_compile: + return torch_compile( + module, enabled_precisions=enabled_precisions_set, **kwargs + ) + else: + raise RuntimeError("Module is an unknown format or the ir requested is unknown")
+ + +def torch_compile(module: torch.nn.Module, **kwargs: Any) -> Any: + """ + Returns a boxed model which is the output of torch.compile. + This does not compile the model to TRT. Execute this model on + sample inputs to compile the model to TRT. + """ + from torch_tensorrt.dynamo.backend import torch_tensorrt_backend + + # TODO: Remove dynamic=False when SymInt Dynamic shape support is ready + boxed_fn = torch.compile( + module, backend=torch_tensorrt_backend, dynamic=False, options={**kwargs} + ) + + return boxed_fn + + +
[docs]def convert_method_to_trt_engine( + module: Any, + method_name: str = "forward", + inputs: Optional[Sequence[Input | torch.Tensor]] = None, + ir: str = "default", + enabled_precisions: Optional[Set[torch.dtype | dtype]] = None, + **kwargs: Any, +) -> bytes: + """Convert a TorchScript module method to a serialized TensorRT engine + + Converts a specified method of a module to a serialized TensorRT engine given a dictionary of conversion settings + + Arguments: + module (Union(torch.nn.Module,torch.jit.ScriptModule): Source module + + Keyword Arguments: + inputs (List[Union(torch_tensorrt.Input, torch.Tensor)]): **Required** List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using + torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum + to select device type. :: + + input=[ + torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1 + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ), # Dynamic input shape for input #2 + torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings + ] + + enabled_precision (Set(Union(torch.dtype, torch_tensorrt.dtype))): The set of datatypes that TensorRT can use when selecting kernels + ir (str): The requested strategy to compile. (Options: default - Let Torch-TensorRT decide, ts - TorchScript with scripting path) + **kwargs: Additional settings for the specific requested strategy (See submodules for more info) + Returns: + bytes: Serialized TensorRT engine, can either be saved to a file or deserialized via TensorRT APIs + """ + enabled_precisions_set = ( + enabled_precisions if enabled_precisions is not None else {torch.float} + ) + + module_type = _parse_module_type(module) + target_ir = _get_target_ir(module_type, ir) + if target_ir == _IRType.ts: + ts_mod = module + if module_type == _ModuleType.nn: + logger.info( + "Module was provided as a torch.nn.Module, trying to script the module with torch.jit.script. In the event of a failure please preconvert your module to TorchScript" + ) + ts_mod = torch.jit.script(module) + return torch_tensorrt.ts.convert_method_to_trt_engine( # type: ignore[no-any-return] + ts_mod, + inputs=inputs, + method_name=method_name, + enabled_precisions=enabled_precisions_set, + **kwargs, + ) + elif target_ir == _IRType.fx: + raise RuntimeError( + "convert_method_to_trt_engine call is not supported for ir=fx" + ) + elif target_ir == _IRType.dynamo: + raise RuntimeError( + "convert_method_to_trt_engine call is not supported for ir=dynamo." + ) + elif target_ir == _IRType.torch_compile: + raise RuntimeError( + "convert_method_to_trt_engine call is not supported for ir=torch_compile" + ) + else: + raise RuntimeError("Module is an unknown format or the ir requested is unknown")
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/_utils.html b/docs/v2.2.0/_modules/torch_tensorrt/_utils.html new file mode 100644 index 0000000000..30573edce0 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/_utils.html @@ -0,0 +1,776 @@ + + + + + + + + + + + + torch_tensorrt._utils — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt._utils

+from typing import Any
+
+import torch
+from torch_tensorrt import _C
+from torch_tensorrt._version import __version__
+
+
+
[docs]def dump_build_info() -> None: + """Prints build information about the torch_tensorrt distribution to stdout""" + print(get_build_info())
+ + +
[docs]def get_build_info() -> str: + """Returns a string containing the build information of torch_tensorrt distribution + + Returns: + str: String containing the build information for torch_tensorrt distribution + """ + core_build_info = _C.get_build_info() + build_info = str( + "Torch-TensorRT Version: " + + str(__version__) + + "\n" + + "Using PyTorch Version: " + + str(torch.__version__) + + "\n" + + core_build_info + ) + return build_info
+ + +
[docs]def set_device(gpu_id: int) -> None: + _C.set_device(gpu_id)
+ + +def sanitized_torch_version() -> Any: + return ( + torch.__version__ + if ".nv" not in torch.__version__ + else torch.__version__.split(".nv")[0] + ) +
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_SourceIR.html b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_SourceIR.html new file mode 100644 index 0000000000..a71e6b312f --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_SourceIR.html @@ -0,0 +1,759 @@ + + + + + + + + + + + + torch_tensorrt.dynamo._SourceIR — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.dynamo._SourceIR

+from enum import Enum, auto
+
+
+
[docs]class SourceIR(Enum): + NN = auto() + ACC = auto() + ATEN = auto() + PRIM = auto() + TORCHTRT_LOWERED = auto() + UNKNOWN = auto() + + def __str__(self) -> str: + if self == SourceIR.NN: + return "nn" + elif self == SourceIR.ACC: + return "acc" + elif self == SourceIR.ATEN: + return "aten" + elif self == SourceIR.PRIM: + return "prim" + elif self == SourceIR.TORCHTRT_LOWERED: + return "torchtrt_lowered" + else: + return "unknown_ir"
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_compiler.html b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_compiler.html new file mode 100644 index 0000000000..c1d553c4c2 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_compiler.html @@ -0,0 +1,1098 @@ + + + + + + + + + + + + torch_tensorrt.dynamo._compiler — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.dynamo._compiler

+from __future__ import annotations
+
+import collections.abc
+import logging
+from typing import Any, Collection, List, Optional, Sequence, Set, Tuple, Union
+
+import torch
+import torch_tensorrt
+from torch.export import ExportedProgram
+from torch.fx.node import Target
+from torch_tensorrt._Device import Device
+from torch_tensorrt._enums import (  # TODO: Should probabably be the TRT EngineCapability Enum
+    EngineCapability,
+)
+from torch_tensorrt._Input import Input
+from torch_tensorrt.dynamo import partitioning
+from torch_tensorrt.dynamo._defaults import (
+    DEBUG,
+    DEVICE,
+    DISABLE_TF32,
+    DLA_GLOBAL_DRAM_SIZE,
+    DLA_LOCAL_DRAM_SIZE,
+    DLA_SRAM_SIZE,
+    ENABLE_EXPERIMENTAL_DECOMPOSITIONS,
+    ENGINE_CAPABILITY,
+    MAX_AUX_STREAMS,
+    MIN_BLOCK_SIZE,
+    NUM_AVG_TIMING_ITERS,
+    OPTIMIZATION_LEVEL,
+    OUTPUT_FORMAT,
+    PASS_THROUGH_BUILD_FAILURES,
+    PRECISION,
+    REFIT,
+    REQUIRE_FULL_COMPILATION,
+    SPARSE_WEIGHTS,
+    TRUNCATE_LONG_AND_DOUBLE,
+    USE_FAST_PARTITIONER,
+    USE_PYTHON_RUNTIME,
+    VERSION_COMPATIBLE,
+    WORKSPACE_SIZE,
+)
+from torch_tensorrt.dynamo._exporter import export
+from torch_tensorrt.dynamo.conversion import (
+    CompilationSettings,
+    convert_module,
+    repair_long_or_double_inputs,
+)
+from torch_tensorrt.dynamo.conversion._ConverterRegistry import (
+    DYNAMO_CONVERTERS as CONVERTERS,
+)
+from torch_tensorrt.dynamo.lowering import apply_lowering_passes, get_decompositions
+from torch_tensorrt.dynamo.utils import (
+    get_torch_inputs,
+    prepare_inputs,
+    set_log_level,
+    to_torch_device,
+    to_torch_tensorrt_device,
+)
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]def compile( + exported_program: ExportedProgram, + inputs: Tuple[Any, ...], + *, + device: Optional[Union[Device, torch.device, str]] = DEVICE, + disable_tf32: bool = DISABLE_TF32, + sparse_weights: bool = SPARSE_WEIGHTS, + enabled_precisions: Set[torch.dtype] | Tuple[torch.dtype] = (torch.float32,), + engine_capability: EngineCapability = ENGINE_CAPABILITY, + refit: bool = REFIT, + debug: bool = DEBUG, + num_avg_timing_iters: int = NUM_AVG_TIMING_ITERS, + workspace_size: int = WORKSPACE_SIZE, + dla_sram_size: int = DLA_SRAM_SIZE, + dla_local_dram_size: int = DLA_LOCAL_DRAM_SIZE, + dla_global_dram_size: int = DLA_GLOBAL_DRAM_SIZE, + truncate_long_and_double: bool = TRUNCATE_LONG_AND_DOUBLE, + require_full_compilation: bool = REQUIRE_FULL_COMPILATION, + min_block_size: int = MIN_BLOCK_SIZE, + torch_executed_ops: Optional[Collection[Target]] = None, + torch_executed_modules: Optional[List[str]] = None, + pass_through_build_failures: bool = PASS_THROUGH_BUILD_FAILURES, + max_aux_streams: Optional[int] = MAX_AUX_STREAMS, + version_compatible: bool = VERSION_COMPATIBLE, + optimization_level: Optional[int] = OPTIMIZATION_LEVEL, + use_python_runtime: bool = USE_PYTHON_RUNTIME, + use_fast_partitioner: bool = USE_FAST_PARTITIONER, + enable_experimental_decompositions: bool = ENABLE_EXPERIMENTAL_DECOMPOSITIONS, + output_format: str = OUTPUT_FORMAT, + **kwargs: Any, +) -> torch.fx.GraphModule: + """Compile a TorchScript module for NVIDIA GPUs using TensorRT + + Takes a existing TorchScript module and a set of settings to configure the compiler + and will convert methods to JIT Graphs which call equivalent TensorRT engines + + Converts specifically the forward method of a TorchScript Module + + Arguments: + exported_program (torch.export.ExportedProgram): Source module, running torch.export on a ``torch.nn.Module`` + inputs (Tuple[Any, ...]): List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using + torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum + to select device type. :: + + input=[ + torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1 + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ), # Dynamic input shape for input #2 + torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings + ] + + Keyword Arguments: + device (Union(torch_tensorrt.Device, torch.device, dict)): Target device for TensorRT engines to run on :: + + device=torch_tensorrt.Device("dla:1", allow_gpu_fallback=True) + + disable_tf32 (bool): Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas + sparse_weights (bool): Enable sparsity for convolution and fully connected layers. + enabled_precision (Set(Union(torch.dtype, torch_tensorrt.dtype))): The set of datatypes that TensorRT can use when selecting kernels + refit (bool): Enable refitting + debug (bool): Enable debuggable engine + capability (torch_tensorrt.EngineCapability): Restrict kernel selection to safe gpu kernels or safe dla kernels + num_avg_timing_iters (int): Number of averaging timing iterations used to select kernels + workspace_size (int): Maximum size of workspace given to TensorRT + dla_sram_size (int): Fast software managed RAM used by DLA to communicate within a layer. + dla_local_dram_size (int): Host RAM used by DLA to share intermediate tensor data across operations + dla_global_dram_size (int): Host RAM used by DLA to store weights and metadata for execution + truncate_long_and_double (bool): Truncate weights provided in int64 or double (float64) to int32 and float32 + calibrator (Union(torch_tensorrt._C.IInt8Calibrator, tensorrt.IInt8Calibrator)): Calibrator object which will provide data to the PTQ system for INT8 Calibration + require_full_compilation (bool): Require modules to be compiled end to end or return an error as opposed to returning a hybrid graph where operations that cannot be run in TensorRT are run in PyTorch + min_block_size (int): The minimum number of contiguous TensorRT convertable operations in order to run a set of operations in TensorRT + torch_executed_ops (Collection[Target]): Set of aten operators that must be run in PyTorch. An error will be thrown if this set is not empty but ``require_full_compilation`` is True + torch_executed_modules (List[str]): List of modules that must be run in PyTorch. An error will be thrown if this list is not empty but ``require_full_compilation`` is True + pass_through_build_failures (bool): Error out if there are issues during compilation (only applicable to torch.compile workflows) + max_aux_stream (Optional[int]): Maximum streams in the engine + version_compatible (bool): Build the TensorRT engines compatible with future versions of TensorRT (Restrict to lean runtime operators to provide version forward compatibility for the engines) + optimization_level: (Optional[int]): Setting a higher optimization level allows TensorRT to spend longer engine building time searching for more optimization options. The resulting engine may have better performance compared to an engine built with a lower optimization level. The default optimization level is 3. Valid values include integers from 0 to the maximum optimization level, which is currently 5. Setting it to be greater than the maximum level results in identical behavior to the maximum level. + use_python_runtime: (bool): Return a graph using a pure Python runtime, reduces options for serialization + use_fast_partitioner: (bool): Use the adjacency based partitioning scheme instead of the global partitioner. Adjacency partitioning is faster but may not be optiminal. Use the global paritioner (``False``) if looking for best performance + enable_experimental_decompositions (bool): Use the full set of operator decompositions. These decompositions may not be tested but serve to make the grap easier to covert to TensorRT, potentially increasing the amount of graphs run in TensorRT. + output_format (str): Output format of the result of TRT compilation. Options include "exported_program" (or) "ep" | "torchscript" (or) "ts" | "graph_module" (or) "fx". Default is "exported_program" + **kwargs: Any, + Returns: + torch.fx.GraphModule: Compiled FX Module, when run it will execute via TensorRT + """ + + if debug: + set_log_level(logger.parent, logging.DEBUG) + + if torch_executed_modules is not None and torch_executed_modules: + logger.warning( + f"Detected torch_executed_modules was non-empty: {torch_executed_modules}" + "\nThis feature is unimplemented in Torch-TRT Dynamo currently." + ) + + if not isinstance(inputs, collections.abc.Sequence): + inputs = [inputs] + + # Prepare torch_trt inputs + inputs = prepare_inputs(inputs) + device = to_torch_tensorrt_device(device) + + if not isinstance(exported_program, ExportedProgram): + raise AssertionError( + f"Input graph should be an ExportedProgram but got type {type(exported_program)}" + ) + exported_program = exported_program.run_decompositions( + get_decompositions(enable_experimental_decompositions) + ) + gm = exported_program.module() + logger.debug("Input graph: " + str(gm.graph)) + + # Apply lowering on the graph module + torch_inputs = get_torch_inputs(inputs, device) + gm = apply_lowering_passes(gm, torch_inputs) + logger.debug("Lowered Input graph: " + str(gm.graph)) + + enabled_precisions = set(enabled_precisions) + + if ( + torch.float16 in enabled_precisions + or torch_tensorrt.dtype.half in enabled_precisions + ): + precision = torch.float16 + elif ( + torch.float32 in enabled_precisions + or torch_tensorrt.dtype.float in enabled_precisions + ): + precision = torch.float32 + elif len(enabled_precisions) == 0: + logger.info(f"No precision specified, defaulting to {PRECISION}") + precision = PRECISION + else: + raise ValueError( + f"Precision {enabled_precisions} not supported in the Dynamo Path" + ) + + compilation_options = { + "precision": precision, + "debug": debug, + "device": device, + "workspace_size": workspace_size, + "min_block_size": min_block_size, + "torch_executed_ops": ( + torch_executed_ops if torch_executed_ops is not None else set() + ), + "pass_through_build_failures": pass_through_build_failures, + "max_aux_streams": max_aux_streams, + "version_compatible": version_compatible, + "optimization_level": optimization_level, + "use_python_runtime": use_python_runtime, + "truncate_long_and_double": truncate_long_and_double, + "use_fast_partitioner": use_fast_partitioner, + "num_avg_timing_iters": num_avg_timing_iters, + "enable_experimental_decompositions": enable_experimental_decompositions, + "require_full_compilation": require_full_compilation, + "disable_tf32": disable_tf32, + "sparse_weights": sparse_weights, + "refit": refit, + "engine_capability": engine_capability, + "dla_sram_size": dla_sram_size, + "dla_local_dram_size": dla_local_dram_size, + "dla_global_dram_size": dla_global_dram_size, + "output_format": output_format, + } + + settings = CompilationSettings(**compilation_options) + logger.info("Compilation Settings: %s\n", settings) + trt_gm = compile_module(gm, inputs, settings) + trt_result = export(trt_gm, torch_inputs, output_format) + return trt_result
+ + +def compile_module( + gm: torch.fx.GraphModule, + sample_inputs: Sequence[Input], + settings: CompilationSettings = CompilationSettings(), +) -> torch.fx.GraphModule: + """Compile a traced FX module + + Includes: Partitioning + Conversion Phases + + Args: + module: FX GraphModule to convert + inputs: Inputs to the module + settings: Compilation settings + Returns: + Compiled FX GraphModule + """ + + # Set torch-executed ops + CONVERTERS.set_disallowed_targets(settings.torch_executed_ops) + + # Check the number of supported operations in the graph + num_supported_ops, total_ops = partitioning.get_graph_converter_support( + gm, settings.debug, settings.torch_executed_ops + ) + + # If the number of supported operations is 0 or less than the block size, skip the subgraph + # TODO: Add condition to second expression below when require_full_compilation is added + if num_supported_ops == 0 or (num_supported_ops < settings.min_block_size): + logger.warning( + f"{num_supported_ops} supported operations detected in subgraph containing {total_ops} computational nodes. " + f"Skipping this subgraph, since min_block_size was detected to be {settings.min_block_size}" + ) + return gm + else: + logger.debug( + f"Detected support for {num_supported_ops} operators out of {total_ops} in subgraph." + ) + + # Partition module into components that can be TRT-accelerated + fast_partitioner_failed = False + + # If specified, try using the fast partitioner and fall back to the global one on failure + if settings.use_fast_partitioner: + try: + partitioned_module = partitioning.fast_partition( + gm, + verbose=settings.debug, + min_block_size=settings.min_block_size, + torch_executed_ops=settings.torch_executed_ops, + ) + except torch.fx.passes.splitter_base.FxNetSplitterInternalError: + logger.error( + "Partitioning failed on the subgraph with fast partition. See trace above. " + + "Retrying with global partition.", + exc_info=True, + ) + + fast_partitioner_failed = True + settings.use_fast_partitioner = False + + if not settings.use_fast_partitioner: + partitioned_module = partitioning.global_partition( + gm, + verbose=settings.debug, + min_block_size=settings.min_block_size, + torch_executed_ops=settings.torch_executed_ops, + ) + + # Store TRT replicas of Torch subgraphs + trt_modules = {} + # Iterate over all components that can be accelerated + # Generate the corresponding TRT Module for those + for name, _ in partitioned_module.named_children(): + submodule = getattr(partitioned_module, name) + # Criteria for a module to be convertible to TRT + if settings.use_fast_partitioner and "_run_on_acc" not in name: + continue + + # Get the submodule inputs for min, opt, max shapes of the graph inputs + submodule_inputs = partitioning.get_submod_inputs( + partitioned_module, + submodule, + sample_inputs, + to_torch_device(settings.device), + ) + + logger.debug( + "Submodule name: %s\n Input shapes: %s\n %s", + str(name), + [input.shape for input in submodule_inputs], + str(submodule.graph), + ) + + assert submodule_inputs is not None + # Handle long/double inputs if requested by the user + if settings.truncate_long_and_double: + submodule_inputs = repair_long_or_double_inputs( + partitioned_module, + submodule, + submodule_inputs, + to_torch_device(settings.device), + name, + ) + + # Create TRT engines from submodule + trt_module = convert_module( + submodule, + submodule_inputs, + settings=settings, + name=name, + ) + + trt_modules[name] = trt_module + + # Replace all FX Modules with TRT Modules + for name, trt_module in trt_modules.items(): + setattr(partitioned_module, name, trt_module) + + # Reset settings object to user specification after fallback to global partitioning mode + if fast_partitioner_failed: + settings.use_fast_partitioner = True + + return partitioned_module +
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_exporter.html b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_exporter.html new file mode 100644 index 0000000000..0bc72ea4ce --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_exporter.html @@ -0,0 +1,1085 @@ + + + + + + + + + + + + torch_tensorrt.dynamo._exporter — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.dynamo._exporter

+import operator
+from typing import Any, Dict, Sequence, Tuple, cast
+
+import torch
+from torch._guards import detect_fake_mode
+from torch._subclasses.fake_tensor import FakeTensor
+from torch.export import ExportedProgram, ExportGraphSignature
+from torch.export.exported_program import (
+    InputKind,
+    InputSpec,
+    OutputKind,
+    OutputSpec,
+    TensorArgument,
+)
+from torch_tensorrt.dynamo import partitioning
+
+
+
[docs]def export( + gm: torch.fx.GraphModule, + inputs: Sequence[torch.Tensor], + output_format: str, +) -> ExportedProgram: + """Export the result of TensorRT compilation into the desired output format. + + Arguments: + gm (torch.fx.GraphModule): Compiled Torch-TensorRT module, generated by ``torch_tensorrt.dynamo.compile`` + inputs (torch.Tensor): Torch input tensors + output_format (str): Output format of the result of TRT compilation. Options include "exported_program" (or) "ep" | "torchscript" (or) "ts" | "graph_module" (or) "fx". Default is "exported_program" + """ + if output_format == "torchscript" or output_format == "ts": + return torch.jit.trace(gm, inputs) + elif output_format == "exported_program" or output_format == "ep": + patched_module = transform(gm, inputs) + exp_program = create_trt_exp_program(patched_module) + return exp_program + elif output_format == "graph_module" or output_format == "fx": + return gm + else: + raise ValueError( + f"Invalid output format {output_format} specified. Supported options include exported_program (or) ep | torchscript (or) ts | graph_module (or) fx" + )
+ + +def transform( + gm: torch.fx.GraphModule, inputs: Sequence[torch.Tensor] +) -> torch.fx.GraphModule: + """ + Transforms the graphmodule by inlining Pytorch and TensorRT submodules. + Inlining collapses submodules into nodes which is necessary for torch.export + serialization. + + Arguments: + gm (torch.fx.GraphModule): Compiled Torch-TensorRT module, generated by ``torch_tensorrt.dynamo.compile`` + inputs (torch.Tensor): Torch input tensors + + Returns an inlined torch.fx.GraphModule + """ + # Run shape analysis + _, outputs_map = partitioning.run_shape_analysis(gm, inputs) + + # Inline TensorRT submodules + inline_trt_modules(gm, outputs_map) + + # Inline pytorch submodules + inline_torch_modules(gm) + + # Clean the graph + gm.delete_all_unused_submodules() + gm.graph.eliminate_dead_code() + gm.graph.lint() + + return gm + + +def lift(gm: torch.fx.GraphModule, graph_signature: Any) -> torch.fx.GraphModule: + """ + Given an unlifted fx.GraphModule, lift all parameters, buffers into placeholders. + Arguments: + gm (torch.fx.GraphModule): Unlifted GraphModule which contains parameters and buffers as get_attr nodes. + graph_signature (torch.export.ExportGraphSignature): Instance of ExportGraphSignature class created for the output ExportedProgram. + After lifting, this graph_signature will be modified with the parameters and buffers added appropriately. + Returns: + A lifted fx.GraphModule, modified graph_signature and a new state_dict + """ + # Get the state_dict of graph_module. This is different from exported_program.state_dict + # exp_program.state_dict contains parameters and buffers whereas a graph_module's state_dict + # has all parameters registered as torch.tensors. + state_dict = gm.state_dict() + + fake_mode = detect_fake_mode( + tuple(node.meta["val"] for node in gm.graph.nodes if node.op == "placeholder") + ) + assert fake_mode is not None + + # Locate the user input to insert new placeholders before them + first_user_input = None + for node in gm.graph.nodes: + if node.op == "placeholder" and node.name in graph_signature.user_inputs: + first_user_input = node + break + + # At first the user_inputs are only present in the graph_signature.input_specs and hence non_user_input_idx=0 + # The input_specs should be of the form [params, buffers, constant_tensors, user_inputs] + non_user_input_idx = 0 + for node in gm.graph.nodes: + if node.op == "get_attr": + constant_tensor = getattr(gm, node.target) + input_kind = InputKind.CONSTANT_TENSOR + + # state_dict has these parameters/buffers as torch.Tensors. We override them as torch.nn.Parameter/torch.Tensors respectively. + for name, _ in gm.named_parameters(): + if node.target == name: + input_kind = InputKind.PARAMETER + state_dict[name] = constant_tensor + break + for name, _ in gm.named_buffers(): + if node.target == name: + input_kind = InputKind.BUFFER + state_dict[name] = constant_tensor + break + + # Replace get_attr nodes with placeholder nodes and copy metadata. + with gm.graph.inserting_before(first_user_input): + const_placeholder_node = gm.graph.placeholder(node.target) + for k, v in node.meta.items(): + const_placeholder_node.meta[k] = v + const_placeholder_node.meta["val"] = fake_mode.from_tensor( + constant_tensor + ) + node.replace_all_uses_with(const_placeholder_node) + gm.graph.erase_node(node) + + # Add these parameters/buffers/constants to the existing graph signature + # before user inputs. These specs are looked up in the state_dict during ExportedProgram creation. + graph_signature.input_specs.insert( + non_user_input_idx, + InputSpec( + kind=input_kind, + arg=TensorArgument(name=const_placeholder_node.name), + target=node.target, + ), + ) + non_user_input_idx += 1 + + gm.graph.eliminate_dead_code() + gm.graph.lint() + + return gm, graph_signature, state_dict + + +def get_duplicate_nodes( + gm: torch.fx.GraphModule, submodule: torch.fx.GraphModule +) -> Tuple[Sequence[Any], Sequence[Any]]: + """ + We check if there are duplicate nodes when we copy submodule graph into gm. + Handle the case where the subgraph input placeholders are same as + gm placeholders. This happens when the first submodule in the graph is + a pytorch submodule + """ + submodule_placeholder_inputs = [ + node for node in submodule.graph.nodes if node.op == "placeholder" + ] + submodule_input_node_names = [node.name for node in submodule_placeholder_inputs] + gm_node_names = [node.name for node in gm.graph.nodes] + submodule_duplicate_inputs = [ + node for node in submodule_placeholder_inputs if node.name in gm_node_names + ] + gm_duplicate_inputs = [ + node for node in gm.graph.nodes if node.name in submodule_input_node_names + ] + return submodule_duplicate_inputs, gm_duplicate_inputs + + +def inline_torch_modules(gm: torch.fx.GraphModule) -> torch.fx.GraphModule: + """ + Inline a submodule within the parent graph (gm). All `call_module` nodes + should be replaced by their nodes in the submodule. + """ + # Clean the graph + gm.graph.eliminate_dead_code() + gm.graph.lint() + + for gm_node in gm.graph.nodes: + if gm_node.op == "call_module" and "_run_on_gpu" in gm_node.name: + submodule = getattr(gm, gm_node.name) + with gm.graph.inserting_before(gm_node): + # Get inputs of submodule node which are most likely outputs of a previous TRT node + # or a placeholder of the main graph + submodule_inputs = gm_node.args + + submodule_duplicate_inputs, gm_duplicate_inputs = get_duplicate_nodes( + gm, submodule + ) + assert len(submodule_duplicate_inputs) == len(gm_duplicate_inputs) + # Avoid creating new copies of duplicate inputs by creating a mapping + val_map = {} + for i in range(len(submodule_duplicate_inputs)): + val_map[submodule_duplicate_inputs[i]] = gm_duplicate_inputs[i] + + # Copy all nodes in the submodule into gm and + # store the output node of this submodule which is now present in gm + submodule_output = gm.graph.graph_copy(submodule.graph, val_map) + + # Get their references (since we copied) in the parent graph (gm) + if len(submodule_duplicate_inputs) == 0: + submodule_placeholder_input_names = [ + node.name + for node in submodule.graph.nodes + if node.op == "placeholder" + ] + gm_added_placeholder_inputs = [ + node + for node in gm.graph.nodes + if node.name in submodule_placeholder_input_names + ] + + assert len(submodule_inputs) == len(gm_added_placeholder_inputs) + + # Replace the added placeholder inputs with original inputs to this submodule node + for idx in range(len(gm_added_placeholder_inputs)): + gm_added_placeholder_inputs[idx].replace_all_uses_with( + submodule_inputs[idx] + ) + + # Erase the placeholder input nodes in the gm + for idx in range(len(gm_added_placeholder_inputs)): + gm.graph.erase_node(gm_added_placeholder_inputs[idx]) + + # Replace the pytorch submodule node (call_module) with the inlined subgraph output + gm_node.replace_all_uses_with(submodule_output) + + # copy the attributes of the submodule into gm (graph_copy doesn't do this) + copy_submodule_attributes(gm, gm_node.name) + + # Erase the pytorch submodule (call_module) node + gm.graph.erase_node(gm_node) + + return gm + + +def copy_submodule_attributes(gm: torch.fx.GraphModule, submod_name: str) -> None: + """ + Copy the getattr attriibutes from submodule to parent module gm. + The graph_copy call doesn't do this for us unfortunately. + """ + for param in gm.named_parameters(): + if param[0].startswith(submod_name + "."): + attr_name = param[0].replace(submod_name + ".", "") + gm.register_parameter(attr_name, param[1]) + + for buffer in gm.named_buffers(): + if buffer[0].startswith(submod_name + "."): + attr_name = buffer[0].replace(submod_name + ".", "") + gm.register_buffer(attr_name, buffer[1]) + + +def create_trt_exp_program( + gm: torch.fx.GraphModule, +) -> ExportedProgram: + """Creates a new Exported Program. This function takes an torch.fx.GraphModule which has TRT engines + and constructs an Exported Program object with the new IO node names and state_dict + """ + + input_nodes = [node for node in gm.graph.nodes if node.op == "placeholder"] + output_nodes = [node for node in gm.graph.nodes if node.op == "output"] + assert output_nodes + output_nodes = output_nodes[0].args[0] + + input_specs = [ + InputSpec(InputKind.USER_INPUT, TensorArgument(name=node.name), node.target) + for node in input_nodes + ] + output_specs = [ + OutputSpec(OutputKind.USER_OUTPUT, TensorArgument(name=node.name), node.target) + for node in output_nodes + ] + + trt_graph_signature = ExportGraphSignature( + input_specs=input_specs, output_specs=output_specs + ) + + # Lift parameters/buffers/constants in the graph + # torch.export serialization expects them to be lifted + gm, trt_graph_signature, state_dict = lift(gm, trt_graph_signature) + + trt_exp_program = ExportedProgram( + gm, gm.graph, trt_graph_signature, state_dict, {}, [], [], [] + ) + + return trt_exp_program + + +def inline_trt_modules( + gm: torch.fx.GraphModule, outputs_map: Dict[Any, Sequence[Any]] +) -> torch.fx.GraphModule: + """ + Replace TRT submodules with trt engine nodes. + """ + for name, _ in gm.named_children(): + if "_run_on_acc" not in name: + continue + # Get the TRT submodule + trt_module = getattr(gm, name) + + # Ensure the trt module node in the main graph (gm) has inputs + trt_module_node = [node for node in gm.graph.nodes if node.name == name] + assert trt_module_node + trt_module_node = trt_module_node[0] + assert trt_module_node.args + + num_outputs = len(outputs_map[trt_module_node.name]) + # Insert a call_function node to perform inference on TRT engine + with gm.graph.inserting_before(trt_module_node): + trt_node = gm.graph.call_function( + torch.ops.tensorrt.execute_engine.default, + (trt_module_node.args, trt_module.engine), + ) + trt_node.meta["val"] = [] + assert num_outputs > 0 + # Generate meta data for TRT node (a FakeTensor with corresponding output shape) + for idx in range(num_outputs): + trt_node.meta["val"].append( + cast( + FakeTensor, + torch.empty_strided( + tuple(outputs_map[trt_module_node.name][idx]), + tuple([1] * len(outputs_map[trt_module_node.name][idx])), + ), + ) + ) + + if num_outputs == 1: + # Insert getitem nodes as outputs (for export serialization to work) + with gm.graph.inserting_after(trt_node): + getitem_output = gm.graph.call_function(operator.getitem, (trt_node, 0)) + getitem_output.meta["val"] = trt_node.meta["val"] + trt_module_node.replace_all_uses_with(getitem_output) + else: + # Multiple outputs case: + # Replace uses of submodule with the trt_node. + # getitem nodes are already added inherently by the partitioner + trt_module_node.replace_all_uses_with(trt_node) + getitem_nodes = trt_node.users + for idx, getitem_node in enumerate(getitem_nodes): + getitem_node.meta["val"] = trt_node.meta["val"][idx] + + # Erase the TRT submodule (call_module) node. + gm.graph.erase_node(trt_module_node) + + return gm +
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_settings.html b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_settings.html new file mode 100644 index 0000000000..2a8e051915 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_settings.html @@ -0,0 +1,829 @@ + + + + + + + + + + + + torch_tensorrt.dynamo._settings — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.dynamo._settings

+from dataclasses import dataclass, field
+from typing import Collection, Optional
+
+import torch
+from tensorrt import EngineCapability
+from torch.fx.node import Target
+from torch_tensorrt._Device import Device
+from torch_tensorrt.dynamo._defaults import (
+    DEBUG,
+    DISABLE_TF32,
+    DLA_GLOBAL_DRAM_SIZE,
+    DLA_LOCAL_DRAM_SIZE,
+    DLA_SRAM_SIZE,
+    ENABLE_EXPERIMENTAL_DECOMPOSITIONS,
+    ENGINE_CAPABILITY,
+    MAX_AUX_STREAMS,
+    MIN_BLOCK_SIZE,
+    NUM_AVG_TIMING_ITERS,
+    OPTIMIZATION_LEVEL,
+    OUTPUT_FORMAT,
+    PASS_THROUGH_BUILD_FAILURES,
+    PRECISION,
+    REFIT,
+    REQUIRE_FULL_COMPILATION,
+    SPARSE_WEIGHTS,
+    TRUNCATE_LONG_AND_DOUBLE,
+    USE_FAST_PARTITIONER,
+    USE_PYTHON_RUNTIME,
+    VERSION_COMPATIBLE,
+    WORKSPACE_SIZE,
+    default_device,
+)
+
+
+
[docs]@dataclass +class CompilationSettings: + """Compilation settings for Torch-TensorRT Dynamo Paths + + Args: + precision (torch.dtype): Model Layer precision + debug (bool): Whether to print out verbose debugging information + workspace_size (int): Workspace TRT is allowed to use for the module (0 is default) + min_block_size (int): Minimum number of operators per TRT-Engine Block + torch_executed_ops (Collection[Target]): Collection of operations to run in Torch, regardless of converter coverage + pass_through_build_failures (bool): Whether to fail on TRT engine build errors (True) or not (False) + max_aux_streams (Optional[int]): Maximum number of allowed auxiliary TRT streams for each engine + version_compatible (bool): Provide version forward-compatibility for engine plan files + optimization_level (Optional[int]): Builder optimization 0-5, higher levels imply longer build time, + searching for more optimization options. TRT defaults to 3 + use_python_runtime (Optional[bool]): Whether to strictly use Python runtime or C++ runtime. To auto-select a runtime + based on C++ dependency presence (preferentially choosing C++ runtime if available), leave the + argument as None + truncate_long_and_double (bool): Whether to truncate int64/float64 TRT engine inputs or weights to int32/float32 + use_fast_partitioner (bool): Whether to use the fast or global graph partitioning system + enable_experimental_decompositions (bool): Whether to enable all core aten decompositions + or only a selected subset of them + device (Device): GPU to compile the model on + require_full_compilation (bool): Whether to require the graph is fully compiled in TensorRT. + Only applicable for `ir="dynamo"`; has no effect for `torch.compile` path + disable_tf32 (bool): Whether to disable TF32 computation for TRT layers + sparse_weights (bool): Whether to allow the builder to use sparse weights + refit (bool): Whether to build a refittable engine + engine_capability (trt.EngineCapability): Restrict kernel selection to safe gpu kernels or safe dla kernels + num_avg_timing_iters (int): Number of averaging timing iterations used to select kernels + dla_sram_size (int): Fast software managed RAM used by DLA to communicate within a layer. + dla_local_dram_size (int): Host RAM used by DLA to share intermediate tensor data across operations + dla_global_dram_size (int): Host RAM used by DLA to store weights and metadata for execution + output_format (str): Output format of the result of TRT compilation. Options include "exported_program" (or) "ep" | "torchscript" (or) "ts" | "graph_module" (or) "fx". Default is "exported_program" + """ + + precision: torch.dtype = PRECISION + debug: bool = DEBUG + workspace_size: int = WORKSPACE_SIZE + min_block_size: int = MIN_BLOCK_SIZE + torch_executed_ops: Collection[Target] = field(default_factory=set) + pass_through_build_failures: bool = PASS_THROUGH_BUILD_FAILURES + max_aux_streams: Optional[int] = MAX_AUX_STREAMS + version_compatible: bool = VERSION_COMPATIBLE + optimization_level: Optional[int] = OPTIMIZATION_LEVEL + use_python_runtime: Optional[bool] = USE_PYTHON_RUNTIME + truncate_long_and_double: bool = TRUNCATE_LONG_AND_DOUBLE + use_fast_partitioner: bool = USE_FAST_PARTITIONER + enable_experimental_decompositions: bool = ENABLE_EXPERIMENTAL_DECOMPOSITIONS + device: Device = field(default_factory=default_device) + require_full_compilation: bool = REQUIRE_FULL_COMPILATION + disable_tf32: bool = DISABLE_TF32 + sparse_weights: bool = SPARSE_WEIGHTS + refit: bool = REFIT + engine_capability: EngineCapability = ENGINE_CAPABILITY + num_avg_timing_iters: int = NUM_AVG_TIMING_ITERS + dla_sram_size: int = DLA_SRAM_SIZE + dla_local_dram_size: int = DLA_LOCAL_DRAM_SIZE + dla_global_dram_size: int = DLA_GLOBAL_DRAM_SIZE + output_format: str = OUTPUT_FORMAT
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_tracer.html b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_tracer.html new file mode 100644 index 0000000000..037800c514 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/dynamo/_tracer.html @@ -0,0 +1,822 @@ + + + + + + + + + + + + torch_tensorrt.dynamo._tracer — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.dynamo._tracer

+from __future__ import annotations
+
+import logging
+from typing import Any, Tuple
+
+import torch
+from torch.export import Dim, export
+from torch_tensorrt._Input import Input
+from torch_tensorrt.dynamo._defaults import DEBUG, default_device
+from torch_tensorrt.dynamo.utils import get_torch_inputs, set_log_level, to_torch_device
+
+logger = logging.getLogger(__name__)
+
+
+
[docs]def trace( + mod: torch.nn.Module | torch.fx.GraphModule, + inputs: Tuple[Any, ...], + **kwargs: Any, +) -> torch.export.ExportedProgram: + """Exports a ``torch.export.ExportedProgram`` from a ``torch.nn.Module`` or ``torch.fx.GraphModule`` specifically targeting being compiled with Torch-TensorRT + + Exports a ``torch.export.ExportedProgram`` from either a ``torch.nn.Module`` or torch.fx.GraphModule``. Runs specific operator decompositions geared towards + compilation by Torch-TensorRT's dynamo frontend. + + Arguments: + mod (torch.nn.Module | torch.fx.GraphModule): Source module to later be compiled by Torch-TensorRT's dynamo fronted + inputs (Tuple[Any, ...]): List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using + torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum + to select device type. :: + + input=[ + torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1 + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ), # Dynamic input shape for input #2 + torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings + ] + Keyword Arguments: + device (Union(torch.device, dict)): Target device for TensorRT engines to run on :: + + device=torch.device("cuda:0") + + debug (bool): Enable debuggable engine + enable_experimental_decompositions (bool): Use the full set of operator decompositions. These decompositions may not be tested but serve to make the grap easier to covert to TensorRT, potentially increasing the amount of graphs run in TensorRT. + **kwargs: Any, + Returns: + torch.fx.GraphModule: Compiled FX Module, when run it will execute via TensorRT + """ + + # Set log level at the top of compilation (torch_tensorrt.dynamo) + debug = kwargs.get("debug", DEBUG) + if debug: + set_log_level(logger.parent, logging.DEBUG) + + device = to_torch_device(kwargs.get("device", default_device())) + torch_inputs = get_torch_inputs(inputs, device) + dynamic_shapes = {} + for input in inputs: + if isinstance(input, Input) and input.shape_mode == Input._ShapeMode.DYNAMIC: + if not input.name: + raise AssertionError( + f"Expected a name for a dynamic input with shape {input.shape} but found none" + ) + min_shape = input.shape["min_shape"] # type: ignore + opt_shape = input.shape["opt_shape"] # type: ignore + max_shape = input.shape["max_shape"] # type: ignore + assert len(min_shape) == len(opt_shape) == len(max_shape) + dynamic_dims = {} + for dim in range(len(min_shape)): + if min_shape[dim] == opt_shape[dim] == max_shape[dim]: + continue + else: + dynamic_dims[dim] = Dim( + input.name + "_" + str(dim), + min=min_shape[dim], + max=max_shape[dim], + ) + + dynamic_shapes[input.name] = dynamic_dims + + exp_program = export(mod, tuple(torch_inputs), dynamic_shapes=dynamic_shapes) + + return exp_program
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/fx/fx2trt.html b/docs/v2.2.0/_modules/torch_tensorrt/fx/fx2trt.html new file mode 100644 index 0000000000..5261906019 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/fx/fx2trt.html @@ -0,0 +1,1123 @@ + + + + + + + + + + + + torch_tensorrt.fx.fx2trt — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.fx.fx2trt

+import logging
+import os
+import warnings
+from datetime import datetime
+from typing import Any, Callable, Dict, List, NamedTuple, Optional, Sequence
+
+import numpy
+
+# @manual=//deeplearning/trt/python:py_tensorrt
+import tensorrt as trt
+import torch
+import torch.fx
+from torch._ops import OpOverload
+from torch.fx.node import _get_qualified_name
+from torch.fx.passes.shape_prop import TensorMetadata
+
+from .converter_registry import CONVERTERS
+from .input_tensor_spec import InputTensorSpec
+from .observer import Observer
+from .utils import Frameworks, LowerPrecision, get_dynamic_dims, unified_dtype_converter
+
+_LOGGER: logging.Logger = logging.getLogger(__name__)
+
+TRT_INTERPRETER_CALL_PRE_OBSERVER: Observer[Callable[[torch.fx.GraphModule], None]] = (
+    Observer("TRT_INTERPRETER_CALL_PRE_OBSERVER")
+)
+
+
+
[docs]class TRTInterpreterResult(NamedTuple): + engine: Any + input_names: Sequence[str] + output_names: Sequence[str] + serialized_cache: bytearray
+ + +
[docs]class TRTInterpreter(torch.fx.Interpreter): + def __init__( + self, + module: torch.fx.GraphModule, + input_specs: List[InputTensorSpec], + explicit_batch_dimension: bool = False, + explicit_precision: bool = False, + logger_level=None, + ): + super().__init__(module) + + self.logger = trt.Logger(logger_level or trt.Logger.WARNING) + self.builder = trt.Builder(self.logger) + + flag = 0 + if explicit_batch_dimension: + EXPLICIT_BATCH = 1 << (int)( + trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH + ) + flag |= EXPLICIT_BATCH + + if explicit_precision: + EXPLICIT_PRECISION = 1 << (int)( + trt.NetworkDefinitionCreationFlag.EXPLICIT_PRECISION + ) + flag |= EXPLICIT_PRECISION + self.network = self.builder.create_network(flag) + + missing_ops = self.validate_conversion() + if missing_ops: + warnings.warn( + "Interpretation will fail due to missing operations \n" + + "\n".join(f"{i}" for i in missing_ops) + ) + + self.optimization_profiles: Optional[List] = None + self.input_specs = input_specs + self.input_specs_iter = 0 + self.validate_input_specs() + self._cur_node_name: Optional[str] = None + self._input_names: List[str] = [] + self._output_names: List[str] = [] + self._itensor_to_tensor_meta: Dict[trt.tensorrt.ITensor, TensorMetadata] = ( + dict() + ) + + def validate_input_specs(self): + for shape, _, _, shape_ranges, has_batch_dim in self.input_specs: + if not self.network.has_implicit_batch_dimension: + assert ( + has_batch_dim + ), "It's required to specify batch dimension when it's explicit in TensorRT network." + + dynamic_dims = get_dynamic_dims(shape) + if len(dynamic_dims): + assert not self.network.has_implicit_batch_dimension, ( + "Can't have dynamic dim when " + f"batch dim is implicit, got {shape}." + ) + assert len( + shape_ranges + ), "shape_ranges must be provided when shape has dynamic dim." + + if self.optimization_profiles: + assert len(shape_ranges) == len(self.optimization_profiles), ( + "Number of optimization " + f"profiles {len(self.optimization_profiles)} doesn't match with the number of shape_range" + f" {len(shape_ranges)} provided." + ) + else: + self.optimization_profiles = [ + self.builder.create_optimization_profile() + for _ in range(len(shape_ranges)) + ] + + for shape_range in shape_ranges: + assert ( + len(shape_range) == 3 + ), f"Expect three elements in shape_range, got {len(shape_range)}" + assert all(len(s) == len(shape) for s in shape_range), ( + "Expect elements in shape_range" + f" {shape_range} have the same number of dimension as the provided shape {len(shape)}" + ) + + for i in range(len(shape)): + if i in dynamic_dims: + assert all( + shape_range[j][i] <= shape_range[j + 1][i] + for j in range(2) + ), ( + "Expect dynamic dim" + f" {i} to have incremental value for shapes in shape_range {shape_range}." + ) + else: + assert all(s[i] == shape[i] for s in shape_range), ( + f"Expect non dynamic dim {i} to be the same" + f" for all shapes in shape_range {shape_range}." + ) + else: + assert ( + len(shape_ranges) == 0 + ), "shape_ranges are provided for input that doesn't have dynamic dim." + + def validate_conversion(self): + missing_converter = set() + + for node in self.module.graph.nodes: + if node.op == "call_function" and not CONVERTERS.get(node.target): + missing_converter.add(f"{node.op} {_get_qualified_name(node.target)}") + elif node.op == "call_method" and not CONVERTERS.get(node.target): + missing_converter.add(f"{node.op} torch.Tensor.{node.target}") + elif node.op == "call_module": + submod = self.fetch_attr(node.target) + submod_type = getattr(submod, "_base_class_origin", type(submod)) + if not CONVERTERS.get(submod_type): + missing_converter.add(f"{node.op} {torch.typename(submod_type)}") + + return missing_converter + + def run( + self, + max_batch_size=64, + max_workspace_size=1 << 25, + lower_precision=LowerPrecision.FP16, + sparse_weights=False, + force_fp32_output=False, + strict_type_constraints=False, + algorithm_selector=None, + timing_cache=None, + profiling_verbosity=None, + tactic_sources=None, + ) -> TRTInterpreterResult: + """ + Build TensorRT engine with some configs. + Args: + max_batch_size: set accordingly for maximum batch size you will use. + max_workspace_size: set to the maximum size we can afford for temporary buffer + lower_precision: the precision model layers are running on (TensorRT will choose the best perforamnce precision). + sparse_weights: allow the builder to examine weights and use optimized functions when weights have suitable sparsity + force_fp32_output: force output to be fp32 + strict_type_constraints: Usually we should set it to False unless we want to control the precision of certain layer for numeric reasons. + algorithm_selector: set up algorithm selection for certain layer + timing_cache: enable timing cache for TensorRT + profiling_verbosity: TensorRT logging level + Return: + TRTInterpreterResult + """ + TRT_INTERPRETER_CALL_PRE_OBSERVER.observe(self.module) + + # For float outputs, we set their dtype to fp16 only if lower_precision == LowerPrecision.FP16 and + # force_fp32_output=False. + self.output_fp16 = ( + not force_fp32_output and lower_precision == LowerPrecision.FP16 + ) + + if ( + lower_precision == LowerPrecision.INT8 + and not self.builder.platform_has_fast_int8 + ): + raise RuntimeError("Current platform doesn't support fast native int8!") + + if ( + lower_precision == LowerPrecision.FP16 + and not self.builder.platform_has_fast_fp16 + ): + warnings.warn("Current platform doesn't support fast native fp16!") + + self.input_specs_iter = 0 + run_module_start_time = datetime.now() + super().run() + _LOGGER.info( + f"TRT INetwork construction elapsed time: {datetime.now() - run_module_start_time}" + ) + build_engine_start_time = datetime.now() + + self.builder.max_batch_size = max_batch_size + builder_config = self.builder.create_builder_config() + builder_config.max_workspace_size = max_workspace_size + + # Speed up TRT build time in the test environment + if trt.__version__ >= "8.6" and os.environ.get("TRT_TEST_ENV", "0") == "1": + _LOGGER.info("Set TRT optimization level to 0") + builder_config.builder_optimization_level = 0 + + cache = None + if timing_cache: + cache_file = numpy.array(timing_cache) + cache = builder_config.create_timing_cache(cache_file.tobytes()) + else: + cache = builder_config.create_timing_cache(b"") + builder_config.set_timing_cache(cache, False) + + if trt.__version__ >= "8.2": + builder_config.profiling_verbosity = ( + profiling_verbosity + if profiling_verbosity + else trt.ProfilingVerbosity.LAYER_NAMES_ONLY + ) + if lower_precision == LowerPrecision.FP16: + builder_config.set_flag(trt.BuilderFlag.FP16) + + if lower_precision == LowerPrecision.INT8: + builder_config.set_flag(trt.BuilderFlag.INT8) + + if sparse_weights: + builder_config.set_flag(trt.BuilderFlag.SPARSE_WEIGHTS) + + if strict_type_constraints: + builder_config.set_flag(trt.BuilderFlag.STRICT_TYPES) + + if self.optimization_profiles: + for optimization_profile in self.optimization_profiles: + builder_config.add_optimization_profile(optimization_profile) + + if algorithm_selector: + builder_config.set_flag(trt.BuilderFlag.DISABLE_TIMING_CACHE) + builder_config.algorithm_selector = algorithm_selector + + if tactic_sources is not None: + builder_config.set_tactic_sources(tactic_sources=tactic_sources) + + engine = self.builder.build_engine(self.network, builder_config) + assert engine + + serialized_cache = ( + bytearray(cache.serialize()) + if builder_config.get_timing_cache() + else bytearray() + ) + _LOGGER.info( + f"Build TRT engine elapsed time: {datetime.now() - build_engine_start_time}" + ) + + return TRTInterpreterResult( + engine, self._input_names, self._output_names, serialized_cache + ) + + def run_node(self, n): + self._cur_node_name = str(n) + # add "_itensor_to_tensor_meta" + kwargs = dict(n.kwargs) + kwargs["_itensor_to_tensor_meta"] = self._itensor_to_tensor_meta + n.kwargs = kwargs + + # run the node + trt_node = super().run_node(n) + + # remove "_itensor_to_tensor_meta" + kwargs = dict(n.kwargs) + del kwargs["_itensor_to_tensor_meta"] + n.kwargs = kwargs + + if isinstance(trt_node, trt.tensorrt.ITensor): + self._itensor_to_tensor_meta[trt_node] = n.meta.get("tensor_meta") + + return trt_node + + def placeholder(self, target, args, kwargs): + self._input_names.append(target) + shape, dtype, _, shape_ranges, has_batch_dim = self.input_specs[ + self.input_specs_iter + ] + self.input_specs_iter += 1 + + if self.network.has_implicit_batch_dimension: + if has_batch_dim: + shape = shape[1:] + else: + for i, shape_range in enumerate(shape_ranges): + assert self.optimization_profiles + self.optimization_profiles[i].set_shape(target, *shape_range) + + return self.network.add_input( + name=target, + shape=tuple(shape), + dtype=unified_dtype_converter(dtype, Frameworks.TRT), + ) + + def call_module(self, target, args, kwargs): + assert isinstance(target, str) + submod = self.fetch_attr(target) + submod_type = getattr(submod, "_base_class_origin", type(submod)) + converter = CONVERTERS.get(submod_type) + + if not converter: + raise RuntimeError( + f"Conversion of module of type {submod_type} not currently supported!" + ) + + assert self._cur_node_name is not None + return converter(self.network, submod, args, kwargs, self._cur_node_name) + + def call_function(self, target, args, kwargs): + converter = CONVERTERS.get(target) + if not converter: + raise RuntimeError( + f"Conversion of function {torch.typename(target)} not currently supported!" + ) + + assert self._cur_node_name is not None + return converter(self.network, target, args, kwargs, self._cur_node_name) + + def call_method(self, target, args, kwargs): + assert isinstance(target, str) + converter = CONVERTERS.get(target) + + if not converter: + raise RuntimeError( + f"Conversion of method {target} not currently supported!" + ) + + assert self._cur_node_name is not None + return converter(self.network, target, args, kwargs, self._cur_node_name) + + def output(self, target, args, kwargs): + assert len(args) == 1 + if isinstance(args[0], tuple): + outputs = args[0] + elif isinstance(args[0], list): + outputs = tuple(args[0]) + else: + outputs = (args[0],) + + if not all(isinstance(output, trt.tensorrt.ITensor) for output in outputs): + raise RuntimeError("TensorRT requires all outputs to be Tensor!") + + for i, output in enumerate(outputs): + if any( + op_name in output.name.split("_") + for op_name in ( + "eq", + "gt", + "lt", + "or", + "xor", + "and", + "not", + "ne", + "isinf", + "any", + ) + ): + output_bool = True + else: + output_bool = False + name = f"output{i}" + output.name = name + self.network.mark_output(output) + if output_bool: + output.dtype = trt.bool + elif self.output_fp16 and output.dtype == trt.float32: + output.dtype = trt.float16 + self._output_names.append(name)
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/fx/input_tensor_spec.html b/docs/v2.2.0/_modules/torch_tensorrt/fx/input_tensor_spec.html new file mode 100644 index 0000000000..a9f05c8071 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/fx/input_tensor_spec.html @@ -0,0 +1,981 @@ + + + + + + + + + + + + torch_tensorrt.fx.input_tensor_spec — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.fx.input_tensor_spec

+from typing import Any, Iterable, List, NamedTuple, Optional, Sequence, Tuple
+
+import torch
+
+from .types import Shape, ShapeRange
+from .utils import get_dynamic_dims
+
+
+def generate_input_specs(inputs, lower_setting, additional_inputs=None):
+    # dynamic_batch is TRT only flag.
+    if (
+        not lower_setting.explicit_batch_dimension
+        or lower_setting.dynamic_batch is False
+    ):
+        return InputTensorSpec.from_tensors(inputs)
+
+    # If we don't have additional inputs, we assume the first dimension
+    # is the dynamic batch dimension. Otherwise, we use the additional
+    # inputs to determine the batch dimension.
+    if additional_inputs is None:
+        batch_dims = None
+        if not isinstance(inputs, torch.Tensor) and len(inputs) > 1:
+            bs = inputs[0].size(0)
+            batch_dims = None
+            if not all(x.size(0) == bs for x in inputs):
+                batch_dims = InputTensorSpec.find_batch_size_dim(inputs)
+        return InputTensorSpec.from_tensors_with_dynamic_batch_size(
+            inputs,
+            (
+                0,
+                lower_setting.max_batch_size,
+                lower_setting.max_batch_size,
+            ),
+            lower_setting.opt_profile_replica,
+            batch_dims,
+        )
+    else:
+        batch_dims = []
+
+        for i, j in zip(inputs, additional_inputs):
+            found_batch_dim = False
+
+            for idx, values in enumerate(zip(i.shape, j.shape)):
+                if values[0] != values[1]:
+                    assert (
+                        found_batch_dim is False
+                    ), f"We've already found a batch dim, {i.shape}, {j.shape}."
+                    batch_dims.append(idx)
+                    found_batch_dim = True
+
+            if not found_batch_dim:
+                raise RuntimeError(
+                    f"Failed to find batch dimension because shapes are the same, {i.shape}"
+                )
+
+        return InputTensorSpec.from_tensors_with_dynamic_batch_size(
+            inputs,
+            (
+                0,
+                lower_setting.max_batch_size,
+                lower_setting.max_batch_size,
+            ),
+            lower_setting.opt_profile_replica,
+            batch_dims,
+        )
+
+
+
[docs]class InputTensorSpec(NamedTuple): + """ + This class contains the information of a input tensor. + + shape: shape of the tensor. + + dtype: dtyep of the tensor. + + device: device of the tensor. This is only used to generate inputs to the given model + in order to run shape prop. For TensorRT engine, inputs have to be on cuda device. + + shape_ranges: If dynamic shape is needed (shape has dimensions of -1), then this field + has to be provided (default is empty list). Every shape_range is a tuple of three + tuples ((min_input_shape), (optimized_input_shape), (max_input_shape)). Each shape_range + is used to populate a TensorRT optimization profile. + e.g. If the input shape varies from (1, 224) to (100, 224) and we want to optimize + for (25, 224) because it's the most common input shape, then we set shape_ranges to + ((1, 224), (25, 225), (100, 224)). + + has_batch_dim: Whether the shape includes batch dimension. Batch dimension has to be provided + if the engine want to run with dynamic shape. + """ + + shape: Shape + dtype: torch.dtype + device: torch.device = torch.device("cpu") + shape_ranges: List[ShapeRange] = [] + has_batch_dim: bool = True + + @classmethod + def from_tensor(cls, tensor: torch.Tensor) -> "InputTensorSpec": + """ + Produce an InputTenosrSpec named tuple which contains the + information of the given PyTorch tensor. + + Args: + tensor (torch.Tensor): A PyTorch tensor. + + Returns: + An InputTensorSpec named tuple. + """ + return cls(tensor.shape, tensor.dtype, tensor.device) + + @classmethod + def from_tensors(cls, tensors: Sequence[torch.Tensor]) -> List["InputTensorSpec"]: + """ + Produce a list of InputTenosrSpec named tuples which contain + the information of all the given PyTorch tensors. + + Args: + tensors (Iterable[torch.Tensor]): A list of PyTorch tensors. + + Returns: + A list of InputTensorSpec named tuples. + """ + assert isinstance(tensors, (list, tuple)) + return [cls.from_tensor(t) for t in tensors] + + @classmethod + def from_tensors_with_dynamic_batch_size( + cls, + tensors: Sequence[torch.Tensor], + batch_size_range: Tuple[int, int, int], + opt_profile_replica: int = 1, + batch_dims: Optional[List[int]] = None, + ) -> List["InputTensorSpec"]: + """ + Produce a list of InputTenosrSpec named tuples which would contain + the information of all the given PyTorch tensors. The produced input + tensor specs will treat all tensors' first dimension as batch dimension + and mark them as dynmaic. + + Args: + tensors (Sequence[torch.Tensor]): A list of PyTorch tensors. + batch_size_range (Tuple[int, int, int]): The first integer indicates + the smallest batch size allowed. The second integer indiceates + the batch size that we'll optimize for. The third integer indicates + the largest batch size allowed. + opt_profile_replica (int): If dynamic shape is enabled, each execution + context requires a different optimization profile. This arg determines + how many optimization profile replicas we want to produce. + batch_dims (Optional[List[int]]): The batch dim might not be the leading dim + and allow user to specify the batch dims using this arg. Default we treat + dim 0 as the batch dim. + + Returns: + A list of InputTensorSpec named tuples with dynamic ranges. + """ + if batch_dims is None: + batch_dims = cls.find_batch_size_dim(tensors) + + input_specs = [] + batch_size = tensors[0].size(batch_dims[0]) + + for i, tensor in enumerate(tensors): + batch_dim = batch_dims[i] + if batch_dim == -1: + input_specs.append(cls.from_tensor(tensor)) + else: + shape = list(tensor.shape) + assert batch_size == tensor.size( + batch_dim + ), f"The {i}th tensor (shape: {tensor.shape}) doesn't have the correct batch size: {batch_size}." + shape[batch_dim] = -1 + shape_ranges: List[ShapeRange] = [tuple(tuple(shape[0:batch_dim] + [bs] + shape[batch_dim + 1 :]) for bs in batch_size_range)] * opt_profile_replica # type: ignore[list-item] + input_specs.append( + cls(tuple(shape), tensor.dtype, tensor.device, shape_ranges) + ) + + return input_specs + + @classmethod + # pyre-ignore [2]: Parameter `sample_input` must have a type other than `Any` + def find_batch_size_dim(cls, inputs: Any) -> []: + if isinstance(inputs, torch.Tensor) or len(inputs) <= 1: + return [0] + shapes = [i.shape for i in inputs] + frequency_map = {} + first_dims = set() + for shape in shapes: + if len(shape) < 2: + # By pass for rank-1 tensors. MRS model has rank-1 tensor carry no batch_size info + continue + # Dedup shape value for single tensor + first_dims.add(shape[0]) + shape = set(shape) + for i in shape: + frequency_map[i] = frequency_map.get(i, 0) + 1 + + if len(first_dims) == 1: + # first dim is the same in every input: we use it as batch_size + batch_size = first_dims.pop() + elif frequency_map: + # first dims are different: we use the most frequent dim as batch_size + sorted_frequency = sorted(frequency_map.items(), key=lambda x: -x[1]) + batch_size = sorted_frequency[0][0] + else: + # no dims to sort: no batch_size + batch_size = -1 + + bs_dim = [] + for i in inputs: + # Default batch size dim = -1, indicate no batch_size + dim = -1 + for index, val in enumerate(i.shape): + if val == batch_size: + dim = index + break + bs_dim.append(dim) + + return bs_dim + + def to_random_tensor(self, id=1): + shape = tuple(self.shape) + if len(get_dynamic_dims(shape)): + # id=0 -> min shape + # id=1 -> optimal shape + # id=2 -> max shape + shape = tuple(self.shape_ranges[0][id]) + elif not self.has_batch_dim: + shape = (1,) + tuple(shape) + + return torch.randn(shape).to(dtype=self.dtype, device=self.device) + + @staticmethod + def create_inputs_from_specs(input_specs: Iterable["InputTensorSpec"]): + inputs = [] + for spec in input_specs: + inputs.append(spec.to_random_tensor()) + + return inputs + + @staticmethod + def create_inputs_from_max_specs(input_specs: Iterable["InputTensorSpec"]): + inputs = [] + for spec in input_specs: + inputs.append(spec.to_random_tensor(2)) + + return inputs
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/fx/lower.html b/docs/v2.2.0/_modules/torch_tensorrt/fx/lower.html new file mode 100644 index 0000000000..b0cee0b593 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/fx/lower.html @@ -0,0 +1,1056 @@ + + + + + + + + + + + + torch_tensorrt.fx.lower — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.fx.lower

+import dataclasses as dc
+import logging
+from typing import Any, Callable, Optional, Sequence
+
+# @manual=//deeplearning/trt/python:py_tensorrt
+import tensorrt as trt
+import torch
+import torch.fx as fx
+import torch.nn as nn
+import torch_tensorrt.fx.tracer.dispatch_tracer.aten_tracer as aten_tracer
+from torch.fx.passes.splitter_base import SplitResult
+
+from .fx2trt import TRTInterpreter, TRTInterpreterResult
+from .lower_setting import LowerSetting
+from .passes.lower_pass_manager_builder import LowerPassManagerBuilder
+from .passes.pass_utils import PassFunc, validate_inference
+from .tools.timing_cache_utils import TimingCacheManager
+from .tools.trt_splitter import TRTSplitter, TRTSplitterSetting
+from .tracer.acc_tracer import acc_tracer
+from .trt_module import TRTModule
+from .utils import LowerPrecision
+
+logger = logging.getLogger(__name__)
+
+Input = Sequence[Any]
+
+
+
[docs]def compile( + module: nn.Module, + input, + min_acc_module_size: int = 10, + max_batch_size: int = 2048, + max_workspace_size=1 << 25, + explicit_batch_dimension=False, + lower_precision=LowerPrecision.FP16, + verbose_log=False, + timing_cache_prefix="", + save_timing_cache=False, + cuda_graph_batch_size=-1, + dynamic_batch=True, + is_aten=False, + use_experimental_fx_rt=False, + correctness_atol=1e-1, + correctness_rtol=1e-1, +) -> nn.Module: + """ + Takes in original module, input and lowering setting, run lowering workflow to turn module + into lowered module, or so called TRTModule. + + Args: + module: Original module for lowering. + input: Input for module. + max_batch_size: Maximum batch size (must be >= 1 to be set, 0 means not set) + min_acc_module_size: Minimal number of nodes for an accelerated submodule + max_workspace_size: Maximum size of workspace given to TensorRT. + explicit_batch_dimension: Use explicit batch dimension in TensorRT if set True, otherwise use implicit batch dimension. + lower_precision: lower_precision config given to TRTModule. + verbose_log: Enable verbose log for TensorRT if set True. + timing_cache_prefix: Timing cache file name for timing cache used by fx2trt. + save_timing_cache: Update timing cache with current timing cache data if set to True. + cuda_graph_batch_size: Cuda graph batch size, default to be -1. + dynamic_batch: batch dimension (dim=0) is dynamic. + use_experimental_fx_rt: Uses the next generation TRTModule which supports both Python and TorchScript based execution (including in C++). + Returns: + A torch.nn.Module lowered by TensorRT. + """ + if use_experimental_fx_rt and not explicit_batch_dimension: + raise ValueError( + "The experimental unifed runtime only supports explicit batch. Please make sure to set explicit_batch_dimension=True when use_experimental_fx_rt=True" + ) + + lower_setting = LowerSetting( + max_batch_size=max_batch_size, + min_acc_module_size=min_acc_module_size, + max_workspace_size=max_workspace_size, + explicit_batch_dimension=explicit_batch_dimension, + lower_precision=lower_precision, + verbose_log=verbose_log, + timing_cache_prefix=timing_cache_prefix, + save_timing_cache=save_timing_cache, + cuda_graph_batch_size=cuda_graph_batch_size, + dynamic_batch=dynamic_batch, + is_aten=is_aten, + use_experimental_rt=use_experimental_fx_rt, + correctness_atol=correctness_atol, + correctness_rtol=correctness_rtol, + ) + lowerer = Lowerer.create(lower_setting=lower_setting) + return lowerer(module, input)
+ + +@dc.dataclass +class LowerTrtInterpreter: + lower_setting: LowerSetting + timing_cache_manager: TimingCacheManager + + @classmethod + def create(cls, lower_setting): + timing_cache_manager = TimingCacheManager( + lower_setting.timing_cache_prefix, lower_setting.save_timing_cache + ) + return LowerTrtInterpreter(lower_setting, timing_cache_manager) + + def __call__(self, mod, input, split_name) -> TRTInterpreterResult: + assert self.lower_setting.input_specs, "Can't find input specs for lowering!" + logger.info( + f"split_name={split_name}, input_specs={self.lower_setting.input_specs}" + ) + + # Prepare algorithm selector and timing_cache for TRTInterpreter + algo_selector = None + if self.lower_setting.algo_selector: + algo_selector = self.lower_setting.algo_selector(f"{split_name}.json") + cache_data = None + if self.timing_cache_manager: + try: + cache_data = self.timing_cache_manager.get_timing_cache_trt(split_name) + logger.info("Timing cache is used!") + except Exception as e: + logger.warning(f"Cannot load timing cache for {split_name}: {str(e)}") + cache_data = None + + interpreter = TRTInterpreter( + mod, + input_specs=self.lower_setting.input_specs, + explicit_batch_dimension=self.lower_setting.explicit_batch_dimension, + explicit_precision=self.lower_setting.explicit_precision, + logger_level=( + trt.Logger.VERBOSE + if self.lower_setting.verbose_log + else trt.Logger.WARNING + ), + ) + + interp_result: TRTInterpreterResult = interpreter.run( + max_batch_size=self.lower_setting.max_batch_size, + max_workspace_size=self.lower_setting.max_workspace_size, + lower_precision=self.lower_setting.lower_precision, + strict_type_constraints=self.lower_setting.strict_type_constraints, + algorithm_selector=algo_selector, + timing_cache=cache_data, + profiling_verbosity=( + trt.ProfilingVerbosity.DETAILED + if self.lower_setting.verbose_profile + else trt.ProfilingVerbosity.LAYER_NAMES_ONLY + ), + tactic_sources=self.lower_setting.tactic_sources, + ) + + # Update timing cache file if needed + timing_cache = interp_result.serialized_cache + if timing_cache and self.timing_cache_manager: + self.timing_cache_manager.update_timing_cache(split_name, timing_cache) + + return interp_result + + +def default_split_function( + model: fx.GraphModule, inputs: Input, lower_setting: LowerSetting +) -> SplitResult: + splitter_setting = TRTSplitterSetting() + splitter_setting.use_implicit_batch_dim = not lower_setting.explicit_batch_dimension + splitter_setting.min_acc_module_size = lower_setting.min_acc_module_size + splitter_setting.use_experimental_rt = lower_setting.use_experimental_rt + splitter = TRTSplitter(model, inputs, settings=splitter_setting) + splitter.node_support_preview() + return splitter.generate_split_results() + + +def create_lower_trt_interpreter(lower_setting: LowerSetting) -> LowerTrtInterpreter: + return LowerTrtInterpreter.create(lower_setting) + + +def default_lower_pass( + create_trt_interpreter: Callable[[LowerSetting], LowerTrtInterpreter], +) -> PassFunc: + def lower_pass( + mod: nn.Module, input: Input, lower_setting: LowerSetting, module_name: str + ) -> nn.Module: + """ + Create a module transformation pass which lowers an `fx.GraphModule` into a + `TRTModule` + """ + interpreter = create_trt_interpreter(lower_setting) + interp_res: TRTInterpreterResult = interpreter(mod, input, module_name) + if lower_setting.use_experimental_rt: + import io + + from torch_tensorrt._Device import Device + from torch_tensorrt.dynamo._TorchTensorRTModule import TorchTensorRTModule + + with io.BytesIO() as engine_bytes: + engine_bytes.write(interp_res.engine.serialize()) + engine_str = engine_bytes.getvalue() + + trt_module = TorchTensorRTModule( + engine_str, + name=module_name, + input_binding_names=interp_res.input_names, + output_binding_names=interp_res.output_names, + target_device=Device(f"cuda:{torch.cuda.current_device()}"), + # cuda_graph_batch_size=lower_setting.cuda_graph_batch_size, # NOTE: Not sure what this is supposed to do + ) + return trt_module + + else: + trt_module = TRTModule( + engine=interp_res.engine, + input_names=interp_res.input_names, + output_names=interp_res.output_names, + cuda_graph_batch_size=lower_setting.cuda_graph_batch_size, + ) + return trt_module + + return lower_pass + + +@dc.dataclass(frozen=True) +class Lowerer: + """Lowers a module using fx2trt. + + This is a composable class to facilitate fx2trt. A normal fx2trt process + composes of the following passes to transform an `fx.GraphModule`: + + 1. trace - use torch.fx to trace the module so we can get the graph + representation of the model. + 2. split - the graph module is split into several submodules, + running either via TensorRT, or via regular CUDA. + + For each split that need to run via TRT, the following passes are + invoked: + + 3. `TRTInterpreter` - build the TRT engine for the submodule that + can be supported through `TRTInterpreter`. + 4. Wraps the executable TRT engine into `TRTModule`, which is an `nn.Module`. + 5. The converted submodule is then set back onto the top-level module + + """ + + lower_pass_manager_builder: LowerPassManagerBuilder + + @classmethod + def create( + cls, + lower_setting: LowerSetting, + interpreter_builder: Callable = create_lower_trt_interpreter, + split_func: Callable = default_split_function, + ) -> "Lowerer": + """Instantiate a `Lowerer` instance.""" + if not lower_setting.is_aten: + return cls( + lower_pass_manager_builder=LowerPassManagerBuilder( + lower_setting=lower_setting, + trace_func=lambda module, inputs: acc_tracer.trace( + module, + inputs, # type: ignore[arg-type] + ast_rewriter_allow_list=lower_setting.ast_rewriter_allow_list, + leaf_module_list=lower_setting.leaf_module_list, + ), + split_func=split_func, + lower_func=default_lower_pass(interpreter_builder), + ) + ) + # proxytensor_trace + else: + return cls( + lower_pass_manager_builder=LowerPassManagerBuilder( + lower_setting=lower_setting, + trace_func=lambda module, inputs: aten_tracer.opt_trace( + module, inputs + ), + split_func=split_func, + lower_func=default_lower_pass(interpreter_builder), + ) + ) + + def __call__( + self, + module: nn.Module, + inputs: Input, + additional_inputs: Optional[Input] = None, + fp16_conversion_fn: Optional[Callable[[Input], Input]] = None, + ) -> nn.Module: + lower_setting = self.lower_pass_manager_builder.lower_setting + atol = lower_setting.correctness_atol + rtol = lower_setting.correctness_rtol + + @validate_inference( + atol=atol, + rtol=rtol, + ) + def do_lower(module: nn.Module, inputs: Input) -> nn.Module: + module.eval() + if ( + self.lower_pass_manager_builder.lower_setting.lower_precision + == LowerPrecision.FP16 + ): + module.half() + # A custom conversion function can be passed to the lowerer to + # handle inputs with custom types. By default, just handle + # tensors and NoneType. + if fp16_conversion_fn is None: + conversion_fn = lambda x: ( + x.half() if x is not None and x.dtype == torch.float32 else x + ) + else: + conversion_fn = fp16_conversion_fn + + inputs = tuple(conversion_fn(x) for x in inputs) + if lower_setting.is_aten: + pm = self.lower_pass_manager_builder.build_aten2trt_lower_pipeline( + inputs, additional_inputs + ) + else: + pm = self.lower_pass_manager_builder.build_trt_lower_pipeline( + inputs, additional_inputs + ) + lower_result = pm(module) + return lower_result + + return do_lower(module, inputs) +
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/fx/trt_module.html b/docs/v2.2.0/_modules/torch_tensorrt/fx/trt_module.html new file mode 100644 index 0000000000..88bc3dec00 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/fx/trt_module.html @@ -0,0 +1,984 @@ + + + + + + + + + + + + torch_tensorrt.fx.trt_module — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.fx.trt_module

+from typing import Any, List, Sequence
+
+# @manual=//deeplearning/trt/python:py_tensorrt
+import tensorrt as trt
+import torch
+
+from .utils import Frameworks, unified_dtype_converter
+
+
+
[docs]class TRTModule(torch.nn.Module): + def __init__( + self, engine=None, input_names=None, output_names=None, cuda_graph_batch_size=-1 + ): + super(TRTModule, self).__init__() + self._register_state_dict_hook(TRTModule._on_state_dict) + self.engine = engine + self.input_names = input_names + self.output_names = output_names + self.cuda_graph_batch_size = cuda_graph_batch_size + self.initialized = False + + if engine: + self._initialize() + + def _initialize(self): + self.initialized = True + self.context = self.engine.create_execution_context() + + # Indices of inputs/outputs in the trt engine bindings, in the order + # as they are in the original PyTorch model. + self.input_binding_indices_in_order: Sequence[int] = [ + self.engine.get_binding_index(name) for name in self.input_names + ] + self.output_binding_indices_in_order: Sequence[int] = [ + self.engine.get_binding_index(name) for name in self.output_names + ] + primary_input_outputs = set() + primary_input_outputs.update(self.input_binding_indices_in_order) + primary_input_outputs.update(self.output_binding_indices_in_order) + self.hidden_output_binding_indices_in_order: Sequence[int] = [] + self.hidden_output_names: Sequence[str] = [] + for i in range( + self.engine.num_bindings // self.engine.num_optimization_profiles + ): + if i not in primary_input_outputs: + self.hidden_output_binding_indices_in_order.append(i) + self.hidden_output_names.append(self.engine.get_binding_name(i)) + + assert (self.engine.num_bindings // self.engine.num_optimization_profiles) == ( + len(self.input_names) + + len(self.output_names) + + len(self.hidden_output_names) + ) + + self.input_dtypes: Sequence[torch.dtype] = [ + unified_dtype_converter( + self.engine.get_binding_dtype(idx), Frameworks.TORCH + ) + for idx in self.input_binding_indices_in_order + ] + self.input_shapes: Sequence[Sequence[int]] = [ + tuple(self.engine.get_binding_shape(idx)) + for idx in self.input_binding_indices_in_order + ] + self.output_dtypes: Sequence[torch.dtype] = [ + unified_dtype_converter( + self.engine.get_binding_dtype(idx), Frameworks.TORCH + ) + for idx in self.output_binding_indices_in_order + ] + self.output_shapes = [ + ( + tuple(self.engine.get_binding_shape(idx)) + if self.engine.has_implicit_batch_dimension + else tuple() + ) + for idx in self.output_binding_indices_in_order + ] + self.hidden_output_dtypes: Sequence[torch.dtype] = [ + unified_dtype_converter( + self.engine.get_binding_dtype(idx), Frameworks.TORCH + ) + for idx in self.hidden_output_binding_indices_in_order + ] + self.hidden_output_shapes = [ + ( + tuple(self.engine.get_binding_shape(idx)) + if self.engine.has_implicit_batch_dimension + else tuple() + ) + for idx in self.hidden_output_binding_indices_in_order + ] + + def _check_initialized(self): + if not self.initialized: + raise RuntimeError("TRTModule is not initialized.") + + def _on_state_dict(self, state_dict, prefix, local_metadata): + self._check_initialized() + state_dict[prefix + "engine"] = bytearray(self.engine.serialize()) + state_dict[prefix + "input_names"] = self.input_names + state_dict[prefix + "output_names"] = self.output_names + state_dict[prefix + "cuda_graph_batch_size"] = self.cuda_graph_batch_size + + def _load_from_state_dict( + self, + state_dict, + prefix, + local_metadata, + strict, + missing_keys, + unexpected_keys, + error_msgs, + ): + engine_bytes = state_dict[prefix + "engine"] + + logger = trt.Logger() + runtime = trt.Runtime(logger) + self.engine = runtime.deserialize_cuda_engine(engine_bytes) + + self.input_names = state_dict[prefix + "input_names"] + self.output_names = state_dict[prefix + "output_names"] + self._initialize() + + def __getstate__(self): + state = self.__dict__.copy() + state["engine"] = bytearray(self.engine.serialize()) + state.pop("context", None) + return state + + def __setstate__(self, state): + logger = trt.Logger() + runtime = trt.Runtime(logger) + state["engine"] = runtime.deserialize_cuda_engine(state["engine"]) + self.__dict__.update(state) + if self.engine: + self.context = self.engine.create_execution_context() + + def forward(self, *inputs): + with torch.autograd.profiler.record_function("TRTModule:Forward"): + self._check_initialized() + + with torch.autograd.profiler.record_function("TRTModule:ProcessInputs"): + assert len(inputs) == len( + self.input_names + ), f"Wrong number of inputs, expect {len(self.input_names)} get {len(inputs)}." + + # This is only used when the trt engine is using implicit batch dim. + batch_size = inputs[0].shape[0] + contiguous_inputs: List[torch.Tensor] = [i.contiguous() for i in inputs] + bindings: List[Any] = [None] * ( + len(self.input_names) + + len(self.output_names) + + len(self.hidden_output_names) + ) + + for i, input_name in enumerate(self.input_names): + assert inputs[ + i + ].is_cuda, f"{i}th input({input_name}) is not on cuda device." + assert ( + inputs[i].dtype == self.input_dtypes[i] + ), f"Dtype mismatch for {i}th input({input_name}). Expect {self.input_dtypes[i]}, got {inputs[i].dtype}." + + idx = self.input_binding_indices_in_order[i] + bindings[idx] = contiguous_inputs[i].data_ptr() + + if not self.engine.has_implicit_batch_dimension: + self.context.set_binding_shape( + idx, tuple(contiguous_inputs[i].shape) + ) + else: + assert inputs[i].size()[1:] == self.input_shapes[i], ( + f"Shape mismatch for {i}th input({input_name}). " + f"Expect {self.input_shapes[i]}, got {inputs[i].size()[1:]}." + ) + + with torch.autograd.profiler.record_function("TRTModule:ProcessOutputs"): + # create output tensors + outputs: List[torch.Tensor] = [] + + for i, idx in enumerate(self.output_binding_indices_in_order): + if self.engine.has_implicit_batch_dimension: + shape = (batch_size,) + self.output_shapes[i] + else: + shape = tuple(self.context.get_binding_shape(idx)) + + output = torch.empty( # type: ignore[call-overload] + size=shape, + dtype=self.output_dtypes[i], + device=torch.cuda.current_device(), + ) + outputs.append(output) + bindings[idx] = output.data_ptr() + + for i, idx in enumerate(self.hidden_output_binding_indices_in_order): + if self.engine.has_implicit_batch_dimension: + shape = (batch_size,) + self.hidden_output_shapes[i] + else: + shape = tuple(self.context.get_binding_shape(idx)) + + output = torch.empty( # type: ignore[call-overload] + size=shape, + dtype=self.hidden_output_dtypes[i], + device=torch.cuda.current_device(), + ) + bindings[idx] = output.data_ptr() + + with torch.autograd.profiler.record_function("TRTModule:TensorRTRuntime"): + if self.engine.has_implicit_batch_dimension: + self.context.execute_async( + batch_size, bindings, torch.cuda.current_stream().cuda_stream + ) + else: + self.context.execute_async_v2( + bindings, torch.cuda.current_stream().cuda_stream + ) + + if len(outputs) == 1: + return outputs[0] + + return tuple(outputs) + + def enable_profiling(self, profiler: "trt.IProfiler" = None): + """ + Enable TensorRT profiling. After calling this function, TensorRT will report + time spent on each layer in stdout for each forward run. + """ + self._check_initialized() + + if not self.context.profiler: + self.context.profiler = trt.Profiler() if profiler is None else profiler + + def disable_profiling(self): + """ + Disable TensorRT profiling. + """ + self._check_initialized() + + torch.cuda.synchronize() + del self.context + self.context = self.engine.create_execution_context() + + def get_layer_info(self) -> str: + """ + Get layer info of the engine. Only support for TRT > 8.2. + """ + inspector = self.engine.create_engine_inspector() + return inspector.get_engine_information(trt.LayerInformationFormat.JSON)
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/logging.html b/docs/v2.2.0/_modules/torch_tensorrt/logging.html new file mode 100644 index 0000000000..50a36058a4 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/logging.html @@ -0,0 +1,953 @@ + + + + + + + + + + + + torch_tensorrt.logging — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.logging

+from enum import Enum
+from typing import Any
+
+from torch_tensorrt._C import (
+    LogLevel,
+    _get_is_colored_output_on,
+    _get_logging_prefix,
+    _get_reportable_log_level,
+    _log,
+    _set_is_colored_output_on,
+    _set_logging_prefix,
+    _set_reportable_log_level,
+)
+
+
+
[docs]class Level(Enum): + """Enum to set the minimum required logging level to print a message to stdout""" + + InternalError = LogLevel.INTERNAL_ERROR + Error = LogLevel.ERROR + Warning = LogLevel.WARNING + Info = LogLevel.INFO + Debug = LogLevel.DEBUG + Graph = LogLevel.GRAPH + + @staticmethod + def _to_internal_level(external: "Level") -> LogLevel: + if external == Level.InternalError: + return LogLevel.INTERNAL_ERROR + elif external == Level.Error: + return LogLevel.ERROR + elif external == Level.Warning: + return LogLevel.WARNING + elif external == Level.Info: + return LogLevel.INFO + elif external == Level.Debug: + return LogLevel.DEBUG + elif external == Level.Graph: + return LogLevel.GRAPH + else: + raise ValueError("Unknown log severity")
+ + +
[docs]def get_logging_prefix() -> str: + """Get the prefix set for logging messages + + Returns: + str: Prefix used for logger + """ + return str(_get_logging_prefix())
+ + +
[docs]def set_logging_prefix(prefix: str) -> None: + """Set the prefix used when logging messages + + Args: + prefix (str): Prefix to use for logging messages + """ + _set_logging_prefix(prefix)
+ + +
[docs]def get_reportable_log_level() -> Level: + """Get the level required for a message to be printed in the log + + Returns: + torch_tensorrt.logging.Level: The enum representing the level required to print + """ + return Level(_get_reportable_log_level())
+ + +
[docs]def set_reportable_log_level(level: Level) -> None: + """Set the level required for a message to be printed to the log + + Args: + level (torch_tensorrt.logging.Level): The enum representing the level required to print + """ + _set_reportable_log_level(Level._to_internal_level(level))
+ + +
[docs]def get_is_colored_output_on() -> bool: + """Get if colored output is enabled for logging + + Returns: + bool: If colored output is one + """ + return bool(_get_is_colored_output_on())
+ + +
[docs]def set_is_colored_output_on(colored_output_on: bool) -> None: + """Enable or disable color in the log output + + Args: + colored_output_on (bool): If colored output should be enabled or not + """ + _set_is_colored_output_on(colored_output_on)
+ + +
[docs]def log(level: Level, msg: str) -> None: + """Add a new message to the log + + Adds a new message to the log at a specified level. The message + will only get printed out if Level > reportable_log_level + + Args: + level (torch_tensorrt.logging.Level): Severity of the message + msg (str): Actual message text + """ + _log(Level._to_internal_level(level), msg) + + InternalError = LogLevel.INTERNAL_ERROR + Error = LogLevel.ERROR + Warning = LogLevel.WARNING + Info = LogLevel.INFO + Debug = LogLevel.DEBUG + Graph = LogLevel.GRAPH
+ + +
[docs]class internal_errors: + """Context-manager to limit displayed log messages to just internal errors + + Example:: + + with torch_tensorrt.logging.internal_errors(): + outputs = model_torchtrt(inputs) + """ + + def __enter__(self) -> None: + self.external_lvl = get_reportable_log_level() + set_reportable_log_level(Level.InternalError) + + def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None: + set_reportable_log_level(self.external_lvl)
+ + +
[docs]class errors: + """Context-manager to limit displayed log messages to just errors and above + + Example:: + + with torch_tensorrt.logging.errors(): + outputs = model_torchtrt(inputs) + """ + + def __enter__(self) -> None: + self.external_lvl = get_reportable_log_level() + set_reportable_log_level(Level.Error) + + def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None: + set_reportable_log_level(self.external_lvl)
+ + +
[docs]class warnings: + """Context-manager to limit displayed log messages to just warnings and above + + Example:: + + with torch_tensorrt.logging.warnings(): + model_trt = torch_tensorrt.compile(model, **spec) + """ + + def __enter__(self) -> None: + self.external_lvl = get_reportable_log_level() + set_reportable_log_level(Level.Warning) + + def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None: + set_reportable_log_level(self.external_lvl)
+ + +
[docs]class info: + """Context-manager to display all info and greater severity messages + + Example:: + + with torch_tensorrt.logging.info(): + model_trt = torch_tensorrt.compile(model, **spec) + """ + + def __enter__(self) -> None: + self.external_lvl = get_reportable_log_level() + set_reportable_log_level(Level.Info) + + def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None: + set_reportable_log_level(self.external_lvl)
+ + +
[docs]class debug: + """Context-manager to display full debug information through the logger + + Example:: + + with torch_tensorrt.logging.debug(): + model_trt = torch_tensorrt.compile(model, **spec) + """ + + def __enter__(self) -> None: + self.external_lvl = get_reportable_log_level() + set_reportable_log_level(Level.Debug) + + def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None: + set_reportable_log_level(self.external_lvl)
+ + +
[docs]class graphs: + """Context-manager to display the results of intermediate lowering passes + as well as full debug information through the logger + + Example:: + + with torch_tensorrt.logging.graphs(): + model_trt = torch_tensorrt.compile(model, **spec) + """ + + def __enter__(self) -> None: + self.external_lvl = get_reportable_log_level() + set_reportable_log_level(Level.Graph) + + def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None: + set_reportable_log_level(self.external_lvl)
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/ptq.html b/docs/v2.2.0/_modules/torch_tensorrt/ptq.html new file mode 100644 index 0000000000..ad9c12f962 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/ptq.html @@ -0,0 +1,955 @@ + + + + + + + + + + + + torch_tensorrt.ptq — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.ptq

+import sys
+from typing import Any, List, Optional
+
+if sys.version_info >= (3, 11):
+    from typing import Self
+else:
+    from typing_extensions import Self
+
+import os
+from enum import Enum
+
+import torch
+from torch_tensorrt import _C
+from torch_tensorrt.logging import Level, log
+
+
+
[docs]class CalibrationAlgo(Enum): + ENTROPY_CALIBRATION = _C.CalibrationAlgo.ENTROPY_CALIBRATION + ENTROPY_CALIBRATION_2 = _C.CalibrationAlgo.ENTROPY_CALIBRATION_2 + LEGACY_CALIBRATION = _C.CalibrationAlgo.LEGACY_CALIBRATION + MINMAX_CALIBRATION = _C.CalibrationAlgo.MINMAX_CALIBRATION
+ + +
[docs]def get_cache_mode_batch(self: object) -> None: + return None
+ + +
[docs]def get_batch_size(self: object) -> int: + return 1
+ + +
[docs]def get_batch(self: object, _: Any) -> Optional[List[int]]: + if self.current_batch_idx + self.batch_size > len(self.data_loader.dataset): + return None + + batch = next(self.dataset_iterator) + self.current_batch_idx += self.batch_size + inputs_gpu = [] + if isinstance(batch, list): + for example in batch: + inputs_gpu.append(example.to(self.device).data_ptr()) + else: + inputs_gpu.append(batch.to(self.device).data_ptr()) + return inputs_gpu
+ + +
[docs]def read_calibration_cache(self: object) -> bytes: + if self.cache_file and self.use_cache: + if os.path.exists(self.cache_file): + with open(self.cache_file, "rb") as f: + b: bytes = f.read() + return b + else: + raise FileNotFoundError(self.cache_file) + else: + return b""
+ + +
[docs]def write_calibration_cache(self: object, cache: bytes) -> None: + if self.cache_file: + with open(self.cache_file, "wb") as f: + f.write(cache) + else: + return
+ + +# deepcopy (which involves pickling) is performed on the compile_spec internally during compilation. +# We register this __reduce__ function for pickler to identity the calibrator object returned by DataLoaderCalibrator during deepcopy. +# This should be the object's local name relative to the module https://docs.python.org/3/library/pickle.html#object.__reduce__ +def __reduce__(self: object) -> str: + return self.__class__.__name__ + + +
[docs]class DataLoaderCalibrator(object): + """ + Constructs a calibrator class in TensorRT and uses pytorch dataloader to load/preproces + data which is passed during calibration. + Args: + dataloader: an instance of pytorch dataloader which iterates through a given dataset. + algo_type: choice of calibration algorithm. + cache_file: path to cache file. + use_cache: flag which enables usage of pre-existing cache. + device: device on which calibration data is copied to. + """ + +
[docs] def __init__(self, **kwargs: Any): + pass
+ + def __new__(cls, *args: Any, **kwargs: Any) -> Self: + dataloader = args[0] + algo_type = kwargs.get("algo_type", CalibrationAlgo.ENTROPY_CALIBRATION_2) + cache_file = kwargs.get("cache_file", None) + use_cache = kwargs.get("use_cache", False) + device = kwargs.get("device", torch.device("cuda:0")) + + if not isinstance(dataloader, torch.utils.data.DataLoader): + log( + Level.Error, + "Dataloader : {} is not a valid instance of torch.utils.data.DataLoader".format( + dataloader + ), + ) + + if not cache_file: + if use_cache: + log( + Level.Debug, + "Using existing cache_file {} for calibration".format(cache_file), + ) + else: + log(Level.Debug, "Overwriting existing calibration cache file.") + else: + if use_cache: + log( + Level.Error, + "Input cache file is None but use_cache is set to True in INT8 mode.", + ) + + # Define attributes and member functions for the calibrator class + attribute_mapping = { + "data_loader": dataloader, + "current_batch_idx": 0, + "batch_size": dataloader.batch_size, + "dataset_iterator": iter(dataloader), + "cache_file": cache_file, + "device": device, + "use_cache": use_cache, + "get_batch_size": get_batch_size, + "get_batch": get_cache_mode_batch if use_cache else get_batch, + "read_calibration_cache": read_calibration_cache, + "write_calibration_cache": write_calibration_cache, + "__reduce__": __reduce__, # used when you deepcopy the DataLoaderCalibrator object + } + + # Using type metaclass to construct calibrator class based on algorithm type + if algo_type == CalibrationAlgo.ENTROPY_CALIBRATION: + calib_ec: Self = type( + "Int8EntropyCalibrator", (_C.IInt8EntropyCalibrator,), attribute_mapping + )() + return calib_ec + elif algo_type == CalibrationAlgo.ENTROPY_CALIBRATION_2: + calib_ec2: Self = type( + "Int8EntropyCalibrator2", + (_C.IInt8EntropyCalibrator2,), + attribute_mapping, + )() + return calib_ec2 + elif algo_type == CalibrationAlgo.LEGACY_CALIBRATION: + calib_lc: Self = type( + "Int8LegacyCalibrator", (_C.IInt8LegacyCalibrator,), attribute_mapping + )() + return calib_lc + elif algo_type == CalibrationAlgo.MINMAX_CALIBRATION: + calib_mmc: Self = type( + "Int8MinMaxCalibrator", (_C.IInt8MinMaxCalibrator,), attribute_mapping + )() + return calib_mmc + else: + raise ValueError( + "Invalid calibration algorithm type. Please select among ENTROPY_CALIBRATION, ENTROPY_CALIBRATION, LEGACY_CALIBRATION or MINMAX_CALIBRATION" + )
+ + +
[docs]class CacheCalibrator(object): + """ + Constructs a calibrator class in TensorRT which directly uses pre-existing cache file for calibration. + Args: + cache_file: path to cache file. + algo_type: choice of calibration algorithm. + """ + +
[docs] def __init__(self, **kwargs: Any): + pass
+ + def __new__(cls, *args: Any, **kwargs: Any) -> Self: + cache_file = args[0] + algo_type = kwargs.get("algo_type", CalibrationAlgo.ENTROPY_CALIBRATION_2) + + if os.path.isfile(cache_file): + log( + Level.Debug, + "Using existing cache_file {} for calibration".format(cache_file), + ) + else: + log(Level.Error, "Invalid calibration cache file.") + + # Define attributes and member functions for the calibrator class + attribute_mapping = { + "use_cache": True, + "cache_file": cache_file, + "get_batch_size": get_batch_size, + "get_batch": get_cache_mode_batch, + "read_calibration_cache": read_calibration_cache, + "write_calibration_cache": write_calibration_cache, + } + # Using type metaclass to construct calibrator class based on algorithm type + if algo_type == CalibrationAlgo.ENTROPY_CALIBRATION: + calib_ec: Self = type( + "DataLoaderCalibrator", (_C.IInt8EntropyCalibrator,), attribute_mapping + )() + return calib_ec + elif algo_type == CalibrationAlgo.ENTROPY_CALIBRATION_2: + calib_ec2: Self = type( + "DataLoaderCalibrator", (_C.IInt8MinMaxCalibrator,), attribute_mapping + )() + return calib_ec2 + elif algo_type == CalibrationAlgo.LEGACY_CALIBRATION: + calib_lc: Self = type( + "DataLoaderCalibrator", (_C.IInt8LegacyCalibrator,), attribute_mapping + )() + return calib_lc + elif algo_type == CalibrationAlgo.MINMAX_CALIBRATION: + calib_mmc: Self = type( + "DataLoaderCalibrator", (_C.IInt8MinMaxCalibrator,), attribute_mapping + )() + return calib_mmc + else: + raise ValueError( + "Invalid calibration algorithm type. Please select among ENTROPY_CALIBRATION, ENTROPY_CALIBRATION, LEGACY_CALIBRATION or MINMAX_CALIBRATION" + )
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/ts/_compile_spec.html b/docs/v2.2.0/_modules/torch_tensorrt/ts/_compile_spec.html new file mode 100644 index 0000000000..8b87683931 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/ts/_compile_spec.html @@ -0,0 +1,1211 @@ + + + + + + + + + + + + torch_tensorrt.ts._compile_spec — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.ts._compile_spec

+from __future__ import annotations
+
+from copy import deepcopy
+from typing import Any, Dict, List, Optional, Set
+
+import tensorrt as trt
+import torch
+import torch_tensorrt._C.ts as _ts_C
+from torch_tensorrt import _C, _enums
+from torch_tensorrt._Device import Device
+from torch_tensorrt._Input import Input
+from torch_tensorrt.logging import Level, log
+from torch_tensorrt.ts._Input import TorchScriptInput
+
+
+def _internal_input_to_torch_class_input(i: _C.Input) -> torch.classes.tensorrt._Input:
+    clone = torch.classes.tensorrt._Input()
+    clone._set_min(i.min)
+    clone._set_opt(i.opt)
+    clone._set_max(i.max)
+    clone._set_dtype(i.dtype)
+    clone._set_tensor_domain(i.tensor_domain)
+    clone._set_format(i.format)
+    clone._set_input_is_dynamic(i.input_is_dynamic)
+    clone._set_explicit_set_dtype(i._explicit_set_dtype)
+    return clone
+
+
+def _supported_input_size_type(input_size: Any) -> bool:
+    if isinstance(input_size, torch.Size):
+        return True
+    elif isinstance(input_size, tuple):
+        return True
+    elif isinstance(input_size, list):
+        return True
+    else:
+        raise TypeError(
+            "Input sizes for inputs are required to be a List, tuple or torch.Size or a Dict of three sizes (min, opt, max), found type: "
+            + str(type(input_size))
+        )
+
+
+def _parse_op_precision(precision: Any) -> _enums.dtype:
+    if isinstance(precision, torch.dtype):
+        if precision == torch.int8:
+            return _enums.dtype.int8
+        elif precision == torch.half:
+            return _enums.dtype.half
+        elif precision == torch.float:
+            return _enums.dtype.float
+        else:
+            raise TypeError(
+                "Provided an unsupported dtype as operating precision (support: int8, half, float), got: "
+                + str(precision)
+            )
+
+    elif isinstance(precision, _enums.dtype):
+        return precision
+
+    else:
+        raise TypeError(
+            "Op precision type needs to be specified with a torch.dtype or a torch_tensorrt.dtype, got: "
+            + str(type(precision))
+        )
+
+
+def _parse_enabled_precisions(precisions: Any) -> Set[_enums.dtype]:
+    parsed_precisions = set()
+    if any(isinstance(precisions, type) for type in [list, tuple, set]):
+        for p in precisions:
+            parsed_precisions.add(_parse_op_precision(p))
+    else:
+        parsed_precisions.add(_parse_op_precision(precisions))
+    return parsed_precisions
+
+
+def _parse_device_type(device: Any) -> _enums.DeviceType:
+    if isinstance(device, torch.device):
+        if device.type == "cuda":
+            return _C.DeviceType.gpu
+        else:
+            ValueError(
+                "Got a device type other than GPU or DLA (type: "
+                + str(device.type)
+                + ")"
+            )
+    elif isinstance(device, _C.DeviceType):
+        return device
+    elif isinstance(device, trt.DeviceType):
+        if device == trt.DeviceType.DLA:
+            return _C.DeviceType.DLA
+        return _C.DeviceType.GPU
+    elif isinstance(device, str):
+        if device == "gpu" or device == "GPU":
+            return _C.DeviceType.GPU
+        elif device == "dla" or device == "DLA":
+            return _C.DeviceType.DLA
+        else:
+            ValueError(
+                "Got a device type other than GPU or DLA (type: " + str(device) + ")"
+            )
+    else:
+        raise TypeError(
+            "Device specification must be of type torch.device, string or torch_tensorrt.DeviceType, but got: "
+            + str(type(device))
+        )
+
+
+def _parse_device(device_info: Any) -> _C.Device:
+    if isinstance(device_info, dict):
+        info = _C.Device()
+        if "device_type" not in device_info:
+            raise KeyError("Device type is required parameter")
+        else:
+            info.device_type = _parse_device_type(device_info["device_type"])
+
+        if "gpu_id" in device_info:
+            assert isinstance(device_info["gpu_id"], int)
+            info.gpu_id = device_info["gpu_id"]
+
+        if "dla_core" in device_info:
+            assert isinstance(device_info["dla_core"], int)
+            info.dla_core = device_info["dla_core"]
+
+        if "allow_gpu_fallback" in device_info:
+            assert isinstance(device_info["allow_gpu_fallback"], bool)
+            info.allow_gpu_fallback = device_info["allow_gpu_fallback"]
+
+        return info
+    elif isinstance(device_info, Device):
+        return device_info._to_internal()
+    elif isinstance(device_info, torch.device):
+        return (Device._from_torch_device(device_info))._to_internal()
+    else:
+        raise ValueError(
+            "Unsupported data for device specification. Expected either a dict, torch_tensorrt.Device or torch.Device"
+        )
+
+
+def _parse_torch_fallback(fallback_info: Dict[str, Any]) -> _ts_C.TorchFallback:
+    info = _ts_C.TorchFallback()
+    if "enabled" not in fallback_info:
+        raise KeyError("Enabled is required parameter")
+    else:
+        assert isinstance(fallback_info["enabled"], bool)
+        info.enabled = fallback_info["enabled"]
+    if "min_block_size" in fallback_info:
+        assert isinstance(fallback_info["min_block_size"], int)
+        info.min_block_size = fallback_info["min_block_size"]
+
+    if "forced_fallback_ops" in fallback_info:
+        assert isinstance(fallback_info["forced_fallback_ops"], list)
+        info.forced_fallback_operators = fallback_info["forced_fallback_ops"]
+
+    if "forced_fallback_modules" in fallback_info:
+        assert isinstance(fallback_info["forced_fallback_modules"], list)
+        info.forced_fallback_modules = fallback_info["forced_fallback_modules"]
+
+    return info
+
+
+def _parse_input_signature(input_signature: Any, depth: int = 0) -> Any:
+    if depth > 2:
+        raise AssertionError(
+            "Input nesting depth exceeds max supported depth, use 1 level: [A, B], or 2 level: [A, (B, C)]"
+        )
+
+    if isinstance(input_signature, tuple):
+        input_list = []
+        for item in input_signature:
+            input = _parse_input_signature(item, depth + 1)
+            input_list.append(input)
+        return tuple(input_list)
+    elif isinstance(input_signature, list):
+        input_list = []
+        for item in input_signature:
+            input = _parse_input_signature(item, depth + 1)
+            input_list.append(input)
+        return input_list
+    elif isinstance(input_signature, (Input, torch.Tensor)):
+        i = (
+            Input.from_tensor(input_signature)
+            if isinstance(input_signature, torch.Tensor)
+            else input_signature
+        )
+
+        if not i.is_trt_dtype():
+            raise TypeError(
+                "Using non-TRT input types with input_signature is not currently "
+                + "supported. Please specify inputs individually to use "
+                + "non-TRT types."
+            )
+
+        ts_i = i
+        if i.shape_mode == Input._ShapeMode.STATIC:
+            ts_i = TorchScriptInput(shape=i.shape, dtype=i.dtype, format=i.format)
+        elif i.shape_mode == Input._ShapeMode.DYNAMIC:
+            if isinstance(i.shape, dict):
+                ts_i = TorchScriptInput(
+                    min_shape=i.shape["min_shape"],
+                    opt_shape=i.shape["opt_shape"],
+                    max_shape=i.shape["max_shape"],
+                    dtype=i.dtype,
+                    format=i.format,
+                )
+            else:
+                raise ValueError(
+                    f"Input set as dynamic, expected dictionary of shapes but found {i.shape}"
+                )
+        else:
+            raise ValueError(
+                "Invalid shape mode detected for input while parsing the input_signature"
+            )
+
+        clone = _internal_input_to_torch_class_input(ts_i._to_internal())
+        return clone
+    else:
+        raise KeyError(
+            "Input signature contains an unsupported type {}".format(
+                type(input_signature)
+            )
+        )
+
+
+def _parse_compile_spec(compile_spec_: Dict[str, Any]) -> _ts_C.CompileSpec:
+    # TODO: Use deepcopy to support partial compilation of collections
+    compile_spec = deepcopy(compile_spec_)
+    info = _ts_C.CompileSpec()
+
+    if len(compile_spec["inputs"]) > 0:
+        if not all(
+            isinstance(i, (torch.Tensor, Input)) for i in compile_spec["inputs"]
+        ):
+            raise KeyError(
+                "Input specs should be either torch_tensorrt.Input or torch.Tensor, found types: {}".format(
+                    [type(i) for i in compile_spec["inputs"]]
+                )
+            )
+
+        inputs = [
+            Input.from_tensor(i) if isinstance(i, torch.Tensor) else i
+            for i in compile_spec["inputs"]
+        ]
+        ts_inputs = []
+        for i in inputs:
+            if i.shape_mode == Input._ShapeMode.STATIC:
+                ts_inputs.append(
+                    TorchScriptInput(
+                        shape=i.shape, dtype=i.dtype, format=i.format
+                    )._to_internal()
+                )
+            elif i.shape_mode == Input._ShapeMode.DYNAMIC:
+                ts_inputs.append(
+                    TorchScriptInput(
+                        min_shape=i.shape["min_shape"],
+                        opt_shape=i.shape["opt_shape"],
+                        max_shape=i.shape["max_shape"],
+                        dtype=i.dtype,
+                        format=i.format,
+                    )._to_internal()
+                )
+        info.inputs = ts_inputs
+
+    elif compile_spec["input_signature"] is not None:
+        log(
+            Level.Warning,
+            "Input signature parsing is an experimental feature, behavior and APIs may change",
+        )
+        signature = _parse_input_signature(compile_spec["input_signature"])
+        info.input_signature = _C.InputSignature(signature)  # py_object
+
+    else:
+        raise KeyError(
+            'Module input definitions are requried to compile module. Provide a list of torch_tensorrt.Input keyed to "inputs" in the compile spec'
+        )
+
+    if "enabled_precisions" in compile_spec:
+        info.enabled_precisions = _parse_enabled_precisions(
+            compile_spec["enabled_precisions"]
+        )
+
+    if "calibrator" in compile_spec and compile_spec["calibrator"]:
+        info.ptq_calibrator = compile_spec["calibrator"]
+
+    if "sparse_weights" in compile_spec:
+        assert isinstance(compile_spec["sparse_weights"], bool)
+        info.sparse_weights = compile_spec["sparse_weights"]
+
+    if "disable_tf32" in compile_spec:
+        assert isinstance(compile_spec["disable_tf32"], bool)
+        info.disable_tf32 = compile_spec["disable_tf32"]
+
+    if "refit" in compile_spec:
+        assert isinstance(compile_spec["refit"], bool)
+        info.refit = compile_spec["refit"]
+
+    if "debug" in compile_spec:
+        assert isinstance(compile_spec["debug"], bool)
+        info.debug = compile_spec["debug"]
+
+    if "allow_shape_tensors" in compile_spec:
+        assert isinstance(compile_spec["allow_shape_tensors"], bool)
+        info.allow_shape_tensors = compile_spec["allow_shape_tensors"]
+
+    if "device" in compile_spec:
+        info.device = _parse_device(compile_spec["device"])
+
+    if "capability" in compile_spec:
+        assert isinstance(compile_spec["capability"], _enums.EngineCapability)
+        info.capability = compile_spec["capability"]
+
+    if "num_avg_timing_iters" in compile_spec:
+        assert type(compile_spec["num_avg_timing_iters"]) is int
+        info.num_avg_timing_iters = compile_spec["num_avg_timing_iters"]
+
+    if "workspace_size" in compile_spec:
+        assert type(compile_spec["workspace_size"]) is int
+        info.workspace_size = compile_spec["workspace_size"]
+
+    if "dla_sram_size" in compile_spec:
+        assert type(compile_spec["dla_sram_size"]) is int
+        info.dla_sram_size = compile_spec["dla_sram_size"]
+
+    if "dla_local_dram_size" in compile_spec:
+        assert type(compile_spec["dla_local_dram_size"]) is int
+        info.dla_local_dram_size = compile_spec["dla_local_dram_size"]
+
+    if "dla_global_dram_size" in compile_spec:
+        assert type(compile_spec["dla_global_dram_size"]) is int
+        info.dla_global_dram_size = compile_spec["dla_global_dram_size"]
+
+    if "truncate_long_and_double" in compile_spec:
+        assert type(compile_spec["truncate_long_and_double"]) is bool
+        info.truncate_long_and_double = compile_spec["truncate_long_and_double"]
+
+    if "torch_fallback" in compile_spec:
+        info.torch_fallback = _parse_torch_fallback(compile_spec["torch_fallback"])
+
+    log(Level.Debug, str(info))
+
+    return info
+
+
+
[docs]def TensorRTCompileSpec( + inputs: Optional[List[torch.Tensor | Input]] = None, + input_signature: Optional[Any] = None, + device: torch.device | Device = Device._current_device(), + disable_tf32: bool = False, + sparse_weights: bool = False, + enabled_precisions: Optional[Set[torch.dtype | _enums.dtype]] = None, + refit: bool = False, + debug: bool = False, + capability: _enums.EngineCapability = _enums.EngineCapability.default, + num_avg_timing_iters: int = 1, + workspace_size: int = 0, + dla_sram_size: int = 1048576, + dla_local_dram_size: int = 1073741824, + dla_global_dram_size: int = 536870912, + truncate_long_and_double: bool = False, + calibrator: object = None, + allow_shape_tensors: bool = False, +) -> torch.classes.tensorrt.CompileSpec: + """Utility to create a formated spec dictionary for using the PyTorch TensorRT backend + + Keyword Args: + inputs (List[Union(torch_tensorrt.Input, torch.Tensor)]): **Required** List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using + torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum + to select device type. :: + + input=[ + torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1 + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ), # Dynamic input shape for input #2 + torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings + ] + + device (Union(torch_tensorrt.Device, torch.device, dict)): Target device for TensorRT engines to run on :: + + device=torch_tensorrt.Device("dla:1", allow_gpu_fallback=True) + + disable_tf32 (bool): Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas + sparse_weights (bool): Enable sparsity for convolution and fully connected layers. + enabled_precision (Set(Union(torch.dtype, torch_tensorrt.dtype))): The set of datatypes that TensorRT can use when selecting kernels + refit (bool): Enable refitting + debug (bool): Enable debuggable engine + capability (torch_tensorrt.EngineCapability): Restrict kernel selection to safe gpu kernels or safe dla kernels + num_avg_timing_iters (int): Number of averaging timing iterations used to select kernels + workspace_size (int): Maximum size of workspace given to TensorRT + truncate_long_and_double (bool): Truncate weights provided in int64 or double (float64) to int32 and float32 + calibrator (Union(torch_tensorrt._C.IInt8Calibrator, tensorrt.IInt8Calibrator)): Calibrator object which will provide data to the PTQ system for INT8 Calibration + allow_shape_tensors: (Experimental) Allow aten::size to output shape tensors using IShapeLayer in TensorRT + + Returns: + torch.classes.tensorrt.CompileSpec: List of methods and formated spec objects to be provided to ``torch._C._jit_to_tensorrt`` + """ + + compile_spec = { + "inputs": inputs if inputs is not None else [], + # "input_signature": input_signature, + "device": device, + "disable_tf32": disable_tf32, # Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas + "sparse_weights": sparse_weights, # Enable sparsity for convolution and fully connected layers. + "enabled_precisions": ( + enabled_precisions if enabled_precisions is not None else set() + ), # Enabling FP16 kernels + "refit": refit, # enable refit + "debug": debug, # enable debuggable engine + "capability": capability, # Restrict kernel selection to safe gpu kernels or safe dla kernels + "num_avg_timing_iters": num_avg_timing_iters, # Number of averaging timing iterations used to select kernels + "workspace_size": workspace_size, # Maximum size of workspace given to TensorRT + "dla_sram_size": dla_sram_size, # Fast software managed RAM used by DLA to communicate within a layer. + "dla_local_dram_size": dla_local_dram_size, # Host RAM used by DLA to share intermediate tensor data across operations + "dla_global_dram_size": dla_global_dram_size, # Host RAM used by DLA to store weights and metadata for execution + "calibrator": calibrator, + "truncate_long_and_double": truncate_long_and_double, + "allow_shape_tensors": allow_shape_tensors, + } + + parsed_spec = _parse_compile_spec(compile_spec) + + backend_spec = torch.classes.tensorrt.CompileSpec() + + if input_signature is not None: + raise ValueError( + "Input signature parsing is not currently supported in the TorchScript backend integration" + ) + + for i in parsed_spec.inputs: + clone = _internal_input_to_torch_class_input(i) + backend_spec._append_input(clone) + + d = torch.classes.tensorrt._Device() + d._set_device_type(int(parsed_spec.device.device_type)) + d._set_gpu_id(parsed_spec.device.gpu_id) + d._set_dla_core(parsed_spec.device.dla_core) + d._set_allow_gpu_fallback(parsed_spec.device.allow_gpu_fallback) + + if parsed_spec.torch_fallback.enabled: + raise RuntimeError( + "Partial module compilation is not currently supported via the PyTorch TensorRT backend. If you need partial compilation, use torch_tensorrt.compile" + ) + + torch_fallback = torch.classes.tensorrt._TorchFallback() + torch_fallback._set_enabled(parsed_spec.torch_fallback.enabled) + torch_fallback._set_min_block_size(parsed_spec.torch_fallback.min_block_size) + torch_fallback._set_forced_fallback_operators( + parsed_spec.torch_fallback.forced_fallback_operators + ) + torch_fallback._set_forced_fallback_modules( + parsed_spec.torch_fallback.forced_fallback_modules + ) + + backend_spec._set_device(d) + backend_spec._set_torch_fallback(torch_fallback) + backend_spec._set_precisions([int(i) for i in parsed_spec.enabled_precisions]) + + backend_spec._set_disable_tf32(parsed_spec.disable_tf32) + backend_spec._set_refit(parsed_spec.refit) + backend_spec._set_debug(parsed_spec.debug) + backend_spec._set_refit(parsed_spec.refit) + backend_spec._set_capability(int(parsed_spec.capability)) + backend_spec._set_num_avg_timing_iters(parsed_spec.num_avg_timing_iters) + backend_spec._set_workspace_size(parsed_spec.workspace_size) + backend_spec._set_dla_sram_size(parsed_spec.dla_sram_size) + backend_spec._set_dla_local_dram_size(parsed_spec.dla_local_dram_size) + backend_spec._set_dla_global_dram_size(parsed_spec.dla_global_dram_size) + backend_spec._set_truncate_long_and_double(parsed_spec.truncate_long_and_double) + backend_spec._set_allow_shape_tensors(parsed_spec.allow_shape_tensors) + backend_spec._set_ptq_calibrator(parsed_spec._get_calibrator_handle()) + + return backend_spec
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_modules/torch_tensorrt/ts/_compiler.html b/docs/v2.2.0/_modules/torch_tensorrt/ts/_compiler.html new file mode 100644 index 0000000000..964cd77dc2 --- /dev/null +++ b/docs/v2.2.0/_modules/torch_tensorrt/ts/_compiler.html @@ -0,0 +1,1077 @@ + + + + + + + + + + + + torch_tensorrt.ts._compiler — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +

Source code for torch_tensorrt.ts._compiler

+from __future__ import annotations
+
+from typing import Any, List, Optional, Sequence, Set, Tuple
+
+import torch
+import torch_tensorrt._C.ts as _C
+from torch_tensorrt import _enums
+from torch_tensorrt._Device import Device
+from torch_tensorrt._Input import Input
+from torch_tensorrt.ts._compile_spec import _parse_compile_spec, _parse_device
+
+
+
[docs]def compile( + module: torch.jit.ScriptModule, + inputs: Optional[Sequence[Input | torch.Tensor]] = None, + input_signature: Optional[Tuple[Input | torch.Tensor | Sequence[Any]]] = None, + device: Device = Device._current_device(), + disable_tf32: bool = False, + sparse_weights: bool = False, + enabled_precisions: Optional[Set[torch.dtype | _enums.dtype]] = None, + refit: bool = False, + debug: bool = False, + capability: _enums.EngineCapability = _enums.EngineCapability.default, + num_avg_timing_iters: int = 1, + workspace_size: int = 0, + dla_sram_size: int = 1048576, + dla_local_dram_size: int = 1073741824, + dla_global_dram_size: int = 536870912, + calibrator: object = None, + truncate_long_and_double: bool = False, + require_full_compilation: bool = False, + min_block_size: int = 3, + torch_executed_ops: Optional[List[str]] = None, + torch_executed_modules: Optional[List[str]] = None, + allow_shape_tensors: bool = False, +) -> torch.jit.ScriptModule: + """Compile a TorchScript module for NVIDIA GPUs using TensorRT + + Takes a existing TorchScript module and a set of settings to configure the compiler + and will convert methods to JIT Graphs which call equivalent TensorRT engines + + Converts specifically the forward method of a TorchScript Module + + Arguments: + module (torch.jit.ScriptModule): Source module, a result of tracing or scripting a PyTorch + ``torch.nn.Module`` + + Keyword Arguments: + inputs (List[Union(torch_tensorrt.Input, torch.Tensor)]): **Required** List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using + torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum + to select device type. :: + + input=[ + torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1 + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ), # Dynamic input shape for input #2 + torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings + ] + + input_signature Union(List, Tuple, torch_tensorrt.Input, torch.Tensor): A formatted collection of input specifications for the module. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using + torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum to select device type. **This API should be considered beta-level stable and may change in the future** :: + + input_signature=([ + torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1 + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ), # Dynamic input shape for input #2 + ], torch.randn((1, 3, 224, 244))) # Use an example tensor and let torch_tensorrt infer settings for input #3 + device (Union(torch_tensorrt.Device, torch.device, dict)): Target device for TensorRT engines to run on :: + + device=torch_tensorrt.Device("dla:1", allow_gpu_fallback=True) + + disable_tf32 (bool): Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas + sparse_weights (bool): Enable sparsity for convolution and fully connected layers. + enabled_precision (Set(Union(torch.dtype, torch_tensorrt.dtype))): The set of datatypes that TensorRT can use when selecting kernels + refit (bool): Enable refitting + debug (bool): Enable debuggable engine + capability (torch_tensorrt.EngineCapability): Restrict kernel selection to safe gpu kernels or safe dla kernels + num_avg_timing_iters (int): Number of averaging timing iterations used to select kernels + workspace_size (int): Maximum size of workspace given to TensorRT + dla_sram_size (int): Fast software managed RAM used by DLA to communicate within a layer. + dla_local_dram_size (int): Host RAM used by DLA to share intermediate tensor data across operations + dla_global_dram_size (int): Host RAM used by DLA to store weights and metadata for execution + truncate_long_and_double (bool): Truncate weights provided in int64 or double (float64) to int32 and float32 + calibrator (Union(torch_tensorrt._C.IInt8Calibrator, tensorrt.IInt8Calibrator)): Calibrator object which will provide data to the PTQ system for INT8 Calibration + require_full_compilation (bool): Require modules to be compiled end to end or return an error as opposed to returning a hybrid graph where operations that cannot be run in TensorRT are run in PyTorch + min_block_size (int): The minimum number of contiguous TensorRT convertable operations in order to run a set of operations in TensorRT + torch_executed_ops (List[str]): List of aten operators that must be run in PyTorch. An error will be thrown if this list is not empty but ``require_full_compilation`` is True + torch_executed_modules (List[str]): List of modules that must be run in PyTorch. An error will be thrown if this list is not empty but ``require_full_compilation`` is True + allow_shape_tensors: (Experimental) Allow aten::size to output shape tensors using IShapeLayer in TensorRT + + Returns: + torch.jit.ScriptModule: Compiled TorchScript Module, when run it will execute via TensorRT + """ + + input_list = list(inputs) if inputs is not None else [] + enabled_precisions_set = ( + enabled_precisions if enabled_precisions is not None else set() + ) + torch_executed_module_list = ( + torch_executed_modules if torch_executed_modules is not None else [] + ) + torch_executed_op_list = ( + torch_executed_ops if torch_executed_ops is not None else [] + ) + + if isinstance(module, torch.jit.ScriptFunction): + raise TypeError( + "torch.jit.ScriptFunction currently is not directly supported, wrap the function in a module to compile" + ) + + if require_full_compilation and ( + len(torch_executed_module_list) > 0 or len(torch_executed_op_list) > 0 + ): + raise ValueError( + f"require_full_compilation is enabled however the list of modules and ops to run in torch is not empty. Found: torch_executed_ops: {torch_executed_ops}, torch_executed_modules: {torch_executed_modules}" + ) + + spec = { + "inputs": input_list, + "input_signature": input_signature, + "device": device, + "disable_tf32": disable_tf32, # Force FP32 layers to use traditional as FP32 format + "sparse_weights": sparse_weights, # Enable sparsity for convolution and fully connected layers. + "enabled_precisions": enabled_precisions_set, # Enabling FP16 kernels + "refit": refit, # enable refit + "debug": debug, # enable debuggable engine + "capability": capability, # Restrict kernel selection to safe gpu kernels or safe dla kernels + "num_avg_timing_iters": num_avg_timing_iters, # Number of averaging timing iterations used to select kernels + "workspace_size": workspace_size, # Maximum size of workspace given to TensorRT + "calibrator": calibrator, + "truncate_long_and_double": truncate_long_and_double, + "torch_fallback": { + "enabled": not require_full_compilation, + "forced_fallback_ops": torch_executed_op_list, + "forced_fallback_modules": torch_executed_module_list, + "min_block_size": min_block_size, + }, + "allow_shape_tensors": allow_shape_tensors, + } + + compiled_cpp_mod = _C.compile_graph(module._c, _parse_compile_spec(spec)) + compiled_module: torch.jit.ScriptModule = torch.jit._recursive.wrap_cpp_module( + compiled_cpp_mod + ) + return compiled_module
+ + +
[docs]def convert_method_to_trt_engine( + module: torch.jit.ScriptModule, + method_name: str = "forward", + inputs: Optional[Sequence[Input | torch.Tensor]] = None, + device: Device = Device._current_device(), + disable_tf32: bool = False, + sparse_weights: bool = False, + enabled_precisions: Optional[Set[torch.dtype | _enums.dtype]] = None, + refit: bool = False, + debug: bool = False, + capability: _enums.EngineCapability = _enums.EngineCapability.default, + num_avg_timing_iters: int = 1, + workspace_size: int = 0, + dla_sram_size: int = 1048576, + dla_local_dram_size: int = 1073741824, + dla_global_dram_size: int = 536870912, + truncate_long_and_double: int = False, + calibrator: object = None, + allow_shape_tensors: bool = False, +) -> bytes: + """Convert a TorchScript module method to a serialized TensorRT engine + + Converts a specified method of a module to a serialized TensorRT engine given a dictionary of conversion settings + + Arguments: + module (torch.jit.ScriptModule): Source module, a result of tracing or scripting a PyTorch + ``torch.nn.Module`` + + Keyword Args: + inputs (List[Union(torch_tensorrt.Input, torch.Tensor)]): **Required** List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using + torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum + to select device type. :: + + input=[ + torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1 + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ), # Dynamic input shape for input #2 + torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings + ] + + method_name (str): Name of method to convert + input_signature Union(List, Tuple, torch_tensorrt.Input, torch.Tensor): A formatted collection of input specifications for the module. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using + torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum to select device type. **This API should be considered beta-level stable and may change in the future** :: + + input_signature=([ + torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1 + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ), # Dynamic input shape for input #2 + ], torch.randn((1, 3, 224, 244))) # Use an example tensor and let torch_tensorrt infer settings for input #3 + + device (Union(torch_tensorrt.Device, torch.device, dict)): Target device for TensorRT engines to run on :: + + device=torch_tensorrt.Device("dla:1", allow_gpu_fallback=True) + + disable_tf32 (bool): Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas + sparse_weights (bool): Enable sparsity for convolution and fully connected layers. + enabled_precision (Set(Union(torch.dtype, torch_tensorrt.dtype))): The set of datatypes that TensorRT can use when selecting kernels + refit (bool): Enable refitting + debug (bool): Enable debuggable engine + capability (torch_tensorrt.EngineCapability): Restrict kernel selection to safe gpu kernels or safe dla kernels + num_avg_timing_iters (int): Number of averaging timing iterations used to select kernels + workspace_size (int): Maximum size of workspace given to TensorRT + dla_sram_size (int): Fast software managed RAM used by DLA to communicate within a layer. + dla_local_dram_size (int): Host RAM used by DLA to share intermediate tensor data across operations + dla_global_dram_size (int): Host RAM used by DLA to store weights and metadata for execution + truncate_long_and_double (bool): Truncate weights provided in int64 or double (float64) to int32 and float32 + calibrator (Union(torch_tensorrt._C.IInt8Calibrator, tensorrt.IInt8Calibrator)): Calibrator object which will provide data to the PTQ system for INT8 Calibration + allow_shape_tensors: (Experimental) Allow aten::size to output shape tensors using IShapeLayer in TensorRT + + Returns: + bytes: Serialized TensorRT engine, can either be saved to a file or deserialized via TensorRT APIs + """ + input_list = list(inputs) if inputs is not None else [] + enabled_precisions_set = ( + enabled_precisions if enabled_precisions is not None else {torch.float} + ) + + if isinstance(module, torch.jit.ScriptFunction): + raise TypeError( + "torch.jit.ScriptFunctions currently are not directly supported, wrap the function in a module to compile" + ) + + compile_spec = { + "inputs": input_list, + "device": device, + "disable_tf32": disable_tf32, # Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas + "sparse_weights": sparse_weights, # Enable sparsity for convolution and fully connected layers. + "enabled_precisions": enabled_precisions_set, # Enabling FP16 kernels + "refit": refit, # enable refit + "debug": debug, # enable debuggable engine + "capability": capability, # Restrict kernel selection to safe gpu kernels or safe dla kernels + "num_avg_timing_iters": num_avg_timing_iters, # Number of averaging timing iterations used to select kernels + "workspace_size": workspace_size, # Maximum size of workspace given to TensorRT + "calibrator": calibrator, + "truncate_long_and_double": truncate_long_and_double, + "allow_shape_tensors": allow_shape_tensors, + } + + engine_str = _C.convert_graph_to_trt_engine( + module._c, method_name, _parse_compile_spec(compile_spec) + ) + + import io + + with io.BytesIO() as engine_bytes: + engine_bytes.write(engine_str) + engine_bytearray = engine_bytes.getvalue() + + return engine_bytearray
+ + +
[docs]def embed_engine_in_new_module( + serialized_engine: bytes, + input_binding_names: Optional[List[str]] = None, + output_binding_names: Optional[List[str]] = None, + device: Device = Device._current_device(), +) -> torch.jit.ScriptModule: + """Takes a pre-built serialized TensorRT engine and embeds it within a TorchScript module + + Takes a pre-built serialied TensorRT engine (as bytes) and embeds it within a TorchScript module. + Registers the forward method to execute the TensorRT engine with the function signature: + + forward(Tensor[]) -> Tensor[] + + TensorRT bindings either be explicitly specified using ``[in/out]put_binding_names`` or have names with the following format: + - [symbol].[index in input / output array] + ex. + - [x.0, x.1, x.2] -> [y.0] + + Module can be save with engine embedded with torch.jit.save and moved / loaded according to torch_tensorrt portability rules + + Arguments: + serialized_engine (bytearray): Serialized TensorRT engine from either torch_tensorrt or TensorRT APIs + + Keyword Arguments: + input_binding_names (List[str]): List of names of TensorRT bindings in order to be passed to the encompassing PyTorch module + output_binding_names (List[str]): List of names of TensorRT bindings in order that should be returned from the encompassing PyTorch module + device (Union(torch_tensorrt.Device, torch.device, dict)): Target device to run engine on. Must be compatible with engine provided. Default: Current active device + Returns: + torch.jit.ScriptModule: New TorchScript module with engine embedded + """ + input_binding_name_list = ( + input_binding_names if input_binding_names is not None else [] + ) + output_binding_name_list = ( + output_binding_names if output_binding_names is not None else [] + ) + cpp_mod = _C.embed_engine_in_new_module( + serialized_engine, + _parse_device(device), + input_binding_name_list, + output_binding_name_list, + ) + wrapped_mod: torch.jit.ScriptModule = torch.jit._recursive.wrap_cpp_module(cpp_mod) + return wrapped_mod
+ + +
[docs]def check_method_op_support( + module: torch.jit.ScriptModule, method_name: str = "forward" +) -> bool: + """Checks to see if a method is fully supported by torch_tensorrt + + Checks if a method of a TorchScript module can be compiled by torch_tensorrt, if not, a list of operators + that are not supported are printed out and the function returns false, else true. + + Arguments: + module (torch.jit.ScriptModule): Source module, a result of tracing or scripting a PyTorch + ``torch.nn.Module`` + method_name (str): Name of method to check + + Returns: + bool: True if supported Method + """ + supported: bool = _C.check_method_op_support(module._c, method_name) + return supported
+
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1DataType.rst.txt b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1DataType.rst.txt new file mode 100644 index 0000000000..6a40d653a7 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1DataType.rst.txt @@ -0,0 +1,17 @@ +.. _exhale_class_classtorch__tensorrt_1_1DataType: + +Class DataType +============== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Class Documentation +------------------- + + +.. doxygenclass:: torch_tensorrt::DataType + :project: Torch-TensorRT + :members: + :protected-members: + :undoc-members: \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType.rst.txt b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType.rst.txt new file mode 100644 index 0000000000..5479dea0ee --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType.rst.txt @@ -0,0 +1,23 @@ +.. _exhale_class_classtorch__tensorrt_1_1Device_1_1DeviceType: + +Class Device::DeviceType +======================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Nested Relationships +-------------------- + +This class is a nested type of :ref:`exhale_struct_structtorch__tensorrt_1_1Device`. + + +Class Documentation +------------------- + + +.. doxygenclass:: torch_tensorrt::Device::DeviceType + :project: Torch-TensorRT + :members: + :protected-members: + :undoc-members: \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1TensorFormat.rst.txt b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1TensorFormat.rst.txt new file mode 100644 index 0000000000..3f2030e8f2 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1TensorFormat.rst.txt @@ -0,0 +1,17 @@ +.. _exhale_class_classtorch__tensorrt_1_1TensorFormat: + +Class TensorFormat +================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Class Documentation +------------------- + + +.. doxygenclass:: torch_tensorrt::TensorFormat + :project: Torch-TensorRT + :members: + :protected-members: + :undoc-members: \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator.rst.txt b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator.rst.txt new file mode 100644 index 0000000000..7e76229f19 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator.rst.txt @@ -0,0 +1,26 @@ +.. _exhale_class_classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator: + +Template Class Int8CacheCalibrator +================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_ptq.h` + + +Inheritance Relationships +------------------------- + +Base Type +********* + +- ``private Algorithm`` + + +Class Documentation +------------------- + + +.. doxygenclass:: torch_tensorrt::ptq::Int8CacheCalibrator + :project: Torch-TensorRT + :members: + :protected-members: + :undoc-members: \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator.rst.txt b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator.rst.txt new file mode 100644 index 0000000000..6ef15f8ff1 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator.rst.txt @@ -0,0 +1,26 @@ +.. _exhale_class_classtorch__tensorrt_1_1ptq_1_1Int8Calibrator: + +Template Class Int8Calibrator +============================= + +- Defined in :ref:`file_cpp_include_torch_tensorrt_ptq.h` + + +Inheritance Relationships +------------------------- + +Base Type +********* + +- ``private Algorithm`` + + +Class Documentation +------------------- + + +.. doxygenclass:: torch_tensorrt::ptq::Int8Calibrator + :project: Torch-TensorRT + :members: + :protected-members: + :undoc-members: \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502.rst.txt b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502.rst.txt new file mode 100644 index 0000000000..70809499b3 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_define_macros_8h_1a18d295a837ac71add5578860b55e5502: + +Define STR +========== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_macros.h` + + +Define Documentation +-------------------- + + +.. doxygendefine:: STR + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268.rst.txt b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268.rst.txt new file mode 100644 index 0000000000..10850f77a2 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268: + +Define TORCH_TENSORRT_PATCH_VERSION +=================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_macros.h` + + +Define Documentation +-------------------- + + +.. doxygendefine:: TORCH_TENSORRT_PATCH_VERSION + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e.rst.txt b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e.rst.txt new file mode 100644 index 0000000000..9a3d3c8aa8 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e: + +Define TORCH_TENSORRT_MAJOR_VERSION +=================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_macros.h` + + +Define Documentation +-------------------- + + +.. doxygendefine:: TORCH_TENSORRT_MAJOR_VERSION + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827.rst.txt b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827.rst.txt new file mode 100644 index 0000000000..0c495bc60c --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827: + +Define TORCH_TENSORRT_MINOR_VERSION +=================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_macros.h` + + +Define Documentation +-------------------- + + +.. doxygendefine:: TORCH_TENSORRT_MINOR_VERSION + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b.rst.txt b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b.rst.txt new file mode 100644 index 0000000000..40ad2fd99f --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b: + +Define TORCHTRT_API +=================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_macros.h` + + +Define Documentation +-------------------- + + +.. doxygendefine:: TORCHTRT_API + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da.rst.txt b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da.rst.txt new file mode 100644 index 0000000000..75d62d3b65 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da: + +Define XSTR +=========== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_macros.h` + + +Define Documentation +-------------------- + + +.. doxygendefine:: XSTR + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59.rst.txt b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59.rst.txt new file mode 100644 index 0000000000..262bd89acd --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_define_macros_8h_1ad19939408f7be171a74a89928b36eb59: + +Define TORCHTRT_HIDDEN +====================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_macros.h` + + +Define Documentation +-------------------- + + +.. doxygendefine:: TORCHTRT_HIDDEN + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883.rst.txt b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883.rst.txt new file mode 100644 index 0000000000..ea5d28d205 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883: + +Define TORCH_TENSORRT_VERSION +============================= + +- Defined in :ref:`file_cpp_include_torch_tensorrt_macros.h` + + +Define Documentation +-------------------- + + +.. doxygendefine:: TORCH_TENSORRT_VERSION + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/dir_cpp.rst.txt b/docs/v2.2.0/_sources/_cpp_api/dir_cpp.rst.txt new file mode 100644 index 0000000000..f09e39c518 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/dir_cpp.rst.txt @@ -0,0 +1,16 @@ +.. _dir_cpp: + + +Directory cpp +============= + + +*Directory path:* ``cpp`` + +Subdirectories +-------------- + +- :ref:`dir_cpp_include` + + + diff --git a/docs/v2.2.0/_sources/_cpp_api/dir_cpp_include.rst.txt b/docs/v2.2.0/_sources/_cpp_api/dir_cpp_include.rst.txt new file mode 100644 index 0000000000..e262b4a9af --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/dir_cpp_include.rst.txt @@ -0,0 +1,20 @@ +.. _dir_cpp_include: + + +Directory include +================= + + +|exhale_lsh| :ref:`Parent directory ` (``cpp``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +*Directory path:* ``cpp/include`` + +Subdirectories +-------------- + +- :ref:`dir_cpp_include_torch_tensorrt` + + + diff --git a/docs/v2.2.0/_sources/_cpp_api/dir_cpp_include_torch_tensorrt.rst.txt b/docs/v2.2.0/_sources/_cpp_api/dir_cpp_include_torch_tensorrt.rst.txt new file mode 100644 index 0000000000..f1da041e12 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/dir_cpp_include_torch_tensorrt.rst.txt @@ -0,0 +1,23 @@ +.. _dir_cpp_include_torch_tensorrt: + + +Directory torch_tensorrt +======================== + + +|exhale_lsh| :ref:`Parent directory ` (``cpp/include``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +*Directory path:* ``cpp/include/torch_tensorrt`` + + +Files +----- + +- :ref:`file_cpp_include_torch_tensorrt_logging.h` +- :ref:`file_cpp_include_torch_tensorrt_macros.h` +- :ref:`file_cpp_include_torch_tensorrt_ptq.h` +- :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + diff --git a/docs/v2.2.0/_sources/_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558.rst.txt b/docs/v2.2.0/_sources/_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558.rst.txt new file mode 100644 index 0000000000..6a1c2671ae --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558: + +Enum Level +========== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_logging.h` + + +Enum Documentation +------------------ + + +.. doxygenenum:: torch_tensorrt::logging::Level + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb.rst.txt b/docs/v2.2.0/_sources/_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb.rst.txt new file mode 100644 index 0000000000..a004103bfe --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb: + +Enum EngineCapability +===================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Enum Documentation +------------------ + + +.. doxygenenum:: torch_tensorrt::EngineCapability + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_logging.h.rst.txt b/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_logging.h.rst.txt new file mode 100644 index 0000000000..ea89d38038 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_logging.h.rst.txt @@ -0,0 +1,80 @@ + +.. _file_cpp_include_torch_tensorrt_logging.h: + +File logging.h +============== + +|exhale_lsh| :ref:`Parent directory ` (``cpp/include/torch_tensorrt``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +.. contents:: Contents + :local: + :backlinks: none + +Definition (``cpp/include/torch_tensorrt/logging.h``) +----------------------------------------------------- + + +.. toctree:: + :maxdepth: 1 + + program_listing_file_cpp_include_torch_tensorrt_logging.h.rst + + + + + +Includes +-------- + + +- ``string`` + +- ``torch_tensorrt/macros.h`` (:ref:`file_cpp_include_torch_tensorrt_macros.h`) + + + +Included By +----------- + + +- :ref:`file_cpp_include_torch_tensorrt_ptq.h` + + + + +Namespaces +---------- + + +- :ref:`namespace_torch_tensorrt` + +- :ref:`namespace_torch_tensorrt__logging` + + +Enums +----- + + +- :ref:`exhale_enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558` + + +Functions +--------- + + +- :ref:`exhale_function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a` + +- :ref:`exhale_function_logging_8h_1a0593f776f469c20469e2f729fc7861a3` + +- :ref:`exhale_function_logging_8h_1a0c012cb374addd90eb1f42eaec570650` + +- :ref:`exhale_function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8` + +- :ref:`exhale_function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5` + +- :ref:`exhale_function_logging_8h_1af8f3443813315af7901903d25dd495cc` + +- :ref:`exhale_function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2` + diff --git a/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_macros.h.rst.txt b/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_macros.h.rst.txt new file mode 100644 index 0000000000..61447e1ada --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_macros.h.rst.txt @@ -0,0 +1,71 @@ + +.. _file_cpp_include_torch_tensorrt_macros.h: + +File macros.h +============= + +|exhale_lsh| :ref:`Parent directory ` (``cpp/include/torch_tensorrt``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +.. contents:: Contents + :local: + :backlinks: none + +Definition (``cpp/include/torch_tensorrt/macros.h``) +---------------------------------------------------- + + +.. toctree:: + :maxdepth: 1 + + program_listing_file_cpp_include_torch_tensorrt_macros.h.rst + + + + + + + +Included By +----------- + + +- :ref:`file_cpp_include_torch_tensorrt_logging.h` + +- :ref:`file_cpp_include_torch_tensorrt_ptq.h` + +- :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + + + +Namespaces +---------- + + +- :ref:`namespace_torch_tensorrt` + +- :ref:`namespace_torch_tensorrt__torchscript` + + +Defines +------- + + +- :ref:`exhale_define_macros_8h_1a18d295a837ac71add5578860b55e5502` + +- :ref:`exhale_define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e` + +- :ref:`exhale_define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827` + +- :ref:`exhale_define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268` + +- :ref:`exhale_define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883` + +- :ref:`exhale_define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b` + +- :ref:`exhale_define_macros_8h_1ad19939408f7be171a74a89928b36eb59` + +- :ref:`exhale_define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da` + diff --git a/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_ptq.h.rst.txt b/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_ptq.h.rst.txt new file mode 100644 index 0000000000..34b64af6e0 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_ptq.h.rst.txt @@ -0,0 +1,84 @@ + +.. _file_cpp_include_torch_tensorrt_ptq.h: + +File ptq.h +========== + +|exhale_lsh| :ref:`Parent directory ` (``cpp/include/torch_tensorrt``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +.. contents:: Contents + :local: + :backlinks: none + +Definition (``cpp/include/torch_tensorrt/ptq.h``) +------------------------------------------------- + + +.. toctree:: + :maxdepth: 1 + + program_listing_file_cpp_include_torch_tensorrt_ptq.h.rst + + + + + +Includes +-------- + + +- ``NvInfer.h`` + +- ``fstream`` + +- ``iostream`` + +- ``iterator`` + +- ``memory`` + +- ``sstream`` + +- ``string`` + +- ``torch/torch.h`` + +- ``torch_tensorrt/logging.h`` (:ref:`file_cpp_include_torch_tensorrt_logging.h`) + +- ``torch_tensorrt/macros.h`` (:ref:`file_cpp_include_torch_tensorrt_macros.h`) + +- ``vector`` + + + + + + +Namespaces +---------- + + +- :ref:`namespace_torch_tensorrt` + +- :ref:`namespace_torch_tensorrt__ptq` + + +Classes +------- + + +- :ref:`exhale_class_classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator` + +- :ref:`exhale_class_classtorch__tensorrt_1_1ptq_1_1Int8Calibrator` + + +Functions +--------- + + +- :ref:`exhale_function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c` + +- :ref:`exhale_function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178` + diff --git a/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst.txt b/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst.txt new file mode 100644 index 0000000000..8057364274 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst.txt @@ -0,0 +1,105 @@ + +.. _file_cpp_include_torch_tensorrt_torch_tensorrt.h: + +File torch_tensorrt.h +===================== + +|exhale_lsh| :ref:`Parent directory ` (``cpp/include/torch_tensorrt``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +.. contents:: Contents + :local: + :backlinks: none + +Definition (``cpp/include/torch_tensorrt/torch_tensorrt.h``) +------------------------------------------------------------ + + +.. toctree:: + :maxdepth: 1 + + program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst + + + + + +Includes +-------- + + +- ``cuda_runtime.h`` + +- ``iostream`` + +- ``memory`` + +- ``set`` + +- ``string`` + +- ``torch/custom_class.h`` + +- ``torch_tensorrt/macros.h`` (:ref:`file_cpp_include_torch_tensorrt_macros.h`) + +- ``vector`` + + + + + + +Namespaces +---------- + + +- :ref:`namespace_torch_tensorrt` + +- :ref:`namespace_torch_tensorrt__torchscript` + + +Classes +------- + + +- :ref:`exhale_struct_structtorch__tensorrt_1_1Device` + +- :ref:`exhale_struct_structtorch__tensorrt_1_1GraphInputs` + +- :ref:`exhale_struct_structtorch__tensorrt_1_1Input` + +- :ref:`exhale_struct_structtorch__tensorrt_1_1torchscript_1_1CompileSpec` + +- :ref:`exhale_class_classtorch__tensorrt_1_1DataType` + +- :ref:`exhale_class_classtorch__tensorrt_1_1Device_1_1DeviceType` + +- :ref:`exhale_class_classtorch__tensorrt_1_1TensorFormat` + + +Enums +----- + + +- :ref:`exhale_enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb` + + +Functions +--------- + + +- :ref:`exhale_function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1` + +- :ref:`exhale_function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528` + +- :ref:`exhale_function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384` + +- :ref:`exhale_function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797` + +- :ref:`exhale_function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9` + +- :ref:`exhale_function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2` + +- :ref:`exhale_function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9` + diff --git a/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3.rst.txt new file mode 100644 index 0000000000..8cab943a9a --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_logging_8h_1a0593f776f469c20469e2f729fc7861a3: + +Function torch_tensorrt::logging::get_logging_prefix +==================================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_logging.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::logging::get_logging_prefix() + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650.rst.txt new file mode 100644 index 0000000000..55bb2bde5c --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_logging_8h_1a0c012cb374addd90eb1f42eaec570650: + +Function torch_tensorrt::logging::get_reportable_log_level +========================================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_logging.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::logging::get_reportable_log_level() + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a.rst.txt new file mode 100644 index 0000000000..e8b0ac046d --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a: + +Function torch_tensorrt::logging::get_is_colored_output_on +========================================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_logging.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::logging::get_is_colored_output_on() + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2.rst.txt new file mode 100644 index 0000000000..95380eb157 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2: + +Function torch_tensorrt::logging::set_reportable_log_level +========================================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_logging.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::logging::set_reportable_log_level(Level) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.rst.txt new file mode 100644 index 0000000000..0ca83fe039 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8: + +Function torch_tensorrt::logging::log +===================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_logging.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::logging::log(Level, std::string) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5.rst.txt new file mode 100644 index 0000000000..86c2c7d61e --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5: + +Function torch_tensorrt::logging::set_is_colored_output_on +========================================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_logging.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::logging::set_is_colored_output_on(bool) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc.rst.txt new file mode 100644 index 0000000000..9d0a42d2bd --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_logging_8h_1af8f3443813315af7901903d25dd495cc: + +Function torch_tensorrt::logging::set_logging_prefix +==================================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_logging.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::logging::set_logging_prefix(std::string) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c.rst.txt new file mode 100644 index 0000000000..5d9188270f --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c: + +Template Function torch_tensorrt::ptq::make_int8_cache_calibrator +================================================================= + +- Defined in :ref:`file_cpp_include_torch_tensorrt_ptq.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::ptq::make_int8_cache_calibrator(const std::string&) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178.rst.txt new file mode 100644 index 0000000000..9551f48bb6 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178: + +Template Function torch_tensorrt::ptq::make_int8_calibrator +=========================================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_ptq.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::ptq::make_int8_calibrator(DataLoader, const std::string&, bool) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.rst.txt new file mode 100644 index 0000000000..54f7c29df3 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797: + +Function torch_tensorrt::torchscript::check_method_operator_support +=================================================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::torchscript::check_method_operator_support(const torch::jit::Module&, std::string) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9.rst.txt new file mode 100644 index 0000000000..b80699688a --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9: + +Function torch_tensorrt::torchscript::compile +============================================= + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::torchscript::compile(const torch::jit::Module&, CompileSpec) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9.rst.txt new file mode 100644 index 0000000000..e01e80e211 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9: + +Function torch_tensorrt::torchscript::embed_engine_in_new_module +================================================================ + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::torchscript::embed_engine_in_new_module(const std::string&, Device, const std::vector&, const std::vector&) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528.rst.txt new file mode 100644 index 0000000000..d551c4894d --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528: + +Function torch_tensorrt::get_build_info +======================================= + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::get_build_info() + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384.rst.txt new file mode 100644 index 0000000000..e296177bfa --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384: + +Function torch_tensorrt::set_device +=================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::set_device(const int) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.rst.txt new file mode 100644 index 0000000000..06b03cbfd9 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1: + +Function torch_tensorrt::dump_build_info +======================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::dump_build_info() + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2.rst.txt b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2.rst.txt new file mode 100644 index 0000000000..2a1f0c89d0 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2.rst.txt @@ -0,0 +1,14 @@ +.. _exhale_function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2: + +Function torch_tensorrt::torchscript::convert_method_to_trt_engine +================================================================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Function Documentation +---------------------- + + +.. doxygenfunction:: torch_tensorrt::torchscript::convert_method_to_trt_engine(const torch::jit::Module&, std::string, CompileSpec) + :project: Torch-TensorRT \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/namespace_torch.rst.txt b/docs/v2.2.0/_sources/_cpp_api/namespace_torch.rst.txt new file mode 100644 index 0000000000..23f54f958d --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/namespace_torch.rst.txt @@ -0,0 +1,13 @@ + +.. _namespace_torch: + +Namespace torch +=============== + + +.. contents:: Contents + :local: + :backlinks: none + + + diff --git a/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt.rst.txt b/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt.rst.txt new file mode 100644 index 0000000000..43a0afb20d --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt.rst.txt @@ -0,0 +1,59 @@ + +.. _namespace_torch_tensorrt: + +Namespace torch_tensorrt +======================== + + +.. contents:: Contents + :local: + :backlinks: none + + + + + +Namespaces +---------- + + +- :ref:`namespace_torch_tensorrt__logging` + +- :ref:`namespace_torch_tensorrt__ptq` + +- :ref:`namespace_torch_tensorrt__torchscript` + + +Classes +------- + + +- :ref:`exhale_struct_structtorch__tensorrt_1_1Device` + +- :ref:`exhale_struct_structtorch__tensorrt_1_1GraphInputs` + +- :ref:`exhale_struct_structtorch__tensorrt_1_1Input` + +- :ref:`exhale_class_classtorch__tensorrt_1_1DataType` + +- :ref:`exhale_class_classtorch__tensorrt_1_1Device_1_1DeviceType` + +- :ref:`exhale_class_classtorch__tensorrt_1_1TensorFormat` + + +Enums +----- + + +- :ref:`exhale_enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb` + + +Functions +--------- + + +- :ref:`exhale_function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1` + +- :ref:`exhale_function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528` + +- :ref:`exhale_function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384` diff --git a/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__logging.rst.txt b/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__logging.rst.txt new file mode 100644 index 0000000000..49f946f937 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__logging.rst.txt @@ -0,0 +1,39 @@ + +.. _namespace_torch_tensorrt__logging: + +Namespace torch_tensorrt::logging +================================= + + +.. contents:: Contents + :local: + :backlinks: none + + + + + +Enums +----- + + +- :ref:`exhale_enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558` + + +Functions +--------- + + +- :ref:`exhale_function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a` + +- :ref:`exhale_function_logging_8h_1a0593f776f469c20469e2f729fc7861a3` + +- :ref:`exhale_function_logging_8h_1a0c012cb374addd90eb1f42eaec570650` + +- :ref:`exhale_function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8` + +- :ref:`exhale_function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5` + +- :ref:`exhale_function_logging_8h_1af8f3443813315af7901903d25dd495cc` + +- :ref:`exhale_function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2` diff --git a/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__ptq.rst.txt b/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__ptq.rst.txt new file mode 100644 index 0000000000..bdc39cb326 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__ptq.rst.txt @@ -0,0 +1,31 @@ + +.. _namespace_torch_tensorrt__ptq: + +Namespace torch_tensorrt::ptq +============================= + + +.. contents:: Contents + :local: + :backlinks: none + + + + + +Classes +------- + + +- :ref:`exhale_class_classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator` + +- :ref:`exhale_class_classtorch__tensorrt_1_1ptq_1_1Int8Calibrator` + + +Functions +--------- + + +- :ref:`exhale_function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c` + +- :ref:`exhale_function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178` diff --git a/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__torchscript.rst.txt b/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__torchscript.rst.txt new file mode 100644 index 0000000000..fa21b92a73 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/namespace_torch_tensorrt__torchscript.rst.txt @@ -0,0 +1,33 @@ + +.. _namespace_torch_tensorrt__torchscript: + +Namespace torch_tensorrt::torchscript +===================================== + + +.. contents:: Contents + :local: + :backlinks: none + + + + + +Classes +------- + + +- :ref:`exhale_struct_structtorch__tensorrt_1_1torchscript_1_1CompileSpec` + + +Functions +--------- + + +- :ref:`exhale_function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797` + +- :ref:`exhale_function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9` + +- :ref:`exhale_function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2` + +- :ref:`exhale_function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9` diff --git a/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h.rst.txt b/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h.rst.txt new file mode 100644 index 0000000000..ec413cb1b7 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h.rst.txt @@ -0,0 +1,51 @@ + +.. _program_listing_file_cpp_include_torch_tensorrt_logging.h: + +Program Listing for File logging.h +================================== + +|exhale_lsh| :ref:`Return to documentation for file ` (``cpp/include/torch_tensorrt/logging.h``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +.. code-block:: cpp + + /* + * Copyright (c) NVIDIA Corporation. + * All rights reserved. + * + * This library is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + #pragma once + + #include + #include "torch_tensorrt/macros.h" + + namespace torch_tensorrt { + namespace logging { + enum Level { + kINTERNAL_ERROR, + kERROR, + kWARNING, + kINFO, + kDEBUG, + kGRAPH, + }; + + // Are these ones necessary for the user? + TORCHTRT_API std::string get_logging_prefix(); + TORCHTRT_API void set_logging_prefix(std::string prefix); + + TORCHTRT_API void set_reportable_log_level(Level lvl); + + TORCHTRT_API void set_is_colored_output_on(bool colored_output_on); + + TORCHTRT_API Level get_reportable_log_level(); + + TORCHTRT_API bool get_is_colored_output_on(); + + // Dont know if we want this? + TORCHTRT_API void log(Level lvl, std::string msg); + } // namespace logging + } // namespace torch_tensorrt diff --git a/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h.rst.txt b/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h.rst.txt new file mode 100644 index 0000000000..5bda443ab9 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h.rst.txt @@ -0,0 +1,50 @@ + +.. _program_listing_file_cpp_include_torch_tensorrt_macros.h: + +Program Listing for File macros.h +================================= + +|exhale_lsh| :ref:`Return to documentation for file ` (``cpp/include/torch_tensorrt/macros.h``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +.. code-block:: cpp + + /* + * Copyright (c) NVIDIA Corporation. + * All rights reserved. + * + * This library is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + #pragma once + + #if defined(USE_CMAKE_GENERATED_EXPORT_HEADER) + #include + #else + #if defined(__GNUC__) + #define TORCHTRT_API __attribute__((__visibility__("default"))) + #define TORCHTRT_HIDDEN __attribute__((__visibility__("hidden"))) + #else + #define TORCHTRT_API + #define TORCHTRT_HIDDEN + #endif // defined(__GNUC__) + #endif // defined(USE_CMAKE_GENERATED_EXPORT_HEADER) + + // Does this need to be gaurded or something? + #define XSTR(x) #x + #define STR(x) XSTR(x) + + #define TORCH_TENSORRT_MAJOR_VERSION 2 + #define TORCH_TENSORRT_MINOR_VERSION 2 + #define TORCH_TENSORRT_PATCH_VERSION 0 + #define TORCH_TENSORRT_VERSION \ + STR(TORCH_TENSORRT_MAJOR_VERSION) \ + "." STR(TORCH_TENSORRT_MINOR_VERSION) "." STR(TORCH_TENSORRT_PATCH_VERSION) + + // Setup namespace aliases for ease of use + namespace torch_tensorrt { + namespace torchscript {} + namespace ts = torchscript; + } // namespace torch_tensorrt + namespace torchtrt = torch_tensorrt; diff --git a/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h.rst.txt b/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h.rst.txt new file mode 100644 index 0000000000..8f4e8e4865 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h.rst.txt @@ -0,0 +1,190 @@ + +.. _program_listing_file_cpp_include_torch_tensorrt_ptq.h: + +Program Listing for File ptq.h +============================== + +|exhale_lsh| :ref:`Return to documentation for file ` (``cpp/include/torch_tensorrt/ptq.h``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +.. code-block:: cpp + + /* + * Copyright (c) NVIDIA Corporation. + * All rights reserved. + * + * This library is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + #pragma once + + #include + #include + #include + #include + #include + #include + #include + + #include "NvInfer.h" + #include "torch/torch.h" + #include "torch_tensorrt/logging.h" + #include "torch_tensorrt/macros.h" + + #ifndef DOXYGEN_SHOULD_SKIP_THIS + namespace nvinfer1 { + class IInt8Calibrator; + class IInt8EntropyCalibrator2; + } // namespace nvinfer1 + + namespace torch_tensorrt { + namespace ptq { + TORCHTRT_API bool get_batch_impl(void* bindings[], const char* names[], int nbBindings, torch::Tensor& data); + } + } // namespace torch_tensorrt + #endif // DOXYGEN_SHOULD_SKIP_THIS + + namespace torch_tensorrt { + namespace ptq { + + template + class Int8Calibrator : Algorithm { + using DataLoader = typename DataLoaderUniquePtr::element_type; + using Batch = typename DataLoader::super::BatchType; + + public: + Int8Calibrator(DataLoaderUniquePtr dataloader, const std::string& cache_file_path, bool use_cache) + : dataloader_(dataloader.get()), cache_file_path_(cache_file_path), use_cache_(use_cache) { + for (auto batch : *dataloader_) { + batched_data_.push_back(batch.data); + } + it_ = batched_data_.begin(); + } + + int getBatchSize() const noexcept override { + // HACK: Torch-TensorRT only uses explict batch sizing, INT8 Calibrator does not + // work when reporting the batch size here and having explicity batching. + // So we just report batch size 1 (warnings will still be printed out). + return 1; + // return static_cast(dataloader_->options().batch_size); + } + + bool getBatch(void* bindings[], const char* names[], int nbBindings) noexcept override { + if (it_ != batched_data_.end()) { + auto status = get_batch_impl(bindings, names, nbBindings, *it_); + it_ = ++it_; + return status; + } else { + // Reset iterator if incase calibrator is going to be used again + it_ = batched_data_.begin(); + return false; + } + } + + const void* readCalibrationCache(size_t& length) noexcept override { + if (use_cache_) { + std::stringstream ss; + ss << "Reading Calibration Cache from " << cache_file_path_; + logging::log(logging::Level::kINFO, ss.str()); + + cache_.clear(); + std::ifstream input(cache_file_path_, std::ios::binary); + input >> std::noskipws; + if (input.good()) { + std::copy(std::istream_iterator(input), std::istream_iterator(), std::back_inserter(cache_)); + logging::log(logging::Level::kDEBUG, "Cache read"); + } + length = cache_.size(); + return length ? cache_.data() : nullptr; + } + return nullptr; + } + + void writeCalibrationCache(const void* cache, size_t length) noexcept override { + std::ofstream cache_file(cache_file_path_, std::ios::binary); + cache_file.write(reinterpret_cast(cache), length); + std::stringstream ss; + ss << "Saved Calibration Cache to " << cache_file_path_; + logging::log(logging::Level::kINFO, ss.str()); + } + + operator nvinfer1::IInt8Calibrator*() { + return reinterpret_cast(this); + } + + private: + DataLoader* dataloader_; + const std::string& cache_file_path_; + size_t cache_size_ = 0; + bool use_cache_; + std::vector cache_; + std::vector batched_data_; + std::vector::iterator it_; + }; + + template + class Int8CacheCalibrator : Algorithm { + public: + Int8CacheCalibrator(const std::string& cache_file_path) : cache_file_path_(cache_file_path) {} + + int getBatchSize() const noexcept override { + // HACK: Torch-TensorRT only uses explict batch sizing, INT8 Calibrator does not + // work when reporting the batch size here and having explicity batching. + // So we just report batch size 1 (warnings will still be printed out). + return 1; + } + + bool getBatch(void* bindings[], const char* names[], int nbBindings) noexcept override { + return false; + } + + const void* readCalibrationCache(size_t& length) noexcept override { + std::stringstream ss; + ss << "Reading Calibration Cache from " << cache_file_path_; + logging::log(logging::Level::kINFO, ss.str()); + + cache_.clear(); + std::ifstream input(cache_file_path_, std::ios::binary); + input >> std::noskipws; + if (input.good()) { + std::copy(std::istream_iterator(input), std::istream_iterator(), std::back_inserter(cache_)); + logging::log(logging::Level::kDEBUG, "Cache read"); + } + length = cache_.size(); + return length ? cache_.data() : nullptr; + } + + void writeCalibrationCache(const void* cache, size_t length) noexcept override { + std::ofstream cache_file(cache_file_path_, std::ios::binary); + cache_file.write(reinterpret_cast(cache), length); + std::stringstream ss; + ss << "Saved Calibration Cache to " << cache_file_path_; + logging::log(logging::Level::kINFO, ss.str()); + } + + operator nvinfer1::IInt8Calibrator*() { + return reinterpret_cast(this); + } + + private: + const std::string& cache_file_path_; + size_t cache_size_ = 0; + std::vector cache_; + }; + + template + inline Int8Calibrator make_int8_calibrator( + DataLoader dataloader, + const std::string& cache_file_path, + bool use_cache) { + return Int8Calibrator(std::move(dataloader), cache_file_path, use_cache); + } + + template + inline Int8CacheCalibrator make_int8_cache_calibrator(const std::string& cache_file_path) { + return Int8CacheCalibrator(cache_file_path); + } + + } // namespace ptq + } // namespace torch_tensorrt diff --git a/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst.txt b/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst.txt new file mode 100644 index 0000000000..9a34bf9d4f --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst.txt @@ -0,0 +1,354 @@ + +.. _program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h: + +Program Listing for File torch_tensorrt.h +========================================= + +|exhale_lsh| :ref:`Return to documentation for file ` (``cpp/include/torch_tensorrt/torch_tensorrt.h``) + +.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS + +.. code-block:: cpp + + /* + * Copyright (c) NVIDIA Corporation. + * All rights reserved. + * + * This library is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + + #pragma once + + #include + #include + #include + #include + #include + #include + #include "torch/custom_class.h" + + #include "torch_tensorrt/macros.h" + + // Just include the .h? + #ifndef DOXYGEN_SHOULD_SKIP_THIS + namespace torch { + namespace jit { + struct Graph; + struct Module; + } // namespace jit + } // namespace torch + + namespace c10 { + enum class DeviceType : int8_t; + enum class ScalarType : int8_t; + template + class ArrayRef; + } // namespace c10 + + namespace nvinfer1 { + class IInt8Calibrator; + } + #endif // DOXYGEN_SHOULD_SKIP_THIS + + namespace torch_tensorrt { + class DataType { + public: + enum Value : int8_t { + kLong, + kDouble, + kFloat, + kHalf, + kChar, + kInt, + kBool, + kUnknown + }; + + DataType() = default; + constexpr DataType(Value t) : value(t) {} + TORCHTRT_API DataType(c10::ScalarType t); + operator Value() const { + return value; + } + explicit operator bool() = delete; + constexpr bool operator==(DataType other) const { + return value == other.value; + } + constexpr bool operator==(DataType::Value other) const { + return value == other; + } + constexpr bool operator!=(DataType other) const { + return value != other.value; + } + constexpr bool operator!=(DataType::Value other) const { + return value != other; + } + + private: + friend TORCHTRT_API std::ostream& operator<<(std::ostream& os, const DataType& dtype); + Value value; + }; + + struct Device { + class DeviceType { + public: + enum Value : int8_t { + kGPU, + kDLA, + }; + + DeviceType() = default; + constexpr DeviceType(Value t) : value(t) {} + DeviceType(c10::DeviceType t); + operator Value() const { + return value; + } + explicit operator bool() = delete; + constexpr bool operator==(DeviceType other) const { + return value == other.value; + } + constexpr bool operator!=(DeviceType other) const { + return value != other.value; + } + + private: + Value value; + }; + + DeviceType device_type; + + /* + * Target gpu id + */ + int64_t gpu_id; + + /* + * When using DLA core on NVIDIA AGX platforms gpu_id should be set as Xavier device + */ + int64_t dla_core; + + bool allow_gpu_fallback; + + Device() : device_type(DeviceType::kGPU), gpu_id(0), dla_core(0), allow_gpu_fallback(false) {} + }; + + enum class EngineCapability : int8_t { + kSTANDARD, + kSAFETY, + kDLA_STANDALONE, + }; + + class TensorFormat { + public: + enum Value : int8_t { + kContiguous, + kChannelsLast, + kUnknown, + }; + + TensorFormat() = default; + constexpr TensorFormat(Value t) : value(t) {} + TORCHTRT_API TensorFormat(at::MemoryFormat t); + operator Value() const { + return value; + } + explicit operator bool() = delete; + constexpr bool operator==(TensorFormat other) const { + return value == other.value; + } + constexpr bool operator==(TensorFormat::Value other) const { + return value == other; + } + constexpr bool operator!=(TensorFormat other) const { + return value != other.value; + } + constexpr bool operator!=(TensorFormat::Value other) const { + return value != other; + } + + private: + friend TORCHTRT_API std::ostream& operator<<(std::ostream& os, const TensorFormat& format); + Value value; + }; + + struct Input : torch::CustomClassHolder { + std::vector min_shape; + std::vector opt_shape; + std::vector max_shape; + std::vector shape; + DataType dtype; + TensorFormat format; + std::vector tensor_domain; + + Input() {} + TORCHTRT_API Input(std::vector shape, TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + std::vector shape, + std::vector tensor_domain, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input(std::vector shape, DataType dtype, TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + std::vector shape, + DataType dtype, + std::vector tensor_domain, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input(c10::ArrayRef shape, TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + c10::ArrayRef shape, + std::vector tensor_domain, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input(c10::ArrayRef shape, DataType dtype, TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + c10::ArrayRef shape, + DataType dtype, + std::vector tensor_domain, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + std::vector min_shape, + std::vector opt_shape, + std::vector max_shape, + TensorFormat format = TensorFormat::kContiguous); + TORCHTRT_API Input( + std::vector min_shape, + std::vector opt_shape, + std::vector max_shape, + std::vector tensor_domain, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + std::vector min_shape, + std::vector opt_shape, + std::vector max_shape, + DataType dtype, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + std::vector min_shape, + std::vector opt_shape, + std::vector max_shape, + DataType dtype, + std::vector tensor_domain, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + c10::ArrayRef min_shape, + c10::ArrayRef opt_shape, + c10::ArrayRef max_shape, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + c10::ArrayRef min_shape, + c10::ArrayRef opt_shape, + c10::ArrayRef max_shape, + std::vector tensor_domain, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + c10::ArrayRef min_shape, + c10::ArrayRef opt_shape, + c10::ArrayRef max_shape, + DataType dtype, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input( + c10::ArrayRef min_shape, + c10::ArrayRef opt_shape, + c10::ArrayRef max_shape, + DataType dtype, + std::vector tensor_domain, + TensorFormat format = TensorFormat::kContiguous); + + TORCHTRT_API Input(at::Tensor tensor); + + private: + friend TORCHTRT_API std::ostream& operator<<(std::ostream& os, const Input& input); + bool input_is_dynamic; + }; + + struct GraphInputs { + torch::jit::IValue input_signature; // nested Input, full input spec + std::vector inputs; // flatten input spec + }; + + TORCHTRT_API std::string get_build_info(); + + TORCHTRT_API void dump_build_info(); + + TORCHTRT_API void set_device(const int gpu_id); + + namespace torchscript { + struct CompileSpec { + TORCHTRT_API CompileSpec(std::vector> fixed_sizes); + + TORCHTRT_API CompileSpec(std::vector> fixed_sizes); + + TORCHTRT_API CompileSpec(std::vector inputs); + + TORCHTRT_API CompileSpec(torch::jit::IValue input_signature); + // Defaults should reflect TensorRT defaults for BuilderConfig + + GraphInputs graph_inputs; + std::set enabled_precisions = {DataType::kFloat}; + + bool disable_tf32 = false; + + bool sparse_weights = false; + + bool refit = false; + + bool debug = false; + + bool truncate_long_and_double = false; + + bool allow_shape_tensors = false; + + Device device; + + EngineCapability capability = EngineCapability::kSTANDARD; + + uint64_t num_avg_timing_iters = 1; + + uint64_t workspace_size = 0; + + uint64_t dla_sram_size = 1048576; + + uint64_t dla_local_dram_size = 1073741824; + + uint64_t dla_global_dram_size = 536870912; + + nvinfer1::IInt8Calibrator* ptq_calibrator = nullptr; + + bool require_full_compilation = false; + + uint64_t min_block_size = 3; + + std::vector torch_executed_ops; + + std::vector torch_executed_modules; + }; + + TORCHTRT_API bool check_method_operator_support(const torch::jit::Module& module, std::string method_name); + + TORCHTRT_API torch::jit::Module compile(const torch::jit::Module& module, CompileSpec info); + + TORCHTRT_API std::string convert_method_to_trt_engine( + const torch::jit::Module& module, + std::string method_name, + CompileSpec info); + + TORCHTRT_API torch::jit::Module embed_engine_in_new_module( + const std::string& engine, + Device device, + const std::vector& input_binding_names = std::vector(), + const std::vector& output_binding_names = std::vector()); + } // namespace torchscript + } // namespace torch_tensorrt diff --git a/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1Device.rst.txt b/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1Device.rst.txt new file mode 100644 index 0000000000..a090eaa324 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1Device.rst.txt @@ -0,0 +1,27 @@ +.. _exhale_struct_structtorch__tensorrt_1_1Device: + +Struct Device +============= + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Nested Relationships +-------------------- + + +Nested Types +************ + +- :ref:`exhale_class_classtorch__tensorrt_1_1Device_1_1DeviceType` + + +Struct Documentation +-------------------- + + +.. doxygenstruct:: torch_tensorrt::Device + :project: Torch-TensorRT + :members: + :protected-members: + :undoc-members: \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1GraphInputs.rst.txt b/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1GraphInputs.rst.txt new file mode 100644 index 0000000000..60bc3285c6 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1GraphInputs.rst.txt @@ -0,0 +1,17 @@ +.. _exhale_struct_structtorch__tensorrt_1_1GraphInputs: + +Struct GraphInputs +================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Struct Documentation +-------------------- + + +.. doxygenstruct:: torch_tensorrt::GraphInputs + :project: Torch-TensorRT + :members: + :protected-members: + :undoc-members: \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1Input.rst.txt b/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1Input.rst.txt new file mode 100644 index 0000000000..64144c4dd7 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1Input.rst.txt @@ -0,0 +1,26 @@ +.. _exhale_struct_structtorch__tensorrt_1_1Input: + +Struct Input +============ + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Inheritance Relationships +------------------------- + +Base Type +********* + +- ``public torch::CustomClassHolder`` + + +Struct Documentation +-------------------- + + +.. doxygenstruct:: torch_tensorrt::Input + :project: Torch-TensorRT + :members: + :protected-members: + :undoc-members: \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec.rst.txt b/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec.rst.txt new file mode 100644 index 0000000000..31f2296658 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec.rst.txt @@ -0,0 +1,17 @@ +.. _exhale_struct_structtorch__tensorrt_1_1torchscript_1_1CompileSpec: + +Struct CompileSpec +================== + +- Defined in :ref:`file_cpp_include_torch_tensorrt_torch_tensorrt.h` + + +Struct Documentation +-------------------- + + +.. doxygenstruct:: torch_tensorrt::torchscript::CompileSpec + :project: Torch-TensorRT + :members: + :protected-members: + :undoc-members: \ No newline at end of file diff --git a/docs/v2.2.0/_sources/_cpp_api/torch_tensort_cpp.rst.txt b/docs/v2.2.0/_sources/_cpp_api/torch_tensort_cpp.rst.txt new file mode 100644 index 0000000000..1b34d45a77 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/torch_tensort_cpp.rst.txt @@ -0,0 +1,10 @@ +====================== +Torch-TensorRT C++ API +====================== + +.. include:: class_view_hierarchy.rst.include + +.. include:: file_view_hierarchy.rst.include + +.. include:: unabridged_api.rst.include + diff --git a/docs/v2.2.0/_sources/_cpp_api/unabridged_orphan.rst.txt b/docs/v2.2.0/_sources/_cpp_api/unabridged_orphan.rst.txt new file mode 100644 index 0000000000..5789e581e8 --- /dev/null +++ b/docs/v2.2.0/_sources/_cpp_api/unabridged_orphan.rst.txt @@ -0,0 +1,48 @@ +:orphan: + + +Full API +======== + +Directories +*********** + + +.. toctree:: + :maxdepth: 5 + + dir_cpp.rst + +.. toctree:: + :maxdepth: 5 + + dir_cpp_include.rst + +.. toctree:: + :maxdepth: 5 + + dir_cpp_include_torch_tensorrt.rst + +Files +***** + + +.. toctree:: + :maxdepth: 5 + + file_cpp_include_torch_tensorrt_logging.h.rst + +.. toctree:: + :maxdepth: 5 + + file_cpp_include_torch_tensorrt_macros.h.rst + +.. toctree:: + :maxdepth: 5 + + file_cpp_include_torch_tensorrt_ptq.h.rst + +.. toctree:: + :maxdepth: 5 + + file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst diff --git a/docs/v2.2.0/_sources/cli/torchtrtc.rst.txt b/docs/v2.2.0/_sources/cli/torchtrtc.rst.txt new file mode 100644 index 0000000000..69292c491c --- /dev/null +++ b/docs/v2.2.0/_sources/cli/torchtrtc.rst.txt @@ -0,0 +1,149 @@ +.. _torchtrtc: + +torchtrtc +================================= + +``torchtrtc`` is a CLI application for using the Torch-TensorRT compiler. It serves as an easy way to compile a +TorchScript Module with Torch-TensorRT from the command-line to quickly check support or as part of +a deployment pipeline. All basic features of the compiler are supported including post training +quantization (though you must already have a calibration cache file to use the PTQ feature). The compiler can +output two formats, either a TorchScript program with the TensorRT engine embedded or +the TensorRT engine itself as a PLAN file. + +All that is required to run the program after compilation is for C++ linking against ``libtorchtrt.so`` +or in Python importing the torch_tensorrt package. All other aspects of using compiled modules are identical +to standard TorchScript. Load with ``torch.jit.load()`` and run like you would run any other module. + +.. code-block:: txt + + torchtrtc [input_file_path] [output_file_path] + [input_specs...] {OPTIONS} + + torchtrtc is a compiler for TorchScript, it will compile and optimize + TorchScript programs to run on NVIDIA GPUs using TensorRT + + OPTIONS: + + -h, --help Display this help menu + Verbiosity of the compiler + -v, --verbose Dumps debugging information about the + compilation process onto the console + -w, --warnings Disables warnings generated during + compilation onto the console (warnings + are on by default) + --i, --info Dumps info messages generated during + compilation onto the console + --build-debuggable-engine Creates a debuggable engine + --allow-gpu-fallback (Only used when targeting DLA + (device-type)) Lets engine run layers on + GPU if they are not supported on DLA + --require-full-compilation Require that the model should be fully + compiled to TensorRT or throw an error + --check-method-support=[method_name] + Check the support for end to end + compilation of a specified method in the + TorchScript module + --disable-tf32 Prevent Float32 layers from using the + TF32 data format + --sparse-weights Enable sparsity for weights of conv and + FC layers + -p[precision...], + --enable-precision=[precision...] (Repeatable) Enabling an operating + precision for kernels to use when + building the engine (Int8 requires a + calibration-cache argument) [ float | + float32 | f32 | fp32 | half | float16 | + f16 | fp16 | int8 | i8 | char ] + (default: float) + -d[type], --device-type=[type] The type of device the engine should be + built for [ gpu | dla ] (default: gpu) + --gpu-id=[gpu_id] GPU id if running on multi-GPU platform + (defaults to 0) + --dla-core=[dla_core] DLACore id if running on available DLA + (defaults to 0) + --engine-capability=[capability] The type of device the engine should be + built for [ standard | safety | + dla_standalone ] + --calibration-cache-file=[file_path] + Path to calibration cache file to use + for post training quantization + --teo=[op_name...], + --torch-executed-op=[op_name...] (Repeatable) Operator in the graph that + should always be run in PyTorch for + execution (partial compilation must be + enabled) + --tem=[module_name...], + --torch-executed-mod=[module_name...] + (Repeatable) Module that should always + be run in Pytorch for execution (partial + compilation must be enabled) + --mbs=[num_ops], + --min-block-size=[num_ops] Minimum number of contiguous TensorRT + supported ops to compile a subgraph to + TensorRT + --embed-engine Whether to treat input file as a + serialized TensorRT engine and embed it + into a TorchScript module (device spec + must be provided) + --num-avg-timing-iters=[num_iters] + Number of averaging timing iterations + used to select kernels + --workspace-size=[workspace_size] Maximum size of workspace given to + TensorRT + --dla-sram-size=[dla_sram_size] Fast software managed RAM used by DLA + to communicate within a layer. + --dla-local-dram-size=[dla_local_dram_size] Host RAM used by DLA to share + intermediate tensor data across operations. + --dla-global-dram-size=[dla_global_dram_size] Host RAM used by DLA to store + weights and metadata for execution + --atol=[atol] Absolute tolerance threshold for acceptable + numerical deviation from standard torchscript + output (default 1e-8) + --rtol=[rtol] Relative tolerance threshold for acceptable + numerical deviation from standard torchscript + output (default 1e-5) + --no-threshold-check Skip checking threshold compliance + --truncate-long-double, + --truncate, --truncate-64bit Truncate weights that are provided in + 64bit to 32bit (Long, Double to Int, + Float) + --save-engine Instead of compiling a full a + TorchScript program, save the created + engine to the path specified as the + output path + --custom-torch-ops (repeatable) Shared object/DLL containing custom torch operators + --custom-converters (repeatable) Shared object/DLL containing custom converters + input_file_path Path to input TorchScript file + output_file_path Path for compiled TorchScript (or + TensorRT engine) file + input_specs... Specs for inputs to engine, can either + be a single size or a range defined by + Min, Optimal, Max sizes, e.g. + "(N,..,C,H,W)" + "[(MIN_N,..,MIN_C,MIN_H,MIN_W);(OPT_N,..,OPT_C,OPT_H,OPT_W);(MAX_N,..,MAX_C,MAX_H,MAX_W)]". + Data Type and format can be specified by + adding an "@" followed by dtype and "%" + followed by format to the end of the + shape spec. e.g. "(3, 3, 32, + 32)@f16%NHWC" + "--" can be used to terminate flag options and force all following + arguments to be treated as positional options + +e.g. + +.. code-block:: shell + + torchtrtc tests/modules/ssd_traced.jit.pt ssd_trt.ts "[(1,3,300,300); (1,3,512,512); (1, 3, 1024, 1024)]@f16%contiguous" -p f16 + +- To include a set of custom operators + +.. code-block:: shell + + torchtrtc tests/modules/ssd_traced.jit.pt ssd_trt.ts --custom-torch-ops= "[(1,3,300,300); (1,3,512,512); (1, 3, 1024, 1024)]@fp16%contiguous" -p f16 + + +- To include a set of custom converters + +.. code-block:: shell + + torchtrtc tests/modules/ssd_traced.jit.pt ssd_trt.ts --custom-converters= "[(1,3,300,300); (1,3,512,512); (1, 3, 1024, 1024)]@fp16%contiguous" -p f16 diff --git a/docs/v2.2.0/_sources/contributors/conversion.rst.txt b/docs/v2.2.0/_sources/contributors/conversion.rst.txt new file mode 100644 index 0000000000..f19fc5eba8 --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/conversion.rst.txt @@ -0,0 +1,53 @@ +.. _conversion: + +Conversion Phase +================== + +Once the graph has be simplified to a form thats easy to convert, we then set up a conversion context +to manage the construction of a TensorRT ``INetworkDefinition`` from the blocks nodes. The conversion context +records the set of converted nodes, block inputs and outputs and other information about the conversion +of the graph. This data is then used to help converters link together layers and also hold build time +information like weights required to construct the engine. After the context is created, the block +converter starts iterating through the list of nodes, for each node, the converter will look at its +inputs and assemble an array of resources to pass to the converter. Inputs can be in a couple of states: + +* The input is a block parameter + + * In this case the input should have already been stored in as an IValue in the + conversion context ``evaluated_value_map``. The conversion stage will add the IValue to the list of args for the + converter + +* The input is an output of a node that has already been converted + + * In this case the ITensor of the output has added to the ``value_tensor_map``, + The conversion stage will add the ITensor to the list of args for the converter + +* The input is from a node that produces a static value + + * There are nodes that produce static values, typically used to store parameters for operators, we need to + evaluate these nodes at conversion time to be able to convert a op. The conversion system will look for a node + evaluator in the evaluator registry and run it on the node. The IValue produced will be entered in the + conversion context ``evaluated_value_map`` and added to the list of args for the converter. If the node + to be evaluated takes inputs, the conversion stage will recursively resolve dependencies until the final + static value has been evaluated + +* The input is from a node that has not been converted + + * Torch-TensorRT will error out here + +Node Evaluation +----------------- +There are some nodes that contain static data and are resources for operations. These can be evaluated at +conversion time so that you can use those values when doing node conversion. In theory any node kind can have +a conversion time evaluator as long as it produces a static IValue, This IValue will be stored in the conversion +context so it can be consumed by any node that takes the evaluated node as an input. Common node types are +``prim::Constant`` which emits a constant and ``prim::ListConstruct`` which makes lists. + +Node Converters +---------------- + +Node converters map JIT nodes to layers or subgraphs of layers. They then associate outputs from the JIT graph +and the TRT graph together in the conversion context. This allows the conversion stage to assemble the inputs +for the next node. There are some cases where a node produces an output that is not a Tensor but a static result +from a calculation done on inputs which need to be converted first. In this case the converter may associate the outputs in +the ``evaluated_value_map`` instead of the ``value_tensor_map``. For more information take a look at: :ref:`writing_converters` diff --git a/docs/v2.2.0/_sources/contributors/dynamo_converters.rst.txt b/docs/v2.2.0/_sources/contributors/dynamo_converters.rst.txt new file mode 100644 index 0000000000..3238d609f3 --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/dynamo_converters.rst.txt @@ -0,0 +1,131 @@ +.. _dynamo_converters: + +Writing Dynamo Converters +============================= +The dynamo converter library in Torch-TensorRT is located in ``TensorRT/py/torch_tensorrt/dynamo/conversion``. + +Converter implementation +------------------------ + +Registration +^^^^^^^^^^^^^^^^ + +A converter is a function decrorated with ``torch_tensorrt.dynamo.dynamo_tensorrt_converter`` that follows the function signature: + + +.. code-block:: python + + @torch_tensorrt.dynamo.conversion.dynamo_tensorrt_converter(torch.ops.aten.leaky_relu.default) + def leaky_relu_converter( + ctx: torch_tensorrt.dynamo.conversion.ConversionCtx, + target: Target, + args: Tuple[Argument, ...], + kwargs: Dict[str, Argument], + name: str, + ) -> Union[tensorrt.ITensor, Sequence[tensorrt.ITensor]]: + + + +The decorator takes a number of arguments: + + * ``key``: Node target for which the converter is implemented for (for example, torch.ops.aten.leaky_relu.default) + * ``enabled``: Whether the converter should be enabled as a converter that can be used in the converter registry + * ``capability_validator``: A lambda that can take a ``torch.fx.Node`` and determine if the converter can properly handle this Node. If the validator returns ``False``, the subgraph partitioner will make sure this Node is run in PyTorch in the compiled graph. + * ``priority``: Allows developers to override existing converters in the converter registry + +All that is required for a converter is the key. + +The function body is responsible for taking the current state of the network and adding the next subgraph to perform the op specified in the decorator with TensorRT operations. +The function is provided arguments as the native PyTorch op would be provided with the added case of numpy arrays for frozen Tensor attributes or TensorRT ITensors which are ouput Tensors of previous nodes, correspoding to edges/output Tensors of intermediate operations in the graph. +To determine the types expected as well as the return type of the converter, look at the definition of the op being converted. In the case of ``aten`` operations, this file will be the source of truth: https://github.com/pytorch/pytorch/blob/main/aten/src/ATen/native/native_functions.yaml +Since many converters a developer may write are a composition of lower level operators, instead of needing to implement the converter in raw TensorRT, the ``torch_tensorrt.dynamo.conversion.impl`` subpackage contains many implementations of operations that can be chained to create a TensorRT subgraph. + + * ``ctx`` : The current state of the compiler. Converters primarily will manipulate ctx.net which is the ``tensorrt.INetworkDefinition`` being constructed. Additional metadata including user provided settings is available in this struct as well. + * ``target``: Target key in the ``call_module`` or ``call_function`` above. eg: ``torch.ops.aten_.leaky_relu.default``. Note that ``torch.ops.aten._leaky_relu`` is the ``OpOverloadPacket`` while ``torch.ops.aten_.leaky_relu.default`` is ``OpOverload``. + * ``args``: The arguments being passed to a particular Node (as collected by the ``torch_tensorrt.dynamo.conversion.TRTInterpreter``). These arguments along with the kwargs are to be used to construct a specific TensorRT subgraph representing the current node in the INetworkDefinition. + * ``kwargs``: The arguments being passed to a particular Node (as collected by the ``torch_tensorrt.dynamo.conversion.TRTInterpreter``). + * ``name``: String containing the name of the target + +The function is expected to return the ``tensorrt.ITensor`` or some collection of ``tensorrt.ITensor`` for use in the ``torch_tensorrt.dynamo.conversion.TRTInterpreter`` matching the output signature of the operation being converted + +Capability Validation +^^^^^^^^^^^^^^^^^^^^^^^ + +There are some converters which have special cases to be accounted for. In those cases, one should use ``capability_validators`` to register the converter using ``@dynamo_tensorrt_converter`` +We illustrate this through ``torch.ops.aten.embedding.default``. It has parameters - ``scale_grad_by_freq`` and ``sparse`` which are not currently supported by the implementation. +In such cases we can write validator ``embedding_param_validator`` which implements that given those paramters the converter is not supported and register the converter by + + +Type Contract +^^^^^^^^^^^^^^^ + +The function is expected to follow the type contract established by the signature. This includes accepting the union of valid PyTorch types + numpy arrays for constant tensors and TensorRT ITensors. +In the case that only a subset of types is supported in the converter, you can also add the ``torch_tensorrt.dynamo.conversion.converter_utils.enforce_tensor_types``, which allows you to specify a dictionary mapping between input positions and types that those inputs can take. Where possible the decorator will convert inputs to match these types prefering the order provided. +``int`` keys in the dictionary will refer to positional arguments in ``args``. ``str`` keys will refer to keyword arguments in ``kwargs``. + + +Example: ``Convolution`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The default convolution converter both uses a capability validator and type enforcement to prevent being run in unsupported situations. +The capability validator is run during partitioning to determine if a particular convolution node can be converted to TensorRT or needs to run in PyTorch. Here the validator ensures that the convolution is no greater than 3D. +The type enforcer will autocast before the converter is called, inputs to the supported type in the converter, thereby limiting the number of cases an author must handle. + +.. code-block:: python + + @dynamo_tensorrt_converter( + torch.ops.aten.convolution.default, capability_validator=lambda conv_node: conv_node.args[7] in ([0], [0, 0], [0, 0, 0]) + ) # type: ignore[misc] + @enforce_tensor_types( + { + 0: (TRTTensor,), + 1: (np.ndarray, torch.Tensor, TRTTensor), + 2: (np.ndarray, torch.Tensor, TRTTensor), + } + ) # type: ignore[misc] + def aten_ops_convolution( + ctx: ConversionContext, + target: Target, + args: Tuple[Argument, ...], + kwargs: Dict[str, Argument], + name: str, + ) -> Union[TRTTensor, Sequence[TRTTensor]]: + +Evaluators +------------------------ + +Some operations do not produce TensorRT subgraphs as a side-effect. These are termed evaluators. + + Example: ``operator.getitem`` + + Evaluators are categorized as so since they do not make any modification to the graph. This is implemented in ``py/torch_tensorrt/dynamo/conversion/op_evaluators.py``, with the corresponding ``capbility_validator``. + The opcode is ``operator.getitem``. + + +Operator Decomposition +----------------------- + +There are some converters which can be decomposed into suboperations in PyTorch and need not have seperate converter registration. +Such converters can be implemented via a decomposition + +Example: ``addmm`` +^^^^^^^^^^^^^^^^^^^^^^^ + +The decompositions are registered via ``register_torch_trt_decomposition`` decorator +We define ``addmm_replacement`` and replace it with the torch ops, which will have their corresponding converters called. + +.. code-block:: python + + @torch_tensorrt.dynamo.lowering.register_torch_trt_decomposition(torch.ops.aten.addmm) + def addmm_replacement( + input_: torch.Tensor, mat1: torch.Tensor, mat2: torch.Tensor, *, beta=1, alpha=1 + ) -> torch.Tensor: + return torch.add( + torch.mul(input_, beta), torch.mul(torch.matmul(mat1, mat2), alpha) + ) + +You can modify the decompositions run by editing ``torch_tensorrt.dynamo.lowering.torch_enabled_decompositions`` and ``torch_tensorrt.dynamo.lowering.torch_disabled_decompositions`` + + Note: ``torch_tensorrt.dynamo.lowering.torch_enabled_decompositions`` and ``torch_tensorrt.dynamo.lowering.torch_disabled_decompositions`` must be disjoint sets and that the decompositions already defined in ``torch_tensorrt.dynamo.lowering`` will take precedence over torch lowering ops. + +Much of the time, this is significantly easier than implementing a converter. So where possible, this is what should be tried first. \ No newline at end of file diff --git a/docs/v2.2.0/_sources/contributors/lowering.rst.txt b/docs/v2.2.0/_sources/contributors/lowering.rst.txt new file mode 100644 index 0000000000..a82f497ed2 --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/lowering.rst.txt @@ -0,0 +1,214 @@ +.. _lowering: + +Lowering Phase +=============== + +The lowering phase is made up out of passes which are operations which map a graph from a high level representation +to a lower level one. Each pass does something specific for instance inlining method calls. The idea is to +significantly reduce what the conversion phase needs to be able to handle when actually mapping to TensorRT. +We aim for closer to 1->1 op conversion vs looking for applicable subgraphs, limiting the number of converters and +reduce the scope of each converter. + +You can see the effects of each pass by setting the log level to ``Level::kGraph`` + +Passes Used +------------- + +EliminateCommonSubexpression +*********************************** + + `torch/csrc/jit/passes/common_subexpression_elimination.h `_ + +Removes common subexpressions in the graph + + + +Eliminate Dead Code +************************** + + `torch/csrc/jit/passes/dead_code_elimination.h `_ + +Dead code elimination will check if a node has side effects and not delete it if it does. + +Eliminate Exeception Or Pass Pattern +*************************************** + + `Torch-TensorRT/core/lowering/passes/exception_elimination.cpp `_ + +A common pattern in scripted modules are dimension gaurds which will throw execptions if +the input dimension is not what was expected. + +.. code-block:: none + + %1013 : bool = aten::ne(%1012, %24) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/batchnorm.py:248:11 + = prim::If(%1013) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/batchnorm.py:248:8 + block0(): + = prim::RaiseException(%23) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/batchnorm.py:249:12 + -> () + block1(): + -> () + +Since we are resolving all of this at compile time and there are no execptions in the TensorRT graph, we just remove it. + +Eliminate Redundant Gaurds +*************************************** + + `torch/csrc/jit/passes/guard_elimination.h `_ + +Eliminate redundant guards for ops whose outputs are fully determined by their inputs i.e. if inputs to such ops are +guarded we are allowed to remove a guard on ops' outputs + +Freeze Module +*************************************** + + `torch/csrc/jit/passes/freeze_module.h `_ + +Freeze attributes and inline constants and modules. Propogates constants in the graph. + +Fuse AddMM Branches +*************************************** + + `Torch-TensorRT/core/lowering/passes/fuse_addmm_branches.cpp `_ + +A common pattern in scripted modules is tensors of different dimensions use different constructions for implementing linear layers. We fuse these +different varients into a single one that will get caught by the Unpack AddMM pass. + +.. code-block:: none + + %ret : Tensor = prim::If(%622) + block0(): + %ret.1 : Tensor = aten::addmm(%self.fc.bias, %x9.1, %3677, %3, %3) + -> (%ret.1) + block1(): + %output.1 : Tensor = aten::matmul(%x9.1, %3677) + %output0.1 : Tensor = aten::add_(%output.1, %self.fc.bias, %3) + -> (%output0.1) + +We fuse this set of blocks into a graph like this: + +.. code-block:: none + + %ret : Tensor = aten::addmm(%self.fc.bias, %x9.1, %3677, %3, %3) + +Fuse Linear +*************************************** + + `torch/csrc/jit/passes/fuse_linear.h `_ + +Match the ``aten::linear`` pattern and fuse it into a single ``aten::linear`` +This pass fuse the addmm or matmul + add generated by JIT back to linear + +Fuse Flatten Linear +*************************************** + + `Torch-TensorRT/core/lowering/passes/fuse_flatten_linear.cpp `_ + +TensorRT implicity flattens input layers into fully connected layers when they are higher than 1D. So when there is a +``aten::flatten`` -> ``aten::linear`` pattern we remove the ``aten::flatten``. + +Lower Graph +*************************************** + + `torch/csrc/jit/passes/lower_graph.h `_ + +Given a graph with of a method which first argument is %self, lower it to a graph where +all attributes accesses are replaced with explicit inputs of the graph +(rather than results of prim::GetAttr executed on %self). Returns a tuple +(graph, parameters) where the last module.parameters.size() inputs to the +graph are the trainable parameters used in this method. The remaining inputs +are the true inputs to the function. + +Lower Tuples +*************************************** + + `torch/csrc/jit/passes/lower_tuples.h `_ + +* ``LowerSimpleTuples``: + +Removes tuples where TupleConstruct and TupleUnpack are matched but leaves tuples in place across if statements, loops, and as inputs/outputs + +* ``LowerAllTuples``: + +Removes _all_ tuples and raises an error if some cannot be removed, this is used by ONNX to ensure there are not tuples before conversion, but will not work on graphs whose inputs contain tuples. + +Module Fallback +***************** + + `Torch-TensorRT/core/lowering/passes/module_fallback.cpp `_ + +Module fallback consists of two lowering passes that must be run as a pair. The first pass is run before freezing to place delimiters in the graph around modules +that should run in PyTorch. The second pass marks nodes between these delimiters after freezing to signify they should run in PyTorch. + +* ``NotateModuleForFallback`` + +Places delimiting nodes around module calls pre freezing to signify where in the graph nodes should run in PyTorch + +* ``MarkNodesForFallback`` + +Looks for delimiters then marks all nodes between the delimiters to tell partitioning to run them in PyTorch + +Peephole Optimze +*************************************** + + `torch/csrc/jit/passes/peephole_optimze.h `_ + +The intent for this optimization pass is to catch all of the small, easy to catch peephole optimizations you might be interested in doing. + +Right now, it does: + - Eliminate no-op 'expand' nodes + - Simply x.t().t() to x + + +Remove Contiguous +*************************************** + + `Torch-TensorRT/core/lowering/passes/remove_contiguous.cpp `_ + +Removes contiguous operators since we are doing TensorRT memory is already contiguous. + + +Remove Dropout +*************************************** + + `Torch-TensorRT/core/lowering/passes/remove_dropout.cpp `_ + +Removes dropout operators since we are doing inference. + +Remove To +*************************************** + + `Torch-TensorRT/core/lowering/passes/remove_to.cpp `_ + +Removes ``aten::to`` operators that do casting, since TensorRT mangages it itself. It is important that this is one of the last passes run so that +other passes have a change to move required cast operators out of the main namespace. + +Unpack AddMM +*************************************** + + `Torch-TensorRT/core/lowering/passes/unpack_addmm.cpp `_ + +Unpacks ``aten::addmm`` into ``aten::matmul`` and ``aten::add_`` (with an additional ``trt::const`` +op to freeze the bias in the TensorRT graph). This lets us reuse the ``aten::matmul`` and ``aten::add_`` +converters instead of needing a dedicated converter. + +Unpack LogSoftmax +*************************************** + + `Torch-TensorRT/core/lowering/passes/unpack_log_softmax.cpp `_ + +Unpacks ``aten::logsoftmax`` into ``aten::softmax`` and ``aten::log``. This lets us reuse the +``aten::softmax`` and ``aten::log`` converters instead of needing a dedicated converter. + +Unroll Loops +*************************************** + + `torch/csrc/jit/passes/loop_unrolling.h `_ + +Unrolls the operations of compatable loops (e.g. sufficently short) so that you only have to go through the loop once. + +Replace Tile with Repeat +*************************************** + + `Torch-TensorRT/core/lowering/passes/tile_to_repeat.cpp `_ + +Removes dropout operators since we are doing inference. diff --git a/docs/v2.2.0/_sources/contributors/partitioning.rst.txt b/docs/v2.2.0/_sources/contributors/partitioning.rst.txt new file mode 100644 index 0000000000..8c83ddcadc --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/partitioning.rst.txt @@ -0,0 +1,241 @@ +.. _partitioning: + +Partitioning Phase +==================== + +The phase is optional and enabled by the user. It instructs the compiler to separate nodes into ones that should run in PyTorch and ones that should run in TensorRT. +Criteria for separation include: Lack of a converter, operator is explicitly set to run in PyTorch by the user or the node has a flag which tells partitioning to +run in PyTorch by the module fallback passes. + +On a high level, Torch-TensorRT partitioning phase does the following: + +* Segmentation. Go through the set of operators in order and verify if there is converter for each operator. Then, roughly separate the graph into parts that Torch-TensorRT can support and parts Torch-TensorRT cannot. + +* Dependency Analysis. For every to be compiled operator there is a "complete dependency graph", which means that every input can to traced back to an input as Tensor or TensorList. Go through all segments after segmentation then do dependency analysis to ensure that there are only Tensor/TensorList inputs and outputs for TensorRT segments. + +* Shape Analysis. For each segments, figure out the input and outputs shapes starting from the provided input shape from the user. Shapes can be calculated by running the graphs with JIT. + +* Conversion. Every TensorRT segments will be converted to TensorRT engine. This part is done in compiler.cpp, but it's still a phase in our partitioning process. + +* Stitching. Stitch all TensorRT engines with PyTorch nodes altogether. + +Here are the brief description of these functions of each file: + +PartitonInfo.h/.cpp +*********************************** + + `core/partitioning/PartitionInfo.h `_ + +The automatic fallback APIs that is used for partitioning. + + +SegmentedBlock.h/.cpp +*********************************** + + `core/partitioning/SegmentedBlock.h `_ + +The main data structures that is used to maintain information for each segments after segmentation. + + +shape_analysis.h/.cpp +*********************************** + + `core/partitioning/shape_analysis.h `_ + +Code implementation to get the shapes for each segments by running them in JIT. + + +partitioning.h/.cpp +*********************************** + `core/partitioning/partitioning.h `_ + +APIs and main code implementation for partitioning phase. + +Automatic Fallback +==================== + +To enable automatic fallback feature, you can set following attributes in Python: + +.. code-block:: none + + import torch + import torch_tensorrt as torchtrt + + ... + model = MyModel() + ts_model = torch.jit.script(model) + trt_model = torchtrt.ts.compile(model, **{ + ... + "min_block_size" : 3, + "torch_executed_ops": ["aten::add"], + "torch_executed_modules": [], + }) + +* enabled: By default automatic fallback will be off. It is enabled by setting it to True. +* min_block_size: The minimum number of consecutive operations that must satisfy to be converted to TensorRT. For example, if it's set to 3, then there must be 3 consecutive supported operators then this segments will be converted. +* forced_fallback_ops: A list of strings that will be the names of operations that the user explicitly want to be in PyTorch nodes. + + +.. code-block:: none + + #include "torch/script.h" + #include "torch_tensorrt/torch_tensorrt.h" + + ... + auto in = torch::randn({1, 3, 224, 224}, {torch::kCUDA}); + + auto mod = torch::jit::load("trt_ts_module.ts"); + auto input_sizes = std::vector{{in.sizes()}}; + torchtrt::ts::CompileSpec cfg(input_sizes); + cfg.min_block_size = 2; + cfg.torch_executed_ops.push_back("aten::relu"); + auto trt_mod = torchtrt::ts::compile(mod, cfg); + auto out = trt_mod.forward({in}); + +Dependency Aware Partitioning +==================== +During segmentation, Torch-TensorRT uses a dependency graph of the input TorchScript nodes to reduce the number of segments created. Consider this example from test Partitioning.SegmentModelWithDependencyAwareness in `tests/core/partitioning/test_segmentation.cpp `_ + +.. code-block:: none + + graph(%x : Tensor, %y : Tensor): + %3 : int = prim::Constant[value=0]() + %20 : int = prim::Constant[value=1]() + %add : Tensor = aten::add(%x, %y, %20) + %x_lgamma : Tensor = aten::lgamma(%x) + %mul : Tensor = aten::mul(%x, %y) + %y_lgamma : Tensor = aten::lgamma(%y) + %div : Tensor = aten::div(%x, %y) + %div_lgamma : Tensor = aten::lgamma(%div) + %27 : Tensor[] = prim::ListConstruct(%x_lgamma, %y_lgamma, %div_lgamma, %add, %mul) + %12 : Tensor = aten::cat(%27, %3) + return (%12) + +In this graph `aten::lgamma` is not supported by conversion and must be partitioned in a Torch fallback segment. If Torch-TensorRT uses a greedy segmentation strategy that traverses nodes in the input graph in order and gathers ops with the same target (TensorRT or Torch) into a segment until it encounters an op with a different target, the resulting partition includes 7 segments, many with just a single op. + +.. code-block:: none + + Segment Block @0: + Target: TensorRT + + Graph: graph(%x : Tensor, + %y : Tensor): + %3 : int = prim::Constant[value=1]() + %0 : Tensor = aten::add(%x, %y, %3) + return () + + Segment Block @1: + Target: Torch + + Graph: graph(%x : Tensor): + %0 : Tensor = aten::lgamma(%x) + return () + + Segment Block @2: + Target: TensorRT + + Graph: graph(%x : Tensor, + %y : Tensor): + %0 : Tensor = aten::mul(%x, %y) + return () + + Segment Block @3: + Target: Torch + + Graph: graph(%y : Tensor): + %0 : Tensor = aten::lgamma(%y) + return () + + Segment Block @4: + Target: TensorRT + + Graph: graph(%x : Tensor, + %y : Tensor): + %0 : Tensor = aten::div(%x, %y) + return () + + Segment Block @5: + Target: Torch + + Graph: graph(%1 : Tensor): + %0 : Tensor = aten::lgamma(%1) + return () + + Segment Block @6: + Target: TensorRT + + Graph: graph(%1 : Tensor, + %2 : Tensor, + %3 : Tensor, + %4 : Tensor, + %5 : Tensor): + %7 : int = prim::Constant[value=0]() + %0 : Tensor[] = prim::ListConstruct(%1, %2, %3, %4, %5) + %6 : Tensor = aten::cat(%0, %7) + return () + +This partition is valid, but the segmentation is suboptimal. These arithmetic ops and `aten::lgamma` ops are each split into their own segment as we alternate between Torch and TensorRT targets in the linear traversal of the graph. + +.. code-block:: none + + %add : Tensor = aten::add(%x, %y, %20) + %x_lgamma : Tensor = aten::lgamma(%x) + %mul : Tensor = aten::mul(%x, %y) + %y_lgamma : Tensor = aten::lgamma(%y) + %div : Tensor = aten::div(%x, %y) + %div_lgamma : Tensor = aten::lgamma(%div) + +Each of the arithmetic ops in this segment is only dependent on constants and the inputs `%x` and `%y`. The `aten::lgamma` ops are dependent on the inputs `%x`, `%y` and the output of the `aten::div`. This means that we could rewrite this portion of the input graph as below without changing the behavior of the graph. This reordered series of ops could be cleanly partitioned into just 2 segments using the greedy segmentation approach described above. + +.. code-block:: none + + %add : Tensor = aten::add(%x, %y, %20) + %mul : Tensor = aten::mul(%x, %y) + %div : Tensor = aten::div(%x, %y) + %x_lgamma : Tensor = aten::lgamma(%x) + %y_lgamma : Tensor = aten::lgamma(%y) + %div_lgamma : Tensor = aten::lgamma(%div) + +By adding awareness of the dependencies between ops to the basic greedy segmentation approach we can achieve the same partition without rewriting the graph. Now we will maintain both Torch and TensorRT targeted segments at the same time as we traverse the graph. We will only finalize a segment once we hit an op that is both dependent on an op in the segment and has a different target. This will allow the partition to create larger segments by reordering nodes across the segment boundary while guaranteeing that we will not modify the behavior of the graph by reordering nodes relative to their dependencies. +In this example we will collect the arithmetic ops in a TensorRT segment and the `aten::lgamma` ops in a Torch segment. When we encounter the `%div_lgamma : Tensor = aten::lgamma(%div)` op we can see it is dependent on `%div : Tensor = aten::div(%x, %y)` in the current TensorRT segment. This triggers finalization of the TensorRT segment containing the `aten::div` op to guarantee it will appear before its dependency in the final partition. The Torch segment containing the `aten::lgamma` op is finalized when we encounter the `prim::ListConstruct` op which targets TensorRT and is dependent on the results of the `aten::lgamma` ops. + +.. code-block:: none + + Segment Block @0: + Target: TensorRT + + Graph: graph(%x : Tensor, + %y : Tensor): + %3 : int = prim::Constant[value=1]() + %0 : Tensor = aten::add(%x, %y, %3) + %4 : Tensor = aten::mul(%x, %y) + %5 : Tensor = aten::div(%x, %y) + return () + + Segment Block @1: + Target: Torch + + Graph: graph(%x : Tensor, + %y : Tensor, + %5 : Tensor): + %0 : Tensor = aten::lgamma(%x) + %2 : Tensor = aten::lgamma(%y) + %4 : Tensor = aten::lgamma(%5) + return () + + Segment Block @2: + Target: TensorRT + + Graph: graph(%1 : Tensor, + %2 : Tensor, + %3 : Tensor, + %4 : Tensor, + %5 : Tensor): + %7 : int = prim::Constant[value=0]() + %0 : Tensor[] = prim::ListConstruct(%1, %2, %3, %4, %5) + %6 : Tensor = aten::cat(%0, %7) + return () + +In some cases this approach may create adjacent segments in the partition which have the same target. As a clean-up step we can consolidate these adjacent segments to further reduce the number of segments in the final partition. +The merge segments step identifies a list of segments that are adjacent in the graph, have the same target, and are not marked as `do_not_merge`. The nodes from these segments will be combined into a single new segment that will replace the merged segments in the partition. +The `do_not_merge` marking is used to prevent merging of segments created for conditional nodes and loops that are handled as special cases in graph stitching and should not be merged with adjacent segments of the same type. diff --git a/docs/v2.2.0/_sources/contributors/phases.rst.txt b/docs/v2.2.0/_sources/contributors/phases.rst.txt new file mode 100644 index 0000000000..e99af77faa --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/phases.rst.txt @@ -0,0 +1,46 @@ +Compiler Phases +---------------- + +.. toctree:: + :caption: Compiler Phases + :maxdepth: 1 + :hidden: + + lowering + partitioning + conversion + runtime + +Lowering +^^^^^^^^^^^ +:ref:`lowering` + +The lowering is made up of a set of passes (some from PyTorch and some specific to Torch-TensorRT) +run over the graph IR to map the large PyTorch opset to a reduced opset that is easier to convert to +TensorRT. + +Partitioning +^^^^^^^^^^^^^ +:ref:`partitioning` + +The phase is optional and enabled by the user. It instructs the compiler to separate nodes into ones that should run in PyTorch and ones that should run in TensorRT. +Criteria for separation include: Lack of a converter, operator is explicitly set to run in PyTorch by the user or the node has a flag which tells partitioning to +run in PyTorch by the module fallback passes. + +Conversion +^^^^^^^^^^^ +:ref:`conversion` + +In the conversion phase we traverse the lowered graph and construct an equivalent TensorRT graph. +The conversion phase is made up of three main components, a context to manage compile time data, +a evaluator library which will execute operations that can be resolved at compile time and a converter +library which maps an op from JIT to TensorRT. + +Compilation and Runtime +^^^^^^^^^^^^^^^^^^^^^^^^ +:ref:`runtime` + +The final compilation phase constructs a TorchScript program to run the converted TensorRT engine. It +takes a serialized engine and instantiates it within a engine manager, then the compiler will +build out a JIT graph that references this engine and wraps it in a module to return to the user. +When the user executes the module, the JIT program run in the JIT runtime extended by Torch-TensorRT with the data providied from the user. diff --git a/docs/v2.2.0/_sources/contributors/runtime.rst.txt b/docs/v2.2.0/_sources/contributors/runtime.rst.txt new file mode 100644 index 0000000000..23d83b6db2 --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/runtime.rst.txt @@ -0,0 +1,85 @@ +.. _execution: + +Runtime Phase +================ + +The Runtime phase is responsible for constructing self standing TorchScript graphs with embedded TensorRT engines and serving as the runtime +when these engines are called. The main interface accepts a serialized TensorRT engine. The execution phase +will deserialize and wrap this engine in a class which maintains a execution context for each engine +and some metadata about its inputs and outputs and is compatable with the TorchScript interpreter so that +it can be moved around and used like other TorchScript IValues. The engine is run by providing it and inputs +to the ``tensorrt::execute_engine`` operator which will take the engine and its inputs and return the results of engine exeuction. + + +Background +------------ +PyTorch JIT's runtime is based around a stack machine, all operators pop off arguments from the stack, pass them to +some implementation of the operator then push results back onto the stack. The actual elements of the stack +are ``torch::jit::IValues``, the same type we evaluate in the conversion phase (the realization of the abstract +torch::jit::Value type). + +TensorRT Engine Executor Op +---------------------------- + +When the Torch-TensorRT is loaded, it registers an operator in the PyTorch JIT operator library called +``trt::execute_engine(Tensor[] inputs, __torch__.torch.classes.tensorrt.Engine engine) -> Tensor[]`` which takes an +instantiated engine and list of inputs. Compiled graphs store this engine in an attribute so that it is portable and serializable. +When the op is called, an instnantiated engine and input tensors are popped off the runtime stack. These inputs are passed into a generic engine execution function which +will run the tensors through the TensorRT engine and return new tensors as results. These tensors are pushed on to the +stack so that the next op whatever it is can use it. + +Constructing the Resulting Graph +----------------------------------- + +Once the engine is deserialized and instantiated, the compiler will construct a graph that will execute the engine when the module is called. +Here is an example: + +.. code-block:: + + graph(%self_1 : __torch__.torchvision.models.resnet.___torch_mangle_4847.ResNet_trt, + %input_0 : Tensor): + %1 : __torch__.torch.classes.tensorrt.Engine = prim::GetAttr[name="__torch___torchvision_models_resnet____torch_mangle_4847_ResNet_trt_engine"](%self_1) + %3 : Tensor[] = prim::ListConstruct(%input_0) + %4 : Tensor[] = trt::execute_engine(%3, %1) + %5 : Tensor = prim::ListUnpack(%4) + return (%5) + +You can see the engine attribute in the graph and the ``trt::execute_engine`` op taking a list of input tensors and an engine in +and produces a list of output tensors which is returned. When ``forward`` is called on the module this graph is executed, thereby +running the TensorRT engine. + +In the case of multiple outputs, the compiled graph may repack output tensors into a Tuple to return back to the user. + +.. code-block:: + + graph(%self_1 : __torch__.PyTorch.Detection.SSD.src.model.SSD300_trt, + %input_0 : Tensor): + %1 : __torch__.torch.classes.tensorrt.Engine = prim::GetAttr[name="__torch___PyTorch_Detection_SSD_src_model_SSD300_trt_engine"](%self_1) + %3 : Tensor[] = prim::ListConstruct(%input_0) + %4 : Tensor[] = trt::execute_engine(%3, %1) + %5 : Tensor, %6 : Tensor = prim::ListUnpack(%4) + %7 : (Tensor, Tensor) = prim::TupleConstruct(%5, %6) + return (%7) + +Serialization and Deserialization +---------------------------------- + +Serialization and deserialization of TensorRT engines embedded in TorchScript graphs are handled by the holder class for the engine and TorchBind. +When a TorchScript module is saved, the pickler will run serilization on the cuda engine and store the serialized engine in the zip file created. +When deserializing, the depickler will call a constructor for the engine holder class with the serialized engine so that it can be set up again for +execution. + +ABI Versioning and Serialization Format +========================================= + +Torch-TensorRT programs are standard TorchScript with TensorRT engines as objects embedded in the graph. Therefore there is a serialization format +for the TensorRT engines. The format for Torch-TensorRT serialized programs are versioned with an "ABI" version which tells the runtime about runtime compatibility. + +> Current ABI version is 3 + +The format is a vector of serialized strings. They encode the following information + +* ABI Version for the program +* Name of the TRT engine +* Device information: Includes the target device the engine was built on, SM capability and other device information. This information is used at deserialization time to select the correct device to run the engine +* Serialized TensorRT engine diff --git a/docs/v2.2.0/_sources/contributors/system_overview.rst.txt b/docs/v2.2.0/_sources/contributors/system_overview.rst.txt new file mode 100644 index 0000000000..d16697e3a3 --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/system_overview.rst.txt @@ -0,0 +1,29 @@ +.. _system_overview: + +System Overview +================ + +Torch-TensorRT is primarily a C++ Library with a Python API planned. We use Bazel as our build system and target Linux x86_64 and +Linux aarch64 (only natively) right now. The compiler we use is GCC 7.5.0 and the library is untested with compilers before that +version so there may be compilation errors if you try to use an older compiler. + +The repository is structured into: + +* core: Main compiler source code +* cpp: C++ API +* tests: tests of the C++ API, the core and converters +* py: Python API +* notebooks: Example applications built with Torch-TensorRT +* docs: Documentation +* docsrc: Documentation Source +* third_party: BUILD files for dependency libraries +* toolchains: Toolchains for different platforms + + +The C++ API is unstable and subject to change until the library matures, though most work is done under the hood in the core. + +The core has a couple major parts: The top level compiler interface which coordinates ingesting a module, lowering, +converting and generating a new module and returning it back to the user. There are the three main phases of the +compiler, the lowering phase, the conversion phase, and the execution phase. + +.. include:: phases.rst diff --git a/docs/v2.2.0/_sources/contributors/ts_converters.rst.txt b/docs/v2.2.0/_sources/contributors/ts_converters.rst.txt new file mode 100644 index 0000000000..3266354ad8 --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/ts_converters.rst.txt @@ -0,0 +1,129 @@ +.. _ts_converters: + +Writing TorchScript Converters +================================= + +Background +------------ + +In the JIT IR, operations are represented as nodes in a graph. A node has inputs and outputs, represented by ``torch::jit::Values`` +which are typed abstract representation of data flowing into and out of a node. TensorRT represents its graph though the +use of ``nvinfer1::ILayers`` and ``nvinfer1::ITensors`` which are its analogues to nodes and values. The goal of +converters create new ILayers and subgraphs that do operation specified by the node and associate produced ITensors +and Values together. + +Converters +------------ + +Converters should be functions which will use a list of inputs (either ``nvinfer1::ITensors`` or ``torch::jit::IValues``) to +construct an equivalent layer to the LibTorch op. + +Converters can be registered using the ``RegisterNodeConversionPatterns`` helper class where you instantiate a +RegisterNodeConversionPatterns object and call the pattern function on it (like below) which takes a string +which describes the function schema of the op that will cause the converter to be run and a lambda or function +which will do the actual conversion: + + Note the pattern function can be chained + +.. code-block:: c++ + + auto acthardtanh TORCHTRT_UNUSED = RegisterNodeConversionPatterns() + .pattern({ + "aten::hardtanh(Tensor self, Scalar min_val=-1, Scalar max_val=1) -> (Tensor)", + [](ConversionCtx* ctx, const torch::jit::Node* n, args& args) -> bool { + auto in = args[0].ITensor(); + auto min = args[1].unwrapToDouble(); + auto max = args[2].unwrapToDouble(); + + auto new_layer = ctx->net->addActivation(*in, nvinfer1::ActivationType::kCLIP); + TORCHTRT_CHECK(new_layer, "Unable to create layer for aten::hardtanh"); + + new_layer->setAlpha(min); + new_layer->setBeta(max); + + new_layer->setName(util::node_info(n).c_str()); + auto out_tensor = ctx->AssociateValueAndTensor(n->outputs()[0], new_layer->getOutput(0)); + + LOG_DEBUG("Output shape: " << out_tensor->getDimensions()); + return true; + } + }); + + +Converter Contract +---------------------- + +What is guaranteed to converters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. In the args there will be an entry for each node input value, either a ITensor or IValue +2. Inputs will be provided in order according to the function schema + +Responsibilities of a converter +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. Args must be guaranteed to be a type to unwrap the Arg union without checking, typically input tensor arguments can be expected to be ITensors +2. Any weights or static values must guaranteed to be valid until the end of conversion time + + a. A helpful tool is the Weights helper class described below + +3. Converters are expected to produce an IValue or ITensor for each output of a node. The compiler will check this and produce warnings if there are Values that don't have associated ITensors or IValues. +4. Outputs must be annotated + + a. There must be an association between a JIT nodes output values and the new TRT layers output tensors in the ``value_tensor_map`` in the conversion context + +5. Name your layers + + a. Its much easier to debug when we can track which layers and nodes correspond with each other. The system we are currently using is to use the "node info" of the node as the name of the layer + +6. Name your tensors + + a. Use the output value debug name as the name for the new ITensor (again for debugging) + +Conversion Context +-------------------- + +The conversion context maintains the state of conversion, it manages the Network Definition, two maps +one that stores associations between Values and IValues (the evaluated_value_map) and one that stores +associations between Values and ITensors, and any sort of memory that needs to live until the end of +conversion. The main apis that you will interface with in converters is directly accessing the network +definition to add layers ``ctx->net`` and data association functions ``ctx->AssociateValueAndTensor()`` +and ``ctx->AssociateValueAndIValue()``, which you will use to add layers to the TRT layers and log +pairs of node outputs and static values or TensorRT layer outputs. + +Args +------- + +Arguments provided to the converter are inspectable unions of ``nvinfer1::ITensors`` and ``torch::jit::IValues`` (i.e. +abstract dataflow in the TensorRT graph and static values). You are guaranteed that you will have some +argument for each input value for the node. They are provided in the order of the function schema. +It can be expected that inputs (meaning the parameters that would be passed into the forward +function of a module in PyTorch) will be ITensors but the Arg class also has mechanisms to inspect arguments safely +before unwrapping if you are unsure. Args also have deep unwrap methods that let you get straight to the +underlying data in an IValue if you know it's safe. You can also pass in a fallback value if there is a +chance the IValue is None. IValues have been extended to be able to hold a wrapper around ITensors only in the case of TensorLists. +You can get an ITensor from an IValue by a pattern similar to this: ``ivalue.toCustomClass()->tensor()``. +You can tell if an IValue contains a Tensor or an ITensor by using ``ivalue.isTensor()`` or ``ivalue.isCustomClass()``. + + +Weights +-------------- + +Weights are used during build time, so any weights need to be guaranteed to live until the end of the conversion phase. +TensorRT also uses its own weights structure to hold the weights. There is a wrapper around this class available +to converts which abstracts a lot of this. + +The weights wrapper class can accept either ``at::Tensors`` or singular values (right now). You also need to pass the +conversion context when constructing these weights because internally the weights class will allocate memory managed +by the conversion context to store a copy of the tensor data. This data gets freed when the conversion context +destructor gets destroyed so converters don't really need to think about it. + +There is metadata generated from the shape of the input data which becomes useful in interfacing with TensorRT, such +as number of input maps, number of output maps and kernel shape. + +Other advice +-------------- + +You have the benefit of the full aten library when dealing with weights and other static values. This means that you +can do quite a bit of work during conversion time to produce efficient conversion. A good example is batch_norm +converter where the converter does fusion of operations with PyTorch before creating the TensorRT layer. diff --git a/docs/v2.2.0/_sources/contributors/useful_links.rst.txt b/docs/v2.2.0/_sources/contributors/useful_links.rst.txt new file mode 100644 index 0000000000..d5903a16b0 --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/useful_links.rst.txt @@ -0,0 +1,34 @@ +.. _useful_links: + +Useful Links for Torch-TensorRT Development +============================================== + +TensorRT Available Layers and Expected Dimensions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* https://docs.nvidia.com/deeplearning/sdk/tensorrt-support-matrix/index.html#layers-matrix + +TensorRT C++ Documentation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* https://docs.nvidia.com/deeplearning/tensorrt/api/c_api/index.html + +TensorRT Python Documentation (Sometimes easier to read) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/python_api/index.html + +PyTorch Functional API +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* https://pytorch.org/docs/stable/nn.functional.html + +PyTorch native_ops +^^^^^^^^^^^^^^^^^^^^^ + +* https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/native/native_functions.yaml + +PyTorch IR Documentation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* https://github.com/pytorch/pytorch/blob/master/torch/csrc/jit/OVERVIEW.md diff --git a/docs/v2.2.0/_sources/contributors/writing_dynamo_aten_lowering_passes.rst.txt b/docs/v2.2.0/_sources/contributors/writing_dynamo_aten_lowering_passes.rst.txt new file mode 100644 index 0000000000..4c29bc9b75 --- /dev/null +++ b/docs/v2.2.0/_sources/contributors/writing_dynamo_aten_lowering_passes.rst.txt @@ -0,0 +1,109 @@ +.. _writing_dynamo_aten_lowering_passes: + +Writing Dynamo ATen Lowering Passes +=================== + +Basics of a Lowering Pass +------------ + +ATen lowering passes are Python functions which take as input a graph of ATen operators, apply some desired modification such as operator coalescing/fusion, operator replacement, subgraph rewriting, custom operator insertion, or other operation on a `torch.fx.GraphModule`, then return the modified graph to the caller. These lowering passes generally modify the graph in-place and return the same input object. + +Lowering Pass Requirements +------------ + +An ATen lowering pass function in Torch-TRT must satisfy two requirements: +- The function must take as input a `torch.fx.GraphModule` and a sequence of torch Tensors, `Sequence[torch.Tensor]`, and return the lowered `torch.fx.GraphModule` +- The function must leave the graph in a valid and invoke-able state, including performing any necessary linting and recompilation + +See this link for information on `Graph Manipulations `_ in FX. See below for an example of a lowering pass which repairs graphs that have inputs which are also outputs, a disallowed configuration for TRT Engines. + +Example Lowering Pass +------------ + +.. code-block:: python + + def repair_input_as_output(gm: torch.fx.GraphModule, sample_inputs: Sequence[torch.Tensor]) -> torch.fx.GraphModule: + """Repair scenarios where inputs are also outputs of the graph + + TRT does not allow such cases, so we insert a clone (identity) layer + """ + modified_graph = False + + # Extract graph placeholder Tensors + placeholders = [ + node + for node in gm.graph.nodes + if ( + node.op == "placeholder" + and isinstance(node.type, type) + and issubclass(node.type, torch.Tensor) + ) + ] + + for placeholder in placeholders: + # If any placeholder has any users which are direct graph outputs + if len(placeholder.users) >= 1 and any( + user.op == "output" for user in placeholder.users + ): + modified_graph = True + + # Get direct graph outputs which are direct uses of placeholders + direct_outputs = [user for user in placeholder.users if user.op == "output"] + + # Insert clone node for placeholder to ensure + # placeholder is not a direct output + with gm.graph.inserting_after(placeholder): + cloned_placeholder = gm.graph.call_function( + torch.ops.aten.clone.default, + args=(placeholder,), + ) + + # Replace placeholder as output with cloned version + for output in direct_outputs: + output.replace_input_with(placeholder, cloned_placeholder) + + # If the graph was modified, clean up the graph and ensure it is up-to-date + if modified_graph: + gm.graph.eliminate_dead_code() + gm.graph.lint() + gm.recompile() + logger.debug(f"Graph after repair_input_as_output:\n{gm.graph}") + + return gm + + +Registering Lowering Passes +---------------------- + +Lowering passes are currently registered in `py/torch_tensorrt/dynamo/lowering/passes/__init__.py`, using the `torch.fx.passes.pass_manager.PassManager` utility to assemble the list of passes in a desired order. New passes added directly to that list will be applied to graphs in the Torch-TensorRT `torch.compile` backend. Currently, we offer an ATen lowering pass registration decorator for convenience, which can be invoked either directly, or with the optional `index` keyword argument which controls where in the pass list the lowering pass will be inserted. + +For instance, to insert the pass at the default location (end of the list), the following code can be used: + +.. code-block:: python + + @_aten_lowering_pass + def my_custom_pass(gm: torch.fx.GraphModule, sample_inputs: Sequence[torch.Tensor]) -> torch.fx.GraphModule: + ... + +Alternatively, to insert the pass at a custom index (such as the front of the list) in the passlist, the following code can be used: + +.. code-block:: python + + @_aten_lowering_pass(index=0) + def my_custom_pass(gm: torch.fx.GraphModule, sample_inputs: Sequence[torch.Tensor]) -> torch.fx.GraphModule: + ... + +There are also provided utilities in `torch_tensorrt.dynamo.lowering.passes` for displaying the currently-available lowering pass list, applying those passes to an arbitrary `torch.fx.GraphModule`, and removing the lowering pass at a specific index. + +.. code-block:: python + + # Print all lowering passes in the list + print(dump_lowering_passes()) + + # Apply lowering passes to a GraphModule + apply_lowering_passes(graph_module, sample_inputs) + + # Remove the lowering pass at index 1 + _remove_lowering_pass(index=1) + +**Note:** The above APIs are subject to change, as the lowering pass system evolves. diff --git a/docs/v2.2.0/_sources/dynamo/dynamo_export.rst.txt b/docs/v2.2.0/_sources/dynamo/dynamo_export.rst.txt new file mode 100644 index 0000000000..7a17cd5df2 --- /dev/null +++ b/docs/v2.2.0/_sources/dynamo/dynamo_export.rst.txt @@ -0,0 +1,75 @@ +.. _dynamo_export: + +Compiling Exported Programs with Torch-TensorRT +============================================= +.. currentmodule:: torch_tensorrt.dynamo + +.. automodule:: torch_tensorrt.dynamo + :members: + :undoc-members: + :show-inheritance: + +Pytorch 2.1 introduced ``torch.export`` APIs which +can export graphs from Pytorch programs into ``ExportedProgram`` objects. Torch-TensorRT dynamo +frontend compiles these ``ExportedProgram`` objects and optimizes them using TensorRT. Here's a simple +usage of the dynamo frontend + +.. code-block:: python + + import torch + import torch_tensorrt + + model = MyModel().eval().cuda() + inputs = [torch.randn((1, 3, 224, 224), dtype=torch.float32).cuda()] + exp_program = torch.export.export(model, tuple(inputs)) + trt_gm = torch_tensorrt.dynamo.compile(exp_program, inputs) # Output is a torch.fx.GraphModule + trt_gm(*inputs) + +.. note:: ``torch_tensorrt.dynamo.compile`` is the main API for users to interact with Torch-TensorRT dynamo frontend. The input type of the model should be ``ExportedProgram`` (ideally the output of ``torch.export.export`` or ``torch_tensorrt.dynamo.trace`` (discussed in the section below)) and output type is a ``torch.fx.GraphModule`` object. + +Customizeable Settings +---------------------- + +There are lot of options for users to customize their settings for optimizing with TensorRT. +Some of the frequently used options are as follows: + +* ``inputs`` - For static shapes, this can be a list of torch tensors or `torch_tensorrt.Input` objects. For dynamic shapes, this should be a list of ``torch_tensorrt.Input`` objects. +* ``enabled_precisions`` - Set of precisions that TensorRT builder can use during optimization. +* ``truncate_long_and_double`` - Truncates long and double values to int and floats respectively. +* ``torch_executed_ops`` - Operators which are forced to be executed by Torch. +* ``min_block_size`` - Minimum number of consecutive operators required to be executed as a TensorRT segment. + +The complete list of options can be found `here `_ + +.. note:: We do not support INT precision currently in Dynamo. Support for this currently exists in our Torchscript IR. We plan to implement similar support for dynamo in our next release. + +Under the hood +-------------- + +Under the hood, ``torch_tensorrt.dynamo.compile`` performs the following on the graph. + +* Lowering - Applies lowering passes to add/remove operators for optimal conversion. +* Partitioning - Partitions the graph into Pytorch and TensorRT segments based on the ``min_block_size`` and ``torch_executed_ops`` field. +* Conversion - Pytorch ops get converted into TensorRT ops in this phase. +* Optimization - Post conversion, we build the TensorRT engine and embed this inside the pytorch graph. + +Tracing +------- + +``torch_tensorrt.dynamo.trace`` can be used to trace a Pytorch graphs and produce ``ExportedProgram``. +This internally performs some decompositions of operators for downstream optimization. +The ``ExportedProgram`` can then be used with ``torch_tensorrt.dynamo.compile`` API. +If you have dynamic input shapes in your model, you can use this ``torch_tensorrt.dynamo.trace`` to export +the model with dynamic shapes. Alternatively, you can use ``torch.export`` `with constraints `_ directly as well. + +.. code-block:: python + + import torch + import torch_tensorrt + + inputs = [torch_tensorrt.Input(min_shape=(1, 3, 224, 224), + opt_shape=(4, 3, 224, 224), + max_shape=(8, 3, 224, 224), + dtype=torch.float32)] + model = MyModel().eval() + exp_program = torch_tensorrt.dynamo.trace(model, inputs) diff --git a/docs/v2.2.0/_sources/dynamo/torch_compile.rst.txt b/docs/v2.2.0/_sources/dynamo/torch_compile.rst.txt new file mode 100644 index 0000000000..6e969092ae --- /dev/null +++ b/docs/v2.2.0/_sources/dynamo/torch_compile.rst.txt @@ -0,0 +1,110 @@ +.. _torch_compile: + +TensorRT Backend for ``torch.compile`` +====================================================== +.. currentmodule:: torch_tensorrt.dynamo + +.. automodule:: torch_tensorrt.dynamo + :members: + :undoc-members: + :show-inheritance: + +This guide presents the Torch-TensorRT `torch.compile` backend: a deep learning compiler which uses TensorRT to accelerate JIT-style workflows across a wide variety of models. + +Key Features +-------------------------------------------- + +The primary goal of the Torch-TensorRT `torch.compile` backend is to enable Just-In-Time compilation workflows by combining the simplicity of `torch.compile` API with the performance of TensorRT. Invoking the `torch.compile` backend is as simple as importing the `torch_tensorrt` package and specifying the backend: + +.. code-block:: python + + import torch_tensorrt + ... + optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False) + +.. note:: Many additional customization options are available to the user. These will be discussed in further depth in this guide. + +The backend can handle a variety of challenging model structures and offers a simple-to-use interface for effective acceleration of models. Additionally, it has many customization options to ensure the compilation process is fitting to the specific use case. + +Customizeable Settings +----------------- +.. autoclass:: CompilationSettings + +Custom Setting Usage +^^^^^^^^^^^^^^^^^ +.. code-block:: python + + import torch_tensorrt + ... + optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False, + options={"truncate_long_and_double": True, + "precision": torch.half, + "debug": True, + "min_block_size": 2, + "torch_executed_ops": {"torch.ops.aten.sub.Tensor"}, + "optimization_level": 4, + "use_python_runtime": False,}) + +.. note:: Quantization/INT8 support is slated for a future release; currently, we support FP16 and FP32 precision layers. + +Compilation +----------------- +Compilation is triggered by passing inputs to the model, as so: + +.. code-block:: python + + import torch_tensorrt + ... + # Causes model compilation to occur + first_outputs = optimized_model(*inputs) + + # Subsequent inference runs with the same, or similar inputs will not cause recompilation + # For a full discussion of this, see "Recompilation Conditions" below + second_outputs = optimized_model(*inputs) + +After Compilation +----------------- +The compilation object can be used for inference within the Python session, and will recompile according to the recompilation conditions detailed below. In addition to general inference, the compilation process can be a helpful tool in determining model performance, current operator coverage, and feasibility of serialization. Each of these points will be covered in detail below. + +Model Performance +^^^^^^^^^^^^^^^^^ +The optimized model returned from `torch.compile` is useful for model benchmarking since it can automatically handle changes in the compilation context, or differing inputs that could require recompilation. When benchmarking inputs of varying distributions, batch sizes, or other criteria, this can save time. + +Operator Coverage +^^^^^^^^^^^^^^^^^ +Compilation is also a useful tool in determining operator coverage for a particular model. For instance, the following compilation command will display the operator coverage for each graph, but will not compile the model - effectively providing a "dryrun" mechanism: + +.. code-block:: python + + import torch_tensorrt + ... + optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False, + options={"debug": True, + "min_block_size": float("inf"),}) + +If key operators for your model are unsupported, see :ref:`dynamo_conversion` to contribute your own converters, or file an issue here: https://github.com/pytorch/TensorRT/issues. + +Feasibility of Serialization +^^^^^^^^^^^^^^^^^ +Compilation can also be helpful in demonstrating graph breaks and the feasibility of serialization of a particular model. For instance, if a model has no graph breaks and compiles successfully with the Torch-TensorRT backend, then that model should be compileable and serializeable via the `torch_tensorrt` Dynamo IR, as discussed in :ref:`dynamic_shapes`. To determine the number of graph breaks in a model, the `torch._dynamo.explain` function is very useful: + +.. code-block:: python + + import torch + import torch_tensorrt + ... + explanation = torch._dynamo.explain(model)(*inputs) + print(f"Graph breaks: {explanation.graph_break_count}") + optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False, options={"truncate_long_and_double": True}) + +Dynamic Shape Support +----------------- + +The Torch-TensorRT `torch.compile` backend will currently require recompilation for each new batch size encountered, and it is preferred to use the `dynamic=False` argument when compiling with this backend. Full dynamic shape support is planned for a future release. + +Recompilation Conditions +----------------- + +Once the model has been compiled, subsequent inference inputs with the same shape and data type, which traverse the graph in the same way will not require recompilation. Furthermore, each new recompilation will be cached for the duration of the Python session. For instance, if inputs of batch size 4 and 8 are provided to the model, causing two recompilations, no further recompilation would be necessary for future inputs with those batch sizes during inference within the same session. Support for engine cache serialization is planned for a future release. + +Recompilation is generally triggered by one of two events: encountering inputs of different sizes or inputs which traverse the model code differently. The latter scenario can occur when the model code includes conditional logic, complex loops, or data-dependent-shapes. `torch.compile` handles guarding in both of these scenario and determines when recompilation is necessary. diff --git a/docs/v2.2.0/_sources/fx/getting_started_with_fx_path.rst.txt b/docs/v2.2.0/_sources/fx/getting_started_with_fx_path.rst.txt new file mode 100644 index 0000000000..ca630b7a9b --- /dev/null +++ b/docs/v2.2.0/_sources/fx/getting_started_with_fx_path.rst.txt @@ -0,0 +1,333 @@ +.. _getting_started_with_fx: + +Torch-TensorRT (FX Frontend) User Guide +======================== +Torch-TensorRT (FX Frontend) is a tool that can convert a PyTorch model through ``torch.fx`` to an +TensorRT engine optimized targeting running on Nvidia GPUs. TensorRT is the inference engine +developed by NVIDIA which composed of various kinds of optimization including kernel fusion, +graph optimization, low precision, etc.. This tool is developed in Python environment which allows this +workflow to be very accessible to researchers and engineers. There are a few stages that a +user want to use this tool and we will introduce them here. + +> Torch-TensorRT (FX Frontend) is in ``Beta`` and currently it is recommended to work with PyTorch nightly. + +.. code-block:: shell + + # Test an example by + $ python py/torch_tensorrt/fx/example/lower_example.py + + +Converting a PyTorch Model to TensorRT Engine +--------------------------------------------- +In general, users are welcome to use the ``compile()`` to finish the conversion from a model to tensorRT engine. It is a +wrapper API that consists of the major steps needed to finish this converison. Please refer to an example usage in ``lower_example.py`` file under ``examples/fx``. + +.. code-block:: shell + + def compile( + module: nn.Module, + input, + max_batch_size=2048, + max_workspace_size=33554432, + explicit_batch_dimension=False, + lower_precision=LowerPrecision.FP16, + verbose_log=False, + timing_cache_prefix="", + save_timing_cache=False, + cuda_graph_batch_size=-1, + dynamic_batch=True, + ) -> nn.Module: + + """ + Takes in original module, input and lowering setting, run lowering workflow to turn module + into lowered module, or so called TRTModule. + + Args: + module: Original module for lowering. + input: Input for module. + max_batch_size: Maximum batch size (must be >= 1 to be set, 0 means not set) + max_workspace_size: Maximum size of workspace given to TensorRT. + explicit_batch_dimension: Use explicit batch dimension in TensorRT if set True, otherwise use implicit batch dimension. + lower_precision: lower_precision config given to TRTModule. + verbose_log: Enable verbose log for TensorRT if set True. + timing_cache_prefix: Timing cache file name for timing cache used by fx2trt. + save_timing_cache: Update timing cache with current timing cache data if set to True. + cuda_graph_batch_size: Cuda graph batch size, default to be -1. + dynamic_batch: batch dimension (dim=0) is dynamic. + Returns: + A torch.nn.Module lowered by TensorRT. + """ + +In this section, we will go through an example to illustrate the major steps that fx path uses. +Users can refer to ``fx2trt_example.py`` file in ``examples/fx``. + +* **Step 1: Trace the model with acc_tracer** +Acc_tracer is a tracer inheritated from FX tracer. It comes with args normalizer to convert all args to kwargs and pass to TRT converters. + +.. code-block:: shell + + import torch_tensorrt.fx.tracer.acc_tracer.acc_tracer as acc_tracer + + # Build the model which needs to be a PyTorch nn.Module. + my_pytorch_model = build_model() + + # Prepare inputs to the model. Inputs have to be a List of Tensors + inputs = [Tensor, Tensor, ...] + + # Trace the model with acc_tracer. + acc_mod = acc_tracer.trace(my_pytorch_model, inputs) + +*Common Errors:* + +symbolically traced variables cannot be used as inputs to control flow +This means the model contains dynamic control flow. Please refer to section “Dynamic Control Flow” in `FX guide `_. + +* **Step 2: Build TensorRT engine** +There are `two different modes `_ for how TensorRT handles batch dimension, explicit batch dimension and implicit batch dimension. This mode was used by early versions of TensorRT, and is now deprecated but continues to be supported for backwards compatibility. In explicit batch mode, all dimensions are explicit and can be dynamic, that is their length can change at execution time. Many new features, such as dynamic shapes and loops, are available only in this mode. User can still choose to use implicit batch mode when they set ``explicit_batch_dimension=False`` in ``compile()``. We do not recommend to use it since it will lack of support in future TensorRT versions. + +Explicit batch is the default mode and it must be set for dynamic shape. For most of vision task, user can choose to enable ``dynamic_batch`` in ``compile()`` if they want to get the similar effects as implicit mode where only batch dimension changes. It has some requirements: +1. Shapes of inputs, outputs and activations are fixed except batch dimension. +2. Inputs, outputs and activations have batch dimension as the major dimension. +3. All the operators in the model do not modify batch dimension (permute, transpose, split, etc.) or compute over batch dimension (sum, softmax, etc.). + +For examples of the last path, if we have a 3D tensor t shaped as (batch, sequence, dimension), operations such as torch.transpose(0, 2). If any of these three are not satisfied, we’ll need to specify InputTensorSpec as inputs with dynamic range. + +.. code-block:: shell + + import deeplearning.trt.fx2trt.converter.converters + from torch.fx.experimental.fx2trt.fx2trt import InputTensorSpec, TRTInterpreter + + # InputTensorSpec is a dataclass we use to store input information. + # There're two ways we can build input_specs. + # Option 1, build it manually. + input_specs = [ + InputTensorSpec(shape=(1, 2, 3), dtype=torch.float32), + InputTensorSpec(shape=(1, 4, 5), dtype=torch.float32), + ] + # Option 2, build it using sample_inputs where user provide a sample + inputs = [ + torch.rand((1,2,3), dtype=torch.float32), + torch.rand((1,4,5), dtype=torch.float32), + ] + input_specs = InputTensorSpec.from_tensors(inputs) + + # IMPORTANT: If dynamic shape is needed, we need to build it slightly differently. + input_specs = [ + InputTensorSpec( + shape=(-1, 2, 3), + dtype=torch.float32, + # Currently we only support one set of dynamic range. User may set other dimensions but it is not promised to work for any models + # (min_shape, optimize_target_shape, max_shape) + # For more information refer to fx/input_tensor_spec.py + shape_ranges = [ + ((1, 2, 3), (4, 2, 3), (100, 2, 3)), + ], + ), + InputTensorSpec(shape=(1, 4, 5), dtype=torch.float32), + ] + + # Build a TRT interpreter. Set explicit_batch_dimension accordingly. + interpreter = TRTInterpreter( + acc_mod, input_specs, explicit_batch_dimension=True/False + ) + + # The output of TRTInterpreter run() is wrapped as TRTInterpreterResult. + # The TRTInterpreterResult contains required parameter to build TRTModule, + # and other informational output from TRTInterpreter run. + class TRTInterpreterResult(NamedTuple): + engine: Any + input_names: Sequence[str] + output_names: Sequence[str] + serialized_cache: bytearray + + #max_batch_size: set accordingly for maximum batch size you will use. + #max_workspace_size: set to the maximum size we can afford for temporary buffer + #lower_precision: the precision model layers are running on (TensorRT will choose the best perforamnce precision). + #sparse_weights: allow the builder to examine weights and use optimized functions when weights have suitable sparsity + #force_fp32_output: force output to be fp32 + #strict_type_constraints: Usually we should set it to False unless we want to control the precision of certain layer for numeric #reasons. + #algorithm_selector: set up algorithm selection for certain layer + #timing_cache: enable timing cache for TensorRT + #profiling_verbosity: TensorRT logging level + trt_interpreter_result = interpreter.run( + max_batch_size=64, + max_workspace_size=1 << 25, + sparse_weights=False, + force_fp32_output=False, + strict_type_constraints=False, + algorithm_selector=None, + timing_cache=None, + profiling_verbosity=None, + ) + + +*Common Errors:* + +RuntimeError: Conversion of function xxx not currently supported! +- This means we don’t have the support for this xxx operator. Please refer to section “How to add a missing op” below for further instructions. + +* **Step 3: Run the model** +One way is using TRTModule, which is basically a PyTorch nn.Module. + +.. code-block:: shell + + from torch_tensorrt.fx import TRTModule + mod = TRTModule( + trt_interpreter_result.engine, + trt_interpreter_result.input_names, + trt_interpreter_result.output_names) + # Just like all other PyTorch modules + outputs = mod(*inputs) + torch.save(mod, "trt.pt") + reload_trt_mod = torch.load("trt.pt") + reload_model_output = reload_trt_mod(*inputs) + +So far, we give a detailed explanation of major steps in convterting a PyTorch model into TensorRT engine. Users are welcome to refer to the source code for some parameters explanations. In the converting scheme, there are two important actions in it. One is acc tracer which helps us to convert a PyTorch model to acc graph. The other is FX path converter which helps to convert the acc graph's operation to corresponding TensorRT operation and build up the TensoRT engine for it. + +Acc Tracer +--------- + +Acc tracer is a custom FX symbolic tracer. It does a couple more things compare to the vanilla FX symbolic tracer. We mainly depend on it to convert PyTorch ops or builtin ops to acc ops. There are two main purposes for fx2trt to use acc ops: + +1. there’re many ops that do similar things in PyTorch ops and builtin ops such like torch.add, builtin.add and torch.Tensor.add. Using acc tracer, we normalize these three ops to a single acc_ops.add. This helps reduce the number of converters we need to write. +2. acc ops only have kwargs which makes writing converter easier as we don’t need to add additional logic to find arguments in args and kwargs. + +FX2TRT +-------- +After symbolic tracing, we have the graph representation of a PyTorch model. fx2trt leverages the power of fx.Interpreter. fx.Interpreter goes through the whole graph node by node and calls the function that node represents. fx2trt overrides the original behavior of calling the function with invoking corresponding converts for each node. Each converter function adds corresponding TensorRT layer(s). + +Below is an example of a converter function. The decorator is used to register this converter function with the corresponding node. In this example, we register this converter to a fx node whose target is acc_ops.sigmoid. + +.. code-block:: shell + + @tensorrt_converter(acc_ops.sigmoid) + def acc_ops_sigmoid(network, target, args, kwargs, name): + """ + network: TensorRT network. We'll be adding layers to it. + + The rest arguments are attributes of fx node. + """ + input_val = kwargs['input'] + + if not isinstance(input_val, trt.tensorrt.ITensor): + raise RuntimeError(f'Sigmoid received input {input_val} that is not part ' + 'of the TensorRT region!') + + layer = network.add_activation(input=input_val, type=trt.ActivationType.SIGMOID) + layer.name = name + return layer.get_output(0) + +How to Add a Missing Op +**************** + +You can actually add it wherever you want just need to remember import the file so that all acc ops and mapper will be registered before tracing with acc_tracer. + +* **Step 1. Add a new acc op** + +TODO: Need to explain more on the logistic of acc op like when we want to break down an op and when we want to reuse other ops. + +In `acc tracer `_, we convert nodes in the graph to acc ops if there’s a mapping registered for the node to an acc op. + +In order to make the conversion to acc ops to happen, there’re two things required. One is that there should be an acc op function defined and the other is there should be a mapping registered. + +Defining an acc op is simple, we first just need a function and register the function as an acc op via this decorator `acc_normalizer.py `_. e.g. the following code adds an acc op named foo() which adds two given inputs. + +.. code-block:: shell + + # NOTE: all acc ops should only take kwargs as inputs, therefore we need the "*" + # at the beginning. + @register_acc_op + def foo(*, input, other, alpha): + return input + alpha * other + +There’re two ways to register a mapping. One is `register_acc_op_mapping() `_. Let’s register a mapping from torch.add to foo() we just created above. We need to add decorator register_acc_op_mapping to it. + +.. code-block:: shell + + this_arg_is_optional = True + + @register_acc_op_mapping( + op_and_target=("call_function", torch.add), + arg_replacement_tuples=[ + ("input", "input"), + ("other", "other"), + ("alpha", "alpha", this_arg_is_optional), + ], + ) + @register_acc_op + def foo(*, input, other, alpha=1.0): + return input + alpha * other + +``op_and_target`` determines which node will trigger this mapping. op and target are the attributes of FX node. In acc_normalization when we see a node with the same op and target as set in the ``op_and_target``, we will trigger the mapping. Since we want to map from ``torch.add``, then op would be call_function and target would be ``torch.add``. ``arg_replacement_tuples`` determines how we construct kwargs for new acc op node using args and kwargs from original node. Each tuple in ``arg_replacement_tuples`` represents one argument mapping rule. It contains two or three elements. The third element is a boolean variable that determines whether this kwarg is optional in *original node*. We only need to specify the third element if it’s True. The first element is the argument name in original node which will be used as the acc op node’s argument whose name is the second element in the tuple. The sequence of the tuples does matter because the position of the tuple determines where the argument is in original node’s args. We use this information to map args from original node to kwargs in acc op node. +We don’t have to specify arg_replacement_tuples if none of the followings are true. + +1. kwargs of original nodes and acc op nodes have different name. +2. there’re optional arguments. + +The other way to register a mapping is through `register_custom_acc_mapper_fn() `_. This one is designed to reduce the redundant op registration as it allows you to use a function to map to one or more existing acc ops throught some combinations. In the function, you can do basically whatever you want. Let’s use an example to explain how it works. + +.. code-block:: shell + + @register_acc_op + def foo(*, input, other, alpha=1.0): + return input + alpha * other + + @register_custom_acc_mapper_fn( + op_and_target=("call_function", torch.add), + arg_replacement_tuples=[ + ("input", "input"), + ("other", "other"), + ("alpha", "alpha", this_arg_is_optional), + ], + ) + def custom_mapper(node: torch.fx.Node, _: nn.Module) -> torch.fx.Node: + """ + `node` is original node, which is a call_function node with target + being torch.add. + """ + alpha = 1 + if "alpha" in node.kwargs: + alpha = node.kwargs["alpha"] + foo_kwargs = {"input": node["input"], "other": node["other"], "alpha": alpha} + with node.graph.inserting_before(node): + foo_node = node.graph.call_function(foo, kwargs=foo_kwargs) + foo_node.meta = node.meta.copy() + return foo_node + + +In the custom mapper function, we construct an acc op node and return it. The node we returns here would take over all the children nodes of original nodes `acc_normalizer.py `_. + +The last step would be *adding unit test* for the new acc op or mapper function we added. The place to add the unit test is here `test_acc_tracer.py `_. + +* **Step 2. Add a new converter** + +All the developed converters for acc ops are all in `acc_op_converter.py `_. It could give you a good example of how the converter is added. + +Essentially, the converter is the mapping mechanism that maps the acc ops to a TensorRT layer. If we are able to find all the TensorRT layers we need we can get start to add a converter for the node using `TensorRT APIs `_. + +.. code-block:: shell + + @tensorrt_converter(acc_ops.sigmoid) + def acc_ops_sigmoid(network, target, args, kwargs, name): + """ + network: TensorRT network. We'll be adding layers to it. + + The rest arguments are attributes of fx node. + """ + input_val = kwargs['input'] + + if not isinstance(input_val, trt.tensorrt.ITensor): + raise RuntimeError(f'Sigmoid received input {input_val} that is not part ' + 'of the TensorRT region!') + + layer = network.add_activation(input=input_val, type=trt.ActivationType.SIGMOID) + layer.name = name + return layer.get_output(0) + +We need to use ``tensorrt_converter`` decorator to register the converter. The argument for the decorator is the target of the fx node that we need to convert. In the converter, we can find the inputs to the fx node in kwargs. As in the example, the original node is `acc_ops.sigmoid` which only has one argument “input” in acc_ops.py. We get the input and check if it’s a TensorRT tensor. After that, we add a sigmoid layer to TensorRT network and return the output of the layer. The output we returned will be passed to the children nodes of acc_ops.sigmoid by fx.Interpreter. + +**What if we can not find corresponding layers in TensorRT that do the same thing as the node.** + +In this case, we would need to do a bit more work. TensorRT provides plugins which serves as custom layers. *We have not implement this feature yet. We will update once it is enabled*. + +Last step would be adding the unit test for the new converter we added. User could add corresponding unit test in this `folder `_. diff --git a/docs/v2.2.0/_sources/getting_started/getting_started_with_windows.rst.txt b/docs/v2.2.0/_sources/getting_started/getting_started_with_windows.rst.txt new file mode 100644 index 0000000000..edb3262d66 --- /dev/null +++ b/docs/v2.2.0/_sources/getting_started/getting_started_with_windows.rst.txt @@ -0,0 +1,147 @@ +.. _getting_started_windows: + +Building Torch-TensorRT on Windows +==================================== + +Torch-TensorRT has community support for Windows platform using CMake + +Prerequisite: + +* Microsoft Visual Studio +* LibTorch +* TensorRT +* CUDA +* cuDNN + + +Build configuration +------------------- + +* Open Microsoft Visual Studio +* Open Torch-TensorRT source code folder +* Open Manage configurations -> Edit JSON to open CMakeSettings.json file. +* Configure the CMake build configurations. Following is an example configuration: + +.. code-block:: none + + { + "configurations": [ + { + "name": "x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "-S . -B out", + "buildCommandArgs": "cmake --build out", + "ctestCommandArgs": "", + "variables": [ + { + "name": "CMAKE_MODULE_PATH", + "value": "$PWD\cmake\Modules", + "type": "FILEPATH" + }, + { + "name": "Torch_DIR", + "value": "\share\cmake\Torch", + "type": "FILEPATH" + }, + { + "name": "TensorRT_ROOT", + "value": "", + "type": "FILEPATH" + }, + { + "name": "CMAKE_BUILD_TYPE", + "value": "Release", + "type": " STRING" + } + ] + } + ] + } + + +Compilation +----------- + +* Click Build -> Build All or directly press Ctrl + Shift + B + +Note: After successful compilation, the build artifacts will be present at buildRoot path configured. + +Installation +------------ + +* Build -> Install Torch-TensorRT + +Note: After successful installation, the artifacts will be present at installRoot. + + +Building With Visual Studio Code +================================== + +1. Install Visual Studio Code +2. Install Build Tools for Visual Studio 2022 + + - Select "Desktop Development with C++" + > Currently, this installs MSVC v143 - 2022. There are also options to install previous 2019/2017/2015 editions of MSVC + > License term "1b Build Tools additional use right" allows using Build Tools to compile Open Source Dependencies + > Also allows using Build Tools to develop and test Open Source Dependencies, to the minor extend of ensuring compatibility with Build Tools + +3. Install CUDA (e.g. 11.7.1) +4. Install cuDNN (e.g. 8.5.0.96) + + - Set ``cuDNN_ROOT_DIR`` + +5. Install `TensorRT` (e.g 8.5.1.7) + + - Set ``TensorRT_ROOT`` + - Add ``TensorRT_ROOT\lib`` to ``PATH`` + +6. Install "libtorch-win-shared-with-deps-latest.zip" + + - Select build targeting the appropriate CUDA version + - Set ``Torch_DIR`` + - Add ``Torch_DIR\lib`` to ``PATH`` + +7. Clone TensorRT repo +8. Install C++ and CMake Tools extensions from MS + + - Change build to ``RelWithDebInfo`` + +9. Update ``.vscode\settings.json`` + + - Clean, configure, build + +e.g. /.vscode/settings.json + +.. code-block:: json + + { + "cmake.generator": "Ninja", + "cmake.configureSettings": { + "CMAKE_MODULE_PATH": { + "type": "FILEPATH", + "value": "$PWD\\cmake\\Modules" + }, + "CMAKE_CXX_FLAGS": { + "type": "STRING", + "value": "-D_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING" + }, + "Torch_DIR": { + "type": "FILEPATH", + "value": "X:\\libtorch\\share\\cmake\\Torch" + }, + "TensorRT_ROOT": { + "type": "FILEPATH", + "value": "X:\\path\\to\\tensorrt" + }, + "cuDNN_ROOT_DIR": { + "type": "FILEPATH", + "value": "X:\\path\\to\\cudnn" + }, + "CMAKE_CUDA_FLAGS": "-allow-unsupported-compiler" + }, + "cmake.buildDirectory": "${workspaceFolder}/torch_tensorrt_build" + } diff --git a/docs/v2.2.0/_sources/getting_started/installation.rst.txt b/docs/v2.2.0/_sources/getting_started/installation.rst.txt new file mode 100644 index 0000000000..9f0088c3b8 --- /dev/null +++ b/docs/v2.2.0/_sources/getting_started/installation.rst.txt @@ -0,0 +1,317 @@ +.. _installation: + +Installation +============= + +Precompiled Binaries +********************* + +Torch-TensorRT 2.x is centered primarily around Python. As such, precompiled releases can be found on pypi.org + +Dependencies +--------------- + +You need to have CUDA, PyTorch, and TensorRT (python package is sufficient) installed to use Torch-TensorRT + + * https://developer.nvidia.com/cuda + * https://pytorch.org + + +Installing Torch-TensorRT +--------------------------- + +You can install the python package using + +.. code-block:: sh + + python -m pip install torch torch-tensorrt tensorrt + +Installing Torch-TensorRT for a specific CUDA version +-------------------------------------------------------- + +Similar to PyTorch, Torch-TensorRT has builds compiled for different versions of CUDA. These are distributed on PyTorch's package index + +For example CUDA 11.8 + +.. code-block:: sh + + python -m pip install torch torch-tensorrt tensorrt --extra-index-url https://download.pytorch.org/whl/cu118 + +Installing Nightly Builds +--------------------------- + +Torch-TensorRT distributed nightlies targeting the PyTorch nightly. These can be installed from the PyTorch nightly package index (separated by CUDA version) + +.. code-block:: sh + + python -m pip install --pre torch torch-tensorrt tensorrt --extra-index-url https://download.pytorch.org/whl/nightly/cu121 + + + +.. _bin-dist: + +C++ Precompiled Binaries (TorchScript Only) +-------------------------------------------------- + +Precompiled tarballs for releases are provided here: https://github.com/pytorch/TensorRT/releases + +.. _compile-from-source: + +Compiling From Source +****************************************** + +.. _installing-deps: + +Dependencies for Compilation +------------------------------- + +* Torch-TensorRT is built with **Bazel**, so begin by installing it. + + * The easiest way is to install bazelisk using the method of your choosing https://github.com/bazelbuild/bazelisk + * Otherwise you can use the following instructions to install binaries https://docs.bazel.build/versions/master/install.html + * Finally if you need to compile from source (e.g. aarch64 until bazel distributes binaries for the architecture) you can use these instructions + + .. code-block:: shell + + export BAZEL_VERSION=$(cat /.bazelversion) + mkdir bazel + cd bazel + curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-dist.zip + unzip bazel-$BAZEL_VERSION-dist.zip + bash ./compile.sh + cp output/bazel /usr/local/bin/ + + +* You will also need to have **CUDA** installed on the system (or if running in a container, the system must have the CUDA driver installed and the container must have CUDA) + + * Specify your CUDA version here if not the version used in the branch being built: https://github.com/pytorch/TensorRT/blob/4e5b0f6e860910eb510fa70a76ee3eb9825e7a4d/WORKSPACE#L46 + + +* The correct **LibTorch** version will be pulled down for you by bazel. + + NOTE: By default bazel will pull the latest nightly from pytorch.org. For building main, this is usually sufficient however if there is a specific PyTorch you are targeting, + edit these locations with updated URLs/paths: + + * https://github.com/pytorch/TensorRT/blob/4e5b0f6e860910eb510fa70a76ee3eb9825e7a4d/WORKSPACE#L53C1-L53C1 + + +* **cuDNN and TensorRT** are not required to be installed on the system to build Torch-TensorRT, in fact this is preferable to ensure reproducable builds. Download the tarballs for cuDNN and TensorRT from https://developer.nvidia.com and update the paths in the WORKSPACE file here https://github.com/pytorch/TensorRT/blob/4e5b0f6e860910eb510fa70a76ee3eb9825e7a4d/WORKSPACE#L71 + + For example: + + .. code-block:: python + + http_archive( + name = "cudnn", + build_file = "@//third_party/cudnn/archive:BUILD", + sha256 = "79d77a769c7e7175abc7b5c2ed5c494148c0618a864138722c887f95c623777c", + strip_prefix = "cudnn-linux-x86_64-8.8.1.3_cuda12-archive", + urls = [ + #"https://developer.nvidia.com/downloads/compute/cudnn/secure/8.8.1/local_installers/12.0/cudnn-linux-x86_64-8.8.1.3_cuda12-archive.tar.xz", + "file:////cudnn-linux-x86_64-8.8.1.3_cuda12-archive.tar.xz" + ], + ) + + http_archive( + name = "tensorrt", + build_file = "@//third_party/tensorrt/archive:BUILD", + sha256 = "0f8157a5fc5329943b338b893591373350afa90ca81239cdadd7580cd1eba254", + strip_prefix = "TensorRT-8.6.1.6", + urls = [ + #"https://developer.nvidia.com/downloads/compute/machine-learning/tensorrt/secure/8.6.1/tars/TensorRT-8.6.1.6.Linux.x86_64-gnu.cuda-12.0.tar.gz", + "file:////TensorRT-8.6.1.6.Linux.x86_64-gnu.cuda-12.0.tar.gz" + ], + ) + +If you have a local version of cuDNN and TensorRT installed, this can be used as well by commenting out the above lines and uncommenting the following lines https://github.com/pytorch/TensorRT/blob/4e5b0f6e860910eb510fa70a76ee3eb9825e7a4d/WORKSPACE#L114C1-L124C3 + + +Building the Package +--------------------- + +Once the WORKSPACE has been configured properly, all that is required to build torch-tensorrt is the following command + + .. code-block:: sh + + python -m pip install --pre . --extra-index-url https://download.pytorch.org/whl/nightly/cu121 + + +To build the wheel file + + .. code-block:: sh + + python -m pip wheel --no-deps --pre . --extra-index-url https://download.pytorch.org/whl/nightly/cu121 -w dist + + +Building the C++ Library (TorchScript Only) +------------------------------ + +Release Build +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: shell + + bazel build //:libtorchtrt -c opt + +A tarball with the include files and library can then be found in ``bazel-bin`` + +.. _build-from-archive-debug: + +Debug Build +^^^^^^^^^^^^^^^^^^^^^^^^ + +To build with debug symbols use the following command + +.. code-block:: shell + + bazel build //:libtorchtrt -c dbg + +A tarball with the include files and library can then be found in ``bazel-bin`` + +Pre CXX11 ABI Build +^^^^^^^^^^^^^^^^^^^^^^^^ + +To build using the pre-CXX11 ABI use the ``pre_cxx11_abi`` config + +.. code-block:: shell + + bazel build //:libtorchtrt --config pre_cxx11_abi -c [dbg/opt] + +A tarball with the include files and library can then be found in ``bazel-bin`` + + +.. _abis: + +Choosing the Right ABI +^^^^^^^^^^^^^^^^^^^^^^^^ + +Likely the most complicated thing about compiling Torch-TensorRT is selecting the correct ABI. There are two options +which are incompatible with each other, pre-cxx11-abi and the cxx11-abi. The complexity comes from the fact that while +the most popular distribution of PyTorch (wheels downloaded from pytorch.org/pypi directly) use the pre-cxx11-abi, most +other distributions you might encounter (e.g. ones from NVIDIA - NGC containers, and builds for Jetson as well as certain +libtorch builds and likely if you build PyTorch from source) use the cxx11-abi. It is important you compile Torch-TensorRT +using the correct ABI to function properly. Below is a table with general pairings of PyTorch distribution sources and the +recommended commands: + ++-------------------------------------------------------------+----------------------------------------------------------+--------------------------------------------------------------------+ +| PyTorch Source | Recommended Python Compilation Command | Recommended C++ Compilation Command | ++=============================================================+==========================================================+====================================================================+ +| PyTorch whl file from PyTorch.org | python -m pip install . | bazel build //:libtorchtrt -c opt --config pre_cxx11_abi | ++-------------------------------------------------------------+----------------------------------------------------------+--------------------------------------------------------------------+ +| libtorch-shared-with-deps-*.zip from PyTorch.org | python -m pip install . | bazel build //:libtorchtrt -c opt --config pre_cxx11_abi | ++-------------------------------------------------------------+----------------------------------------------------------+--------------------------------------------------------------------+ +| libtorch-cxx11-abi-shared-with-deps-*.zip from PyTorch.org | python setup.py bdist_wheel --use-cxx11-abi | bazel build //:libtorchtrt -c opt | ++-------------------------------------------------------------+----------------------------------------------------------+--------------------------------------------------------------------+ +| PyTorch preinstalled in an NGC container | python setup.py bdist_wheel --use-cxx11-abi | bazel build //:libtorchtrt -c opt | ++-------------------------------------------------------------+----------------------------------------------------------+--------------------------------------------------------------------+ +| PyTorch from the NVIDIA Forums for Jetson | python setup.py bdist_wheel --use-cxx11-abi | bazel build //:libtorchtrt -c opt | ++-------------------------------------------------------------+----------------------------------------------------------+--------------------------------------------------------------------+ +| PyTorch built from Source | python setup.py bdist_wheel --use-cxx11-abi | bazel build //:libtorchtrt -c opt | ++-------------------------------------------------------------+----------------------------------------------------------+--------------------------------------------------------------------+ + + NOTE: For all of the above cases you must correctly declare the source of PyTorch you intend to use in your WORKSPACE file for both Python and C++ builds. See below for more information + +**Building with CMake** (TorchScript Only) +------------------------------------------- + +It is possible to build the API libraries (in cpp/) and the torchtrtc executable using CMake instead of Bazel. +Currently, the python API and the tests cannot be built with CMake. +Begin by installing CMake. + + * Latest releases of CMake and instructions on how to install are available for different platforms + [on their website](https://cmake.org/download/). + +A few useful CMake options include: + + * CMake finders for TensorRT and cuDNN are provided in `cmake/Modules`. In order for CMake to use them, pass + `-DCMAKE_MODULE_PATH=cmake/Modules` when configuring the project with CMake. + * Libtorch provides its own CMake finder. In case CMake doesn't find it, pass the path to your install of + libtorch with `-DTorch_DIR=/share/cmake/Torch` + * If TensorRT is not found with the provided cmake finder, specify `-DTensorRT_ROOT=` + * Finally, configure and build the project in a build directory of your choice with the following command + from the root of Torch-TensorRT project: + + .. code-block:: shell + + cmake -S. -B \ + [-DCMAKE_MODULE_PATH=cmake/Module] \ + [-DTorch_DIR=/share/cmake/Torch] \ + [-DTensorRT_ROOT=] \ + [-DCMAKE_BUILD_TYPE=Debug|Release] + cmake --build + +**Building Natively on aarch64 (Jetson)** +------------------------------------------- + +Prerequisites +^^^^^^^^^^^^^^ + +Install or compile a build of PyTorch/LibTorch for aarch64 + +NVIDIA hosts builds the latest release branch for Jetson here: + + https://forums.developer.nvidia.com/t/pytorch-for-jetson-version-1-10-now-available/72048 + + +Enviorment Setup +^^^^^^^^^^^^^^^^^ + +To build natively on aarch64-linux-gnu platform, configure the ``WORKSPACE`` with local available dependencies. + +1. Replace ``WORKSPACE`` with the corresponding WORKSPACE file in ``//toolchains/jp_workspaces`` + +2. Configure the correct paths to directory roots containing local dependencies in the ``new_local_repository`` rules: + + NOTE: If you installed PyTorch using a pip package, the correct path is the path to the root of the python torch package. + In the case that you installed with ``sudo pip install`` this will be ``/usr/local/lib/python3.8/dist-packages/torch``. + In the case you installed with ``pip install --user`` this will be ``$HOME/.local/lib/python3.8/site-packages/torch``. + +In the case you are using NVIDIA compiled pip packages, set the path for both libtorch sources to the same path. This is because unlike +PyTorch on x86_64, NVIDIA aarch64 PyTorch uses the CXX11-ABI. If you compiled for source using the pre_cxx11_abi and only would like to +use that library, set the paths to the same path but when you compile make sure to add the flag ``--config=pre_cxx11_abi`` + +.. code-block:: shell + + new_local_repository( + name = "libtorch", + path = "/usr/local/lib/python3.8/dist-packages/torch", + build_file = "third_party/libtorch/BUILD" + ) + + new_local_repository( + name = "libtorch_pre_cxx11_abi", + path = "/usr/local/lib/python3.8/dist-packages/torch", + build_file = "third_party/libtorch/BUILD" + ) + + +Compile C++ Library and Compiler CLI +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + NOTE: Due to shifting dependency locations between Jetpack 4.5 and 4.6 there is a now a flag to inform bazel of the Jetpack version + + .. code-block:: shell + + --platforms //toolchains:jetpack_x.x + + +Compile Torch-TensorRT library using bazel command: + +.. code-block:: shell + + bazel build //:libtorchtrt --platforms //toolchains:jetpack_5.0 + +Compile Python API +^^^^^^^^^^^^^^^^^^^^ + + NOTE: Due to shifting dependencies locations between Jetpack 4.5 and newer Jetpack verisons there is now a flag for ``setup.py`` which sets the jetpack version (default: 5.0) + +Compile the Python API using the following command from the ``//py`` directory: + +.. code-block:: shell + + python3 setup.py install --use-cxx11-abi + +If you have a build of PyTorch that uses Pre-CXX11 ABI drop the ``--use-cxx11-abi`` flag + +If you are building for Jetpack 4.5 add the ``--jetpack-version 5.0`` flag diff --git a/docs/v2.2.0/_sources/index.rst.txt b/docs/v2.2.0/_sources/index.rst.txt new file mode 100644 index 0000000000..455aeab8b3 --- /dev/null +++ b/docs/v2.2.0/_sources/index.rst.txt @@ -0,0 +1,210 @@ +.. Torch-TensorRT documentation master file, created by + sphinx-quickstart on Mon May 4 13:43:16 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Torch-TensorRT +============== + +In-framework compilation of PyTorch inference code for NVIDIA GPUs +-------------------------------------------------------------------------- +Torch-TensorRT is a inference compiler for PyTorch, targeting NVIDIA GPUs via NVIDIA's TensorRT Deep Learning Optimizer and Runtime. +It supports both just-in-time (JIT) compilation workflows via the ``torch.compile`` interface as well as ahead-of-time (AOT) workflows. +Torch-TensorRT integrates seamlessly into the PyTorch ecosystem supporting hybrid execution of optimized TensorRT code with standard PyTorch code. + +More Information / System Architecture: + +* `Torch-TensorRT 2.0 `_ + +Getting Started +---------------- +* :ref:`installation` + +.. toctree:: + :caption: Getting Started + :maxdepth: 1 + :hidden: + + getting_started/installation + getting_started/getting_started_with_windows + + +Dynamo Frontend +---------------- + +* :ref:`torch_compile` +* :ref:`dynamo_export` + +.. toctree:: + :caption: Dynamo Frontend + :maxdepth: 1 + :hidden: + + dynamo/torch_compile + dynamo/dynamo_export + +TorchScript Frontend +----------------------- +* :ref:`creating_a_ts_mod` +* :ref:`getting_started_with_python_api` +* :ref:`getting_started_cpp` +* :ref:`use_from_pytorch` + +.. toctree:: + :caption: TorchScript Frontend + :maxdepth: 1 + :hidden: + + ts/creating_torchscript_module_in_python + ts/getting_started_with_python_api + ts/getting_started_with_cpp_api + ts/use_from_pytorch + +FX Frontend +------------ + +* :ref:`getting_started_with_fx` + +.. toctree:: + :caption: FX Frontend + :maxdepth: 1 + :hidden: + + fx/getting_started_with_fx_path + + +User Guide +------------ + +* :ref:`dynamic_shapes` +* :ref:`ptq` +* :ref:`saving_models` +* :ref:`runtime` +* :ref:`using_dla` + +.. toctree:: + :caption: User Guide + :maxdepth: 1 + :hidden: + + + user_guide/dynamic_shapes + user_guide/ptq + user_guide/saving_models + user_guide/runtime + user_guide/using_dla + +Tutorials +------------ +* :ref:`torch_tensorrt_tutorials` +* :ref:`serving_torch_tensorrt_with_triton` +* :ref:`notebooks` + +.. toctree:: + :caption: Tutorials + :maxdepth: 3 + :hidden: + + tutorials/serving_torch_tensorrt_with_triton + tutorials/notebooks + tutorials/_rendered_examples/dynamo/torch_compile_resnet_example + tutorials/_rendered_examples/dynamo/torch_compile_transformers_example + tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage + tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion + +Python API Documenation +------------------------ +* :ref:`torch_tensorrt_py` +* :ref:`torch_tensorrt_logging_py` +* :ref:`torch_tensorrt_ptq_py` +* :ref:`torch_tensorrt_dynamo_py` +* :ref:`torch_tensorrt_ts_py` +* :ref:`torch_tensorrt_fx_py` + +.. toctree:: + :caption: Python API Documenation + :maxdepth: 0 + :hidden: + + py_api/torch_tensorrt + py_api/logging + py_api/ptq + py_api/dynamo + py_api/ts + py_api/fx + +C++ API Documenation +---------------------- +* :ref:`namespace_torch_tensorrt` +* :ref:`namespace_torch_tensorrt__logging` +* :ref:`namespace_torch_tensorrt__ptq` +* :ref:`namespace_torch_tensorrt__torchscript` + + +.. toctree:: + :caption: C++ API Documenation + :maxdepth: 1 + :hidden: + + _cpp_api/torch_tensort_cpp + _cpp_api/namespace_torch_tensorrt + _cpp_api/namespace_torch_tensorrt__logging + _cpp_api/namespace_torch_tensorrt__torchscript + _cpp_api/namespace_torch_tensorrt__ptq + +CLI Documentation +--------------------- +* :ref:`torchtrtc` + +.. toctree:: + :caption: CLI Documenation + :maxdepth: 0 + :hidden: + + cli/torchtrtc + + +Contributor Documentation +-------------------------------- +* :ref:`system_overview` +* :ref:`dynamo_converters` +* :ref:`writing_dynamo_aten_lowering_passes` +* :ref:`ts_converters` +* :ref:`useful_links` + +.. toctree:: + :caption: Contributor Documentation + :maxdepth: 1 + :hidden: + + contributors/system_overview + contributors/dynamo_converters + contributors/writing_dynamo_aten_lowering_passes + contributors/ts_converters + contributors/useful_links + +Indices +---------------- +* :ref:`supported_ops` +* :ref:`genindex` +* :ref:`search` + +.. toctree:: + :caption: Indices + :maxdepth: 1 + :hidden: + + indices/supported_ops + + +Legacy Further Information (TorchScript) +------------------------------------------- + +* `Introductory Blog Post `_ +* `GTC 2020 Talk `_ +* `GTC 2020 Fall Talk `_ +* `GTC 2021 Talk `_ +* `GTC 2021 Fall Talk `_ +* `PyTorch Ecosystem Day 2021 `_ +* `PyTorch Developer Conference 2021 `_ +* `PyTorch Developer Conference 2022 `_ diff --git a/docs/v2.2.0/_sources/indices/supported_ops.rst.txt b/docs/v2.2.0/_sources/indices/supported_ops.rst.txt new file mode 100644 index 0000000000..0367c02710 --- /dev/null +++ b/docs/v2.2.0/_sources/indices/supported_ops.rst.txt @@ -0,0 +1,285 @@ + +.. _supported_ops: + +================================= +Operators Supported +================================= + + +Operators Currently Supported Through Converters +------------------------------------------------- + +- aten::_convolution(Tensor input, Tensor weight, Tensor? bias, int[] stride, int[] padding, int[] dilation, bool transposed, int[] output_padding, int groups, bool benchmark, bool deterministic, bool cudnn_enabled, bool allow_tf32) -> (Tensor) +- aten::_convolution.deprecated(Tensor input, Tensor weight, Tensor? bias, int[] stride, int[] padding, int[] dilation, bool transposed, int[] output_padding, int groups, bool benchmark, bool deterministic, bool cudnn_enabled) -> (Tensor) +- aten::abs(Tensor self) -> (Tensor) +- aten::acos(Tensor self) -> (Tensor) +- aten::acosh(Tensor self) -> (Tensor) +- aten::adaptive_avg_pool1d(Tensor self, int[1] output_size) -> (Tensor) +- aten::adaptive_avg_pool2d(Tensor self, int[2] output_size) -> (Tensor) +- aten::adaptive_avg_pool3d(Tensor self, int[3] output_size) -> (Tensor) +- aten::adaptive_max_pool1d(Tensor self, int[2] output_size) -> (Tensor, Tensor) +- aten::adaptive_max_pool2d(Tensor self, int[2] output_size) -> (Tensor, Tensor) +- aten::adaptive_max_pool3d(Tensor self, int[3] output_size) -> (Tensor, Tensor) +- aten::add.Scalar(Tensor self, Scalar other, Scalar alpha=1) -> (Tensor) +- aten::add.Tensor(Tensor self, Tensor other, Scalar alpha=1) -> (Tensor) +- aten::add_.Tensor(Tensor(a!) self, Tensor other, *, Scalar alpha=1) -> (Tensor(a!)) +- aten::argmax(Tensor self, int dim, bool keepdim=False) -> (Tensor) +- aten::argmin(Tensor self, int dim, bool keepdim=False) -> (Tensor) +- aten::asin(Tensor self) -> (Tensor) +- aten::asinh(Tensor self) -> (Tensor) +- aten::atan(Tensor self) -> (Tensor) +- aten::atanh(Tensor self) -> (Tensor) +- aten::avg_pool1d(Tensor self, int[1] kernel_size, int[1] stride=[], int[1] padding=[0], bool ceil_mode=False, bool count_include_pad=True) -> (Tensor) +- aten::avg_pool2d(Tensor self, int[2] kernel_size, int[2] stride=[], int[2] padding=[0, 0], bool ceil_mode=False, bool count_include_pad=True, int? divisor_override=None) -> (Tensor) +- aten::avg_pool3d(Tensor self, int[3] kernel_size, int[3] stride=[], int[3] padding=[], bool ceil_mode=False, bool count_include_pad=True, int? divisor_override=None) -> (Tensor) +- aten::batch_norm(Tensor input, Tensor? gamma, Tensor? beta, Tensor? mean, Tensor? var, bool training, float momentum, float eps, bool cudnn_enabled) -> (Tensor) +- aten::bitwise_not(Tensor self) -> (Tensor) +- aten::bmm(Tensor self, Tensor mat2) -> (Tensor) +- aten::cat(Tensor[] tensors, int dim=0) -> (Tensor) +- aten::ceil(Tensor self) -> (Tensor) +- aten::clamp(Tensor self, Scalar? min=None, Scalar? max=None) -> (Tensor) +- aten::clamp_max(Tensor self, Scalar max) -> (Tensor) +- aten::clamp_min(Tensor self, Scalar min) -> (Tensor) +- aten::constant_pad_nd(Tensor self, int[] pad, Scalar value=0) -> (Tensor) +- aten::cos(Tensor self) -> (Tensor) +- aten::cosh(Tensor self) -> (Tensor) +- aten::cumsum(Tensor self, int dim, *, int? dtype=None) -> (Tensor) +- aten::div.Scalar(Tensor self, Scalar other) -> (Tensor) +- aten::div.Tensor(Tensor self, Tensor other) -> (Tensor) +- aten::div.Tensor_mode(Tensor self, Tensor other, *, str? rounding_mode) -> (Tensor) +- aten::div_.Scalar(Tensor(a!) self, Scalar other) -> (Tensor(a!)) +- aten::div_.Tensor(Tensor(a!) self, Tensor other) -> (Tensor(a!)) +- aten::elu(Tensor self, Scalar alpha=1, Scalar scale=1, Scalar input_scale=1) -> (Tensor) +- aten::embedding(Tensor weight, Tensor indices, int padding_idx=-1, bool scale_grad_by_freq=False, bool sparse=False) -> (Tensor) +- aten::eq.Scalar(Tensor self, Scalar other) -> (Tensor) +- aten::eq.Tensor(Tensor self, Tensor other) -> (Tensor) +- aten::erf(Tensor self) -> (Tensor) +- aten::exp(Tensor self) -> (Tensor) +- aten::expand(Tensor(a) self, int[] size, *, bool implicit=False) -> (Tensor(a)) +- aten::expand_as(Tensor(a) self, Tensor other) -> (Tensor(a)) +- aten::fake_quantize_per_channel_affine(Tensor self, Tensor scale, Tensor zero_point, int axis, int quant_min, int quant_max) -> (Tensor) +- aten::fake_quantize_per_tensor_affine(Tensor self, float scale, int zero_point, int quant_min, int quant_max) -> (Tensor) +- aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor) +- aten::floor(Tensor self) -> (Tensor) +- aten::floor_divide(Tensor self, Tensor other) -> (Tensor) +- aten::floor_divide.Scalar(Tensor self, Scalar other) -> (Tensor) +- aten::ge.Scalar(Tensor self, Scalar other) -> (Tensor) +- aten::ge.Tensor(Tensor self, Tensor other) -> (Tensor) +- aten::gru_cell(Tensor input, Tensor hx, Tensor w_ih, Tensor w_hh, Tensor? b_ih=None, Tensor? b_hh=None) -> (Tensor) +- aten::gt.Scalar(Tensor self, Scalar other) -> (Tensor) +- aten::gt.Tensor(Tensor self, Tensor other) -> (Tensor) +- aten::hardtanh(Tensor self, Scalar min_val=-1, Scalar max_val=1) -> (Tensor) +- aten::hardtanh_(Tensor(a!) self, Scalar min_val=-1, Scalar max_val=1) -> (Tensor(a!)) +- aten::index.Tensor(Tensor self, Tensor?[] indices) -> (Tensor) +- aten::instance_norm(Tensor input, Tensor? weight, Tensor? bias, Tensor? running_mean, Tensor? running_var, bool use_input_stats, float momentum, float eps, bool cudnn_enabled) -> (Tensor) +- aten::layer_norm(Tensor input, int[] normalized_shape, Tensor? gamma, Tensor? beta, float eps, bool cudnn_enabled) -> (Tensor) +- aten::le.Scalar(Tensor self, Scalar other) -> (Tensor) +- aten::le.Tensor(Tensor self, Tensor other) -> (Tensor) +- aten::leaky_relu(Tensor self, Scalar negative_slope=0.01) -> (Tensor) +- aten::leaky_relu_(Tensor(a!) self, Scalar negative_slope=0.01) -> (Tensor(a!)) +- aten::linear(Tensor input, Tensor weight, Tensor? bias=None) -> (Tensor) +- aten::log(Tensor self) -> (Tensor) +- aten::lstm_cell(Tensor input, Tensor[] hx, Tensor w_ih, Tensor w_hh, Tensor? b_ih=None, Tensor? b_hh=None) -> (Tensor, Tensor) +- aten::lt.Scalar(Tensor self, Scalar other) -> (Tensor) +- aten::lt.Tensor(Tensor self, Tensor other) -> (Tensor) +- aten::masked_fill.Scalar(Tensor self, Tensor mask, Scalar value) -> (Tensor) +- aten::matmul(Tensor self, Tensor other) -> (Tensor) +- aten::max(Tensor self) -> (Tensor) +- aten::max.dim(Tensor self, int dim, bool keepdim=False) -> (Tensor values, Tensor indices) +- aten::max.other(Tensor self, Tensor other) -> (Tensor) +- aten::max_pool1d(Tensor self, int[1] kernel_size, int[1] stride=[], int[1] padding=[], int[1] dilation=[], bool ceil_mode=False) -> (Tensor) +- aten::max_pool2d(Tensor self, int[2] kernel_size, int[2] stride=[], int[2] padding=[0, 0], int[2] dilation=[1, 1], bool ceil_mode=False) -> (Tensor) +- aten::max_pool3d(Tensor self, int[3] kernel_size, int[3] stride=[], int[3] padding=[], int[3] dilation=[], bool ceil_mode=False) -> (Tensor) +- aten::mean(Tensor self, *, int? dtype=None) -> (Tensor) +- aten::mean.dim(Tensor self, int[] dim, bool keepdim=False, *, int? dtype=None) -> (Tensor) +- aten::min(Tensor self) -> (Tensor) +- aten::min.dim(Tensor self, int dim, bool keepdim=False) -> (Tensor values, Tensor indices) +- aten::min.other(Tensor self, Tensor other) -> (Tensor) +- aten::mul.Scalar(Tensor self, Scalar other) -> (Tensor) +- aten::mul.Tensor(Tensor self, Tensor other) -> (Tensor) +- aten::mul_.Tensor(Tensor(a!) self, Tensor other) -> (Tensor(a!)) +- aten::narrow(Tensor(a) self, int dim, int start, int length) -> (Tensor(a)) +- aten::narrow.Tensor(Tensor(a) self, int dim, Tensor start, int length) -> (Tensor(a)) +- aten::ne.Scalar(Tensor self, Scalar other) -> (Tensor) +- aten::ne.Tensor(Tensor self, Tensor other) -> (Tensor) +- aten::neg(Tensor self) -> (Tensor) +- aten::norm.ScalarOpt_dim(Tensor self, Scalar? p, int[1] dim, bool keepdim=False) -> (Tensor) +- aten::permute(Tensor(a) self, int[] dims) -> (Tensor(a)) +- aten::pixel_shuffle(Tensor self, int upscale_factor) -> (Tensor) +- aten::pow.Tensor_Scalar(Tensor self, Scalar exponent) -> (Tensor) +- aten::pow.Tensor_Tensor(Tensor self, Tensor exponent) -> (Tensor) +- aten::prelu(Tensor self, Tensor weight) -> (Tensor) +- aten::prod(Tensor self, *, int? dtype=None) -> (Tensor) +- aten::prod.dim_int(Tensor self, int dim, bool keepdim=False, *, int? dtype=None) -> (Tensor) +- aten::reciprocal(Tensor self) -> (Tensor) +- aten::reflection_pad1d(Tensor self, int[2] padding) -> (Tensor) +- aten::reflection_pad2d(Tensor self, int[4] padding) -> (Tensor) +- aten::relu(Tensor input) -> (Tensor) +- aten::relu_(Tensor(a!) self) -> (Tensor(a!)) +- aten::repeat(Tensor self, int[] repeats) -> (Tensor) +- aten::repeat_interleave.self_int(Tensor self, int repeats, int? dim=None, *, int? output_size=None) -> (Tensor) +- aten::replication_pad1d(Tensor self, int[2] padding) -> (Tensor) +- aten::replication_pad2d(Tensor self, int[4] padding) -> (Tensor) +- aten::replication_pad3d(Tensor self, int[6] padding) -> (Tensor) +- aten::reshape(Tensor self, int[] shape) -> (Tensor) +- aten::roll(Tensor self, int[1] shifts, int[1] dims=[]) -> (Tensor) +- aten::rsub.Scalar(Tensor self, Scalar other, Scalar alpha=1) -> (Tensor) +- aten::rsub.Tensor(Tensor self, Tensor other, Scalar alpha=1) -> (Tensor) +- aten::scatter.src(Tensor self, int dim, Tensor index, Tensor src) -> (Tensor) +- aten::scatter.value(Tensor self, int dim, Tensor index, Scalar value) -> (Tensor) +- aten::select.int(Tensor(a) self, int dim, int index) -> (Tensor(a)) +- aten::sigmoid(Tensor input) -> (Tensor) +- aten::sigmoid_(Tensor(a!) self) -> (Tensor(a!)) +- aten::sin(Tensor self) -> (Tensor) +- aten::sinh(Tensor self) -> (Tensor) +- aten::slice.Tensor(Tensor(a) self, int dim=0, int? start=None, int? end=None, int step=1) -> (Tensor(a)) +- aten::softmax.int(Tensor self, int dim, int? dtype=None) -> (Tensor) +- aten::split(Tensor self, int[] split_sizes, int dim=0) -> (Tensor[]) +- aten::split.Tensor(Tensor(a) self, int split_size, int dim=0) -> (Tensor[]) +- aten::split.sizes(Tensor(a -> *) self, int[] split_size, int dim=0) -> (Tensor[]) +- aten::split_with_sizes(Tensor(a) self, int[] split_sizes, int dim=0) -> (Tensor[]) +- aten::sqrt(Tensor self) -> (Tensor) +- aten::square(Tensor self) -> (Tensor) +- aten::squeeze.dim(Tensor(a) self, int dim) -> (Tensor(a)) +- aten::stack(Tensor[] tensors, int dim=0) -> (Tensor) +- aten::sub.Scalar(Tensor self, Scalar other, Scalar alpha=1) -> (Tensor) +- aten::sub.Tensor(Tensor self, Tensor other, Scalar alpha=1) -> (Tensor) +- aten::sub_.Tensor(Tensor(a!) self, Tensor other, *, Scalar alpha=1) -> (Tensor(a!)) +- aten::sum(Tensor self, *, int? dtype=None) -> (Tensor) +- aten::sum.dim_IntList(Tensor self, int[1] dim, bool keepdim=False, *, int? dtype=None) -> (Tensor) +- aten::t(Tensor self) -> (Tensor) +- aten::tan(Tensor self) -> (Tensor) +- aten::tanh(Tensor input) -> (Tensor) +- aten::tanh_(Tensor(a!) self) -> (Tensor(a!)) +- aten::to.device(Tensor(a) self, Device device, int dtype, bool non_blocking=False, bool copy=False, int? memory_format=None) -> (Tensor(a)) +- aten::to.dtype(Tensor self, int dtype, bool non_blocking=False, bool copy=False, int? memory_format=None) -> (Tensor) +- aten::to.other(Tensor self, Tensor other, bool non_blocking=False, bool copy=False, int? memory_format=None) -> (Tensor) +- aten::to.prim_Device(Tensor(a) self, Device? device, int? dtype=None, bool non_blocking=False, bool copy=False) -> (Tensor(a|b)) +- aten::topk(Tensor self, int k, int dim=-1, bool largest=True, bool sorted=True) -> (Tensor values, Tensor indices) +- aten::transpose.int(Tensor(a) self, int dim0, int dim1) -> (Tensor(a)) +- aten::unbind.int(Tensor(a -> *) self, int dim=0) -> (Tensor[]) +- aten::unsqueeze(Tensor(a) self, int dim) -> (Tensor(a)) +- aten::upsample_bilinear2d(Tensor self, int[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> (Tensor) +- aten::upsample_bilinear2d.vec(Tensor input, int[]? output_size, bool align_corners, float[]? scale_factors) -> (Tensor) +- aten::upsample_linear1d(Tensor self, int[1] output_size, bool align_corners, float? scales=None) -> (Tensor) +- aten::upsample_linear1d.vec(Tensor input, int[]? output_size, bool align_corners, float[]? scale_factors) -> (Tensor) +- aten::upsample_nearest1d(Tensor self, int[1] output_size, float? scales=None) -> (Tensor) +- aten::upsample_nearest1d.vec(Tensor input, int[]? output_size, float[]? scale_factors) -> (Tensor) +- aten::upsample_nearest2d(Tensor self, int[2] output_size, float? scales_h=None, float? scales_w=None) -> (Tensor) +- aten::upsample_nearest2d.vec(Tensor input, int[]? output_size, float[]? scale_factors) -> (Tensor) +- aten::upsample_nearest3d(Tensor self, int[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> (Tensor) +- aten::upsample_nearest3d.vec(Tensor input, int[]? output_size, float[]? scale_factors) -> (Tensor) +- aten::upsample_trilinear3d(Tensor self, int[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> (Tensor) +- aten::upsample_trilinear3d.vec(Tensor input, int[]? output_size, bool align_corners, float[]? scale_factors) -> (Tensor) +- aten::view(Tensor(a) self, int[] size) -> (Tensor(a)) +- trt::const(Tensor self) -> (Tensor) + +Operators Currently Supported Through Evaluators +------------------------------------------------- + +- aten::Bool.float(float b) -> (bool) +- aten::Bool.int(int a) -> (bool) +- aten::Float.Scalar(Scalar a) -> float +- aten::Float.bool(bool a) -> float +- aten::Float.int(int a) -> float +- aten::Int.Scalar(Scalar a) -> int +- aten::Int.bool(bool a) -> int +- aten::Int.float(float a) -> int +- aten::Int.int(int a) -> int +- aten::__and__(int a, int b) -> (bool) +- aten::__and__.bool(bool a, bool b) -> (bool) +- aten::__derive_index(int idx, int start, int step) -> int +- aten::__getitem__.t(t[](a) list, int idx) -> (t(*)) +- aten::__is__(t1 self, t2 obj) -> bool +- aten::__isnot__(t1 self, t2 obj) -> bool +- aten::__not__(bool self) -> bool +- aten::__or__(int a, int b) -> (bool) +- aten::__range_length(int lo, int hi, int step) -> int +- aten::__round_to_zero_floordiv(int a, int b) -> (int) +- aten::__xor__(int a, int b) -> (bool) +- aten::add.float(float a, float b) -> (float) +- aten::add.int(int a, int b) -> (int) +- aten::add.str(str a, str b) -> (str) +- aten::add_.t(t[](a!) self, t[] b) -> (t[]) +- aten::append.t(t[](a!) self, t(c -> *) el) -> (t[](a!)) +- aten::arange(Scalar end, *, int? dtype=None, int? layout=None, + Device? device=None, bool? pin_memory=None) -> (Tensor) +- aten::arange.start(Scalar start, Scalar end, *, ScalarType? dtype=None, + Layout? layout=None, Device? device=None, bool? pin_memory=None) -> (Tensor) +- aten::arange.start_step(Scalar start, Scalar end, Scalar step, *, ScalarType? dtype=None, + Layout? layout=None, Device? device=None, bool? pin_memory=None) -> (Tensor) +- aten::clone(Tensor self, *, int? memory_format=None) -> (Tensor) +- aten::copy_(Tensor(a!) self, Tensor src, bool non_blocking=False) -> (Tensor(a!)) +- aten::dim(Tensor self) -> int +- aten::div.float(float a, float b) -> (float) +- aten::div.int(int a, int b) -> (float) +- aten::eq.bool(bool a, bool b) -> (bool) +- aten::eq.float(float a, float b) -> (bool) +- aten::eq.float_int(float a, int b) -> (bool) +- aten::eq.int(int a, int b) -> (bool) +- aten::eq.int_float(int a, float b) -> (bool) +- aten::eq.str(str a, str b) -> (bool) +- aten::extend.t(t[](a!) self, t[] other) -> () +- aten::floor.float(float a) -> (int) +- aten::floor.int(int a) -> (int) +- aten::floordiv.float(float a, float b) -> (int) +- aten::floordiv.int(int a, int b) -> (int) +- aten::format(str self, ...) -> (str) +- aten::ge.bool(bool a, bool b) -> (bool) +- aten::ge.float(float a, float b) -> (bool) +- aten::ge.float_int(float a, int b) -> (bool) +- aten::ge.int(int a, int b) -> (bool) +- aten::ge.int_float(int a, float b) -> (bool) +- aten::gt.bool(bool a, bool b) -> (bool) +- aten::gt.float(float a, float b) -> (bool) +- aten::gt.float_int(float a, int b) -> (bool) +- aten::gt.int(int a, int b) -> (bool) +- aten::gt.int_float(int a, float b) -> (bool) +- aten::is_floating_point(Tensor self) -> (bool) +- aten::le.bool(bool a, bool b) -> (bool) +- aten::le.float(float a, float b) -> (bool) +- aten::le.float_int(float a, int b) -> (bool) +- aten::le.int(int a, int b) -> (bool) +- aten::le.int_float(int a, float b) -> (bool) +- aten::len.t(t[] a) -> (int) +- aten::lt.bool(bool a, bool b) -> (bool) +- aten::lt.float(float a, float b) -> (bool) +- aten::lt.float_int(float a, int b) -> (bool) +- aten::lt.int(int a, int b) -> (bool) +- aten::lt.int_float(int a, float b) -> (bool) +- aten::mul.float(float a, float b) -> (float) +- aten::mul.int(int a, int b) -> (int) +- aten::ne.bool(bool a, bool b) -> (bool) +- aten::ne.float(float a, float b) -> (bool) +- aten::ne.float_int(float a, int b) -> (bool) +- aten::ne.int(int a, int b) -> (bool) +- aten::ne.int_float(int a, float b) -> (bool) +- aten::neg.int(int a) -> (int) +- aten::numel(Tensor self) -> int +- aten::pow.float(float a, float b) -> (float) +- aten::pow.float_int(float a, int b) -> (float) +- aten::pow.int(int a, int b) -> (float) +- aten::pow.int_float(int a, float b) -> (float) +- aten::size(Tensor self) -> (int[]) +- aten::size.int(Tensor self, int dim) -> (int) +- aten::slice.t(t[] l, int start, int end=9223372036854775807, int step=1) -> (t[]) +- aten::sqrt.float(float a) -> (float) +- aten::sqrt.int(int a) -> (float) +- aten::sub.float(float a, float b) -> (float) +- aten::sub.int(int a, int b) -> (int) +- aten::tensor(t[] data, *, int? dtype=None, Device? device=None, bool requires_grad=False) -> (Tensor) +- prim::TupleIndex(Any tup, int i) -> (Any) +- prim::dtype(Tensor a) -> (int) +- prim::max.bool(bool a, bool b) -> (bool) +- prim::max.float(float a, float b) -> (bool) +- prim::max.float_int(float a, int b) -> (bool) +- prim::max.int(int a, int b) -> (bool) +- prim::max.int_float(int a, float b) -> (bool) +- prim::max.self_int(int[] self) -> (int) +- prim::min.bool(bool a, bool b) -> (bool) +- prim::min.float(float a, float b) -> (bool) +- prim::min.float_int(float a, int b) -> (bool) +- prim::min.int(int a, int b) -> (bool) +- prim::min.int_float(int a, float b) -> (bool) +- prim::min.self_int(int[] self) -> (int) +- prim::shape(Tensor a) -> (int[]) diff --git a/docs/v2.2.0/_sources/py_api/dynamo.rst.txt b/docs/v2.2.0/_sources/py_api/dynamo.rst.txt new file mode 100644 index 0000000000..fce5372d0e --- /dev/null +++ b/docs/v2.2.0/_sources/py_api/dynamo.rst.txt @@ -0,0 +1,36 @@ +.. _torch_tensorrt_dynamo_py: + +torch_tensorrt.dynamo +=================== + +.. currentmodule:: torch_tensorrt.dynamo + +.. automodule torch_tensorrt.ts + :undoc-members: + +.. automodule:: torch_tensorrt.dynamo + :members: + :undoc-members: + :show-inheritance: + +Functions +------------ + +.. autofunction:: compile + +.. autofunction:: trace + +.. autofunction:: export + + + +Classes +-------- + +.. autoclass:: CompilationSettings + +.. autoclass:: SourceIR + +.. autoclass:: runtime.TorchTensorRTModule + +.. autoclass:: runtime.PythonTorchTensorRTModule \ No newline at end of file diff --git a/docs/v2.2.0/_sources/py_api/fx.rst.txt b/docs/v2.2.0/_sources/py_api/fx.rst.txt new file mode 100644 index 0000000000..8ce591f5ee --- /dev/null +++ b/docs/v2.2.0/_sources/py_api/fx.rst.txt @@ -0,0 +1,31 @@ +.. _torch_tensorrt_fx_py: + +torch_tensorrt.fx +=================== + +.. currentmodule:: torch_tensorrt.fx + +.. automodule torch_tensorrt.ts + :undoc-members: + +.. automodule:: torch_tensorrt.fx + :members: + :undoc-members: + :show-inheritance: + +Functions +------------ + +.. autofunction:: compile + + +Classes +-------- + +.. autoclass:: TRTModule + +.. autoclass:: InputTensorSpec + +.. autoclass:: TRTInterpreter + +.. autoclass:: TRTInterpreterResult \ No newline at end of file diff --git a/docs/v2.2.0/_sources/py_api/logging.rst.txt b/docs/v2.2.0/_sources/py_api/logging.rst.txt new file mode 100644 index 0000000000..7918fe7f86 --- /dev/null +++ b/docs/v2.2.0/_sources/py_api/logging.rst.txt @@ -0,0 +1,13 @@ +.. _torch_tensorrt_logging_py: + +torch_tensorrt.logging +---------------------- + +.. currentmodule:: torch_tensorrt.logging + +.. automodule:: torch_tensorrt.logging + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: py torch_tensorrt.logging.Level diff --git a/docs/v2.2.0/_sources/py_api/ptq.rst.txt b/docs/v2.2.0/_sources/py_api/ptq.rst.txt new file mode 100644 index 0000000000..ec83662efb --- /dev/null +++ b/docs/v2.2.0/_sources/py_api/ptq.rst.txt @@ -0,0 +1,27 @@ +.. _torch_tensorrt_ptq_py: + +torch_tensorrt.ptq +=================== + +.. currentmodule:: torch_tensorrt.ptq + +.. automodule:: torch_tensorrt.ptq + :members: + :undoc-members: + :show-inheritance: + +Classes +--------- + +.. autoclass:: DataLoaderCalibrator + :members: + :special-members: __init__ + +.. autoclass:: CacheCalibrator + :members: + :special-members: __init__ + +Enums +------- + +.. autoclass:: CalibrationAlgo diff --git a/docs/v2.2.0/_sources/py_api/torch_tensorrt.rst.txt b/docs/v2.2.0/_sources/py_api/torch_tensorrt.rst.txt new file mode 100644 index 0000000000..22fda13ba2 --- /dev/null +++ b/docs/v2.2.0/_sources/py_api/torch_tensorrt.rst.txt @@ -0,0 +1,65 @@ +.. _torch_tensorrt_py: + +torch_tensorrt +=============== + +.. automodule torch_tensorrt + :undoc-members: + + + +.. automodule:: torch_tensorrt + :members: + :undoc-members: + :show-inheritance: + +Functions +------------ + +.. autofunction:: set_device + +.. autofunction:: compile + +.. autofunction:: convert_method_to_trt_engine + +.. autofunction:: get_build_info + +.. autofunction:: dump_build_info + +Classes +--------- + +.. autoclass:: Input + :members: + :special-members: __init__ + +.. autoclass:: Device + :members: + :special-members: __init__ + +.. autoclass:: TRTModuleNext + :members: + :special-members: __init__ + +Enums +------- + +.. autoclass:: dtype + +.. autoclass:: DeviceType + +.. autoclass:: EngineCapability + +.. autoclass:: TensorFormat + +Submodules +---------- + +.. toctree:: + :maxdepth: 1 + + logging + ptq + ts + fx + dynamo diff --git a/docs/v2.2.0/_sources/py_api/ts.rst.txt b/docs/v2.2.0/_sources/py_api/ts.rst.txt new file mode 100644 index 0000000000..45f6418eb7 --- /dev/null +++ b/docs/v2.2.0/_sources/py_api/ts.rst.txt @@ -0,0 +1,27 @@ +.. _torch_tensorrt_ts_py: + +torch_tensorrt.ts +=================== + +.. currentmodule:: torch_tensorrt.ts + +.. automodule torch_tensorrt.ts + :undoc-members: + +.. automodule:: torch_tensorrt.ts + :members: + :undoc-members: + :show-inheritance: + +Functions +------------ + +.. autofunction:: compile + +.. autofunction:: convert_method_to_trt_engine + +.. autofunction:: check_method_op_support + +.. autofunction:: embed_engine_in_new_module + +.. autofunction:: TensorRTCompileSpec diff --git a/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/changelog.rst.txt b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/changelog.rst.txt new file mode 100644 index 0000000000..d1ad81a0df --- /dev/null +++ b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/changelog.rst.txt @@ -0,0 +1,6 @@ + +********* +Changelog +********* + +v0.0.1 diff --git a/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/configuring.rst.txt b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/configuring.rst.txt new file mode 100644 index 0000000000..3afcb7bc62 --- /dev/null +++ b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/configuring.rst.txt @@ -0,0 +1,108 @@ + +************* +Configuration +************* + +You can configure different parts of the theme. + +Project-wide Configuration +========================== + +HTML Theme Options +------------------ + +The theme's project-wide options are defined in the ``pytorch_sphinx_theme/theme.conf`` +file of this repository, and can be defined in your project's ``conf.py`` via +``html_theme_options``. For example: + +.. code:: python + + html_theme_options = { + 'canonical_url': '', + 'analytics_id': '', + 'logo_only': False, + 'display_version': True, + 'prev_next_buttons_location': 'bottom', + 'style_external_links': False, + 'vcs_pageview_mode': '', + # Toc options + 'collapse_navigation': True, + 'sticky_navigation': True, + 'navigation_depth': 4, + 'includehidden': True, + 'titles_only': False + } + +The following options are available: + +Base options +~~~~~~~~~~~~ + +* ``canonical_url`` String. This will specify a `canonical url `__ + to let search engines know they should give higher ranking to latest version of the docs. + The url points to the root of the documentation and requires a trailing slash. +* ``analytics_id`` String. Change the Google Analytics ID that is included on pages. +* ``display_version`` Bool. With this disabled, the version number isn't shown at the top of the sidebar. +* ``prev_next_buttons_location`` String. can take the value ``bottom``, ``top``, ``both`` , or ``None`` + and will display the "Next" and "Previous" buttons accordingly. +* ``style_external_links`` Bool. Add an icon next to external links. Defaults to ``False``. +* ``vcs_pageview_mode`` String. Changes how to view files when using `display_github`, `display_gitlab`, etc. + When using Github or Gitlab this can be: `blob` (default), `edit`, or `raw`, + on Bitbucket, this can be either: `view` (default) or `edit`. + +TOC Options +~~~~~~~~~~~ + +These effect how we display the Table of Contents in the side bar. You can read more about them here: http://www.sphinx-doc.org/en/stable/templating.html#toctree + +* ``collapse_navigation`` Bool. With this enabled, you will lose the ``[+]`` drop downs next to each section in the sidebar. +* ``sticky_navigation`` Bool. This causes the sidebar to scroll with the main page content as you scroll the page. +* ``navigation_depth`` Int. Indicate the max depth of the tree; by default, 4 levels are included; + set it to -1 to allow unlimited depth. +* ``includehidden`` Bool. Specifies if the sidebar includes toctrees marked with the ``:hidden:`` option +* ``titles_only`` Bool. If True, removes headers within a page from the sidebar. + +.. note:: + + Setting ``collapse_navigation`` to False and using a high ``navigation_depth`` + can cause projects with many files and a deep file structure to generate HTML files + that are significantly larger in file size and much longer compilation times. + + +HTML Context Options +-------------------- + +TODO. + + +Page-level Configuration +======================== + +Pages support metadata that changes how the theme renders. +You can currently add the following: + +* ``:github_url:`` This will force the "Edit on GitHub" to the configured URL +* ``:bitbucket_url:`` This will force the "Edit on Bitbucket" to the configured URL +* ``:gitlab_url:`` This will force the "Edit on GitLab" to the configured URL + + +How the Table of Contents builds +================================ + +Currently the left menu will build based upon any ``toctree(s)`` defined in your ``index.rst`` file. +It outputs 2 levels of depth, which should give your visitors a high level of access to your +docs. If no toctrees are set the theme reverts to sphinx's usual local toctree. + +It's important to note that if you don't follow the same styling for your rST headers across +your documents, the toctree will misbuild, and the resulting menu might not show the correct +depth when it renders. + +Also note that by default the table of contents is set with ``includehidden=True``. This allows you +to set a hidden toc in your index file with the `:hidden: `_ property that will allow you +to build a toc without it rendering in your index. + +By default, the navigation will "stick" to the screen as you scroll. However if your toc +is vertically too large, it will revert to static positioning. To disable the sticky nav +altogether change the setting in ``conf.py``. + +.. _hidden: http://sphinx-doc.org/markup/toctree.html diff --git a/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/api.rst.txt b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/api.rst.txt new file mode 100644 index 0000000000..b49bc248ac --- /dev/null +++ b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/api.rst.txt @@ -0,0 +1,53 @@ + +********************* +:mod:`test_py_module` +********************* + +.. contents:: Table of Contents + +.. automodule:: test_py_module.test + :members: + :private-members: + :special-members: + +Generated Index +=============== + +Part of the sphinx build process in generate and index file: :ref:`genindex`. + + +Optional parameter args +======================= + +At this point optional parameters `cannot be generated from code`_. +However, some projects will manually do it, like so: + +This example comes from `django-payments module docs`_. + +.. class:: payments.dotpay.DotpayProvider(seller_id, pin[, channel=0[, lock=False], lang='pl']) + + This backend implements payments using a popular Polish gateway, `Dotpay.pl `_. + + Due to API limitations there is no support for transferring purchased items. + + + :param seller_id: Seller ID assigned by Dotpay + :param pin: PIN assigned by Dotpay + :param channel: Default payment channel (consult reference guide) + :param lang: UI language + :param lock: Whether to disable channels other than the default selected above + +.. _cannot be generated from code: https://groups.google.com/forum/#!topic/sphinx-users/_qfsVT5Vxpw +.. _django-payments module docs: http://django-payments.readthedocs.org/en/latest/modules.html#payments.authorizenet.AuthorizeNetProvide + + +Data +==== + +.. data:: Data_item_1 + Data_item_2 + Data_item_3 + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce congue elit eu hendrerit mattis. + +Some data link :data:`Data_item_1`. diff --git a/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/demo.rst.txt b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/demo.rst.txt new file mode 100644 index 0000000000..3ad6e46b15 --- /dev/null +++ b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/demo.rst.txt @@ -0,0 +1,475 @@ +.. This is a comment. Note how any initial comments are moved by + transforms to after the document title, subtitle, and docinfo. + +.. demo.rst from: http://docutils.sourceforge.net/docs/user/rst/demo.txt + +.. |EXAMPLE| image:: static/yi_jing_01_chien.jpg + :width: 1em + +********************** +Paragraph Level Markup +********************** + +.. contents:: Table of Contents + +Inline Markup +============= + +Paragraphs contain text and may contain inline markup: *emphasis*, **strong emphasis**, ``inline literals``, +standalone hyperlinks (http://www.python.org), external hyperlinks (Python_), internal cross-references (example_), +external hyperlinks with embedded URIs (`Python web site `__), footnote references +(manually numbered [1]_, anonymous auto-numbered [#]_, labeled auto-numbered [#label]_, or symbolic [*]_), +citation references ([12]_), substitution references (|example|), and _`inline hyperlink targets` +(see Targets_ below for a reference back to here). Character-level inline markup is also possible +(although exceedingly ugly!) in *re*\ ``Structured``\ *Text*. Problems are indicated by |problematic| +text (generated by processing errors; this one is intentional). + +Also with ``sphinx.ext.autodoc``, which I use in the demo, I can link to :class:`test_py_module.test.Foo`. +It will link you right my code documentation for it. + +The default role for interpreted text is `Title Reference`. Here are some explicit interpreted text roles: +a PEP reference (:PEP:`287`); an RFC reference (:RFC:`2822`); a :sub:`subscript`; a :sup:`superscript`; +and explicit roles for :emphasis:`standard` :strong:`inline` :literal:`markup`. + +GUI labels are a useful way to indicate that :guilabel:`Some action` is to be taken by the user. +The GUI label should not run over ``line-height`` so as not to :guilabel:`interfere` with text from adjacent lines. + +Key-bindings indicate that the read is to press a button on the keyboard or mouse, +for example :kbd:`MMB` and :kbd:`Shift-MMB`. Another useful markup to indicate a user action +is to use ``menuselection`` this can be used to show short and long menus in software. +For example, and ``menuselection`` can be seen here that breaks is too long to fit on this line. +:menuselection:`My --> Software --> Some menu --> Some sub menu 1 --> sub menu 2`. + +.. DO NOT RE-WRAP THE FOLLOWING PARAGRAPH! + +Let's test wrapping and whitespace significance in inline literals: +``This is an example of --inline-literal --text, --including some-- +strangely--hyphenated-words. Adjust-the-width-of-your-browser-window +to see how the text is wrapped. -- ---- -------- Now note the +spacing between the words of this sentence (words +should be grouped in pairs).`` + +If the ``--pep-references`` option was supplied, there should be a live link to PEP 258 here. + +Math +==== + +This is a test. Here is an equation: +:math:`X_{0:5} = (X_0, X_1, X_2, X_3, X_4)`. +Here is another: + +.. math:: + :label: This is a label + + \nabla^2 f = + \frac{1}{r^2} \frac{\partial}{\partial r} + \left( r^2 \frac{\partial f}{\partial r} \right) + + \frac{1}{r^2 \sin \theta} \frac{\partial f}{\partial \theta} + \left( \sin \theta \, \frac{\partial f}{\partial \theta} \right) + + \frac{1}{r^2 \sin^2\theta} \frac{\partial^2 f}{\partial \phi^2} + +You can add a link to equations like the one above :eq:`This is a label` by using ``:eq:``. + +Meta +==== + +.. meta:: + :keywords: reStructuredText, demonstration, demo, parser + :description lang=en: A demonstration of the reStructuredText + markup language, containing examples of all basic + constructs and many advanced constructs. + +Blocks +====== + +Literal Blocks +-------------- + +Literal blocks are indicated with a double-colon ("::") at the end of +the preceding paragraph (over there ``-->``). They can be indented:: + + if literal_block: + text = 'is left as-is' + spaces_and_linebreaks = 'are preserved' + markup_processing = None + +Or they can be quoted without indentation:: + +>> Great idea! +> +> Why didn't I think of that? + +Line Blocks +----------- + +| This is a line block. It ends with a blank line. +| Each new line begins with a vertical bar ("|"). +| Line breaks and initial indents are preserved. +| Continuation lines are wrapped portions of long lines; + they begin with a space in place of the vertical bar. +| The left edge of a continuation line need not be aligned with + the left edge of the text above it. + +| This is a second line block. +| +| Blank lines are permitted internally, but they must begin with a "|". + +Take it away, Eric the Orchestra Leader! + + | A one, two, a one two three four + | + | Half a bee, philosophically, + | must, *ipso facto*, half not be. + | But half the bee has got to be, + | *vis a vis* its entity. D'you see? + | + | But can a bee be said to be + | or not to be an entire bee, + | when half the bee is not a bee, + | due to some ancient injury? + | + | Singing... + +Block Quotes +------------ + +Block quotes consist of indented body elements: + + My theory by A. Elk. Brackets Miss, brackets. This theory goes + as follows and begins now. All brontosauruses are thin at one + end, much much thicker in the middle and then thin again at the + far end. That is my theory, it is mine, and belongs to me and I + own it, and what it is too. + + -- Anne Elk (Miss) + +Doctest Blocks +-------------- + +>>> print 'Python-specific usage examples; begun with ">>>"' +Python-specific usage examples; begun with ">>>" +>>> print '(cut and pasted from interactive Python sessions)' +(cut and pasted from interactive Python sessions) + +Code Blocks +----------- + +.. parsed-literal:: + + # parsed-literal test + curl -O http://someurl/release-|version|.tar-gz + + +.. code-block:: json + :caption: Code Blocks can have captions. + + { + "windows": [ + { + "panes": [ + { + "shell_command": [ + "echo 'did you know'", + "echo 'you can inline'" + ] + }, + { + "shell_command": "echo 'single commands'" + }, + "echo 'for panes'" + ], + "window_name": "long form" + } + ], + "session_name": "shorthands" + } + +Emphasized lines with line numbers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: python + :linenos: + :emphasize-lines: 3,5 + + def some_function(): + interesting = False + print 'This line is highlighted.' + print 'This one is not...' + print '...but this one is.' + +Sidebar +======= + +.. sidebar:: Ch'ien / The Creative + + .. image:: static/yi_jing_01_chien.jpg + + *Above* CH'IEN THE CREATIVE, HEAVEN + + *Below* CH'IEN THE CREATIVE, HEAVEN + +The first hexagram is made up of six unbroken lines. These unbroken lines stand for the primal power, +which is light-giving, active, strong, and of the spirit. The hexagram is consistently strong in character, +and since it is without weakness, its essence is power or energy. Its image is heaven. +Its energy is represented as unrestricted by any fixed conditions in space and is therefore conceived of as motion. +Time is regarded as the basis of this motion. +Thus the hexagram includes also the power of time and the power of persisting in time, that is, duration. + +The power represented by the hexagram is to be interpreted in a dual sense in terms of its action +on the universe and of its action on the world of men. In relation to the universe, the hexagram expresses the strong, +creative action of the Deity. In relation to the human world, it denotes the creative action of the holy man or sage, +of the ruler or leader of men, who through his power awakens and develops their higher nature. + +Code with Sidebar +----------------- + +.. sidebar:: A code example + + With a sidebar on the right. + +.. literalinclude:: test_py_module/test.py + :language: python + :caption: Literal includes can also have captions. + :linenos: + :lines: 1-40 + +References +========== + +Footnotes +--------- + +.. [1] A footnote contains body elements, consistently indented by at + least 3 spaces. + + This is the footnote's second paragraph. + +.. [#label] Footnotes may be numbered, either manually (as in [1]_) or + automatically using a "#"-prefixed label. This footnote has a + label so it can be referred to from multiple places, both as a + footnote reference ([#label]_) and as a hyperlink reference + (label_). + +.. [#] This footnote is numbered automatically and anonymously using a + label of "#" only. + +.. [*] Footnotes may also use symbols, specified with a "*" label. + Here's a reference to the next footnote: [*]_. + +.. [*] This footnote shows the next symbol in the sequence. + +.. [4] Here's an unreferenced footnote, with a reference to a + nonexistent footnote: [5]_. + +Citations +--------- + +.. [11] This is the citation I made, let's make this extremely long so that we can tell that it doesn't follow the normal responsive table stuff. + +.. [12] This citation has some ``code blocks`` in it, maybe some **bold** and + *italics* too. Heck, lets put a link to a meta citation [13]_ too. + +.. [13] This citation will have two backlinks. + + +Here's a reference to the above, [12]_, and a [nonexistent]_ citation. + +Here is another type of citation: `citation` + +Glossary +-------- + +This is a glossary with definition terms for thing like :term:`Writing`: + +.. glossary:: + + Documentation + Provides users with the knowledge they need to use something. + + Reading + The process of taking information into ones mind through the use of eyes. + + Writing + The process of putting thoughts into a medium for other people to :term:`read `. + +Targets +------- + +.. _example: + +This paragraph is pointed to by the explicit "example" target. +A reference can be found under `Inline Markup`_, above. `Inline +hyperlink targets`_ are also possible. + +Section headers are implicit targets, referred to by name. See +Targets_, which is a subsection of `Body Elements`_. + +Explicit external targets are interpolated into references such as "Python_". + +.. _Python: http://www.python.org/ + +Targets may be indirect and anonymous. Thus `this phrase`__ may also +refer to the Targets_ section. + +__ Targets_ + +Here's a `hyperlink reference without a target`_, which generates an error. + + +Directives +========== + +Contents +-------- + +.. contents:: :local: + +These are just a sample of the many reStructuredText Directives. For others, please see: +http://docutils.sourceforge.net/docs/ref/rst/directives.html. + + +Centered text +------------- + +You can create a statement with centered text with ``.. centered::`` + +.. centered:: This is centered text! + +Images & Figures +---------------- + +Images +^^^^^^ + +An image directive (also clickable -- a hyperlink reference): + +.. image:: static/yi_jing_01_chien.jpg + :target: directives_ + +Figures +^^^^^^^ + +.. figure:: static/yi_jing_01_chien.jpg + :alt: reStructuredText, the markup syntax + + A figure is an image with a caption and/or a legend: + + +------------+-----------------------------------------------+ + | re | Revised, revisited, based on 're' module. | + +------------+-----------------------------------------------+ + | Structured | Structure-enhanced text, structuredtext. | + +------------+-----------------------------------------------+ + | Text | Well it is, isn't it? | + +------------+-----------------------------------------------+ + + This paragraph is also part of the legend. + +A figure directive with center alignment + +.. figure:: static/yi_jing_01_chien.jpg + :align: center + + This caption should be centered. + +Admonitions +----------- + +.. Attention:: Directives at large. + +.. Caution:: Don't take any wooden nickels. + +.. DANGER:: Mad scientist at work! + +.. Error:: Does not compute. + +.. Hint:: It's bigger than a bread box. + +.. Important:: + - Wash behind your ears. + - Clean up your room. + + - Including the closet. + - The bathroom too. + + - Take the trash out of the bathroom. + - Clean the sink. + - Call your mother. + - Back up your data. + +.. Note:: This is a note. + Equations within a note: + :math:`G_{\mu\nu} = 8 \pi G (T_{\mu\nu} + \rho_\Lambda g_{\mu\nu})`. + +.. Tip:: 15% if the service is good. + + +---------+ + | Example | + +=========+ + | Thing1 | + +---------+ + | Thing2 | + +---------+ + | Thing3 | + +---------+ + +.. WARNING:: Strong prose may provoke extreme mental exertion. + Reader discretion is strongly advised. + +.. admonition:: And, by the way... + + You can make up your own admonition too. + +Topics, Sidebars, and Rubrics +----------------------------- + +.. sidebar:: Sidebar Title + :subtitle: Optional Subtitle + + This is a sidebar. It is for text outside the flow of the main + text. + + .. rubric:: This is a rubric inside a sidebar + + Sidebars often appears beside the main text with a border and + background color. + +.. topic:: Topic Title + + This is a topic. + +.. rubric:: This is a rubric + +Target Footnotes +---------------- + +.. target-notes:: + +Replacement Text +---------------- + +I recommend you try |Python|_. + +.. |Python| replace:: Python, *the* best language around + +Compound Paragraph +------------------ + +.. compound:: + + This paragraph contains a literal block:: + + Connecting... OK + Transmitting data... OK + Disconnecting... OK + + and thus consists of a simple paragraph, a literal block, and + another simple paragraph. Nonetheless it is semantically *one* + paragraph. + +This construct is called a *compound paragraph* and can be produced +with the "compound" directive. + +Download Links +============== + +:download:`This long long long long long long long long long long long long long long long download link should be blue, normal weight text with a leading icon, and should wrap white-spaces ` diff --git a/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/lists_tables.rst.txt b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/lists_tables.rst.txt new file mode 100644 index 0000000000..4c7642e5c5 --- /dev/null +++ b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/lists_tables.rst.txt @@ -0,0 +1,302 @@ + +************** +Lists & Tables +************** + +.. contents:: Table of Contents + +Lists +===== + +Enumerated Lists +---------------- + +1. Arabic numerals. + + a) lower alpha) + + (i) (lower roman) + + A. upper alpha. + + I) upper roman) + +2. Lists that don't start at 1: + + 3. Three + + 4. Four + + C. C + + D. D + + iii. iii + + iv. iv + +#. List items may also be auto-enumerated. + +Definition Lists +---------------- + +Term + Definition +Term : classifier + Definition paragraph 1. + + Definition paragraph 2. +Term + Definition + + +Option Lists +------------ + +For listing command-line options: + +-a command-line option "a" +-b file options can have arguments + and long descriptions +--long options can be long also +--input=file long options can also have + arguments + +--very-long-option + The description can also start on the next line. + + The description may contain multiple body elements, + regardless of where it starts. + +-x, -y, -z Multiple options are an "option group". +-v, --verbose Commonly-seen: short & long options. +-1 file, --one=file, --two file + Multiple options with arguments. +/V DOS/VMS-style options too + +There must be at least two spaces between the option and the description. + +Field list +---------- + +.. bibliographic fields (which also require a transform): + +:Author: David Goodger +:Address: 123 Example Street + Example, EX Canada + A1B 2C3 +:Contact: docutils-develop@lists.sourceforge.net +:Authors: Me; Myself; I +:organization: humankind +:date: $Date: 2012-01-03 19:23:53 +0000 (Tue, 03 Jan 2012) $ +:status: This is a "work in progress" +:revision: $Revision: 7302 $ +:version: 1 +:copyright: This document has been placed in the public domain. You + may do with it as you wish. You may copy, modify, + redistribute, reattribute, sell, buy, rent, lease, + destroy, or improve it, quote it at length, excerpt, + incorporate, collate, fold, staple, or mutilate it, or do + anything else to it that your or anyone else's heart + desires. +:field name: This is a generic bibliographic field. +:field name 2: + Generic bibliographic fields may contain multiple body elements. + + Like this. + +:Dedication: + + For Docutils users & co-developers. + +:abstract: + + This document is a demonstration of the reStructuredText markup + language, containing examples of all basic reStructuredText + constructs and many advanced constructs. + +Bullet Lists +------------ + +- A bullet list + + + Nested bullet list. + + Nested item 2. + +- Item 2. + + Paragraph 2 of item 2. + + * Nested bullet list. + * Nested item 2. + + - Third level. + - Item 2. + + * Nested item 3. + +- ``inline literall`` +- ``inline literall`` +- ``inline literall`` + +Second list level +^^^^^^^^^^^^^^^^^ + +- here is a list in a second-level section. +- `yahoo `_ +- `yahoo `_ + + - `yahoo `_ + - here is an inner bullet ``oh`` + + - one more ``with an inline literally``. `yahoo `_ + + heh heh. child. try to beat this embed: + + .. literalinclude:: test_py_module/test.py + :language: python + :linenos: + :lines: 1-10 + - and another. `yahoo `_ + - `yahoo `_ + - ``hi`` +- and hehe + +But deeper down the rabbit hole +""""""""""""""""""""""""""""""" + +- I kept saying that, "deeper down the rabbit hole". `yahoo `_ + + - I cackle at night `yahoo `_. +- I'm so lonely here in GZ ``guangzhou`` +- A man of python destiny, hopes and dreams. `yahoo `_ + + - `yahoo `_ + + - `yahoo `_ ``hi`` + - ``destiny`` + +Hlists +------ + +.. hlist:: + :columns: 2 + + - First item + - Second item + - Third item + - Forth item + - Fifth item + - Sixths item + +.. rubric:: Hlist with images + +.. hlist:: + :columns: 2 + + - .. figure:: static/yi_jing_01_chien.jpg + + This is a short caption for a figure. + + - .. figure:: static/yi_jing_01_chien.jpg + + This is a long caption for a figure. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Donec porttitor dolor in odio posuere, vitae ornare libero mattis. In lobortis justo vestibulum nibh aliquet, non. + +Numbered List +------------- + +#. One, +#. Two. +#. Three with long text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Sed feugiat sagittis neque quis eleifend. Duis rutrum lectus sit amet mattis suscipit. + +- A) Using bullets and letters. (A) +- B) Using bullets and letters. (B) +- C) Using bullets and letters. (C) + +Tables +====== + +Grid Tables +----------- + +Here's a grid table followed by a simple table: + ++------------------------+------------+----------+----------+ +| Header row, column 1 | Header 2 | Header 3 | Header 4 | +| (header rows optional) | | | | ++========================+============+==========+==========+ +| body row 1, column 1 | column 2 | column 3 | column 4 | ++------------------------+------------+----------+----------+ +| body row 2 | Cells may span columns. | ++------------------------+------------+---------------------+ +| body row 3 | Cells may | - Table cells | ++------------------------+ span rows. | - contain | +| body row 4 | | - body elements. | ++------------------------+------------+----------+----------+ +| body row 5 | Cells may also be | | +| | empty: ``-->`` | | ++------------------------+-----------------------+----------+ + +===== ===== ====== + Inputs Output +------------ ------ + A B A or B +===== ===== ====== +False False False +True False True +False True True +True True True +===== ===== ====== + +Giant Tables +^^^^^^^^^^^^ + ++------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+ +| Header 1 | Header 2 | Header 3 | Header 1 | Header 2 | Header 3 | Header 1 | Header 2 | Header 3 | Header 1 | Header 2 | Header 3 | ++============+============+===========+============+============+===========+============+============+===========+============+============+===========+ +| body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | ++------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+ +| body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | ++------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+ +| body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | ++------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+ +| body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | body row 1 | column 2 | column 3 | ++------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+------------+------------+-----------+ + +List Tables +----------- + +.. list-table:: List tables can have captions like this one. + :widths: 10 5 10 50 + :header-rows: 1 + :stub-columns: 1 + + * - List table + - Header 1 + - Header 2 + - Header 3 long. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet mauris arcu. + * - Stub Row 1 + - Row 1 + - Column 2 + - Column 3 long. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet mauris arcu. + * - Stub Row 2 + - Row 2 + - Column 2 + - Column 3 long. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet mauris arcu. + * - Stub Row 3 + - Row 3 + - Column 2 + - Column 3 long. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet mauris arcu. + +.. list-table:: This is a list table with images in it. + + * - .. figure:: static/yi_jing_01_chien.jpg + + This is a short caption for a figure. + + - .. figure:: static/yi_jing_01_chien.jpg + + This is a long caption for a figure. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Donec porttitor dolor in odio posuere, vitae ornare libero mattis. In lobortis justo vestibulum nibh aliquet, non. diff --git a/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/long.rst.txt b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/long.rst.txt new file mode 100644 index 0000000000..26b1add9d1 --- /dev/null +++ b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/long.rst.txt @@ -0,0 +1,214 @@ + +*************** +Long Sticky Nav +*************** + +.. contents:: Table of Contents + +This section demonstrates how the 'sticky_navigation' setting behaves when the menu is very long. +When this section is selected, it will make the menu and the main area scroll when you are at the top of the page. + + +Example Menu 1 +============== + +Just a place holder... + + +Example Menu 2 +============== + +Just a place holder... + + +Example Menu 3 +============== + +Just a place holder... + + +Example Menu 4 +============== + +Just a place holder... + + +Example Menu 5 +============== + +Just a place holder... + + +Example Menu 6 +============== + +Just a place holder... + + +Example Menu 7 +============== + +Just a place holder... + + +Example Menu 8 +============== + +Just a place holder... + + +Example Menu 9 +============== + +Just a place holder... + + +Example Menu 10 +=============== + +Just a place holder... + + +Example Menu 11 +=============== + +Just a place holder... + + +Example Menu 12 +=============== + +Just a place holder... + + +Example Menu 13 +=============== + +Just a place holder... + + +Example Menu 14 +=============== + +Just a place holder... + + +Example Menu 15 +=============== + +Just a place holder... + + +Example Menu 16 +=============== + +Just a place holder... + + +Example Menu 17 +=============== + +Just a place holder... + + +Example Menu 18 +=============== + +Just a place holder... + + +Example Menu 19 +=============== + +Just a place holder... + + +Example Menu 20 +=============== + +Just a place holder... + +Example Submenu 1 +================= + +Just a place holder... + +Submenu 1 +--------- + +Just a place holder... + +Subsubmenu 1 +^^^^^^^^^^^^ + +Just a place holder... + +Subsubmenu 2 +^^^^^^^^^^^^ + +Just a place holder... + +Submenu 2 +--------- + +Just a place holder... + +Subsubmenu 1 +^^^^^^^^^^^^ + +Just a place holder... + +Submenu 3 +--------- + +Just a place holder... + +Submenu 4 +--------- + +Just a place holder... + +Submenu 5 +--------- + +Just a place holder... + +Example Submenu 2 +================= + +Just a place holder... + +Submenu 1 +--------- + +Just a place holder... + +Subsubmenu 1 +^^^^^^^^^^^^ + +Just a place holder... + +Submenu 2 +--------- + +Just a place holder... + +Subsubmenu 1 +^^^^^^^^^^^^ + +Just a place holder... + +Submenu 3 +--------- + +Just a place holder... + +Submenu 4 +--------- + +Just a place holder... + +Submenu 5 +--------- + +Just a place holder... diff --git a/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/structure.rst.txt b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/structure.rst.txt new file mode 100644 index 0000000000..178ed63f07 --- /dev/null +++ b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/demo/structure.rst.txt @@ -0,0 +1,101 @@ + +******************* +Structural Elements +******************* + +.. contents:: Table of Contents + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lorem neque, interdum in ipsum nec, +finibus dictum velit. Ut eu efficitur arcu, id aliquam erat. In sit amet diam gravida, imperdiet tellus eu, +gravida nisl. Praesent aliquet odio eget libero elementum, quis rhoncus tellus tincidunt. +Suspendisse quis volutpat ipsum. Sed lobortis scelerisque tristique. Aenean condimentum risus tellus, +quis accumsan ipsum laoreet ut. Integer porttitor maximus suscipit. Mauris in posuere sapien. +Aliquam accumsan feugiat ligula, nec fringilla libero commodo sed. Proin et erat pharetra. + +--------- + +Etiam turpis ante, luctus sed velit tristique, finibus volutpat dui. Nam sagittis vel ante nec malesuada. +Praesent dignissim mi nec ornare elementum. Nunc eu augue vel sem dignissim cursus sed et nulla. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. +Pellentesque dictum dui sem, non placerat tortor rhoncus in. Sed placerat nulla at rhoncus iaculis. + +Document Section +================ + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed condimentum nulla vel neque venenatis, +nec placerat lorem placerat. Cras purus eros, gravida vitae tincidunt id, vehicula nec nulla. +Fusce aliquet auctor cursus. Phasellus ex neque, vestibulum non est vitae, viverra fringilla tortor. +Donec vestibulum convallis justo, a faucibus lorem vulputate vel. Aliquam cursus odio eu felis sodales aliquet. +Aliquam erat volutpat. Maecenas eget dictum mauris. Suspendisse arcu eros, condimentum eget risus sed, +luctus efficitur arcu. Cras ut dictum mi. Nulla congue interdum lorem, semper semper enim commodo nec. + +Document Subsection +------------------- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam efficitur in eros et blandit. Nunc maximus, +nisl at auctor vestibulum, justo ex sollicitudin ligula, id faucibus urna orci tristique nisl. +Duis auctor rutrum orci, in ornare lacus condimentum quis. Quisque arcu velit, facilisis quis interdum ac, +hendrerit auctor mauris. Curabitur urna nibh, porttitor at ante sit amet, vestibulum interdum dolor. +Duis dictum elit orci, tincidunt imperdiet sem pellentesque et. In vehicula pellentesque varius. +Phasellus a turpis sollicitudin, bibendum massa et, imperdiet neque. Integer quis sapien in magna rutrum bibendum. +Integer cursus ex sed magna vehicula finibus. Proin tempus orci quis dolor tempus, nec condimentum odio vestibulum. +Etiam efficitur sollicitudin libero, tincidunt volutpat ligula interdum sed. + +Document Subsubsection +^^^^^^^^^^^^^^^^^^^^^^ + +Donec non rutrum lorem. Aenean sagittis metus at pharetra fringilla. Nunc sapien dolor, cursus sed nisi at, +pretium tristique lectus. Sed pellentesque leo lectus, et convallis ipsum euismod a. +Integer at leo vitae felis pretium aliquam fringilla quis odio. Sed pharetra enim accumsan feugiat pretium. +Maecenas at pharetra tortor. Morbi semper eget mi vel finibus. Cras rutrum nulla eros, id feugiat arcu pellentesque ut. +Sed finibus tortor ac nisi ultrices viverra. Duis feugiat malesuada sapien, at commodo ante porttitor ac. +Curabitur posuere mauris mi, vel ornare orci scelerisque sit amet. Suspendisse nec fringilla dui. + +Document Paragraph +"""""""""""""""""" + +Pellentesque nec est in odio ultrices elementum. Vestibulum et hendrerit sapien, quis vulputate turpis. +Suspendisse potenti. Curabitur tristique sit amet lectus non viverra. Phasellus rutrum dapibus turpis sed imperdiet. +Mauris maximus viverra ante. Donec eu egestas mauris. Morbi vulputate tincidunt euismod. Integer vel porttitor neque. +Donec at lacus suscipit, lacinia lectus vel, sagittis lectus. + +********************* +Structural Elements 2 +********************* + +Etiam turpis ante, luctus sed velit tristique, finibus volutpat dui. Nam sagittis vel ante nec malesuada. +Praesent dignissim mi nec ornare elementum. Nunc eu augue vel sem dignissim cursus sed et nulla. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. +Pellentesque dictum dui sem, non placerat tortor rhoncus in. Sed placerat nulla at rhoncus iaculis. + +Document Section +================ + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed condimentum nulla vel neque venenatis, +nec placerat lorem placerat. Cras purus eros, gravida vitae tincidunt id, vehicula nec nulla. +Fusce aliquet auctor cursus. Phasellus ex neque, vestibulum non est vitae, viverra fringilla tortor. +Donec vestibulum convallis justo, a faucibus lorem vulputate vel. Aliquam cursus odio eu felis sodales aliquet. +Aliquam erat volutpat. Maecenas eget dictum mauris. Suspendisse arcu eros, condimentum eget risus sed, +luctus efficitur arcu. Cras ut dictum mi. Nulla congue interdum lorem, semper semper enim commodo nec. + +Document Subsection +------------------- + +.. figure:: static/yi_jing_01_chien.jpg + :align: right + :figwidth: 200px + + This is a caption for a figure. Text should wrap around the caption. + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam efficitur in eros et blandit. Nunc maximus, +nisl at auctor vestibulum, justo ex sollicitudin ligula, id faucibus urna orci tristique nisl. +Duis auctor rutrum orci, in ornare lacus condimentum quis. Quisque arcu velit, facilisis quis interdum ac, +hendrerit auctor mauris. Curabitur urna nibh, porttitor at ante sit amet, vestibulum interdum dolor. +Duis dictum elit orci, tincidunt imperdiet sem pellentesque et. In vehicula pellentesque varius. +Phasellus a turpis sollicitudin, bibendum massa et, imperdiet neque. Integer quis sapien in magna rutrum bibendum. +Integer cursus ex sed magna vehicula finibus. Proin tempus orci quis dolor tempus, nec condimentum odio vestibulum. +Etiam efficitur sollicitudin libero, tincidunt volutpat ligula interdum sed. Praesent congue sagittis nisl et suscipit. +Vivamus sagittis risus et egestas commodo.Cras venenatis arcu in pharetra interdum. +Donec quis metus porttitor tellus cursus lobortis. Quisque et orci magna. Fusce rhoncus mi mi, +at vehicula massa rhoncus quis. Mauris augue leo, pretium eget molestie vitae, efficitur nec nulla. +In hac habitasse platea dictumst. Sed sit amet imperdiet purus. diff --git a/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/index.rst.txt b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/index.rst.txt new file mode 100644 index 0000000000..ba42326fd7 --- /dev/null +++ b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/index.rst.txt @@ -0,0 +1,27 @@ +.. include:: ../README.rst + +.. toctree:: + :caption: Theme Documentation + :maxdepth: 2 + + installing + configuring + changelog + + +.. toctree:: + :maxdepth: 2 + :numbered: + :caption: Demo Documents + + demo/structure + demo/demo + demo/lists_tables + demo/api + +.. toctree:: + :maxdepth: 3 + :numbered: + :caption: This is an incredibly long caption for a long menu + + demo/long diff --git a/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/installing.rst.txt b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/installing.rst.txt new file mode 100644 index 0000000000..df406b999d --- /dev/null +++ b/docs/v2.2.0/_sources/src/pytorch-sphinx-theme/docs/installing.rst.txt @@ -0,0 +1,17 @@ + +************ +Installation +************ + +Via Git or Download +=================== + +Symlink or subtree the ``pytorch_sphinx_theme`` repository into your documentation at +``docs/_themes/pytorch_sphinx_theme`` then add the following two settings to your Sphinx +``conf.py`` file: + +.. code:: python + + html_theme = "pytorch_sphinx_theme" + html_theme_path = ["_themes", ] + diff --git a/docs/v2.2.0/_sources/ts/creating_torchscript_module_in_python.rst.txt b/docs/v2.2.0/_sources/ts/creating_torchscript_module_in_python.rst.txt new file mode 100644 index 0000000000..1d1cdba574 --- /dev/null +++ b/docs/v2.2.0/_sources/ts/creating_torchscript_module_in_python.rst.txt @@ -0,0 +1,140 @@ +.. _creating_a_ts_mod: + +Creating a TorchScript Module +------------------------------ +TorchScript is a way to create serializable and optimizable models from PyTorch code. +PyTorch has detailed documentation on how to do this https://pytorch.org/tutorials/beginner/Intro_to_TorchScript_tutorial.html but briefly here is the +here is key background information and the process: + +PyTorch programs are based around ``Module`` s which can be used to compose higher level modules. ``Modules`` contain a constructor to set up the modules, parameters and sub-modules +and a forward function which describes how to use the parameters and submodules when the module is invoked. + +For example, we can define a LeNet module like this: + +.. code-block:: python + :linenos: + + import torch.nn as nn + import torch.nn.functional as F + + + class LeNetFeatExtractor(nn.Module): + def __init__(self): + super(LeNetFeatExtractor, self).__init__() + self.conv1 = nn.Conv2d(1, 6, 3) + self.conv2 = nn.Conv2d(6, 16, 3) + + def forward(self, x): + x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) + x = F.max_pool2d(F.relu(self.conv2(x)), 2) + return x + + + class LeNetClassifier(nn.Module): + def __init__(self): + super(LeNetClassifier, self).__init__() + self.fc1 = nn.Linear(16 * 6 * 6, 120) + self.fc2 = nn.Linear(120, 84) + self.fc3 = nn.Linear(84, 10) + + def forward(self, x): + x = torch.flatten(x, 1) + x = F.relu(self.fc1(x)) + x = F.relu(self.fc2(x)) + x = self.fc3(x) + return x + + + class LeNet(nn.Module): + def __init__(self): + super(LeNet, self).__init__() + self.feat = LeNetFeatExtractor() + self.classifer = LeNetClassifier() + + def forward(self, x): + x = self.feat(x) + x = self.classifer(x) + return x + +. + + Obviously you may want to consolidate such a simple model into a single module but we can see the composability of PyTorch here + +From here are two pathways for going from PyTorch Python code to TorchScript code: Tracing and Scripting. + +Tracing follows the path of execution when the module is called and records what happens. +To trace an instance of our LeNet module, we can call ``torch.jit.trace`` with an example input. + +.. code-block:: python + + import torch + + model = LeNet() + input_data = torch.empty([1, 1, 32, 32]) + traced_model = torch.jit.trace(model, input_data) + +Scripting actually inspects your code with a compiler and generates an equivalent TorchScript program. The difference is that since tracing +is following the execution of your module, it cannot pick up control flow for instance. By working from the Python code, the compiler can +include these components. We can run the script compiler on our LeNet module by calling ``torch.jit.script`` + +.. code-block:: python + + import torch + + model = LeNet() + script_model = torch.jit.script(model) + +There are reasons to use one path or another, the PyTorch documentation has information on how to choose. From a Torch-TensorRT prespective, there is +better support (i.e your module is more likely to compile) for traced modules because it doesn't include all the complexities of a complete +programming language, though both paths supported. + +After scripting or tracing your module, you are given back a TorchScript Module. This contains the code and parameters used to run the module stored +in a intermediate representation that Torch-TensorRT can consume. + +Here is what the LeNet traced module IR looks like: + +.. code-block:: none + + graph(%self.1 : __torch__.___torch_mangle_10.LeNet, + %input.1 : Float(1, 1, 32, 32)): + %129 : __torch__.___torch_mangle_9.LeNetClassifier = prim::GetAttr[name="classifer"](%self.1) + %119 : __torch__.___torch_mangle_5.LeNetFeatExtractor = prim::GetAttr[name="feat"](%self.1) + %137 : Tensor = prim::CallMethod[name="forward"](%119, %input.1) + %138 : Tensor = prim::CallMethod[name="forward"](%129, %137) + return (%138) + +and the LeNet scripted module IR: + +.. code-block:: none + + graph(%self : __torch__.LeNet, + %x.1 : Tensor): + %2 : __torch__.LeNetFeatExtractor = prim::GetAttr[name="feat"](%self) + %x.3 : Tensor = prim::CallMethod[name="forward"](%2, %x.1) # x.py:38:12 + %5 : __torch__.LeNetClassifier = prim::GetAttr[name="classifer"](%self) + %x.5 : Tensor = prim::CallMethod[name="forward"](%5, %x.3) # x.py:39:12 + return (%x.5) + +You can see that the IR preserves the module structure we have in our python code. + +.. _ts_in_py: + +Working with TorchScript in Python +----------------------------------- + +TorchScript Modules are run the same way you run normal PyTorch modules. You can run the forward pass using the +``forward`` method or just calling the module ``torch_scirpt_module(in_tensor)`` The JIT compiler will compile +and optimize the module on the fly and then returns the results. + +Saving TorchScript Module to Disk +----------------------------------- + +For either traced or scripted modules, you can save the module to disk with the following command + +.. code-block:: python + + import torch + + model = LeNet() + script_model = torch.jit.script(model) + script_model.save("lenet_scripted.ts") diff --git a/docs/v2.2.0/_sources/ts/getting_started_with_cpp_api.rst.txt b/docs/v2.2.0/_sources/ts/getting_started_with_cpp_api.rst.txt new file mode 100644 index 0000000000..70f439ea6d --- /dev/null +++ b/docs/v2.2.0/_sources/ts/getting_started_with_cpp_api.rst.txt @@ -0,0 +1,340 @@ +.. _getting_started_cpp: + +Using Torch-TensorRT in C++ +============================== + +If you haven't already, acquire a tarball of the library by following the instructions in :ref:`Installation` + +Using Torch-TensorRT in C++ +*************************** +Torch-TensorRT C++ API accepts TorchScript modules (generated either from ``torch.jit.script`` or ``torch.jit.trace``) as an input and returns +a Torchscript module (optimized using TensorRT), Dynamo compilation workflows will not be supported in the C++ API however, execution of +torch.jit.trace'd compiled FX GraphModules is supported for FX and Dyanmo workflows. + +Please refer to `Creating TorchScript modules in Python `_ section to generate torchscript graphs. + + +.. _torch_tensorrt_quickstart: + +[Torch-TensorRT Quickstart] Compiling TorchScript Modules with ``torchtrtc`` +--------------------------------------------------------------------------------- + +An easy way to get started with Torch-TensorRT and to check if your model can be supported without extra work is to run it through +``torchtrtc``, which supports almost all features of the compiler from the command line including post training quantization +(given a previously created calibration cache). For example we can compile our lenet model by setting our preferred operating +precision and input size. This new TorchScript file can be loaded into Python (note: you need to ``import torch_tensorrt`` before loading +these compiled modules because the compiler extends the PyTorch the deserializer and runtime to execute compiled modules). + +.. code-block:: shell + + ❯ torchtrtc -p f16 lenet_scripted.ts trt_lenet_scripted.ts "(1,1,32,32)" + + ❯ python3 + Python 3.6.9 (default, Apr 18 2020, 01:56:04) + [GCC 8.4.0] on linux + Type "help", "copyright", "credits" or "license" for more information. + >>> import torch + >>> import torch_tensorrt + >>> ts_model = torch.jit.load(“trt_lenet_scripted.ts”) + >>> ts_model(torch.randn((1,1,32,32)).to(“cuda”).half()) + +You can learn more about ``torchtrtc`` usage here: :ref:`torchtrtc` + +.. _ts_in_cc: + +Working with TorchScript in C++ +-------------------------------- + +If we are developing an application to deploy with C++, we can save either our traced or scripted module using ``torch.jit.save`` +which will serialize the TorchScript code, weights and other information into a package. This is also where our dependency on Python ends. + +.. code-block:: python + + torch_script_module.save("lenet.jit.pt") + +From here we can now load our TorchScript module in C++ + +.. code-block:: c++ + + #include // One-stop header. + + #include + #include + + int main(int argc, const char* argv[]) { + torch::jit::Module module; + try { + // Deserialize the ScriptModule from a file using torch::jit::load(). + module = torch::jit::load(""); + } + catch (const c10::Error& e) { + std::cerr << "error loading the model\n"; + return -1; + } + + std::cout << "ok\n"; + + +You can do full training and inference in C++ with PyTorch / LibTorch if you would like, you can even define your modules in C++ and +have access to the same powerful tensor library that backs PyTorch. (For more information: https://pytorch.org/cppdocs/). +For instance we can do inference with our LeNet module like this: + +.. code-block:: c++ + + mod.eval(); + torch::Tensor in = torch::randn({1, 1, 32, 32}); + auto out = mod.forward(in); + +and to run on the GPU: + +.. code-block:: c++ + + mod.eval(); + mod.to(torch::kCUDA); + torch::Tensor in = torch::randn({1, 1, 32, 32}, torch::kCUDA); + auto out = mod.forward(in); + +As you can see it is pretty similar to the Python API. When you call the ``forward`` method, you invoke the PyTorch JIT compiler, which will optimize and run your TorchScript code. + +.. _compile_cpp: + +Compiling with Torch-TensorRT in C++ +------------------------------------- +We are also at the point were we can compile and optimize our module with Torch-TensorRT, but instead of in a JIT fashion we must do it ahead-of-time (AOT) i.e. before we start doing actual inference work +since it takes a bit of time to optimize the module, it would not make sense to do this every time you run the module or even the first time you run it. + +With our module loaded, we can feed it into the Torch-TensorRT compiler. When we do so we must provide some information on the expected input size and also configure any additional settings. + +.. code-block:: c++ + + #include "torch/script.h" + #include "torch_tensorrt/torch_tensorrt.h" + ... + + mod.to(at::kCUDA); + mod.eval(); + + auto in = torch::randn({1, 1, 32, 32}, {torch::kCUDA}); + auto trt_mod = torch_tensorrt::CompileGraph(mod, std::vector{{in.sizes()}}); + auto out = trt_mod.forward({in}); + +Thats it! Now the graph runs primarily not with the JIT compiler but using TensorRT (though we execute the graph using the JIT runtime). + +We can also set settings like operating precision to run in FP16. + +.. code-block:: c++ + + #include "torch/script.h" + #include "torch_tensorrt/torch_tensorrt.h" + ... + + mod.to(at::kCUDA); + mod.eval(); + + auto in = torch::randn({1, 1, 32, 32}, {torch::kCUDA}).to(torch::kHALF); + auto input_sizes = std::vector({in.sizes()}); + torch_tensorrt::CompileSpec info(input_sizes); + info.enable_precisions.insert(torch::kHALF); + auto trt_mod = torch_tensorrt::CompileGraph(mod, info); + auto out = trt_mod.forward({in}); + +And now we are running the module in FP16 precision. You can then save the module to load later. + +.. code-block:: c++ + + trt_mod.save("") + +Torch-TensorRT compiled TorchScript modules are loaded in the same way as normal TorchScript module. Make sure your deployment application is linked against ``libtorchtrt.so`` + +.. code-block:: c++ + + #include "torch/script.h" + #include "torch_tensorrt/torch_tensorrt.h" + + int main(int argc, const char* argv[]) { + torch::jit::Module module; + try { + // Deserialize the ScriptModule from a file using torch::jit::load(). + module = torch::jit::load(""); + } + catch (const c10::Error& e) { + std::cerr << "error loading the model\n"; + return -1; + } + + torch::Tensor in = torch::randn({1, 1, 32, 32}, torch::kCUDA); + auto out = mod.forward(in); + + std::cout << "ok\n"; + } + +If you want to save the engine produced by Torch-TensorRT to use in a TensorRT application you can use the ``ConvertGraphToTRTEngine`` API. + +.. code-block:: c++ + + #include "torch/script.h" + #include "torch_tensorrt/torch_tensorrt.h" + ... + + mod.to(at::kCUDA); + mod.eval(); + + auto in = torch::randn({1, 1, 32, 32}, {torch::kCUDA}).to(torch::kHALF); + auto input_sizes = std::vector({in.sizes()}); + torch_tensorrt::CompileSpec info(input_sizes); + info.enabled_precisions.insert(torch::kHALF); + auto trt_mod = torch_tensorrt::ConvertGraphToTRTEngine(mod, "forward", info); + std::ofstream out("/tmp/engine_converted_from_jit.trt"); + out << engine; + out.close(); + +.. _under_the_hood: + +Under The Hood +--------------- + +When a module is provided to Torch-TensorRT, the compiler starts by mapping a graph like you saw above to a graph like this: + +.. code-block:: none + + graph(%input.2 : Tensor): + %2 : Float(84, 10) = prim::Constant[value=]() + %3 : Float(120, 84) = prim::Constant[value=]() + %4 : Float(576, 120) = prim::Constant[value=]() + %5 : int = prim::Constant[value=-1]() # x.py:25:0 + %6 : int[] = prim::Constant[value=annotate(List[int], [])]() + %7 : int[] = prim::Constant[value=[2, 2]]() + %8 : int[] = prim::Constant[value=[0, 0]]() + %9 : int[] = prim::Constant[value=[1, 1]]() + %10 : bool = prim::Constant[value=1]() # ~/.local/lib/python3.6/site-packages/torch/nn/modules/conv.py:346:0 + %11 : int = prim::Constant[value=1]() # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0 + %12 : bool = prim::Constant[value=0]() # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0 + %self.classifer.fc3.bias : Float(10) = prim::Constant[value= 0.0464 0.0383 0.0678 0.0932 0.1045 -0.0805 -0.0435 -0.0818 0.0208 -0.0358 [ CUDAFloatType{10} ]]() + %self.classifer.fc2.bias : Float(84) = prim::Constant[value=]() + %self.classifer.fc1.bias : Float(120) = prim::Constant[value=]() + %self.feat.conv2.weight : Float(16, 6, 3, 3) = prim::Constant[value=]() + %self.feat.conv2.bias : Float(16) = prim::Constant[value=]() + %self.feat.conv1.weight : Float(6, 1, 3, 3) = prim::Constant[value=]() + %self.feat.conv1.bias : Float(6) = prim::Constant[value= 0.0530 -0.1691 0.2802 0.1502 0.1056 -0.1549 [ CUDAFloatType{6} ]]() + %input0.4 : Tensor = aten::_convolution(%input.2, %self.feat.conv1.weight, %self.feat.conv1.bias, %9, %8, %9, %12, %8, %11, %12, %12, %10) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/conv.py:346:0 + %input0.5 : Tensor = aten::relu(%input0.4) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0 + %input1.2 : Tensor = aten::max_pool2d(%input0.5, %7, %6, %8, %9, %12) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0 + %input0.6 : Tensor = aten::_convolution(%input1.2, %self.feat.conv2.weight, %self.feat.conv2.bias, %9, %8, %9, %12, %8, %11, %12, %12, %10) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/conv.py:346:0 + %input2.1 : Tensor = aten::relu(%input0.6) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0 + %x.1 : Tensor = aten::max_pool2d(%input2.1, %7, %6, %8, %9, %12) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0 + %input.1 : Tensor = aten::flatten(%x.1, %11, %5) # x.py:25:0 + %27 : Tensor = aten::matmul(%input.1, %4) + %28 : Tensor = trt::const(%self.classifer.fc1.bias) + %29 : Tensor = aten::add_(%28, %27, %11) + %input0.2 : Tensor = aten::relu(%29) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0 + %31 : Tensor = aten::matmul(%input0.2, %3) + %32 : Tensor = trt::const(%self.classifer.fc2.bias) + %33 : Tensor = aten::add_(%32, %31, %11) + %input1.1 : Tensor = aten::relu(%33) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0 + %35 : Tensor = aten::matmul(%input1.1, %2) + %36 : Tensor = trt::const(%self.classifer.fc3.bias) + %37 : Tensor = aten::add_(%36, %35, %11) + return (%37) + (CompileGraph) + +The graph has now been transformed from a collection of modules, each managing their own parameters into a single graph with the parameters inlined +into the graph and all of the operations laid out. Torch-TensorRT has also executed a number of optimizations and mappings to make the graph easier to translate to TensorRT. +From here the compiler can assemble the TensorRT engine by following the dataflow through the graph. + +When the graph construction phase is complete, Torch-TensorRT produces a serialized TensorRT engine. From here depending on the API, this engine is returned +to the user or moves into the graph construction phase. Here Torch-TensorRT creates a JIT Module to execute the TensorRT engine which will be instantiated and managed +by the Torch-TensorRT runtime. + +Here is the graph that you get back after compilation is complete: + +.. code-block:: none + + graph(%self_1 : __torch__.lenet, %input_0 : Tensor): + %1 : ...trt.Engine = prim::GetAttr[name="lenet"](%self_1) + %3 : Tensor[] = prim::ListConstruct(%input_0) + %4 : Tensor[] = trt::execute_engine(%3, %1) + %5 : Tensor = prim::ListUnpack(%4) + return (%5) + + +You can see the call where the engine is executed, after extracting the attribute containing the engine and constructing a list of inputs, then returns the tensors back to the user. + +.. _unsupported_ops: + +Working with Unsupported Operators +----------------------------------- + +Torch-TensorRT is a new library and the PyTorch operator library is quite large, so there will be ops that aren't supported natively by the compiler. You can either use the composition techinques +shown above to make modules are fully Torch-TensorRT supported and ones that are not and stitch the modules together in the deployment application or you can register converters for missing ops. + + You can check support without going through the full compilation pipleine using the ``torch_tensorrt::CheckMethodOperatorSupport(const torch::jit::Module& module, std::string method_name)`` api + to see what operators are not supported. ``torchtrtc`` automatically checks modules with this method before starting compilation and will print out a list of operators that are not supported. + +.. _custom_converters: + +Registering Custom Converters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Operations are mapped to TensorRT through the use of modular converters, a function that takes a node from a the JIT graph and produces an equivalent layer or subgraph in TensorRT. +Torch-TensorRT ships with a library of these converters stored in a registry, that will be executed depending on the node being parsed. For instance a ``aten::relu(%input0.4)`` instruction will trigger +the relu converter to be run on it, producing an activation layer in the TensorRT graph. But since this library is not exhaustive you may need to write your own to get Torch-TensorRT +to support your module. + +Shipped with the Torch-TensorRT distribution are the internal core API headers. You can therefore access the converter registry and add a converter for the op you need. + +For example, if we try to compile a graph with a build of Torch-TensorRT that doesn't support the flatten operation (``aten::flatten``) you may see this error: + +.. code-block:: none + + terminate called after throwing an instance of 'torch_tensorrt::Error' + what(): [enforce fail at core/conversion/conversion.cpp:109] Expected converter to be true but got false + Unable to convert node: %input.1 : Tensor = aten::flatten(%x.1, %11, %5) # x.py:25:0 (conversion.AddLayer) + Schema: aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor) + Converter for aten::flatten requested, but no such converter was found. + If you need a converter for this operator, you can try implementing one yourself + or request a converter: https://www.github.com/NVIDIA/Torch-TensorRT/issues + +We can register a converter for this operator in our application. All of the tools required to build a converter can be imported by including ``torch_tensorrt/core/conversion/converters/converters.h``. +We start by creating an instance of the self-registering class ``torch_tensorrt::core::conversion::converters::RegisterNodeConversionPatterns()`` which will register converters +in the global converter registry, associating a function schema like ``aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor)`` with a lambda that +will take the state of the conversion, the node/operation in question to convert and all of the inputs to the node and produces as a side effect a new layer in the TensorRT network. +Arguments are passed as a vector of inspectable unions of TensorRT ``ITensors`` and Torch ``IValues`` in the order arguments are listed in the schema. + +Below is a implementation of a ``aten::flatten`` converter that we can use in our application. You have full access to the Torch and TensorRT libraries in the converter implementation. So +for example we can quickly get the output size by just running the operation in PyTorch instead of implementing the full calculation outself like we do below for this flatten converter. + +.. code-block:: c++ + + #include "torch/script.h" + #include "torch_tensorrt/torch_tensorrt.h" + #include "torch_tensorrt/core/conversion/converters/converters.h" + + static auto flatten_converter = torch_tensorrt::core::conversion::converters::RegisterNodeConversionPatterns() + .pattern({ + "aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor)", + [](torch_tensorrt::core::conversion::ConversionCtx* ctx, + const torch::jit::Node* n, + torch_tensorrt::core::conversion::converters::args& args) -> bool { + auto in = args[0].ITensor(); + auto start_dim = args[1].unwrapToInt(); + auto end_dim = args[2].unwrapToInt(); + auto in_shape = torch_tensorrt::core::util::toVec(in->getDimensions()); + auto out_shape = torch::flatten(torch::rand(in_shape), start_dim, end_dim).sizes(); + + auto shuffle = ctx->net->addShuffle(*in); + shuffle->setReshapeDimensions(torch_tensorrt::core::util::toDims(out_shape)); + shuffle->setName(torch_tensorrt::core::util::node_info(n).c_str()); + + auto out_tensor = ctx->AssociateValueAndTensor(n->outputs()[0], shuffle->getOutput(0)); + return true; + } + }); + + int main() { + ... + +To use this converter in Python, it is recommended to use PyTorch's `C++ / CUDA Extention `_ +template to wrap your library of converters into a ``.so`` that you can load with ``ctypes.CDLL()`` in your Python application. + +You can find more information on all the details of writing converters in the contributors documentation (:ref:`writing_converters`). +If you find yourself with a large library of converter implementations, do consider upstreaming them, PRs are welcome and it would be great for the community to benefit as well. diff --git a/docs/v2.2.0/_sources/ts/getting_started_with_python_api.rst.txt b/docs/v2.2.0/_sources/ts/getting_started_with_python_api.rst.txt new file mode 100644 index 0000000000..9ca679d602 --- /dev/null +++ b/docs/v2.2.0/_sources/ts/getting_started_with_python_api.rst.txt @@ -0,0 +1,82 @@ +.. _getting_started_with_python_api: + +Using Torch-TensorRT in Python +******************************* + +The Torch-TensorRT Python API supports a number of unique usecases compared to the CLI and C++ APIs which solely support TorchScript compilation. + +Torch-TensorRT Python API can accept a ``torch.nn.Module``, ``torch.jit.ScriptModule``, or ``torch.fx.GraphModule`` as an input. +Depending on what is provided one of the two frontends (TorchScript or FX) will be selected to compile the module. Provided the +module type is supported, users may explicitly set which frontend they would like to use using the ``ir`` flag for ``compile``. +If given a ``torch.nn.Module`` and the ``ir`` flag is set to either ``default`` or ``torchscript`` the module will be run through +``torch.jit.script`` to convert the input module into a TorchScript module. + + +To compile your input ``torch.nn.Module`` with Torch-TensorRT, all you need to do is provide the module and inputs +to Torch-TensorRT and you will be returned an optimized TorchScript module to run or add into another PyTorch module. Inputs +is a list of ``torch_tensorrt.Input`` classes which define input Tensors' shape, datatype and memory format. Alternatively, if your input is a more complex data type, such as a tuple or list of Tensors, you can use the ``input_signature`` argument to specify a collection-based input, such as ``(List[Tensor], Tuple[Tensor, Tensor])``. See the second sample below for an example. You can also specify settings such as operating precision for the engine or target device. After compilation you can save the module just like any other module +to load in a deployment application. In order to load a TensorRT/TorchScript module, make sure you first import ``torch_tensorrt``. + +.. code-block:: python + + import torch_tensorrt + + ... + + model = MyModel().eval() # torch module needs to be in eval (not training) mode + + inputs = [ + torch_tensorrt.Input( + min_shape=[1, 1, 16, 16], + opt_shape=[1, 1, 32, 32], + max_shape=[1, 1, 64, 64], + dtype=torch.half, + ) + ] + enabled_precisions = {torch.float, torch.half} # Run with fp16 + + trt_ts_module = torch_tensorrt.compile( + model, inputs=inputs, enabled_precisions=enabled_precisions + ) + + input_data = input_data.to("cuda").half() + result = trt_ts_module(input_data) + torch.jit.save(trt_ts_module, "trt_ts_module.ts") + +.. code-block:: python + + # Sample using collection-based inputs via the input_signature argument + import torch_tensorrt + + ... + + model = MyModel().eval() + + # input_signature expects a tuple of individual input arguments to the module + # The module below, for example, would have a docstring of the form: + # def forward(self, input0: List[torch.Tensor], input1: Tuple[torch.Tensor, torch.Tensor]) + input_signature = ( + [torch_tensorrt.Input(shape=[64, 64], dtype=torch.half), torch_tensorrt.Input(shape=[64, 64], dtype=torch.half)], + (torch_tensorrt.Input(shape=[64, 64], dtype=torch.half), torch_tensorrt.Input(shape=[64, 64], dtype=torch.half)), + ) + enabled_precisions = {torch.float, torch.half} + + trt_ts_module = torch_tensorrt.compile( + model, input_signature=input_signature, enabled_precisions=enabled_precisions + ) + + input_data = input_data.to("cuda").half() + result = trt_ts_module(input_data) + torch.jit.save(trt_ts_module, "trt_ts_module.ts") + +.. code-block:: python + + # Deployment application + import torch + import torch_tensorrt + + trt_ts_module = torch.jit.load("trt_ts_module.ts") + input_data = input_data.to("cuda").half() + result = trt_ts_module(input_data) + +Torch-TensorRT Python API also provides ``torch_tensorrt.ts.compile`` which accepts a TorchScript module as input and ``torch_tensorrt.fx.compile`` which accepts a FX GraphModule as input. diff --git a/docs/v2.2.0/_sources/ts/torchscript_frontend_from_pytorch.rst.txt b/docs/v2.2.0/_sources/ts/torchscript_frontend_from_pytorch.rst.txt new file mode 100644 index 0000000000..d0a403e93c --- /dev/null +++ b/docs/v2.2.0/_sources/ts/torchscript_frontend_from_pytorch.rst.txt @@ -0,0 +1,64 @@ +.. _use_from_pytorch: + +Using Torch-TensorRT TorchScript Frontend Directly From PyTorch +============================================ + +You will now be able to directly access TensorRT from PyTorch APIs. The process to use this feature +is very similar to the compilation workflow described in :ref:`getting_started_with_python_api` + +Start by loading ``torch_tensorrt`` into your application. + +.. code-block:: python + + import torch + import torch_tensorrt + + +Then given a TorchScript module, you can compile it with TensorRT using the ``torch._C._jit_to_backend("tensorrt", ...)`` API. + +.. code-block:: python + + import torchvision.models as models + + model = models.mobilenet_v2(pretrained=True) + script_model = torch.jit.script(model) + +Unlike the ``compile`` API in Torch-TensorRT which assumes you are trying to compile the ``forward`` function of a module +or the ``convert_method_to_trt_engine`` which converts a specified function to a TensorRT engine, the backend API +will take a dictionary which maps names of functions to compile to Compilation Spec objects which wrap the same +sort of dictionary you would provide to ``compile``. For more information on the compile spec dictionary take a look +at the documentation for the Torch-TensorRT ``TensorRTCompileSpec`` API. + +.. code-block:: python + + spec = { + "forward": torch_tensorrt.ts.TensorRTCompileSpec( + **{ + "inputs": [torch_tensorrt.Input([1, 3, 300, 300])], + "enabled_precisions": {torch.float, torch.half}, + "refit": False, + "debug": False, + "device": { + "device_type": torch_tensorrt.DeviceType.GPU, + "gpu_id": 0, + "dla_core": 0, + "allow_gpu_fallback": True, + }, + "capability": torch_tensorrt.EngineCapability.default, + "num_avg_timing_iters": 1, + } + ) + } + +Now to compile with Torch-TensorRT, provide the target module objects and the spec dictionary to ``torch._C._jit_to_backend("tensorrt", ...)`` + +.. code-block:: python + + trt_model = torch._C._jit_to_backend("tensorrt", script_model, spec) + +To run explicitly call the function of the method you want to run (vs. how you can just call on the module itself in standard PyTorch) + +.. code-block:: python + + input = torch.randn((1, 3, 300, 300)).to("cuda").to(torch.half) + print(trt_model.forward(input)) diff --git a/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/index.rst.txt b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/index.rst.txt new file mode 100644 index 0000000000..d0e4d6630e --- /dev/null +++ b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/index.rst.txt @@ -0,0 +1,105 @@ + + +.. _sphx_glr_tutorials__rendered_examples_dynamo: + +.. _torch_compile: + +Dynamo / ``torch.compile`` +---------------------------- + +Torch-TensorRT provides a backend for the new ``torch.compile`` API released in PyTorch 2.0. In the following examples we describe +a number of ways you can leverage this backend to accelerate inference. + +* :ref:`torch_compile_resnet`: Compiling a ResNet model using the Torch Compile Frontend for ``torch_tensorrt.compile`` +* :ref:`torch_compile_transformer`: Compiling a Transformer model using ``torch.compile`` +* :ref:`torch_compile_advanced_usage`: Advanced usage including making a custom backend to use directly with the ``torch.compile`` API +* :ref:`torch_compile_stable_diffusion`: Compiling a Stable Diffusion model using ``torch.compile`` + + + +.. raw:: html + +
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /tutorials/_rendered_examples/dynamo/images/thumb/sphx_glr_torch_compile_stable_diffusion_thumb.png + :alt: + + :ref:`sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_stable_diffusion.py` + +.. raw:: html + +
Torch Compile Stable Diffusion
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /tutorials/_rendered_examples/dynamo/images/thumb/sphx_glr_torch_compile_resnet_example_thumb.png + :alt: + + :ref:`sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_resnet_example.py` + +.. raw:: html + +
Compiling ResNet using the Torch-TensorRT torch.compile Backend
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /tutorials/_rendered_examples/dynamo/images/thumb/sphx_glr_torch_compile_transformers_example_thumb.png + :alt: + + :ref:`sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_transformers_example.py` + +.. raw:: html + +
Compiling a Transformer using torch.compile and TensorRT
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /tutorials/_rendered_examples/dynamo/images/thumb/sphx_glr_torch_compile_advanced_usage_thumb.png + :alt: + + :ref:`sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_advanced_usage.py` + +.. raw:: html + +
Torch Compile Advanced Usage
+
+ + +.. raw:: html + +
+ + +.. toctree:: + :hidden: + + /tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion + /tutorials/_rendered_examples/dynamo/torch_compile_resnet_example + /tutorials/_rendered_examples/dynamo/torch_compile_transformers_example + /tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage + diff --git a/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.rst.txt b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.rst.txt new file mode 100644 index 0000000000..9eaa970313 --- /dev/null +++ b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.rst.txt @@ -0,0 +1,197 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_advanced_usage.py: + + +.. _torch_compile_advanced_usage: + +Torch Compile Advanced Usage +====================================================== + +This interactive script is intended as an overview of the process by which `torch_tensorrt.compile(..., ir="torch_compile", ...)` works, and how it integrates with the `torch.compile` API. + +.. GENERATED FROM PYTHON SOURCE LINES 10-12 + +Imports and Model Definition +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 12-16 + +.. code-block:: python + + + import torch + import torch_tensorrt + + +.. GENERATED FROM PYTHON SOURCE LINES 17-32 + +.. code-block:: python + + + + # We begin by defining a model + class Model(torch.nn.Module): + def __init__(self) -> None: + super().__init__() + self.relu = torch.nn.ReLU() + + def forward(self, x: torch.Tensor, y: torch.Tensor): + x_out = self.relu(x) + y_out = self.relu(y) + x_y_out = x_out + y_out + return torch.mean(x_y_out) + + + +.. GENERATED FROM PYTHON SOURCE LINES 33-35 + +Compilation with `torch.compile` Using Default Settings +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 35-40 + +.. code-block:: python + + + # Define sample float inputs and initialize model + sample_inputs = [torch.rand((5, 7)).cuda(), torch.rand((5, 7)).cuda()] + model = Model().eval().cuda() + + +.. GENERATED FROM PYTHON SOURCE LINES 41-49 + +.. code-block:: python + + + # Next, we compile the model using torch.compile + # For the default settings, we can simply call torch.compile + # with the backend "torch_tensorrt", and run the model on an + # input to cause compilation, as so: + optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False) + optimized_model(*sample_inputs) + + +.. GENERATED FROM PYTHON SOURCE LINES 50-52 + +Compilation with `torch.compile` Using Custom Settings +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 52-64 + +.. code-block:: python + + + # First, we use Torch utilities to clean up the workspace + # after the previous compile invocation + torch._dynamo.reset() + + # Define sample half inputs and initialize model + sample_inputs_half = [ + torch.rand((5, 7)).half().cuda(), + torch.rand((5, 7)).half().cuda(), + ] + model_half = Model().eval().cuda() + + +.. GENERATED FROM PYTHON SOURCE LINES 65-91 + +.. code-block:: python + + + # If we want to customize certain options in the backend, + # but still use the torch.compile call directly, we can provide + # custom options to the backend via the "options" keyword + # which takes in a dictionary mapping options to values. + # + # For accepted backend options, see the CompilationSettings dataclass: + # py/torch_tensorrt/dynamo/_settings.py + backend_kwargs = { + "enabled_precisions": {torch.half}, + "debug": True, + "min_block_size": 2, + "torch_executed_ops": {"torch.ops.aten.sub.Tensor"}, + "optimization_level": 4, + "use_python_runtime": False, + } + + # Run the model on an input to cause compilation, as so: + optimized_model_custom = torch.compile( + model_half, + backend="torch_tensorrt", + options=backend_kwargs, + dynamic=False, + ) + optimized_model_custom(*sample_inputs_half) + + +.. GENERATED FROM PYTHON SOURCE LINES 92-94 + +Cleanup +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 94-98 + +.. code-block:: python + + + # Finally, we use Torch utilities to clean up the workspace + torch._dynamo.reset() + + +.. GENERATED FROM PYTHON SOURCE LINES 99-108 + +Cuda Driver Error Note +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Occasionally, upon exiting the Python runtime after Dynamo compilation with `torch_tensorrt`, +one may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052 +and can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in:: + + if __name__ == '__main__': + compile_engine_and_infer() + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** ( 0 minutes 0.000 seconds) + + +.. _sphx_glr_download_tutorials__rendered_examples_dynamo_torch_compile_advanced_usage.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + + + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: torch_compile_advanced_usage.py ` + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: torch_compile_advanced_usage.ipynb ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.rst.txt b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.rst.txt new file mode 100644 index 0000000000..b0d1bb5fb2 --- /dev/null +++ b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.rst.txt @@ -0,0 +1,187 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_resnet_example.py: + + +.. _torch_compile_resnet: + +Compiling ResNet using the Torch-TensorRT `torch.compile` Backend +========================================================== + +This interactive script is intended as a sample of the Torch-TensorRT workflow with `torch.compile` on a ResNet model. + +.. GENERATED FROM PYTHON SOURCE LINES 10-12 + +Imports and Model Definition +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 12-17 + +.. code-block:: python + + + import torch + import torch_tensorrt + import torchvision.models as models + + +.. GENERATED FROM PYTHON SOURCE LINES 18-23 + +.. code-block:: python + + + # Initialize model with half precision and sample inputs + model = models.resnet18(pretrained=True).half().eval().to("cuda") + inputs = [torch.randn((1, 3, 224, 224)).to("cuda").half()] + + +.. GENERATED FROM PYTHON SOURCE LINES 24-26 + +Optional Input Arguments to `torch_tensorrt.compile` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 26-43 + +.. code-block:: python + + + # Enabled precision for TensorRT optimization + enabled_precisions = {torch.half} + + # Whether to print verbose logs + debug = True + + # Workspace size for TensorRT + workspace_size = 20 << 30 + + # Maximum number of TRT Engines + # (Lower value allows more graph segmentation) + min_block_size = 7 + + # Operations to Run in Torch, regardless of converter support + torch_executed_ops = {} + + +.. GENERATED FROM PYTHON SOURCE LINES 44-46 + +Compilation with `torch_tensorrt.compile` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 46-59 + +.. code-block:: python + + + # Build and compile the model with torch.compile, using Torch-TensorRT backend + optimized_model = torch_tensorrt.compile( + model, + ir="torch_compile", + inputs=inputs, + enabled_precisions=enabled_precisions, + debug=debug, + workspace_size=workspace_size, + min_block_size=min_block_size, + torch_executed_ops=torch_executed_ops, + ) + + +.. GENERATED FROM PYTHON SOURCE LINES 60-62 + +Equivalently, we could have run the above via the torch.compile frontend, as so: +`optimized_model = torch.compile(model, backend="torch_tensorrt", options={"enabled_precisions": enabled_precisions, ...}); optimized_model(*inputs)` + +.. GENERATED FROM PYTHON SOURCE LINES 64-66 + +Inference +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 66-71 + +.. code-block:: python + + + # Does not cause recompilation (same batch size as input) + new_inputs = [torch.randn((1, 3, 224, 224)).half().to("cuda")] + new_outputs = optimized_model(*new_inputs) + + +.. GENERATED FROM PYTHON SOURCE LINES 72-77 + +.. code-block:: python + + + # Does cause recompilation (new batch size) + new_batch_size_inputs = [torch.randn((8, 3, 224, 224)).half().to("cuda")] + new_batch_size_outputs = optimized_model(*new_batch_size_inputs) + + +.. GENERATED FROM PYTHON SOURCE LINES 78-80 + +Cleanup +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 80-84 + +.. code-block:: python + + + # Finally, we use Torch utilities to clean up the workspace + torch._dynamo.reset() + + +.. GENERATED FROM PYTHON SOURCE LINES 85-94 + +Cuda Driver Error Note +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Occasionally, upon exiting the Python runtime after Dynamo compilation with `torch_tensorrt`, +one may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052 +and can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in:: + + if __name__ == '__main__': + compile_engine_and_infer() + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** ( 0 minutes 0.000 seconds) + + +.. _sphx_glr_download_tutorials__rendered_examples_dynamo_torch_compile_resnet_example.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + + + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: torch_compile_resnet_example.py ` + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: torch_compile_resnet_example.ipynb ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.rst.txt b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.rst.txt new file mode 100644 index 0000000000..937eb5117e --- /dev/null +++ b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.rst.txt @@ -0,0 +1,116 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_stable_diffusion.py: + + +.. _torch_compile_stable_diffusion: + +Torch Compile Stable Diffusion +====================================================== + +This interactive script is intended as a sample of the Torch-TensorRT workflow with `torch.compile` on a Stable Diffusion model. A sample output is featured below: + +.. image:: /tutorials/images/majestic_castle.png + :width: 512px + :height: 512px + :scale: 50 % + :align: right + +.. GENERATED FROM PYTHON SOURCE LINES 17-19 + +Imports and Model Definition +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 19-47 + +.. code-block:: python + + + import torch + from diffusers import DiffusionPipeline + + import torch_tensorrt + + model_id = "CompVis/stable-diffusion-v1-4" + device = "cuda:0" + + # Instantiate Stable Diffusion Pipeline with FP16 weights + pipe = DiffusionPipeline.from_pretrained( + model_id, revision="fp16", torch_dtype=torch.float16 + ) + pipe = pipe.to(device) + + backend = "torch_tensorrt" + + # Optimize the UNet portion with Torch-TensorRT + pipe.unet = torch.compile( + pipe.unet, + backend=backend, + options={ + "truncate_long_and_double": True, + "precision": torch.float16, + }, + dynamic=False, + ) + + +.. GENERATED FROM PYTHON SOURCE LINES 48-50 + +Inference +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 50-56 + +.. code-block:: python + + + prompt = "a majestic castle in the clouds" + image = pipe(prompt).images[0] + + image.save("images/majestic_castle.png") + image.show() + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** ( 0 minutes 0.000 seconds) + + +.. _sphx_glr_download_tutorials__rendered_examples_dynamo_torch_compile_stable_diffusion.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + + + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: torch_compile_stable_diffusion.py ` + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: torch_compile_stable_diffusion.ipynb ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.rst.txt b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.rst.txt new file mode 100644 index 0000000000..b362e42447 --- /dev/null +++ b/docs/v2.2.0/_sources/tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.rst.txt @@ -0,0 +1,203 @@ + +.. DO NOT EDIT. +.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. +.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: +.. "tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.py" +.. LINE NUMBERS ARE GIVEN BELOW. + +.. only:: html + + .. note:: + :class: sphx-glr-download-link-note + + :ref:`Go to the end ` + to download the full example code + +.. rst-class:: sphx-glr-example-title + +.. _sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_transformers_example.py: + + +.. _torch_compile_transformer: + +Compiling a Transformer using torch.compile and TensorRT +============================================================== + +This interactive script is intended as a sample of the Torch-TensorRT workflow with `torch.compile` on a transformer-based model. + +.. GENERATED FROM PYTHON SOURCE LINES 10-12 + +Imports and Model Definition +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 12-17 + +.. code-block:: python + + + import torch + import torch_tensorrt + from transformers import BertModel + + +.. GENERATED FROM PYTHON SOURCE LINES 18-27 + +.. code-block:: python + + + # Initialize model with float precision and sample inputs + model = BertModel.from_pretrained("bert-base-uncased").eval().to("cuda") + inputs = [ + torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"), + torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"), + ] + + + +.. GENERATED FROM PYTHON SOURCE LINES 28-30 + +Optional Input Arguments to `torch_tensorrt.compile` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 30-47 + +.. code-block:: python + + + # Enabled precision for TensorRT optimization + enabled_precisions = {torch.float} + + # Whether to print verbose logs + debug = True + + # Workspace size for TensorRT + workspace_size = 20 << 30 + + # Maximum number of TRT Engines + # (Lower value allows more graph segmentation) + min_block_size = 7 + + # Operations to Run in Torch, regardless of converter support + torch_executed_ops = {} + + +.. GENERATED FROM PYTHON SOURCE LINES 48-50 + +Compilation with `torch.compile` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 50-69 + +.. code-block:: python + + + # Define backend compilation keyword arguments + compilation_kwargs = { + "enabled_precisions": enabled_precisions, + "debug": debug, + "workspace_size": workspace_size, + "min_block_size": min_block_size, + "torch_executed_ops": torch_executed_ops, + } + + # Build and compile the model with torch.compile, using Torch-TensorRT backend + optimized_model = torch.compile( + model, + backend="torch_tensorrt", + dynamic=False, + options=compilation_kwargs, + ) + optimized_model(*inputs) + + +.. GENERATED FROM PYTHON SOURCE LINES 70-72 + +Equivalently, we could have run the above via the convenience frontend, as so: +`torch_tensorrt.compile(model, ir="torch_compile", inputs=inputs, **compilation_kwargs)` + +.. GENERATED FROM PYTHON SOURCE LINES 74-76 + +Inference +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 76-84 + +.. code-block:: python + + + # Does not cause recompilation (same batch size as input) + new_inputs = [ + torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"), + torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"), + ] + new_outputs = optimized_model(*new_inputs) + + +.. GENERATED FROM PYTHON SOURCE LINES 85-93 + +.. code-block:: python + + + # Does cause recompilation (new batch size) + new_inputs = [ + torch.randint(0, 2, (4, 14), dtype=torch.int32).to("cuda"), + torch.randint(0, 2, (4, 14), dtype=torch.int32).to("cuda"), + ] + new_outputs = optimized_model(*new_inputs) + + +.. GENERATED FROM PYTHON SOURCE LINES 94-96 + +Cleanup +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. GENERATED FROM PYTHON SOURCE LINES 96-100 + +.. code-block:: python + + + # Finally, we use Torch utilities to clean up the workspace + torch._dynamo.reset() + + +.. GENERATED FROM PYTHON SOURCE LINES 101-110 + +Cuda Driver Error Note +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Occasionally, upon exiting the Python runtime after Dynamo compilation with `torch_tensorrt`, +one may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052 +and can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in:: + + if __name__ == '__main__': + compile_engine_and_infer() + + +.. rst-class:: sphx-glr-timing + + **Total running time of the script:** ( 0 minutes 0.000 seconds) + + +.. _sphx_glr_download_tutorials__rendered_examples_dynamo_torch_compile_transformers_example.py: + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-example + + + + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download Python source code: torch_compile_transformers_example.py ` + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download Jupyter notebook: torch_compile_transformers_example.ipynb ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/v2.2.0/_sources/tutorials/_rendered_examples/index.rst.txt b/docs/v2.2.0/_sources/tutorials/_rendered_examples/index.rst.txt new file mode 100644 index 0000000000..067d1b3e00 --- /dev/null +++ b/docs/v2.2.0/_sources/tutorials/_rendered_examples/index.rst.txt @@ -0,0 +1,139 @@ +:orphan: + +.. _torch_tensorrt_tutorials: + +Torch-TensorRT Tutorials +=========================== + +The user guide covers the basic concepts and usage of Torch-TensorRT. +We also provide a number of tutorials to explore specific usecases and advanced concepts + + + +.. raw:: html + +
+ + +.. raw:: html + +
+ + +Dynamo / ``torch.compile`` +---------------------------- + +Torch-TensorRT provides a backend for the new ``torch.compile`` API released in PyTorch 2.0. In the following examples we describe +a number of ways you can leverage this backend to accelerate inference. + +* :ref:`torch_compile_resnet`: Compiling a ResNet model using the Torch Compile Frontend for ``torch_tensorrt.compile`` +* :ref:`torch_compile_transformer`: Compiling a Transformer model using ``torch.compile`` +* :ref:`torch_compile_advanced_usage`: Advanced usage including making a custom backend to use directly with the ``torch.compile`` API +* :ref:`torch_compile_stable_diffusion`: Compiling a Stable Diffusion model using ``torch.compile`` + + + +.. raw:: html + +
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /tutorials/_rendered_examples/dynamo/images/thumb/sphx_glr_torch_compile_stable_diffusion_thumb.png + :alt: + + :ref:`sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_stable_diffusion.py` + +.. raw:: html + +
Torch Compile Stable Diffusion
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /tutorials/_rendered_examples/dynamo/images/thumb/sphx_glr_torch_compile_resnet_example_thumb.png + :alt: + + :ref:`sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_resnet_example.py` + +.. raw:: html + +
Compiling ResNet using the Torch-TensorRT torch.compile Backend
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /tutorials/_rendered_examples/dynamo/images/thumb/sphx_glr_torch_compile_transformers_example_thumb.png + :alt: + + :ref:`sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_transformers_example.py` + +.. raw:: html + +
Compiling a Transformer using torch.compile and TensorRT
+
+ + +.. raw:: html + +
+ +.. only:: html + + .. image:: /tutorials/_rendered_examples/dynamo/images/thumb/sphx_glr_torch_compile_advanced_usage_thumb.png + :alt: + + :ref:`sphx_glr_tutorials__rendered_examples_dynamo_torch_compile_advanced_usage.py` + +.. raw:: html + +
Torch Compile Advanced Usage
+
+ + +.. raw:: html + +
+ + +.. toctree:: + :hidden: + :includehidden: + + + /tutorials/_rendered_examples//dynamo/index.rst + + +.. only:: html + + .. container:: sphx-glr-footer sphx-glr-footer-gallery + + .. container:: sphx-glr-download sphx-glr-download-python + + :download:`Download all examples in Python source code: _rendered_examples_python.zip ` + + .. container:: sphx-glr-download sphx-glr-download-jupyter + + :download:`Download all examples in Jupyter notebooks: _rendered_examples_jupyter.zip ` + + +.. only:: html + + .. rst-class:: sphx-glr-signature + + `Gallery generated by Sphinx-Gallery `_ diff --git a/docs/v2.2.0/_sources/tutorials/notebooks.rst.txt b/docs/v2.2.0/_sources/tutorials/notebooks.rst.txt new file mode 100644 index 0000000000..df903fc353 --- /dev/null +++ b/docs/v2.2.0/_sources/tutorials/notebooks.rst.txt @@ -0,0 +1,154 @@ +.. _notebooks: + +Example notebooks +=================== + +There exists a number of notebooks which cover specific using specific features and models +with Torch-TensorRT + +Notebooks +------------ + +Compiling CitriNet with Torch-TensorRT +******************************************** + +Citrinet is an acoustic model used for the speech to text recognition task. It is a version +of QuartzNet that extends ContextNet, utilizing subword encoding (via Word Piece tokenization) +and Squeeze-and-Excitation(SE) mechanism and are therefore smaller than QuartzNet models. CitriNet +models take in audio segments and transcribe them to letter, byte pair, or word piece sequences. + +This notebook demonstrates the steps for optimizing a pretrained CitriNet model with Torch-TensorRT, +and running it to test the speedup obtained. + +* `Torch-TensorRT Getting Started - CitriNet `_ + + +Compiling EfficentNet with Torch-TensorRT +******************************************** + +EfficentNet is a feedforward CNN designed to achieve better performance and accuracy than alternative architectures +by using a "scaling method that uniformly scales all dimensions of depth/width/resolution using a simple yet highly effective compound coefficient". + +This notebook demonstrates the steps for optimizing a pretrained EfficentNet model with Torch-TensorRT, +and running it to test the speedup obtained. + +* `Torch-TensorRT Getting Started - EfficientNet-B0 `_ + + +Masked Language Modeling (MLM) with Hugging Face BERT Transformer accelerated by Torch-TensorRT +************************************************************************************************* + +"BERT is a transformer model pretrained on a large corpus of English data in a self-supervised fashion. +This way, the model learns an inner representation of the English language that can then be used to extract +features useful for downstream tasks: if you have a dataset of labeled sentences for instance, you can train +a standard classifier using the features produced by the BERT model as inputs." (https://huggingface.co/bert-base-uncased) + +This notebook demonstrates the steps for optimizing a pretrained EfficentNet model with Torch-TensorRT, +and running it to test the speedup obtained. + +* `Masked Language Modeling (MLM) with Hugging Face BERT Transformer `_ + + +Serving a model in C++ using Torch-TensorRT +********************************************** + +This example shows how you can load a pretrained ResNet-50 model, convert it to a Torch-TensorRT +optimized model (via the Torch-TensorRT Python API), save the model as a torchscript module, and +then finally load and serve the model with the PyTorch C++ API. + +* `ResNet C++ Serving Example `_ + + +Compiling ResNet50 with Torch-TensorRT +******************************************** + +This notebook demonstrates the steps for compiling a TorchScript module with Torch-TensorRT on a +pretrained ResNet-50 network, and running it to test the speedup obtained. + +* `Torch-TensorRT Getting Started - ResNet 50 `_ + + +Using Dynamic Shapes with Torch-TensorRT +******************************************** + +Making use of Dynamic Shaped Tensors in Torch TensorRT is quite simple. Let's say you are +using the ``torch_tensorrt.compile(...)`` function to compile a torchscript module. One +of the args in this function in this function is ``input``: which defines an input to a +module in terms of expected shape, data type and tensor format: ``torch_tensorrt.Input.`` + +For the purposes of this walkthrough we just need three kwargs: `min_shape`, `opt_shape`` and `max_shape`. + +.. code-block:: py + + torch_tensorrt.Input( + min_shape=(1, 224, 224, 3), + opt_shape=(1, 512, 512, 3), + max_shape=(1, 1024, 1024, 3), + dtype=torch.int32 + format=torch.channel_last + ) + ... + +In this example, we are going to use a simple ResNet model to demonstrate the use of the API. + +* `Torch-TensorRT - Using Dynamic Shapes `_ + +Using the FX Frontend with Torch-TensorRT +******************************************** + +The purpose of this example is to demostrate the overall flow of lowering a PyTorch model to TensorRT +conveniently with using FX. + +* `Using the FX Frontend with Torch-TensorRT `_ + + +Compiling a PyTorch model using FX Frontend with Torch-TensorRT +******************************************************************* + +The purpose of this example is to demonstrate the overall flow of lowering a PyTorch +model to TensorRT via FX with existing FX based tooling + +* `Compiling a PyTorch model using FX Frontend with Torch-TensorRT `_ + + +Compiling LeNet with Torch-TensorRT +******************************************************************* + +This notebook demonstrates the steps for compiling a TorchScript module with Torch-TensorRT on a simple LeNet network. + +* `Torch-TensorRT Getting Started - LeNet `_ + + +Accelerate Deep Learning Models using Quantization in Torch-TensorRT +******************************************************************* + +Model Quantization is a popular way of optimization which reduces the size of models thereby +accelerating inference, also opening up the possibilities of deployments on devices with lower +computation power such as Jetson. Simply put, quantization is a process of mapping input values + from a larger set to output values in a smaller set. In this notebook, we illustrate the workflow + that you can adopt while quantizing a deep learning model in Torch-TensorRT. The notebook takes + you through an example of Mobilenetv2 for a classification task on a subset of Imagenet Dataset + called Imagenette which has 10 classes. + +* `Accelerate Deep Learning Models using Quantization in Torch-TensorRT `_ + + +Object Detection with Torch-TensorRT (SSD) +******************************************************************* + +This notebook demonstrates the steps for compiling a TorchScript module with Torch-TensorRT on a pretrained SSD network, and running it to test the speedup obtained. + +* `Object Detection with Torch-TensorRT (SSD) `_ + + +Deploying Quantization Aware Trained models in INT8 using Torch-TensorRT +***************************************************************************** + +Quantization Aware training (QAT) simulates quantization during training by +quantizing weights and activation layers. This will help to reduce the loss in +accuracy when we convert the network trained in FP32 to INT8 for faster inference. +QAT introduces additional nodes in the graph which will be used to learn the dynamic +ranges of weights and activation layers. In this notebook, we illustrate the following +steps from training to inference of a QAT model in Torch-TensorRT. + +* `Deploying Quantization Aware Trained models in INT8 using Torch-TensorRT `_ diff --git a/docs/v2.2.0/_sources/tutorials/serving_torch_tensorrt_with_triton.rst.txt b/docs/v2.2.0/_sources/tutorials/serving_torch_tensorrt_with_triton.rst.txt new file mode 100644 index 0000000000..a713d563c2 --- /dev/null +++ b/docs/v2.2.0/_sources/tutorials/serving_torch_tensorrt_with_triton.rst.txt @@ -0,0 +1,216 @@ +.. _serving_torch_tensorrt_with_triton: + +Serving a Torch-TensorRT model with Triton +========================================== + +Optimization and deployment go hand in hand in a discussion about Machine +Learning infrastructure. Once network level optimzation are done +to get the maximum performance, the next step would be to deploy it. + +However, serving this optimized model comes with it's own set of considerations +and challenges like: building an infrastructure to support concorrent model +executions, supporting clients over HTTP or gRPC and more. + +The `Triton Inference Server `__ +solves the aforementioned and more. Let's discuss step-by-step, the process of +optimizing a model with Torch-TensorRT, deploying it on Triton Inference +Server, and building a client to query the model. + +Step 1: Optimize your model with Torch-TensorRT +----------------------------------------------- + +Most Torch-TensorRT users will be familiar with this step. For the purpose of +this demonstration, we will be using a ResNet50 model from Torchhub. + +Let’s first pull the `NGC PyTorch Docker container `__. You may need to create +an account and get the API key from `here `__. +Sign up and login with your key (follow the instructions +`here `__ after signing up). + +:: + + # is the yy:mm for the publishing tag for NVIDIA's Pytorch + # container; eg. 22.04 + + docker run -it --gpus all -v ${PWD}:/scratch_space nvcr.io/nvidia/pytorch:-py3 + cd /scratch_space + +Once inside the container, we can proceed to download a ResNet model from +Torchhub and optimize it with Torch-TensorRT. + +:: + + import torch + import torch_tensorrt + torch.hub._validate_not_a_forked_repo=lambda a,b,c: True + + # load model + model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True).eval().to("cuda") + + # Compile with Torch TensorRT; + trt_model = torch_tensorrt.compile(model, + inputs= [torch_tensorrt.Input((1, 3, 224, 224))], + enabled_precisions= { torch.half} # Run with FP32 + ) + + # Save the model + torch.jit.save(trt_model, "model.pt") + +After copying the model, exit the container. The next step in the process +is to set up a Triton Inference Server. + +Step 2: Set Up Triton Inference Server +-------------------------------------- + +If you are new to the Triton Inference Server and want to learn more, we +highly recommend to checking our `Github +Repository `__. + +To use Triton, we need to make a model repository. A model repository, as the +name suggested, is a repository of the models the Inference server hosts. While +Triton can serve models from multiple repositories, in this example, we will +discuss the simplest possible form of the model repository. + +The structure of this repository should look something like this: + +:: + + model_repository + | + +-- resnet50 + | + +-- config.pbtxt + +-- 1 + | + +-- model.pt + +There are two files that Triton requires to serve the model: the model itself +and a model configuration file which is typically provided in ``config.pbtxt``. +For the model we prepared in step 1, the following configuration can be used: + +:: + + name: "resnet50" + platform: "pytorch_libtorch" + max_batch_size : 0 + input [ + { + name: "input__0" + data_type: TYPE_FP32 + dims: [ 3, 224, 224 ] + reshape { shape: [ 1, 3, 224, 224 ] } + } + ] + output [ + { + name: "output__0" + data_type: TYPE_FP32 + dims: [ 1, 1000 ,1, 1] + reshape { shape: [ 1, 1000 ] } + } + ] + +The ``config.pbtxt`` file is used to describe the exact model configuration +with details like the names and shapes of the input and output layer(s), +datatypes, scheduling and batching details and more. If you are new to Triton, +we highly encourage you to check out this `section of our +documentation `__ +for more details. + +With the model repository setup, we can proceed to launch the Triton server +with the docker command below. Refer `this page `__ for the pull tag for the container. + +:: + + # Make sure that the TensorRT version in the Triton container + # and TensorRT version in the environment used to optimize the model + # are the same. + + docker run --gpus all --rm -p 8000:8000 -p 8001:8001 -p 8002:8002 -v /full/path/to/the_model_repository/model_repository:/models nvcr.io/nvidia/tritonserver:-py3 tritonserver --model-repository=/models + +This should spin up a Triton Inference server. Next step, building a simple +http client to query the server. + +Step 3: Building a Triton Client to Query the Server +---------------------------------------------------- + +Before proceeding, make sure to have a sample image on hand. If you don't +have one, download an example image to test inference. In this section, we +will be going over a very basic client. For a variety of more fleshed out +examples, refer to the `Triton Client Repository `__ + +:: + + wget -O img1.jpg "https://www.hakaimagazine.com/wp-content/uploads/header-gulf-birds.jpg" + +We then need to install dependencies for building a python client. These will +change from client to client. For a full list of all languages supported by Triton, +please refer to `Triton's client repository `__. + +:: + + pip install torchvision + pip install attrdict + pip install nvidia-pyindex + pip install tritonclient[all] + +Let's jump into the client. Firstly, we write a small preprocessing function to +resize and normalize the query image. + +:: + + import numpy as np + from torchvision import transforms + from PIL import Image + import tritonclient.http as httpclient + from tritonclient.utils import triton_to_np_dtype + + # preprocessing function + def rn50_preprocess(img_path="img1.jpg"): + img = Image.open(img_path) + preprocess = transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + ]) + return preprocess(img).numpy() + + transformed_img = rn50_preprocess() + +Building a client requires three basic points. Firstly, we setup a connection +with the Triton Inference Server. + +:: + + # Setting up client + client = httpclient.InferenceServerClient(url="localhost:8000") + +Secondly, we specify the names of the input and output layer(s) of our model. + +:: + + inputs = httpclient.InferInput("input__0", transformed_img.shape, datatype="FP32") + inputs.set_data_from_numpy(transformed_img, binary_data=True) + + outputs = httpclient.InferRequestedOutput("output__0", binary_data=True, class_count=1000) + +Lastly, we send an inference request to the Triton Inference Server. + +:: + + # Querying the server + results = client.infer(model_name="resnet50", inputs=[inputs], outputs=[outputs]) + inference_output = results.as_numpy('output__0') + print(inference_output[:5]) + +The output of the same should look like below: + +:: + + [b'12.468750:90' b'11.523438:92' b'9.664062:14' b'8.429688:136' + b'8.234375:11'] + +The output format here is ``:``. +To learn how to map these to the label names and more, refer to Triton Inference Server's +`documentation `__. diff --git a/docs/v2.2.0/_sources/user_guide/dynamic_shapes.rst.txt b/docs/v2.2.0/_sources/user_guide/dynamic_shapes.rst.txt new file mode 100644 index 0000000000..73ed9b594a --- /dev/null +++ b/docs/v2.2.0/_sources/user_guide/dynamic_shapes.rst.txt @@ -0,0 +1,209 @@ +.. _dynamic_shapes: + +Dynamic shapes with Torch-TensorRT +==================================== + +By default, you can run a pytorch model with varied input shapes and the output shapes are determined eagerly. +However, Torch-TensorRT is an AOT compiler which requires some prior information about the input shapes to compile and optimize the model. +In the case of dynamic input shapes, we must provide the (min_shape, opt_shape, max_shape) arguments so that the model can be optimized for +these range of input shapes. An example usage of static and dynamic shapes is as follows. + +NOTE: The following code uses Dynamo Frontend. Incase of Torchscript Frontend, please swap out ``ir=dynamo`` with ``ir=ts`` and the behavior is exactly the same. + +.. code-block:: python + + import torch + import torch_tensorrt + + model = MyModel().eval().cuda() + # Compile with static shapes + inputs = torch_tensorrt.Input(shape=[1, 3, 224, 224], dtype=torch.float32) + # or compile with dynamic shapes + inputs = torch_tensorrt.Input(min_shape=[1, 3, 224, 224], + opt_shape=[4, 3, 224, 224], + max_shape=[8, 3, 224, 224], + dtype=torch.float32) + trt_gm = torch_tensorrt.compile(model, ir="dynamo", inputs) + +Under the hood +-------------- + +There are two phases of compilation when we use ``torch_tensorrt.compile`` API with ``ir=dynamo`` (default). + +- aten_tracer.trace (which uses torch.export to trace the graph with the given inputs) + +In the tracing phase, we use torch.export along with the constraints. In the case of +dynamic shaped inputs, the range can be provided to the tracing via constraints. Please +refer to this `docstring `_ +for detailed information on how to set constraints. In short, we create new inputs for +torch.export tracing and provide constraints on the min and max values(provided by the user), a particular dimension can take. +Please take a look at ``aten_tracer.py`` file to understand how this works under the hood. + +- dynamo.compile (which compiles a torch.fx.GraphModule object using TensorRT) + +In the conversion to TensorRT, we use the user provided dynamic shape inputs. +We perform shape analysis using dummy inputs (across min, opt and max shapes) and store the +intermediate output shapes which can be used in case the graph has a mix of Pytorch +and TensorRT submodules. + +Custom Constraints +------------------ + +Given an input ``x = torch_tensorrt.Input(min_shape, opt_shape, max_shape, dtype)``, +Torch-TensorRT automatically sets the constraints during ``torch.export`` tracing as follows + +.. code-block:: python + + for dim in constraint_dims: + if min_shape[dim] > 1: + constraints.append(min_shape[dim] <= dynamic_dim(trace_input, dim)) + if max_shape[dim] > 1: + constraints.append(dynamic_dim(trace_input, dim) <= max_shape[dim]) + +Sometimes, we might need to set additional constraints and Torchdynamo errors out if we don't specify them. +For example, in the case of BERT model compilation, there are two inputs and a constraint has to be set involving the sequence length size of these two inputs. + +.. code-block:: python + + constraints.append(dynamic_dim(trace_inputs[0], 0) == dynamic_dim(trace_inputs[1], 0)) + + +If you have to provide any custom constraints to your model, the overall workflow for model compilation using ``ir=dynamo`` would involve a few steps. + +.. code-block:: python + + import torch + import torch_tensorrt + from torch_tensorrt.dynamo.lowering import apply_lowering_passes, get_decompositions + # Assume the model has two inputs + model = MyModel() + torch_input_1 = torch.randn((1, 14), dtype=torch.int32).cuda() + torch_input_2 = torch.randn((1, 14), dtype=torch.int32).cuda() + + dynamic_inputs = [torch_tensorrt.Input(min_shape=[1, 14], + opt_shape=[4, 14], + max_shape=[8, 14], + dtype=torch.int32), + torch_tensorrt.Input(min_shape=[1, 14], + opt_shape=[4, 14], + max_shape=[8, 14], + dtype=torch.int32)] + + # Export the model with additional constraints + constraints = [] + # The following constraints are automatically added by Torch-TensorRT in the + # general case when you call torch_tensorrt.compile directly on MyModel() + constraints.append(dynamic_dim(torch_input_1, 0) < 8) + constraints.append(dynamic_dim(torch_input_2, 0) < 8) + # This is an additional constraint as instructed by Torchdynamo + constraints.append(dynamic_dim(torch_input_1, 0) == dynamic_dim(torch_input_2, 0)) + with unittest.mock.patch( + "torch._export.DECOMP_TABLE", get_decompositions(experimental_decompositions) + ): + graph_module = export( + model, (torch_input_1, torch_input_2), constraints=constraints + ).module() + + # Use the dynamo.compile API + trt_mod = torch_tensorrt.dynamo.compile(graph_module, inputs=dynamic_inputs, **compile_spec) + +Limitations +----------- + +If there are operations in the graph that use the dynamic dimension of the input, Pytorch +introduces ``torch.ops.aten.sym_size.int`` ops in the graph. Currently, we cannot handle these operators and +the compilation results in undefined behavior. We plan to add support for these operators and implement +robust support for shape tensors in the next release. Here is an example of the limitation described above + +.. code-block:: python + + import torch + import torch_tensorrt + + class MyModule(torch.nn.Module): + def __init__(self): + super().__init__() + self.avgpool = torch.nn.AdaptiveAvgPool2d((1, 1)) + + def forward(self, x): + x = self.avgpool(x) + out = torch.flatten(x, 1) + return out + + model = MyModel().eval().cuda() + # Compile with dynamic shapes + inputs = torch_tensorrt.Input(min_shape=(1, 512, 1, 1), + opt_shape=(4, 512, 1, 1), + max_shape=(8, 512, 1, 1), + dtype=torch.float32) + trt_gm = torch_tensorrt.compile(model, ir="dynamo", inputs) + + +The traced graph of `MyModule()` looks as follows + +.. code-block:: python + + Post export graph: graph(): + %arg0_1 : [num_users=2] = placeholder[target=arg0_1] + %mean : [num_users=1] = call_function[target=torch.ops.aten.mean.dim](args = (%arg0_1, [-1, -2], True), kwargs = {}) + %sym_size : [num_users=1] = call_function[target=torch.ops.aten.sym_size.int](args = (%arg0_1, 0), kwargs = {}) + %view : [num_users=1] = call_function[target=torch.ops.aten.view.default](args = (%mean, [%sym_size, 512]), kwargs = {}) + return (view,) + + +Here the ``%sym_size`` node captures the dynamic batch and uses it in the ``aten.view`` layer. This requires shape tensors support +which would be a part of our next release. + +Workaround (BERT static compilation example) +------------------------------------------ + +In the case where you encounter the issues mentioned in the **Limitations** section, +you can compile the model (static mode) with max input size that can be provided. In the cases of smaller inputs, +we can pad them accordingly. This is only a workaround until we address the limitations. + +.. code-block:: python + + import torch + import torch_tensorrt + from transformers.utils.fx import symbolic_trace as transformers_trace + + model = BertModel.from_pretrained("bert-base-uncased").cuda().eval() + + # Input sequence length is 20. + input1 = torch.randint(0, 5, (1, 20), dtype=torch.int32).to("cuda") + input2 = torch.randint(0, 5, (1, 20), dtype=torch.int32).to("cuda") + + model = transformers_trace(model, input_names=["input_ids", "attention_mask"]).eval().cuda() + trt_mod = torch_tensorrt.compile(model, inputs=[input1, input2], **compile_spec) + model_outputs = model(input, input2) + + # If you have a sequence of length 14, pad 6 zero tokens and run inference + # or recompile for sequence length of 14. + input1 = torch.randint(0, 5, (1, 14), dtype=torch.int32).to("cuda") + input2 = torch.randint(0, 5, (1, 14), dtype=torch.int32).to("cuda") + trt_mod = torch_tensorrt.compile(model, inputs=[input1, input2], **compile_spec) + model_outputs = model(input, input2) + + +Dynamic shapes with ir=torch_compile +------------------------------------ + +``torch_tensorrt.compile(model, inputs, ir="torch_compile")`` returns a torch.compile boxed function with the backend +configured to Tensorrt. In the case of ``ir=torch_compile``, when the input size changes, Dynamo will trigger a recompilation +of the TensorRT engine automatically giving dynamic shape behavior similar to native PyTorch eager however with the cost of rebuilding +TRT engine. This limitation will be addressed in future versions of Torch-TensorRT. + +.. code-block:: python + + import torch + import torch_tensorrt + + model = MyModel().eval().cuda() + inputs = torch.randn((1, 3, 224, 224), dtype=float32) + trt_gm = torch_tensorrt.compile(model, ir="torch_compile", inputs) + # Compilation happens when you call the model + trt_gm(inputs) + + # Recompilation happens with modified batch size + inputs_bs2 = torch.randn((2, 3, 224, 224), dtype=torch.float32) + trt_gm = torch_tensorrt.compile(model, ir="torch_compile", inputs_bs2) diff --git a/docs/v2.2.0/_sources/user_guide/ptq.rst.txt b/docs/v2.2.0/_sources/user_guide/ptq.rst.txt new file mode 100644 index 0000000000..b62457109f --- /dev/null +++ b/docs/v2.2.0/_sources/user_guide/ptq.rst.txt @@ -0,0 +1,205 @@ +.. _ptq: + +Post Training Quantization (PTQ) +================================= + +Post Training Quantization (PTQ) is a technique to reduce the required computational resources for inference +while still preserving the accuracy of your model by mapping the traditional FP32 activation space to a reduced +INT8 space. TensorRT uses a calibration step which executes your model with sample data from the target domain +and track the activations in FP32 to calibrate a mapping to INT8 that minimizes the information loss between +FP32 inference and INT8 inference. + +Users writing TensorRT applications are required to setup a calibrator class which will provide sample data to +the TensorRT calibrator. With Torch-TensorRT we look to leverage existing infrastructure in PyTorch to make implementing +calibrators easier. + +LibTorch provides a ``DataLoader`` and ``Dataset`` API which steamlines preprocessing and batching input data. +These APIs are exposed via both C++ and Python interface which makes it easier for the end user. +For C++ interface, we use ``torch::Dataset`` and ``torch::data::make_data_loader`` objects to construct and perform pre-processing on datasets. +The equivalent functionality in python interface uses ``torch.utils.data.Dataset`` and ``torch.utils.data.DataLoader``. +This section of the PyTorch documentation has more information https://pytorch.org/tutorials/advanced/cpp_frontend.html#loading-data and https://pytorch.org/tutorials/recipes/recipes/loading_data_recipe.html. +Torch-TensorRT uses Dataloaders as the base of a generic calibrator implementation. So you will be able to reuse or quickly +implement a ``torch::Dataset`` for your target domain, place it in a DataLoader and create a INT8 Calibrator +which you can provide to Torch-TensorRT to run INT8 Calibration during compliation of your module. + +.. _writing_ptq_cpp: + +How to create your own PTQ application in C++ +----------------------------------------------- + +Here is an example interface of a ``torch::Dataset`` class for CIFAR10: + +.. code-block:: c++ + :linenos: + + //cpp/ptq/datasets/cifar10.h + #pragma once + + #include "torch/data/datasets/base.h" + #include "torch/data/example.h" + #include "torch/types.h" + + #include + #include + + namespace datasets { + // The CIFAR10 Dataset + class CIFAR10 : public torch::data::datasets::Dataset { + public: + // The mode in which the dataset is loaded + enum class Mode { kTrain, kTest }; + + // Loads CIFAR10 from un-tarred file + // Dataset can be found https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz + // Root path should be the directory that contains the content of tarball + explicit CIFAR10(const std::string& root, Mode mode = Mode::kTrain); + + // Returns the pair at index in the dataset + torch::data::Example<> get(size_t index) override; + + // The size of the dataset + c10::optional size() const override; + + // The mode the dataset is in + bool is_train() const noexcept; + + // Returns all images stacked into a single tensor + const torch::Tensor& images() const; + + // Returns all targets stacked into a single tensor + const torch::Tensor& targets() const; + + // Trims the dataset to the first n pairs + CIFAR10&& use_subset(int64_t new_size); + + + private: + Mode mode_; + torch::Tensor images_, targets_; + }; + } // namespace datasets + + +This class's implementation reads from the binary distribution of the CIFAR10 dataset and builds two tensors which hold the images and labels. + +We use a subset of the dataset to use for calibration, since we don't need the the full dataset for effective calibration and calibration does +some take time, then define the preprocessing to apply to the images in the dataset and create a DataLoader from the dataset which will batch the data: + +.. code-block:: c++ + + auto calibration_dataset = datasets::CIFAR10(data_dir, datasets::CIFAR10::Mode::kTest) + .use_subset(320) + .map(torch::data::transforms::Normalize<>({0.4914, 0.4822, 0.4465}, + {0.2023, 0.1994, 0.2010})) + .map(torch::data::transforms::Stack<>()); + auto calibration_dataloader = torch::data::make_data_loader(std::move(calibration_dataset), + torch::data::DataLoaderOptions().batch_size(32) + .workers(2)); + + +Next we create a calibrator from the ``calibration_dataloader`` using the calibrator factory (found in ``torch_tensorrt/ptq.h``): + +.. code-block:: c++ + + #include "torch_tensorrt/ptq.h" + ... + + auto calibrator = torch_tensorrt::ptq::make_int8_calibrator(std::move(calibration_dataloader), calibration_cache_file, true); + +Here we also define a location to write a calibration cache file to which we can use to reuse the calibration data without needing the dataset and whether or not +we should use the cache file if it exists. There also exists a ``torch_tensorrt::ptq::make_int8_cache_calibrator`` factory which creates a calibrator that uses the cache +only for cases where you may do engine building on a machine that has limited storage (i.e. no space for a full dataset) or to have a simpiler deployment application. + +The calibrator factories create a calibrator that inherits from a ``nvinfer1::IInt8Calibrator`` virtual class (``nvinfer1::IInt8EntropyCalibrator2`` by default) which +defines the calibration algorithm used when calibrating. You can explicitly make the selection of calibration algorithm like this: + +.. code-block:: c++ + + // MinMax Calibrator is geared more towards NLP tasks + auto calibrator = torch_tensorrt::ptq::make_int8_calibrator(std::move(calibration_dataloader), calibration_cache_file, true); + +Then all thats required to setup the module for INT8 calibration is to set the following compile settings in the `torch_tensorrt::CompileSpec` struct and compiling the module: + +.. code-block:: c++ + + std::vector> input_shape = {{32, 3, 32, 32}}; + /// Configure settings for compilation + auto compile_spec = torch_tensorrt::CompileSpec({input_shape}); + /// Set operating precision to INT8 + compile_spec.enabled_precisions.insert(torch::kF16); + compile_spec.enabled_precisions.insert(torch::kI8); + /// Use the TensorRT Entropy Calibrator + compile_spec.ptq_calibrator = calibrator; + + auto trt_mod = torch_tensorrt::CompileGraph(mod, compile_spec); + +If you have an existing Calibrator implementation for TensorRT you may directly set the ``ptq_calibrator`` field with a pointer to your calibrator and it will work as well. +From here not much changes in terms of how to execution works. You are still able to fully use LibTorch as the sole interface for inference. Data should remain +in FP32 precision when it's passed into `trt_mod.forward`. There exists an example application in the Torch-TensorRT demo that takes you from training a VGG16 network on +CIFAR10 to deploying in INT8 with Torch-TensorRT here: https://github.com/pytorch/TensorRT/tree/master/cpp/ptq + +.. _writing_ptq_python: + +How to create your own PTQ application in Python +-------------------------------------------------- + +Torch-TensorRT Python API provides an easy and convenient way to use pytorch dataloaders with TensorRT calibrators. ``DataLoaderCalibrator`` class can be used to create +a TensorRT calibrator by providing desired configuration. The following code demonstrates an example on how to use it + +.. code-block:: python + + testing_dataset = torchvision.datasets.CIFAR10( + root="./data", + train=False, + download=True, + transform=transforms.Compose( + [ + transforms.ToTensor(), + transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), + ] + ), + ) + + testing_dataloader = torch.utils.data.DataLoader( + testing_dataset, batch_size=1, shuffle=False, num_workers=1 + ) + calibrator = torch_tensorrt.ptq.DataLoaderCalibrator( + testing_dataloader, + cache_file="./calibration.cache", + use_cache=False, + algo_type=torch_tensorrt.ptq.CalibrationAlgo.ENTROPY_CALIBRATION_2, + device=torch.device("cuda:0"), + ) + + trt_mod = torch_tensorrt.compile(model, inputs=[torch_tensorrt.Input((1, 3, 32, 32))], + enabled_precisions={torch.float, torch.half, torch.int8}, + calibrator=calibrator, + device={ + "device_type": torch_tensorrt.DeviceType.GPU, + "gpu_id": 0, + "dla_core": 0, + "allow_gpu_fallback": False, + "disable_tf32": False + }) + +In the cases where there is a pre-existing calibration cache file that users want to use, ``CacheCalibrator`` can be used without any dataloaders. The following example demonstrates how +to use ``CacheCalibrator`` to use in INT8 mode. + +.. code-block:: python + + calibrator = torch_tensorrt.ptq.CacheCalibrator("./calibration.cache") + + trt_mod = torch_tensorrt.compile(model, inputs=[torch_tensorrt.Input([1, 3, 32, 32])], + enabled_precisions={torch.float, torch.half, torch.int8}, + calibrator=calibrator) + +If you already have an existing calibrator class (implemented directly using TensorRT API), you can directly set the calibrator field to your class which can be very convenient. +For a demo on how PTQ can be performed on a VGG network using Torch-TensorRT API, you can refer to https://github.com/pytorch/TensorRT/blob/master/tests/py/test_ptq_dataloader_calibrator.py +and https://github.com/pytorch/TensorRT/blob/master/tests/py/test_ptq_trt_calibrator.py + +Citations +^^^^^^^^^^^ + +Krizhevsky, A., & Hinton, G. (2009). Learning multiple layers of features from tiny images. + +Simonyan, K., & Zisserman, A. (2014). Very deep convolutional networks for large-scale image recognition. arXiv preprint arXiv:1409.1556. diff --git a/docs/v2.2.0/_sources/user_guide/runtime.rst.txt b/docs/v2.2.0/_sources/user_guide/runtime.rst.txt new file mode 100644 index 0000000000..8264abdd32 --- /dev/null +++ b/docs/v2.2.0/_sources/user_guide/runtime.rst.txt @@ -0,0 +1,70 @@ +.. _runtime: + +Deploying Torch-TensorRT Programs +==================================== + +After compiling and saving Torch-TensorRT programs there is no longer a strict dependency on the full +Torch-TensorRT library. All that is required to run a compiled program is the runtime. There are therfore a couple +options to deploy your programs other than shipping the full Torch-TensorRT compiler with your applications. + +Torch-TensorRT package / libtorchtrt.so +-------------------------------------------- + +Once a program is compiled, you run it using the standard PyTorch APIs. All that is required is that the package +must be imported in python or linked in C++. + +Runtime Library +----------------- + +Distributed with the C++ distribution is ``libtorchtrt_runtime.so``. This library only contains the components +necessary to run Torch-TensorRT programs. Instead of linking ``libtorchtrt.so`` or importing ``torch_tensorrt`` you can +link ``libtorchtrt_runtime.so`` in your deployment programs or use ``DL_OPEN`` or ``LD_PRELOAD``. For python +you can load the runtime with ``torch.ops.load_library("libtorchtrt_runtime.so")``. You can then continue to use +programs just as you would otherwise via PyTorch API. + +.. note:: If you are using the standard distribution of PyTorch in Python on x86, likely you will need the pre-cxx11-abi variant of ``libtorchtrt_runtime.so``, check :ref:`Installation` documentation for more details. + +.. note:: If you are linking ``libtorchtrt_runtime.so``, likely using the following flags will help ``-Wl,--no-as-needed -ltorchtrt -Wl,--as-needed`` as theres no direct symbol dependency to anything in the Torch-TensorRT runtime for most Torch-TensorRT runtime applications + +An example of how to use ``libtorchtrt_runtime.so`` can be found here: https://github.com/pytorch/TensorRT/tree/master/examples/torchtrt_runtime_example + +Plugin Library +--------------- + +In the case you use Torch-TensorRT as a converter to a TensorRT engine and your engine uses plugins provided by Torch-TensorRT, Torch-TensorRT +ships the library ``libtorchtrt_plugins.so`` which contains the implementation of the TensorRT plugins used by Torch-TensorRT during +compilation. This library can be ``DL_OPEN`` or ``LD_PRELOAD`` similar to other TensorRT plugin libraries. + +Multi Device Safe Mode +--------------- + +Multi-device safe mode is a setting in Torch-TensorRT which allows the user to determine whether +the runtime checks for device consistency prior to every inference call. + +There is a non-negligible, fixed cost per-inference call when multi-device safe mode is enabled, which is why +it is now disabled by default. It can be controlled via the following convenience function which +doubles as a context manager. + +.. code-block:: python + + # Enables Multi Device Safe Mode + torch_tensorrt.runtime.set_multi_device_safe_mode(True) + + # Disables Multi Device Safe Mode [Default Behavior] + torch_tensorrt.runtime.set_multi_device_safe_mode(False) + + # Enables Multi Device Safe Mode, then resets the safe mode to its prior setting + with torch_tensorrt.runtime.set_multi_device_safe_mode(True): + ... + +TensorRT requires that each engine be associated with the CUDA context in the active thread from which it is invoked. +Therefore, if the device were to change in the active thread, which may be the case when invoking +engines on multiple GPUs from the same Python process, safe mode will cause Torch-TensorRT to display +an alert and switch GPUs accordingly. If safe mode were not enabled, there could be a mismatch in the engine +device and CUDA context device, which could lead the program to crash. + +One technique for managing multiple TRT engines on different GPUs while not sacrificing performance for +multi-device safe mode is to use Python threads. Each thread is responsible for all of the TRT engines +on a single GPU, and the default CUDA device on each thread corresponds to the GPU for which it is +responsible (can be set via ``torch.cuda.set_device(...)``). In this way, multiple threads can be used in the same +Python script without needing to switch CUDA contexts and incur performance overhead. diff --git a/docs/v2.2.0/_sources/user_guide/saving_models.rst.txt b/docs/v2.2.0/_sources/user_guide/saving_models.rst.txt new file mode 100644 index 0000000000..8379b44f0f --- /dev/null +++ b/docs/v2.2.0/_sources/user_guide/saving_models.rst.txt @@ -0,0 +1,101 @@ +.. _saving_models: + +Saving models compiled with Torch-TensorRT +==================================== +.. currentmodule:: torch_tensorrt.dynamo + +.. automodule:: torch_tensorrt.dynamo + :members: + :undoc-members: + :show-inheritance: + +Saving models compiled with Torch-TensorRT varies slightly with the `ir` that has been used for compilation. + +Dynamo IR +------------- + +The output type of `ir=dynamo` compilation of Torch-TensorRT is `torch.export.ExportedProgram` object by default. +In addition, we provide a new parameter `output_format` in the `CompilationSetting` object provided before compilation. +The `output_format` can take the following options + +* `exported_program` (or) `ep` : This is the default. Returns an ExportedProgram +* `torchscript` (or) `ts` : This returns a TorchScript module +* `graph_module` (or) `fx` : This returns a torch.fx.GraphModule which can be traced into Torchscript to save to disk. + +a) Torchscript +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you set the `output_format="torchscript"`, this will return a `ScriptModule` which can be serialized via torch.jit.save + +.. code-block:: python + + import torch + import torch_tensorrt + + model = MyModel().eval().cuda() + inputs = [torch.randn((1, 3, 224, 224)).cuda()] + # trt_ts is a torch.jit.ScriptModule object + trt_ts = torch_tensorrt.compile(model, ir="dynamo", inputs, output_format="torchscript") + torch.jit.save(trt_ts, "trt_model.ts") + + # Later, you can load it and run inference + model = torch.jit.load("trt_model.ts").cuda() + model(*inputs) + +b) ExportedProgram +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +`torch.export.ExportedProgram`, a new format introduced in Pytorch 2.X is the default return type of Torch-TensorRT compilation. + +.. code-block:: python + + import torch + import torch_tensorrt + + model = MyModel().eval().cuda() + inputs = [torch.randn((1, 3, 224, 224)).cuda()] + # trt_ep is a torch.export.ExportedProgram object + trt_ep = torch_tensorrt.compile(model, ir="dynamo", inputs) + torch.export.save(trt_ep, "trt_model.ep") + + # Later, you can load it and run inference + model = torch.export.load("trt_model.ep") + model(*inputs) + +c) GraphModule +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We can also return a `torch.fx.GraphModule` object as the output of Torch-TensorRT compilation by setting `output_format="graph_module"`. +Internally, partitioning, lowering, conversion phases operate using GraphModule objects. These can be either traced into a Torchscript modules or +exported into `ExportedProgram` objects + +.. code-block:: python + + import torch + import torch_tensorrt + + model = MyModel().eval().cuda() + inputs = [torch.randn((1, 3, 224, 224)).cuda()] + # trt_gm is a torch.fx.GraphModule object + trt_gm = torch_tensorrt.compile(model, ir="dynamo", inputs, output_format="graph_module") + +Torchscript IR +------------- + +In Torch-TensorRT 1.X versions, the primary way to compile and run inference with Torch-TensorRT is using Torchscript IR. +For `ir=ts`, this behavior stays the same in 2.X versions as well. + +.. code-block:: python + + import torch + import torch_tensorrt + + model = MyModel().eval().cuda() + inputs = [torch.randn((1, 3, 224, 224)).cuda()] + trt_ts = torch_tensorrt.compile(model, ir="ts", inputs) # Output is a ScriptModule object + torch.jit.save(trt_ts, "trt_model.ts") + + # Later, you can load it and run inference + model = torch.jit.load("trt_model.ts").cuda() + model(*inputs) + diff --git a/docs/v2.2.0/_sources/user_guide/using_dla.rst.txt b/docs/v2.2.0/_sources/user_guide/using_dla.rst.txt new file mode 100644 index 0000000000..9b062f7053 --- /dev/null +++ b/docs/v2.2.0/_sources/user_guide/using_dla.rst.txt @@ -0,0 +1,47 @@ +.. _using_dla: + +DLA +================================= + +``DLA`` NVIDIA Deep Learning Accelerator is a fixed-function accelerator engine targeted for deep learning operations. DLA is designed to do full hardware acceleration of convolutional neural networks. DLA supports various layers such as convolution, deconvolution, fully-connected, activation, pooling, batch normalization, etc. ``torch_tensorrt`` supports compilation of TorchScript Module and deployment pipeline on the DLA hardware available on NVIDIA embedded platforms. + +NOTE: DLA supports fp16 and int8 precision only. + +Using DLA with torchtrtc + +.. code-block:: shell + + torchtrtc [input_file_path] [output_file_path] [input_shapes...] -p f16 -d dla {OPTIONS} + +Using DLA in a C++ application + +.. code-block:: c++ + + std::vector> input_shape = {{32, 3, 32, 32}}; + auto compile_spec = torch_tensorrt::CompileSpec({input_shape}); + + # Set a precision. DLA supports fp16 or int8 only + compile_spec.enabled_precisions = {torch::kF16}; + compile_spec.device.device_type = torch_tensorrt::CompileSpec::DeviceType::kDLA; + + # Make sure the gpu id is set to Xavier id for DLA + compile_spec.device.gpu_id = 0; + + # Set the DLA core id + compile_spec.device.dla_core = 1; + + # If a layer fails to run on DLA it will fallback to GPU + compile_spec.device.allow_gpu_fallback = true; + + +Using DLA in a python application + +.. code-block:: python + + compile_spec = { + "inputs": [torch_tensorrt.Input(self.input.shape)], + "device": torch_tensorrt.Device("dla:0", allow_gpu_fallback=True), + "enalbed_precisions": {torch.half}, + } + + trt_mod = torch_tensorrt.compile(self.scripted_model, compile_spec) diff --git a/docs/v2.2.0/_static/basic.css b/docs/v2.2.0/_static/basic.css new file mode 100644 index 0000000000..bf18350b65 --- /dev/null +++ b/docs/v2.2.0/_static/basic.css @@ -0,0 +1,906 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/v2.2.0/_static/binder_badge_logo.svg b/docs/v2.2.0/_static/binder_badge_logo.svg new file mode 100644 index 0000000000..327f6b639a --- /dev/null +++ b/docs/v2.2.0/_static/binder_badge_logo.svg @@ -0,0 +1 @@ + launchlaunchbinderbinder \ No newline at end of file diff --git a/docs/v2.2.0/_static/broken_example.png b/docs/v2.2.0/_static/broken_example.png new file mode 100644 index 0000000000000000000000000000000000000000..4fea24e7df4781c2c32c8d7995511ac89e953145 GIT binary patch literal 21404 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 Dnpk0b literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/collapsible-lists/css/button-open.png b/docs/v2.2.0/_static/collapsible-lists/css/button-open.png new file mode 100644 index 0000000000000000000000000000000000000000..ac4a6ef32a50516609a06733d3365c78237e2143 GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XCV9FzhE&{|GBJ>gS&_#j`GUT_;*XoNPsnBTUtm6Y&+UWI zzhh}p_Fm4rZ#T9-;BoF*cdbf!(e5A-HSIvY)bAY6=4_uLWcl2u=-kP@-`8&amZQa? zcbGwU|ALtpHI%;ip7~?-g8%3Cn;OS5n38#<|C#vBUf-h_aen=WPb~a4CH+tKE*EHG o{QhC0^XI-+?dA4A1QHnTT=Tf{X8(i9K-V#Ny85}Sb4q9e0Cgu}D*ylh literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/collapsible-lists/css/button.png b/docs/v2.2.0/_static/collapsible-lists/css/button.png new file mode 100644 index 0000000000000000000000000000000000000000..631d734d136a3c0e7698e249b09ac06462589ca8 GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XIy_w*Ln>}_1wcZrxMOpdTT1SY*0BaajE)#RCaoBVu2L* zl`q`0TYJ;m{DmgIKFEJ*``x_5|FhF>RLskN_)_w^#h<=_&?6G!7R%4e%r2L^v-9u4 c=?u&a+cKO!dpZ{#2fB&D)78&qol`;+0OL4aGynhq literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/collapsible-lists/css/list-item-contents.png b/docs/v2.2.0/_static/collapsible-lists/css/list-item-contents.png new file mode 100644 index 0000000000000000000000000000000000000000..bc082929dccbabcf58e5e7d88abe49bcb21c191e GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^azHG>!3HGXX8P_2Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JicCFS978H@y*ay)lYxPQ`QU?pk5l&F=w6!exiSCJoJkpJ l*0<{;UuGVFgYVglYz$osB0q2a^8jQegQu&X%Q~loCIAKZH$VUY literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/collapsible-lists/css/list-item-last-open.png b/docs/v2.2.0/_static/collapsible-lists/css/list-item-last-open.png new file mode 100644 index 0000000000000000000000000000000000000000..cf4cf9bdb9027b5b50ce2e259e5c8248d08e4e28 GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^azHG>!3HGXX8P_2Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jikv-N978H@CH?vT-=5j(#;#Irj|meS+Zs9(8xE{Ex>&3~ z$|mdMh0QZq`|td3+%RL}F}Z*Cvv#=Y%5AN<@@QeYp+f^BL(Mr3|LlYN!3HGXX8P_2Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jikv)M978H@CH?vT-=5j(#;#Irj|meS+Zs9(8xE{Ex>&3~ z$|mdMh0QZq`|s38MV;wbJ4vGVabUN*uH4p&D@i#F3I`ZWpL2P7J1TSnO=IwM^>bP0 Hl+XkKgRnR! literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/collapsible-lists/css/list-item-open.png b/docs/v2.2.0/_static/collapsible-lists/css/list-item-open.png new file mode 100644 index 0000000000000000000000000000000000000000..0889c801a9a86ea0fdbbd8cb07e3f47885bfa33e GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^azHG>!3HGXX8P_2Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jikv)M978H@CH?vT-=5j(#;#Irj|meS+Zs9(8xE{Ex>&3~ z$|mdMh0QZq`|td3+%#j_)Fb~d9x=`O2$JKs?Pg@+VW>I9;UCzqxBzGxgQu&X%Q~lo FCIHwyIzIpa literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/collapsible-lists/css/list-item-root.png b/docs/v2.2.0/_static/collapsible-lists/css/list-item-root.png new file mode 100644 index 0000000000000000000000000000000000000000..874417106af03875a02c3e19b1d57186419be94b GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^azHG>!3HGXX8P_2Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jii|y7978H@y}7{1%fP^Kctdl&_4V=;hZAWFPHJ_UW$Ci= p@bLU$*(Mvt36 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/collapsible-lists/css/list-item.png b/docs/v2.2.0/_static/collapsible-lists/css/list-item.png new file mode 100644 index 0000000000000000000000000000000000000000..81934f9b82d482150215e2dbfd21b7a94802c1c7 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^azHG>!3HGXX8P_2Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JitIgI978H@CH?vT-=5j(#;#Irj|meS+Zs9(8xE{Ex>&3~ z$|mdMh0QZq`|td3+*Gk;lEl`ED~|%Z-F4j<85r3Zj#;q>9G$xQ9MC8RPgg&ebxsLQ E0O;yB$N&HU literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/collapsible-lists/css/tree_view.css b/docs/v2.2.0/_static/collapsible-lists/css/tree_view.css new file mode 100644 index 0000000000..fa21ac4e84 --- /dev/null +++ b/docs/v2.2.0/_static/collapsible-lists/css/tree_view.css @@ -0,0 +1,61 @@ +/* Source taken directly from: + * view-source:http://code.iamkate.com/javascript/collapsible-lists/ + * + * Kate Morley's license for this code is CC0: + * Created by [Kate Morley](http://iamkate.com/). Except where explicitly + * stated otherwise, all content is released under the terms of the + * [CC0 1.0 Universal legal code](http://creativecommons.org/publicdomain/zero/1.0/legalcode). + */ +.treeView{ + -moz-user-select:none; + position:relative; +} + +.treeView ul{ + margin:0 0 0 -1.5em ! important; + padding:0 0 0 1.5em ! important; +} + +.treeView ul ul{ + background:url('list-item-contents.png') repeat-y left ! important; +} + +.treeView li.lastChild > ul{ + background-image:none ! important; +} + +.treeView li{ + margin:0 ! important; + padding:0 ! important; + background:url('list-item-root.png') no-repeat top left ! important; + list-style-position:inside ! important; + list-style-image:url('button.png') ! important; + cursor:auto; +} + +.treeView li.collapsibleListOpen{ + list-style-image:url('button-open.png') ! important; + cursor:pointer; +} + +.treeView li.collapsibleListClosed{ + list-style-image:url('button-closed.png') ! important; + cursor:pointer; +} + +.treeView li li{ + background-image:url('list-item.png') ! important; + padding-left:1.5em ! important; +} + +.treeView li.lastChild{ + background-image:url('list-item-last.png') ! important; +} + +.treeView li.collapsibleListOpen{ + background-image:url('list-item-open.png') ! important; +} + +.treeView li.collapsibleListOpen.lastChild{ + background-image:url('list-item-last-open.png') ! important; +} diff --git a/docs/v2.2.0/_static/collapsible-lists/js/CollapsibleLists.compressed.js b/docs/v2.2.0/_static/collapsible-lists/js/CollapsibleLists.compressed.js new file mode 100644 index 0000000000..429406cf39 --- /dev/null +++ b/docs/v2.2.0/_static/collapsible-lists/js/CollapsibleLists.compressed.js @@ -0,0 +1,83 @@ +/* + +CollapsibleLists.js + +An object allowing lists to dynamically expand and collapse + +Created by Kate Morley - http://code.iamkate.com/ - and released under +the terms of the CC0 1.0 Universal legal code: + +http://creativecommons.org/publicdomain/zero/1.0/legalcode + +*/ + +var CollapsibleLists=new function(){ +this.apply=function(_1){ +var _2=document.getElementsByTagName("ul"); +for(var _3=0;_3<_2.length;_3++){ +if(_2[_3].className.match(/(^| )collapsibleList( |$)/)){ +this.applyTo(_2[_3],true); +if(!_1){ +var _4=_2[_3].getElementsByTagName("ul"); +for(var _5=0;_5<_4.length;_5++){ +_4[_5].className+=" collapsibleList"; +} +} +} +} +}; +this.applyTo=function(_6,_7){ +var _8=_6.getElementsByTagName("li"); +for(var _9=0;_9<_8.length;_9++){ +if(!_7||_6==_8[_9].parentNode){ +if(_8[_9].addEventListener){ +_8[_9].addEventListener("mousedown",function(e){ +e.preventDefault(); +},false); +}else{ +_8[_9].attachEvent("onselectstart",function(){ +event.returnValue=false; +}); +} +if(_8[_9].addEventListener){ +_8[_9].addEventListener("click",_a(_8[_9]),false); +}else{ +_8[_9].attachEvent("onclick",_a(_8[_9])); +} +_b(_8[_9]); +} +} +}; +function _a(_c){ +return function(e){ +if(!e){ +e=window.event; +} +var _d=(e.target?e.target:e.srcElement); +while(_d.nodeName!="LI"){ +_d=_d.parentNode; +} +if(_d==_c){ +_b(_c); +} +}; +}; +function _b(_e){ +var _f=_e.className.match(/(^| )collapsibleListClosed( |$)/); +var uls=_e.getElementsByTagName("ul"); +for(var _10=0;_100){ +_e.className+=" collapsibleList"+(_f?"Open":"Closed"); +} +}; +}(); + diff --git a/docs/v2.2.0/_static/collapsible-lists/js/apply-collapsible-lists.js b/docs/v2.2.0/_static/collapsible-lists/js/apply-collapsible-lists.js new file mode 100644 index 0000000000..e848bb9811 --- /dev/null +++ b/docs/v2.2.0/_static/collapsible-lists/js/apply-collapsible-lists.js @@ -0,0 +1,3 @@ +$(document).ready(function() { + CollapsibleLists.apply(); +}); diff --git a/docs/v2.2.0/_static/css/custom.css b/docs/v2.2.0/_static/css/custom.css new file mode 100644 index 0000000000..2523d4e541 --- /dev/null +++ b/docs/v2.2.0/_static/css/custom.css @@ -0,0 +1,8 @@ +/* sphinx-design styles for cards/tabs +*/ + +.sphx-glr-thumbcontainer { + padding: 50%; + display: flex; + align-content: center; +} \ No newline at end of file diff --git a/docs/v2.2.0/_static/css/pytorch_theme.css b/docs/v2.2.0/_static/css/pytorch_theme.css new file mode 100644 index 0000000000..153f4889c0 --- /dev/null +++ b/docs/v2.2.0/_static/css/pytorch_theme.css @@ -0,0 +1,127 @@ +body { + font-family: "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif; +} + +/* Default header fonts are ugly */ +h1, h2, .rst-content .toctree-wrapper p.caption, h3, h4, h5, h6, legend, p.caption { + font-family: "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif; +} + +/* Use white for docs background */ +.wy-side-nav-search { + background-color: #fff; +} + +.wy-nav-content-wrap, .wy-menu li.current > a { + background-color: #fff; +} + +@media screen and (min-width: 1400px) { + .wy-nav-content-wrap { + background-color: rgba(0, 0, 0, 0.0470588); + } + + .wy-nav-content { + background-color: #fff; + } +} + +/* Fixes for mobile */ +.wy-nav-top { + background-color: #fff; + background-image: url('../img/pytorch-logo-dark.svg'); + background-repeat: no-repeat; + background-position: center; + padding: 0; + margin: 0.4045em 0.809em; + color: #333; +} + +.wy-nav-top > a { + display: none; +} + +@media screen and (max-width: 768px) { + .wy-side-nav-search>a img.logo { + height: 60px; + } +} + +/* This is needed to ensure that logo above search scales properly */ +.wy-side-nav-search a { + display: block; +} + +/* This ensures that multiple constructors will remain in separate lines. */ +.rst-content dl:not(.docutils) dt { + display: table; +} + +/* Use our red for literals (it's very similar to the original color) */ +.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal { + color: #F05732; +} + +.rst-content tt.xref, a .rst-content tt, .rst-content tt.xref, +.rst-content code.xref, a .rst-content tt, a .rst-content code { + color: #404040; +} + +/* Change link colors (except for the menu) */ + +a { + color: #F05732; +} + +a:hover { + color: #F05732; +} + + +a:visited { + color: #D44D2C; +} + +.wy-menu a { + color: #b3b3b3; +} + +.wy-menu a:hover { + color: #b3b3b3; +} + +a.icon.icon-home { + color: #D44D2C; +} + +.version{ + color: #D44D2C !important; +} + +/* Default footer text is quite big */ +footer { + font-size: 80%; +} + +footer .rst-footer-buttons { + font-size: 125%; /* revert footer settings - 1/80% = 125% */ +} + +footer p { + font-size: 100%; +} + +/* For hidden headers that appear in TOC tree */ +/* see https://stackoverflow.com/a/32363545/3343043 */ +.rst-content .hidden-section { + display: none; +} + +nav .hidden-section { + display: inherit; +} + +/* Make code blocks have a background */ +.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'] { + background: rgba(0, 0, 0, 0.0470588); +} diff --git a/docs/v2.2.0/_static/css/theme.css b/docs/v2.2.0/_static/css/theme.css new file mode 100644 index 0000000000..b8d69c23b0 --- /dev/null +++ b/docs/v2.2.0/_static/css/theme.css @@ -0,0 +1,12483 @@ +@charset "UTF-8"; +/*! + * Bootstrap v4.0.0 (https://getbootstrap.com) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +:root { + --blue: #007bff; + --indigo: #6610f2; + --purple: #6f42c1; + --pink: #e83e8c; + --red: #dc3545; + --orange: #fd7e14; + --yellow: #ffc107; + --green: #28a745; + --teal: #20c997; + --cyan: #17a2b8; + --white: #fff; + --gray: #6c757d; + --gray-dark: #343a40; + --primary: #007bff; + --secondary: #6c757d; + --success: #28a745; + --info: #17a2b8; + --warning: #ffc107; + --danger: #dc3545; + --light: #f8f9fa; + --dark: #343a40; + --breakpoint-xs: 0; + --breakpoint-sm: 576px; + --breakpoint-md: 768px; + --breakpoint-lg: 992px; + --breakpoint-xl: 1200px; + --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +*, +*::before, +*::after { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +html { + font-family: sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +@-ms-viewport { + width: device-width; +} +article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { + display: block; +} + +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: left; + background-color: #fff; +} + +[tabindex="-1"]:focus { + outline: 0 !important; +} + +hr { + -webkit-box-sizing: content-box; + box-sizing: content-box; + height: 0; + overflow: visible; +} + +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 0.5rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title], +abbr[data-original-title] { + text-decoration: underline; + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + border-bottom: 0; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: .5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +dfn { + font-style: italic; +} + +b, +strong { + font-weight: bolder; +} + +small { + font-size: 80%; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -.25em; +} + +sup { + top: -.5em; +} + +a { + color: #007bff; + text-decoration: none; + background-color: transparent; + -webkit-text-decoration-skip: objects; +} +a:hover { + color: #0056b3; + text-decoration: underline; +} + +a:not([href]):not([tabindex]) { + color: inherit; + text-decoration: none; +} +a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { + color: inherit; + text-decoration: none; +} +a:not([href]):not([tabindex]):focus { + outline: 0; +} + +pre, +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +pre { + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + -ms-overflow-style: scrollbar; +} + +figure { + margin: 0 0 1rem; +} + +img { + vertical-align: middle; + border-style: none; +} + +svg:not(:root) { + overflow: hidden; +} + +table { + border-collapse: collapse; +} + +caption { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: #6c757d; + text-align: left; + caption-side: bottom; +} + +th { + text-align: inherit; +} + +label { + display: inline-block; + margin-bottom: .5rem; +} + +button { + border-radius: 0; +} + +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +button, +html [type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + padding: 0; + border-style: none; +} + +input[type="radio"], +input[type="checkbox"] { + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + -webkit-appearance: listbox; +} + +textarea { + overflow: auto; + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + max-width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; + color: inherit; + white-space: normal; +} + +progress { + vertical-align: baseline; +} + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + outline-offset: -2px; + -webkit-appearance: none; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +summary { + display: list-item; + cursor: pointer; +} + +template { + display: none; +} + +[hidden] { + display: none !important; +} + +h1, h2, h3, h4, h5, h6, +.h1, .h2, .h3, .h4, .h5, .h6 { + margin-bottom: 0.5rem; + font-family: inherit; + font-weight: 500; + line-height: 1.2; + color: inherit; +} + +h1, .h1 { + font-size: 2.5rem; +} + +h2, .h2 { + font-size: 2rem; +} + +h3, .h3 { + font-size: 1.75rem; +} + +h4, .h4 { + font-size: 1.5rem; +} + +h5, .h5 { + font-size: 1.25rem; +} + +h6, .h6 { + font-size: 1rem; +} + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +.display-1 { + font-size: 6rem; + font-weight: 300; + line-height: 1.2; +} + +.display-2 { + font-size: 5.5rem; + font-weight: 300; + line-height: 1.2; +} + +.display-3 { + font-size: 4.5rem; + font-weight: 300; + line-height: 1.2; +} + +.display-4 { + font-size: 3.5rem; + font-weight: 300; + line-height: 1.2; +} + +hr { + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: 1px solid rgba(0, 0, 0, 0.1); +} + +small, +.small { + font-size: 80%; + font-weight: 400; +} + +mark, +.mark { + padding: 0.2em; + background-color: #fcf8e3; +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline-item { + display: inline-block; +} +.list-inline-item:not(:last-child) { + margin-right: 0.5rem; +} + +.initialism { + font-size: 90%; + text-transform: uppercase; +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; +} + +.blockquote-footer { + display: block; + font-size: 80%; + color: #6c757d; +} +.blockquote-footer::before { + content: "\2014 \00A0"; +} + +.img-fluid { + max-width: 100%; + height: auto; +} + +.img-thumbnail { + padding: 0.25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: 0.25rem; + max-width: 100%; + height: auto; +} + +.figure { + display: inline-block; +} + +.figure-img { + margin-bottom: 0.5rem; + line-height: 1; +} + +.figure-caption { + font-size: 90%; + color: #6c757d; +} + +code, +kbd, +pre, +samp { + font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +code { + font-size: 87.5%; + color: #e83e8c; + word-break: break-word; +} +a > code { + color: inherit; +} + +kbd { + padding: 0.2rem 0.4rem; + font-size: 87.5%; + color: #fff; + background-color: #212529; + border-radius: 0.2rem; +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: 700; +} + +pre { + display: block; + font-size: 87.5%; + color: #212529; +} +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +.container { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 576px) { + .container { + max-width: 540px; + } +} +@media (min-width: 768px) { + .container { + max-width: 720px; + } +} +@media (min-width: 992px) { + .container { + max-width: 960px; + } +} +@media (min-width: 1200px) { + .container { + max-width: 1140px; + } +} + +.container-fluid { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.row { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px; +} + +.no-gutters { + margin-right: 0; + margin-left: 0; +} +.no-gutters > .col, +.no-gutters > [class*="col-"] { + padding-right: 0; + padding-left: 0; +} + +.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col, +.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm, +.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md, +.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg, +.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl, +.col-xl-auto { + position: relative; + width: 100%; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} + +.col { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; +} + +.col-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; +} + +.col-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; +} + +.col-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; +} + +.col-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; +} + +.col-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; +} + +.col-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; +} + +.col-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; +} + +.col-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; +} + +.col-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; +} + +.col-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; +} + +.col-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; +} + +.col-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; +} + +.col-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; +} + +.order-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; +} + +.order-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; +} + +.order-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; +} + +.order-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; +} + +.order-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; +} + +.order-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; +} + +.order-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; +} + +.order-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; +} + +.order-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; +} + +.order-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; +} + +.order-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; +} + +.order-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; +} + +.order-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; +} + +.order-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; +} + +.order-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; +} + +.offset-1 { + margin-left: 8.3333333333%; +} + +.offset-2 { + margin-left: 16.6666666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.3333333333%; +} + +.offset-5 { + margin-left: 41.6666666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.3333333333%; +} + +.offset-8 { + margin-left: 66.6666666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.3333333333%; +} + +.offset-11 { + margin-left: 91.6666666667%; +} + +@media (min-width: 576px) { + .col-sm { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + + .col-sm-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + + .col-sm-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; + } + + .col-sm-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; + } + + .col-sm-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + + .col-sm-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; + } + + .col-sm-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; + } + + .col-sm-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + + .col-sm-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; + } + + .col-sm-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; + } + + .col-sm-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + + .col-sm-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; + } + + .col-sm-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; + } + + .col-sm-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .order-sm-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + + .order-sm-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + + .order-sm-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + + .order-sm-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + + .order-sm-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + + .order-sm-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + + .order-sm-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + + .order-sm-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + + .order-sm-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + + .order-sm-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + + .order-sm-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + + .order-sm-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + + .order-sm-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + + .order-sm-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + + .order-sm-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + + .offset-sm-0 { + margin-left: 0; + } + + .offset-sm-1 { + margin-left: 8.3333333333%; + } + + .offset-sm-2 { + margin-left: 16.6666666667%; + } + + .offset-sm-3 { + margin-left: 25%; + } + + .offset-sm-4 { + margin-left: 33.3333333333%; + } + + .offset-sm-5 { + margin-left: 41.6666666667%; + } + + .offset-sm-6 { + margin-left: 50%; + } + + .offset-sm-7 { + margin-left: 58.3333333333%; + } + + .offset-sm-8 { + margin-left: 66.6666666667%; + } + + .offset-sm-9 { + margin-left: 75%; + } + + .offset-sm-10 { + margin-left: 83.3333333333%; + } + + .offset-sm-11 { + margin-left: 91.6666666667%; + } +} +@media (min-width: 768px) { + .col-md { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + + .col-md-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + + .col-md-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; + } + + .col-md-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; + } + + .col-md-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + + .col-md-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; + } + + .col-md-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; + } + + .col-md-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + + .col-md-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; + } + + .col-md-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; + } + + .col-md-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + + .col-md-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; + } + + .col-md-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; + } + + .col-md-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .order-md-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + + .order-md-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + + .order-md-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + + .order-md-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + + .order-md-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + + .order-md-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + + .order-md-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + + .order-md-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + + .order-md-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + + .order-md-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + + .order-md-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + + .order-md-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + + .order-md-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + + .order-md-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + + .order-md-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + + .offset-md-0 { + margin-left: 0; + } + + .offset-md-1 { + margin-left: 8.3333333333%; + } + + .offset-md-2 { + margin-left: 16.6666666667%; + } + + .offset-md-3 { + margin-left: 25%; + } + + .offset-md-4 { + margin-left: 33.3333333333%; + } + + .offset-md-5 { + margin-left: 41.6666666667%; + } + + .offset-md-6 { + margin-left: 50%; + } + + .offset-md-7 { + margin-left: 58.3333333333%; + } + + .offset-md-8 { + margin-left: 66.6666666667%; + } + + .offset-md-9 { + margin-left: 75%; + } + + .offset-md-10 { + margin-left: 83.3333333333%; + } + + .offset-md-11 { + margin-left: 91.6666666667%; + } +} +@media (min-width: 992px) { + .col-lg { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + + .col-lg-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + + .col-lg-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; + } + + .col-lg-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; + } + + .col-lg-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + + .col-lg-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; + } + + .col-lg-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; + } + + .col-lg-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + + .col-lg-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; + } + + .col-lg-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; + } + + .col-lg-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + + .col-lg-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; + } + + .col-lg-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; + } + + .col-lg-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .order-lg-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + + .order-lg-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + + .order-lg-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + + .order-lg-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + + .order-lg-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + + .order-lg-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + + .order-lg-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + + .order-lg-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + + .order-lg-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + + .order-lg-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + + .order-lg-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + + .order-lg-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + + .order-lg-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + + .order-lg-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + + .order-lg-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + + .offset-lg-0 { + margin-left: 0; + } + + .offset-lg-1 { + margin-left: 8.3333333333%; + } + + .offset-lg-2 { + margin-left: 16.6666666667%; + } + + .offset-lg-3 { + margin-left: 25%; + } + + .offset-lg-4 { + margin-left: 33.3333333333%; + } + + .offset-lg-5 { + margin-left: 41.6666666667%; + } + + .offset-lg-6 { + margin-left: 50%; + } + + .offset-lg-7 { + margin-left: 58.3333333333%; + } + + .offset-lg-8 { + margin-left: 66.6666666667%; + } + + .offset-lg-9 { + margin-left: 75%; + } + + .offset-lg-10 { + margin-left: 83.3333333333%; + } + + .offset-lg-11 { + margin-left: 91.6666666667%; + } +} +@media (min-width: 1200px) { + .col-xl { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + + .col-xl-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + + .col-xl-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.3333333333%; + flex: 0 0 8.3333333333%; + max-width: 8.3333333333%; + } + + .col-xl-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.6666666667%; + flex: 0 0 16.6666666667%; + max-width: 16.6666666667%; + } + + .col-xl-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + + .col-xl-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.3333333333%; + flex: 0 0 33.3333333333%; + max-width: 33.3333333333%; + } + + .col-xl-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.6666666667%; + flex: 0 0 41.6666666667%; + max-width: 41.6666666667%; + } + + .col-xl-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + + .col-xl-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.3333333333%; + flex: 0 0 58.3333333333%; + max-width: 58.3333333333%; + } + + .col-xl-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.6666666667%; + flex: 0 0 66.6666666667%; + max-width: 66.6666666667%; + } + + .col-xl-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + + .col-xl-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.3333333333%; + flex: 0 0 83.3333333333%; + max-width: 83.3333333333%; + } + + .col-xl-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.6666666667%; + flex: 0 0 91.6666666667%; + max-width: 91.6666666667%; + } + + .col-xl-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + + .order-xl-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + + .order-xl-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + + .order-xl-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + + .order-xl-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + + .order-xl-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + + .order-xl-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + + .order-xl-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + + .order-xl-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + + .order-xl-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + + .order-xl-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + + .order-xl-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + + .order-xl-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + + .order-xl-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + + .order-xl-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + + .order-xl-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + + .offset-xl-0 { + margin-left: 0; + } + + .offset-xl-1 { + margin-left: 8.3333333333%; + } + + .offset-xl-2 { + margin-left: 16.6666666667%; + } + + .offset-xl-3 { + margin-left: 25%; + } + + .offset-xl-4 { + margin-left: 33.3333333333%; + } + + .offset-xl-5 { + margin-left: 41.6666666667%; + } + + .offset-xl-6 { + margin-left: 50%; + } + + .offset-xl-7 { + margin-left: 58.3333333333%; + } + + .offset-xl-8 { + margin-left: 66.6666666667%; + } + + .offset-xl-9 { + margin-left: 75%; + } + + .offset-xl-10 { + margin-left: 83.3333333333%; + } + + .offset-xl-11 { + margin-left: 91.6666666667%; + } +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 1rem; + background-color: transparent; +} +.table th, +.table td { + padding: 0.75rem; + vertical-align: top; + border-top: 1px solid #dee2e6; +} +.table thead th { + vertical-align: bottom; + border-bottom: 2px solid #dee2e6; +} +.table tbody + tbody { + border-top: 2px solid #dee2e6; +} +.table .table { + background-color: #fff; +} + +.table-sm th, +.table-sm td { + padding: 0.3rem; +} + +.table-bordered { + border: 1px solid #dee2e6; +} +.table-bordered th, +.table-bordered td { + border: 1px solid #dee2e6; +} +.table-bordered thead th, +.table-bordered thead td { + border-bottom-width: 2px; +} + +.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(0, 0, 0, 0.05); +} + +.table-hover tbody tr:hover { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-primary, +.table-primary > th, +.table-primary > td { + background-color: #b8daff; +} + +.table-hover .table-primary:hover { + background-color: #9fcdff; +} +.table-hover .table-primary:hover > td, +.table-hover .table-primary:hover > th { + background-color: #9fcdff; +} + +.table-secondary, +.table-secondary > th, +.table-secondary > td { + background-color: #d6d8db; +} + +.table-hover .table-secondary:hover { + background-color: #c8cbcf; +} +.table-hover .table-secondary:hover > td, +.table-hover .table-secondary:hover > th { + background-color: #c8cbcf; +} + +.table-success, +.table-success > th, +.table-success > td { + background-color: #c3e6cb; +} + +.table-hover .table-success:hover { + background-color: #b1dfbb; +} +.table-hover .table-success:hover > td, +.table-hover .table-success:hover > th { + background-color: #b1dfbb; +} + +.table-info, +.table-info > th, +.table-info > td { + background-color: #bee5eb; +} + +.table-hover .table-info:hover { + background-color: #abdde5; +} +.table-hover .table-info:hover > td, +.table-hover .table-info:hover > th { + background-color: #abdde5; +} + +.table-warning, +.table-warning > th, +.table-warning > td { + background-color: #ffeeba; +} + +.table-hover .table-warning:hover { + background-color: #ffe8a1; +} +.table-hover .table-warning:hover > td, +.table-hover .table-warning:hover > th { + background-color: #ffe8a1; +} + +.table-danger, +.table-danger > th, +.table-danger > td { + background-color: #f5c6cb; +} + +.table-hover .table-danger:hover { + background-color: #f1b0b7; +} +.table-hover .table-danger:hover > td, +.table-hover .table-danger:hover > th { + background-color: #f1b0b7; +} + +.table-light, +.table-light > th, +.table-light > td { + background-color: #fdfdfe; +} + +.table-hover .table-light:hover { + background-color: #ececf6; +} +.table-hover .table-light:hover > td, +.table-hover .table-light:hover > th { + background-color: #ececf6; +} + +.table-dark, +.table-dark > th, +.table-dark > td { + background-color: #c6c8ca; +} + +.table-hover .table-dark:hover { + background-color: #b9bbbe; +} +.table-hover .table-dark:hover > td, +.table-hover .table-dark:hover > th { + background-color: #b9bbbe; +} + +.table-active, +.table-active > th, +.table-active > td { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-hover .table-active:hover { + background-color: rgba(0, 0, 0, 0.075); +} +.table-hover .table-active:hover > td, +.table-hover .table-active:hover > th { + background-color: rgba(0, 0, 0, 0.075); +} + +.table .thead-dark th { + color: #fff; + background-color: #212529; + border-color: #32383e; +} +.table .thead-light th { + color: #495057; + background-color: #e9ecef; + border-color: #dee2e6; +} + +.table-dark { + color: #fff; + background-color: #212529; +} +.table-dark th, +.table-dark td, +.table-dark thead th { + border-color: #32383e; +} +.table-dark.table-bordered { + border: 0; +} +.table-dark.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(255, 255, 255, 0.05); +} +.table-dark.table-hover tbody tr:hover { + background-color: rgba(255, 255, 255, 0.075); +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-sm > .table-bordered { + border: 0; + } +} +@media (max-width: 767.98px) { + .table-responsive-md { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-md > .table-bordered { + border: 0; + } +} +@media (max-width: 991.98px) { + .table-responsive-lg { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-lg > .table-bordered { + border: 0; + } +} +@media (max-width: 1199.98px) { + .table-responsive-xl { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-xl > .table-bordered { + border: 0; + } +} +.table-responsive { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; +} +.table-responsive > .table-bordered { + border: 0; +} + +.form-control { + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + border-radius: 0.25rem; + -webkit-transition: border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; + transition: border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; +} +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} +.form-control:focus { + color: #495057; + background-color: #fff; + border-color: #80bdff; + outline: 0; + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.form-control::-webkit-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::-moz-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::-ms-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:disabled, .form-control[readonly] { + background-color: #e9ecef; + opacity: 1; +} + +select.form-control:not([size]):not([multiple]) { + height: calc(2.25rem + 2px); +} +select.form-control:focus::-ms-value { + color: #495057; + background-color: #fff; +} + +.form-control-file, +.form-control-range { + display: block; + width: 100%; +} + +.col-form-label { + padding-top: calc(0.375rem + 1px); + padding-bottom: calc(0.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5; +} + +.col-form-label-lg { + padding-top: calc(0.5rem + 1px); + padding-bottom: calc(0.5rem + 1px); + font-size: 1.25rem; + line-height: 1.5; +} + +.col-form-label-sm { + padding-top: calc(0.25rem + 1px); + padding-bottom: calc(0.25rem + 1px); + font-size: 0.875rem; + line-height: 1.5; +} + +.form-control-plaintext { + display: block; + width: 100%; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + margin-bottom: 0; + line-height: 1.5; + background-color: transparent; + border: solid transparent; + border-width: 1px 0; +} +.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control, +.input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text, +.input-group-sm > .input-group-append > .form-control-plaintext.input-group-text, +.input-group-sm > .input-group-prepend > .form-control-plaintext.btn, +.input-group-sm > .input-group-append > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, .input-group-lg > .form-control-plaintext.form-control, +.input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text, +.input-group-lg > .input-group-append > .form-control-plaintext.input-group-text, +.input-group-lg > .input-group-prepend > .form-control-plaintext.btn, +.input-group-lg > .input-group-append > .form-control-plaintext.btn { + padding-right: 0; + padding-left: 0; +} + +.form-control-sm, .input-group-sm > .form-control, +.input-group-sm > .input-group-prepend > .input-group-text, +.input-group-sm > .input-group-append > .input-group-text, +.input-group-sm > .input-group-prepend > .btn, +.input-group-sm > .input-group-append > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} + +select.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]), +.input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), +.input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]), +.input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]), +.input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) { + height: calc(1.8125rem + 2px); +} + +.form-control-lg, .input-group-lg > .form-control, +.input-group-lg > .input-group-prepend > .input-group-text, +.input-group-lg > .input-group-append > .input-group-text, +.input-group-lg > .input-group-prepend > .btn, +.input-group-lg > .input-group-append > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} + +select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]), +.input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), +.input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]), +.input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]), +.input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) { + height: calc(2.875rem + 2px); +} + +.form-group { + margin-bottom: 1rem; +} + +.form-text { + display: block; + margin-top: 0.25rem; +} + +.form-row { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -5px; + margin-left: -5px; +} +.form-row > .col, +.form-row > [class*="col-"] { + padding-right: 5px; + padding-left: 5px; +} + +.form-check { + position: relative; + display: block; + padding-left: 1.25rem; +} + +.form-check-input { + position: absolute; + margin-top: 0.3rem; + margin-left: -1.25rem; +} +.form-check-input:disabled ~ .form-check-label { + color: #6c757d; +} + +.form-check-label { + margin-bottom: 0; +} + +.form-check-inline { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding-left: 0; + margin-right: 0.75rem; +} +.form-check-inline .form-check-input { + position: static; + margin-top: 0; + margin-right: 0.3125rem; + margin-left: 0; +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #28a745; +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1; + color: #fff; + background-color: rgba(40, 167, 69, 0.8); + border-radius: .2rem; +} + +.was-validated .form-control:valid, .form-control.is-valid, +.was-validated .custom-select:valid, +.custom-select.is-valid { + border-color: #28a745; +} +.was-validated .form-control:valid:focus, .form-control.is-valid:focus, +.was-validated .custom-select:valid:focus, +.custom-select.is-valid:focus { + border-color: #28a745; + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} +.was-validated .form-control:valid ~ .valid-feedback, +.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback, +.form-control.is-valid ~ .valid-tooltip, +.was-validated .custom-select:valid ~ .valid-feedback, +.was-validated .custom-select:valid ~ .valid-tooltip, +.custom-select.is-valid ~ .valid-feedback, +.custom-select.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { + color: #28a745; +} +.was-validated .form-check-input:valid ~ .valid-feedback, +.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback, +.form-check-input.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label { + color: #28a745; +} +.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before { + background-color: #71dd8a; +} +.was-validated .custom-control-input:valid ~ .valid-feedback, +.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback, +.custom-control-input.is-valid ~ .valid-tooltip { + display: block; +} +.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before { + background-color: #34ce57; +} +.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before { + -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25); + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label { + border-color: #28a745; +} +.was-validated .custom-file-input:valid ~ .custom-file-label::before, .custom-file-input.is-valid ~ .custom-file-label::before { + border-color: inherit; +} +.was-validated .custom-file-input:valid ~ .valid-feedback, +.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback, +.custom-file-input.is-valid ~ .valid-tooltip { + display: block; +} +.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #dc3545; +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1; + color: #fff; + background-color: rgba(220, 53, 69, 0.8); + border-radius: .2rem; +} + +.was-validated .form-control:invalid, .form-control.is-invalid, +.was-validated .custom-select:invalid, +.custom-select.is-invalid { + border-color: #dc3545; +} +.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, +.was-validated .custom-select:invalid:focus, +.custom-select.is-invalid:focus { + border-color: #dc3545; + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} +.was-validated .form-control:invalid ~ .invalid-feedback, +.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback, +.form-control.is-invalid ~ .invalid-tooltip, +.was-validated .custom-select:invalid ~ .invalid-feedback, +.was-validated .custom-select:invalid ~ .invalid-tooltip, +.custom-select.is-invalid ~ .invalid-feedback, +.custom-select.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { + color: #dc3545; +} +.was-validated .form-check-input:invalid ~ .invalid-feedback, +.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback, +.form-check-input.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label { + color: #dc3545; +} +.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before { + background-color: #efa2a9; +} +.was-validated .custom-control-input:invalid ~ .invalid-feedback, +.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback, +.custom-control-input.is-invalid ~ .invalid-tooltip { + display: block; +} +.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before { + background-color: #e4606d; +} +.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before { + -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25); + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label { + border-color: #dc3545; +} +.was-validated .custom-file-input:invalid ~ .custom-file-label::before, .custom-file-input.is-invalid ~ .custom-file-label::before { + border-color: inherit; +} +.was-validated .custom-file-input:invalid ~ .invalid-feedback, +.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback, +.custom-file-input.is-invalid ~ .invalid-tooltip { + display: block; +} +.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.form-inline { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.form-inline .form-check { + width: 100%; +} +@media (min-width: 576px) { + .form-inline label { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + margin-bottom: 0; + } + .form-inline .form-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-bottom: 0; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-plaintext { + display: inline-block; + } + .form-inline .input-group { + width: auto; + } + .form-inline .form-check { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: auto; + padding-left: 0; + } + .form-inline .form-check-input { + position: relative; + margin-top: 0; + margin-right: 0.25rem; + margin-left: 0; + } + .form-inline .custom-control { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + } + .form-inline .custom-control-label { + margin-bottom: 0; + } +} + +.btn { + display: inline-block; + font-weight: 400; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + border: 1px solid transparent; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + border-radius: 0.25rem; + -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out; +} +.btn:hover, .btn:focus { + text-decoration: none; +} +.btn:focus, .btn.focus { + outline: 0; + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.btn.disabled, .btn:disabled { + opacity: 0.65; +} +.btn:not(:disabled):not(.disabled) { + cursor: pointer; +} +.btn:not(:disabled):not(.disabled):active, .btn:not(:disabled):not(.disabled).active { + background-image: none; +} + +a.btn.disabled, +fieldset:disabled a.btn { + pointer-events: none; +} + +.btn-primary { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-primary:hover { + color: #fff; + background-color: #0069d9; + border-color: #0062cc; +} +.btn-primary:focus, .btn-primary.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} +.btn-primary.disabled, .btn-primary:disabled { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active, .show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #0062cc; + border-color: #005cbf; +} +.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-primary.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-secondary { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-secondary:hover { + color: #fff; + background-color: #5a6268; + border-color: #545b62; +} +.btn-secondary:focus, .btn-secondary.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} +.btn-secondary.disabled, .btn-secondary:disabled { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active, .show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #545b62; + border-color: #4e555b; +} +.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus, .show > .btn-secondary.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-success { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-success:hover { + color: #fff; + background-color: #218838; + border-color: #1e7e34; +} +.btn-success:focus, .btn-success.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} +.btn-success.disabled, .btn-success:disabled { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active, .show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #1e7e34; + border-color: #1c7430; +} +.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus, .show > .btn-success.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-info { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-info:hover { + color: #fff; + background-color: #138496; + border-color: #117a8b; +} +.btn-info:focus, .btn-info.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} +.btn-info.disabled, .btn-info:disabled { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active, .show > .btn-info.dropdown-toggle { + color: #fff; + background-color: #117a8b; + border-color: #10707f; +} +.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus, .show > .btn-info.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-warning { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-warning:hover { + color: #212529; + background-color: #e0a800; + border-color: #d39e00; +} +.btn-warning:focus, .btn-warning.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} +.btn-warning.disabled, .btn-warning:disabled { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active, .show > .btn-warning.dropdown-toggle { + color: #212529; + background-color: #d39e00; + border-color: #c69500; +} +.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus, .show > .btn-warning.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-danger { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-danger:hover { + color: #fff; + background-color: #c82333; + border-color: #bd2130; +} +.btn-danger:focus, .btn-danger.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} +.btn-danger.disabled, .btn-danger:disabled { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active, .show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #bd2130; + border-color: #b21f2d; +} +.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus, .show > .btn-danger.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-light { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-light:hover { + color: #212529; + background-color: #e2e6ea; + border-color: #dae0e5; +} +.btn-light:focus, .btn-light.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} +.btn-light.disabled, .btn-light:disabled { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active, .show > .btn-light.dropdown-toggle { + color: #212529; + background-color: #dae0e5; + border-color: #d3d9df; +} +.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus, .show > .btn-light.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-dark { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-dark:hover { + color: #fff; + background-color: #23272b; + border-color: #1d2124; +} +.btn-dark:focus, .btn-dark.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} +.btn-dark.disabled, .btn-dark:disabled { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active, .show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1d2124; + border-color: #171a1d; +} +.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus, .show > .btn-dark.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-outline-primary { + color: #007bff; + background-color: transparent; + background-image: none; + border-color: #007bff; +} +.btn-outline-primary:hover { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-outline-primary:focus, .btn-outline-primary.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} +.btn-outline-primary.disabled, .btn-outline-primary:disabled { + color: #007bff; + background-color: transparent; +} +.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active, .show > .btn-outline-primary.dropdown-toggle { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-primary.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-outline-secondary { + color: #6c757d; + background-color: transparent; + background-image: none; + border-color: #6c757d; +} +.btn-outline-secondary:hover { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-outline-secondary:focus, .btn-outline-secondary.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} +.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { + color: #6c757d; + background-color: transparent; +} +.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active, .show > .btn-outline-secondary.dropdown-toggle { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-secondary.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-outline-success { + color: #28a745; + background-color: transparent; + background-image: none; + border-color: #28a745; +} +.btn-outline-success:hover { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-outline-success:focus, .btn-outline-success.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} +.btn-outline-success.disabled, .btn-outline-success:disabled { + color: #28a745; + background-color: transparent; +} +.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active, .show > .btn-outline-success.dropdown-toggle { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-success.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-outline-info { + color: #17a2b8; + background-color: transparent; + background-image: none; + border-color: #17a2b8; +} +.btn-outline-info:hover { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-outline-info:focus, .btn-outline-info.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} +.btn-outline-info.disabled, .btn-outline-info:disabled { + color: #17a2b8; + background-color: transparent; +} +.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active, .show > .btn-outline-info.dropdown-toggle { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-info.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-outline-warning { + color: #ffc107; + background-color: transparent; + background-image: none; + border-color: #ffc107; +} +.btn-outline-warning:hover { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-outline-warning:focus, .btn-outline-warning.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} +.btn-outline-warning.disabled, .btn-outline-warning:disabled { + color: #ffc107; + background-color: transparent; +} +.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active, .show > .btn-outline-warning.dropdown-toggle { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-warning.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-outline-danger { + color: #dc3545; + background-color: transparent; + background-image: none; + border-color: #dc3545; +} +.btn-outline-danger:hover { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-outline-danger:focus, .btn-outline-danger.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} +.btn-outline-danger.disabled, .btn-outline-danger:disabled { + color: #dc3545; + background-color: transparent; +} +.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active, .show > .btn-outline-danger.dropdown-toggle { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-danger.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-outline-light { + color: #f8f9fa; + background-color: transparent; + background-image: none; + border-color: #f8f9fa; +} +.btn-outline-light:hover { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-outline-light:focus, .btn-outline-light.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} +.btn-outline-light.disabled, .btn-outline-light:disabled { + color: #f8f9fa; + background-color: transparent; +} +.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active, .show > .btn-outline-light.dropdown-toggle { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-light.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-outline-dark { + color: #343a40; + background-color: transparent; + background-image: none; + border-color: #343a40; +} +.btn-outline-dark:hover { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-outline-dark:focus, .btn-outline-dark.focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} +.btn-outline-dark.disabled, .btn-outline-dark:disabled { + color: #343a40; + background-color: transparent; +} +.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active, .show > .btn-outline-dark.dropdown-toggle { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-dark.dropdown-toggle:focus { + -webkit-box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-link { + font-weight: 400; + color: #007bff; + background-color: transparent; +} +.btn-link:hover { + color: #0056b3; + text-decoration: underline; + background-color: transparent; + border-color: transparent; +} +.btn-link:focus, .btn-link.focus { + text-decoration: underline; + border-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link:disabled, .btn-link.disabled { + color: #6c757d; +} + +.btn-lg, .btn-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} + +.btn-sm, .btn-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} + +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 0.5rem; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.show { + opacity: 1; +} + +.collapse { + display: none; +} +.collapse.show { + display: block; +} + +tr.collapse.show { + display: table-row; +} + +tbody.collapse.show { + display: table-row-group; +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} +.dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0.125rem 0 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} + +.dropup .dropdown-menu { + margin-top: 0; + margin-bottom: 0.125rem; +} +.dropup .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropright .dropdown-menu { + margin-top: 0; + margin-left: 0.125rem; +} +.dropright .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} +.dropright .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropright .dropdown-toggle::after { + vertical-align: 0; +} + +.dropleft .dropdown-menu { + margin-top: 0; + margin-right: 0.125rem; +} +.dropleft .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; +} +.dropleft .dropdown-toggle::after { + display: none; +} +.dropleft .dropdown-toggle::before { + display: inline-block; + width: 0; + height: 0; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} +.dropleft .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropleft .dropdown-toggle::before { + vertical-align: 0; +} + +.dropdown-divider { + height: 0; + margin: 0.5rem 0; + overflow: hidden; + border-top: 1px solid #e9ecef; +} + +.dropdown-item { + display: block; + width: 100%; + padding: 0.25rem 1.5rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + white-space: nowrap; + background-color: transparent; + border: 0; +} +.dropdown-item:hover, .dropdown-item:focus { + color: #16181b; + text-decoration: none; + background-color: #f8f9fa; +} +.dropdown-item.active, .dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #007bff; +} +.dropdown-item.disabled, .dropdown-item:disabled { + color: #6c757d; + background-color: transparent; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-header { + display: block; + padding: 0.5rem 1.5rem; + margin-bottom: 0; + font-size: 0.875rem; + color: #6c757d; + white-space: nowrap; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + -webkit-box-flex: 0; + -ms-flex: 0 1 auto; + flex: 0 1 auto; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover { + z-index: 1; +} +.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 1; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group, +.btn-group-vertical .btn + .btn, +.btn-group-vertical .btn + .btn-group, +.btn-group-vertical .btn-group + .btn, +.btn-group-vertical .btn-group + .btn-group { + margin-left: -1px; +} + +.btn-toolbar { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} +.btn-toolbar .input-group { + width: auto; +} + +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:not(:first-child), +.btn-group > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.dropdown-toggle-split { + padding-right: 0.5625rem; + padding-left: 0.5625rem; +} +.dropdown-toggle-split::after { + margin-left: 0; +} + +.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} + +.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} + +.btn-group-vertical { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} +.btn-group-vertical .btn, +.btn-group-vertical .btn-group { + width: 100%; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group-vertical > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:not(:first-child), +.btn-group-vertical > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.btn-group-toggle > .btn, +.btn-group-toggle > .btn-group > .btn { + margin-bottom: 0; +} +.btn-group-toggle > .btn input[type="radio"], +.btn-group-toggle > .btn input[type="checkbox"], +.btn-group-toggle > .btn-group > .btn input[type="radio"], +.btn-group-toggle > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} + +.input-group { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: stretch; + -ms-flex-align: stretch; + align-items: stretch; + width: 100%; +} +.input-group > .form-control, +.input-group > .custom-select, +.input-group > .custom-file { + position: relative; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + width: 1%; + margin-bottom: 0; +} +.input-group > .form-control:focus, +.input-group > .custom-select:focus, +.input-group > .custom-file:focus { + z-index: 3; +} +.input-group > .form-control + .form-control, +.input-group > .form-control + .custom-select, +.input-group > .form-control + .custom-file, +.input-group > .custom-select + .form-control, +.input-group > .custom-select + .custom-select, +.input-group > .custom-select + .custom-file, +.input-group > .custom-file + .form-control, +.input-group > .custom-file + .custom-select, +.input-group > .custom-file + .custom-file { + margin-left: -1px; +} +.input-group > .form-control:not(:last-child), +.input-group > .custom-select:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > .form-control:not(:first-child), +.input-group > .custom-select:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group > .custom-file { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.input-group > .custom-file:not(:last-child) .custom-file-label, .input-group > .custom-file:not(:last-child) .custom-file-label::before { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > .custom-file:not(:first-child) .custom-file-label, .input-group > .custom-file:not(:first-child) .custom-file-label::before { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.input-group-prepend, +.input-group-append { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} +.input-group-prepend .btn, +.input-group-append .btn { + position: relative; + z-index: 2; +} +.input-group-prepend .btn + .btn, +.input-group-prepend .btn + .input-group-text, +.input-group-prepend .input-group-text + .input-group-text, +.input-group-prepend .input-group-text + .btn, +.input-group-append .btn + .btn, +.input-group-append .btn + .input-group-text, +.input-group-append .input-group-text + .input-group-text, +.input-group-append .input-group-text + .btn { + margin-left: -1px; +} + +.input-group-prepend { + margin-right: -1px; +} + +.input-group-append { + margin-left: -1px; +} + +.input-group-text { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 0.375rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} +.input-group-text input[type="radio"], +.input-group-text input[type="checkbox"] { + margin-top: 0; +} + +.input-group > .input-group-prepend > .btn, +.input-group > .input-group-prepend > .input-group-text, +.input-group > .input-group-append:not(:last-child) > .btn, +.input-group > .input-group-append:not(:last-child) > .input-group-text, +.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group > .input-group-append > .btn, +.input-group > .input-group-append > .input-group-text, +.input-group > .input-group-prepend:not(:first-child) > .btn, +.input-group > .input-group-prepend:not(:first-child) > .input-group-text, +.input-group > .input-group-prepend:first-child > .btn:not(:first-child), +.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.custom-control { + position: relative; + display: block; + min-height: 1.5rem; + padding-left: 1.5rem; +} + +.custom-control-inline { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + margin-right: 1rem; +} + +.custom-control-input { + position: absolute; + z-index: -1; + opacity: 0; +} +.custom-control-input:checked ~ .custom-control-label::before { + color: #fff; + background-color: #007bff; +} +.custom-control-input:focus ~ .custom-control-label::before { + -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-control-input:active ~ .custom-control-label::before { + color: #fff; + background-color: #b3d7ff; +} +.custom-control-input:disabled ~ .custom-control-label { + color: #6c757d; +} +.custom-control-input:disabled ~ .custom-control-label::before { + background-color: #e9ecef; +} + +.custom-control-label { + margin-bottom: 0; +} +.custom-control-label::before { + position: absolute; + top: 0.25rem; + left: 0; + display: block; + width: 1rem; + height: 1rem; + pointer-events: none; + content: ""; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: #dee2e6; +} +.custom-control-label::after { + position: absolute; + top: 0.25rem; + left: 0; + display: block; + width: 1rem; + height: 1rem; + content: ""; + background-repeat: no-repeat; + background-position: center center; + background-size: 50% 50%; +} + +.custom-checkbox .custom-control-label::before { + border-radius: 0.25rem; +} +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before { + background-color: #007bff; +} +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); +} +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { + background-color: #007bff; +} +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E"); +} +.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} +.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-radio .custom-control-label::before { + border-radius: 50%; +} +.custom-radio .custom-control-input:checked ~ .custom-control-label::before { + background-color: #007bff; +} +.custom-radio .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E"); +} +.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-select { + display: inline-block; + width: 100%; + height: calc(2.25rem + 2px); + padding: 0.375rem 1.75rem 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + vertical-align: middle; + background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center; + background-size: 8px 10px; + border: 1px solid #ced4da; + border-radius: 0.25rem; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +.custom-select:focus { + border-color: #80bdff; + outline: 0; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5); +} +.custom-select:focus::-ms-value { + color: #495057; + background-color: #fff; +} +.custom-select[multiple], .custom-select[size]:not([size="1"]) { + height: auto; + padding-right: 0.75rem; + background-image: none; +} +.custom-select:disabled { + color: #6c757d; + background-color: #e9ecef; +} +.custom-select::-ms-expand { + opacity: 0; +} + +.custom-select-sm { + height: calc(1.8125rem + 2px); + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: 75%; +} + +.custom-select-lg { + height: calc(2.875rem + 2px); + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: 125%; +} + +.custom-file { + position: relative; + display: inline-block; + width: 100%; + height: calc(2.25rem + 2px); + margin-bottom: 0; +} + +.custom-file-input { + position: relative; + z-index: 2; + width: 100%; + height: calc(2.25rem + 2px); + margin: 0; + opacity: 0; +} +.custom-file-input:focus ~ .custom-file-control { + border-color: #80bdff; + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-file-input:focus ~ .custom-file-control::before { + border-color: #80bdff; +} +.custom-file-input:lang(en) ~ .custom-file-label::after { + content: "Browse"; +} + +.custom-file-label { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 1; + height: calc(2.25rem + 2px); + padding: 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} +.custom-file-label::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + z-index: 3; + display: block; + height: calc(calc(2.25rem + 2px) - 1px * 2); + padding: 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + content: "Browse"; + background-color: #e9ecef; + border-left: 1px solid #ced4da; + border-radius: 0 0.25rem 0.25rem 0; +} + +.nav { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: 0.5rem 1rem; +} +.nav-link:hover, .nav-link:focus { + text-decoration: none; +} +.nav-link.disabled { + color: #6c757d; +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6; +} +.nav-tabs .nav-item { + margin-bottom: -1px; +} +.nav-tabs .nav-link { + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { + border-color: #e9ecef #e9ecef #dee2e6; +} +.nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent; +} +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav-pills .nav-link { + border-radius: 0.25rem; +} +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: #fff; + background-color: #007bff; +} + +.nav-fill .nav-item { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + text-align: center; +} + +.nav-justified .nav-item { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + text-align: center; +} + +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} + +.navbar { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 0.5rem 1rem; +} +.navbar > .container, +.navbar > .container-fluid { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.navbar-brand { + display: inline-block; + padding-top: 0.3125rem; + padding-bottom: 0.3125rem; + margin-right: 1rem; + font-size: 1.25rem; + line-height: inherit; + white-space: nowrap; +} +.navbar-brand:hover, .navbar-brand:focus { + text-decoration: none; +} + +.navbar-nav { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0; +} +.navbar-nav .dropdown-menu { + position: static; + float: none; +} + +.navbar-text { + display: inline-block; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.navbar-collapse { + -ms-flex-preferred-size: 100%; + flex-basis: 100%; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.navbar-toggler { + padding: 0.25rem 0.75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: 0.25rem; +} +.navbar-toggler:hover, .navbar-toggler:focus { + text-decoration: none; +} +.navbar-toggler:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + content: ""; + background: no-repeat center center; + background-size: 100% 100%; +} + +@media (max-width: 575.98px) { + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 576px) { + .navbar-expand-sm { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-sm .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } + .navbar-expand-sm .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} +@media (max-width: 767.98px) { + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 768px) { + .navbar-expand-md { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-md .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } + .navbar-expand-md .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} +@media (max-width: 991.98px) { + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 992px) { + .navbar-expand-lg { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-lg .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } + .navbar-expand-lg .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} +@media (max-width: 1199.98px) { + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 1200px) { + .navbar-expand-xl { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-xl .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } + .navbar-expand-xl .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} +.navbar-expand { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} +.navbar-expand > .container, +.navbar-expand > .container-fluid { + padding-right: 0; + padding-left: 0; +} +.navbar-expand .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; +} +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} +.navbar-expand .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; +} +.navbar-expand .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; +} +.navbar-expand > .container, +.navbar-expand > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; +} +.navbar-expand .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; +} +.navbar-expand .navbar-toggler { + display: none; +} +.navbar-expand .dropup .dropdown-menu { + top: auto; + bottom: 100%; +} + +.navbar-light .navbar-brand { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, 0.5); +} +.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { + color: rgba(0, 0, 0, 0.7); +} +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, 0.3); +} +.navbar-light .navbar-nav .show > .nav-link, +.navbar-light .navbar-nav .active > .nav-link, +.navbar-light .navbar-nav .nav-link.show, +.navbar-light .navbar-nav .nav-link.active { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-toggler { + color: rgba(0, 0, 0, 0.5); + border-color: rgba(0, 0, 0, 0.1); +} +.navbar-light .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); +} +.navbar-light .navbar-text { + color: rgba(0, 0, 0, 0.5); +} +.navbar-light .navbar-text a { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-dark .navbar-brand { + color: #fff; +} +.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { + color: #fff; +} +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, 0.5); +} +.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { + color: rgba(255, 255, 255, 0.75); +} +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, 0.25); +} +.navbar-dark .navbar-nav .show > .nav-link, +.navbar-dark .navbar-nav .active > .nav-link, +.navbar-dark .navbar-nav .nav-link.show, +.navbar-dark .navbar-nav .nav-link.active { + color: #fff; +} +.navbar-dark .navbar-toggler { + color: rgba(255, 255, 255, 0.5); + border-color: rgba(255, 255, 255, 0.1); +} +.navbar-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); +} +.navbar-dark .navbar-text { + color: rgba(255, 255, 255, 0.5); +} +.navbar-dark .navbar-text a { + color: #fff; +} +.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus { + color: #fff; +} + +.card { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} +.card > hr { + margin-right: 0; + margin-left: 0; +} +.card > .list-group:first-child .list-group-item:first-child { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.card > .list-group:last-child .list-group-item:last-child { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.card-body { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 1.25rem; +} + +.card-title { + margin-bottom: 0.75rem; +} + +.card-subtitle { + margin-top: -0.375rem; + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link:hover { + text-decoration: none; +} +.card-link + .card-link { + margin-left: 1.25rem; +} + +.card-header { + padding: 0.75rem 1.25rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, 0.03); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} +.card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; +} +.card-header + .list-group .list-group-item:first-child { + border-top: 0; +} + +.card-footer { + padding: 0.75rem 1.25rem; + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); +} +.card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); +} + +.card-header-tabs { + margin-right: -0.625rem; + margin-bottom: -0.75rem; + margin-left: -0.625rem; + border-bottom: 0; +} + +.card-header-pills { + margin-right: -0.625rem; + margin-left: -0.625rem; +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1.25rem; +} + +.card-img { + width: 100%; + border-radius: calc(0.25rem - 1px); +} + +.card-img-top { + width: 100%; + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} + +.card-img-bottom { + width: 100%; + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} + +.card-deck { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.card-deck .card { + margin-bottom: 15px; +} +@media (min-width: 576px) { + .card-deck { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + margin-right: -15px; + margin-left: -15px; + } + .card-deck .card { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-flex: 1; + -ms-flex: 1 0 0%; + flex: 1 0 0%; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + margin-right: 15px; + margin-bottom: 0; + margin-left: 15px; + } +} + +.card-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} +.card-group > .card { + margin-bottom: 15px; +} +@media (min-width: 576px) { + .card-group { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + } + .card-group > .card { + -webkit-box-flex: 1; + -ms-flex: 1 0 0%; + flex: 1 0 0%; + margin-bottom: 0; + } + .card-group > .card + .card { + margin-left: 0; + border-left: 0; + } + .card-group > .card:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .card-group > .card:first-child .card-img-top, + .card-group > .card:first-child .card-header { + border-top-right-radius: 0; + } + .card-group > .card:first-child .card-img-bottom, + .card-group > .card:first-child .card-footer { + border-bottom-right-radius: 0; + } + .card-group > .card:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .card-group > .card:last-child .card-img-top, + .card-group > .card:last-child .card-header { + border-top-left-radius: 0; + } + .card-group > .card:last-child .card-img-bottom, + .card-group > .card:last-child .card-footer { + border-bottom-left-radius: 0; + } + .card-group > .card:only-child { + border-radius: 0.25rem; + } + .card-group > .card:only-child .card-img-top, + .card-group > .card:only-child .card-header { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } + .card-group > .card:only-child .card-img-bottom, + .card-group > .card:only-child .card-footer { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) { + border-radius: 0; + } + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer { + border-radius: 0; + } +} + +.card-columns .card { + margin-bottom: 0.75rem; +} +@media (min-width: 576px) { + .card-columns { + -webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; + -webkit-column-gap: 1.25rem; + -moz-column-gap: 1.25rem; + column-gap: 1.25rem; + } + .card-columns .card { + display: inline-block; + width: 100%; + } +} + +.breadcrumb { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding: 0.75rem 1rem; + margin-bottom: 1rem; + list-style: none; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.breadcrumb-item + .breadcrumb-item::before { + display: inline-block; + padding-right: 0.5rem; + padding-left: 0.5rem; + color: #6c757d; + content: "/"; +} +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: underline; +} +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: none; +} +.breadcrumb-item.active { + color: #6c757d; +} + +.pagination { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + padding-left: 0; + list-style: none; + border-radius: 0.25rem; +} + +.page-link { + position: relative; + display: block; + padding: 0.5rem 0.75rem; + margin-left: -1px; + line-height: 1.25; + color: #007bff; + background-color: #fff; + border: 1px solid #dee2e6; +} +.page-link:hover { + color: #0056b3; + text-decoration: none; + background-color: #e9ecef; + border-color: #dee2e6; +} +.page-link:focus { + z-index: 2; + outline: 0; + -webkit-box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.page-link:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.page-item:first-child .page-link { + margin-left: 0; + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} +.page-item:last-child .page-link { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; +} +.page-item.active .page-link { + z-index: 1; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + cursor: auto; + background-color: #fff; + border-color: #dee2e6; +} + +.pagination-lg .page-link { + padding: 0.75rem 1.5rem; + font-size: 1.25rem; + line-height: 1.5; +} +.pagination-lg .page-item:first-child .page-link { + border-top-left-radius: 0.3rem; + border-bottom-left-radius: 0.3rem; +} +.pagination-lg .page-item:last-child .page-link { + border-top-right-radius: 0.3rem; + border-bottom-right-radius: 0.3rem; +} + +.pagination-sm .page-link { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; +} +.pagination-sm .page-item:first-child .page-link { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; +} +.pagination-sm .page-item:last-child .page-link { + border-top-right-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; +} + +.badge { + display: inline-block; + padding: 0.25em 0.4em; + font-size: 75%; + font-weight: 700; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25rem; +} +.badge:empty { + display: none; +} + +.btn .badge { + position: relative; + top: -1px; +} + +.badge-pill { + padding-right: 0.6em; + padding-left: 0.6em; + border-radius: 10rem; +} + +.badge-primary { + color: #fff; + background-color: #007bff; +} +.badge-primary[href]:hover, .badge-primary[href]:focus { + color: #fff; + text-decoration: none; + background-color: #0062cc; +} + +.badge-secondary { + color: #fff; + background-color: #6c757d; +} +.badge-secondary[href]:hover, .badge-secondary[href]:focus { + color: #fff; + text-decoration: none; + background-color: #545b62; +} + +.badge-success { + color: #fff; + background-color: #28a745; +} +.badge-success[href]:hover, .badge-success[href]:focus { + color: #fff; + text-decoration: none; + background-color: #1e7e34; +} + +.badge-info { + color: #fff; + background-color: #17a2b8; +} +.badge-info[href]:hover, .badge-info[href]:focus { + color: #fff; + text-decoration: none; + background-color: #117a8b; +} + +.badge-warning { + color: #212529; + background-color: #ffc107; +} +.badge-warning[href]:hover, .badge-warning[href]:focus { + color: #212529; + text-decoration: none; + background-color: #d39e00; +} + +.badge-danger { + color: #fff; + background-color: #dc3545; +} +.badge-danger[href]:hover, .badge-danger[href]:focus { + color: #fff; + text-decoration: none; + background-color: #bd2130; +} + +.badge-light { + color: #212529; + background-color: #f8f9fa; +} +.badge-light[href]:hover, .badge-light[href]:focus { + color: #212529; + text-decoration: none; + background-color: #dae0e5; +} + +.badge-dark { + color: #fff; + background-color: #343a40; +} +.badge-dark[href]:hover, .badge-dark[href]:focus { + color: #fff; + text-decoration: none; + background-color: #1d2124; +} + +.jumbotron { + padding: 2rem 1rem; + margin-bottom: 2rem; + background-color: #e9ecef; + border-radius: 0.3rem; +} +@media (min-width: 576px) { + .jumbotron { + padding: 4rem 2rem; + } +} + +.jumbotron-fluid { + padding-right: 0; + padding-left: 0; + border-radius: 0; +} + +.alert { + position: relative; + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; +} + +.alert-heading { + color: inherit; +} + +.alert-link { + font-weight: 700; +} + +.alert-dismissible { + padding-right: 4rem; +} +.alert-dismissible .close { + position: absolute; + top: 0; + right: 0; + padding: 0.75rem 1.25rem; + color: inherit; +} + +.alert-primary { + color: #004085; + background-color: #cce5ff; + border-color: #b8daff; +} +.alert-primary hr { + border-top-color: #9fcdff; +} +.alert-primary .alert-link { + color: #002752; +} + +.alert-secondary { + color: #383d41; + background-color: #e2e3e5; + border-color: #d6d8db; +} +.alert-secondary hr { + border-top-color: #c8cbcf; +} +.alert-secondary .alert-link { + color: #202326; +} + +.alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; +} +.alert-success hr { + border-top-color: #b1dfbb; +} +.alert-success .alert-link { + color: #0b2e13; +} + +.alert-info { + color: #0c5460; + background-color: #d1ecf1; + border-color: #bee5eb; +} +.alert-info hr { + border-top-color: #abdde5; +} +.alert-info .alert-link { + color: #062c33; +} + +.alert-warning { + color: #856404; + background-color: #fff3cd; + border-color: #ffeeba; +} +.alert-warning hr { + border-top-color: #ffe8a1; +} +.alert-warning .alert-link { + color: #533f03; +} + +.alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +} +.alert-danger hr { + border-top-color: #f1b0b7; +} +.alert-danger .alert-link { + color: #491217; +} + +.alert-light { + color: #818182; + background-color: #fefefe; + border-color: #fdfdfe; +} +.alert-light hr { + border-top-color: #ececf6; +} +.alert-light .alert-link { + color: #686868; +} + +.alert-dark { + color: #1b1e21; + background-color: #d6d8d9; + border-color: #c6c8ca; +} +.alert-dark hr { + border-top-color: #b9bbbe; +} +.alert-dark .alert-link { + color: #040505; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} +.progress { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + height: 1rem; + overflow: hidden; + font-size: 0.75rem; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.progress-bar { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + color: #fff; + text-align: center; + background-color: #007bff; + -webkit-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 1rem 1rem; +} + +.progress-bar-animated { + -webkit-animation: progress-bar-stripes 1s linear infinite; + animation: progress-bar-stripes 1s linear infinite; +} + +.media { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; +} + +.media-body { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; +} + +.list-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; +} + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit; +} +.list-group-item-action:hover, .list-group-item-action:focus { + color: #495057; + text-decoration: none; + background-color: #f8f9fa; +} +.list-group-item-action:active { + color: #212529; + background-color: #e9ecef; +} + +.list-group-item { + position: relative; + display: block; + padding: 0.75rem 1.25rem; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} +.list-group-item:first-child { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} +.list-group-item:hover, .list-group-item:focus { + z-index: 1; + text-decoration: none; +} +.list-group-item.disabled, .list-group-item:disabled { + color: #6c757d; + background-color: #fff; +} +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.list-group-flush .list-group-item { + border-right: 0; + border-left: 0; + border-radius: 0; +} +.list-group-flush:first-child .list-group-item:first-child { + border-top: 0; +} +.list-group-flush:last-child .list-group-item:last-child { + border-bottom: 0; +} + +.list-group-item-primary { + color: #004085; + background-color: #b8daff; +} +.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { + color: #004085; + background-color: #9fcdff; +} +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #004085; + border-color: #004085; +} + +.list-group-item-secondary { + color: #383d41; + background-color: #d6d8db; +} +.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { + color: #383d41; + background-color: #c8cbcf; +} +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #383d41; + border-color: #383d41; +} + +.list-group-item-success { + color: #155724; + background-color: #c3e6cb; +} +.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { + color: #155724; + background-color: #b1dfbb; +} +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #155724; + border-color: #155724; +} + +.list-group-item-info { + color: #0c5460; + background-color: #bee5eb; +} +.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { + color: #0c5460; + background-color: #abdde5; +} +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #0c5460; + border-color: #0c5460; +} + +.list-group-item-warning { + color: #856404; + background-color: #ffeeba; +} +.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { + color: #856404; + background-color: #ffe8a1; +} +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #856404; + border-color: #856404; +} + +.list-group-item-danger { + color: #721c24; + background-color: #f5c6cb; +} +.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { + color: #721c24; + background-color: #f1b0b7; +} +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #721c24; + border-color: #721c24; +} + +.list-group-item-light { + color: #818182; + background-color: #fdfdfe; +} +.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { + color: #818182; + background-color: #ececf6; +} +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #818182; + border-color: #818182; +} + +.list-group-item-dark { + color: #1b1e21; + background-color: #c6c8ca; +} +.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { + color: #1b1e21; + background-color: #b9bbbe; +} +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #1b1e21; + border-color: #1b1e21; +} + +.close { + float: right; + font-size: 1.5rem; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .5; +} +.close:hover, .close:focus { + color: #000; + text-decoration: none; + opacity: .75; +} +.close:not(:disabled):not(.disabled) { + cursor: pointer; +} + +button.close { + padding: 0; + background-color: transparent; + border: 0; + -webkit-appearance: none; +} + +.modal-open { + overflow: hidden; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + outline: 0; +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} + +.modal-dialog { + position: relative; + width: auto; + margin: 0.5rem; + pointer-events: none; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform 0.3s ease-out; + transition: -webkit-transform 0.3s ease-out; + transition: transform 0.3s ease-out; + transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out; + -webkit-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.show .modal-dialog { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); +} + +.modal-dialog-centered { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + min-height: calc(100% - (0.5rem * 2)); +} + +.modal-content { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; + outline: 0; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop.show { + opacity: 0.5; +} + +.modal-header { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 1rem; + border-bottom: 1px solid #e9ecef; + border-top-left-radius: 0.3rem; + border-top-right-radius: 0.3rem; +} +.modal-header .close { + padding: 1rem; + margin: -1rem -1rem -1rem auto; +} + +.modal-title { + margin-bottom: 0; + line-height: 1.5; +} + +.modal-body { + position: relative; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 1rem; +} + +.modal-footer { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + padding: 1rem; + border-top: 1px solid #e9ecef; +} +.modal-footer > :not(:first-child) { + margin-left: .25rem; +} +.modal-footer > :not(:last-child) { + margin-right: .25rem; +} + +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} + +@media (min-width: 576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto; + } + + .modal-dialog-centered { + min-height: calc(100% - (1.75rem * 2)); + } + + .modal-sm { + max-width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + max-width: 800px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + opacity: 0; +} +.tooltip.show { + opacity: 0.9; +} +.tooltip .arrow { + position: absolute; + display: block; + width: 0.8rem; + height: 0.4rem; +} +.tooltip .arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-tooltip-top, .bs-tooltip-auto[x-placement^="top"] { + padding: 0.4rem 0; +} +.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^="top"] .arrow { + bottom: 0; +} +.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^="top"] .arrow::before { + top: 0; + border-width: 0.4rem 0.4rem 0; + border-top-color: #000; +} + +.bs-tooltip-right, .bs-tooltip-auto[x-placement^="right"] { + padding: 0 0.4rem; +} +.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^="right"] .arrow { + left: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^="right"] .arrow::before { + right: 0; + border-width: 0.4rem 0.4rem 0.4rem 0; + border-right-color: #000; +} + +.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^="bottom"] { + padding: 0.4rem 0; +} +.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^="bottom"] .arrow { + top: 0; +} +.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^="bottom"] .arrow::before { + bottom: 0; + border-width: 0 0.4rem 0.4rem; + border-bottom-color: #000; +} + +.bs-tooltip-left, .bs-tooltip-auto[x-placement^="left"] { + padding: 0 0.4rem; +} +.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^="left"] .arrow { + right: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^="left"] .arrow::before { + left: 0; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-left-color: #000; +} + +.tooltip-inner { + max-width: 200px; + padding: 0.25rem 0.5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 0.25rem; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: block; + max-width: 276px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; +} +.popover .arrow { + position: absolute; + display: block; + width: 1rem; + height: 0.5rem; + margin: 0 0.3rem; +} +.popover .arrow::before, .popover .arrow::after { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-popover-top, .bs-popover-auto[x-placement^="top"] { + margin-bottom: 0.5rem; +} +.bs-popover-top .arrow, .bs-popover-auto[x-placement^="top"] .arrow { + bottom: calc((0.5rem + 1px) * -1); +} +.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^="top"] .arrow::before, +.bs-popover-top .arrow::after, +.bs-popover-auto[x-placement^="top"] .arrow::after { + border-width: 0.5rem 0.5rem 0; +} +.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^="top"] .arrow::before { + bottom: 0; + border-top-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^="top"] .arrow::after { + bottom: 1px; + border-top-color: #fff; +} + +.bs-popover-right, .bs-popover-auto[x-placement^="right"] { + margin-left: 0.5rem; +} +.bs-popover-right .arrow, .bs-popover-auto[x-placement^="right"] .arrow { + left: calc((0.5rem + 1px) * -1); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} +.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^="right"] .arrow::before, +.bs-popover-right .arrow::after, +.bs-popover-auto[x-placement^="right"] .arrow::after { + border-width: 0.5rem 0.5rem 0.5rem 0; +} +.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^="right"] .arrow::before { + left: 0; + border-right-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^="right"] .arrow::after { + left: 1px; + border-right-color: #fff; +} + +.bs-popover-bottom, .bs-popover-auto[x-placement^="bottom"] { + margin-top: 0.5rem; +} +.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^="bottom"] .arrow { + top: calc((0.5rem + 1px) * -1); +} +.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^="bottom"] .arrow::before, +.bs-popover-bottom .arrow::after, +.bs-popover-auto[x-placement^="bottom"] .arrow::after { + border-width: 0 0.5rem 0.5rem 0.5rem; +} +.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^="bottom"] .arrow::before { + top: 0; + border-bottom-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^="bottom"] .arrow::after { + top: 1px; + border-bottom-color: #fff; +} +.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^="bottom"] .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -0.5rem; + content: ""; + border-bottom: 1px solid #f7f7f7; +} + +.bs-popover-left, .bs-popover-auto[x-placement^="left"] { + margin-right: 0.5rem; +} +.bs-popover-left .arrow, .bs-popover-auto[x-placement^="left"] .arrow { + right: calc((0.5rem + 1px) * -1); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} +.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^="left"] .arrow::before, +.bs-popover-left .arrow::after, +.bs-popover-auto[x-placement^="left"] .arrow::after { + border-width: 0.5rem 0 0.5rem 0.5rem; +} +.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^="left"] .arrow::before { + right: 0; + border-left-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^="left"] .arrow::after { + right: 1px; + border-left-color: #fff; +} + +.popover-header { + padding: 0.5rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + color: inherit; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} +.popover-header:empty { + display: none; +} + +.popover-body { + padding: 0.5rem 0.75rem; + color: #212529; +} + +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-item { + position: relative; + display: none; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + -webkit-transition: -webkit-transform 0.6s ease; + transition: -webkit-transform 0.6s ease; + transition: transform 0.6s ease; + transition: transform 0.6s ease, -webkit-transform 0.6s ease; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} + +.carousel-item-next, +.carousel-item-prev { + position: absolute; + top: 0; +} + +.carousel-item-next.carousel-item-left, +.carousel-item-prev.carousel-item-right { + -webkit-transform: translateX(0); + transform: translateX(0); +} +@supports (transform-style: preserve-3d) { + .carousel-item-next.carousel-item-left, + .carousel-item-prev.carousel-item-right { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.carousel-item-next, +.active.carousel-item-right { + -webkit-transform: translateX(100%); + transform: translateX(100%); +} +@supports (transform-style: preserve-3d) { + .carousel-item-next, + .active.carousel-item-right { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +.carousel-item-prev, +.active.carousel-item-left { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); +} +@supports (transform-style: preserve-3d) { + .carousel-item-prev, + .active.carousel-item-left { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 15%; + color: #fff; + text-align: center; + opacity: 0.5; +} +.carousel-control-prev:hover, .carousel-control-prev:focus, +.carousel-control-next:hover, +.carousel-control-next:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9; +} + +.carousel-control-prev { + left: 0; +} + +.carousel-control-next { + right: 0; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: 20px; + height: 20px; + background: transparent no-repeat center center; + background-size: 100% 100%; +} + +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"); +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"); +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 10px; + left: 0; + z-index: 15; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + padding-left: 0; + margin-right: 15%; + margin-left: 15%; + list-style: none; +} +.carousel-indicators li { + position: relative; + -webkit-box-flex: 0; + -ms-flex: 0 1 auto; + flex: 0 1 auto; + width: 30px; + height: 3px; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + background-color: rgba(255, 255, 255, 0.5); +} +.carousel-indicators li::before { + position: absolute; + top: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; +} +.carousel-indicators li::after { + position: absolute; + bottom: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; +} +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; +} + +.align-baseline { + vertical-align: baseline !important; +} + +.align-top { + vertical-align: top !important; +} + +.align-middle { + vertical-align: middle !important; +} + +.align-bottom { + vertical-align: bottom !important; +} + +.align-text-bottom { + vertical-align: text-bottom !important; +} + +.align-text-top { + vertical-align: text-top !important; +} + +.bg-primary { + background-color: #007bff !important; +} + +a.bg-primary:hover, a.bg-primary:focus, +button.bg-primary:hover, +button.bg-primary:focus { + background-color: #0062cc !important; +} + +.bg-secondary { + background-color: #6c757d !important; +} + +a.bg-secondary:hover, a.bg-secondary:focus, +button.bg-secondary:hover, +button.bg-secondary:focus { + background-color: #545b62 !important; +} + +.bg-success { + background-color: #28a745 !important; +} + +a.bg-success:hover, a.bg-success:focus, +button.bg-success:hover, +button.bg-success:focus { + background-color: #1e7e34 !important; +} + +.bg-info { + background-color: #17a2b8 !important; +} + +a.bg-info:hover, a.bg-info:focus, +button.bg-info:hover, +button.bg-info:focus { + background-color: #117a8b !important; +} + +.bg-warning { + background-color: #ffc107 !important; +} + +a.bg-warning:hover, a.bg-warning:focus, +button.bg-warning:hover, +button.bg-warning:focus { + background-color: #d39e00 !important; +} + +.bg-danger { + background-color: #dc3545 !important; +} + +a.bg-danger:hover, a.bg-danger:focus, +button.bg-danger:hover, +button.bg-danger:focus { + background-color: #bd2130 !important; +} + +.bg-light { + background-color: #f8f9fa !important; +} + +a.bg-light:hover, a.bg-light:focus, +button.bg-light:hover, +button.bg-light:focus { + background-color: #dae0e5 !important; +} + +.bg-dark { + background-color: #343a40 !important; +} + +a.bg-dark:hover, a.bg-dark:focus, +button.bg-dark:hover, +button.bg-dark:focus { + background-color: #1d2124 !important; +} + +.bg-white { + background-color: #fff !important; +} + +.bg-transparent { + background-color: transparent !important; +} + +.border { + border: 1px solid #dee2e6 !important; +} + +.border-top { + border-top: 1px solid #dee2e6 !important; +} + +.border-right { + border-right: 1px solid #dee2e6 !important; +} + +.border-bottom { + border-bottom: 1px solid #dee2e6 !important; +} + +.border-left { + border-left: 1px solid #dee2e6 !important; +} + +.border-0 { + border: 0 !important; +} + +.border-top-0 { + border-top: 0 !important; +} + +.border-right-0 { + border-right: 0 !important; +} + +.border-bottom-0 { + border-bottom: 0 !important; +} + +.border-left-0 { + border-left: 0 !important; +} + +.border-primary { + border-color: #007bff !important; +} + +.border-secondary { + border-color: #6c757d !important; +} + +.border-success { + border-color: #28a745 !important; +} + +.border-info { + border-color: #17a2b8 !important; +} + +.border-warning { + border-color: #ffc107 !important; +} + +.border-danger { + border-color: #dc3545 !important; +} + +.border-light { + border-color: #f8f9fa !important; +} + +.border-dark { + border-color: #343a40 !important; +} + +.border-white { + border-color: #fff !important; +} + +.rounded { + border-radius: 0.25rem !important; +} + +.rounded-top { + border-top-left-radius: 0.25rem !important; + border-top-right-radius: 0.25rem !important; +} + +.rounded-right { + border-top-right-radius: 0.25rem !important; + border-bottom-right-radius: 0.25rem !important; +} + +.rounded-bottom { + border-bottom-right-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-left { + border-top-left-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-0 { + border-radius: 0 !important; +} + +.clearfix::after { + display: block; + clear: both; + content: ""; +} + +.d-none { + display: none !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; +} + +.d-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; +} + +@media (min-width: 576px) { + .d-sm-none { + display: none !important; + } + + .d-sm-inline { + display: inline !important; + } + + .d-sm-inline-block { + display: inline-block !important; + } + + .d-sm-block { + display: block !important; + } + + .d-sm-table { + display: table !important; + } + + .d-sm-table-row { + display: table-row !important; + } + + .d-sm-table-cell { + display: table-cell !important; + } + + .d-sm-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-sm-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media (min-width: 768px) { + .d-md-none { + display: none !important; + } + + .d-md-inline { + display: inline !important; + } + + .d-md-inline-block { + display: inline-block !important; + } + + .d-md-block { + display: block !important; + } + + .d-md-table { + display: table !important; + } + + .d-md-table-row { + display: table-row !important; + } + + .d-md-table-cell { + display: table-cell !important; + } + + .d-md-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-md-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media (min-width: 992px) { + .d-lg-none { + display: none !important; + } + + .d-lg-inline { + display: inline !important; + } + + .d-lg-inline-block { + display: inline-block !important; + } + + .d-lg-block { + display: block !important; + } + + .d-lg-table { + display: table !important; + } + + .d-lg-table-row { + display: table-row !important; + } + + .d-lg-table-cell { + display: table-cell !important; + } + + .d-lg-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-lg-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media (min-width: 1200px) { + .d-xl-none { + display: none !important; + } + + .d-xl-inline { + display: inline !important; + } + + .d-xl-inline-block { + display: inline-block !important; + } + + .d-xl-block { + display: block !important; + } + + .d-xl-table { + display: table !important; + } + + .d-xl-table-row { + display: table-row !important; + } + + .d-xl-table-cell { + display: table-cell !important; + } + + .d-xl-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-xl-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media print { + .d-print-none { + display: none !important; + } + + .d-print-inline { + display: inline !important; + } + + .d-print-inline-block { + display: inline-block !important; + } + + .d-print-block { + display: block !important; + } + + .d-print-table { + display: table !important; + } + + .d-print-table-row { + display: table-row !important; + } + + .d-print-table-cell { + display: table-cell !important; + } + + .d-print-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + + .d-print-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +.embed-responsive { + position: relative; + display: block; + width: 100%; + padding: 0; + overflow: hidden; +} +.embed-responsive::before { + display: block; + content: ""; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} + +.embed-responsive-21by9::before { + padding-top: 42.8571428571%; +} + +.embed-responsive-16by9::before { + padding-top: 56.25%; +} + +.embed-responsive-4by3::before { + padding-top: 75%; +} + +.embed-responsive-1by1::before { + padding-top: 100%; +} + +.flex-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; +} + +.flex-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; +} + +.flex-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; +} + +.flex-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; +} + +.flex-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; +} + +.justify-content-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; +} + +.justify-content-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; +} + +.justify-content-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; +} + +.justify-content-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; +} + +.align-items-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; +} + +.align-items-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; +} + +.align-items-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; +} + +.align-items-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; +} + +.align-items-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; +} + +.align-content-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; +} + +.align-content-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; +} + +.align-content-center { + -ms-flex-line-pack: center !important; + align-content: center !important; +} + +.align-content-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; +} + +.align-content-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; +} + +.align-content-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; +} + +.align-self-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; +} + +.align-self-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; +} + +.align-self-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; +} + +.align-self-center { + -ms-flex-item-align: center !important; + align-self: center !important; +} + +.align-self-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; +} + +.align-self-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; +} + +@media (min-width: 576px) { + .flex-sm-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + + .flex-sm-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + + .flex-sm-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + + .flex-sm-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + + .flex-sm-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + + .flex-sm-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + + .flex-sm-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + + .justify-content-sm-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + + .justify-content-sm-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + + .justify-content-sm-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + + .justify-content-sm-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + + .justify-content-sm-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + + .align-items-sm-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + + .align-items-sm-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + + .align-items-sm-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + + .align-items-sm-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + + .align-items-sm-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + + .align-content-sm-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + + .align-content-sm-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + + .align-content-sm-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + + .align-content-sm-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + + .align-content-sm-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + + .align-content-sm-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + + .align-self-sm-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + + .align-self-sm-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + + .align-self-sm-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + + .align-self-sm-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + + .align-self-sm-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + + .align-self-sm-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +@media (min-width: 768px) { + .flex-md-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + + .flex-md-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + + .flex-md-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + + .flex-md-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + + .flex-md-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + + .flex-md-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + + .flex-md-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + + .justify-content-md-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + + .justify-content-md-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + + .justify-content-md-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + + .justify-content-md-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + + .justify-content-md-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + + .align-items-md-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + + .align-items-md-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + + .align-items-md-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + + .align-items-md-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + + .align-items-md-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + + .align-content-md-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + + .align-content-md-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + + .align-content-md-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + + .align-content-md-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + + .align-content-md-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + + .align-content-md-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + + .align-self-md-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + + .align-self-md-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + + .align-self-md-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + + .align-self-md-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + + .align-self-md-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + + .align-self-md-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +@media (min-width: 992px) { + .flex-lg-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + + .flex-lg-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + + .flex-lg-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + + .flex-lg-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + + .flex-lg-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + + .flex-lg-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + + .flex-lg-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + + .justify-content-lg-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + + .justify-content-lg-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + + .justify-content-lg-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + + .justify-content-lg-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + + .justify-content-lg-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + + .align-items-lg-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + + .align-items-lg-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + + .align-items-lg-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + + .align-items-lg-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + + .align-items-lg-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + + .align-content-lg-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + + .align-content-lg-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + + .align-content-lg-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + + .align-content-lg-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + + .align-content-lg-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + + .align-content-lg-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + + .align-self-lg-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + + .align-self-lg-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + + .align-self-lg-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + + .align-self-lg-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + + .align-self-lg-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + + .align-self-lg-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +@media (min-width: 1200px) { + .flex-xl-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + + .flex-xl-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + + .flex-xl-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + + .flex-xl-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + + .flex-xl-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + + .flex-xl-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + + .flex-xl-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + + .justify-content-xl-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + + .justify-content-xl-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + + .justify-content-xl-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + + .justify-content-xl-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + + .justify-content-xl-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + + .align-items-xl-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + + .align-items-xl-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + + .align-items-xl-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + + .align-items-xl-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + + .align-items-xl-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + + .align-content-xl-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + + .align-content-xl-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + + .align-content-xl-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + + .align-content-xl-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + + .align-content-xl-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + + .align-content-xl-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + + .align-self-xl-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + + .align-self-xl-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + + .align-self-xl-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + + .align-self-xl-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + + .align-self-xl-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + + .align-self-xl-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +.float-left { + float: left !important; +} + +.float-right { + float: right !important; +} + +.float-none { + float: none !important; +} + +@media (min-width: 576px) { + .float-sm-left { + float: left !important; + } + + .float-sm-right { + float: right !important; + } + + .float-sm-none { + float: none !important; + } +} +@media (min-width: 768px) { + .float-md-left { + float: left !important; + } + + .float-md-right { + float: right !important; + } + + .float-md-none { + float: none !important; + } +} +@media (min-width: 992px) { + .float-lg-left { + float: left !important; + } + + .float-lg-right { + float: right !important; + } + + .float-lg-none { + float: none !important; + } +} +@media (min-width: 1200px) { + .float-xl-left { + float: left !important; + } + + .float-xl-right { + float: right !important; + } + + .float-xl-none { + float: none !important; + } +} +.position-static { + position: static !important; +} + +.position-relative { + position: relative !important; +} + +.position-absolute { + position: absolute !important; +} + +.position-fixed { + position: fixed !important; +} + +.position-sticky { + position: sticky !important; +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; +} + +@supports (position: sticky) { + .sticky-top { + position: sticky; + top: 0; + z-index: 1020; + } +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + border: 0; +} + +.sr-only-focusable:active, .sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + overflow: visible; + clip: auto; + white-space: normal; + -webkit-clip-path: none; + clip-path: none; +} + +.w-25 { + width: 25% !important; +} + +.w-50 { + width: 50% !important; +} + +.w-75 { + width: 75% !important; +} + +.w-100 { + width: 100% !important; +} + +.h-25 { + height: 25% !important; +} + +.h-50 { + height: 50% !important; +} + +.h-75 { + height: 75% !important; +} + +.h-100 { + height: 100% !important; +} + +.mw-100 { + max-width: 100% !important; +} + +.mh-100 { + max-height: 100% !important; +} + +.m-0 { + margin: 0 !important; +} + +.mt-0, +.my-0 { + margin-top: 0 !important; +} + +.mr-0, +.mx-0 { + margin-right: 0 !important; +} + +.mb-0, +.my-0 { + margin-bottom: 0 !important; +} + +.ml-0, +.mx-0 { + margin-left: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.mt-1, +.my-1 { + margin-top: 0.25rem !important; +} + +.mr-1, +.mx-1 { + margin-right: 0.25rem !important; +} + +.mb-1, +.my-1 { + margin-bottom: 0.25rem !important; +} + +.ml-1, +.mx-1 { + margin-left: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.mt-2, +.my-2 { + margin-top: 0.5rem !important; +} + +.mr-2, +.mx-2 { + margin-right: 0.5rem !important; +} + +.mb-2, +.my-2 { + margin-bottom: 0.5rem !important; +} + +.ml-2, +.mx-2 { + margin-left: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.mt-3, +.my-3 { + margin-top: 1rem !important; +} + +.mr-3, +.mx-3 { + margin-right: 1rem !important; +} + +.mb-3, +.my-3 { + margin-bottom: 1rem !important; +} + +.ml-3, +.mx-3 { + margin-left: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.mt-4, +.my-4 { + margin-top: 1.5rem !important; +} + +.mr-4, +.mx-4 { + margin-right: 1.5rem !important; +} + +.mb-4, +.my-4 { + margin-bottom: 1.5rem !important; +} + +.ml-4, +.mx-4 { + margin-left: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.mt-5, +.my-5 { + margin-top: 3rem !important; +} + +.mr-5, +.mx-5 { + margin-right: 3rem !important; +} + +.mb-5, +.my-5 { + margin-bottom: 3rem !important; +} + +.ml-5, +.mx-5 { + margin-left: 3rem !important; +} + +.p-0 { + padding: 0 !important; +} + +.pt-0, +.py-0 { + padding-top: 0 !important; +} + +.pr-0, +.px-0 { + padding-right: 0 !important; +} + +.pb-0, +.py-0 { + padding-bottom: 0 !important; +} + +.pl-0, +.px-0 { + padding-left: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.pt-1, +.py-1 { + padding-top: 0.25rem !important; +} + +.pr-1, +.px-1 { + padding-right: 0.25rem !important; +} + +.pb-1, +.py-1 { + padding-bottom: 0.25rem !important; +} + +.pl-1, +.px-1 { + padding-left: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.pt-2, +.py-2 { + padding-top: 0.5rem !important; +} + +.pr-2, +.px-2 { + padding-right: 0.5rem !important; +} + +.pb-2, +.py-2 { + padding-bottom: 0.5rem !important; +} + +.pl-2, +.px-2 { + padding-left: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.pt-3, +.py-3 { + padding-top: 1rem !important; +} + +.pr-3, +.px-3 { + padding-right: 1rem !important; +} + +.pb-3, +.py-3 { + padding-bottom: 1rem !important; +} + +.pl-3, +.px-3 { + padding-left: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.pt-4, +.py-4 { + padding-top: 1.5rem !important; +} + +.pr-4, +.px-4 { + padding-right: 1.5rem !important; +} + +.pb-4, +.py-4 { + padding-bottom: 1.5rem !important; +} + +.pl-4, +.px-4 { + padding-left: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.pt-5, +.py-5 { + padding-top: 3rem !important; +} + +.pr-5, +.px-5 { + padding-right: 3rem !important; +} + +.pb-5, +.py-5 { + padding-bottom: 3rem !important; +} + +.pl-5, +.px-5 { + padding-left: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mt-auto, +.my-auto { + margin-top: auto !important; +} + +.mr-auto, +.mx-auto { + margin-right: auto !important; +} + +.mb-auto, +.my-auto { + margin-bottom: auto !important; +} + +.ml-auto, +.mx-auto { + margin-left: auto !important; +} + +@media (min-width: 576px) { + .m-sm-0 { + margin: 0 !important; + } + + .mt-sm-0, + .my-sm-0 { + margin-top: 0 !important; + } + + .mr-sm-0, + .mx-sm-0 { + margin-right: 0 !important; + } + + .mb-sm-0, + .my-sm-0 { + margin-bottom: 0 !important; + } + + .ml-sm-0, + .mx-sm-0 { + margin-left: 0 !important; + } + + .m-sm-1 { + margin: 0.25rem !important; + } + + .mt-sm-1, + .my-sm-1 { + margin-top: 0.25rem !important; + } + + .mr-sm-1, + .mx-sm-1 { + margin-right: 0.25rem !important; + } + + .mb-sm-1, + .my-sm-1 { + margin-bottom: 0.25rem !important; + } + + .ml-sm-1, + .mx-sm-1 { + margin-left: 0.25rem !important; + } + + .m-sm-2 { + margin: 0.5rem !important; + } + + .mt-sm-2, + .my-sm-2 { + margin-top: 0.5rem !important; + } + + .mr-sm-2, + .mx-sm-2 { + margin-right: 0.5rem !important; + } + + .mb-sm-2, + .my-sm-2 { + margin-bottom: 0.5rem !important; + } + + .ml-sm-2, + .mx-sm-2 { + margin-left: 0.5rem !important; + } + + .m-sm-3 { + margin: 1rem !important; + } + + .mt-sm-3, + .my-sm-3 { + margin-top: 1rem !important; + } + + .mr-sm-3, + .mx-sm-3 { + margin-right: 1rem !important; + } + + .mb-sm-3, + .my-sm-3 { + margin-bottom: 1rem !important; + } + + .ml-sm-3, + .mx-sm-3 { + margin-left: 1rem !important; + } + + .m-sm-4 { + margin: 1.5rem !important; + } + + .mt-sm-4, + .my-sm-4 { + margin-top: 1.5rem !important; + } + + .mr-sm-4, + .mx-sm-4 { + margin-right: 1.5rem !important; + } + + .mb-sm-4, + .my-sm-4 { + margin-bottom: 1.5rem !important; + } + + .ml-sm-4, + .mx-sm-4 { + margin-left: 1.5rem !important; + } + + .m-sm-5 { + margin: 3rem !important; + } + + .mt-sm-5, + .my-sm-5 { + margin-top: 3rem !important; + } + + .mr-sm-5, + .mx-sm-5 { + margin-right: 3rem !important; + } + + .mb-sm-5, + .my-sm-5 { + margin-bottom: 3rem !important; + } + + .ml-sm-5, + .mx-sm-5 { + margin-left: 3rem !important; + } + + .p-sm-0 { + padding: 0 !important; + } + + .pt-sm-0, + .py-sm-0 { + padding-top: 0 !important; + } + + .pr-sm-0, + .px-sm-0 { + padding-right: 0 !important; + } + + .pb-sm-0, + .py-sm-0 { + padding-bottom: 0 !important; + } + + .pl-sm-0, + .px-sm-0 { + padding-left: 0 !important; + } + + .p-sm-1 { + padding: 0.25rem !important; + } + + .pt-sm-1, + .py-sm-1 { + padding-top: 0.25rem !important; + } + + .pr-sm-1, + .px-sm-1 { + padding-right: 0.25rem !important; + } + + .pb-sm-1, + .py-sm-1 { + padding-bottom: 0.25rem !important; + } + + .pl-sm-1, + .px-sm-1 { + padding-left: 0.25rem !important; + } + + .p-sm-2 { + padding: 0.5rem !important; + } + + .pt-sm-2, + .py-sm-2 { + padding-top: 0.5rem !important; + } + + .pr-sm-2, + .px-sm-2 { + padding-right: 0.5rem !important; + } + + .pb-sm-2, + .py-sm-2 { + padding-bottom: 0.5rem !important; + } + + .pl-sm-2, + .px-sm-2 { + padding-left: 0.5rem !important; + } + + .p-sm-3 { + padding: 1rem !important; + } + + .pt-sm-3, + .py-sm-3 { + padding-top: 1rem !important; + } + + .pr-sm-3, + .px-sm-3 { + padding-right: 1rem !important; + } + + .pb-sm-3, + .py-sm-3 { + padding-bottom: 1rem !important; + } + + .pl-sm-3, + .px-sm-3 { + padding-left: 1rem !important; + } + + .p-sm-4 { + padding: 1.5rem !important; + } + + .pt-sm-4, + .py-sm-4 { + padding-top: 1.5rem !important; + } + + .pr-sm-4, + .px-sm-4 { + padding-right: 1.5rem !important; + } + + .pb-sm-4, + .py-sm-4 { + padding-bottom: 1.5rem !important; + } + + .pl-sm-4, + .px-sm-4 { + padding-left: 1.5rem !important; + } + + .p-sm-5 { + padding: 3rem !important; + } + + .pt-sm-5, + .py-sm-5 { + padding-top: 3rem !important; + } + + .pr-sm-5, + .px-sm-5 { + padding-right: 3rem !important; + } + + .pb-sm-5, + .py-sm-5 { + padding-bottom: 3rem !important; + } + + .pl-sm-5, + .px-sm-5 { + padding-left: 3rem !important; + } + + .m-sm-auto { + margin: auto !important; + } + + .mt-sm-auto, + .my-sm-auto { + margin-top: auto !important; + } + + .mr-sm-auto, + .mx-sm-auto { + margin-right: auto !important; + } + + .mb-sm-auto, + .my-sm-auto { + margin-bottom: auto !important; + } + + .ml-sm-auto, + .mx-sm-auto { + margin-left: auto !important; + } +} +@media (min-width: 768px) { + .m-md-0 { + margin: 0 !important; + } + + .mt-md-0, + .my-md-0 { + margin-top: 0 !important; + } + + .mr-md-0, + .mx-md-0 { + margin-right: 0 !important; + } + + .mb-md-0, + .my-md-0 { + margin-bottom: 0 !important; + } + + .ml-md-0, + .mx-md-0 { + margin-left: 0 !important; + } + + .m-md-1 { + margin: 0.25rem !important; + } + + .mt-md-1, + .my-md-1 { + margin-top: 0.25rem !important; + } + + .mr-md-1, + .mx-md-1 { + margin-right: 0.25rem !important; + } + + .mb-md-1, + .my-md-1 { + margin-bottom: 0.25rem !important; + } + + .ml-md-1, + .mx-md-1 { + margin-left: 0.25rem !important; + } + + .m-md-2 { + margin: 0.5rem !important; + } + + .mt-md-2, + .my-md-2 { + margin-top: 0.5rem !important; + } + + .mr-md-2, + .mx-md-2 { + margin-right: 0.5rem !important; + } + + .mb-md-2, + .my-md-2 { + margin-bottom: 0.5rem !important; + } + + .ml-md-2, + .mx-md-2 { + margin-left: 0.5rem !important; + } + + .m-md-3 { + margin: 1rem !important; + } + + .mt-md-3, + .my-md-3 { + margin-top: 1rem !important; + } + + .mr-md-3, + .mx-md-3 { + margin-right: 1rem !important; + } + + .mb-md-3, + .my-md-3 { + margin-bottom: 1rem !important; + } + + .ml-md-3, + .mx-md-3 { + margin-left: 1rem !important; + } + + .m-md-4 { + margin: 1.5rem !important; + } + + .mt-md-4, + .my-md-4 { + margin-top: 1.5rem !important; + } + + .mr-md-4, + .mx-md-4 { + margin-right: 1.5rem !important; + } + + .mb-md-4, + .my-md-4 { + margin-bottom: 1.5rem !important; + } + + .ml-md-4, + .mx-md-4 { + margin-left: 1.5rem !important; + } + + .m-md-5 { + margin: 3rem !important; + } + + .mt-md-5, + .my-md-5 { + margin-top: 3rem !important; + } + + .mr-md-5, + .mx-md-5 { + margin-right: 3rem !important; + } + + .mb-md-5, + .my-md-5 { + margin-bottom: 3rem !important; + } + + .ml-md-5, + .mx-md-5 { + margin-left: 3rem !important; + } + + .p-md-0 { + padding: 0 !important; + } + + .pt-md-0, + .py-md-0 { + padding-top: 0 !important; + } + + .pr-md-0, + .px-md-0 { + padding-right: 0 !important; + } + + .pb-md-0, + .py-md-0 { + padding-bottom: 0 !important; + } + + .pl-md-0, + .px-md-0 { + padding-left: 0 !important; + } + + .p-md-1 { + padding: 0.25rem !important; + } + + .pt-md-1, + .py-md-1 { + padding-top: 0.25rem !important; + } + + .pr-md-1, + .px-md-1 { + padding-right: 0.25rem !important; + } + + .pb-md-1, + .py-md-1 { + padding-bottom: 0.25rem !important; + } + + .pl-md-1, + .px-md-1 { + padding-left: 0.25rem !important; + } + + .p-md-2 { + padding: 0.5rem !important; + } + + .pt-md-2, + .py-md-2 { + padding-top: 0.5rem !important; + } + + .pr-md-2, + .px-md-2 { + padding-right: 0.5rem !important; + } + + .pb-md-2, + .py-md-2 { + padding-bottom: 0.5rem !important; + } + + .pl-md-2, + .px-md-2 { + padding-left: 0.5rem !important; + } + + .p-md-3 { + padding: 1rem !important; + } + + .pt-md-3, + .py-md-3 { + padding-top: 1rem !important; + } + + .pr-md-3, + .px-md-3 { + padding-right: 1rem !important; + } + + .pb-md-3, + .py-md-3 { + padding-bottom: 1rem !important; + } + + .pl-md-3, + .px-md-3 { + padding-left: 1rem !important; + } + + .p-md-4 { + padding: 1.5rem !important; + } + + .pt-md-4, + .py-md-4 { + padding-top: 1.5rem !important; + } + + .pr-md-4, + .px-md-4 { + padding-right: 1.5rem !important; + } + + .pb-md-4, + .py-md-4 { + padding-bottom: 1.5rem !important; + } + + .pl-md-4, + .px-md-4 { + padding-left: 1.5rem !important; + } + + .p-md-5 { + padding: 3rem !important; + } + + .pt-md-5, + .py-md-5 { + padding-top: 3rem !important; + } + + .pr-md-5, + .px-md-5 { + padding-right: 3rem !important; + } + + .pb-md-5, + .py-md-5 { + padding-bottom: 3rem !important; + } + + .pl-md-5, + .px-md-5 { + padding-left: 3rem !important; + } + + .m-md-auto { + margin: auto !important; + } + + .mt-md-auto, + .my-md-auto { + margin-top: auto !important; + } + + .mr-md-auto, + .mx-md-auto { + margin-right: auto !important; + } + + .mb-md-auto, + .my-md-auto { + margin-bottom: auto !important; + } + + .ml-md-auto, + .mx-md-auto { + margin-left: auto !important; + } +} +@media (min-width: 992px) { + .m-lg-0 { + margin: 0 !important; + } + + .mt-lg-0, + .my-lg-0 { + margin-top: 0 !important; + } + + .mr-lg-0, + .mx-lg-0 { + margin-right: 0 !important; + } + + .mb-lg-0, + .my-lg-0 { + margin-bottom: 0 !important; + } + + .ml-lg-0, + .mx-lg-0 { + margin-left: 0 !important; + } + + .m-lg-1 { + margin: 0.25rem !important; + } + + .mt-lg-1, + .my-lg-1 { + margin-top: 0.25rem !important; + } + + .mr-lg-1, + .mx-lg-1 { + margin-right: 0.25rem !important; + } + + .mb-lg-1, + .my-lg-1 { + margin-bottom: 0.25rem !important; + } + + .ml-lg-1, + .mx-lg-1 { + margin-left: 0.25rem !important; + } + + .m-lg-2 { + margin: 0.5rem !important; + } + + .mt-lg-2, + .my-lg-2 { + margin-top: 0.5rem !important; + } + + .mr-lg-2, + .mx-lg-2 { + margin-right: 0.5rem !important; + } + + .mb-lg-2, + .my-lg-2 { + margin-bottom: 0.5rem !important; + } + + .ml-lg-2, + .mx-lg-2 { + margin-left: 0.5rem !important; + } + + .m-lg-3 { + margin: 1rem !important; + } + + .mt-lg-3, + .my-lg-3 { + margin-top: 1rem !important; + } + + .mr-lg-3, + .mx-lg-3 { + margin-right: 1rem !important; + } + + .mb-lg-3, + .my-lg-3 { + margin-bottom: 1rem !important; + } + + .ml-lg-3, + .mx-lg-3 { + margin-left: 1rem !important; + } + + .m-lg-4 { + margin: 1.5rem !important; + } + + .mt-lg-4, + .my-lg-4 { + margin-top: 1.5rem !important; + } + + .mr-lg-4, + .mx-lg-4 { + margin-right: 1.5rem !important; + } + + .mb-lg-4, + .my-lg-4 { + margin-bottom: 1.5rem !important; + } + + .ml-lg-4, + .mx-lg-4 { + margin-left: 1.5rem !important; + } + + .m-lg-5 { + margin: 3rem !important; + } + + .mt-lg-5, + .my-lg-5 { + margin-top: 3rem !important; + } + + .mr-lg-5, + .mx-lg-5 { + margin-right: 3rem !important; + } + + .mb-lg-5, + .my-lg-5 { + margin-bottom: 3rem !important; + } + + .ml-lg-5, + .mx-lg-5 { + margin-left: 3rem !important; + } + + .p-lg-0 { + padding: 0 !important; + } + + .pt-lg-0, + .py-lg-0 { + padding-top: 0 !important; + } + + .pr-lg-0, + .px-lg-0 { + padding-right: 0 !important; + } + + .pb-lg-0, + .py-lg-0 { + padding-bottom: 0 !important; + } + + .pl-lg-0, + .px-lg-0 { + padding-left: 0 !important; + } + + .p-lg-1 { + padding: 0.25rem !important; + } + + .pt-lg-1, + .py-lg-1 { + padding-top: 0.25rem !important; + } + + .pr-lg-1, + .px-lg-1 { + padding-right: 0.25rem !important; + } + + .pb-lg-1, + .py-lg-1 { + padding-bottom: 0.25rem !important; + } + + .pl-lg-1, + .px-lg-1 { + padding-left: 0.25rem !important; + } + + .p-lg-2 { + padding: 0.5rem !important; + } + + .pt-lg-2, + .py-lg-2 { + padding-top: 0.5rem !important; + } + + .pr-lg-2, + .px-lg-2 { + padding-right: 0.5rem !important; + } + + .pb-lg-2, + .py-lg-2 { + padding-bottom: 0.5rem !important; + } + + .pl-lg-2, + .px-lg-2 { + padding-left: 0.5rem !important; + } + + .p-lg-3 { + padding: 1rem !important; + } + + .pt-lg-3, + .py-lg-3 { + padding-top: 1rem !important; + } + + .pr-lg-3, + .px-lg-3 { + padding-right: 1rem !important; + } + + .pb-lg-3, + .py-lg-3 { + padding-bottom: 1rem !important; + } + + .pl-lg-3, + .px-lg-3 { + padding-left: 1rem !important; + } + + .p-lg-4 { + padding: 1.5rem !important; + } + + .pt-lg-4, + .py-lg-4 { + padding-top: 1.5rem !important; + } + + .pr-lg-4, + .px-lg-4 { + padding-right: 1.5rem !important; + } + + .pb-lg-4, + .py-lg-4 { + padding-bottom: 1.5rem !important; + } + + .pl-lg-4, + .px-lg-4 { + padding-left: 1.5rem !important; + } + + .p-lg-5 { + padding: 3rem !important; + } + + .pt-lg-5, + .py-lg-5 { + padding-top: 3rem !important; + } + + .pr-lg-5, + .px-lg-5 { + padding-right: 3rem !important; + } + + .pb-lg-5, + .py-lg-5 { + padding-bottom: 3rem !important; + } + + .pl-lg-5, + .px-lg-5 { + padding-left: 3rem !important; + } + + .m-lg-auto { + margin: auto !important; + } + + .mt-lg-auto, + .my-lg-auto { + margin-top: auto !important; + } + + .mr-lg-auto, + .mx-lg-auto { + margin-right: auto !important; + } + + .mb-lg-auto, + .my-lg-auto { + margin-bottom: auto !important; + } + + .ml-lg-auto, + .mx-lg-auto { + margin-left: auto !important; + } +} +@media (min-width: 1200px) { + .m-xl-0 { + margin: 0 !important; + } + + .mt-xl-0, + .my-xl-0 { + margin-top: 0 !important; + } + + .mr-xl-0, + .mx-xl-0 { + margin-right: 0 !important; + } + + .mb-xl-0, + .my-xl-0 { + margin-bottom: 0 !important; + } + + .ml-xl-0, + .mx-xl-0 { + margin-left: 0 !important; + } + + .m-xl-1 { + margin: 0.25rem !important; + } + + .mt-xl-1, + .my-xl-1 { + margin-top: 0.25rem !important; + } + + .mr-xl-1, + .mx-xl-1 { + margin-right: 0.25rem !important; + } + + .mb-xl-1, + .my-xl-1 { + margin-bottom: 0.25rem !important; + } + + .ml-xl-1, + .mx-xl-1 { + margin-left: 0.25rem !important; + } + + .m-xl-2 { + margin: 0.5rem !important; + } + + .mt-xl-2, + .my-xl-2 { + margin-top: 0.5rem !important; + } + + .mr-xl-2, + .mx-xl-2 { + margin-right: 0.5rem !important; + } + + .mb-xl-2, + .my-xl-2 { + margin-bottom: 0.5rem !important; + } + + .ml-xl-2, + .mx-xl-2 { + margin-left: 0.5rem !important; + } + + .m-xl-3 { + margin: 1rem !important; + } + + .mt-xl-3, + .my-xl-3 { + margin-top: 1rem !important; + } + + .mr-xl-3, + .mx-xl-3 { + margin-right: 1rem !important; + } + + .mb-xl-3, + .my-xl-3 { + margin-bottom: 1rem !important; + } + + .ml-xl-3, + .mx-xl-3 { + margin-left: 1rem !important; + } + + .m-xl-4 { + margin: 1.5rem !important; + } + + .mt-xl-4, + .my-xl-4 { + margin-top: 1.5rem !important; + } + + .mr-xl-4, + .mx-xl-4 { + margin-right: 1.5rem !important; + } + + .mb-xl-4, + .my-xl-4 { + margin-bottom: 1.5rem !important; + } + + .ml-xl-4, + .mx-xl-4 { + margin-left: 1.5rem !important; + } + + .m-xl-5 { + margin: 3rem !important; + } + + .mt-xl-5, + .my-xl-5 { + margin-top: 3rem !important; + } + + .mr-xl-5, + .mx-xl-5 { + margin-right: 3rem !important; + } + + .mb-xl-5, + .my-xl-5 { + margin-bottom: 3rem !important; + } + + .ml-xl-5, + .mx-xl-5 { + margin-left: 3rem !important; + } + + .p-xl-0 { + padding: 0 !important; + } + + .pt-xl-0, + .py-xl-0 { + padding-top: 0 !important; + } + + .pr-xl-0, + .px-xl-0 { + padding-right: 0 !important; + } + + .pb-xl-0, + .py-xl-0 { + padding-bottom: 0 !important; + } + + .pl-xl-0, + .px-xl-0 { + padding-left: 0 !important; + } + + .p-xl-1 { + padding: 0.25rem !important; + } + + .pt-xl-1, + .py-xl-1 { + padding-top: 0.25rem !important; + } + + .pr-xl-1, + .px-xl-1 { + padding-right: 0.25rem !important; + } + + .pb-xl-1, + .py-xl-1 { + padding-bottom: 0.25rem !important; + } + + .pl-xl-1, + .px-xl-1 { + padding-left: 0.25rem !important; + } + + .p-xl-2 { + padding: 0.5rem !important; + } + + .pt-xl-2, + .py-xl-2 { + padding-top: 0.5rem !important; + } + + .pr-xl-2, + .px-xl-2 { + padding-right: 0.5rem !important; + } + + .pb-xl-2, + .py-xl-2 { + padding-bottom: 0.5rem !important; + } + + .pl-xl-2, + .px-xl-2 { + padding-left: 0.5rem !important; + } + + .p-xl-3 { + padding: 1rem !important; + } + + .pt-xl-3, + .py-xl-3 { + padding-top: 1rem !important; + } + + .pr-xl-3, + .px-xl-3 { + padding-right: 1rem !important; + } + + .pb-xl-3, + .py-xl-3 { + padding-bottom: 1rem !important; + } + + .pl-xl-3, + .px-xl-3 { + padding-left: 1rem !important; + } + + .p-xl-4 { + padding: 1.5rem !important; + } + + .pt-xl-4, + .py-xl-4 { + padding-top: 1.5rem !important; + } + + .pr-xl-4, + .px-xl-4 { + padding-right: 1.5rem !important; + } + + .pb-xl-4, + .py-xl-4 { + padding-bottom: 1.5rem !important; + } + + .pl-xl-4, + .px-xl-4 { + padding-left: 1.5rem !important; + } + + .p-xl-5 { + padding: 3rem !important; + } + + .pt-xl-5, + .py-xl-5 { + padding-top: 3rem !important; + } + + .pr-xl-5, + .px-xl-5 { + padding-right: 3rem !important; + } + + .pb-xl-5, + .py-xl-5 { + padding-bottom: 3rem !important; + } + + .pl-xl-5, + .px-xl-5 { + padding-left: 3rem !important; + } + + .m-xl-auto { + margin: auto !important; + } + + .mt-xl-auto, + .my-xl-auto { + margin-top: auto !important; + } + + .mr-xl-auto, + .mx-xl-auto { + margin-right: auto !important; + } + + .mb-xl-auto, + .my-xl-auto { + margin-bottom: auto !important; + } + + .ml-xl-auto, + .mx-xl-auto { + margin-left: auto !important; + } +} +.text-justify { + text-align: justify !important; +} + +.text-nowrap { + white-space: nowrap !important; +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text-left { + text-align: left !important; +} + +.text-right { + text-align: right !important; +} + +.text-center { + text-align: center !important; +} + +@media (min-width: 576px) { + .text-sm-left { + text-align: left !important; + } + + .text-sm-right { + text-align: right !important; + } + + .text-sm-center { + text-align: center !important; + } +} +@media (min-width: 768px) { + .text-md-left { + text-align: left !important; + } + + .text-md-right { + text-align: right !important; + } + + .text-md-center { + text-align: center !important; + } +} +@media (min-width: 992px) { + .text-lg-left { + text-align: left !important; + } + + .text-lg-right { + text-align: right !important; + } + + .text-lg-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .text-xl-left { + text-align: left !important; + } + + .text-xl-right { + text-align: right !important; + } + + .text-xl-center { + text-align: center !important; + } +} +.text-lowercase { + text-transform: lowercase !important; +} + +.text-uppercase { + text-transform: uppercase !important; +} + +.text-capitalize { + text-transform: capitalize !important; +} + +.font-weight-light { + font-weight: 300 !important; +} + +.font-weight-normal { + font-weight: 400 !important; +} + +.font-weight-bold { + font-weight: 700 !important; +} + +.font-italic { + font-style: italic !important; +} + +.text-white { + color: #fff !important; +} + +.text-primary { + color: #007bff !important; +} + +a.text-primary:hover, a.text-primary:focus { + color: #0062cc !important; +} + +.text-secondary { + color: #6c757d !important; +} + +a.text-secondary:hover, a.text-secondary:focus { + color: #545b62 !important; +} + +.text-success { + color: #28a745 !important; +} + +a.text-success:hover, a.text-success:focus { + color: #1e7e34 !important; +} + +.text-info { + color: #17a2b8 !important; +} + +a.text-info:hover, a.text-info:focus { + color: #117a8b !important; +} + +.text-warning { + color: #ffc107 !important; +} + +a.text-warning:hover, a.text-warning:focus { + color: #d39e00 !important; +} + +.text-danger { + color: #dc3545 !important; +} + +a.text-danger:hover, a.text-danger:focus { + color: #bd2130 !important; +} + +.text-light { + color: #f8f9fa !important; +} + +a.text-light:hover, a.text-light:focus { + color: #dae0e5 !important; +} + +.text-dark { + color: #343a40 !important; +} + +a.text-dark:hover, a.text-dark:focus { + color: #1d2124 !important; +} + +.text-muted { + color: #6c757d !important; +} + +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.visible { + visibility: visible !important; +} + +.invisible { + visibility: hidden !important; +} + +@media print { + *, + *::before, + *::after { + text-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + + a:not(.btn) { + text-decoration: underline; + } + + abbr[title]::after { + content: " (" attr(title) ")"; + } + + pre { + white-space: pre-wrap !important; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + thead { + display: table-header-group; + } + + tr, + img { + page-break-inside: avoid; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } + + @page { + size: a3; + } + body { + min-width: 992px !important; + } + + .container { + min-width: 992px !important; + } + + .navbar { + display: none; + } + + .badge { + border: 1px solid #000; + } + + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +/*Github syntax highlighting theme via Rouge*/ +.highlight table td { + padding: 5px; +} + +.highlight table pre { + margin: 0; +} + +.highlight .cm { + color: #999988; + font-style: italic; +} + +.highlight .cp { + color: #999999; + font-weight: bold; +} + +.highlight .c1 { + color: #999988; + font-style: italic; +} + +.highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; +} + +.highlight .c, .highlight .cd { + color: #999988; + font-style: italic; +} + +.highlight .err { + color: #a61717; + background-color: #e3d2d2; +} + +.highlight .gd { + color: #000000; + background-color: #ffdddd; +} + +.highlight .ge { + color: #000000; + font-style: italic; +} + +.highlight .gr { + color: #aa0000; +} + +.highlight .gh { + color: #999999; +} + +.highlight .gi { + color: #000000; + background-color: #ddffdd; +} + +.highlight .go { + color: #888888; +} + +.highlight .gp { + color: #555555; +} + +.highlight .gs { + font-weight: bold; +} + +.highlight .gu { + color: #aaaaaa; +} + +.highlight .gt { + color: #aa0000; +} + +.highlight .kc { + color: #000000; + font-weight: bold; +} + +.highlight .kd { + color: #000000; + font-weight: bold; +} + +.highlight .kn { + color: #000000; + font-weight: bold; +} + +.highlight .kp { + color: #000000; + font-weight: bold; +} + +.highlight .kr { + color: #000000; + font-weight: bold; +} + +.highlight .kt { + color: #445588; + font-weight: bold; +} + +.highlight .k, .highlight .kv { + color: #000000; + font-weight: bold; +} + +.highlight .mf { + color: #009999; +} + +.highlight .mh { + color: #009999; +} + +.highlight .il { + color: #009999; +} + +.highlight .mi { + color: #009999; +} + +.highlight .mo { + color: #009999; +} + +.highlight .m, .highlight .mb, .highlight .mx { + color: #009999; +} + +.highlight .sb { + color: #d14; +} + +.highlight .sc { + color: #d14; +} + +.highlight .sd { + color: #d14; +} + +.highlight .s2 { + color: #d14; +} + +.highlight .se { + color: #d14; +} + +.highlight .sh { + color: #d14; +} + +.highlight .si { + color: #d14; +} + +.highlight .sx { + color: #d14; +} + +.highlight .sr { + color: #009926; +} + +.highlight .s1 { + color: #d14; +} + +.highlight .ss { + color: #990073; +} + +.highlight .s { + color: #d14; +} + +.highlight .na { + color: #008080; +} + +.highlight .bp { + color: #525252; +} + +.highlight .nb { + color: #0086B3; +} + +.highlight .nc { + color: #445588; + font-weight: bold; +} + +.highlight .no { + color: #008080; +} + +.highlight .nd { + color: #3c5d5d; + font-weight: bold; +} + +.highlight .ni { + color: #800080; +} + +.highlight .ne { + color: #990000; + font-weight: bold; +} + +.highlight .nf { + color: #990000; + font-weight: bold; +} + +.highlight .nl { + color: #990000; + font-weight: bold; +} + +.highlight .nn { + color: #555555; +} + +.highlight .nt { + color: #000080; +} + +.highlight .vc { + color: #008080; +} + +.highlight .vg { + color: #008080; +} + +.highlight .vi { + color: #008080; +} + +.highlight .nv { + color: #008080; +} + +.highlight .ow { + color: #000000; + font-weight: bold; +} + +.highlight .o { + color: #000000; + font-weight: bold; +} + +.highlight .n { + color: #000000; + font-weight: bold; +} + +.highlight .p { + color: #000000; + font-weight: bold; +} + +.highlight .w { + color: #bbbbbb; +} + +.highlight { + background-color: #f8f8f8; +} + +@font-face { + font-family: FreightSans; + font-weight: 700; + font-style: normal; + src: url("../fonts/FreightSans/freight-sans-bold.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-bold.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 700; + font-style: italic; + src: url("../fonts/FreightSans/freight-sans-bold-italic.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-bold-italic.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 500; + font-style: normal; + src: url("../fonts/FreightSans/freight-sans-medium.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-medium.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 500; + font-style: italic; + src: url("../fonts/FreightSans/freight-sans-medium-italic.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-medium-italic.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 100; + font-style: normal; + src: url("../fonts/FreightSans/freight-sans-light.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-light.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 100; + font-style: italic; + src: url("../fonts/FreightSans/freight-sans-light-italic.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-light-italic.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 400; + font-style: italic; + src: url("../fonts/FreightSans/freight-sans-book-italic.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-book-italic.woff") format("woff"); +} +@font-face { + font-family: FreightSans; + font-weight: 400; + font-style: normal; + src: url("../fonts/FreightSans/freight-sans-book.woff2") format("woff2"), url("../fonts/FreightSans/freight-sans-book.woff") format("woff"); +} +@font-face { + font-family: IBMPlexMono; + font-weight: 600; + font-style: normal; + unicode-range: u+0020-007f; + src: local("IBMPlexMono-SemiBold"), url("../fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff2") format("woff2"), url("../fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff") format("woff"); +} +@font-face { + font-family: IBMPlexMono; + font-weight: 500; + font-style: normal; + unicode-range: u+0020-007f; + src: local("IBMPlexMono-Medium"), url("../fonts/IBMPlexMono/IBMPlexMono-Medium.woff2") format("woff2"), url("../fonts/IBMPlexMono/IBMPlexMono-Medium.woff") format("woff"); +} +@font-face { + font-family: IBMPlexMono; + font-weight: 400; + font-style: normal; + unicode-range: u+0020-007f; + src: local("IBMPlexMono-Regular"), url("../fonts/IBMPlexMono/IBMPlexMono-Regular.woff2") format("woff2"), url("../fonts/IBMPlexMono/IBMPlexMono-Regular.woff") format("woff"); +} +@font-face { + font-family: IBMPlexMono; + font-weight: 300; + font-style: normal; + unicode-range: u+0020-007f; + src: local("IBMPlexMono-Light"), url("../fonts/IBMPlexMono/IBMPlexMono-Light.woff2") format("woff2"), url("../fonts/IBMPlexMono/IBMPlexMono-Light.woff") format("woff"); +} +html { + position: relative; + min-height: 100%; + font-size: 12px; +} +@media screen and (min-width: 768px) { + html { + font-size: 16px; + } +} + +* { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +body { + font-family: FreightSans, Helvetica Neue, Helvetica, Arial, sans-serif; +} + +a:link, +a:visited, +a:hover { + text-decoration: none; + color: #e44c2c; +} + +a.with-right-arrow, .btn.with-right-arrow { + padding-right: 1.375rem; + position: relative; + background-image: url("../images/chevron-right-orange.svg"); + background-size: 6px 13px; + background-position: center right 5px; + background-repeat: no-repeat; +} +@media screen and (min-width: 768px) { + a.with-right-arrow, .btn.with-right-arrow { + background-size: 8px 14px; + background-position: center right 12px; + padding-right: 2rem; + } +} + +::-webkit-input-placeholder { + color: #e44c2c; +} + +::-moz-placeholder { + color: #e44c2c; +} + +:-ms-input-placeholder { + color: #e44c2c; +} + +:-moz-placeholder { + color: #e44c2c; +} + +.email-subscribe-form input.email { + color: #e44c2c; + border: none; + border-bottom: 1px solid #939393; + width: 100%; + background-color: transparent; + outline: none; + font-size: 1.125rem; + letter-spacing: 0.25px; + line-height: 2.25rem; +} +.email-subscribe-form input[type="submit"] { + position: absolute; + right: 0; + top: 10px; + height: 15px; + width: 15px; + background-image: url("../images/arrow-right-with-tail.svg"); + background-color: transparent; + background-repeat: no-repeat; + background-size: 15px 15px; + background-position: center center; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border: 0; +} + +.email-subscribe-form-fields-wrapper { + position: relative; +} + +.anchorjs-link { + color: #6c6c6d !important; +} +@media screen and (min-width: 768px) { + .anchorjs-link:hover { + color: inherit; + text-decoration: none !important; + } +} + +.pytorch-article #table-of-contents { + display: none; +} + +code, kbd, pre, samp { + font-family: IBMPlexMono,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; +} +code span, kbd span, pre span, samp span { + font-family: IBMPlexMono,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; +} + +pre { + padding: 1.125rem; +} +pre code { + font-size: 0.875rem; +} +pre.highlight { + background-color: #f3f4f7; + line-height: 1.3125rem; +} + +code.highlighter-rouge { + color: #6c6c6d; + background-color: #f3f4f7; + padding: 2px 6px; +} + +a:link code.highlighter-rouge, +a:visited code.highlighter-rouge, +a:hover code.highlighter-rouge { + color: #4974D1; +} +a:link.has-code, +a:visited.has-code, +a:hover.has-code { + color: #4974D1; +} + +p code, +h1 code, +h2 code, +h3 code, +h4 code, +h5 code, +h6 code { + font-size: 78.5%; +} + +pre { + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; +} + +.header-holder { + height: 68px; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + left: 0; + margin-left: auto; + margin-right: auto; + position: fixed; + right: 0; + top: 0; + width: 100%; + z-index: 9999; + background-color: #ffffff; + border-bottom: 1px solid #e2e2e2; +} +@media screen and (min-width: 1100px) { + .header-holder { + height: 90px; + } +} + +.header-container { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.header-container:before, .header-container:after { + content: ""; + display: table; +} +.header-container:after { + clear: both; +} +.header-container { + *zoom: 1; +} +@media screen and (min-width: 1100px) { + .header-container { + display: block; + } +} + +.header-logo { + height: 23px; + width: 93px; + background-image: url("../images/logo.svg"); + background-repeat: no-repeat; + background-size: 93px 23px; + display: block; + float: left; + z-index: 10; +} +@media screen and (min-width: 1100px) { + .header-logo { + background-size: 108px 27px; + position: absolute; + height: 27px; + width: 108px; + top: 4px; + float: none; + } +} + +.main-menu-open-button { + background-image: url("../images/icon-menu-dots.svg"); + background-position: center center; + background-size: 25px 7px; + background-repeat: no-repeat; + width: 25px; + height: 17px; + position: absolute; + right: 0; + top: 4px; +} +@media screen and (min-width: 1100px) { + .main-menu-open-button { + display: none; + } +} + +.header-holder .main-menu { + display: none; +} +@media screen and (min-width: 1100px) { + .header-holder .main-menu { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + } +} +.header-holder .main-menu ul { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + margin: 0; +} +.header-holder .main-menu ul li { + display: inline-block; + margin-right: 40px; + position: relative; +} +.header-holder .main-menu ul li.active:after { + content: "•"; + bottom: -24px; + color: #e44c2c; + font-size: 1.375rem; + left: 0; + position: absolute; + right: 0; + text-align: center; +} +.header-holder .main-menu ul li.active a { + color: #e44c2c; +} +.header-holder .main-menu ul li.docs-active:after { + content: "•"; + bottom: -24px; + color: #e44c2c; + font-size: 1.375rem; + left: -24px; + position: absolute; + right: 0; + text-align: center; +} +.header-holder .main-menu ul li:last-of-type { + margin-right: 0; +} +.header-holder .main-menu ul li a { + color: #ffffff; + font-size: 1.3rem; + letter-spacing: 0; + line-height: 2.125rem; + text-align: center; + text-decoration: none; +} +@media screen and (min-width: 1100px) { + .header-holder .main-menu ul li a:hover { + color: #e44c2c; + } +} + +.mobile-main-menu { + display: none; +} +.mobile-main-menu.open { + background-color: #262626; + display: block; + height: 100%; + left: 0; + margin-left: auto; + margin-right: auto; + min-height: 100%; + position: fixed; + right: 0; + top: 0; + width: 100%; + z-index: 99999; +} + +.mobile-main-menu .container-fluid { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + height: 68px; + position: relative; +} +.mobile-main-menu .container-fluid:before, .mobile-main-menu .container-fluid:after { + content: ""; + display: table; +} +.mobile-main-menu .container-fluid:after { + clear: both; +} +.mobile-main-menu .container-fluid { + *zoom: 1; +} + +.mobile-main-menu.open ul { + list-style-type: none; + padding: 0; +} +.mobile-main-menu.open ul li a, .mobile-main-menu.open .resources-mobile-menu-title { + font-size: 2rem; + color: #ffffff; + letter-spacing: 0; + line-height: 4rem; + text-decoration: none; +} +.mobile-main-menu.open ul li.active a { + color: #e44c2c; +} + +.main-menu-close-button { + background-image: url("../images/icon-close.svg"); + background-position: center center; + background-repeat: no-repeat; + background-size: 24px 24px; + height: 24px; + position: absolute; + right: 0; + width: 24px; + top: -4px; +} + +.mobile-main-menu-header-container { + position: relative; +} + +.mobile-main-menu-links-container { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding-left: 2.8125rem; + height: 90vh; + margin-top: -25px; + padding-top: 50%; + overflow-y: scroll; +} +.mobile-main-menu-links-container .main-menu { + height: 100vh; +} + +.mobile-main-menu-links-container ul.resources-mobile-menu-items li { + padding-left: 15px; +} + +.site-footer { + padding: 2.5rem 0; + width: 100%; + background: #000000; + background-size: 100%; + margin-left: 0; + margin-right: 0; + position: relative; + z-index: 201; +} +@media screen and (min-width: 768px) { + .site-footer { + padding: 5rem 0; + } +} + +.site-footer p { + color: #ffffff; +} +.site-footer ul { + list-style-type: none; + padding-left: 0; + margin-bottom: 0; +} + +.site-footer ul li { + font-size: 1.125rem; + line-height: 2rem; + color: #A0A0A1; + padding-bottom: 0.375rem; +} +.site-footer ul li.list-title { + padding-bottom: 0.75rem; + color: #ffffff; +} +.site-footer a:link, +.site-footer a:visited { + color: inherit; +} +@media screen and (min-width: 768px) { + .site-footer a:hover { + color: #e44c2c; + } +} + +.site-footer .privacy-policy { + background: #000000; + display: flex; + border-bottom: 1px solid white; + padding-bottom: 10px; +} + +.site-footer .privacy-policy-links { + background: #000000; + display: flex; + padding-top: 1rem; + padding-right: 1rem; + display: inline-flex; + color: white; +} + +.site-footer .footer-links-wrapper { + display: flex; + flex-wrap: wrap; + border-bottom: 1px solid white; + padding-bottom: 1rem; +} + +.site-footer .copyright { + padding-top: 1rem; + padding-right: 1rem; + display: inline-flex; + color: white; +} + +.site-footer .copyright p { + color: white; +} + +.site-footer .copyright a { + color: red; +} + +.docs-tutorials-resources { + background-color: #262626; + color: #ffffff; + padding-top: 2.5rem; + padding-bottom: 2.5rem; + position: relative; + z-index: 201; +} +@media screen and (min-width: 768px) { + .docs-tutorials-resources { + padding-top: 5rem; + padding-bottom: 5rem; + } +} +.docs-tutorials-resources p { + color: #929292; + font-size: 1.125rem; +} +.docs-tutorials-resources h2 { + font-size: 1.5rem; + letter-spacing: -0.25px; + text-transform: none; + margin-bottom: 0.25rem; +} +@media screen and (min-width: 768px) { + .docs-tutorials-resources h2 { + margin-bottom: 1.25rem; + } +} +.docs-tutorials-resources .col-md-4 { + margin-bottom: 2rem; + text-align: center; +} +@media screen and (min-width: 768px) { + .docs-tutorials-resources .col-md-4 { + margin-bottom: 0; + } +} +.docs-tutorials-resources .with-right-arrow { + margin-left: 12px; +} +.docs-tutorials-resources .with-right-arrow:hover { + background-image: url("../images/chevron-right-white.svg"); +} +.docs-tutorials-resources p { + font-size: 1rem; + line-height: 1.5rem; + letter-spacing: 0.22px; + color: #939393; + margin-bottom: 0; +} +@media screen and (min-width: 768px) { + .docs-tutorials-resources p { + margin-bottom: 1.25rem; + } +} +.docs-tutorials-resources a { + font-size: 1.125rem; + color: #e44c2c; +} +.docs-tutorials-resources a:hover { + color: #ffffff; +} + +.footer-container { + position: relative; +} + +@media screen and (min-width: 768px) { + .footer-logo-wrapper { + position: absolute; + top: 0; + left: 30px; + } +} + +.footer-logo { + background-image: url("../images/logo-icon.svg"); + background-position: center; + background-repeat: no-repeat; + background-size: 20px 24px; + display: block; + height: 24px; + margin-bottom: 2.8125rem; + width: 20px; +} +@media screen and (min-width: 768px) { + .footer-logo { + background-size: 29px 36px; + height: 36px; + margin-bottom: 0; + margin-bottom: 0; + width: 29px; + } +} + +.footer-links-wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} +@media screen and (min-width: 768px) { + .footer-links-wrapper { + -ms-flex-wrap: initial; + flex-wrap: initial; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + } +} + +.footer-links-col { + margin-bottom: 3.75rem; + width: 50%; +} +@media screen and (min-width: 768px) { + .footer-links-col { + margin-bottom: 0; + width: 14%; + margin-right: 23px; + } + .footer-links-col.follow-us-col { + width: 18%; + margin-right: 0; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + .footer-links-col { + width: 18%; + margin-right: 30px; + } +} + +.footer-social-icons { + margin: 8.5625rem 0 2.5rem 0; +} +.footer-social-icons a { + height: 32px; + width: 32px; + display: inline-block; + background-color: #CCCDD1; + border-radius: 50%; + margin-right: 5px; +} +.footer-social-icons a.facebook { + background-image: url("../images/logo-facebook-dark.svg"); + background-position: center center; + background-size: 9px 18px; + background-repeat: no-repeat; +} +.footer-social-icons a.twitter { + background-image: url("../images/logo-twitter-dark.svg"); + background-position: center center; + background-size: 17px 17px; + background-repeat: no-repeat; +} +.footer-social-icons a.youtube { + background-image: url("../images/logo-youtube-dark.svg"); + background-position: center center; + background-repeat: no-repeat; +} + +.site-footer .mc-field-group { + margin-top: -2px; +} + +article.pytorch-article { + max-width: 920px; + margin: 0 auto; +} +article.pytorch-article h2, +article.pytorch-article h3, +article.pytorch-article h4, +article.pytorch-article h5, +article.pytorch-article h6 { + margin: 1.375rem 0; + color: #262626; +} +article.pytorch-article h2 { + font-size: 1.625rem; + letter-spacing: 1.33px; + line-height: 2rem; + text-transform: none; +} +article.pytorch-article h3 { + font-size: 1.5rem; + letter-spacing: -0.25px; + line-height: 1.875rem; + text-transform: none; +} +article.pytorch-article h4, +article.pytorch-article h5, +article.pytorch-article h6 { + font-size: 1.125rem; + letter-spacing: -0.19px; + line-height: 1.875rem; +} +article.pytorch-article p { + margin-bottom: 1.125rem; +} +article.pytorch-article p, +article.pytorch-article ul li, +article.pytorch-article ol li, +article.pytorch-article dl dt, +article.pytorch-article dl dd, +article.pytorch-article blockquote { + font-size: 1rem; + line-height: 1.375rem; + color: #262626; + letter-spacing: 0.01px; + font-weight: 500; +} +article.pytorch-article table { + margin-bottom: 2.5rem; + width: 100%; +} +article.pytorch-article table thead { + border-bottom: 1px solid #cacaca; +} +article.pytorch-article table th { + padding: 0.625rem; + color: #262626; +} +article.pytorch-article table td { + padding: 0.3125rem; +} +article.pytorch-article table tr th:first-of-type, +article.pytorch-article table tr td:first-of-type { + padding-left: 0; +} +article.pytorch-article table.docutils.field-list th.field-name { + padding: 0.3125rem; + padding-left: 0; +} +article.pytorch-article table.docutils.field-list td.field-body { + padding: 0.3125rem; +} +article.pytorch-article table.docutils.field-list td.field-body p:last-of-type { + margin-bottom: 0; +} +article.pytorch-article ul, +article.pytorch-article ol { + margin: 1.5rem 0 3.125rem 0; +} +@media screen and (min-width: 768px) { + article.pytorch-article ul, + article.pytorch-article ol { + padding-left: 6.25rem; + } +} +article.pytorch-article ul li, +article.pytorch-article ol li { + margin-bottom: 0.625rem; +} +article.pytorch-article dl { + margin-bottom: 1.5rem; +} +article.pytorch-article dl dt { + margin-bottom: 0.75rem; +} +article.pytorch-article pre { + margin-bottom: 2.5rem; +} +article.pytorch-article hr { + margin-top: 4.6875rem; + margin-bottom: 4.6875rem; +} +article.pytorch-article blockquote { + margin: 0 auto; + margin-bottom: 2.5rem; + width: 65%; +} +article.pytorch-article img { + width: 100%; +} + +html { + height: 100%; +} +@media screen and (min-width: 768px) { + html { + font-size: 16px; + } +} + +body { + background: #ffffff; + height: 100%; + margin: 0; +} +body.no-scroll { + height: 100%; + overflow: hidden; +} + +p { + margin-top: 0; + margin-bottom: 1.125rem; +} +p a:link, +p a:visited, +p a:hover { + color: #e44c2c; + text-decoration: none; +} +@media screen and (min-width: 768px) { + p a:hover { + text-decoration: underline; + } +} +p a:link, +p a:visited, +p a:hover { + color: #ee4c2c; +} + +.wy-breadcrumbs li a { + color: #ee4c2c; +} + +ul.pytorch-breadcrumbs { + padding-left: 0; + list-style-type: none; +} +ul.pytorch-breadcrumbs li { + display: inline-block; + font-size: 0.875rem; +} +ul.pytorch-breadcrumbs a { + color: #ee4c2c; + text-decoration: none; +} + +.table-of-contents-link-wrapper { + display: block; + margin-top: 0; + padding: 1.25rem 1.875rem; + background-color: #f3f4f7; + position: relative; + color: #262626; + font-size: 1.25rem; +} +.table-of-contents-link-wrapper.is-open .toggle-table-of-contents { + -webkit-transform: rotate(180deg); + transform: rotate(180deg); +} +@media screen and (min-width: 1100px) { + .table-of-contents-link-wrapper { + display: none; + } +} + +.toggle-table-of-contents { + background-image: url("../images/chevron-down-grey.svg"); + background-position: center center; + background-repeat: no-repeat; + background-size: 18px 18px; + height: 100%; + position: absolute; + right: 21px; + width: 30px; + top: 0; +} + +.tutorials-header .header-logo { + background-image: url("../images/logo-dark.svg"); +} +.tutorials-header .main-menu ul li a { + color: #262626; +} +.tutorials-header .main-menu-open-button { + background-image: url("../images/icon-menu-dots-dark.svg"); +} + +.rst-content footer .rating-hr.hr-top { + margin-bottom: -0.0625rem; +} +.rst-content footer .rating-hr.hr-bottom { + margin-top: -0.0625rem; +} +.rst-content footer .rating-container { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + font-size: 1.125rem; +} +.rst-content footer .rating-container .rating-prompt, .rst-content footer .rating-container .was-helpful-thank-you { + padding: 0.625rem 1.25rem 0.625rem 1.25rem; +} +.rst-content footer .rating-container .was-helpful-thank-you { + display: none; +} +.rst-content footer .rating-container .rating-prompt.yes-link, .rst-content footer .rating-container .rating-prompt.no-link { + color: #e44c2c; + cursor: pointer; +} +.rst-content footer .rating-container .rating-prompt.yes-link:hover, .rst-content footer .rating-container .rating-prompt.no-link:hover { + background-color: #e44c2c; + color: #ffffff; +} +.rst-content footer .rating-container .stars-outer { + display: inline-block; + position: relative; + font-family: FontAwesome; + padding: 0.625rem 1.25rem 0.625rem 1.25rem; +} +.rst-content footer .rating-container .stars-outer i { + cursor: pointer; +} +.rst-content footer .rating-container .stars-outer .star-fill { + color: #ee4c2c; +} +.rst-content footer div[role="contentinfo"] { + padding-top: 2.5rem; +} +.rst-content footer div[role="contentinfo"] p { + margin-bottom: 0; +} + +h1 { + font-size: 2rem; + letter-spacing: 1.78px; + line-height: 2.5rem; + margin: 1.375rem 0; +} + +span.pre { + color: #6c6c6d; + background-color: #f3f4f7; + padding: 2px 0px; +} + +pre { + padding: 1.375rem; +} + +.highlight .c1 { + color: #6c6c6d; +} + +.headerlink { + display: none !important; +} + +a:link.has-code, +a:hover.has-code, +a:visited.has-code { + color: #4974D1; +} +a:link.has-code span, +a:hover.has-code span, +a:visited.has-code span { + color: #4974D1; +} + +article.pytorch-article ul, +article.pytorch-article ol { + padding-left: 1.875rem; + margin: 0; +} +article.pytorch-article ul li, +article.pytorch-article ol li { + margin: 0; + line-height: 1.75rem; +} +article.pytorch-article ul p, +article.pytorch-article ol p { + line-height: 1.75rem; + margin-bottom: 0; +} +article.pytorch-article ul ul, +article.pytorch-article ul ol, +article.pytorch-article ol ul, +article.pytorch-article ol ol { + margin: 0; +} +article.pytorch-article h1 { + font-weight: 600; +} +article.pytorch-article h2, +article.pytorch-article h3, +article.pytorch-article h4, +article.pytorch-article h5, +article.pytorch-article h6 { + font-weight: normal; +} +article.pytorch-article h1 a, +article.pytorch-article h2 a, +article.pytorch-article h3 a, +article.pytorch-article h4 a, +article.pytorch-article h5 a, +article.pytorch-article h6 a { + color: #262626; +} +article.pytorch-article p.caption { + margin-top: 1.25rem; +} + +article.pytorch-article .section:first-of-type h1:first-of-type { + margin-top: 0; +} + +article.pytorch-article .sphx-glr-thumbcontainer { + margin: 0; + border: 1px solid #d6d7d8; + border-radius: 0; + width: 45%; + text-align: center; + margin-bottom: 5%; +} +@media screen and (max-width: 1100px) { + article.pytorch-article .sphx-glr-thumbcontainer:nth-child(odd) { + margin-left: 0; + margin-right: 2.5%; + } + article.pytorch-article .sphx-glr-thumbcontainer:nth-child(even) { + margin-right: 0; + margin-left: 2.5%; + } + article.pytorch-article .sphx-glr-thumbcontainer .figure { + width: 40%; + } +} +@media screen and (min-width: 1101px) { + article.pytorch-article .sphx-glr-thumbcontainer { + margin-right: 3%; + margin-bottom: 3%; + width: 30%; + } +} +article.pytorch-article .sphx-glr-thumbcontainer .caption-text a { + font-size: 1rem; + color: #262626; + letter-spacing: 0; + line-height: 1.5rem; + text-decoration: none; +} +article.pytorch-article .sphx-glr-thumbcontainer:hover { + -webkit-box-shadow: none; + box-shadow: none; + border-bottom-color: #ffffff; +} +article.pytorch-article .sphx-glr-thumbcontainer:hover .figure:before { + bottom: 100%; +} +article.pytorch-article .sphx-glr-thumbcontainer .figure { + width: 80%; +} +article.pytorch-article .sphx-glr-thumbcontainer .figure:before { + content: ""; + display: block; + position: absolute; + top: 0; + bottom: 35%; + left: 0; + right: 0; + background: #8A94B3; + opacity: 0.10; +} +article.pytorch-article .sphx-glr-thumbcontainer .figure a.reference.internal { + text-align: left; +} +@media screen and (min-width: 768px) { + article.pytorch-article .sphx-glr-thumbcontainer:after { + content: ""; + display: block; + width: 0; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + background-color: #e44c2c; + -webkit-transition: width .250s ease-in-out; + transition: width .250s ease-in-out; + } + article.pytorch-article .sphx-glr-thumbcontainer:hover:after { + width: 100%; + } +} +@media screen and (min-width: 768px) { + article.pytorch-article .sphx-glr-thumbcontainer:after { + background-color: #ee4c2c; + } +} + +article.pytorch-article .section :not(dt) > code { + color: #262626; + border-top: solid 2px #ffffff; + background-color: #ffffff; + border-bottom: solid 2px #ffffff; + padding: 0px 3px; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; +} +article.pytorch-article .section :not(dt) > code .pre { + outline: 0px; + padding: 0px; +} +article.pytorch-article .function dt, article.pytorch-article .attribute dt, article.pytorch-article .class .attribute dt, article.pytorch-article .class dt { + position: relative; + background: #f3f4f7; + padding: 0.5rem; + border-left: 3px solid #ee4c2c; + word-wrap: break-word; + padding-right: 100px; +} + +article.pytorch-article .class dt.field-odd, article.pytorch-article .class dt.field-even, +article.pytorch-article .function dt.field-odd, article.pytorch-article .function dt.field-even, +article.pytorch-article .attribute dt.field-odd, article.pytorch-article .attribute dt.field-even, +article.pytorch-article .class .attribute dt.field-odd,article.pytorch-article .class .attribute dt.field-even, +article.pytorch-article .class .method dt.field-odd, article.pytorch-article .class .staticmethod dt.field-odd, +article.pytorch-article .class .method dt.field-even, article.pytorch-article .class .staticmethod dt.field-even +{ + background: none; + padding-right: -20px; + border-top: none; + border-left: none; + padding-left: 0.0rem; + padding-top: 0.0rem; + padding-bottom: 0.0rem; + font-weight: 700; +} + +article.pytorch-article .function dt.sig { + position: relative; + background: #f3f4f7; + padding: 0.8rem; + border-left: 3px solid #ee4c2c; + word-wrap: break-word; + padding-right: 100px; + font-weight: 500; +} + +article.pytorch-article .function dt { + background: #ffffff; + padding-right: -20px; + border-left: none; + border-top: none; + padding-left: 0.0rem; + padding-top: 0.0rem; + padding-bottom: 0.0rem; + font-weight: 700; +} + +article.pytorch-article .function dt em.property, article.pytorch-article .attribute dt em.property, article.pytorch-article .class dt em.property { + font-family: inherit; +} +article.pytorch-article .function dt em, article.pytorch-article .attribute dt em, article.pytorch-article .class .attribute dt em, article.pytorch-article .class dt em, article.pytorch-article .function dt .sig-paren, article.pytorch-article .attribute dt .sig-paren, article.pytorch-article .class dt .sig-paren { + font-family: IBMPlexMono,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; + font-size: 87.5%; +} +article.pytorch-article .function dt a, article.pytorch-article .attribute dt a, article.pytorch-article .class .attribute dt a, article.pytorch-article .class dt a { + right: 30px; + padding-right: 0; + top: 50%; + -webkit-transform: perspective(1px) translateY(-50%); + transform: perspective(1px) translateY(-50%); +} +article.pytorch-article .function dt:hover .viewcode-link, article.pytorch-article .attribute dt:hover .viewcode-link, article.pytorch-article .class dt:hover .viewcode-link { + color: #ee4c2c; +} +article.pytorch-article .function .anchorjs-link, article.pytorch-article .attribute .anchorjs-link, article.pytorch-article .class .anchorjs-link { + display: inline; + position: absolute; + right: 8px; + font-size: 1.5625rem !important; + padding-left: 0; +} +article.pytorch-article .function dt > code, article.pytorch-article .attribute dt > code, article.pytorch-article .class .attribute dt > code, article.pytorch-article .class dt > code { + color: #262626; + border-top: solid 2px #f3f4f7; + background-color: #f3f4f7; + border-bottom: solid 2px #f3f4f7; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; +} +article.pytorch-article .function .viewcode-link, article.pytorch-article .attribute .viewcode-link, article.pytorch-article .class .viewcode-link { + padding-left: 0.6rem; + position: absolute; + font-size: 0.875rem; + color: #979797; + letter-spacing: 0; + line-height: 1.5rem; + text-transform: uppercase; +} +article.pytorch-article .function dd, article.pytorch-article .attribute dd, article.pytorch-article .class .attribute dd, article.pytorch-article .class dd { + padding-left: 3.75rem; +} +article.pytorch-article .function dd p, article.pytorch-article .attribute dd p, article.pytorch-article .class .attribute dd p, article.pytorch-article .class dd p { + color: #262626; +} +article.pytorch-article .function table tbody tr th.field-name, article.pytorch-article .attribute table tbody tr th.field-name, article.pytorch-article .class table tbody tr th.field-name { + white-space: nowrap; + color: #262626; + width: 20%; +} +@media screen and (min-width: 768px) { + article.pytorch-article .function table tbody tr th.field-name, article.pytorch-article .attribute table tbody tr th.field-name, article.pytorch-article .class table tbody tr th.field-name { + width: 15%; + } +} +article.pytorch-article .function table tbody tr td.field-body, article.pytorch-article .attribute table tbody tr td.field-body, article.pytorch-article .class table tbody tr td.field-body { + padding: 0.625rem; + width: 80%; + color: #262626; +} +@media screen and (min-width: 768px) { + article.pytorch-article .function table tbody tr td.field-body, article.pytorch-article .attribute table tbody tr td.field-body, article.pytorch-article .class table tbody tr td.field-body { + width: 85%; + } +} +@media screen and (min-width: 1600px) { + article.pytorch-article .function table tbody tr td.field-body, article.pytorch-article .attribute table tbody tr td.field-body, article.pytorch-article .class table tbody tr td.field-body { + padding-left: 1.25rem; + } +} +article.pytorch-article .function table tbody tr td.field-body p, article.pytorch-article .attribute table tbody tr td.field-body p, article.pytorch-article .class table tbody tr td.field-body p { + padding-left: 0px; +} +article.pytorch-article .function table tbody tr td.field-body p:last-of-type, article.pytorch-article .attribute table tbody tr td.field-body p:last-of-type, article.pytorch-article .class table tbody tr td.field-body p:last-of-type { + margin-bottom: 0; +} +article.pytorch-article .function table tbody tr td.field-body ol, article.pytorch-article .attribute table tbody tr td.field-body ol, article.pytorch-article .class table tbody tr td.field-body ol, article.pytorch-article .function table tbody tr td.field-body ul, article.pytorch-article .attribute table tbody tr td.field-body ul, article.pytorch-article .class table tbody tr td.field-body ul { + padding-left: 1rem; + padding-bottom: 0; +} +article.pytorch-article .function table.docutils.field-list, article.pytorch-article .attribute table.docutils.field-list, article.pytorch-article .class table.docutils.field-list { + margin-bottom: 0.75rem; +} +article.pytorch-article .attribute .has-code { + float: none; +} +article.pytorch-article .class dt { + border-left: none; + border-top: 3px solid #ee4c2c; + padding-left: 4em; +} +article.pytorch-article .class dt em.property { + position: absolute; + left: 0.5rem; +} +article.pytorch-article .class dd .docutils dt { + padding-left: 0.5rem; +} +article.pytorch-article .class em.property { + text-transform: uppercase; + font-style: normal; + color: #ee4c2c; + font-size: 1rem; + letter-spacing: 0; + padding-right: 0.75rem; +} +article.pytorch-article .class dl dt em.property { + position: static; + left: 0; + padding-right: 0; +} + +article.pytorch-article .class .method dt, +article.pytorch-article .class .staticmethod dt { + border-left: 3px solid #ee4c2c; + border-top: none; +} + +article.pytorch-article .class .method dt, +article.pytorch-article .class .staticmethod dt { + padding-left: 0.5rem; +} +article.pytorch-article .class .attribute dt { + border-top: none; +} +article.pytorch-article .class .attribute dt em.property { + position: relative; + left: 0; +} +article.pytorch-article table { + table-layout: fixed; +} + +div.deprecated p { + display: inline; +} +div.deprecated, +div.versionchanged { + margin-top: 0.5rem; + padding: 0.5rem; + margin-bottom: 0.5rem; + border: none; +} +div.versionadded { + margin: 1rem 0; +} +div.deprecated p:last-child, +div.versionchanged p:last-child, +div.versionadded p:last-child { + margin-bottom: 0 +} +div.deprecated { + color: #b94a48; + background-color: #fdede9; +} +div.versionchanged { + background-color: #fffbe8; +} + +article.pytorch-article .note, +article.pytorch-article .warning, +article.pytorch-article .tip, +article.pytorch-article .seealso, +article.pytorch-article .hint, +article.pytorch-article .important, +article.pytorch-article .caution, +article.pytorch-article .danger, +article.pytorch-article .attention, +article.pytorch-article .error { + background: #f3f4f7; + margin-top: 1.875rem; + margin-bottom: 1.125rem; +} +article.pytorch-article .note .admonition-title, +article.pytorch-article .warning .admonition-title, +article.pytorch-article .tip .admonition-title, +article.pytorch-article .seealso .admonition-title, +article.pytorch-article .hint .admonition-title, +article.pytorch-article .important .admonition-title, +article.pytorch-article .caution .admonition-title, +article.pytorch-article .danger .admonition-title, +article.pytorch-article .attention .admonition-title, +article.pytorch-article .error .admonition-title { + color: #ffffff; + letter-spacing: 1px; + text-transform: uppercase; + margin-bottom: 1.125rem; + padding: 3px 0 3px 1.375rem; + position: relative; + font-size: 0.875rem; +} +article.pytorch-article .note .admonition-title:before, +article.pytorch-article .warning .admonition-title:before, +article.pytorch-article .tip .admonition-title:before, +article.pytorch-article .seealso .admonition-title:before, +article.pytorch-article .hint .admonition-title:before, +article.pytorch-article .important .admonition-title:before, +article.pytorch-article .caution .admonition-title:before, +article.pytorch-article .danger .admonition-title:before, +article.pytorch-article .attention .admonition-title:before, +article.pytorch-article .error .admonition-title:before { + content: "\2022"; + position: absolute; + left: 9px; + color: #ffffff; + top: 2px; +} +article.pytorch-article .note p:nth-child(n + 2), +article.pytorch-article .warning p:nth-child(n + 2), +article.pytorch-article .tip p:nth-child(n + 2), +article.pytorch-article .seealso p:nth-child(n + 2), +article.pytorch-article .hint p:nth-child(n + 2), +article.pytorch-article .important p:nth-child(n + 2), +article.pytorch-article .caution p:nth-child(n + 2), +article.pytorch-article .danger p:nth-child(n + 2), +article.pytorch-article .attention p:nth-child(n + 2), +article.pytorch-article .error p:nth-child(n + 2) { + padding: 0 1.375rem; +} +article.pytorch-article .note table, +article.pytorch-article .warning table, +article.pytorch-article .tip table, +article.pytorch-article .seealso table, +article.pytorch-article .hint table, +article.pytorch-article .important table, +article.pytorch-article .caution table, +article.pytorch-article .danger table, +article.pytorch-article .attention table, +article.pytorch-article .error table { + margin: 0 2rem; + width: auto; +} +article.pytorch-article .note :not(dt) > code, +article.pytorch-article .warning :not(dt) > code, +article.pytorch-article .tip :not(dt) > code, +article.pytorch-article .seealso :not(dt) > code, +article.pytorch-article .hint :not(dt) > code, +article.pytorch-article .important :not(dt) > code, +article.pytorch-article .caution :not(dt) > code, +article.pytorch-article .danger :not(dt) > code, +article.pytorch-article .attention :not(dt) > code, +article.pytorch-article .error :not(dt) > code { + border-top: solid 2px #ffffff; + background-color: #ffffff; + border-bottom: solid 2px #ffffff; + padding: 0px 3px; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; + outline: 1px solid #e9e9e9; +} +article.pytorch-article .note :not(dt) > code .pre, +article.pytorch-article .warning :not(dt) > code .pre, +article.pytorch-article .tip :not(dt) > code .pre, +article.pytorch-article .seealso :not(dt) > code .pre, +article.pytorch-article .hint :not(dt) > code .pre, +article.pytorch-article .important :not(dt) > code .pre, +article.pytorch-article .caution :not(dt) > code .pre, +article.pytorch-article .danger :not(dt) > code .pre, +article.pytorch-article .attention :not(dt) > code .pre, +article.pytorch-article .error :not(dt) > code .pre { + outline: 0px; + padding: 0px; +} +article.pytorch-article .note pre, +article.pytorch-article .warning pre, +article.pytorch-article .tip pre, +article.pytorch-article .seealso pre, +article.pytorch-article .hint pre, +article.pytorch-article .important pre, +article.pytorch-article .caution pre, +article.pytorch-article .danger pre, +article.pytorch-article .attention pre, +article.pytorch-article .error pre { + margin-bottom: 0; +} +article.pytorch-article .note .highlight, +article.pytorch-article .warning .highlight, +article.pytorch-article .tip .highlight, +article.pytorch-article .seealso .highlight, +article.pytorch-article .hint .highlight, +article.pytorch-article .important .highlight, +article.pytorch-article .caution .highlight, +article.pytorch-article .danger .highlight, +article.pytorch-article .attention .highlight, +article.pytorch-article .error .highlight { + margin: 0 2rem 1.125rem 2rem; +} +article.pytorch-article .note ul, +article.pytorch-article .note ol, +article.pytorch-article .warning ul, +article.pytorch-article .warning ol, +article.pytorch-article .tip ul, +article.pytorch-article .tip ol, +article.pytorch-article .seealso ul, +article.pytorch-article .seealso ol, +article.pytorch-article .hint ul, +article.pytorch-article .hint ol, +article.pytorch-article .important ul, +article.pytorch-article .important ol, +article.pytorch-article .caution ul, +article.pytorch-article .caution ol, +article.pytorch-article .danger ul, +article.pytorch-article .danger ol, +article.pytorch-article .attention ul, +article.pytorch-article .attention ol, +article.pytorch-article .error ul, +article.pytorch-article .error ol { + padding-left: 3.25rem; +} +article.pytorch-article .note ul li, +article.pytorch-article .note ol li, +article.pytorch-article .warning ul li, +article.pytorch-article .warning ol li, +article.pytorch-article .tip ul li, +article.pytorch-article .tip ol li, +article.pytorch-article .seealso ul li, +article.pytorch-article .seealso ol li, +article.pytorch-article .hint ul li, +article.pytorch-article .hint ol li, +article.pytorch-article .important ul li, +article.pytorch-article .important ol li, +article.pytorch-article .caution ul li, +article.pytorch-article .caution ol li, +article.pytorch-article .danger ul li, +article.pytorch-article .danger ol li, +article.pytorch-article .attention ul li, +article.pytorch-article .attention ol li, +article.pytorch-article .error ul li, +article.pytorch-article .error ol li { + color: #262626; +} +article.pytorch-article .note p, +article.pytorch-article .warning p, +article.pytorch-article .tip p, +article.pytorch-article .seealso p, +article.pytorch-article .hint p, +article.pytorch-article .important p, +article.pytorch-article .caution p, +article.pytorch-article .danger p, +article.pytorch-article .attention p, +article.pytorch-article .error p { + margin-top: 1.125rem; +} +article.pytorch-article .note .admonition-title { + background: #54c7ec; +} +article.pytorch-article .warning .admonition-title { + background: #e94f3b; +} +article.pytorch-article .tip .admonition-title { + background: #6bcebb; +} +article.pytorch-article .seealso .admonition-title { + background: #6bcebb; +} +article.pytorch-article .hint .admonition-title { + background: #a2cdde; +} +article.pytorch-article .important .admonition-title { + background: #5890ff; +} +article.pytorch-article .caution .admonition-title { + background: #f7923a; +} +article.pytorch-article .danger .admonition-title { + background: #db2c49; +} +article.pytorch-article .attention .admonition-title { + background: #f5a623; +} +article.pytorch-article .error .admonition-title { + background: #cc2f90; +} +article.pytorch-article .sphx-glr-download-link-note.admonition.note, +article.pytorch-article .reference.download.internal, article.pytorch-article .sphx-glr-signature { + display: none; +} +article.pytorch-article .admonition > p:last-of-type { + margin-bottom: 0; + padding-bottom: 1.125rem !important; +} + +.pytorch-article div.sphx-glr-download a { + background-color: #f3f4f7; + background-image: url("../images/arrow-down-orange.svg"); + background-repeat: no-repeat; + background-position: left 10px center; + background-size: 15px 15px; + border-radius: 0; + border: none; + display: block; + text-align: left; + padding: 0.9375rem 3.125rem; + position: relative; + margin: 1.25rem auto; +} +@media screen and (min-width: 768px) { + .pytorch-article div.sphx-glr-download a:after { + content: ""; + display: block; + width: 0; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + background-color: #e44c2c; + -webkit-transition: width .250s ease-in-out; + transition: width .250s ease-in-out; + } + .pytorch-article div.sphx-glr-download a:hover:after { + width: 100%; + } +} +@media screen and (min-width: 768px) { + .pytorch-article div.sphx-glr-download a:after { + background-color: #ee4c2c; + } +} +@media screen and (min-width: 768px) { + .pytorch-article div.sphx-glr-download a { + background-position: left 20px center; + } +} +.pytorch-article div.sphx-glr-download a:hover { + -webkit-box-shadow: none; + box-shadow: none; + text-decoration: none; + background-image: url("../images/arrow-down-orange.svg"); + background-color: #f3f4f7; +} +.pytorch-article div.sphx-glr-download a span.pre { + background-color: transparent; + font-size: 1.125rem; + padding: 0; + color: #262626; +} +.pytorch-article div.sphx-glr-download a code, .pytorch-article div.sphx-glr-download a kbd, .pytorch-article div.sphx-glr-download a pre, .pytorch-article div.sphx-glr-download a samp, .pytorch-article div.sphx-glr-download a span.pre { + font-family: FreightSans, Helvetica Neue, Helvetica, Arial, sans-serif; +} + +.pytorch-article p.sphx-glr-script-out { + margin-bottom: 1.125rem; +} + +.pytorch-article div.sphx-glr-script-out { + margin-bottom: 2.5rem; +} +.pytorch-article div.sphx-glr-script-out .highlight { + margin-left: 0; + margin-top: 0; +} +.pytorch-article div.sphx-glr-script-out .highlight pre { + background-color: #fdede9; + padding: 1.5625rem; + color: #837b79; +} +.pytorch-article div.sphx-glr-script-out + p { + margin-top: unset; +} + +article.pytorch-article .wy-table-responsive table { + border: none; + border-color: #ffffff !important; + table-layout: fixed; +} +article.pytorch-article .wy-table-responsive table thead tr { + border-bottom: 2px solid #6c6c6d; +} +article.pytorch-article .wy-table-responsive table thead th { + line-height: 1.75rem; + padding-left: 0.9375rem; + padding-right: 0.9375rem; +} +article.pytorch-article .wy-table-responsive table tbody .row-odd { + background-color: #f3f4f7; +} +article.pytorch-article .wy-table-responsive table tbody td { + color: #6c6c6d; + white-space: normal; + padding: 0.9375rem; + font-size: 1rem; + line-height: 1.375rem; +} +article.pytorch-article .wy-table-responsive table tbody td .pre { + background: #ffffff; + color: #ee4c2c; + font-size: 87.5%; +} +article.pytorch-article .wy-table-responsive table tbody td code { + font-size: 87.5%; +} + +a[rel~="prev"], a[rel~="next"] { + padding: 0.375rem 0 0 0; +} + +img.next-page, +img.previous-page { + width: 8px; + height: 10px; + position: relative; + top: -1px; +} + +img.previous-page { + -webkit-transform: scaleX(-1); + transform: scaleX(-1); +} + +.rst-footer-buttons { + margin-top: 1.875rem; + margin-bottom: 1.875rem; +} +.rst-footer-buttons .btn:focus, +.rst-footer-buttons .btn.focus { + -webkit-box-shadow: none; + box-shadow: none; +} + +article.pytorch-article blockquote { + margin-left: 3.75rem; + color: #6c6c6d; +} + +article.pytorch-article .caption { + color: #6c6c6d; + letter-spacing: 0.25px; + line-height: 2.125rem; +} + +article.pytorch-article .math { + color: #262626; + width: auto; + text-align: center; +} +article.pytorch-article .math img { + width: auto; +} + +.pytorch-breadcrumbs-wrapper { + width: 100%; +} +@media screen and (min-width: 1101px) { + .pytorch-breadcrumbs-wrapper { + float: left; + margin-left: 3%; + width: 75%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-breadcrumbs-wrapper { + width: 850px; + margin-left: 1.875rem; + } +} +.pytorch-breadcrumbs-wrapper .pytorch-breadcrumbs-aside { + float: right; +} +.pytorch-breadcrumbs-wrapper .pytorch-breadcrumbs-aside .fa.fa-github { + margin-top: 5px; + display: block; +} + +.pytorch-article .container { + padding-left: 0; + padding-right: 0; + max-width: none; +} + +a:link, +a:visited, +a:hover { + color: #ee4c2c; +} + +::-webkit-input-placeholder { + color: #ee4c2c; +} + +::-moz-placeholder { + color: #ee4c2c; +} + +:-ms-input-placeholder { + color: #ee4c2c; +} + +:-moz-placeholder { + color: #ee4c2c; +} + +@media screen and (min-width: 768px) { + .site-footer a:hover { + color: #ee4c2c; + } +} + +.docs-tutorials-resources a { + color: #ee4c2c; +} + +.header-holder { + position: relative; + z-index: 201; +} + +.header-holder .main-menu ul li.active:after { + color: #ee4c2c; +} +.header-holder .main-menu ul li.active a { + color: #ee4c2c; +} +@media screen and (min-width: 1100px) { + .header-holder .main-menu ul li a:hover { + color: #ee4c2c; + } +} + +.mobile-main-menu.open ul li.active a { + color: #ee4c2c; +} + +.version { + padding-bottom: 1rem; +} + +.pytorch-call-to-action-links { + padding-top: 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} +@media screen and (min-width: 768px) { + .pytorch-call-to-action-links { + padding-top: 2.5rem; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + .pytorch-call-to-action-links { + padding-top: 0; + } +} +@media (min-width: 1100px) and (max-width: 1239px) { + .pytorch-call-to-action-links { + padding-top: 2.5rem; + } +} +.pytorch-call-to-action-links #tutorial-type { + display: none; +} +.pytorch-call-to-action-links .call-to-action-img, .pytorch-call-to-action-links .call-to-action-notebook-img { + height: 1.375rem; + width: 1.375rem; + margin-right: 10px; +} +.pytorch-call-to-action-links .call-to-action-notebook-img { + height: 1rem; +} +.pytorch-call-to-action-links a { + padding-right: 1.25rem; + color: #000000; + cursor: pointer; +} +.pytorch-call-to-action-links a:hover { + color: #e44c2c; +} +.pytorch-call-to-action-links a .call-to-action-desktop-view { + display: none; +} +@media screen and (min-width: 768px) { + .pytorch-call-to-action-links a .call-to-action-desktop-view { + display: block; + } +} +.pytorch-call-to-action-links a .call-to-action-mobile-view { + display: block; +} +@media screen and (min-width: 768px) { + .pytorch-call-to-action-links a .call-to-action-mobile-view { + display: none; + } +} +.pytorch-call-to-action-links a #google-colab-link, .pytorch-call-to-action-links a #download-notebook-link, +.pytorch-call-to-action-links a #github-view-link { + padding-bottom: 0.625rem; + border-bottom: 1px solid #f3f4f7; + padding-right: 2.5rem; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +.pytorch-call-to-action-links a #google-colab-link:hover, .pytorch-call-to-action-links a #download-notebook-link:hover, +.pytorch-call-to-action-links a #github-view-link:hover { + border-bottom-color: #e44c2c; + color: #e44c2c; +} + +#tutorial-cards-container #tutorial-cards { + width: 100%; +} +#tutorial-cards-container .tutorials-nav { + padding-left: 0; + padding-right: 0; + padding-bottom: 0; +} +#tutorial-cards-container .tutorials-hr { + margin-top: 1rem; + margin-bottom: 1rem; +} +#tutorial-cards-container .card.tutorials-card { + border-radius: 0; + border-color: #f3f4f7; + height: 98px; + margin-bottom: 1.25rem; + margin-bottom: 1.875rem; + overflow: scroll; + background-color: #f3f4f7; + cursor: pointer; +} +@media screen and (min-width: 1240px) { + #tutorial-cards-container .card.tutorials-card { + height: 200px; + overflow: inherit; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card { + height: 200px; + overflow: scroll; + } +} +#tutorial-cards-container .card.tutorials-card .tutorials-image { + position: absolute; + top: 0px; + right: 0px; + height: 96px; + width: 96px; + opacity: 0.5; +} +#tutorial-cards-container .card.tutorials-card .tutorials-image img { + height: 100%; + width: 100%; +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card .tutorials-image { + height: 100%; + width: 25%; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card .tutorials-image { + height: 100%; + width: 198px; + } +} +#tutorial-cards-container .card.tutorials-card .tutorials-image:before { + content: ''; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + z-index: 1; + background: #000000; + opacity: .075; +} +#tutorial-cards-container .card.tutorials-card .card-title-container { + width: 70%; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card .card-title-container { + width: 75%; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card .card-title-container { + width: 70%; + } +} +#tutorial-cards-container .card.tutorials-card .card-title-container h4 { + margin-bottom: 1.125rem; + margin-top: 0; + font-size: 1.5rem; +} +#tutorial-cards-container .card.tutorials-card p.card-summary, #tutorial-cards-container .card.tutorials-card p.tags { + font-size: 0.9375rem; + line-height: 1.5rem; + margin-bottom: 0; + color: #6c6c6d; + font-weight: 400; + width: 70%; +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card p.card-summary, #tutorial-cards-container .card.tutorials-card p.tags { + width: 75%; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card p.card-summary, #tutorial-cards-container .card.tutorials-card p.tags { + width: 70%; + } +} +#tutorial-cards-container .card.tutorials-card p.tags { + margin-top: 30px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} +#tutorial-cards-container .card.tutorials-card h4 { + color: #262626; + margin-bottom: 1.125rem; +} +#tutorial-cards-container .card.tutorials-card a { + height: 100%; +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card a { + min-height: 190px; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + #tutorial-cards-container .card.tutorials-card a { + min-height: 234px; + } +} +@media screen and (min-width: 768px) { + #tutorial-cards-container .card.tutorials-card:after { + content: ""; + display: block; + width: 0; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + background-color: #e44c2c; + -webkit-transition: width .250s ease-in-out; + transition: width .250s ease-in-out; + } + #tutorial-cards-container .card.tutorials-card:hover:after { + width: 100%; + } +} +#tutorial-cards-container .card.tutorials-card:hover { + background-color: #ffffff; + border: 1px solid #e2e2e2; + border-bottom: none; +} +#tutorial-cards-container .card.tutorials-card:hover p.card-summary { + color: #262626; +} +#tutorial-cards-container .card.tutorials-card:hover .tutorials-image { + opacity: unset; +} +#tutorial-cards-container .tutorial-tags-container { + width: 75%; +} +#tutorial-cards-container .tutorial-tags-container.active { + width: 0; +} +#tutorial-cards-container .tutorial-filter-menu ul { + list-style-type: none; + padding-left: 1.25rem; +} +#tutorial-cards-container .tutorial-filter-menu ul li { + padding-right: 1.25rem; + word-break: break-all; +} +#tutorial-cards-container .tutorial-filter-menu ul li a { + color: #979797; +} +#tutorial-cards-container .tutorial-filter-menu ul li a:hover { + color: #e44c2c; +} +#tutorial-cards-container .tutorial-filter { + cursor: pointer; +} +#tutorial-cards-container .filter-btn { + color: #979797; + border: 1px solid #979797; + display: inline-block; + text-align: center; + white-space: nowrap; + vertical-align: middle; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + margin-bottom: 5px; +} +#tutorial-cards-container .filter-btn:hover { + border: 1px solid #e44c2c; + color: #e44c2c; +} +#tutorial-cards-container .filter-btn.selected { + background-color: #e44c2c; + border: 1px solid #e44c2c; + color: #ffffff; +} +#tutorial-cards-container .all-tag-selected { + background-color: #979797; + color: #ffffff; +} +#tutorial-cards-container .all-tag-selected:hover { + border-color: #979797; + color: #ffffff; +} +#tutorial-cards-container .pagination .page { + border: 1px solid #dee2e6; + padding: 0.5rem 0.75rem; +} +#tutorial-cards-container .pagination .active .page { + background-color: #dee2e6; +} + +article.pytorch-article .tutorials-callout-container { + padding-bottom: 50px; +} +article.pytorch-article .tutorials-callout-container .col-md-6 { + padding-bottom: 10px; +} +article.pytorch-article .tutorials-callout-container .text-container { + padding: 10px 0px 30px 0px; + padding-bottom: 10px; +} +article.pytorch-article .tutorials-callout-container .text-container .body-paragraph { + color: #666666; + font-weight: 300; + font-size: 1.125rem; + line-height: 1.875rem; +} +article.pytorch-article .tutorials-callout-container .btn.callout-button { + font-size: 1.125rem; + border-radius: 0; + border: none; + background-color: #f3f4f7; + color: #6c6c6d; + font-weight: 400; + position: relative; + letter-spacing: 0.25px; +} +@media screen and (min-width: 768px) { + article.pytorch-article .tutorials-callout-container .btn.callout-button:after { + content: ""; + display: block; + width: 0; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + background-color: #e44c2c; + -webkit-transition: width .250s ease-in-out; + transition: width .250s ease-in-out; + } + article.pytorch-article .tutorials-callout-container .btn.callout-button:hover:after { + width: 100%; + } +} +article.pytorch-article .tutorials-callout-container .btn.callout-button a { + color: inherit; +} + +.pytorch-container { + margin: 0 auto; + padding: 0 1.875rem; + width: auto; + position: relative; +} +@media screen and (min-width: 1100px) { + .pytorch-container { + padding: 0; + } +} +@media screen and (min-width: 1101px) { + .pytorch-container { + margin-left: 25%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-container { + margin-left: 350px; + } +} +.pytorch-container:before, .pytorch-container:after { + content: ""; + display: table; +} +.pytorch-container:after { + clear: both; +} +.pytorch-container { + *zoom: 1; +} + +.pytorch-content-wrap { + background-color: #ffffff; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + position: relative; + padding-top: 0; +} +.pytorch-content-wrap:before, .pytorch-content-wrap:after { + content: ""; + display: table; +} +.pytorch-content-wrap:after { + clear: both; +} +.pytorch-content-wrap { + *zoom: 1; +} +@media screen and (min-width: 1101px) { + .pytorch-content-wrap { + padding-top: 45px; + float: left; + width: 100%; + display: block; + } +} +@media screen and (min-width: 1600px) { + .pytorch-content-wrap { + width: 100%; + } +} + +.pytorch-content { + background: #ffffff; + width: 100%; + max-width: 700px; + position: relative; +} + +.pytorch-content-left { + min-height: 100vh; + margin-top: 2.5rem; + width: 100%; +} +@media screen and (min-width: 1101px) { + .pytorch-content-left { + margin-top: 0; + margin-left: 3%; + width: 75%; + float: left; + } +} +@media screen and (min-width: 1600px) { + .pytorch-content-left { + width: 850px; + margin-left: 30px; + } +} +.pytorch-content-left .main-content { + padding-top: 0.9375rem; +} +.pytorch-content-left .main-content ul.simple { + padding-bottom: 1.25rem; +} +.pytorch-content-left .main-content .note:nth-child(1), .pytorch-content-left .main-content .warning:nth-child(1) { + margin-top: 0; +} + +.pytorch-content-right { + display: none; + position: relative; + overflow-x: hidden; + overflow-y: hidden; +} +@media screen and (min-width: 1101px) { + .pytorch-content-right { + display: block; + margin-left: 0; + width: 19%; + float: left; + height: 100%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-content-right { + width: 280px; + } +} + +@media screen and (min-width: 1101px) { + .pytorch-side-scroll { + position: relative; + overflow-x: hidden; + overflow-y: scroll; + height: 100%; + } +} + +.pytorch-menu-vertical { + padding: 1.25rem 1.875rem 2.5rem 1.875rem; +} +@media screen and (min-width: 1101px) { + .pytorch-menu-vertical { + display: block; + padding-top: 0; + padding-right: 13.5%; + padding-bottom: 5.625rem; + } +} +@media screen and (min-width: 1600px) { + .pytorch-menu-vertical { + padding-left: 0; + padding-right: 1.5625rem; + } +} + +.pytorch-left-menu { + display: none; + background-color: #f3f4f7; + color: #262626; + overflow: scroll; +} +@media screen and (min-width: 1101px) { + .pytorch-left-menu { + display: block; + overflow-x: hidden; + overflow-y: hidden; + padding-bottom: 110px; + padding: 0 1.875rem 0 0; + width: 25%; + z-index: 200; + float: left; + } + .pytorch-left-menu.make-fixed { + position: fixed; + top: 0; + bottom: 0; + left: 0; + float: none; + } +} +@media screen and (min-width: 1600px) { + .pytorch-left-menu { + padding: 0 0 0 1.875rem; + width: 350px; + } +} + +.expand-menu, .hide-menu { + color: #6c6c6d; + padding-left: 10px; + cursor: pointer; +} + +.collapse { + display: none; +} + +.left-nav-top-caption { + padding-top: 1rem; +} + +.pytorch-left-menu p.caption { + color: #262626; + display: block; + font-size: 1rem; + line-height: 1.375rem; + margin-bottom: 1rem; + text-transform: none; + white-space: normal; +} + +.pytorch-left-menu-search { + margin-bottom: 2.5rem; +} +@media screen and (min-width: 1101px) { + .pytorch-left-menu-search { + margin: 1.25rem 0.625rem 1.875rem 0; + } +} + +.pytorch-left-menu-search ::-webkit-input-placeholder { + color: #262626; +} +.pytorch-left-menu-search ::-moz-placeholder { + color: #262626; +} +.pytorch-left-menu-search :-ms-input-placeholder { + color: #262626; +} +.pytorch-left-menu-search ::-ms-input-placeholder { + color: #262626; +} +.pytorch-left-menu-search ::placeholder { + color: #262626; +} + +.pytorch-left-menu-search :focus::-webkit-input-placeholder { + color: transparent; +} +.pytorch-left-menu-search :focus::-moz-placeholder { + color: transparent; +} +.pytorch-left-menu-search :focus:-ms-input-placeholder { + color: transparent; +} +.pytorch-left-menu-search :focus::-ms-input-placeholder { + color: transparent; +} +.pytorch-left-menu-search :focus::placeholder { + color: transparent; +} + +.pytorch-left-menu-search input[type=text] { + border-radius: 0; + padding: 0.5rem 0.75rem; + border-color: #ffffff; + color: #262626; + border-style: solid; + font-size: 1rem; + width: 100%; + background-color: #f3f4f7; + background-image: url("../images/search-icon.svg"); + background-repeat: no-repeat; + background-size: 18px 18px; + background-position: 12px 10px; + padding-left: 40px; + background-color: #ffffff; +} +.pytorch-left-menu-search input[type=text]:focus { + outline: 0; +} + +@media screen and (min-width: 1101px) { + .pytorch-left-menu .pytorch-side-scroll { + width: 120%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-left-menu .pytorch-side-scroll { + width: 340px; + } +} + +.pytorch-right-menu { + min-height: 100px; + overflow-x: hidden; + overflow-y: hidden; + left: 0; + z-index: 200; + padding-top: 0; + position: relative; +} +@media screen and (min-width: 1101px) { + .pytorch-right-menu { + width: 100%; + } + .pytorch-right-menu.scrolling-fixed { + position: fixed; + top: 45px; + left: 83.5%; + width: 14%; + } + .pytorch-right-menu.scrolling-absolute { + position: absolute; + left: 0; + } +} +@media screen and (min-width: 1600px) { + .pytorch-right-menu { + left: 0; + width: 380px; + } + .pytorch-right-menu.scrolling-fixed { + position: fixed; + top: 45px; + left: 1230px; + } + .pytorch-right-menu.scrolling-absolute { + position: absolute; + left: 0; + } +} + +.pytorch-left-menu ul, +.pytorch-right-menu ul { + list-style-type: none; + padding-left: 0; + margin-bottom: 2.5rem; +} +.pytorch-left-menu > ul, +.pytorch-right-menu > ul { + margin-bottom: 2.5rem; +} +.pytorch-left-menu a:link, +.pytorch-left-menu a:visited, +.pytorch-left-menu a:hover, +.pytorch-right-menu a:link, +.pytorch-right-menu a:visited, +.pytorch-right-menu a:hover { + color: #6c6c6d; + font-size: 0.875rem; + line-height: 1rem; + padding: 0; + text-decoration: none; +} +.pytorch-left-menu a:link.reference.internal, +.pytorch-left-menu a:visited.reference.internal, +.pytorch-left-menu a:hover.reference.internal, +.pytorch-right-menu a:link.reference.internal, +.pytorch-right-menu a:visited.reference.internal, +.pytorch-right-menu a:hover.reference.internal { + margin-bottom: 0.3125rem; + position: relative; +} +.pytorch-left-menu li code, +.pytorch-right-menu li code { + border: none; + background: inherit; + color: inherit; + padding-left: 0; + padding-right: 0; +} +.pytorch-left-menu li span.toctree-expand, +.pytorch-right-menu li span.toctree-expand { + display: block; + float: left; + margin-left: -1.2em; + font-size: 0.8em; + line-height: 1.6em; +} +.pytorch-left-menu li.on a, .pytorch-left-menu li.current > a, +.pytorch-right-menu li.on a, +.pytorch-right-menu li.current > a { + position: relative; + border: none; +} +.pytorch-left-menu li.on a span.toctree-expand, .pytorch-left-menu li.current > a span.toctree-expand, +.pytorch-right-menu li.on a span.toctree-expand, +.pytorch-right-menu li.current > a span.toctree-expand { + display: block; + font-size: 0.8em; + line-height: 1.6em; +} +.pytorch-left-menu li.toctree-l1.current > a, +.pytorch-right-menu li.toctree-l1.current > a { + color: #ee4c2c; +} +.pytorch-left-menu li.toctree-l1.current > a:before, +.pytorch-right-menu li.toctree-l1.current > a:before { + content: "\2022"; + display: inline-block; + position: absolute; + left: -15px; + top: -10%; + font-size: 1.375rem; + color: #ee4c2c; +} +@media screen and (min-width: 1101px) { + .pytorch-left-menu li.toctree-l1.current > a:before, + .pytorch-right-menu li.toctree-l1.current > a:before { + left: -20px; + } +} +.pytorch-left-menu li.toctree-l1.current li.toctree-l2 > ul, .pytorch-left-menu li.toctree-l2.current li.toctree-l3 > ul, +.pytorch-right-menu li.toctree-l1.current li.toctree-l2 > ul, +.pytorch-right-menu li.toctree-l2.current li.toctree-l3 > ul { + display: none; +} +.pytorch-left-menu li.toctree-l1.current li.toctree-l2.current > ul, .pytorch-left-menu li.toctree-l2.current li.toctree-l3.current > ul, +.pytorch-right-menu li.toctree-l1.current li.toctree-l2.current > ul, +.pytorch-right-menu li.toctree-l2.current li.toctree-l3.current > ul { + display: block; +} +.pytorch-left-menu li.toctree-l2.current li.toctree-l3 > a, +.pytorch-right-menu li.toctree-l2.current li.toctree-l3 > a { + display: block; +} +.pytorch-left-menu li.toctree-l3, +.pytorch-right-menu li.toctree-l3 { + font-size: 0.9em; +} +.pytorch-left-menu li.toctree-l3.current li.toctree-l4 > a, +.pytorch-right-menu li.toctree-l3.current li.toctree-l4 > a { + display: block; +} +.pytorch-left-menu li.toctree-l4, +.pytorch-right-menu li.toctree-l4 { + font-size: 0.9em; +} +.pytorch-left-menu li.current ul, +.pytorch-right-menu li.current ul { + display: block; +} +.pytorch-left-menu li ul, +.pytorch-right-menu li ul { + margin-bottom: 0; + display: none; +} +.pytorch-left-menu li ul li a, +.pytorch-right-menu li ul li a { + margin-bottom: 0; +} +.pytorch-left-menu a, +.pytorch-right-menu a { + display: inline-block; + position: relative; +} +.pytorch-left-menu a:hover, +.pytorch-right-menu a:hover { + cursor: pointer; +} +.pytorch-left-menu a:active, +.pytorch-right-menu a:active { + cursor: pointer; +} + +.pytorch-left-menu ul { + padding-left: 0; +} + +.pytorch-right-menu a:link, +.pytorch-right-menu a:visited, +.pytorch-right-menu a:hover { + color: #6c6c6d; +} +.pytorch-right-menu a:link span.pre, +.pytorch-right-menu a:visited span.pre, +.pytorch-right-menu a:hover span.pre { + color: #6c6c6d; +} +.pytorch-right-menu a.reference.internal.expanded:before { + content: "-"; + font-family: monospace; + position: absolute; + left: -12px; +} +.pytorch-right-menu a.reference.internal.not-expanded:before { + content: "+"; + font-family: monospace; + position: absolute; + left: -12px; +} +.pytorch-right-menu li.active > a { + color: #ee4c2c; +} +.pytorch-right-menu li.active > a span.pre, .pytorch-right-menu li.active > a:before { + color: #ee4c2c; +} +.pytorch-right-menu li.active > a:after { + content: "\2022"; + color: #e44c2c; + display: inline-block; + font-size: 1.375rem; + left: -17px; + position: absolute; + top: 1px; +} +.pytorch-right-menu .pytorch-side-scroll > ul > li > ul > li { + margin-bottom: 0; +} +.pytorch-right-menu ul ul { + padding-left: 0; +} +.pytorch-right-menu ul ul li { + padding-left: 0px; +} +.pytorch-right-menu ul ul li a.reference.internal { + padding-left: 0; +} +.pytorch-right-menu ul ul li ul { + display: none; + padding-left: 10px; +} +.pytorch-right-menu ul ul li li a.reference.internal { + padding-left: 0; +} +.pytorch-right-menu li ul { + display: block; +} + +.pytorch-right-menu .pytorch-side-scroll { + padding-top: 20px; +} +@media screen and (min-width: 1101px) { + .pytorch-right-menu .pytorch-side-scroll { + width: 120%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-right-menu .pytorch-side-scroll { + width: 400px; + } +} +.pytorch-right-menu .pytorch-side-scroll > ul { + padding-left: 10%; + padding-right: 10%; + margin-bottom: 0; +} +@media screen and (min-width: 1600px) { + .pytorch-right-menu .pytorch-side-scroll > ul { + padding-left: 25px; + } +} +.pytorch-right-menu .pytorch-side-scroll > ul > li > a.reference.internal { + color: #262626; + font-weight: 500; +} +.pytorch-right-menu .pytorch-side-scroll ul li { + position: relative; +} + +#pytorch-right-menu .side-scroll-highlight { + color: #ee4c2c; +} + +.header-container { + max-width: none; + margin-top: 4px; +} +@media screen and (min-width: 1101px) { + .header-container { + margin-top: 0; + } +} +@media screen and (min-width: 1600px) { + .header-container { + margin-top: 0; + } +} + +.container-fluid.header-holder { + padding-right: 0; + padding-left: 0; +} + +.header-holder .container { + max-width: none; + padding-right: 1.875rem; + padding-left: 1.875rem; +} +@media screen and (min-width: 1101px) { + .header-holder .container { + padding-right: 1.875rem; + padding-left: 1.875rem; + } +} + +.header-holder .main-menu { + -webkit-box-pack: unset; + -ms-flex-pack: unset; + justify-content: unset; + position: relative; +} +@media screen and (min-width: 1101px) { + .header-holder .main-menu ul { + padding-left: 0; + margin-left: 26%; + } +} +@media screen and (min-width: 1600px) { + .header-holder .main-menu ul { + padding-left: 38px; + margin-left: 310px; + } +} + +.pytorch-page-level-bar { + display: none; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: #ffffff; + border-bottom: 1px solid #e2e2e2; + width: 100%; + z-index: 201; +} +@media screen and (min-width: 1101px) { + .pytorch-page-level-bar { + left: 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + height: 45px; + padding-left: 0; + width: 100%; + position: absolute; + z-index: 1; + } + .pytorch-page-level-bar.left-menu-is-fixed { + position: fixed; + top: 0; + left: 25%; + padding-left: 0; + right: 0; + width: 75%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-page-level-bar { + left: 0; + right: 0; + width: auto; + z-index: 1; + } + .pytorch-page-level-bar.left-menu-is-fixed { + left: 350px; + right: 0; + width: auto; + } +} +.pytorch-page-level-bar ul, .pytorch-page-level-bar li { + margin: 0; +} + +.pytorch-shortcuts-wrapper { + display: none; +} +@media screen and (min-width: 1101px) { + .pytorch-shortcuts-wrapper { + font-size: 0.875rem; + float: left; + margin-left: 2%; + } +} +@media screen and (min-width: 1600px) { + .pytorch-shortcuts-wrapper { + margin-left: 1.875rem; + } +} + +.cookie-banner-wrapper { + display: none; +} +.cookie-banner-wrapper .container { + padding-left: 1.875rem; + padding-right: 1.875rem; + max-width: 1240px; +} +.cookie-banner-wrapper.is-visible { + display: block; + position: fixed; + bottom: 0; + background-color: #f3f4f7; + min-height: 100px; + width: 100%; + z-index: 401; + border-top: 3px solid #ededee; +} +.cookie-banner-wrapper .gdpr-notice { + color: #6c6c6d; + margin-top: 1.5625rem; + text-align: left; + max-width: 1440px; +} +@media screen and (min-width: 768px) { + .cookie-banner-wrapper .gdpr-notice { + width: 77%; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + .cookie-banner-wrapper .gdpr-notice { + width: inherit; + } +} +.cookie-banner-wrapper .gdpr-notice .cookie-policy-link { + color: #343434; +} +.cookie-banner-wrapper .close-button { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: transparent; + border: 1px solid #f3f4f7; + height: 1.3125rem; + position: absolute; + bottom: 42px; + right: 0; + top: 0; + cursor: pointer; + outline: none; +} +@media screen and (min-width: 768px) { + .cookie-banner-wrapper .close-button { + right: 20%; + top: inherit; + } +} +@media (min-width: 768px) and (max-width: 1239px) { + .cookie-banner-wrapper .close-button { + right: 0; + top: 0; + } +} + +.main-menu ul li .resources-dropdown a { + cursor: pointer; +} +.main-menu ul li .dropdown-menu { + border-radius: 0; + padding: 0; +} +.main-menu ul li .dropdown-menu .dropdown-item { + color: #6c6c6d; + border-bottom: 1px solid #e2e2e2; +} +.main-menu ul li .dropdown-menu .dropdown-item:last-of-type { + border-bottom-color: transparent; +} +.main-menu ul li .dropdown-menu .dropdown-item:hover { + background-color: #e44c2c; +} +.main-menu ul li .dropdown-menu .dropdown-item p { + font-size: 1rem; + color: #979797; +} +.main-menu ul li .dropdown-menu a.dropdown-item:hover { + color: #ffffff; +} +.main-menu ul li .dropdown-menu a.dropdown-item:hover p { + color: #ffffff; +} + +.resources-dropdown-menu { + left: -75px; + width: 226px; + display: none; + position: absolute; + z-index: 1000; + display: none; + float: left; + min-width: 10rem; + padding: 0.5rem 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #ffffff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} + +.resources-dropdown:hover .resources-dropdown-menu { + display: block; +} + +.main-menu ul li .resources-dropdown-menu { + border-radius: 0; + padding: 0; +} +.main-menu ul li.active:hover .resources-dropdown-menu { + display: block; +} + +.main-menu ul li .resources-dropdown-menu .dropdown-item { + color: #6c6c6d; + border-bottom: 1px solid #e2e2e2; +} + +.resources-dropdown .with-down-orange-arrow { + padding-right: 2rem; + position: relative; + background: url("../images/chevron-down-orange.svg"); + background-size: 14px 18px; + background-position: top 7px right 10px; + background-repeat: no-repeat; +} + +.with-down-arrow { + padding-right: 2rem; + position: relative; + background-image: url("../images/chevron-down-black.svg"); + background-size: 14px 18px; + background-position: top 7px right 10px; + background-repeat: no-repeat; +} +.with-down-arrow:hover { + background-image: url("../images/chevron-down-orange.svg"); + background-repeat: no-repeat; +} + +.header-holder .main-menu ul li .resources-dropdown .doc-dropdown-option { + padding-top: 1rem; +} + +.header-holder .main-menu ul li a.nav-dropdown-item { + display: block; + font-size: 1rem; + line-height: 1.3125rem; + width: 100%; + padding: 0.25rem 1.5rem; + clear: both; + font-weight: 400; + color: #979797; + text-align: center; + background-color: transparent; + border-bottom: 1px solid #e2e2e2; +} +.header-holder .main-menu ul li a.nav-dropdown-item:last-of-type { + border-bottom-color: transparent; +} +.header-holder .main-menu ul li a.nav-dropdown-item:hover { + background-color: #e44c2c; + color: white; +} +.header-holder .main-menu ul li a.nav-dropdown-item .dropdown-title { + font-size: 1.125rem; + color: #6c6c6d; + letter-spacing: 0; + line-height: 34px; +} + +.header-holder .main-menu ul li a.nav-dropdown-item:hover .dropdown-title { + background-color: #e44c2c; + color: white; +} + +/*# sourceMappingURL=theme.css.map */ diff --git a/docs/v2.2.0/_static/doctools.js b/docs/v2.2.0/_static/doctools.js new file mode 100644 index 0000000000..e1bfd708b7 --- /dev/null +++ b/docs/v2.2.0/_static/doctools.js @@ -0,0 +1,358 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + this.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + var url = new URL(window.location); + url.searchParams.delete('highlight'); + window.history.replaceState({}, '', url); + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar : function() { + $('input[name=q]').first().focus(); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + return; + + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON') { + if (event.altKey || event.ctrlKey || event.metaKey) + return; + + if (!event.shiftKey) { + switch (event.key) { + case 'ArrowLeft': + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) + break; + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + break; + case 'ArrowRight': + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) + break; + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + break; + case 'Escape': + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + break; + Documentation.hideSearchWords(); + return false; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case '/': + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + break; + Documentation.focusSearchBar(); + return false; + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/v2.2.0/_static/documentation_options.js b/docs/v2.2.0/_static/documentation_options.js new file mode 100644 index 0000000000..faaddfa25f --- /dev/null +++ b/docs/v2.2.0/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: 'v2.2.0', + LANGUAGE: 'None', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/docs/v2.2.0/_static/file.png b/docs/v2.2.0/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-bold-italic.woff b/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-bold-italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..e317248423c75c8291b49bf7ef10e792167a1623 GIT binary patch literal 39560 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-book-italic.woff b/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-book-italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..a50e5038a40569ac50f2cee39a0751cb26037eca GIT binary patch literal 33944 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 V37Pl+`?OL900001TdUiQ003jn30(jH literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-book.woff2 b/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-book.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..2688739f1f0bbaeb667259838a5ef06ecf9a5c1e GIT binary patch literal 25120 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 T)@X9ci+<3aS@reXfBhT)8I@;R literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-light-italic.woff b/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-light-italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..beda58d4e2189693806b79b00cc3c29575a308fc GIT binary patch literal 29304 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 ?{)rYg%aN&w}ky;bH8!>#J4RhUvTAPlljI0=S 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 Lkf!TzE&u=kDziPT literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-light.woff b/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-light.woff new file mode 100644 index 0000000000000000000000000000000000000000..226a0bf83583627ed9d9575063e22d874b84e790 GIT binary patch literal 26908 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 T^;oYa-GVc%0S9p2zT08|&6ZP< literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium-italic.woff b/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium-italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..a42115d63b39e9dc66c33d6294a81e0115569003 GIT binary patch literal 19420 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium-italic.woff2 b/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium-italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..16a7713a451ad09b4351a550b1d54345ea7c08bc GIT binary patch literal 16000 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium.woff b/docs/v2.2.0/_static/fonts/FreightSans/freight-sans-medium.woff new file mode 100644 index 0000000000000000000000000000000000000000..5ea34539c6f54063a4a89213bfffebb244888eae GIT binary patch literal 32072 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Light.woff b/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Light.woff new file mode 100644 index 0000000000000000000000000000000000000000..cf37a5c50bdb70f837f65c6233c0be5e4fc8bfa1 GIT binary patch literal 50680 zcmY&;V{|25*X@bjQO8Ngwr$(CZ9D1MPCB-2yJPi9yP0K&6;a#tX-pO zjqNTkCI$cje3zkT0P^<*q<#6@{vY!n`~Mbk5mB*kLBKa>{f*x^W;l}K3i8U|+&KUM z8Uz49kl@hhiij(#3IPD%4&OF6007g$XcuTDuT0PMeP8wMr}YhkNNbA}V_U;-4J9Zv)Obtx{fO7b64eK}95Ok5YExyTbPUPDr{00ex zFIa(vt&7JuX8{0!DFFZo3VJ6eI5zgi-@2+U006S^8x=ZVppdqP9^dUY8hrZ^{0E3g zFgZIzThnhY;Csxj-(!qeo7X^fuy=L=09v2F>-q@*;39$@OH(>HnST2Y{nwZ8`2zWU zf+gwgkwrSr2pgn;Bno^p^TUcqasVSF&{)$bLV0`Fm1x;M1b>Pr^X*gJ4|Lw?3li)L zx%-V10_kYlByV;#gtl38?W#m!L+oFnZ0`NgQn9L9xzV(u+sW&a_xv|*lCTFf9=gX^;!WkNhB)_#d-^G~i*o1V45aaEpROenKH5=lfk{=C(vd1>s&fUu|A( zbf%@bLxCCKi!s32yHt6==&IMGl^~^Ow6Vp2gT6;*<8jpLZkz*YyDCwOC0!zr8F#$T z&h#GuGZ%l6MSQi37&CwKt7A91r#mfG{wvJhq#HiRAIlHMS{K2BOMWXefQhRcP|U9~ zLOAoNd4Samr@z6rzxlCNX8i%Nb=|mQNONJ`^K?}&VkzRl>frehj(ijS2hDp3)kuma z@@Ob{neIm^z^|UgJiDkR>@R)I|wb;zwocqE2)lZp9y7yWVgCHXUo#v=E|WnCmRion{5Pi z+_QIGP?6=MBpC^FAzn!SCZ9tv(#S;y8LhW+&o~>k{z1MolEYQQpm}4&Gd5C0{uS5Mc{h00VTnvo&8aC~n^5;IWs4!abbH|h0xMh3v23t2?F~0l(28ApF_ah(2_E<3T zjOC2K@33AXUGVWO9*ccXA`_dN*Z8z#y2eDZ8}p=q#nBw8nv&Uyd5eR_rPW?kT`oD~v-FR`6h_$lm0gLGcS2Ma!5my>#+-AfF{-qz zbY|z#OoYb3r17)lTWmGGk%!^tQ(vifP}{*g`R^D^N!7MVRz({5V!pGby?7kZvdCY% zfGA4NEY>M5rY+V*LQX*v3MX7tBch=xf`42BZ+AozA@Ho9$p5mWp^;E zbm=Zg7Yg+Y9#KOj%l$`7nzU4m3VArVB#}KbsGZQ}(KvMrfg6 z*wm3_a88fMC!7ZD_s@GFgn+acO{8yyRsj-p~tIqK-jXlpIsFYB1I82o0s@R`!7VfkonE$s>M zS@YqGVcl`qRbw0G7HVWQ=#r$|N%_-db0QUX;wOd0^6< z)GXiQeRXP|J^XVXYZAyf=i>WDL{r$GNIjVHa$CSeL!68p!%}uPHRsH(Fl-^Mk2khd z&XAojE`(J~BX`R>c|R^=AAW+siU6#4ePC6O@ST5ilvY%V!Z(#G;4K$rJ}4&Bv~20( zjH_PGtoC+jHw*02>=+jR%R#5Oac+Z+~ZG9XUEzWhCqWKOr@zz*(|V?cCA*p0L}$ zo8CJJCePL^sc|5w|9UQnx{I9a+1c$l9`4;8?oGgySC_bWshI0I_4(v}Wo4hqoStFD zc$y+Vw{PFnj?;Q^FS?moAAWlQ;O`6j{8@W}#$U*BUUiO+bB1!ig}K~K@`;qc!@5{0 z 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 E0I?7Y`Tzg` literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Medium.woff b/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Medium.woff new file mode 100644 index 0000000000000000000000000000000000000000..fc65a679c2263361a257094d35efba5431eac4da GIT binary patch literal 51872 zcmY&;Q;=p&u3 zCMPNi00R89v0MPs&kLx#^2h%l=0Em-H!)!m(VqanAI|Cr0XU{O5@PalN+Av)X3GD5CA~p|A`U)5Ac^D#HRLUHa}d@&pg0Ca01uJWHU2x`WcHH_7j8n zKfnYKnOS?7{&0T*fb@F+kZIhBPQbUhiGeWyP!;tP!}0@GI61^S^B?ku8~E{we((#- z4kW}udEL{-Eo(cYpSW6n006x72jvSP?$R~}?mzQ3|HJ_Z{{vVA zh@7o~jR^qI0{N4($4`#Q!cYt9_I6G``FH%R84e8qz(oLsmXfk}H2E1jn)(0p*unaJ z!0et$I>rDUD32&I`)>LND-O{fgosdmUA++b{X<8*Y3B&^IgZSyN9DlZX}2d(peOh~ z04EsS!K6XX^m-6&tNO-8k;0n9w_M50>#?bPO{HS9VO6J{$2s?9Aa;cH+L+hzpHkNd z-^DHb3cx+HGpSc=~N`~FXQx|UVGVNr2PYehwMMnx-nQW`m(#3vB4^JqY!P`HS& zy!hYHI7kE{Bz*M16GVJL0d8Rks08>qBJQBj6GS}Xf7kCciGc$0$~=!dSQ8pAD$RQzs<2pT0$~f0v)6ki|M1WCKQWHo!rAc zsLgpJO>Swnc0qUz@o>_82i+v6jPUp-gP-iuijRn2uwOdh!(0riv#SgnSBRRzLG~ON zh(rha_s|$4lGJI*RMOt-G6orMlU7JsJ=?&VE1{Dqrzw}3B9f!?(C|ifKrjES z?b_LoO`}k>*CAXaT-nU^eDTp2kM%vGdedha}5-Cxu#7*|(zE^gUv_i~E)#t}f zwl(9Kyl8ixg}l{{tX%4=4&5w!`Pgv0x5y4&6y;% zHe?N()np!dqNppDtk!(TS^8WpZ>O?{F^-x2v%B0glT);;lT;9gznSiBXfB`nG|ltY zFTo0vGK#c|ifD>-5RsA*1;dDzREepn3&D_~7=j>#+zAIT#og(7G2Iy=!oo@+HEj>) z6tCO_XhR_IVG-1oGwq)IU|7hE-F)wTjwdG4oQ^U%V1VO7qB}4Y39@)$IApFHsRbAF zhfExp`{#AJy~C){0#F|W<#U8i0=W-J0t{h=e~0`!jpyYn!Dot#KAy$+L=+{Gya5I` zGEcxK@l!4&LFtSS)P4{Hil7Gs%7++WZmqPKW0~OGM~TSDM5fN^8?`!kJ9&>9ma~XP z&mT84v(8HI}?>&oWo-RHd2Vj`Wx->H$H&|6aV0Fa7A(i8 zqzcs|Ej;;FwJoixkpp5zMj%3-W0CZsly_Ecc7V&y>5iOSj>BVo^j+4KyfBGN-x+tYY24#YhspR-r47!n7W`hfvP|G^)8>0nj{G+nz{6Ta^8tee#l%(4{vn2 zj6N%VOc1MxTK0}*;$ckMF69B}Q!=kB! zBerTKqsq&^)zrU3qpgqVq6ZCH39Pe>A=$jKv zJbE{*UkT0kY8`>yM_C_m*K^r&jmKJBliRn?A0XGe1RiwP_tQXjPxV!LN72}J00?`; zPjj6WcN<|F;Si`@9m5|2T`A)qpo|G^6md_GCtqqts^5EQdMG>nMvkjxlr^a`9{ojs zDH`^-&e%^>?aueMOos1woM6R!Srbg?DU-z}QFr;eQyI^DbF-exgKh$2m9WNAx{VXX zQaxOR67Hu3T9qJgRq-O^JouU)@S1Q2VqR4PT5v<`Q(o9wDcs8Hi0(O=!_)58qil?Uiw zB8>7Bt8+L-tObl2vxwj53$>IiSJ(@N2~!qzQ>8!(x4-7U2uxm|tAv?B!W$8PFT%Q; z61+g*>4i}LoSjDc1`+xneLZ76Jqv@Vy*)iUaCun!nBG`2{`ni$nU&HLu+kGSn1Am; zFj32~a(m`S)%^4P{dd_=n5KQvz`@Z)MGe5fhfWDO$k2;*_$B@Qu>guPFiZcP%acnk z&S+}D;5XOrrpN(8kcfhiObEp4kXN*Wq%B(Z2v@y2lK#Ln_!KiKd-8?izc)>ataK<6 zQu$#9H?`(6#KulfcP~~y?aZcl?ytOuN(D7n(`LolNOC^M zJC7dUgQj_0nnu8?28de%R1bod8}u-v}bv|nuO@}^mz5N zC~!M{fr1oK_QHh73KRkP6d`*Q{^m)-u#$PqW4Y90dEAt_#FTlAo<@K-ed2V@G=qKu zEJXdaY^bz&xYc+N4x}(`NI}~J0bNiM0>QZLLK;7M)S$pF%z!_CLI3fEGWyrIFr4y8vn}k7q5Hrq}?e{q8roAsA;Klj{ys)G)U*zZk43-;@c#)V^T#p{K1rF~VJ( zgnN>N^by+FnBi(lck<+z{^7rX$|zM^Dyj=V_4x#*;^Z%LV_p*$xsGBB6}|b;4ED6h z)`bl#a;0QFv;_gNheq18cjH>%$;a0!LDeLejVasVmCXyJCv30!&)UvmUhABO?)uIr zm-pIFZmsBlX$DsP*<1p$VJJuLnULf|Wfu!BAsqXetyAFSv#Wa-_O4v-nL<+v$A2@% zC-*%!AlcSzPMci0+H^Kmu3X(>y?S^qvK{5T4sM@~pFuqZxec-nv%#~kvbT24h@C`O zf2Z6ZHIg6eQnDt~PFXb?-IuW(!_ zx^{F9=-SyeyRE!m?mw|TiM-eO4F55$`}LRlJWE^lAIcef7j?3?hA1c0sYVlLduHcU z@3x7>Zj%*1~rFoA}KA86l>z)g;YAVw9kiUT@hLFbeo@Yw;uUU zg;UK^I+7w^XL|pHUzCN@vr5)Cw*!GQc(pQk0##QvIfg`a%7sKshj#x(atB@Kbf+lj zHOaNmwa>NAHQqJq^)EZ?I}tlNLKD-mizJStm8m3f)0#L%R*SOMJ>EEG#^1cZY0E4X z-4%E5$?3ek3??(Wy=|r}w2N#g8##hVe1hC7`;JD3JBUcv%FP$Ol`53K3VVZhJutB>pJTdn{j&D<> z0P#eL`$WFt8`3hHPO+^0Dz;*phxBBY!QEdnkUoSWkxl3N?L8nhH0U$5v^liM zBf1nhw6rd|%&Y|xRXwEoq3=v%?d=j>g)eQCbldnR{oloer)Xy{dr#NOAQAh>sQ8|8 zp*=RO6Ld#r3{|H8bt|SD2hK7(0b48RGdl#IBU-i-Y4$Bh$AM+X4t4?o^2QkTMxV5{ zSOx(D6Px13P~}Gu$Lnv9v`8*Y{dqiuEnZ++6QEVNfS)uV2W=_KRC zkID{J0jiZTv(^-&V08o4LNr?ui}d1iBbg;>n^{$xdDqU8!#Cl`MtQ5p_&&5eagnmH zi1NP?6+!tbiVT!RbCd;jlqGjVlM&^GW99kf<;7>^dFkavYvl!Pb%!;u(DI@til!zC zswPUVhw`#ul&JwpS{^@3&5$EHvOz8fhE@{ba6D8XLQ`d8S;k~hlp3@u6t!q*D+?Ve zPptLy6E!c|V-|@{&LvAPFHSF5N-t^B%%Ad9(`iuFX_Ve<6y#~t^l6X~WknDW)e>)R; zoX37#7KNKNg*z5<-Q#IG25~(ATpSW!9AjqguzQc*vJXPNL>M_F+_D=Mz6TW8M-@0^ zlGrD~*hfa%hhFdTrtSfy?joh`GpOxAZTAb=nu^*Qg5w(y{pq#OHu(LOX7YlOa;T>f z<7;T~XK?Q$ef9%H>Mk~F*CJ)dgmv%Px-Y|eaNW9}%X+-sdRWVP((Gc2{9@?%q8H=h zR7=VErizv`-DSePK0w24D-q}4Y$Y8lkwU7A44bo3vx^kpsoCbN&gL=?&kPgKf)kR` zgL3SnaBQWjDpZB>TEqc{zZ@sWj{<-J5Cup9)B(HzWq=|e5}*sv02Bf!etd0!4d6!u z0Kk5;17Lw90N_AYKal%@0{|Qt6aWj{_Jacetb3+T9FOb(J!0@MJM{s$IC=sN6)IKD zNtq&hynH%81vebuT($5MytswAwtY$-lMZc&enNE9$`I4__L`NOFlXWGW+uUiou>v1>BjMC+YC#;q!f zbKdd&Z%j%Bymh=iJg2(w#L3Js=@q)5Pig%gI=ZZO(Zmjmexcl6DoP$oBWDpK9P@`U z!n>ujze(p}zKzCRI};TwY^e~E7^TXfnEL`6LPAlLcUI2r?RS}m!UodrpV#PP_0|+ta z+oz!qxIf^w%XejWs<{YkA~Uqfa>frFBc7}SI!NASlXs^viU%ro+45)V9R#AnM0<%q zgSpheY7mk89`JNuTv|Wixw`sk7xuX*_(K7BUKR>e&O^t+qInN}ABQR?;d&h+4(lK&3rp$g!s*Tv)LD9;jXb-6)=So+^RM#gH>JX zbr@aNgejJH1o2^_N*wcC_1=3nshMF#RiBHg*X#{*IiJ4BLJ&2PA|UZkS^FqVGGZW8 z!liB=ZmvEC6lXb@jqcnH-wr3fzaP4xvE4jX=wWz!<!Dv+gyevBvSfy6=lSP%pQ$Ga}D5+(sy`m?M#8&)UfG}&Pp-2UpC7o?X}#5;aZ zFC?1l#>ZP!H5=<37W4Rgf2w#6m@~47ygcpg84_CVC(^i3;s+o33MTf>ru9 z`QI&LGWM*+X*3bwTNV@h{B54SHqeNj7m22Dr_aynaw9FabZ#3j*bcU2XKBaq&~qQx zb8C{5sv*?!Orir&bSbS_+$HyD#!1AvNX4VuRiqnAL~zk`sCI>rVo8;npamIqyqIX! zOzn;@1m3+x%%nWcOX=3MShSqddifmLvv|4p2qc?4g-}j|w?<8UwH(#uXSUGy;|q95 zSf@%cW4}2rIY3>IF4KbRCe5cG_=@{d8lrb!*+)rPf+S3yA<|8zoC7^Vzys|!@ zK(^iRVhFFJam^k>hZLe8=g_4QR8c#snx`ocShP~BI9PfoFyXQp0Dy7DWAFnF?=Q}m zD-zB0gAMV1tITDT^a<^%7Fk!M{}axBn4=oYV*3c#cb4(}C@Xmj$^Lj-?*1}vvWuUf zp>>I-+iLymG8{<3 z5u<%-gQcapo(#F##u`C%4X>=soblp`TJQR4uYO(O(8fj2>9uQIu*~e!CTo5EGnU-2 z7E~LrK9S7KN{Aw#j_RKE1;ix%Y&B*_zi`Rek(p-2rU2=sK(wM(>oO#5c5SG#^0Nypb3k3bc1u|nCM4Z3$!=o9QJ+H)r1?rw)H$9EFBbpymAGM7oSII|s z6=@2w;bCR)oN3mCrZ>P4IWl&(7{PpA%mQU~>=(@fv>U;XA&x@WxkQbmm~fsiQFX@# zPfuQ%Bx8nhs{4y;z%W5BSf9Wv(GrKR^?Ce+IeuSyJF%Gw=}Vh<_{>Hw+TYOHs45WV zQ=fPcj0Y69oJ09^X1Q|4m!d@rZ&k_vmNH|O-_rWp` zw4BRD6_LdCr4ebFD|1d+R9>NW+Q?F@6@Y&fVX`*zptjAk$JRF0i*8iGBlo2 zKOLW)@vwMxc0nS4UNm#$_rfXPAkzXWg0N&6cO=i4@;jI=MdUt|wP`GjSn$9Mndjg9?U1K zX;pokdX0Y6?k;cnkCf{pLZ|SVd!X9D+u)<`1-4qS_Q$8&QX-Iv7;brXzwusYBsC7P(h&To{52v>(n4mJx>hNZYH^P=FSnEe5xSfqEO z)h&@)ABWF$k%&-JcRft^1dLY&tkfOoBa!%}BoJl7TtgTSvC&N@02A;8tP&+fxe=2X zTCEYtSupgI8`e}IGzl`}6SxW^d6tr&Bo#`BjrP}2Yw(5W?Mz1@Lqkviji!qT^&E;u zxlQRK^&<0vhwx)=MI-5sMaFveC!vNUI8XLPdr|uYc~q3#U+5Q5F}Lbw5lG52UNOXL zn=-=PX27;wzIOTN4Bj7 zZLP=$wyE24*4?25T|(RZb}Y2E3>G~%CXWf<;H%=4gQn#M!&BwJumk1146DWu`#4@}KN3{6RtQPXN6 z&CtTK;0fD|f$0f|swjDXDHA~emBq6w^T!sNT!C-rdUa9F+LhYUU)dL~W81YDUzC zH@KqNrg_*!3wk`Ra&+uX**21(JH~S}4s(v3GDZ`pm1LuD$vqCeP-w^LIBA$?UMI$Z zpLO@g)3I*xJNc6iZ%)#7Bn#CA;MjFgV)6F(9=5ZEJC-I$Ui7xa-#a%c4!nfI>i1OU zBnGOb_NssP$fR(KL3rIqKEV=J9i|*cji0P~9CTRgI=;*z<|%d>pw_f0VRw6uYvx79 z1>?EP2Fk!GII1JqkWrD8yFI=RPI6uCA71YB-;z`H{sebV3m&2s{=-oiWKcvilZw$` zzKy`{Nt1)O$b_c=97;LB6=|Rn{lddrEq=%u3;fndF)UIVCX?E4AD)6ujmbn>T(!7^ z)jjtmdp1?e-K3ehGBt0OaOaA#L1RIcyhOjv+S3|Tir=X6--dQhQR#_=eFz6M1jMlA zg<$blar8LA?5PF0Q%a1dPHizJEs%v&dwo$g%aS%+CJJZpF!T7FOkNPkO3P;Rdqenz zHY<43q3?TDEH;FZm9bYOMi)jQj^`N^QP>Wvp#73YzD33RKz%(^vD19>a@)kzX!jJ$ zX_8Z};X{n1>B_47K4Hq~Wt9P=8 z{p8Bi(M8hG!lP~+jz4`1_Os3+vAWPzp)fem{L4h23#&Y}c*0pNDs>kKpWDbd{j7Mo zG7$usWt`^VfMfqxee!O8itUNuGW^-L!j8ahO83P^OipfiQjJWpY#@2>Ebn!zR#Ikg zLfxHu_TLQl^N^OW1ZRMP9rKG2W(lq3{U0FVHh~6k&l5x91En-0DOH=janfpY=~OdE zKcOHMG13hGdBZW)JYt_~PM@{#UsnH^EJ;%PASMux^Z=GNJ zF6%-u<%tm0T=sQiNOkRmWGCwu`O>CMzK8g*CYN`@VFY&bu4!NQ^_j1%H_d~k~BNh z8T-+g@#^v5k~>pNFA0!}4MF3IYvnDYCdpq~ggKMhBw4E%P!q9-b~NAm8kT`F1Iu!| z!^KtudfVWG88R>jL4-Yi@xqh_mA;W!!|IS{wK1+W?WhOS!t~oft58z+D)@C z&qQ()1ZGq25fn5KJ0Sy;DFRK)MTS-qg?gmc06*$pAyVGVpwQISK+zQh1o9o^+jGcZ zVp)fOkSFNH?4Q#@_+O7>&>wPpt9FqUtG-0Nk4O~UFg_G{K7T2$gpk-&ENz2`b%n~n zawL~l+CnE1CEt2x6h6{@9uyp(X2p(0_CG$}u8-4TrFBaf4ZxR+z0=|``|*1{WISc_uwJgPb`>l!j&x zaLNd()Y|katYpxv6dD>u1CO45c1P<@nyjVl2;K_yYe89gT6UUbNW4IADE<| z6SB1v9_rug}+Ujat&W40f8jp4Vn?Fsw zY?CFiUnBW$VjWfk#g6+c9GMQiuaPDv_2e`*THdfINxth>rLF5?yl@K=d zrH7I$V84Is`fan>;hjlH4__ijAP~HdxUom%U|-&)x?Xg8NDAJEs>yH>Obam$J0;yA zR{RTauP(;nft}{?Vp?W)^w|sB&b-yiqsVJiCt-(Bc%cF-HC`|=1{K=bH3Fmuk0lxg z>VKX=;f9>vc6YzprA}%8dBwsFUmb^Ay)Sf~{<`_vhLrAZ0WhA!2x5BV$eN>TqTWYn ziLjRF;}r#3nhS&I{H5BNDlH5sx2PcerK;o_td(L0cCFcU*{f&nIm5UPlB^f*dp#** zB;&;iA-c|#SeqC3x|E!?>?wwA+BWxj`(-l@Q~mWB(lub;P*hS-Bx6T$JIItR74s{f zB-@@C-*!GVBgQ&%%9UA=z)IhmQCaU~&?VaA+q$*-mdKEjA=NjIZwGomj|z*U z^7|42+A|Fu(-$+WJ99smWe}3~gk{+bZD#>^MWsSVf%wZPRzcC@nsvS*bUoxuG8|^m zX+5?VGit;d3sv#T*6nR41IoYAtljvgwY8>rdJkeRKlVP#2UOR5PU4t=dy7z^~o&8f! z{Xy3w(p_`Q8gfrJVT`zq8d^iAxem3VoJh5HYwM)7V~}MVcxkZ4vAl!IXap4}PRn0| z9;1{=`n?evruBwIuC1?ryDdh}VyyM2C*MEMm(AT7+M-9YS-d`!@9Z5tfXnPct9^V_ z)Vt*&;uxg{R!WUdC_R zv6?1LKq^3;Xp@b&A^#)}F&vrT%_`D0L06I%71sIV#D{=te`^WK8WRv7*I$#A&=P&S zy(Uz`>;BbB^%2x=!BsnQCF)f(6&3vY9)<3NrWC;wizfK%5Sc5)2Tj5qmx!U!)r!WK z++C#6kSX`{EccdpH74mccU@L--=osdaLwhh^9DkWqo_1{UZ7MKa=oZkPV@LcQnL;B zue=NIou;Z>u^Z2>XuEP4U1QjJrfb>If)m~4E)nCB{sGDc72Q^AN-QvfwuW_1a>dje zu;S%#Tmqq7IIx1^@AVWrl${?Fxtzo8Ts0}J?LYHIw^O^8@ToxvO1HTZ_eNtWu!+=? zMJI6Fw`GWTL|hnaOkwdJ_0=HmR%baHHR-__O&izuSvOdd%+2^Qfs&(({3uu0-SJgR zx)$@Rp&x92HtfC!HoffJ&@X-A!?66i`e9iohR7dVR6kINNyH<_ME zTVvR2^eTI*T6!>#(f9dD*s*I|VLsu>CmpwQZ}3D=Ip<7P%%^(G+{efeqW>^@EV5HGm&(3%7n6; zV~0fK@BrF?&uCdR@qk3Twoyi5lzaAw%AQBZk!pS{o!+R(ybByYg;1OmzXE|J*J$-P z>=`5!-h}V5?P&_+z)RzMFRLb@S%Fi~mk*(#0_sxCMNl5{_s}mtIs^*Mf`tKKQPKH| z+;q%VtT{Y^Ti|t*Bo>6dxmg}@R$$!w@)kqy3EH~&PfL|>pVD@d^7+Fnt*h`Tw~#2V zF`N!0vF{msyujc5g(q@6;xRvaD}I~+it0zQRE zrj$FYPzQ*4GEPUYhI&a%TxEo~e%Dw{AV^7yX?z8VoDlh>EW^=?x6sK`DFt=FtKE%W zdO7Vb>)A)|p72qk<1U_JO6?UUbp^BY-8J=g#)WiDjD|O{_*2r^8mo(l*;!g=s8wB_ z1qDv5OI=i#t4x`{$6@CY$Y5MSXcm>;_bL7)&B4ty^9xu%qMZIMi>Jf_5|rB;FcBG5 zdbG$N`}!h$ea#sxn&;zb`1*Y|9qigfII#{Mx5pJ68u#o5wK>rregAb-)kt~xu3!~0 z&f5-uHG+1W8OG`O2@B{J5~F42_Cdlg1v^vq<}aA14(3LP5dPhW&8lSk4|=~p8~U^5 zZgT0B#E5pre}3Gj`c&F+Cj^Du7E|1`SjT7l)PHsssKb*n4Zj68deml;#HkqhJ|_Dz z6yD}~)qs{^GMd>=iuLMBQXNI-Aux(O|8N%c6X0Etm>YU`hQ1JRXHi!@Bjv>8gX*hH zZoU#roWO^|*$+m64+}70ngJ9@#Lauml`8`#6I;=gQm}s<)~Ts*&XM?S>t&u9AJ{qe(W+mcW0Z+SEJj#b~D1T4tJ zB=h%o#gOT&*$^Fst`qjn3YpB1tdv?gXxPN+RJNeWj{VX>yevIR5Ke^(ifL%hE5K?| zt{SqJWMC7w70VOa94k9x)Q^R3Zi_VLk5#=_@$pys6}s?O z;;=<)QZD^PiaUN4HAJyuOx=E$B_q=Qlc)v;2}hC$fk{^ozuEA5aQ zpZ9D!Uc4vMARXVcl8+SX7&(qEq_Oed%0ata*KqQDySR*v4+5mh~ zdPbs;r>@p8i6LHS&57gjE=AXR)x~x9ViFs>?MCo%C3VwIUbr3qv2C&IhJ`G?TG>Xo z>C=2(lv>?=-R1B?+GHdi1{n6hTdRE*T8ZiGYd3%Q1lWSP^RF~JFl}zFyK&sj6WCaj zG)JJ#FxMjr9ZvM^D>OLw3-r-$SC*Q&Hq^nGKhO!NZ3c1JHkIF%zCH{1{`=W4cERUP z+r);f?=-X5cK_J^A($?IBF$V@Ie!mExqf{-Lu;+O+`EG=6q7v=a zRn5ZiaE6wsq3q>eVEL7_2=&_Lo|`Mna(Jy^W{mX*kogDLTIyxXl7tTfR?!zlCXpk% z4L?7Kkuj!HFSRI~^J#y~q7rNga)#v)rxov_dOi#7qf zdq17D#A)}=>iy|a$Llqq-r+T!Yvp4L=8=zZv1WSFZtq?yfwTM;^n79M>u^Z~~Jctmv)f$H!NmNC6YaXoy4U{Y~{PL(vx^MgQs$JzeQ@2Khm6}>e z$8EOFyOlx<2(Ex#;FqucL+;X?XV|F7bI7R9DuMTN`yRpfM~ua7>U`yPXkImpyc*q^ zJUC)LV`a7IR<$SxWI6Da_qM;(76oT|%X4xMiA3QehA0VK9Z4J4AoArGKb2w3AoDID z54*1ssR~|<#+FnlyooWfXhHdpay%b zMcTRT%<>eZC5ruV0IqB@Jhor>KHZ=k`>8C(pLJM76tqOBB8ObqsL(v#GF7R@Nq^Pxq8RMU9E@-A_tVnR$9a7_*nfXmgK0cE8-g;_ z3EXV8A)LNqt+NylmwxvxW8j1*W*NWtUMTU)`~C@)f56FmVZ(lb^I(2o5U9)g77zN} z_jJdw-lGBwr7?U8!{VS_=h9;R?eMjKPY@`jJ^ANb{^`9% z@l>EY9k{C)0<9Qms1S_e`n;6?8M1TZV-Qw=w{3d#3hrZT*=zct9(4nnc14HZRJuT+O*Z5B2H9`*Ez1rN+(h{^R{|gmPcHZxn46bBwI@H zS5&gXz(LKLE@n7>Xzzdwi~xqC%YI(=3MC^8x%nxh!nYtFh)6Zv6M&PEfoDP`E-hS5 z@Nl}P`5wDDUSA9hQ0t!R8E=%N4?taAG zYR1}|8E!qYHjQk8C-nvk+0-fk)#x4}lC2cVT}XiuB{C1f9hO(hJnsb@2c;NiRY%YfPJQ3Qn)jdO~r3~};^cQkCb&&NG6w3K9h9$(JW zD=6tAWAhopZF;JyDU0Wd&sX%L`ec8@gB*@gaI&9Js$vd@EZWQmlcxkE}vO z{vNMe^v$>z_*h|yol1Cm-xeIm9I{Jp9u)TyATfWoM)Gr^K<^Vt#KMhdEe=j!h z*WRode^+%$prkP{mH6WEnvvIm7>^`ZGYIS3pfwdRaz+LC*oTuluq-QKmBw?ivxwPe zBBuCrG36PbWTW=&0c05FNt`JJ3S__c!VKu4Skwv}6ddb`Cck>seSBc!HaGdNLG~y@L)l~3m)fq%w5Is(8U&PQV7@oC~nr zTqIn$Zi*!D5Kq2asBFc$lxc?RRgYggocNj}-Ki)yUuS+JnEj2gDYi$f?=fHeKAZ*PW<9@~s9>T>>^yrgPu1jMDo{-f{j<3BMWyIA zFSF{~?z#N=d~N9AxFv! z%KO%%ItkupS-vyHTK4&IYP!+bTo7cI%Yf*b*E>*mDxT(KZ$fjdloLW|m&^g-65wZe z`Ad#{GhZ{uQo?mw7B;3eW4vIfwmPq@r<`r4^nPHZuAq7=HG&MK>DJTgA20LD^KI9A zg$;N{V=Yk_dn=s%9SChd^?paiA?TL4%$a zl;b3m*VDuf8f<8weSEMG3{2?F*npr8=Ga#7DQa#fTY}I*Ns=0KzFc09Tl03rwGj=$ zLl%+0Yx2VJhx$=_Fy8RQxTbJjzxkrs7bvk~D4(MYi==n(4G(nv&d_qO>*( zXqy|i5rGG~ETRcv?QRQq2nzW(JC0Rl06-e z0vZeBLikDmOg^Fic|VMK0Qd!0heivtI+d_ zIIY0<;3zNOvU|tvX>L(Oaia)pg=W0@54#?Vp;!a2wtzZtDF7FuK_M>*ni7GT46iZ% zj8pB^dQdp^E;dJta=ePy%;@;-0U*e?3 zeRW@_Fna6{!E}Xs8=u4oYg<^!5_9iv}zWrpA6GE*p%SDQB}%#S5}P}eoaf7V5_ z3&GqkIk2(l6oacX!O!V~We?z+7mEMHFInu!R0gl+B;LnXU+D&a69g~Mtwea#3R8zZ zi#8o#WE`>qF3u^e^1Z{E`BuK;V;}g$`L^TmcM{)#3WE_JsuJ5C*bJ{17|l|&Hx{YC zs6z=vyWj3dvYj{j%g(rMw+%yJ26VbsnYYPc-9M+vQY$1Jh_Zbz>eer4-vp)(vcV$0 zAq+aY1Rfh#$lf%oO^)MU`GH(8kBmvO5-SC;S#ve$V9&xg+q=8Ho`=9^J|Fp?ziHos zmHHTRFO>Q|qj-a4dn6z!GE8ZAxsjg_5E%`c-Eux(X7IuUkU2AeL|9rn<-|-c#Mxa^fRoy2yYIBe! z;#G}lRaM}$-Taz;E|=_8E&S4Q1L~2&9a%Q`55GFKT9H$Ev{5{K>R+}^C)$*2PR*vq z?E3)!gaV3XWw|BnBD*2TiXEMI!#ocOkEZjZWA`J*Hj|?5VZ?^Dh#C2#C3toXu!~lrxV<*9lk^S}F(@!i5e4b%BN?-`pv*TgCbM#VO?~rPj_SAAj1*opoP`*C zju)G|l`At=){#TSs92N(EQrbAM1h0jVFQQLWsTAi3dTos4{*@*v{0-^3rGB8w)YU; zz~zXS&Fb61NAYF$!&J{*yggJ8IQJ}qhu*}N8;P#I#SO;DXVwEr*)+YL_L&)ZNH=r zJOnj#xE)%e?mEEE%xU@4k z?cX0BE+G`%?Ot`O<~81VPV|u9%#eNQK!Y&faMShwtsj04759CL9v2Hozemd`bC&mV zqu*^Qf^2&*C;@7Waw0A14pC_&- z3dFY7RyP?|Z!9mRmOd7G;=oDGqmin#g+r@>F_4$!FTNkGqaPn@3YMt~*(m8$P@y%1 z`z~*I@OlvI%wC|K^wEXY@2UB*+R(!bObDuzdL<}hX~gNGJpv5ezL$8bMHH|_@C~&$ z*Qs0QIQZMKDWJ)v{nl|Nyk8fb#(`mA)tsJvB|uV9RSYARk+7pm$njA|o1FtsM09l| zTwIHnmU$7aDbo57?wT|UYSF7N`F^eE=xx=Ty}n*3?O8s}ukwYzFNuxN=4<#SbLHj zL^r$g0(o@CLAH#=8;`H1(rd@BCcdnVTYTMv{>Z;S@fa4l<6V70+VyLP;dedzwIYUZ z4CjMtjj^*7F)KHvNGVM`5clzjrMU)4`M`BA_bKMa&pi)T!3U&F`$3sPmm+gkj49eM zsUT97sdrt}9kx!mp2Pdp&!bdimS+>VQ_syIx4x+#dR4cb@gxt^(w#=KvN505J)a9s zi8pi~I5OfBFvazU)V3US4|*GR_A#}yl+qw6K% zKS?26C*y;@`I#F1^6C3ynkczmxV>JOvubXEQ{%#4sM_J{agPMlD~PaAL9AcMi?rFg5H z?u>#bKER1E$-4J(v@nk*w>}mUGNt;b{%bYjSoGE**xT%Os@i{W7^5CW2ZTMwre|1? zK4y}ldmYB{7n(;Hs-tx~?lAHmgNW-He=I1i35i1`gQV+h3%oNtq+dhbD616hY#}`8 ze64)qS)D}SV3vlojNWNlHC~h(yvphKse&M-4IJ9RiA(X<{{wSCjK3C>X~EeaXr1bC zbjSO>p`LzEcf*3tplfLL)|KcE1Mb2b?-e7eFfhp$5I#PMO-%4$2_4@J#CvROubASP zOze3x&)U$;*D74<%zQHi&H2rI8*)TLv2an(qTB-sfGo%5YS? zCKNGz!;n4N64C##q=U_Q$*yF^d=n)F_OPNkUu2?G#$XDZw6#oA}a`cx&+wn)7UBZsHMO z0>=k(kQNFvz;9bjQu5RC^SH|4wiJW1V0PxdUI)LZq)%?S9yFkO*Kp^siI-16sU|k3 zJnn$bLp|G*m?SD@OT~3KtNZ~KTOu(qG(>bN2e49eE5Qk7#`Q9$s<)T*8wUE850>?p zdM%~>`cQ{?m(d<^2P$^e%#W1z+teCOR9{n}jp?nQFjj?{y!w)>?hJhV#t%McKYpqD z=*^aqmZs*~tVy5nGEm_YG%(X{5{v&&~>CmpcmL<%%#0!Ea2E(Qtk z>lEeI7vkPz>Rg~lU07pgtx6+hx8}KJLBB-2wz26!^;EU>N#id$h22vz%CM`i}FN+Sdbw@;UGyL73Mxp`~3kgeg87%FuR4o9b>IzF>Yjm#a~=dpUI zQIi@rZIW>lFDigz)?4DfVOJ;oyMKz`5A7?-mK?rt;dfI5Q@`Ukk|fUTtKTC|DPP8n zi1eNj9zpIb?JeWpLeA&uqS=TjAcBAh6SgyQAUJO9w)2pq4A<@=vWQX(8qUn zk=~kEwY$8|*kZL;8tcsZnfbm&+e~916oCK5)q{(@dn{k~2U3PAQ z`W9@mCGnoakpI#arXgj9*kx>TpCCtZ4f%o4l*K&W3ujOu|9A(J~MU;e=lUWQwC zgM2)@cL&*-eF86P=V+rjhH;(q2-mJsLmk7GXjH~|Z6z4w0Lo(_ltLK=n2qd!1j%^? zjbZp#-FcROIhWEQESh*gjtK}XOiW*#o3jQQt9I4LhJ#Pv^O@jqTm4*BL%_NqHfEa* zbzvu2&l+OeVs>%W4!7(l$)U#PI>Y+=1ZvO1JVtHeYjh227Cy?BpjO($IwRZ5$9quj zDeqX$;-O5rg-SZ^1XQxoJ{K zHK5JJM3s>_QN%Hg2u;Ps#6(Qm^5RM+vl9LCjW4V|^PSV*Y$IKJh(G%ZUVE}HkS;-) z%Y*KkiUs*ei_$dZ@|c{1IgfJ}t(RuFSJOGnGA$6E!^K8Dn$U8@!pl_hlNNu$?ROK^ZSD)y6fPZ48c568k-Bovcov16XWyi4?tPmN09|s)LJM za@8I1@4V((bZO zco_gcgX?#=L4!Hl@L_}QGQ%I0^i(G`R;m$Bz{4%<4;8FxYV?>Ym5W5+LZEsHB?kUl zd5>F1_pTxW{!k^Tme@jD!8Jb9nzR+jsL~4K6vSF+JA*m#Zc(qM3v9tLdqw<)QN@Kw8Kwt}l4(YMlV#$=pdhUt@{Ci_&xvDRb z=&M?uIrC~swB@GPUc0F!TJkEHm>QgV|F$vs9NR{&^mu+aKK>q$XN1N-zgM(?4&Vg7 z7sdEzH?Vr9%({(Cwscc9Wy|@lT=uk-f0xtQP{)0waa}7r&mww*To2Gv{RugWn{qsi zI?!_7*BX&>XduIFJdgg?LF$bSN+OdZx`-s-gYXKg9a;fH@C4j|GQLJ?==A8Szdbws zj(4iH8smaF-cz-!tlr-A#rn><4o#WHG=Fo+w&DI=>E5GGwZ{3>U5|f(Tz0KxD(0zg zt-Nq;$G!nSxlH`o)rYV9n^?_`f%prA@{u}_#d<-8PY7SZH6lqJ;kJx&R@%leNooa? z;Ug$=vWV|8DF(cZO7&%&InY8Ctk4WToMegg*@A+ov{F>s0AiI@Dx{$bu4JMp8{nd8 zXpO015&D}Lydh#zhLhvQEADJDM3CU7HBn>(P0#A4IQ`V#HVcfCLR8*<2y zY@0}>1DAERZj0CJ7vJ@MV#|KS)Rpv)H}(2Y8XDq5O;%UM*n)b@Tpx|52g0G+mW}` z+O2oi?E>m@G&fpH_G8M`cuBd=GepQ70rwmUKT zDj`S2S2b5&c3ozFEtR)gxV(isZQHlrUoMjQm6&iYU&GU;Bp9!3OfIbc@S81P3if5WaXv87vXvt zom80rP$^}BtTn3h)Lm62nSoU}A9OM|{vu_-z@BH};Q(XL8sTYp_!9ncQra!8P$+Jw zu$53@8C$NRsUV_lE)`8@o&qvQ)=8I3S-UlpcYNpO`w~N9_IIRGGuULPu*;m^sj=o-uqauAF7lC(<3WGowt~|W} zF=*s61)+|1NCzUfh^R456}N~;`U9qT)ze?-FqVdvE0dqf`7cnylxi{Ynpq4W%SM=z zgo!v8By?7EppR2i)SbKF-xW{5zqZ-=E1Z3o41Drmn|20go93E+_QdSm?Dp+*v;TPX zSl@}A5u{(tS052^-_{}gJzAd|`BbwTm06sNw#Sqi^JT=T?qC6ET(&C#||7A>mTbM?Mh_EY@u%N*i9_m^{I~T?v7K;&Uo^A;Cj#93_YS1N(Fe>-3w3gLexL5l5@_j;QA?+8PnU*V|%u%G= zT;gso(gu@`8ny6ACfX(kPRT%MvDB8)BciwsDap>o9sdtOewb$0`F|HiXXI0rm zKh3P8Rh3;3SiCufYh`%F7I1?SE}oa+B{F;z&wu4`oyt!fih6SI)#ue;DwlUD%Zo3_ z<+T^sc=T*U#BtFGGFzYUL5vjY7Y68fB&n<#ls91R8w%d9rS;{07t4Fk2V{6W5B?q*p5SnL<|?IY4VzDY5EO8& z46oP%ZcxJMd}8nt89s_<7jZcDz`5yr^?CJ|%H>_k@^n72^4dSJ`4orw3Kef9C>FdDQDT|6~`-mSDHY|vyYV%j5zYoT#|7flW}Xz z8;cyyO?hMe6B(|~EB{e>?1J*xjVfryPicu$!lu6q<?B~Vupd)koCXE zQ&EQbd}(0C8=!atJvcZ_?I$8#M;c`N35%Y@P}mrcyF;0MkRBv#lUE17BFG@lqpdtL zjjNOa%o3T?)3)H3f73C!Z!zifxV(lD(_~Le+N8E*0@HJEHiz6k{X|J^pxqUpv8eR} zwIP2v8gC%ZVCdr^!_>Cf*;FFZ<^hd zP2}CZoq<4SFC9xdX2^$BnBPe&oaZz_&&yU-A-w!g=zg0AuK;*?xgfy>JYPFP&)4q2 zbIXE!@4CSAIybDj;PbQcd0#9vyn;V5n>*fXQFFy(!W(I6x!Ynv2r^H*M$!cbblVS3m#OtueM8XV3fo%}`e13J&0JI0TvM@pxhu0*H0Gb% zJt(%SRce>V=Cqd8S48xtib{h`qZ+EX=PEp}FNZIfdn!W?UlLsWSC~UO%0qORjtf0Z z0e%}j1KbIW^TUOw-J#%&cWs{}=b552(8LLa7kK+TxruW$!w%blO1qog=X$#ph&dQv~4z6@meGC+12rK>U{J97oq zeZS%mKxtE`j^@BbmA#B_Az%U%BXb($L~Eqh`oFL>bg=^i|MqW>_w;OjXyB)Iq|-ar zAJ3hqKGDa{Q)g#Zz99ravc3b^QetuCvs=w9DFGMquDQTWKot@VuG5rIaNDdD(AmNI#dDB+afZC+kwD2AgPs4Ce6 z{;zWVI=TK)fEzg+SLJwqJ9&A1UVBRA@-EV%sQ(4Iyq4tjEvTO=S|7xGA_M#o_3k`< zpL@I%oh-Sz^jFQ35#jo2;2Bzr)=z_+&&P{dWMpwLN@HYk)$FIMrYsmr+Ljcc;>rny zI;DhYPDlyK$x$jBc8I0*rqtd(uLlSxxtMlk@0lEojaCmCQ$D-fT3S=d8gjzl#<8?tunv8u=e*OoS3HnQ=v(i>4jt0~B#&h1J?M;&e+zM-6~(h6q6*iWd{1S=StXSF;Mv?L;#-UzqC zF;n1 z@-+GUpv8aTdVKahbeNP1{Ac;`@;T+5ji6F*SH*LtT^V0Lk@2Ob_)-gF8y&EkzD~XQ z(SPUzNbx~#qQ@>_ypW#zQ|OJ#(Lx(u=D{j@>)=xO$Vmx%;MhAIT#DjlmOr@S~qHW1HIQ3T*^9>qPiL{FCIP}_Y z$*%sPmsZ63MSLgF6~1Sk&f7{#S7ozo-U3_7lETiMDq) z^=VXJ^enz2K9>XhHD~dmszJ};zZxBZ{7$3*q-mfrtz_FJ^Q z6VR>-)wh9PRY5a#RO|m7pcBrV@)u$@L%sZ$J|eltib&~s zVGbC(td{p+)$$&!R8HVqF{wE2wNkpEJFQmN#AEM$?_&dyud@J!SW(}SiUn-Y( z<(0QW{iU0{7vv3ggST#3v9PM^ZlP&TS`R(}FHj~Sct;^oapDM}$ ze-ux2ooHg~L>^v$B9D(+VDlN_t>U%xtjMd8eMzTU>8anLgw3LD89rM#r+%xfVyodt zJVQ!^>3lWknetZ4Ofl%+U!8A^vBeVw!MUx@$N-|Ib8p6t_ZI(-kMpox@!Cs0;o+MQ zDWIpN@oqS|{)6$c>9KM8!Ta8tn-e6gpk?Sg;3`~1%d|X&=hJd4m65|mwA?EG80y#j zcYggB#38PGH%rtk%^`Wt<;^7ey@k#VrhDiA?twU zpye)M6-{T|LJu7czY(+bvU|?j;=wWWCj>qLZmXP1$o`;97j3W1BucA*j zc^{+|ATjR4*{=~E2EfyBVG5{fx`BabjC)M%*fSju`cLJNgD=4!&A45ml}wqNZD>5} z2?RWFkwZ;>f78xjzfIjVJGEoS^rBZ)-QP5^{f%(Y=`Nkn)%aqW-l5xvdg;f11Uh?r zI|JEo2K-ZK-<)r0y5VGxbznz~ZCe1&C-FQ|MpHo?2|FJ<2B+(6J{;EBD9By7&QdKO zzoEMS1<|PB*EPI6gVTC)aC)9IdO;Y4G0ZqnEsP7>6l)YeuPQfOJqYMw!`09BEBb+n z^SYFEYpJKcF4I?N8x!yW1IXscGv@LDOwP#apKupd+SEMY9&zqy>}_kj>R_o_Z!L4+&dGNbdm#gw_NE?R!0R_wSCok5 z>MB=z)69;rzt0vJcGalMHAVnT?9${mQk3J8TQBADg7GzSIVvoF!(@tHke8@eQyuqe zDv-A?l0%LQo;l4<>C38?WzYtcR=K%T%7~x`D6@Q{Da9g7t&QBMBDpkKb=295W^9*E zgG+f#bA7|_f1J$y-SV+}t{+HGPtNW#Kky&o!LIRzcklUO*@3-BuUhEnwfDpqzLVX7 zeu99PG4c06Z1N4aw3H`Si1UpOoDOjc!` z#nMu`Gg>P9aY;tpyv)9ZnSfc$HA{$S^2}s1j?NwJ@f{tGc&y9otQ+dxzmQsJ?5|EZ zJuNlNnOd3;gbzR>G(^(?ec)CU~(`ZD`K_spEv-&1dI4Al6`%gXGo z7U$qLZRyD9=*as2hMqO?v$yMnJ28xhNz_}O7FA>_RUVOtsi2tpp^He4pL*HTOV2%E z%Z#}bYO2?mx>h5bRH(BNJ=B@IJ0e-+f)wMT@#{l;o$}4Y`%a*U9%A=R6^Yq9Qjc zrIT<0wX?L92H9eP`v*qunZm4vY^}iTTlMELe~#8;+6+U9xH#L`ay%a+dzZyZUntvG zjD(YNe`j+vPIf40bC$~DJBnzNmDd-PM|dgl3rdyj8wt*2@i&#_G5^|-Le6T)gXh-s zJh(#tZ78gVLUOu60QgiJg*P(2izwk*8E#O*sb3z0m*m0K9FBPS!KU@=^Xe~^%S-#N zte&69<)!_=DQLf5fd{9cgy-bVJUHDua?*Nq3Oo#}z6@{|h4;d^`Y>UmZ!Ka^K~MK0e#0@X0OSpWgKSx!+Ca)z>S-XY$}F8NQv?B;rYf z^z7?OkQ46CWjkei6uEenqWo?}CkE#BD9~d^!;exjMWjQrSu0TYW@2kgI}j zsX>pLxzp*hpeu zlf}8NC^nKb9;2LFMoak<8i}Z`ib2OUAU4!cU9}Z-)u!`kS&|Nqh|*&P*x95~+}&St zuanY#sYqtqkjb6&If4#L$)yHQ`)D+$D%xAy6?*20W2fI0pGf))mzG!@LGkFx1J^~T zl8!1z$nN%}TkAJ>w;MG6<3mq;zAlpSy6quHl@f<(ne?6RbVf_+= z6z5)s^M7aj%Y<-omF_0Kh;&jXyE$P#mo2jvDg9^Ea=fDecfRuwp&_UIV7oQ;P)?aY z9(RXR8^1jO*9tc1YAE%pAV^0_@ZUWxJs72jTj_(eM_$e2ZCJh(6kW=>h9-wrrQ~!U zNYsm?qyK#7^yxGI{MD(6iK)3;ZzUu1r16=@9(!irkptHpIP${me=vM;yog$IJN>eShWF*c&&u#jVR=CC=JhBsT>vJZ-@%imi5!SZJ7 zni4N}$o)?$@IFR)y^pUE(H!38@yo+L{oaoCsmDQ{oTe~30=&K^buYkYir{*>M)>#| z5f!97Jk9j1@DOJH%bg>c+t23=aPu?n>HeE6jay_^FUXm~wA9N#E9z1u3*~-c5bj(AH291IO{}aN75wK(%RJ^v$x^ zE&M#p5X^m@R`s9Bu@Q5Tw-l@*W~2N zH@-nSiMnQ24cVXl%E02l3k-jZ7oZHmJbqdQB^+g%RwmO(aD~maS^9-s9_W!$BCiL! z%zW4|@y5+e39=~gRFq|+NDV5o;}u2nanp7cOAq0D;CPW~fCmIajNb>bddXrNYk zOk?+cyYx`s(9btQ-!27x_*Y`hI_Vl;xEk)iVtu9SvH~{|K?z4%jO6h{8BRH2Vfiz1 z`7Rkgit9dy=lEXky}g^%^DN+gh~qw@fPWFncW+XDMSd^ihai@1d<%5a-vLka2rcLr zA;?)#oSc{CVseUdSSg1Dvr0LsxQAXoPD+s){&bcHOqNrNcsbu?sgj=>@H_hCKvjW0 zh2^Ja{w+!@EXX3~9KkXS&{UgryM>$71FCA$yeru@k*Ti*QDq?a_$`&@C+@C^^j#Ba zd@=-ggfDNsb^H7s``X~~XzMN87tZW!BdzwZh1}pfc_8~dXlw9C_6{H7k>ZQ;tS{%S ziwwVa$oQ3bFv3$bcWe-~TZ5eY3jJK`x6WCfJ6vrO#S7yUJQSH~_>o8UkEo_$WlSZi zXM7rooZ%?XK_Z@?rd>=mHdll_h$)oz@ZRd*vy}a>iFA4bF7X9VbLhPX5i=<2A+ii7 z*Zn6CUVGpqpy$9z83(D{93fv*&^F)zaQ3w#+D_$YTTve2&&uV8^2)yp%BS8eEI&kL z@5zF>Fshh?c{5A)lW68Ld(j-?GJ7#RCC^dGu2Tyi-6A@()e1+@B2y=CoGNXB7s+Za z9RY{(dFdLiBxWwfmq*YFC`s_O%zy(-%*DJGaz-1UNeUAr^|#$}%Wb5QS#Bz(;2$cw z)ONE=G#op;a`+hS&m8qN!1Xo8Xjv;L;AdrcMuJlx1jg?fXOD4PG5VEYJ@LFb!Qf|Q zc!sY70g%DGAlDCLj@oKrL>N`913pBGPk|*RmrpahPFiS$D*{)s4?-n%Ehy(n5LlY+ z2Dr17G%=_;=O^5`c2Tbaf1y)>V#_zrtDrs4+B0*NcdTho=fG%tW->MuGT*wg^IGpn z!%SDYKidEwft$~JW==+|VT!_k(Wj+QpPp~M%@crH1Th>m!|iFmk8Uv4_GZRu)V zq`;qm;rMA8$CBI~fU)v&-N{eKDo$~aXDFbIyc&qICt|>RF{* z85Zt7z*gM`BXc8QWZTHhGcFK8q{ulydbPq|z-97ukl)i@X-z)PjRtg7k@nI*1ZJ8@yX*{K; z?wF*EHUiJyqLnk~GXsTTO*%6M1z#y&9-DgP@XEsv|5)_@_+e^}=$!w~^741)*%;7v zQTlJslbdQ_Y%+OrQ~TC%Xe!P}FSXTK(CfNF_I0nImXo)Tn-_aZ^1O@%E@`4!m{|x^ zMwSzg3P@HtLs5d~Cz@ON0Olt8z->p5-X^Zzv2yUh%KLw}9LBxLVW259o&Slv`On}_ z%kaKJIG2qQdGIrG`7RkgDw?U>oyc219bHU?y&n=9y@9^t|XowNXo- zOrO=*qoGjLu36DmHwR+rLJiVvAK%kv0zGVJc%-eiwrwO#p2!|a{J*_@34B}CmG`^v zY4I+}vaHS8EZg!TTef9c-j~?%lEhh@%}H!0glr_3I1otKp%iG@O4)|e7HCU5?SwWd z1%?UmgXsWe3Z-W0ZlL{!ZcLf!*QOnYA@X<5z4tvm=}C4{n2+%Ep5Bw+-Ojydx&L#{ z`oZ?HiYAwpDU^9upRF?H(&<90W>=8Usrm)?FqdWMuN#&AYE}B{lsG|SQ%!39!T844 zBK?*0Xl7l*WTc{b?4km$xmqKsofC^9n!+NBH_5)3m@2EWG;bRn-PWAe^h106^@(q+ zJhZZ^3O=x@a+@YpvdgXJLUHUaDNq@o9!uclifd|+?V-A0kn4&oonqW?Pb5eLHT`0miKq3 z-2aa9p23v&+^GCs-WzO0J1KonM@l`}{U?d91XvujA@cID9_;GwUtUnP>Y}lW zzj|JaK6g*9V#6eUqpg?%ZM4>wBZV)*8pS&*Sj;Kl^j9tJLMC zxv{T>j}JwRGfKma@;sQ?+LHoDQ#>AVo6r)xmRz3r(~PK_074Q4%fex?2i{x6GG`U@ z%vmhPuPz;9ktr^OJVA|fvH-$%Vf4y`RWeFPF-su22UAK14IG1BS~@-DWXJlQiND)P z4t~b%nrOIg>z5K6-nr$LcgTjZiL2RuB9ChzvPc@tm%bnB9S|Nx zFXCva*4)w{)3~Q4@mWCkv~WM`YPzR|$^pyTQOFer%N$08E~dV1jIH=+a&2QU-b3Os z(3yEol6cfeBY^ryFch=}6DvA*Hs|`>_2#DS9mA8u9ow7C^=@Bo^Ulr{lW)KMbf7}7 zFKmD0b@=a*_CmeBBJlLvZ!;d$4t*twW>|;!AmA!YQ}d+Bm6_n4GP>OiXNI3LGuk&( z+BYcy5}9*WCEPcqc^Yv2G@4BD8Im!)Y-$*Ycf)L8$hES)tE0N+x}&wB=8o1O*FfcY z8}^+ai$pt*7PK_AV$@z+zo+9|DH zZMONKagWU8{K&YW-pumUTB9~2n!kgwcu)$iKR-|Z&R+T<>fXAA>_7eCTel?c0s5r% zLENFpVpEv7d^HL8{ZLPba05o;aMGwrS?j5B2v#TJP}?~v6_(;II$w(^6_x@OmQpGd z=?Gzp+)~9Qp-A!H1X9EFK}c(q+e8Qu+~myE6&GJ*@!K4JOMhEmAX2hv3YLkvxu-l1 zyg4s|wh=0u>XM`o0ZqU&dgstFF7N++m`94YIE2qwq|0=cTC zGjzAjpJ%S}Iu5`PxQ)XKGZ?olEpbdJWVZx+ubwr|9^S4q-h8uBw_Viz`Oi?(;I_o; zq<&lCO(u5>0+qY-(aN2dmY;a(x@vr1lXYco@r*8V8C~Q8UF0fs!DxVnYJg$iF!SRX z_#X%Q^oR5FxYjb?MO4Z`oyADQ??zgmJ^^DFV|}`{_0h;<>iQ(bFa4Y%a0UPJ82RbrOvKv2Y=jIGY@k?P zNvMGDEg;Y4gZ|zxypA?AIeL<4X67zD_swP1-8Fb|ZnaI`h~bTxN^jCoV=_?`Qlrdu zU1nLW!ga^YcZXa&XDga?yXn(%D6QMV0)fdPJDcGg;SPVWTyxpX9#jWlDrL+`9oHw- z6$Ad{`Sx~yATXgf*L%G6KC{_Z@AcH1_0yUg_rTBm?W3c=9Bo^@XLXw?+*#@{80TZksucO8~81y0gSyLreoq2*xu-2v5(H5aa8nD=Z}U4G~Ox6O=We08=A*` zo^Aq1**{y5yp`BL^U}=vouV$W0ZH^7SJyrPmydvz$87Jq!77U=cp#e}VASVfdFI(06Oe2|VPw z)WY~pKwV720p#DQHt40tPZQoR^MJ}3i*R5~DFe#}S0ss=sSDs==jLP;6YG8@P#p^M zZ$_bx1+WgCj}y!;I4p9^@T6?4sjYhJQC@M7TZOW__G&=dYii})D@2he-XM%IRKRDcT=W*Vz2*enBa5DLHVOk#ea5^bk1E zgQ4y@Ojv5=N$- zXW6MmUh2*B6kls*>%w-pI0y$_Ek48UO6XukQ(YCzF-5GH+kX-Em{iEP-G)%LELs>Z z@!Jc?)XKey&+Q{uek$bu;k0|?+^g1o@AN~b?zu<&(OKUYlm=a4%~K`Waf z5yGHx@X0l5J3h4p|GQ)Sz+hp8$5o!+vu8!eo{klJdh&x#PetM2f$@$#B$jxI2+g$y zgP}6~KZzfaIz0X-TnRU7n->Ip&g3M-D-?t7(TH}ALcUVUedWbwd9&nBH*oZrft#L8 z5!OJ=dChRp7@)*N-JQ4zr*u&Z4ko5ya0KGqbV=37@b0eVoxSHwb;LWmV#BVH>hsqf zyx3M5_4wm8j$q$ZL0{9*mX4?;5}R&mHrGe11KrX1?oE~PkVCJRN<;0T$XMKm`=CG% zR=S6g-IlWm&QYUqX1C>7m@UVGww&b`6d6zNryt_U#EZ|9)2D|>+w%#A5vFy*{XUUK zW0m^3JqNLx&EiRB&yh0QbCOll0HhaLsx|hU?Qr9uV$Uh0_MB1OPb{s%-@sCMu;{7VW&Y<_#JU(4j|90XPiqRM7K2j;# zbVR-ir$yJ+#6-vxij<|$WJ^%KvVnwa2HloN(&FYF^3?|m9KljoSJ*pP;*t5>T{Lg+#7P=BPaO-7m+noMdb}A(hB@;w z=rfD;Dn{gBsBtN3wMXMf8d4p(>R{RLk6vCQR-Je7tpay>*gG~oEZP!3IdUlpoqoh$ z>&Qc5UicN%^C!S9J+M-L9t{aqLWtp%cmxZN94QmMWvK7k4g_H{Uk-lJC|?Nlf^EAR z=PAE2DmQYu0nN(Kws~r5w(%dxpfnr+=D~{zPZ6+LIVWcV#H46!K{DEu%zt!`p`|Kx z>frh3ADnF)Z*{v{$J=HNy=`s1yYQne_ls9u^~K!HoAu#U`+9r#t*X~;7FQV84eT3O zXXGcgXKsaY8lvOYM#pU#@aBFI6_3lZ+8i`a0GWX7vQJmi=0H0qpLN@UeBomkxDw>U zN{|msJIyxnv&4C`Z_KXT2jut=lH(~_&t}GNVG>Uvk)`I<)ntj)u+wDBDHh+}&b?)+ zdSRhk0XjaZnWc!DArNAMxcMOYyxz5}wrfMHW46%OT-nz;J4=lD1)lEd{#RcMcUG8e zWb^4E%G(6Y?|hQkBc#msh(*>?jbBo#J)$s!JtDN{eE4_zuh3r)iaY2rB=gz*;yQ|n zyECgjVv(_3B=@d*uv6_3bkI%mpqu1DH_3x;f4LTqA|4KBTyB+=wY*jVo!9OxR z0@w19q)c6^$ke5o>=v12YEfClQ)Ox~U8c_LLwe6`i6bac|Mur7Q12HfrxT}U_wG3a z5_MZ+ohHt3_UxJZ(!JP>X410<80e`(d-fdK+R)V1)bIgzKSDmJ-*AYxW!;jt2@T<#Y5mlC z%lK@X(vsT6gkl1`AUjqG>#;^G61-d!zQ37ScFdfnv3SD*UkH=km( zjPh>`+JLr#YtwB7NgP8qCaGC1G)N^Sl5P&S6|mOJ=7B=RJfO50#Q=;=w3vC|y88Y) zyEwRK&!A)v_k|+^;gXW@K&04RoSR#W<^g&x@QhrsJ@GP(+>a)Y4ww1Y-E#iI7BYFE)tDKuA9Eq z>juel*T(5tkhZv*%h%&CO=w_jz6_k!Cl7?-Wyk zu~|eKb4JSJ7%qmjxE+L*{E}T0l?BbSp5*v7)S~K0hKBD!3 z)0p1X8ci|^9a^Z3e5C+}aU5Nj;qeBK*G-Nb8wify~j+p}dMLv9sOP+?8xmHRpB`>Nb9CXvw#-=AbQUrUy1ikrw!!A%q{92U0$ z?Nwr~YaQ1^vRZ~Udls4mavD^gCSsS`&lKhtSE!84c5H;+Hd1T3#7$&Y9#&f3yR*-s zz9eyJnV4CqW0p_1avmf6g=os(MQ}g3A!TUlTrrsi`s420`1acwp+Eb6g?-6zKiJ1C z??}%3G9KtK#RD}UHqHk`(Rg-vAd7+rvM@XlQv!-KcpwXporB9@nCo@*(004xB(yX> z2voU$@7-Ls2tsIjVrQsZ_6xbykKN|ftUbqq~BP_+h;-BmrsK|QeY zAO3-S_t>#S&xF`AF>(6k2|>0O>*-h&rqDaX3E7qV`Re=V&&ux`_P2zb1@ z^)RL(8CR5UhtljnYXEWTl=K>D2$2;AF6UF~*8%nG=z5&X0b;qT6hJl>>5rj^EE;$b zdA`}dX=+A|E*jZs?7VM21zYqE$M3X4o63b_xLc9Bj%s+KW;0D=22MIiFsrXFGh&aq zFXiym-T-MpmcMzNMf&HM_RHLHojd?9dsaSA<4%;rG(bMeS{>5@t1!$iJpD=Yo;}TD zH5bjCXAasO?54=jx3>zUQIrSX-C@6RwiLUeZ)xEi@2w!nlU$p~{mg{E7*)I^?I>8 z5iNufEmZAs=POQoR6Ctl5Mj8(Ls4NP6!J3t62*lf70^j5z_BWZj{hq1KM&tt zC`$3qUb+Q~beo2CpTwk|n@ z;i;RZnsN9(bJG;L5C^V7)V=l^9ksXKTFZxvV`uuQynY4R;g`UhE-JvM$s;)Yg-Q++ z+S+_*ZN6%}WRagYhJx0x9pSzAlG5XQ@7*ivUVU{_V*JfFg(QA&UdcT`c@M0A9M^}q zXINbKp-eAFVJzXy%`W4FvRQ*gY@GBU3Cfa(GJ@urQ26qL(q<&Ul|A7WV z!g8Jg`P@64I5phcGfYSU8CC>K`MiE)r6jE!A(sq~jt-~b6~$d#9zRUwaUa?}Olf{~ z8WfXS9>;jyCPf}ERnY4m-aS5;DtbAbLWW$kAiNOM^j;K^(^AUX#=3Uq@O-c-$z$vL z@;<3x4qs5>hZ@c#ZYhlk%$J@7vaCtAHJxri$%ByMeWr6k8C-d7UA>ipzV@^ zjFh+sm&9$ZSVI%k&(ZV9s6!66@$IK#F5xOTYiytd3QCTs_!ohz(xyPoG%7^Wdsg2ZWC^LBVhR+Dv`Cxf^(u3hyXmG?#Io85hb=dLCsWtB;5#!wLuOa)y-8WgyCsfb&w! z1l6n8aQ_G+2XL9Ww4s}0p~wvL3_fn*XDiPM42wk!qrPLi?7*SWvVr?2pV6DjOUAZu zo+%HFl~>Qqyi;73Gr4Z#rpJ$0)#z`#P4BZKq7(N$Db^3i(4V4X(3}a>&c$*fY^3@h z&izdv4Qrm1AK27NN)L2ng6g*$XWp3k+Rm>rwCw2*Z@GoliRI~g59(x6eV0ZI9ZrqS6W}siZE;@lXDOkQb>0uaFdOt6H84grOlwJPA!#^Lo+qKR7xt%gB_!?jRg8Y zlzGAi`8(#+O!1BSFG0arWs31Eq{f8q=l6M>U3mW$^gG2ip>MIsV%&Av+1kMFuU*tG znq^--t6lU`65dDQPxqWU{SdCTP==RcK`zqDSsIUBH8ho&*-jg-q0EirhxR)30o#@hYJFRSRozzaR9! zi*Y_FdTMzjl`b>KWGPo-@S1rH8$^?sxEaY2fr>r=H;%*c3>*@Ris+zAOdd7B^F3}B zh0+pab!IqCW(Hljt+=$%+f-5B<(|bh=v~XgT^nMK>5YfSEz9ED>pCk;`FV+7izlal zlV6BCv(uN&2uZA#Dt>EsN_^F9aaWUZUHf@lRE~jQdr!Kwy(ez2%hW&e7*=2^D+}|# zl>5uZBWA%k*;rm-3_vXBBVtj8xz+O9>3dDrr|w0;LYubTq}q!zPP4XAoEo-StV@|k z?EVSmKF0#XDyv*%?~?Ny4f5kGY?j4Io8@-6aWKth$u=0# zX33(@IOfnEDDmB4!b6TR-Wy`u(;<0#IwWsThve<)5WGJ`x2FRX^JZBL7ssrdp1$$6 zJ#A`e9DG%vapB>u6d1QCIPPnIRO0v))3FJ&vH26DJKV=dyj&CdfEA|2AUPwvoR{0a z7Q@T26)nQ0$|l*wd1m-IG;#jAf6Bi&fbP7>eK|RuwM!uA#t#*M)Sx($fWA8YH$5DZG32v>9wMgs|jZCbz zKkDHL+l|#TN=BVnPvyltzA>%mil@MbhDlmZMzc8?-FL%`{A+nYZ_t-lKQ>+4__I41P2jq?Sv<+)ZF`!$y)=dXUb37)XER$?QGTayys_f-cVIeWlVfbt_XQf~blvlJ@F zsrVsVNjfTwp{d-knbFF8^;NS{REeh57-rA1JeMZYaenBNSU%35}?H5v!+83|) z8*XFrgCF;>s9e#;412_fIJI`}utuAB)O8?X=JMcc6)VC`hFG zdeE$m@ z_TBW!Pu@iKkPTN}d+n8phZFCgf-!5BbxE;{jXk$L)^J|q7QS?nPHJ^5vTUff%z?r& z0v!ZK5)x@;FkNqE%$*N`oOI)m<;G=#%lD=zM778 zQO9hdClc(5BG*w6(Dk5umy*pgRvTqU6ZI##5oM;-eSFPYtf2!ngUN-TG6gV~wK;>Db@TeVn%P->FueYc zh9g(J`r3-+IbZsU&Ww<5Vk|OTPjxfI_0sX}OVK@O>{aR)5#{?d`>CHszHk-JwvUdd zC)}^#Y%%pwnX|&=eg9jt@63KnM$`}8lR>x2mZO2j*{8p&rR~dESSz+rIq`CoDwLdp z9@$Q$i4U%}XL%H0rVW0hAi`uP35q~q@GU)Ue4!#NnW+k3qcI>5GG}3WD79%N5p&EW zNeZ3_H#wS$XYV5S-lZ>V@$T5zKlqh#66=rW=Oms0F?jl9LH>c6#Gg7wWlTZ~rPr&_ z^JpWj9FLkur>-2lLqY!qV{#+EkZj2; zYnsxCU;P_v6%;$he0E^UeOl`yu{5k)z1^-;u--Z}-dzJXZinMRI3zSXVuF&jaO_|= zFi8{3SYqKD20AKKqd+7Z@q#SJ3=UcJX{|fOcT(Ib65oJ!r1(LRzoYWe-DH6Li})poj6QFF-w>guZnPn~{D}d6foy&X=kZ7GDla66a9=v2aZmaVIQyp_ALL zp+5t$xB_-n8IepRN}f#o{?dTY=k$7WmKP27^bMKIs%-22nT!tYa8)~X4u{w7s*3kC z*{jQargp6F9Y70@Lw#!z16atjBxTK0z*X@QyirI6_5vPjCO~T`z?}dWjrwzy5Cn42 z0o{d||5bMiGpP#H@(az8NkW783#La8Bkppa*VW>U+IpkCE9?Ei#&rXo%dDM+p@2V7 z83>6XXR)rt5e}D?$LfQ1ddU#3YVNEp3)?+zht65r2ZV7ujL&nFPKq%8A&Nw1KG^CQ z1KG5l5}eq$Go`c0o*0F+PA~qF{L1-~C6|Fe#@Y8ie~`Jf5UBqr*6zQf)@rV*k?d@R?;=E>Py90q$58{{_{W znm7poA1;d=7>KQ&Bxp=YuAJ1w*KPwqDp@t5CDqH?Kl0W zc=V{t-xF^ig+4F!2Fi3UpCvcvRTP-N0PXrNm1~2-ZWKFZgh`HBokK?>c&q!p5V;Ke z(UnMho)=qRZ9{ zdV@hP9Ase4KxlbqgSl~iE3uXL#M(zXy`CJ8mwvFh{t(d8QzAB|8$WU>GtQcQGT9Oq z15u=7r3314qj?Rumh^8oT|Y=1*TZX@2R^YZ@hVW&=b+!7f%%CmbqsASg3v0&*%Hgw z>gpx)iqPJ3aSi+moW>5|KhMIgIXHd^hja*T+zuBH!f^s`Acxuk7qf6&Lw|u$rgSt5 zor{KtLSfOxqlXsqC4db|H4VPa7Jk_wL_M=pN5P&tCgI^#bwN+%P=EhWr6*XoY8d+* z4;vv)pIR7)I zw)1IcP1LETyrHo>Iq``NX{5Jie=6+(4`29z{0lj9Ry^F5(Z-?W;R3h5C3(31qw;XW zk}Mo~ID9-$4lT;VGq>Svcz9I9!;>5w_&0n!3H`bl|8`|mHO`cO*O0U3-@v_V99r&8 z`8UwP<51sP;pMFS+m+70%}ep`E3kXn8X?f+qrXI=JJfH2HA29wVl=a;`XRcQ8ZVS{ zk1{WB9#aUFJ)$0rrMwUkgm4LVQ_@*JhTMdbp% zs%N4?CKu>4$OU?hT%hN2K_IJKkdz8QCV(-166)p`?m$9Hl?nLXr7MF9!geSHS`Wm+ z=F59$Mi3&<2}lo8nVw=>^35#A9%D^TSx|7w$rs_`5E}c7sXl}mPn^`I03z`c0)y@U zW|tR8B%{2r4CMuA^LL@mXC^OX9*@Q3g;H)vPs$7Wk0dV`78MsjRsi~X3fi-ntdOY{ z>9Ru9nkFl7NdbAn=b+D?fwh3i3Xh$UtdP0qs*|!pHD3p+VX9ZdRIkQqE5UrJMvpTi zy?79g6ZnJ)4b?Eit6_#$Q=uWig@$UnvY^mVE$awodDX{TT`k@g;-?E-d)C z@LJTsZWl`b=wmy#JgoW~|*hRTm7GyHlnkwFr^LUxnK zKB~@N%H#!|A}{DZvd%xeY}qg#Zs?ys(=A6ts@a#3K& z?y?^!E zKa;Qiq^>!h`1cORgTD^-co_QD!(;}FhDNDoO^v`5}3DlOtr;6_=LT9TuO%)Lv@~2E3-` z4q12EO^#8${|M${NR=D1;bBUd@1Kr>g}i*!i;$l*!i_#S*1{n%F`$U%8Mn|DdZ|5K zNAX)09$AWH4Gyl24IXOkHn-+ic-)?#*B9`Xx$Tj%hLX01_Q4uYpl*chu60-1${Zy| zTWP%1oMW-oRJ(nRHU5xZrw;||TN#i43XIcZN!?#kcsxSEleyY8k#>@l!**+VZcvH? z($Rf`BA$U*KPStX{H3V-D=a?P4eB-NzyH(Q8XAUld&sf=SAHJryZGLF;jItDcsxS& z{=L|_sXShznP|tu4bK_8*satHG2}&b&9xx7OMyO=%5yXWw^r%@q&C)JYAFc1Jzk&F zR%Yxe{P|aN_4(z&hTb9G<9>(EURIow^GxTg-5ZNW2WdZlgSQ3O&dq9X63>!)K5bDc zt-V^OXIo)7SZAZ%*Y_^BSJd1046MsHh`@1LZ{}}*>?O(sn-Lw!{|=Q*%hdA9|if2>^$82;U#0@ zHT{?OB>oegVm}>Mbo*7r?t%ZC~}YV*jtQO}o+04REA zQ}6$FRlawy#^FVmKaQkWodtGH^EBJ%F*Rid8?vP_<+k$d2Re( z?baNtoqpWuEXgTx(ho{oU!!Y2)8%PgNSU?@Q{=)Wd&|Sy>fx)HF@p2OLuZLRL#%1c zn8IpO8~ptwZS^o}Gsq-%AW2)C*p8`540$rhYmbqQXT_5pS#y z7xPM%{ID4Xwv*yKyrC2fWVHlssD2*)2hxsa-iCS=cbQ$@uPQ!<( z0zZ$gHCgy@pTdTb55rhI0(D!A4=*+rZYA);net)%N8!VUtZW$hFmKD!d^mH9WImkK zm9>2MOtj|geAuu!8%911AIG2#RBz70haKsB*sSKmKvwfwE=+8U3*$PB{d64WALGMs zoDm<+++#B5t)`F#&Uy6;qZJR)>FI*$>4NF$V$%~X?1arz7h25nQy4Q^=kbA_+0mvt;0gv*+KGKWsch{++3pQ~9^RZSR@*cl4w1@5Q+H0>VZF%>OHf z#OD?c2naC5Powxl;U2o@p1<%x#^-Y>&!2_o&u4y~<^8XwJjcI(A@lPr<-fK>`P%0% zEb<)R|Gg!irCcI1)J)DZWPXxwTiLD!zae#7XOb|n6Ag#5bfyWjgB`E20yI(Tnj zVL^?UH52W)|m(MOD-KlH4MkS&Ok-a;a)dfpV< zdsbBI43h?3^~#=k`pz}f|L_HPX9RgCe!i(*;poN^jzegM(UHysYyCnT)@x0A?sWb6hKj|6}d-jty z^ofOcR><$nNxrj?22rK&1Q{puAEn&T@e7Cedj9WZZ_1WsX$ zjKmW?D`C|BI(Z)q8qlz-b4oOdr zpZ<$ps#(Fxu?k1TZt*C_`)AP>i&-BTXs&fSmUPb8FjoMZHRK2EJ-)>C>^dW2>wGHqYeKYNb#IMNZ zyc=40HzfW$`Q9NKQ;LrxS%hA4l}S$MB&Y5ce41}f8%TkbyiUyL1Gz*wYI;eQ6X4}U z)5=i@llGgKpI9f8CGaED!Vh4LdJp&!X2gCJIMI7>e=P0Ud;HnE?3sX$<2Q*DVk5}D zb_6|gf4wJRJX84quZoe?jnVPzJ^hVj>&~sDvA^f_lrLgqPd_Ypu->sJ%C(SOyI+7Z zBdAoT`UozP&Rkx*IbGV>1W+yGdOcmm-=wRpdPSdS%lVt?FKlhs3)SLE@h+IxcJ$HX zKHF@4D^=4M_wbMrr5Mnam8_@3;fk(mu3y>eo$P7$)Vd2fMeFFm-5we53HsVrM~aKv zmzRcO-dmD%SP12>m&+HE<(Fb6(UkJ3TQ@CUt_dsubCl=`-L;YNTwE(&%*yvC%P&hGf6Ts(b%=2{mpa0T;MYAX zVcZXw*7~hhe{E@aO=mFJxh8xV2myOwfsRFiGvs!MoCTX5jU$bXBTWuAIO*k+Wcj#m zxK+GW$vkJnND3uhv6Jx0aS^M4T(G?cD^g?U6`zG9xNaI)!0~36F>vj>sIGMWSc*Z;jgx%qakSvx?Gh&?0v1 z?i9W5=1P0@$nNg$-J>;Q%i9l@H4RkP4n$nBCZEo*Sv?KW%u2b6ONo!Xan-SLTNzrzNp*3~1U5GR7uS(3no#9A>BX8XEib5@&_Q9yD8ArW#YUQvF4oH09(M6c)DF%ase-hFipG^0N2~ zSZ-+>IL7>J+mNHQA&0l2KxsoUZ9@s%VU8aqsy3*bKwEHrslTY$V{*G{Op$WcwK!dv zlb`2owg=@i)cy0~Ve&Mr-ICCWb=OgFi$Fa!nU^MEA!Q{w=L5euK`(GN8F+@H&y(`R zTjC4jj9&kbxS3oc{u}hVAMGzm-@}N~5y&cyZ0je*TwN0g)W9KbE_aqX%jpNRe_bzb zC$Ee1@J=_2bY8}d1^H$<>vu%m%@4{KYgOgJS3gfrfrg+W9=r$hR$Egl5>5H`Vx`wx z3CCCXS={cmTkYPo4_43n#Q{+-*{DPlK`BR0P=+ueNvUTfl`b%l5Y!;ZV;e9yKm z-EfElp2xypg9G~X6zB`zlU zc}qeCp&9FujG309&8p&adGS@qLg`|Lq691k;f@izb6Z6&CZWr%*ygm4h$GQxn}5Gf zl63q1ZP6&B*<)f1Xsa1kOOG&yC3`vJE78s?r5egQc94&ObDrTN*{W5-VZ-VEv@{1T zOezv~HJ0%x}i&K*vd#pR?QFy8ONcwZ-(HFG-ioFq|W zkaUbXu9eI$GJ5&CSVqF)JMg?bWloa_-600?1&#;`HaMk&@#v{lhO5Lf8lUf_g$VgJ zw6#oVVOys>?yNaN{X~sQz;O&Oj;O*yTrB6=)}DH!gNi=!sIp;DB$D>}SV3*B&u(>= z)j3PrExLSLzNe-nQ1@zCQ6%3|WGb-hrCsAXNf!v({kA-;&v{UvA)p$kP@#=A!euua z(924P$IeBt5IQm^qnFP+YW&4r?S@r3RrPkG1DJPSLw@Yl+!9}DRj1pOQ{pIh73Y+g zO$GI6!(LceSSwBnkAMtflyr$7VYkA)S@E!N2k=FsWKiz?qqtdE2|Udx8I^lm#qBT# z^KdUmxp$E`Ap9KGf1{ME-1}F!_X${gjZ&U+?;5z*PVeO__r}E`;RMWoqg0@}w;Jvh z!M#G&y;1(VBGvn1P)0M{GqZaFS@@#ZA?%khQ}`AEB@4>Bb68k-6JD^1kR#7*{wN~f znUnAAkT2*RgqY6D+@I$GK^-o5?&S>?9=od}dQ{4-bU8ab{<3qiZqJA#!UWK{Q7V?} zD~Mv5a0Ae;QL-*<<@J4lJS&_7`a=$I=~Of&4fZC@GcIbx2q!emYcv);#}_%gdrCA_ z)(#%RvL0NB2sZ#-8>JGZAD&(q76ulc1KGhR(8x(>nlf?`hDrr8-?XLhea`OxDV4{Q zg>NKI3(FRsr)&v{v$4qtbF=r_wWFOcVjX&*4sM`jqh#ZC5EoX8eZphX7lC~3Ag%LN zHBA;&Nk@59{40T$S~y!FGF!n_zP78*o!e=1)%pE(E?Z}=yROTN0z;pxCh81$t2~}6 zZ@?L?aovp4!{1!KJyZD-FwqRW-zT)5Y58R^;@)}m%0yDr z){BmKVI3^sE9-ux9J|U{%iYD%( znh%p8$v%sD&_^einWRM|pLx+wgp_nOQag$VuCO&qjNdBV87if388r&xy}svaE_a%eaJ z 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

4^Ms(tkTAT$IaHvmd`A%eqxxdw1CI0a{az9 z%e!Ap+CSk*H}L#-(>WLYs`#4ynwWmoMcncIJh1!81k(QEy!)~T_TA73Lk)Sjkl7_m zr85@6!{N0VlQqrQLRdI7HZMnroWrB4y%dADQo$xjUjfp#k|j+hk1nX{e%K7)lkzga z>+P5hTafRvqxI6Lx_yz~1i*&x!#NE!3kUHo+qlHh?`s2@`G*ykg7vhuK7g-xsbVs^ zYiQX)M5=)mG`{9jNX@4PfD08=5HdY;dS*ya0m|jm2l+1FyzB$``fv98>I^|!0lwbr zy*}As&mPNd%idle^SFdAeJG{FLsTABh&c-Q^&%8@=G}-grE)~syE8E8#josN&R;** z4|6VvzJW0s-mv}m zAi$r9+ycC1s-f6o+wvcoE4zByErXjUXrUwA3%#+;O6V- zR@k72f4}8v-TZ|LLi`&NPatOlPwsDvNI$tD!8(kud*}kVuIsZBja_@vus^oMm8n$m zWh;JUL`U`vpMrH`rws2I`Q`7SPP#cimA`ke2r#G?i_ooSpQR09`3@KHMpOS__?oTb zF_TijDU&ecTNHguoEiTtEv)dl-4(vV@Lx6pi%1}{2(#X}n)~KEQ|*3wq$4*kMVwF^ zF;;uZVV4hWq}V*12bU+sdYC_Z zQl|!=pdaD?sjQ{sQ9Zj8BTS>%8nIAhDP;)g&#zAoai1SsH6^2dR0wc{K6uLe zP~{$`Q-F?Vxb9bG``fy0tH%^a%m#UoJmccsnJ}k-e0QWRY>M+jOTcfC_8kxS?E`kd zY^)N&I1JtF#njwW9@+%zgDEYabH{{ME+03JvCeAtn;Wz^svKO#W&?)o z+RS>hA1Hm6tKob3L*+B~_F2E|&Z28KcjgDt z+!bG4_ktty9i@Jc2Upp#W|5V^Br!-#LiSH)Q@|5w)%N)#mwsX=R!2MIuUb&VqJ;~L zx$3+cvT#8puW`tWeo_RUlZ+K7v<`I&D4u`^Cm3c+Xu^s9%QW&*aGKZ|RaJ~VUa}CZ zBYR^*xzvl)VYb-bksp6kM{7|DrY+toQWyEPxPgu=)myG%C$%SmY=N9ddK0f8EOhht2a~kt)IHF% z@72I%`HzezUxhw1k@mb>AjhFIhfXeTl$keEHd~Hb783=I%1I3Ty!1&1;}r@}u|6E?6(0kM=8jX7^09e7USE@3^*r z^P*Jt`{oSM7j4H!@_=^U?C8w|wcV=M+pX#u+Y4CAFn^4yYlNO1yiJ;Ry$Dq1h(|+tarfH@%`|9tJ)(ItEMYOPqJM;s^9rv9Bz*Pcx z&IV^udOA1zB4NUO+B%;AA3<{MO0COeFcmst65XB3&bVT8qU`5{-GdMHOrp;0|ln$bqI9ns#q z;?|2l6ucV<;e^=pemoDU^H$p;JH5VJPxgeG;`9Mc{gTlQdiS2q&L&p|DskBh^b4@f zSbt^Ml_73U!=rDZ-3%uOBTdoX#&+q~cG_k+e`Dj#8TDsNKD^NJUxc?z+5S1nF0*Mu z=*E#1=g6L7RD=Wfp*G4Dyrg9lG&0)esVOV-)YuxUt(kZdgM`lv``L0wPrkllin$IZ z+TR;N8Bf)0&Es*NNW}HqwvYcz2>!V^t*;Wd5|>o4wXl-9l3F=t(M+U8$*wLP2_9KG zjb-z|VN`i=gIwXk<U#g zqbyATTBBdLZnkBL4guo#Ox3r4-|8aQJ+O75cU*+_A1Ze*DKQ)*@!RJ+7dz(%fcx@b zg@y`W6rpnl>spuDj*WZde{%In9Jha`9gOI}@l=vxyN!8O314KhM=ROrLpU++5ITIq z)WVnp;Su2nV%Eg9Tf*|Zbr7C6F$`oI%NCG;M9r?S=ShG>{Ot+5*CCja^ah6_pg3~<_L*_E6bd{K&2g5@{p?Daqap_}82Wcu_ zFe#BYg}}t|#Bv4!)te4DBZcFHR4x}Had7DwKzc8Vkc}4Ihu(@0i@yaWPnf(eB@`3^ z3QbXZ_v7X5HGcLL5Qr42dF3)^AP#76?VeEB7w*#+iM!pse$ETR>Hk0o&nezK0uVG$ zU{?UOdB*JxTW9)HY|s7yQsWkL3(jEX#lA?Vj~3-3d(*k;y~wZ?!V+^JJj~W8?6>;9 z?t)u-?3(f%RlFwevu#_C&v>g11Q@v>A?aM(Ee-4WL1_MMZ2aRnOcsx{CGVFRx)9%To&x0&LvYl)J20fR{?)BdVg}%5alaC_;t>^6LfL7u- znLKl}{aLEZuFCQEZp3l(Qp^pi^qMQKkL2a$=W{qiBoCpiFw;ONBHUMr$miwp`A!;n z9g4|a26#TVfX!IOy|!7n5qm2xe3^gu-IGaQ46^{fM%cG4wE%`am&xwk?N3jOWzX-s zbelcm>m6Rmq{Zi#MUI05EIldq))3)=cS^P61Za@TI`13OYES9Gj=(+`NoJ<2i?9hUFPYR-k&U}(kz4Fv*k#9 zk~V8jy^06^hl?6jL&CD}m@Ek9`?3UcrV6wTDJBw`TOFj#hRcNmH}-?-1dPV=nAK=o zl^HanV$T^M^72maGna0Ry|p1ORghq!OVaAaS~rf#bYmsz^jeWkF;_t9sMgJ+K(t{z zSUQ#mf1PBYs3_iuS0rnhnWR-sGnZLOuOcX36(z~=ng_?G^I%~REoEM{u0ud-*2*SI zua&6XSSHJj6KgT`5_*CuRS>t~R_w;o#|JXXmc$CFz(vO_e>3?R0=@G7R#rL^e%%6} z839>5@!4Z!IDF;O6G$C0A7{!Knv`(1nMoK1e#(iy2Z{yVLqBTQQA6nO^7;#QTX2l^ z;LFP4@y@onP@7*^JmXbXR027;X~B|F^^NuA+ASYc0%~Nec@^U%*sY!IO&l0!M<%j7 zItAnAa9~Y~#%;~ViSxwS#q9+tsPf5IBO|X)2CV1ZUM$Ye#!(=jqP>u0X3QrD4Ibl3 zhOnYP_2g0^)ZEUpDMx&h+P*g z1)Z9R`V6T6o*IXwo!>fdYzaMDdp^06a`#irGjPg7>OW)n!lnk3!&(UxaMGEoRm-xA zo2`XW=$Bayg3?+Cyw61?*irOX>0%LgHE?#x0%Id zJ;WzA-S?9ZFS6+f zcU!71jx~%i9DL08S^C2I>Gk9DYPzA&?wY*utKfz7n921P+?`qPUCj(@hkfp9`k=$D zGnKP64wV((wC=E24N{Lx--hC>(E(kv>=L|kMe9^sQ(4F5`?EG0R1$nlb#^Bl3r%?Q zJR=arF6(SzyZrU+BaaP@&T4k#=rH?!S0XtCdK)dakoej57yZoNgbJUpN+~(bL`4_o1o#bR#*7Xt&GrH|xaNLgHaW~$J-c-X)(lJuiyl0h4 zf@X~$dx(}ab@y`3FPI>iG{`(?l7v)ChD9r)!z4?j(S+oSI1ydaCFv^}V_-2mYq~u# z9xZcjr(}|FI7+eC=kHXO3En{_d1=%%2=tPo!4`E?Udz|1zP~6Wy1mzzsF$eVXMT3I z(`>H9>{x+W=X-P|s#VFw5xv0xS8?{Lpxui+vvFVqSkR*F`%_gy;*fK(*M9twpbi8fW-f8D%pDKo^6B}F0*xe7Tnu9AN8-? zGvYosi}D=to{tuZwQ7$QFUcJbV|tLU4(CPqJU%+TAJ}VqGrdbQ&e%uxF`Z6WZK8ko z+~3AF{UUEPm!{WV*b+dKSxhOmG3mr>9 zrxSYy4T*tZHRxXS_lfwwiLv6}^}oXyqkqQee-D19XXbVFd(~5Y^1{P`bsrh6H>E!& zI8pqGS!qY7+GE8_fFjsa*W57Iwb@#XhX@DJ0KK6A;P*cCt$6S{V#3Bm>;K@HfWQ08 zo=^i zZ(koYvGGjyY5FI0*i#6&At@!qe{Ux3$CO_bEd_mKeN8_SG=wpDO#;LH+)H%l5Bga4WsS+s+u$2hrP`!>w$4qgJS*)BPWGG$A;M~D1T`E(g*Al@@7`^?uy1w` zCKv@q_-A{yt2BkqKpvN#LNLyD9}P~yy_nI09boWq&cpOwl|nCJ(vx~(kAy+UP2ozoM&yuENkE_u`TIrTRULmwse~}_*!{-Rp6ef z!7k99)-B>&E`gW0yRTwL*>I4%y{zpyj~@`bs?F{1NN(Q%F<7K14E?l8}d7C_x0xF&Gel0ThfdK?SRFc0bG(9zy>i&O-^C7(UAbZa+ox z0V6`mxmviQyge=egy1LK|BQeE=Ya!ZFXiRLsklGJXzP@qI3+oklJm?OG1>aBMO-Gl zn=uqO6!Z$dQ=+>u0^16t&ii+g@C~?$%qkaD!gPS+=EnFjS66 zJ@Rk*Hd~(bPRgTC+vwdH9r!fpz4?zYz9Z%Fr&H4VGhV@`W&Q`C&hZ`NUrBlG(?VTt zU>?30Ug!aWl6rJ^<}NbUi%y^f97(v6rQqQcNF^dZmxO|nqH`uP@Xrzle{2JEr2JwS zAAW~@Pve5?@An^vniKz2zWB1ecflctUMw^G{iomlq+cb`z8y$hfG2(X;%~BV_W!&4 zBd-46bO0oTk${C40RS*G460r`*i5enQbuQAWg(ghw}X}0GJcy}NABqW-gcA?EkI1v z#Xh27wh>~~9O;1p$i8M^TAcg>6YiWQpF^5uhM(pt$V zWk`iqn?uKkInzIr%@!sCIzDuZ;DbDJL>q{jYp%t$gnmdd8#R#qWbTTEf%D0zJ{GP; zBYaYhjfKFyw@ung83Ju$d-7@)zoA>bqer6HpAbJ{a1i*l4_T!gF4g+Qq&bWO3ckxnz?FwH6#!Np>O7E`mH_!3ONySEK2jWHqHJoFI$F!YcfRPAfrZC6Tj` zRJb*%m&eh`3V>-;Jg4n9X$Q_@RzxN`9z-k^NuU51fEOl`w%U@iEQ%0lHxcC7zy|D8 z9pZ%Xq{ccy7LBnAzhTbGmwRbw6h178+IF%q4j;P3JUfOBJ9|_Dcx3v{oav`bi>DCA zJ=T`%DJ}Sj!8&5$uHn0Lw{etHambk^Qpoc}h|Ej2rTGzj#Gr9qcW(SabV)kZDPSk{K|r;+AU=mR~(_`l0h)=(IkSEnX$rQpkFi&#}KH`@KfoNQ5v|308Lk2!-q9j#7o-hsg zNd-LK_R@k9c`T-n2wW3TEGRTNlT>Ge_zsO^dmVs%7nBmJ3j=&dCu9_@9RTzK35^h_ zn^Iq`h)_(mvrbImy;VkSW|P>5j=H?saZ94mN(kY2*5X;mhh7sw9A6?~ez0eEKhgwe zhT;eisJMvmz+z$LjIk_Olz}Dzc=ax1*3O)xM{-$eqq_JWu>V9~lRDl>3zEA$sonh% zX7&Tfu*uMvi)&vS%{;1kG>%hF2MC&tE@S~mZ9D`N;?(m~;?YuTg))aK2og!mS2SU* z0X$_EBr^Ytdan}z%)kS3vIu3ND^|-{9dSIOPHa8!pz=oE%kPqJjd6kRSR+E^DWyC$ zOTO!WtMKK$WsU!j9iDTZS1`&3x>t`V*YEU-qp-*dpXh8o_7)s%!1bP$aJV}1?c zQ2?NJ7_!*R9C43QFdC3*s~piGN@g$A>9?Ym1YNkP4ER)Xa_?`afBF_3#8g&WSfaM7sUE0Z{ZoM2 zneSh(?Q@|UA$)YLXGnK?Yc7-?r=OfakM-_NW#ql6r`NDoQ$opEz?7hY%;6amXs>uE zv2cKsu+sL3U-HXbjJH7Idpc7!TG3v6FGu8uh$!so;dILm5Y_C!2=9FBz+(rUJtZg1 z+u4}|Z~v2L$wT%jue=2*9N@i&R$i+hpK?dm+BrnqBUHERF40IvMMa#oPP_4SjbJ1z zeps%AQ&aE_DjD%e2JpFSIbr3-kF}0Ie!idxm8l0aP|nzenVA91C)w5~X3uSN>NtlJ zHb>?h+y1-ko|7x;=>d|Xk}_n9S@91%jTSXrGAOyG1Ji z@>vRk`SAH9>xK(|nTToTDU|TU|D;L8q}Ui0pg}i>$W=L|&<+?xFbc#*8F`}~*~FeP zwuit$_j(Ue^s3&j?`u;E7OcRl5M>xwOr>Jqt`y{N;p?ob)bt$1Wju`M2>>zK9pW1Q zNX`F#sy_O!^D$!ADLo%hs2DKRTA%eEaZz+&=mFMg2w4UD6MMH#^z>PhojiIntEYl-jAdA7jZo^5B3T@k+M zbGkZ7-Z?8Gw8p`GuS4e>gstkq8 z_5O3X?D{<~iC8XOfCF3$6UxXFMvt_IF1SJ$uhF+)ys~wo}ez`Wc0JaO% z-P*|9ZE8Ixr!B<-6k8R>Y${AF)l#OON0!?&t&Zw;t)!iYY$yQhD(%OTAo^dYk6v($ z^VLAwNIcfAkexa`0RnY1vP;2E;(HgpD&NnF=B=18wkXJ0qw5V?wN^ozjOJ%B!pmM0 z=G_l^_8Ku~F@Ac(DvVv%f@WR)IYc$&uR^K$8bN!e0H^yh_2%<;5PZ%IZeSa2kGu@% z4&5NIK=%t-4Pd<$Hh|*sF;|mXwjB$NNN8AZY{=Ws(~BkN6;lqcNAo=roDd)`g!CyR zLXqAD-=eM{)sUK;ShMX6&w>oR78VOKfc=5dTvDJs$7vobGy!r4X?xb#Xp996WV6w9 z4<$$uq2WC#n*EE?((2N;Etdg6v#sY)awmCV%@wiyq@#+bDW^e*;~oz)qn=NA6cgG8 zDP5Mr&_$Y9y_|Vc7T6}4uyIgR++ZA0HdldPJ5LS>4C*&H2heHby_Z%`x#ilq9e`

5B&zizc`ykZ5*#t7Sv5)Cx`L*MU+F3?DO`D(j&}yy zmGec;a@a-|J2bjzjOdGKcJ#uOflwIsXySe1Ev48Ae=G~`+wHDnt1fSaZrk+*=Yo2Q zetr-BLU;Gdy5eqij5E(09*Nhb?JU{zRt6NC4SuVC3>`gJFAyYfIM_G!Rz{FhvSVNj zGF*5(!ydzn-~#u{8Up z(%cX8q~L+Zu%^>+)mEh&u6BkRYTR{&Z-6FDtChNI(a@N=_Yoo{we%5$hPRk!8qgTC za2pD+tVOSa_+^|Bs@w9n8W%35t0{I#u*^3B;+r6+$Z5#ucIFCfNAT)#Jg}Mv6RzE zi0AoGoWsMp1Up;VcFS)(0JX!GqeD9UOP&(dpqE31+WmYl*Y*rdoL;~bmkuDDUz)Cb zxLDU#TwtKo?3b4wINb7A(<^dD4 z+Ka5P%N|Tn+xX}(D-9mSk1tHmmKdS=J|z0`Vf?6%B#_?ePf8xteJjAb-t*mQf1$$Q zG(n+4x1S|vXQRAFdS^H3JqY{ZVi`zw;+~6VPZISW$s-k;KnUNEob5K)#WYKziO9lypHE0 z;~X~w_NuKy(HAs;0=d0I_A2QZK@db+-%>vdVl`$q6}{#MaOjF=bj{J*+g-) zL;)k~`3CEfOQg5aDZ7l2^o*$2Z+wFIF+ytJd5n}hQOcdSI_CkRf0aK%Jw@S55LccM z8p3iQDGO^+YwQ6`(6jKzRP#?*^m-P4Lhv}5{(3KhlYBm7#p2${ya;e5z=jB!P>Waj z`_^;EmQJVy$NM0_M*$Ybo$q7zE5lH$&V~AV2ew}K_Qt&X;;5bC5j@euyCNu&X%wN* z++XFkqW}i_iJINCxzZBw^YJAJ!$A@Z%mX@wpZs75#ECaM7Fo+JF}Mm=9T6tj3g19S zER8&e2yQ{imAG;}1k}@{yV}TVSO&0S4))lIltBAEy;;W@dMGW}(~6L6m_tg$k7RXl ztK7`^T5p2gi(gbjBi^u9fw*o6%<8aT^qKdv# zQbJX80#&SPW-Bs9k!ek|wAh7G2?Q1+HBH$6=4XUS>nuL-vQCoxHiCNCvH_#3VXl0SC+s1sUQdQg! z*2bLdH~SYtZohg6Bhf;b@t$z%j1OgfdfkzX)z8c!G@F66L3k3+6GtN0#HwP)!~Mh& zU_Q&A%qA9*FhO*FsKQ`HI=Fg#L24V7kP{f|T`sOB>OtGa>H&<4`-^>Lzwg+WdT0B! z^M#;#{@Ewl0*OUo_d3+d;WmY-%0iu`kmdqa7+C4H(y|My>AuG@44uu82i^d}66i6U zqUj4Z$}h_djzA}-0O8>9myN)|8ru^)Qhb!L3FoN=l1u#qL7dbPSZ>xuu(B+BdFsG& zcE9V!k>ivwp%O_x_RATxNdx;FA!E&<8}=bEg9$UVPLOgHxn$NyvZDhtfT@|A-2gT~ zUkRfddLpBQs&18e7|!W1Lg;a16ns%$w(-~za5(iN=zG5bW84L`> zt}gI>Tlu(PHY{vWJ7u(GU@}4Ii*84p2CA)h*0+BbME|D%694myf;Kve3=Wk$luG~e zOv9mikyUADbH5@>;>e;523`&&?6gKF`Qd`jsuxfL%E$zhag(X)l zCk~+rCg7N?AFy`aAO)_>&RS*wl?gahtQ>#e;Lcq3C#r0Vt9G_Q!m57KO%@?t;cO7n zGxu)NavhKi1wZ$4yJ~j*${Ya2VgoO~qU)!h^Ifi!^#}Ldq|1>YnleiQc48CjI5mT%Wid?vR=Csva&(a0sf7qK+x`&?UjF%-L?cf!apOPWhiGUfIxtQd9_&IXN zL$3k1xm3REGsFv|ARO90xIhLO3ST@WusQ&C#(FyR{K4iF#st6yA+Tg;(?MMUl zxogrbL-52Od`o$kVY&!4a#b9KA+z>41j(mR|rWBLM;pfOD5aeD6jqoGrzspK>tp z+5~Yxuf=cZSP(flB~i7YPk0bPT?MxcDEQNpoq6OfoW)s7XxHA=Ox>{KC^vbP50nw2 z8H}IOV5d8CHyK4Fr8&VYoKcj^=HsF3P`37_3#@yL%F&Y2cKQR=8)~xI*-((;%%Q1i z;Eb2DtTDA=YQ3B?X2{|DKCq`-zLkne#nwgC4Xs=2WX+|9jT`9^oN?Mw$s?Y@!5y>` zu7;rq7yp_y)-JjY8Z?fT&S3)&XBwA#1WE@-1&`^!4TaTKTS;fqEbdp*#@HS%{*{$$ z9L`D?@VP*#V+;=b>5+r-}3gl4Aa$eCFsi)nK}P18pb(`M-#L& zoq`zy!ppJ#Q_)KnQGhGItbpm00pw6M61JL?pR!c0xfh(L`iHcK^ z{%S9IdO?T~p|j;F7rIR$i3C9((C4*IXaXmV5JlbC>BFp}!4Y9@wTiUWMprXxas^#c zC0+8shRcfieV9mDyUMhceQ3cp2jrr|%jCmLtYol$&VuK`7WUNf;?f9;-n5=n7V$RN+>1Gv#vI8AS5v+NsNRy#0uE>yZ z7ejtaugiM5B(5si{|hhj;nM1*%K{DkVAmOvm`aQRl`d$c!lD@AF6H1~%$$LKm;XXByCmaz_HeE!%% z_HXZc<=C}j2mQ~tj^P$>+qAqMI@@`%usOn3Kt(`@fz%h4;-%Jr7KAb3D(IMlvQ|Uf`&*r zEWXgWHj?dEL{RH>xCKAV-MdX()R+Q!73 zR2>0ZYa3T$+pyvbk=T_MBqqGB>m(Y=oRxXnaw2$!Q?nir0CX*0w>0tW;mWAN1U#6; zrWnDs9)qL@1lvWSBwpjv6c`uB3>iP7_(a2(8vhHlk?@1PM(!w)ttq1*bcQn(AHi7) zV3CM-b%s9Yc_>hr0$VK27>Vo>w$CfI@6uP z#YA4&IT;FRw$3EHpsh@hjwy4JO&7|H+fADQ%ECcrPZe=6D)3>Ah-^dhHcb&2La171 z!MxNnGt7qzflER0BbcP~cPD<+pe(5hFQXOVs-VaMa_H5VK%$32vA0sUi^5CXPncGU zY|CuY>KB5DL3FaCKrCl%-%0knLR}t8OmV%&#W!@D?$rRi`|%b;kEo^go2|{ zi3(GSpJwsod)}XJnqj6+W_htb-~tz$E?{v8lwDVMocWHSVT;a_M`mUKdEi*PcVdrV z6Re(k%$E3&z_qXhNYq+pF*K$QpvoHi3t&z-w)G|AB6hC;KuYe~^TJ(>S~$r`<$O}yv z1@K+iZ@yW&qqfpAds_B5h+Lp(rqT1xC3-^+6(}=SO3qj#tq`k4``*h)R~*gCdNEuA zv0cvwp-A5ra$Q=kplZcIT%C%y(CU^v@OBZ6RMwdQQiAnL=|}rPmdO2S>|?Kc7y2Bk zQ`AZ`QflolG&D>FVk&be8mB%gPDEr%|84NfUPntc5o`r|(^ZTzMp=FkS?X`yTyHHS zfE=Ec47G%fXeA;jjzzP!6m^`N6`$IeC<|{51!4vB9zx^Jd{vYl$|MV&gk7!DkF-Fc zYj5nz5LLO=HZ^e-W{%L6ZnBI+aBMs}w>RSi-Zb3sMKO)46))S!QdGWwsY01kkzaI2 zwG;P24)PvFW-^1{>cKL0HdL+lwGsq8XV6_7HxpaDn8%4056wGOB{~-kF6xS%3ZPIC zB=JmXz3Z!q^#0n7P+x=6>qB@wukH$PSaqF;5Z)J8#U|(EjM(WY*vAt1D_wQ{)^QpS z1A8@{zRXk6l+a)YFDFofIbK=p)o#>RVp)Q^Dbj7mm1Pz816Ur#xc~ zzBq`fGHwTA6B`U=lc<6HCS5pGsqdN}zK-QLt)D4b8i)L#VRFA)KnY>G=?%!m6abLZ zCt&htdV-Cid%5Hv%xG`8J1*g+`8iJw*ptFB199V9i_JQdXjI#2N&rygvp1R$hVA6ihow_ma!R7cLT*u**Km5%Z-G%vuh`>$e9IwwR zd&auv2{^iO&99fW5I!&6Je(XcxUqMApS6CGE^;z%%xfa|B$loVLhbu*wX8`aFzq5p zEys6!Hr?-GF5oMX<61?JY)lS7#jsG8;1pcEDC6 zcVSKGvV3fcRyT!v7`C5t)5}X{kO0Q6n}V#z-QJA@9&ciPsKdRD&O+K4p>Y@^Q=kr@ zKBv$NX6tUgfk$#P3gsrT-a;@Oo7k?HXk|)ND-GKu47i9TW=YE-{CUQ=uE-e$`898F z-J-uWquJidc-E0!YlBxZ%n~!~c;5NPu;(yCS76}tps;@{jTVR=QPe=C&We<;ga^Wx zP=^_WY~B)NNrud1BF&3~jFeCn8)l`|P`$&^CNs%TgQlz;Wk96`|47i-A z{5CBv^klZ@-5{Y7O;_yotrr#B78tNsR&~o~CV0Y9sQwTT40BrI02;p;KN;2X_KA_8 zyonqMvzU!}@IDT9y|5daaJ-*}{37QqpTogBZkDC)^-%P>E@@q*(6z9}8Z6qKGg;Nk0U5(a`!&^VNApBAF0vn> z>N>cdb7`JkALaf+Wh%qrqplWnYThtilCa3*YM|M!hVE&<;;qVHVUx$y>`dnJX1fW+ zLd*1~fRg4t)&+Ln`uit+NUq$Ne#vpO_#C=v70U0LA1+t*7}1H)JHOtm2(7J&f4|0i z^sreU+vp3%2~o=lSmf%Nf$CYq8XlqWz65WS^6F(GAd}w8KMs!~MCyA!@AIJf#)j*} zhi`ntg@hn-3wnte3G-69$;j3AKBsbCF3x+j5`pRR=D-z_Hv@1)Nxj1E@F6!je_>;1 zkLOSM$X7lHbqCkmIhMt9Z5I+vTT>93M>C;Djhe-{p)>!~WMZ8Ds3ds9hSceqQo61x zemLzokI+W6#j5T&^-YF?+#lWNX*al=e#H;S4qp-GY8E+39yWZ1NsNBVIuj>ht8gK% zJZ}E_Fj|@%5|2xar;PXKg#$S{wQy zjU$fT9LMscJ`9FMZpt!mCvwS&wWGPQu}Ne?V;7AL#MB(9admZa9608+8@Ga=M5OpO zGT$|yml?tEE&&Oox+%l3uHDcVBL&$+k7&m<51E^@mP8?`yi+fv+b|lXtQ%Te2msd( zigDAs>sf2xdu}mya*!6*Hk=FNR8vHC<@9x|dy0V=D; zB~?--6)IcF$k zD@ynJ(k64c4p2m6AWK<_()rh{V6NB^rxaI9Q;an|KlIvD*DcLbl~7J$oDmyfdESmh zK^2N+pHqs>s;-+u$3%p>GA4P~@HKu!Po1|sy#id9w?Cvf*9i$XK1(Vj5hP`ymENw5 z4d^7w&L1e-kmXURllH|mV^XYhKZ76)=~IL`bYOppNZF6!;?`Xvo=Pc6OJ;$4AZaX} z$wAf9E_R8_thJ3!iypX85^N=6Xr~R6+${QQSq!1z?wc^lP-R zU$ULMQ~s`6FO*&}e(@YR8~g}Q=@~X|@tD5;#K}MjOQ9@>ir5Td*@>S#F0&^Mr)FPE z+yjHTjc--BxT9FHm1eh)9(SY51KE@(j4cn~?gs#`bH7JV#+L7SH?};uTboQCI%J^@_q$HucBqe9W`Hhgg@_O7&t0F~kBn6BeEpKDO;9TRF&3;A2lr$X<-NO%WG&l1^8dW%g0RvlsLqZ#HSU_g){##(;`Bh~L( zR*4Cz>R^kA@%tg4+03()r`+uuSmNuUtO`L`JBGU=0IX<)s!%qiFh#f6G5<*5NGB^4 zh8|^RKOb8{l$H4dKXAkAp5cXgRZk(|bdc~lcc$0Y)YjZMW7JZx5UTh2XOZV zARe2;z30c~?{TO0z-yln-9&qf$^LXa1wF9QyXMLJS%|G(k02 zWPJ6M3fUB!*G=NMbzj9$@{Ir9-w=PKpyI!$VwlRm)=hI@(n2*tSl(j40$4mEVfQi6 z)*oR&7NQ>wxsvjZu7KU8v`(xf#JLV|>sfEomsV_{Zae_n7PS+e5oT zO7SZub+ZdFkOBj(&{4v5aLeB2qA@hH@Bs=rW&Bz+Qr=aVgZnw2@f9x#vkct2QL#w|<~S zd-u!5MB#HbnRqm>+TpX4Plh!a%w1)m?dK=mxDYXi{eVh-=Uc-x`agG2ScS9BI_UpE z{@N10tEVn*HCF;DQlt*-UCG3wgiciQq!c^<3dhLMvv8Ut@|lXueE4-T%wPRPxAwT< zL-QO|b5JbEER9n!f18PI3Ls|LwIAxwM{{ygIEw!#H;v$5r(`}K)@WMmopz>abWLvn zccx*Q_)wP4GklrFBRoYFuQfE)L>u-J5NY zzZ~TuV{mlH6-MXK!`u49?f+RD^lqE9No!j4Q_B*+oxyj?@yaUh9QGh)c~8Mm$3pa5 z{j6yu{X|ox06I(ryZb!#tLYCN;U9pfUW41zuJ(J80JxX%Od}?FmF(yR4n02LS^rw4 zAIGiV(7lZ!_g^p!7?LORn<~-Kp!g3>%PTB$WfPJR5D>+)cE5h*V3C>XKmbs}2va0O$>~-@F9x^Fijd0==_f4F) z+gHT@8Z5Zmc&n|k!B5q7I&X86e@1KDssqp0{eO;S*{AAr#kyv<9{bvlJoU^Aul&M4 z9-A9)P7NnJaP>{>cnEg`fbWjgk$3Rm2mah&L}_a9)f;$3;-c_%QWB7RvZ*_Q1&BWGo2&dGV%m51Z>O^GA}0Ra@o|EvsD z4dy@1u%7_{2L zna2omm&J)`lhCM~UW`LEOI28l+B1j?ZRoYlCGYW8i>}TIcZD!MijN|!#oPK-E21uVAf79u z0wxn$Y@r#n5hS2tXuVyHKjNsKIvpx?j1-PX!4BtCHZixu6-5dNRH0cavjxOeBqi5m zmC>QgAc|1xO0~|Ity@V*X&=A~`D)D!d-T;>)dT13sNx6UHzs$^E~^PfYcETcsuZ5#1k4*HQ1xFVaX ziIQ-uS~QAgS!7*(s9qYq)DILr{rq-vjxtxVtrtHp?Yr{Pn#AaYc@*^0v4_#${7MUD z^sc)|g1q-#<-UGy;73w3hzQe{j`Uiq)T2pNsxzHH9NLrT78!A80cB!nnLR!O2=?Z- z6xWGfTFQLR_?J}kS4H}_jIzie2$%A}~SOU(Vethao+M@60m!(XM~m=l;<*Eng!H7!){hfnm`DeDK13 z`d5CGr)StNa+4EX8`<0IRHV`6{ytu35Kqo%8FxCG>Jpq0ZI1PhAVwYl5EHT#bX{8;!_Wo2-0&O zOJyDZPh@K{NV735SQ2s4Cjq9@V>Ic%P_(mBhnOhDrCf||$hhl4gJaD57=gLVO~tBjqO>ZyCJn%dL=M;8?7Y}|^i2e6P_`J4kL zxM(=gxvm9`zXg2^5Y;<&p&~OqM+5)|IseVZS}{wQ9wY9z^2HWzZe}+$xwzQ;Py+k; zehvpR?WY0V?-^PKK1T0x0oPzMa0C}FC|Y>%Z@y8*()`*;ih%8w|65$=?R4%Yb~U{! zfY{QGi(j zWzhrLmNsxX-@)$`)B}-OhMiOS&QhX%IxFyX3gsQh?cF4o+*J|_sm1Hg;5YLES#l1L z)8=f7bY^2miPXwc7$12QhZTgjPH$%|tfNyqh~Sinha`|7FvJ@eL$;K729lqaB5IN+ zogk~M>qwbd?wVbTZMeo!gUX~Dwuxhy1gR0YchsT|wDK$2 zWC<}XymQpJu-lm~%`r6R>bRVN@?tczl`7HY>9@+ha?ed}XTJh0q_Z&~mx{6v;m}}9 zNU=69s@T@PJSmiW(?EmJ^9yd6Hgy)*r#l5yCy`lmhl-U%x~nkz2(%JmU}wqhUHMp+ zQ@Chi3m25_E=|uVqXaRMx40EY5B$x&g8dYGTw`n>W7h$PmXX^s2c?@?mP+G9R*+o? zX9=CP3_wvIC&wZTB!ie!C$&u376+P3}4T?Ru%S9E2!JD=A{IDsuuE zGqLeI*SdU2fNwNg3Szzm zj@7PDxAm5rH`!`yn<@DnHdTl%1$Kv1jFDo+iI)H*Q4%nSWKb|E9qvfw;8j)yQ3WKF z)T*KL!AO%X0~SsuJc2AlB-zL)sB+|@q05txfr*8UgNuhxK-lWx{x<|HF$t-mb>}A| zudaFu%4(^oX=v%_85o(E`@zDhfQ_AllS^T@YEV>TO^O?(gj*?(GG65>RI1`rt%hH1 zPt>W`P_t1Q8?C9<#%Qj^Xf0Y>b5>)GHO_bw%(uWoi!8Rp(so>CxfNFSv|nagUB@-n zT4%ity=$DVCYX3r<1MhoR@-d1!%n;Gw#Q!W_Sx@%gT1l7z{8F>>X_p_*V7rjovPTD zwmj{Ovz6G<*5_St(IuB%an&`~-Du96{qCPT;I=#N_Oen(9PM;x9do>MPB`h5)6O{S zobxWY*msv)cEwfKI`4WHy4X)Qy5y!?ZoA`OclEpHz6Tz9veXi*V3fuTe)?hxFI*&+NM&+`QpF?8YbiGXLNJ12^pd~{k}?=g zW{cHkcQ{>ckJsl91ViCSlvkKfQnqv^o68p-MiRr`w~K#9%lYPo}f^ zV!2vx=+SwvCgwkMqQ5^$w<<<=40rcs5U+8X(YsZ{XA%HHFv8*T_yVCw zERo9O3MFK4aZ8|W-EzZV#BkrmY70M{E;n`X|CT?$W5R5)+UyRe%kA;{`~V2SNC~Di zC)PHr2*lu4x#R{haHnfKT1+dnDtH2jm3k+xRWt;bfr{*N1r((!M%Z*SMlqKBv> zsXXNYr_|aD(g=qhQXXk=E~S|GJ{)PRTl%tz%>C<+_-dw!x@47m$t4R_+!5zdx!L5E zt4lE{G!h85UNQ~Ava8G=;%Yk;N4ltem$Fkkx5^Z5E4#K^BN{S76?=ARpeI(z57&(Q zx&cmr{|`QC_JFp`rkuKEVOh~aRh!)t1RL965s)e_Ns=T9c@E3U)?TP`;)pL_SCU(n zkelT?4V=1|imDV%(yAzM-eAc_XS z-(F(pb!PJ~3845tkkw2;?U+ruN&Ajs`Ea24;R>eA7;X;iefKQ`WP1;f%UM7EX#rMg zQV+FjEBC*}=zQC4N4G1nb+~EUcQx|h;O+4AaNe_4sRJCDHw8Q? zcgB_(0l-=SRhUfC15%~=%?UvL{zj*S8Jh5J+RBHc=qd3GA!~_d$q88{BvfItsklGQ z_eZbLhxDrfb6n4v6&7DMgvExv%l;Ae?(Hi3(#zudeip|P3 znas(IIX5*JPA(AaxqWEIUhi%c;Hnl4c)Y7x{V4?hva9FSOR5u0DC0sZZLH(wH3hPMMe{(4!SxhBZ(H$Ne#&xkFqYp&8sOhXV2P16`fTpoRawWrz^&omsWuzPutt)*nH^+X9|Md5*>HZsm zxNZ*8|FCQ(n|7H)sE`H$wp^zgG0QX#!kMy4#jP$2zYJQMP%RIK%?4|_abHH6aY}jU zHw9O1_`@r)C0hGRVAe5D@;2U{7!<~dF{~`R>+E|oXaeU}_U>M8y&;>grs{dz42PeT zEiE-!2$3NLY<67@m<5K={EL6E3!uQ%84PQusUk<&GNpsut=9r^Td4V4)E0Gl5M~G> zTau=!-!RoFL8v+wPjR)x%~e}5j928n&n|v}0_!#`to;$h!q=GlKHPc!mt$M4kqCgi zzJZ;EPR6eN$aBbh-muZ_&=$oo)Cfz7ODC2X?M(f;4?R#?!rPd)JhU@4x_A`#j(gTZ z`L~~(QIl%2BAs7{xjM)^7mnp%xS~vOYsOLVHtjpU?blqIU#P({G?Q6NTMsSNBI^7R zbu;23{ts`b+{Og@>G295<0U>VIPVu;wO(q*ix~qx!Ke5#sDCHNR}SvnDrY~6P%?2K I0hlKM0JgZhVgLXD literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Regular.woff b/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..7d63d89f24bcc0c0f5dc3cda086fee67da266ebf GIT binary patch literal 50664 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%0D2G&3Y8fz)sfMJYF&mh7!l>Kv<9rdEn*UI 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 QGqXAKIiCL_%0K=90Nq5|6#xJL literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Regular.woff2 b/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..d0d7ded90791221663847f6258089ab9bb76c23a GIT binary patch literal 35536 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff b/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff new file mode 100644 index 0000000000000000000000000000000000000000..1da7753cf283671f5d127c6949074d212a843c58 GIT binary patch literal 52936 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

tOoZDe8ce%>V4mauJPm<339_c?PnNgFV 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

8wA3$ns4i`zle@wL zXrh$aD$I|hlrP%LM%{-nRY-c+OQw3H0FWMyc|R173Aje|4`pUT94u25kW46r<%=pA z6JEk{L=^`K4X`3nWf?*WEUO4mMW}`q6e)QTP_W!0#SKC`tfWX;fRG4#=?KUpRKie> zO118cO>+U%Dc#oZwb~TaH=sEKYFk$|Z7cGceagu9VROp7 zHQ1uCI#V^Lx=+5W><#$6wWHMJH($2q%K7^NbuEyEHx-T6_veTZA2kTra>uu^pbYb7 zXY$rmX^SoJ^_Fi^LABOYhHvh?oZZNVL20Jgrw4=sq=8X=6~{2fW6oXQd@2dEgv8c( z3uDSZvoI_O7r`1<JuLO?g3QvfCa*4H;|e4n^=5d`yNy0S&v+fS-+$3~0gzu$F)_Fqc3(jpfLFqv)XC!iKECepq)s|K`3P*#m8C z+}I4)-($W*ZJuFJ2P_aOSiD8#>m;7+A2pgDd?GxEP;&UhvBrd5WNqyp)_I@SDrD+* z@7Z8>s5R6#{NV%%(yXCVSn22z(LIcHX>e(L=ANW z-j0~cnw*?+lJ)55Xgsuh)u~{WqMjMHFGT3Dvvx^Q3 z!i2+-U?RPAyyjEngxf_}pr({MD8CT&xaf|j2LHJhg+QONAu_OlO*zk|L)-%#aE5O) z1j!H`2z59@z}chuY#AcEOJ=@DF2h4~o9b08g}8RM+BrVWDHVSlBr zpW+_0^8z+i3fLH;QE|>Q)Ov%U()^jD+w|cUoFd`=lf(Mm{+y7Ag$d)l`35~ml=EbX zKy(Q+Q)m(sLP(fg_hNg9|5#xQwUGSNU)JV1udI)$6dE(q?sk!gn-!z33_w4IHRM71 z8kJV-Va2iiL+@Ez}R` zRpH(Acd*Uj(}{~IeW7J;z%NNVlk5vyes%*{M*bOjY->Hi^i5b&6M`M+SMTPvl~jC! zPD*F=JQm>}R2Ad=^qC!4_48HowN(p+zefL7jP$1O?_p6nr^`OX2D{SdGeUcK$C$Kw zupjQRu$;0`udlp_1=0VXM!hE}cKHIH?g;~piONnES@~a}Hz39 z9E*|-xg6*lr0Yu4OXZR-A2h zRcB9w@43eCs-?pt4Z!6DbKX-sz4HsyE)ZJNX-QphSKZb1Ifrwm!KqiAvYpU{={j=% zVzhXPninrN*z|ph86ojbmk>n{8z=pt>}*B-iu=#R6|li*9LQ(ZG%CF7=z?OcgPnOl z?&2~34@{iIq|DQ!r(LvHx)SE2r2TCMyg!XAJu#MAF5E9ZC3t#a&|S}5JjRhUD=;X& zq;X3A(62X}+V3p-`)j>Ga`)r1&nKi3rJ#yblo_Z$bt z?zlznI(3UkmT$jQ3cqhD`n*SQFsT_w;Kp`gZ3*(mVHYyCEkZUS$o{DsSR1^cU(A=o z_VfDdjK#-kvN+YvsET-qtB49y8Us&{qzWT8R_-d!^X{J7on;5l%Pwl}T$@t$F3VAT zPeC1cc@_{i`8wSxBdwucTwDck^67?R^oTr+MU~dW%-K(G&idQx8E934;_CK=9;90< zNUe9by8<1?ogIRY&U|LZ-CZ7jDTEUS5+80yEL#W)mQMl>E3f_Xd}ohEEZ93p|N?H})D7Yxzo6@8qw)-&UeB%z|r24IZ?*L8js zkE_~$OJWPd+N;ZX7df?9=YgLetj~@b5lvDQ@W0OBC>@)ZI4f2A)ns$$w)NSHzHH2v zJV>?LGe+aps%XG#Oss)+qS@JT_g-fFGuM1snVFJb{aPrz_~DaB%d+cX$J@WxwOY(- h@zZe_lV3JKRvdRg6LS4>E$I+WWfr@y|LMYoe*#6Z(kTD{ literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff2 b/docs/v2.2.0/_static/fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..79dffdb85f745ed98906f3f28dfe833acd98e287 GIT binary patch literal 37592 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/images/arrow-down-orange.svg b/docs/v2.2.0/_static/images/arrow-down-orange.svg new file mode 100644 index 0000000000..e9d8e9ecf2 --- /dev/null +++ b/docs/v2.2.0/_static/images/arrow-down-orange.svg @@ -0,0 +1,19 @@ + + + + Group 5 + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_static/images/arrow-right-with-tail.svg b/docs/v2.2.0/_static/images/arrow-right-with-tail.svg new file mode 100644 index 0000000000..5843588fca --- /dev/null +++ b/docs/v2.2.0/_static/images/arrow-right-with-tail.svg @@ -0,0 +1,19 @@ + + + + Page 1 + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_static/images/chevron-down-black.svg b/docs/v2.2.0/_static/images/chevron-down-black.svg new file mode 100644 index 0000000000..097bc076ec --- /dev/null +++ b/docs/v2.2.0/_static/images/chevron-down-black.svg @@ -0,0 +1,16 @@ + + + Created with Sketch. + + + + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/chevron-down-grey.svg b/docs/v2.2.0/_static/images/chevron-down-grey.svg new file mode 100644 index 0000000000..82d6514f25 --- /dev/null +++ b/docs/v2.2.0/_static/images/chevron-down-grey.svg @@ -0,0 +1,18 @@ + + + + +Created with Sketch. + + + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/chevron-down-orange.svg b/docs/v2.2.0/_static/images/chevron-down-orange.svg new file mode 100644 index 0000000000..fd79a57854 --- /dev/null +++ b/docs/v2.2.0/_static/images/chevron-down-orange.svg @@ -0,0 +1,16 @@ + + + Created with Sketch. + + + + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/chevron-down-white.svg b/docs/v2.2.0/_static/images/chevron-down-white.svg new file mode 100644 index 0000000000..e6c94e27b6 --- /dev/null +++ b/docs/v2.2.0/_static/images/chevron-down-white.svg @@ -0,0 +1,16 @@ + + + Created with Sketch. + + + + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/chevron-right-orange.svg b/docs/v2.2.0/_static/images/chevron-right-orange.svg new file mode 100644 index 0000000000..7033fc93bf --- /dev/null +++ b/docs/v2.2.0/_static/images/chevron-right-orange.svg @@ -0,0 +1,17 @@ + + + + +Page 1 +Created with Sketch. + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/chevron-right-white.svg b/docs/v2.2.0/_static/images/chevron-right-white.svg new file mode 100644 index 0000000000..dd9e77f261 --- /dev/null +++ b/docs/v2.2.0/_static/images/chevron-right-white.svg @@ -0,0 +1,17 @@ + + + + +Page 1 +Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_static/images/home-footer-background.jpg b/docs/v2.2.0/_static/images/home-footer-background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b307bb57f48511ac8f1e76ac6bdf6cea97441b21 GIT binary patch literal 38907 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 E2S0P)JOBUy literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/_static/images/icon-close.svg b/docs/v2.2.0/_static/images/icon-close.svg new file mode 100644 index 0000000000..348964e79f --- /dev/null +++ b/docs/v2.2.0/_static/images/icon-close.svg @@ -0,0 +1,21 @@ + + + + Page 1 + Created with Sketch. + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_static/images/icon-menu-dots-dark.svg b/docs/v2.2.0/_static/images/icon-menu-dots-dark.svg new file mode 100644 index 0000000000..fa2ad044b3 --- /dev/null +++ b/docs/v2.2.0/_static/images/icon-menu-dots-dark.svg @@ -0,0 +1,42 @@ + + + + Page 1 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/_static/images/logo-dark.svg b/docs/v2.2.0/_static/images/logo-dark.svg new file mode 100644 index 0000000000..9b4c1a56ac --- /dev/null +++ b/docs/v2.2.0/_static/images/logo-dark.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/logo-facebook-dark.svg b/docs/v2.2.0/_static/images/logo-facebook-dark.svg new file mode 100644 index 0000000000..cff17915c4 --- /dev/null +++ b/docs/v2.2.0/_static/images/logo-facebook-dark.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/docs/v2.2.0/_static/images/logo-icon.svg b/docs/v2.2.0/_static/images/logo-icon.svg new file mode 100644 index 0000000000..575f6823e4 --- /dev/null +++ b/docs/v2.2.0/_static/images/logo-icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/logo-twitter-dark.svg b/docs/v2.2.0/_static/images/logo-twitter-dark.svg new file mode 100644 index 0000000000..1572570f88 --- /dev/null +++ b/docs/v2.2.0/_static/images/logo-twitter-dark.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/docs/v2.2.0/_static/images/logo-youtube-dark.svg b/docs/v2.2.0/_static/images/logo-youtube-dark.svg new file mode 100644 index 0000000000..e3cfedd79d --- /dev/null +++ b/docs/v2.2.0/_static/images/logo-youtube-dark.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/logo.svg b/docs/v2.2.0/_static/images/logo.svg new file mode 100644 index 0000000000..f8d44b9842 --- /dev/null +++ b/docs/v2.2.0/_static/images/logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/pytorch-colab.svg b/docs/v2.2.0/_static/images/pytorch-colab.svg new file mode 100644 index 0000000000..2ab15e2f30 --- /dev/null +++ b/docs/v2.2.0/_static/images/pytorch-colab.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/pytorch-download.svg b/docs/v2.2.0/_static/images/pytorch-download.svg new file mode 100644 index 0000000000..cc37d638e9 --- /dev/null +++ b/docs/v2.2.0/_static/images/pytorch-download.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/docs/v2.2.0/_static/images/pytorch-github.svg b/docs/v2.2.0/_static/images/pytorch-github.svg new file mode 100644 index 0000000000..2c2570da1d --- /dev/null +++ b/docs/v2.2.0/_static/images/pytorch-github.svg @@ -0,0 +1,15 @@ + + + + + + diff --git a/docs/v2.2.0/_static/images/pytorch-x.svg b/docs/v2.2.0/_static/images/pytorch-x.svg new file mode 100644 index 0000000000..74856ea9fd --- /dev/null +++ b/docs/v2.2.0/_static/images/pytorch-x.svg @@ -0,0 +1,10 @@ + + + + + + + diff --git a/docs/v2.2.0/_static/images/search-icon.svg b/docs/v2.2.0/_static/images/search-icon.svg new file mode 100644 index 0000000000..ebb0df8677 --- /dev/null +++ b/docs/v2.2.0/_static/images/search-icon.svg @@ -0,0 +1,19 @@ + + + + Created with Sketch. + + + + + + + + + + + + + + + diff --git a/docs/v2.2.0/_static/images/view-page-source-icon.svg b/docs/v2.2.0/_static/images/view-page-source-icon.svg new file mode 100644 index 0000000000..6f5bbe0748 --- /dev/null +++ b/docs/v2.2.0/_static/images/view-page-source-icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/docs/v2.2.0/_static/jquery-3.5.1.js b/docs/v2.2.0/_static/jquery-3.5.1.js new file mode 100644 index 0000000000..50937333b9 --- /dev/null +++ b/docs/v2.2.0/_static/jquery-3.5.1.js @@ -0,0 +1,10872 @@ +/*! + * jQuery JavaScript Library v3.5.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-04T22:49Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.5.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

torchtrtc

+

torchtrtc is a CLI application for using the Torch-TensorRT compiler. It serves as an easy way to compile a +TorchScript Module with Torch-TensorRT from the command-line to quickly check support or as part of +a deployment pipeline. All basic features of the compiler are supported including post training +quantization (though you must already have a calibration cache file to use the PTQ feature). The compiler can +output two formats, either a TorchScript program with the TensorRT engine embedded or +the TensorRT engine itself as a PLAN file.

+

All that is required to run the program after compilation is for C++ linking against libtorchtrt.so +or in Python importing the torch_tensorrt package. All other aspects of using compiled modules are identical +to standard TorchScript. Load with torch.jit.load() and run like you would run any other module.

+
torchtrtc [input_file_path] [output_file_path]
+  [input_specs...] {OPTIONS}
+
+  torchtrtc is a compiler for TorchScript, it will compile and optimize
+  TorchScript programs to run on NVIDIA GPUs using TensorRT
+
+OPTIONS:
+
+    -h, --help                        Display this help menu
+    Verbiosity of the compiler
+      -v, --verbose                     Dumps debugging information about the
+                                        compilation process onto the console
+      -w, --warnings                    Disables warnings generated during
+                                        compilation onto the console (warnings
+                                        are on by default)
+      --i, --info                       Dumps info messages generated during
+                                        compilation onto the console
+    --build-debuggable-engine         Creates a debuggable engine
+    --allow-gpu-fallback              (Only used when targeting DLA
+                                      (device-type)) Lets engine run layers on
+                                      GPU if they are not supported on DLA
+    --require-full-compilation        Require that the model should be fully
+                                      compiled to TensorRT or throw an error
+    --check-method-support=[method_name]
+                                      Check the support for end to end
+                                      compilation of a specified method in the
+                                      TorchScript module
+    --disable-tf32                    Prevent Float32 layers from using the
+                                      TF32 data format
+    --sparse-weights                  Enable sparsity for weights of conv and
+                                      FC layers
+    -p[precision...],
+    --enable-precision=[precision...] (Repeatable) Enabling an operating
+                                      precision for kernels to use when
+                                      building the engine (Int8 requires a
+                                      calibration-cache argument) [ float |
+                                      float32 | f32 | fp32 | half | float16 |
+                                      f16 | fp16 | int8 | i8 | char ]
+                                      (default: float)
+    -d[type], --device-type=[type]    The type of device the engine should be
+                                      built for [ gpu | dla ] (default: gpu)
+    --gpu-id=[gpu_id]                 GPU id if running on multi-GPU platform
+                                      (defaults to 0)
+    --dla-core=[dla_core]             DLACore id if running on available DLA
+                                      (defaults to 0)
+    --engine-capability=[capability]  The type of device the engine should be
+                                      built for [ standard | safety |
+                                      dla_standalone ]
+    --calibration-cache-file=[file_path]
+                                      Path to calibration cache file to use
+                                      for post training quantization
+    --teo=[op_name...],
+    --torch-executed-op=[op_name...]  (Repeatable) Operator in the graph that
+                                      should always be run in PyTorch for
+                                      execution (partial compilation must be
+                                      enabled)
+    --tem=[module_name...],
+    --torch-executed-mod=[module_name...]
+                                      (Repeatable) Module that should always
+                                      be run in Pytorch for execution (partial
+                                      compilation must be enabled)
+    --mbs=[num_ops],
+    --min-block-size=[num_ops]        Minimum number of contiguous TensorRT
+                                      supported ops to compile a subgraph to
+                                      TensorRT
+    --embed-engine                    Whether to treat input file as a
+                                      serialized TensorRT engine and embed it
+                                      into a TorchScript module (device spec
+                                      must be provided)
+    --num-avg-timing-iters=[num_iters]
+                                      Number of averaging timing iterations
+                                      used to select kernels
+    --workspace-size=[workspace_size] Maximum size of workspace given to
+                                      TensorRT
+    --dla-sram-size=[dla_sram_size]   Fast software managed RAM used by DLA
+                                      to communicate within a layer.
+    --dla-local-dram-size=[dla_local_dram_size]  Host RAM used by DLA to share
+                                      intermediate tensor data across operations.
+    --dla-global-dram-size=[dla_global_dram_size] Host RAM used by DLA to store
+                                      weights and metadata for execution
+    --atol=[atol]                     Absolute tolerance threshold for acceptable
+                                      numerical deviation from standard torchscript
+                                      output (default 1e-8)
+    --rtol=[rtol]                     Relative tolerance threshold for acceptable
+                                      numerical deviation from standard torchscript
+                                      output  (default 1e-5)
+    --no-threshold-check              Skip checking threshold compliance
+    --truncate-long-double,
+    --truncate, --truncate-64bit      Truncate weights that are provided in
+                                      64bit to 32bit (Long, Double to Int,
+                                      Float)
+    --save-engine                     Instead of compiling a full a
+                                      TorchScript program, save the created
+                                      engine to the path specified as the
+                                      output path
+    --custom-torch-ops                (repeatable) Shared object/DLL containing custom torch operators
+    --custom-converters               (repeatable) Shared object/DLL containing custom converters
+    input_file_path                   Path to input TorchScript file
+    output_file_path                  Path for compiled TorchScript (or
+                                      TensorRT engine) file
+    input_specs...                    Specs for inputs to engine, can either
+                                      be a single size or a range defined by
+                                      Min, Optimal, Max sizes, e.g.
+                                      "(N,..,C,H,W)"
+                                      "[(MIN_N,..,MIN_C,MIN_H,MIN_W);(OPT_N,..,OPT_C,OPT_H,OPT_W);(MAX_N,..,MAX_C,MAX_H,MAX_W)]".
+                                      Data Type and format can be specified by
+                                      adding an "@" followed by dtype and "%"
+                                      followed by format to the end of the
+                                      shape spec. e.g. "(3, 3, 32,
+                                      32)@f16%NHWC"
+    "--" can be used to terminate flag options and force all following
+    arguments to be treated as positional options
+
+
+

e.g.

+
torchtrtc tests/modules/ssd_traced.jit.pt ssd_trt.ts "[(1,3,300,300); (1,3,512,512); (1, 3, 1024, 1024)]@f16%contiguous" -p f16
+
+
+
    +
  • To include a set of custom operators

  • +
+
torchtrtc tests/modules/ssd_traced.jit.pt ssd_trt.ts --custom-torch-ops=<path to custom library .so file> "[(1,3,300,300); (1,3,512,512); (1, 3, 1024, 1024)]@fp16%contiguous" -p f16
+
+
+
    +
  • To include a set of custom converters

  • +
+
torchtrtc tests/modules/ssd_traced.jit.pt ssd_trt.ts --custom-converters=<path to custom library .so file> "[(1,3,300,300); (1,3,512,512); (1, 3, 1024, 1024)]@fp16%contiguous" -p f16
+
+
+
+ + +
+ +
+ + +
+
+ +
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/conversion.html b/docs/v2.2.0/contributors/conversion.html new file mode 100644 index 0000000000..54bac34d10 --- /dev/null +++ b/docs/v2.2.0/contributors/conversion.html @@ -0,0 +1,813 @@ + + + + + + + + + + + + + Conversion Phase — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Conversion Phase

+

Once the graph has be simplified to a form thats easy to convert, we then set up a conversion context +to manage the construction of a TensorRT INetworkDefinition from the blocks nodes. The conversion context +records the set of converted nodes, block inputs and outputs and other information about the conversion +of the graph. This data is then used to help converters link together layers and also hold build time +information like weights required to construct the engine. After the context is created, the block +converter starts iterating through the list of nodes, for each node, the converter will look at its +inputs and assemble an array of resources to pass to the converter. Inputs can be in a couple of states:

+
    +
  • The input is a block parameter

    +
      +
    • In this case the input should have already been stored in as an IValue in the +conversion context evaluated_value_map. The conversion stage will add the IValue to the list of args for the +converter

    • +
    +
  • +
  • The input is an output of a node that has already been converted

    +
      +
    • In this case the ITensor of the output has added to the value_tensor_map, +The conversion stage will add the ITensor to the list of args for the converter

    • +
    +
  • +
  • The input is from a node that produces a static value

    +
      +
    • There are nodes that produce static values, typically used to store parameters for operators, we need to +evaluate these nodes at conversion time to be able to convert a op. The conversion system will look for a node +evaluator in the evaluator registry and run it on the node. The IValue produced will be entered in the +conversion context evaluated_value_map and added to the list of args for the converter. If the node +to be evaluated takes inputs, the conversion stage will recursively resolve dependencies until the final +static value has been evaluated

    • +
    +
  • +
  • The input is from a node that has not been converted

    +
      +
    • Torch-TensorRT will error out here

    • +
    +
  • +
+
+

Node Evaluation

+

There are some nodes that contain static data and are resources for operations. These can be evaluated at +conversion time so that you can use those values when doing node conversion. In theory any node kind can have +a conversion time evaluator as long as it produces a static IValue, This IValue will be stored in the conversion +context so it can be consumed by any node that takes the evaluated node as an input. Common node types are +prim::Constant which emits a constant and prim::ListConstruct which makes lists.

+
+
+

Node Converters

+

Node converters map JIT nodes to layers or subgraphs of layers. They then associate outputs from the JIT graph +and the TRT graph together in the conversion context. This allows the conversion stage to assemble the inputs +for the next node. There are some cases where a node produces an output that is not a Tensor but a static result +from a calculation done on inputs which need to be converted first. In this case the converter may associate the outputs in +the evaluated_value_map instead of the value_tensor_map. For more information take a look at: writing_converters

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/dynamo_converters.html b/docs/v2.2.0/contributors/dynamo_converters.html new file mode 100644 index 0000000000..fe3c566c98 --- /dev/null +++ b/docs/v2.2.0/contributors/dynamo_converters.html @@ -0,0 +1,880 @@ + + + + + + + + + + + + + Writing Dynamo Converters — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Writing Dynamo Converters
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Writing Dynamo Converters

+

The dynamo converter library in Torch-TensorRT is located in TensorRT/py/torch_tensorrt/dynamo/conversion.

+
+

Converter implementation

+
+

Registration

+

A converter is a function decrorated with torch_tensorrt.dynamo.dynamo_tensorrt_converter that follows the function signature:

+
@torch_tensorrt.dynamo.conversion.dynamo_tensorrt_converter(torch.ops.aten.leaky_relu.default)
+def leaky_relu_converter(
+    ctx: torch_tensorrt.dynamo.conversion.ConversionCtx,
+    target: Target,
+    args: Tuple[Argument, ...],
+    kwargs: Dict[str, Argument],
+    name: str,
+) -> Union[tensorrt.ITensor, Sequence[tensorrt.ITensor]]:
+
+
+

The decorator takes a number of arguments:

+
+
    +
  • key: Node target for which the converter is implemented for (for example, torch.ops.aten.leaky_relu.default)

  • +
  • enabled: Whether the converter should be enabled as a converter that can be used in the converter registry

  • +
  • capability_validator: A lambda that can take a torch.fx.Node and determine if the converter can properly handle this Node. If the validator returns False, the subgraph partitioner will make sure this Node is run in PyTorch in the compiled graph.

  • +
  • priority: Allows developers to override existing converters in the converter registry

  • +
+
+

All that is required for a converter is the key.

+

The function body is responsible for taking the current state of the network and adding the next subgraph to perform the op specified in the decorator with TensorRT operations. +The function is provided arguments as the native PyTorch op would be provided with the added case of numpy arrays for frozen Tensor attributes or TensorRT ITensors which are ouput Tensors of previous nodes, correspoding to edges/output Tensors of intermediate operations in the graph. +To determine the types expected as well as the return type of the converter, look at the definition of the op being converted. In the case of aten operations, this file will be the source of truth: https://github.com/pytorch/pytorch/blob/main/aten/src/ATen/native/native_functions.yaml +Since many converters a developer may write are a composition of lower level operators, instead of needing to implement the converter in raw TensorRT, the torch_tensorrt.dynamo.conversion.impl subpackage contains many implementations of operations that can be chained to create a TensorRT subgraph.

+
+
    +
  • ctx : The current state of the compiler. Converters primarily will manipulate ctx.net which is the tensorrt.INetworkDefinition being constructed. Additional metadata including user provided settings is available in this struct as well.

  • +
  • target: Target key in the call_module or call_function above. eg: torch.ops.aten_.leaky_relu.default. Note that torch.ops.aten._leaky_relu is the OpOverloadPacket while torch.ops.aten_.leaky_relu.default is OpOverload.

  • +
  • args: The arguments being passed to a particular Node (as collected by the torch_tensorrt.dynamo.conversion.TRTInterpreter). These arguments along with the kwargs are to be used to construct a specific TensorRT subgraph representing the current node in the INetworkDefinition.

  • +
  • kwargs: The arguments being passed to a particular Node (as collected by the torch_tensorrt.dynamo.conversion.TRTInterpreter).

  • +
  • name: String containing the name of the target

  • +
+
+

The function is expected to return the tensorrt.ITensor or some collection of tensorrt.ITensor for use in the torch_tensorrt.dynamo.conversion.TRTInterpreter matching the output signature of the operation being converted

+
+
+

Capability Validation

+

There are some converters which have special cases to be accounted for. In those cases, one should use capability_validators to register the converter using @dynamo_tensorrt_converter +We illustrate this through torch.ops.aten.embedding.default. It has parameters - scale_grad_by_freq and sparse which are not currently supported by the implementation. +In such cases we can write validator embedding_param_validator which implements that given those paramters the converter is not supported and register the converter by

+
+
+

Type Contract

+

The function is expected to follow the type contract established by the signature. This includes accepting the union of valid PyTorch types + numpy arrays for constant tensors and TensorRT ITensors. +In the case that only a subset of types is supported in the converter, you can also add the torch_tensorrt.dynamo.conversion.converter_utils.enforce_tensor_types, which allows you to specify a dictionary mapping between input positions and types that those inputs can take. Where possible the decorator will convert inputs to match these types prefering the order provided. +int keys in the dictionary will refer to positional arguments in args. str keys will refer to keyword arguments in kwargs.

+
+
+

Example: Convolution

+

The default convolution converter both uses a capability validator and type enforcement to prevent being run in unsupported situations. +The capability validator is run during partitioning to determine if a particular convolution node can be converted to TensorRT or needs to run in PyTorch. Here the validator ensures that the convolution is no greater than 3D. +The type enforcer will autocast before the converter is called, inputs to the supported type in the converter, thereby limiting the number of cases an author must handle.

+
@dynamo_tensorrt_converter(
+    torch.ops.aten.convolution.default, capability_validator=lambda conv_node: conv_node.args[7] in ([0], [0, 0], [0, 0, 0])
+)  # type: ignore[misc]
+@enforce_tensor_types(
+    {
+        0: (TRTTensor,),
+        1: (np.ndarray, torch.Tensor, TRTTensor),
+        2: (np.ndarray, torch.Tensor, TRTTensor),
+    }
+)  # type: ignore[misc]
+def aten_ops_convolution(
+    ctx: ConversionContext,
+    target: Target,
+    args: Tuple[Argument, ...],
+    kwargs: Dict[str, Argument],
+    name: str,
+) -> Union[TRTTensor, Sequence[TRTTensor]]:
+
+
+
+
+
+

Evaluators

+

Some operations do not produce TensorRT subgraphs as a side-effect. These are termed evaluators.

+
+

Example: operator.getitem

+

Evaluators are categorized as so since they do not make any modification to the graph. This is implemented in py/torch_tensorrt/dynamo/conversion/op_evaluators.py, with the corresponding capbility_validator. +The opcode is operator.getitem.

+
+
+
+

Operator Decomposition

+

There are some converters which can be decomposed into suboperations in PyTorch and need not have seperate converter registration. +Such converters can be implemented via a decomposition

+
+

Example: addmm

+

The decompositions are registered via register_torch_trt_decomposition decorator +We define addmm_replacement and replace it with the torch ops, which will have their corresponding converters called.

+
@torch_tensorrt.dynamo.lowering.register_torch_trt_decomposition(torch.ops.aten.addmm)
+def addmm_replacement(
+    input_: torch.Tensor, mat1: torch.Tensor, mat2: torch.Tensor, *, beta=1, alpha=1
+) -> torch.Tensor:
+    return torch.add(
+        torch.mul(input_, beta), torch.mul(torch.matmul(mat1, mat2), alpha)
+    )
+
+
+

You can modify the decompositions run by editing torch_tensorrt.dynamo.lowering.torch_enabled_decompositions and torch_tensorrt.dynamo.lowering.torch_disabled_decompositions

+
+

Note: torch_tensorrt.dynamo.lowering.torch_enabled_decompositions and torch_tensorrt.dynamo.lowering.torch_disabled_decompositions must be disjoint sets and that the decompositions already defined in torch_tensorrt.dynamo.lowering will take precedence over torch lowering ops.

+
+

Much of the time, this is significantly easier than implementing a converter. So where possible, this is what should be tried first.

+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/lowering.html b/docs/v2.2.0/contributors/lowering.html new file mode 100644 index 0000000000..e46fac6685 --- /dev/null +++ b/docs/v2.2.0/contributors/lowering.html @@ -0,0 +1,983 @@ + + + + + + + + + + + + + Lowering Phase — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Lowering Phase

+

The lowering phase is made up out of passes which are operations which map a graph from a high level representation +to a lower level one. Each pass does something specific for instance inlining method calls. The idea is to +significantly reduce what the conversion phase needs to be able to handle when actually mapping to TensorRT. +We aim for closer to 1->1 op conversion vs looking for applicable subgraphs, limiting the number of converters and +reduce the scope of each converter.

+

You can see the effects of each pass by setting the log level to Level::kGraph

+
+

Passes Used

+
+

EliminateCommonSubexpression

+
+
+

Removes common subexpressions in the graph

+
+
+

Eliminate Dead Code

+
+
+

Dead code elimination will check if a node has side effects and not delete it if it does.

+
+
+

Eliminate Exeception Or Pass Pattern

+
+
+

A common pattern in scripted modules are dimension gaurds which will throw execptions if +the input dimension is not what was expected.

+
%1013 : bool = aten::ne(%1012, %24) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/batchnorm.py:248:11
+    = prim::If(%1013) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/batchnorm.py:248:8
+    block0():
+        = prim::RaiseException(%23) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/batchnorm.py:249:12
+    -> ()
+    block1():
+    -> ()
+
+
+

Since we are resolving all of this at compile time and there are no execptions in the TensorRT graph, we just remove it.

+
+
+

Eliminate Redundant Gaurds

+
+
+

Eliminate redundant guards for ops whose outputs are fully determined by their inputs i.e. if inputs to such ops are +guarded we are allowed to remove a guard on ops’ outputs

+
+
+

Freeze Module

+
+
+

Freeze attributes and inline constants and modules. Propogates constants in the graph.

+
+
+

Fuse AddMM Branches

+
+
+

A common pattern in scripted modules is tensors of different dimensions use different constructions for implementing linear layers. We fuse these +different varients into a single one that will get caught by the Unpack AddMM pass.

+
%ret : Tensor = prim::If(%622)
+block0():
+  %ret.1 : Tensor = aten::addmm(%self.fc.bias, %x9.1, %3677, %3, %3)
+  -> (%ret.1)
+block1():
+  %output.1 : Tensor = aten::matmul(%x9.1, %3677)
+  %output0.1 : Tensor = aten::add_(%output.1, %self.fc.bias, %3)
+  -> (%output0.1)
+
+
+

We fuse this set of blocks into a graph like this:

+
%ret : Tensor = aten::addmm(%self.fc.bias, %x9.1, %3677, %3, %3)
+
+
+
+
+

Fuse Linear

+
+
+

Match the aten::linear pattern and fuse it into a single aten::linear +This pass fuse the addmm or matmul + add generated by JIT back to linear

+
+
+

Fuse Flatten Linear

+
+
+

TensorRT implicity flattens input layers into fully connected layers when they are higher than 1D. So when there is a +aten::flatten -> aten::linear pattern we remove the aten::flatten.

+
+
+

Lower Graph

+
+
+

Given a graph with of a method which first argument is %self, lower it to a graph where +all attributes accesses are replaced with explicit inputs of the graph +(rather than results of prim::GetAttr executed on %self). Returns a tuple +(graph, parameters) where the last module.parameters.size() inputs to the +graph are the trainable parameters used in this method. The remaining inputs +are the true inputs to the function.

+
+
+

Lower Tuples

+
+
+
    +
  • LowerSimpleTuples:

  • +
+

Removes tuples where TupleConstruct and TupleUnpack are matched but leaves tuples in place across if statements, loops, and as inputs/outputs

+
    +
  • LowerAllTuples:

  • +
+

Removes _all_ tuples and raises an error if some cannot be removed, this is used by ONNX to ensure there are not tuples before conversion, but will not work on graphs whose inputs contain tuples.

+
+
+

Module Fallback

+
+
+

Module fallback consists of two lowering passes that must be run as a pair. The first pass is run before freezing to place delimiters in the graph around modules +that should run in PyTorch. The second pass marks nodes between these delimiters after freezing to signify they should run in PyTorch.

+
    +
  • NotateModuleForFallback

  • +
+

Places delimiting nodes around module calls pre freezing to signify where in the graph nodes should run in PyTorch

+
    +
  • MarkNodesForFallback

  • +
+

Looks for delimiters then marks all nodes between the delimiters to tell partitioning to run them in PyTorch

+
+
+

Peephole Optimze

+
+
+

The intent for this optimization pass is to catch all of the small, easy to catch peephole optimizations you might be interested in doing.

+
+
Right now, it does:
    +
  • Eliminate no-op ‘expand’ nodes

  • +
  • Simply x.t().t() to x

  • +
+
+
+
+
+

Remove Contiguous

+
+
+

Removes contiguous operators since we are doing TensorRT memory is already contiguous.

+
+
+

Remove Dropout

+
+
+

Removes dropout operators since we are doing inference.

+
+
+

Remove To

+
+
+

Removes aten::to operators that do casting, since TensorRT mangages it itself. It is important that this is one of the last passes run so that +other passes have a change to move required cast operators out of the main namespace.

+
+
+

Unpack AddMM

+
+
+

Unpacks aten::addmm into aten::matmul and aten::add_ (with an additional trt::const +op to freeze the bias in the TensorRT graph). This lets us reuse the aten::matmul and aten::add_ +converters instead of needing a dedicated converter.

+
+
+

Unpack LogSoftmax

+
+
+

Unpacks aten::logsoftmax into aten::softmax and aten::log. This lets us reuse the +aten::softmax and aten::log converters instead of needing a dedicated converter.

+
+
+

Unroll Loops

+
+
+

Unrolls the operations of compatable loops (e.g. sufficently short) so that you only have to go through the loop once.

+
+
+

Replace Tile with Repeat

+
+
+

Removes dropout operators since we are doing inference.

+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/partitioning.html b/docs/v2.2.0/contributors/partitioning.html new file mode 100644 index 0000000000..d04e189107 --- /dev/null +++ b/docs/v2.2.0/contributors/partitioning.html @@ -0,0 +1,980 @@ + + + + + + + + + + + + + Partitioning Phase — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Partitioning Phase

+

The phase is optional and enabled by the user. It instructs the compiler to separate nodes into ones that should run in PyTorch and ones that should run in TensorRT. +Criteria for separation include: Lack of a converter, operator is explicitly set to run in PyTorch by the user or the node has a flag which tells partitioning to +run in PyTorch by the module fallback passes.

+

On a high level, Torch-TensorRT partitioning phase does the following:

+
    +
  • Segmentation. Go through the set of operators in order and verify if there is converter for each operator. Then, roughly separate the graph into parts that Torch-TensorRT can support and parts Torch-TensorRT cannot.

  • +
  • Dependency Analysis. For every to be compiled operator there is a “complete dependency graph”, which means that every input can to traced back to an input as Tensor or TensorList. Go through all segments after segmentation then do dependency analysis to ensure that there are only Tensor/TensorList inputs and outputs for TensorRT segments.

  • +
  • Shape Analysis. For each segments, figure out the input and outputs shapes starting from the provided input shape from the user. Shapes can be calculated by running the graphs with JIT.

  • +
  • Conversion. Every TensorRT segments will be converted to TensorRT engine. This part is done in compiler.cpp, but it’s still a phase in our partitioning process.

  • +
  • Stitching. Stitch all TensorRT engines with PyTorch nodes altogether.

  • +
+

Here are the brief description of these functions of each file:

+
+

PartitonInfo.h/.cpp

+
+
+

The automatic fallback APIs that is used for partitioning.

+
+
+

SegmentedBlock.h/.cpp

+
+
+

The main data structures that is used to maintain information for each segments after segmentation.

+
+
+

shape_analysis.h/.cpp

+
+
+

Code implementation to get the shapes for each segments by running them in JIT.

+
+
+

partitioning.h/.cpp

+
+
+

APIs and main code implementation for partitioning phase.

+
+
+
+

Automatic Fallback

+

To enable automatic fallback feature, you can set following attributes in Python:

+
import torch
+import torch_tensorrt as torchtrt
+
+...
+model = MyModel()
+ts_model = torch.jit.script(model)
+trt_model = torchtrt.ts.compile(model, **{
+  ...
+  "min_block_size" : 3,
+  "torch_executed_ops": ["aten::add"],
+  "torch_executed_modules": [],
+})
+
+
+
    +
  • enabled: By default automatic fallback will be off. It is enabled by setting it to True.

  • +
  • min_block_size: The minimum number of consecutive operations that must satisfy to be converted to TensorRT. For example, if it’s set to 3, then there must be 3 consecutive supported operators then this segments will be converted.

  • +
  • forced_fallback_ops: A list of strings that will be the names of operations that the user explicitly want to be in PyTorch nodes.

  • +
+
#include "torch/script.h"
+#include "torch_tensorrt/torch_tensorrt.h"
+
+...
+auto in = torch::randn({1, 3, 224, 224}, {torch::kCUDA});
+
+auto mod = torch::jit::load("trt_ts_module.ts");
+auto input_sizes =  std::vector<torchtrt::InputRange>{{in.sizes()}};
+torchtrt::ts::CompileSpec cfg(input_sizes);
+cfg.min_block_size = 2;
+cfg.torch_executed_ops.push_back("aten::relu");
+auto trt_mod = torchtrt::ts::compile(mod, cfg);
+auto out = trt_mod.forward({in});
+
+
+
+
+

Dependency Aware Partitioning

+

During segmentation, Torch-TensorRT uses a dependency graph of the input TorchScript nodes to reduce the number of segments created. Consider this example from test Partitioning.SegmentModelWithDependencyAwareness in tests/core/partitioning/test_segmentation.cpp

+
graph(%x : Tensor, %y : Tensor):
+    %3 : int = prim::Constant[value=0]()
+    %20 : int = prim::Constant[value=1]()
+    %add : Tensor = aten::add(%x, %y, %20)
+    %x_lgamma : Tensor = aten::lgamma(%x)
+    %mul : Tensor = aten::mul(%x, %y)
+    %y_lgamma : Tensor = aten::lgamma(%y)
+    %div : Tensor = aten::div(%x, %y)
+    %div_lgamma : Tensor = aten::lgamma(%div)
+    %27 : Tensor[] = prim::ListConstruct(%x_lgamma, %y_lgamma, %div_lgamma, %add, %mul)
+    %12 : Tensor = aten::cat(%27, %3)
+    return (%12)
+
+
+

In this graph aten::lgamma is not supported by conversion and must be partitioned in a Torch fallback segment. If Torch-TensorRT uses a greedy segmentation strategy that traverses nodes in the input graph in order and gathers ops with the same target (TensorRT or Torch) into a segment until it encounters an op with a different target, the resulting partition includes 7 segments, many with just a single op.

+
Segment Block @0:
+    Target: TensorRT
+
+    Graph: graph(%x : Tensor,
+        %y : Tensor):
+    %3 : int = prim::Constant[value=1]()
+    %0 : Tensor = aten::add(%x, %y, %3)
+    return ()
+
+Segment Block @1:
+    Target: Torch
+
+    Graph: graph(%x : Tensor):
+    %0 : Tensor = aten::lgamma(%x)
+    return ()
+
+Segment Block @2:
+    Target: TensorRT
+
+    Graph: graph(%x : Tensor,
+        %y : Tensor):
+    %0 : Tensor = aten::mul(%x, %y)
+    return ()
+
+Segment Block @3:
+    Target: Torch
+
+    Graph: graph(%y : Tensor):
+    %0 : Tensor = aten::lgamma(%y)
+    return ()
+
+Segment Block @4:
+    Target: TensorRT
+
+    Graph: graph(%x : Tensor,
+        %y : Tensor):
+    %0 : Tensor = aten::div(%x, %y)
+    return ()
+
+Segment Block @5:
+    Target: Torch
+
+    Graph: graph(%1 : Tensor):
+    %0 : Tensor = aten::lgamma(%1)
+    return ()
+
+Segment Block @6:
+    Target: TensorRT
+
+    Graph: graph(%1 : Tensor,
+        %2 : Tensor,
+        %3 : Tensor,
+        %4 : Tensor,
+        %5 : Tensor):
+    %7 : int = prim::Constant[value=0]()
+    %0 : Tensor[] = prim::ListConstruct(%1, %2, %3, %4, %5)
+    %6 : Tensor = aten::cat(%0, %7)
+    return ()
+
+
+

This partition is valid, but the segmentation is suboptimal. These arithmetic ops and aten::lgamma ops are each split into their own segment as we alternate between Torch and TensorRT targets in the linear traversal of the graph.

+
%add : Tensor = aten::add(%x, %y, %20)
+%x_lgamma : Tensor = aten::lgamma(%x)
+%mul : Tensor = aten::mul(%x, %y)
+%y_lgamma : Tensor = aten::lgamma(%y)
+%div : Tensor = aten::div(%x, %y)
+%div_lgamma : Tensor = aten::lgamma(%div)
+
+
+

Each of the arithmetic ops in this segment is only dependent on constants and the inputs %x and %y. The aten::lgamma ops are dependent on the inputs %x, %y and the output of the aten::div. This means that we could rewrite this portion of the input graph as below without changing the behavior of the graph. This reordered series of ops could be cleanly partitioned into just 2 segments using the greedy segmentation approach described above.

+
%add : Tensor = aten::add(%x, %y, %20)
+%mul : Tensor = aten::mul(%x, %y)
+%div : Tensor = aten::div(%x, %y)
+%x_lgamma : Tensor = aten::lgamma(%x)
+%y_lgamma : Tensor = aten::lgamma(%y)
+%div_lgamma : Tensor = aten::lgamma(%div)
+
+
+

By adding awareness of the dependencies between ops to the basic greedy segmentation approach we can achieve the same partition without rewriting the graph. Now we will maintain both Torch and TensorRT targeted segments at the same time as we traverse the graph. We will only finalize a segment once we hit an op that is both dependent on an op in the segment and has a different target. This will allow the partition to create larger segments by reordering nodes across the segment boundary while guaranteeing that we will not modify the behavior of the graph by reordering nodes relative to their dependencies. +In this example we will collect the arithmetic ops in a TensorRT segment and the aten::lgamma ops in a Torch segment. When we encounter the %div_lgamma : Tensor = aten::lgamma(%div) op we can see it is dependent on %div : Tensor = aten::div(%x, %y) in the current TensorRT segment. This triggers finalization of the TensorRT segment containing the aten::div op to guarantee it will appear before its dependency in the final partition. The Torch segment containing the aten::lgamma op is finalized when we encounter the prim::ListConstruct op which targets TensorRT and is dependent on the results of the aten::lgamma ops.

+
Segment Block @0:
+    Target: TensorRT
+
+    Graph: graph(%x : Tensor,
+        %y : Tensor):
+    %3 : int = prim::Constant[value=1]()
+    %0 : Tensor = aten::add(%x, %y, %3)
+    %4 : Tensor = aten::mul(%x, %y)
+    %5 : Tensor = aten::div(%x, %y)
+    return ()
+
+Segment Block @1:
+    Target: Torch
+
+    Graph: graph(%x : Tensor,
+        %y : Tensor,
+        %5 : Tensor):
+    %0 : Tensor = aten::lgamma(%x)
+    %2 : Tensor = aten::lgamma(%y)
+    %4 : Tensor = aten::lgamma(%5)
+    return ()
+
+Segment Block @2:
+    Target: TensorRT
+
+    Graph: graph(%1 : Tensor,
+        %2 : Tensor,
+        %3 : Tensor,
+        %4 : Tensor,
+        %5 : Tensor):
+    %7 : int = prim::Constant[value=0]()
+    %0 : Tensor[] = prim::ListConstruct(%1, %2, %3, %4, %5)
+    %6 : Tensor = aten::cat(%0, %7)
+    return ()
+
+
+

In some cases this approach may create adjacent segments in the partition which have the same target. As a clean-up step we can consolidate these adjacent segments to further reduce the number of segments in the final partition. +The merge segments step identifies a list of segments that are adjacent in the graph, have the same target, and are not marked as do_not_merge. The nodes from these segments will be combined into a single new segment that will replace the merged segments in the partition. +The do_not_merge marking is used to prevent merging of segments created for conditional nodes and loops that are handled as special cases in graph stitching and should not be merged with adjacent segments of the same type.

+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/phases.html b/docs/v2.2.0/contributors/phases.html new file mode 100644 index 0000000000..3339c6a8eb --- /dev/null +++ b/docs/v2.2.0/contributors/phases.html @@ -0,0 +1,781 @@ + + + + + + + + + + + + + Compiler Phases — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Compiler Phases

+
+
+
+

Lowering

+

Lowering Phase

+

The lowering is made up of a set of passes (some from PyTorch and some specific to Torch-TensorRT) +run over the graph IR to map the large PyTorch opset to a reduced opset that is easier to convert to +TensorRT.

+
+
+

Partitioning

+

Partitioning Phase

+

The phase is optional and enabled by the user. It instructs the compiler to separate nodes into ones that should run in PyTorch and ones that should run in TensorRT. +Criteria for separation include: Lack of a converter, operator is explicitly set to run in PyTorch by the user or the node has a flag which tells partitioning to +run in PyTorch by the module fallback passes.

+
+
+

Conversion

+

Conversion Phase

+

In the conversion phase we traverse the lowered graph and construct an equivalent TensorRT graph. +The conversion phase is made up of three main components, a context to manage compile time data, +a evaluator library which will execute operations that can be resolved at compile time and a converter +library which maps an op from JIT to TensorRT.

+
+
+

Compilation and Runtime

+

Deploying Torch-TensorRT Programs

+

The final compilation phase constructs a TorchScript program to run the converted TensorRT engine. It +takes a serialized engine and instantiates it within a engine manager, then the compiler will +build out a JIT graph that references this engine and wraps it in a module to return to the user. +When the user executes the module, the JIT program run in the JIT runtime extended by Torch-TensorRT with the data providied from the user.

+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/runtime.html b/docs/v2.2.0/contributors/runtime.html new file mode 100644 index 0000000000..006eeca482 --- /dev/null +++ b/docs/v2.2.0/contributors/runtime.html @@ -0,0 +1,833 @@ + + + + + + + + + + + + + Runtime Phase — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Runtime Phase

+

The Runtime phase is responsible for constructing self standing TorchScript graphs with embedded TensorRT engines and serving as the runtime +when these engines are called. The main interface accepts a serialized TensorRT engine. The execution phase +will deserialize and wrap this engine in a class which maintains a execution context for each engine +and some metadata about its inputs and outputs and is compatable with the TorchScript interpreter so that +it can be moved around and used like other TorchScript IValues. The engine is run by providing it and inputs +to the tensorrt::execute_engine operator which will take the engine and its inputs and return the results of engine exeuction.

+
+

Background

+

PyTorch JIT’s runtime is based around a stack machine, all operators pop off arguments from the stack, pass them to +some implementation of the operator then push results back onto the stack. The actual elements of the stack +are torch::jit::IValues, the same type we evaluate in the conversion phase (the realization of the abstract +torch::jit::Value type).

+
+
+

TensorRT Engine Executor Op

+

When the Torch-TensorRT is loaded, it registers an operator in the PyTorch JIT operator library called +trt::execute_engine(Tensor[] inputs, __torch__.torch.classes.tensorrt.Engine engine) -> Tensor[] which takes an +instantiated engine and list of inputs. Compiled graphs store this engine in an attribute so that it is portable and serializable. +When the op is called, an instnantiated engine and input tensors are popped off the runtime stack. These inputs are passed into a generic engine execution function which +will run the tensors through the TensorRT engine and return new tensors as results. These tensors are pushed on to the +stack so that the next op whatever it is can use it.

+
+
+

Constructing the Resulting Graph

+

Once the engine is deserialized and instantiated, the compiler will construct a graph that will execute the engine when the module is called. +Here is an example:

+
graph(%self_1 : __torch__.torchvision.models.resnet.___torch_mangle_4847.ResNet_trt,
+  %input_0 : Tensor):
+    %1 : __torch__.torch.classes.tensorrt.Engine = prim::GetAttr[name="__torch___torchvision_models_resnet____torch_mangle_4847_ResNet_trt_engine"](%self_1)
+    %3 : Tensor[] = prim::ListConstruct(%input_0)
+    %4 : Tensor[] = trt::execute_engine(%3, %1)
+    %5 : Tensor = prim::ListUnpack(%4)
+return (%5)
+
+
+

You can see the engine attribute in the graph and the trt::execute_engine op taking a list of input tensors and an engine in +and produces a list of output tensors which is returned. When forward is called on the module this graph is executed, thereby +running the TensorRT engine.

+

In the case of multiple outputs, the compiled graph may repack output tensors into a Tuple to return back to the user.

+
graph(%self_1 : __torch__.PyTorch.Detection.SSD.src.model.SSD300_trt,
+  %input_0 : Tensor):
+    %1 : __torch__.torch.classes.tensorrt.Engine = prim::GetAttr[name="__torch___PyTorch_Detection_SSD_src_model_SSD300_trt_engine"](%self_1)
+    %3 : Tensor[] = prim::ListConstruct(%input_0)
+    %4 : Tensor[] = trt::execute_engine(%3, %1)
+    %5 : Tensor, %6 : Tensor = prim::ListUnpack(%4)
+    %7 : (Tensor, Tensor) = prim::TupleConstruct(%5, %6)
+return (%7)
+
+
+
+
+

Serialization and Deserialization

+

Serialization and deserialization of TensorRT engines embedded in TorchScript graphs are handled by the holder class for the engine and TorchBind. +When a TorchScript module is saved, the pickler will run serilization on the cuda engine and store the serialized engine in the zip file created. +When deserializing, the depickler will call a constructor for the engine holder class with the serialized engine so that it can be set up again for +execution.

+
+
+
+

ABI Versioning and Serialization Format

+

Torch-TensorRT programs are standard TorchScript with TensorRT engines as objects embedded in the graph. Therefore there is a serialization format +for the TensorRT engines. The format for Torch-TensorRT serialized programs are versioned with an “ABI” version which tells the runtime about runtime compatibility.

+

> Current ABI version is 3

+

The format is a vector of serialized strings. They encode the following information

+
    +
  • ABI Version for the program

  • +
  • Name of the TRT engine

  • +
  • Device information: Includes the target device the engine was built on, SM capability and other device information. This information is used at deserialization time to select the correct device to run the engine

  • +
  • Serialized TensorRT engine

  • +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/system_overview.html b/docs/v2.2.0/contributors/system_overview.html new file mode 100644 index 0000000000..306d942da0 --- /dev/null +++ b/docs/v2.2.0/contributors/system_overview.html @@ -0,0 +1,817 @@ + + + + + + + + + + + + + System Overview — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

System Overview

+

Torch-TensorRT is primarily a C++ Library with a Python API planned. We use Bazel as our build system and target Linux x86_64 and +Linux aarch64 (only natively) right now. The compiler we use is GCC 7.5.0 and the library is untested with compilers before that +version so there may be compilation errors if you try to use an older compiler.

+

The repository is structured into:

+
    +
  • core: Main compiler source code

  • +
  • cpp: C++ API

  • +
  • tests: tests of the C++ API, the core and converters

  • +
  • py: Python API

  • +
  • notebooks: Example applications built with Torch-TensorRT

  • +
  • docs: Documentation

  • +
  • docsrc: Documentation Source

  • +
  • third_party: BUILD files for dependency libraries

  • +
  • toolchains: Toolchains for different platforms

  • +
+

The C++ API is unstable and subject to change until the library matures, though most work is done under the hood in the core.

+

The core has a couple major parts: The top level compiler interface which coordinates ingesting a module, lowering, +converting and generating a new module and returning it back to the user. There are the three main phases of the +compiler, the lowering phase, the conversion phase, and the execution phase.

+
+

Compiler Phases

+
+
+
+

Lowering

+

Lowering Phase

+

The lowering is made up of a set of passes (some from PyTorch and some specific to Torch-TensorRT) +run over the graph IR to map the large PyTorch opset to a reduced opset that is easier to convert to +TensorRT.

+
+
+

Partitioning

+

Partitioning Phase

+

The phase is optional and enabled by the user. It instructs the compiler to separate nodes into ones that should run in PyTorch and ones that should run in TensorRT. +Criteria for separation include: Lack of a converter, operator is explicitly set to run in PyTorch by the user or the node has a flag which tells partitioning to +run in PyTorch by the module fallback passes.

+
+
+

Conversion

+

Conversion Phase

+

In the conversion phase we traverse the lowered graph and construct an equivalent TensorRT graph. +The conversion phase is made up of three main components, a context to manage compile time data, +a evaluator library which will execute operations that can be resolved at compile time and a converter +library which maps an op from JIT to TensorRT.

+
+
+

Compilation and Runtime

+

Deploying Torch-TensorRT Programs

+

The final compilation phase constructs a TorchScript program to run the converted TensorRT engine. It +takes a serialized engine and instantiates it within a engine manager, then the compiler will +build out a JIT graph that references this engine and wraps it in a module to return to the user. +When the user executes the module, the JIT program run in the JIT runtime extended by Torch-TensorRT with the data providied from the user.

+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/ts_converters.html b/docs/v2.2.0/contributors/ts_converters.html new file mode 100644 index 0000000000..9427181605 --- /dev/null +++ b/docs/v2.2.0/contributors/ts_converters.html @@ -0,0 +1,888 @@ + + + + + + + + + + + + + Writing TorchScript Converters — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Writing TorchScript Converters
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Writing TorchScript Converters

+
+

Background

+

In the JIT IR, operations are represented as nodes in a graph. A node has inputs and outputs, represented by torch::jit::Values +which are typed abstract representation of data flowing into and out of a node. TensorRT represents its graph though the +use of nvinfer1::ILayers and nvinfer1::ITensors which are its analogues to nodes and values. The goal of +converters create new ILayers and subgraphs that do operation specified by the node and associate produced ITensors +and Values together.

+
+
+

Converters

+

Converters should be functions which will use a list of inputs (either nvinfer1::ITensors or torch::jit::IValues) to +construct an equivalent layer to the LibTorch op.

+

Converters can be registered using the RegisterNodeConversionPatterns helper class where you instantiate a +RegisterNodeConversionPatterns object and call the pattern function on it (like below) which takes a string +which describes the function schema of the op that will cause the converter to be run and a lambda or function +which will do the actual conversion:

+
+

Note the pattern function can be chained

+
+
auto acthardtanh TORCHTRT_UNUSED = RegisterNodeConversionPatterns()
+    .pattern({
+        "aten::hardtanh(Tensor self, Scalar min_val=-1, Scalar max_val=1) -> (Tensor)",
+        [](ConversionCtx* ctx, const torch::jit::Node* n, args& args) -> bool {
+            auto in = args[0].ITensor();
+            auto min = args[1].unwrapToDouble();
+            auto max = args[2].unwrapToDouble();
+
+            auto new_layer = ctx->net->addActivation(*in, nvinfer1::ActivationType::kCLIP);
+            TORCHTRT_CHECK(new_layer, "Unable to create layer for aten::hardtanh");
+
+            new_layer->setAlpha(min);
+            new_layer->setBeta(max);
+
+            new_layer->setName(util::node_info(n).c_str());
+            auto out_tensor = ctx->AssociateValueAndTensor(n->outputs()[0], new_layer->getOutput(0));
+
+            LOG_DEBUG("Output shape: " << out_tensor->getDimensions());
+            return true;
+        }
+    });
+
+
+
+
+

Converter Contract

+
+

What is guaranteed to converters

+
    +
  1. In the args there will be an entry for each node input value, either a ITensor or IValue

  2. +
  3. Inputs will be provided in order according to the function schema

  4. +
+
+
+

Responsibilities of a converter

+
    +
  1. Args must be guaranteed to be a type to unwrap the Arg union without checking, typically input tensor arguments can be expected to be ITensors

  2. +
  3. Any weights or static values must guaranteed to be valid until the end of conversion time

    +
      +
    1. A helpful tool is the Weights helper class described below

    2. +
    +
  4. +
  5. Converters are expected to produce an IValue or ITensor for each output of a node. The compiler will check this and produce warnings if there are Values that don’t have associated ITensors or IValues.

  6. +
  7. Outputs must be annotated

    +
      +
    1. There must be an association between a JIT nodes output values and the new TRT layers output tensors in the value_tensor_map in the conversion context

    2. +
    +
  8. +
  9. Name your layers

    +
      +
    1. Its much easier to debug when we can track which layers and nodes correspond with each other. The system we are currently using is to use the “node info” of the node as the name of the layer

    2. +
    +
  10. +
  11. Name your tensors

    +
      +
    1. Use the output value debug name as the name for the new ITensor (again for debugging)

    2. +
    +
  12. +
+
+
+
+

Conversion Context

+

The conversion context maintains the state of conversion, it manages the Network Definition, two maps +one that stores associations between Values and IValues (the evaluated_value_map) and one that stores +associations between Values and ITensors, and any sort of memory that needs to live until the end of +conversion. The main apis that you will interface with in converters is directly accessing the network +definition to add layers ctx->net and data association functions ctx->AssociateValueAndTensor() +and ctx->AssociateValueAndIValue(), which you will use to add layers to the TRT layers and log +pairs of node outputs and static values or TensorRT layer outputs.

+
+
+

Args

+

Arguments provided to the converter are inspectable unions of nvinfer1::ITensors and torch::jit::IValues (i.e. +abstract dataflow in the TensorRT graph and static values). You are guaranteed that you will have some +argument for each input value for the node. They are provided in the order of the function schema. +It can be expected that inputs (meaning the parameters that would be passed into the forward +function of a module in PyTorch) will be ITensors but the Arg class also has mechanisms to inspect arguments safely +before unwrapping if you are unsure. Args also have deep unwrap methods that let you get straight to the +underlying data in an IValue if you know it’s safe. You can also pass in a fallback value if there is a +chance the IValue is None. IValues have been extended to be able to hold a wrapper around ITensors only in the case of TensorLists. +You can get an ITensor from an IValue by a pattern similar to this: ivalue.toCustomClass<TensorContainer>()->tensor(). +You can tell if an IValue contains a Tensor or an ITensor by using ivalue.isTensor() or ivalue.isCustomClass().

+
+
+

Weights

+

Weights are used during build time, so any weights need to be guaranteed to live until the end of the conversion phase. +TensorRT also uses its own weights structure to hold the weights. There is a wrapper around this class available +to converts which abstracts a lot of this.

+

The weights wrapper class can accept either at::Tensors or singular values (right now). You also need to pass the +conversion context when constructing these weights because internally the weights class will allocate memory managed +by the conversion context to store a copy of the tensor data. This data gets freed when the conversion context +destructor gets destroyed so converters don’t really need to think about it.

+

There is metadata generated from the shape of the input data which becomes useful in interfacing with TensorRT, such +as number of input maps, number of output maps and kernel shape.

+
+
+

Other advice

+

You have the benefit of the full aten library when dealing with weights and other static values. This means that you +can do quite a bit of work during conversion time to produce efficient conversion. A good example is batch_norm +converter where the converter does fusion of operations with PyTorch before creating the TensorRT layer.

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/useful_links.html b/docs/v2.2.0/contributors/useful_links.html new file mode 100644 index 0000000000..a3cc2d3206 --- /dev/null +++ b/docs/v2.2.0/contributors/useful_links.html @@ -0,0 +1,798 @@ + + + + + + + + + + + + + Useful Links for Torch-TensorRT Development — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Useful Links for Torch-TensorRT Development
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ + + + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/contributors/writing_dynamo_aten_lowering_passes.html b/docs/v2.2.0/contributors/writing_dynamo_aten_lowering_passes.html new file mode 100644 index 0000000000..42265db744 --- /dev/null +++ b/docs/v2.2.0/contributors/writing_dynamo_aten_lowering_passes.html @@ -0,0 +1,852 @@ + + + + + + + + + + + + + Writing Dynamo ATen Lowering Passes — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Writing Dynamo ATen Lowering Passes
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Writing Dynamo ATen Lowering Passes

+
+

Basics of a Lowering Pass

+

ATen lowering passes are Python functions which take as input a graph of ATen operators, apply some desired modification such as operator coalescing/fusion, operator replacement, subgraph rewriting, custom operator insertion, or other operation on a torch.fx.GraphModule, then return the modified graph to the caller. These lowering passes generally modify the graph in-place and return the same input object.

+
+
+

Lowering Pass Requirements

+

An ATen lowering pass function in Torch-TRT must satisfy two requirements: +- The function must take as input a torch.fx.GraphModule and a sequence of torch Tensors, Sequence[torch.Tensor], and return the lowered torch.fx.GraphModule +- The function must leave the graph in a valid and invoke-able state, including performing any necessary linting and recompilation

+

See this link for information on Graph Manipulations in FX. See below for an example of a lowering pass which repairs graphs that have inputs which are also outputs, a disallowed configuration for TRT Engines.

+
+
+

Example Lowering Pass

+
def repair_input_as_output(gm: torch.fx.GraphModule, sample_inputs: Sequence[torch.Tensor]) -> torch.fx.GraphModule:
+    """Repair scenarios where inputs are also outputs of the graph
+
+    TRT does not allow such cases, so we insert a clone (identity) layer
+    """
+    modified_graph = False
+
+    # Extract graph placeholder Tensors
+    placeholders = [
+        node
+        for node in gm.graph.nodes
+        if (
+            node.op == "placeholder"
+            and isinstance(node.type, type)
+            and issubclass(node.type, torch.Tensor)
+        )
+    ]
+
+    for placeholder in placeholders:
+        # If any placeholder has any users which are direct graph outputs
+        if len(placeholder.users) >= 1 and any(
+            user.op == "output" for user in placeholder.users
+        ):
+            modified_graph = True
+
+            # Get direct graph outputs which are direct uses of placeholders
+            direct_outputs = [user for user in placeholder.users if user.op == "output"]
+
+            # Insert clone node for placeholder to ensure
+            # placeholder is not a direct output
+            with gm.graph.inserting_after(placeholder):
+                cloned_placeholder = gm.graph.call_function(
+                    torch.ops.aten.clone.default,
+                    args=(placeholder,),
+                )
+
+            # Replace placeholder as output with cloned version
+            for output in direct_outputs:
+                output.replace_input_with(placeholder, cloned_placeholder)
+
+    # If the graph was modified, clean up the graph and ensure it is up-to-date
+    if modified_graph:
+        gm.graph.eliminate_dead_code()
+        gm.graph.lint()
+        gm.recompile()
+        logger.debug(f"Graph after repair_input_as_output:\n{gm.graph}")
+
+    return gm
+
+
+
+
+

Registering Lowering Passes

+

Lowering passes are currently registered in py/torch_tensorrt/dynamo/lowering/passes/__init__.py, using the torch.fx.passes.pass_manager.PassManager utility to assemble the list of passes in a desired order. New passes added directly to that list will be applied to graphs in the Torch-TensorRT torch.compile backend. Currently, we offer an ATen lowering pass registration decorator for convenience, which can be invoked either directly, or with the optional index keyword argument which controls where in the pass list the lowering pass will be inserted.

+

For instance, to insert the pass at the default location (end of the list), the following code can be used:

+
@_aten_lowering_pass
+def my_custom_pass(gm: torch.fx.GraphModule, sample_inputs: Sequence[torch.Tensor]) -> torch.fx.GraphModule:
+    ...
+
+
+

Alternatively, to insert the pass at a custom index (such as the front of the list) in the passlist, the following code can be used:

+
@_aten_lowering_pass(index=0)
+def my_custom_pass(gm: torch.fx.GraphModule, sample_inputs: Sequence[torch.Tensor]) -> torch.fx.GraphModule:
+    ...
+
+
+

There are also provided utilities in torch_tensorrt.dynamo.lowering.passes for displaying the currently-available lowering pass list, applying those passes to an arbitrary torch.fx.GraphModule, and removing the lowering pass at a specific index.

+
# Print all lowering passes in the list
+print(dump_lowering_passes())
+
+# Apply lowering passes to a GraphModule
+apply_lowering_passes(graph_module, sample_inputs)
+
+# Remove the lowering pass at index 1
+_remove_lowering_pass(index=1)
+
+
+

Note: The above APIs are subject to change, as the lowering pass system evolves.

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/dynamo/dynamo_export.html b/docs/v2.2.0/dynamo/dynamo_export.html new file mode 100644 index 0000000000..70d4b0ad20 --- /dev/null +++ b/docs/v2.2.0/dynamo/dynamo_export.html @@ -0,0 +1,823 @@ + + + + + + + + + + + + + Compiling Exported Programs with Torch-TensorRT — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Compiling Exported Programs with Torch-TensorRT
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Compiling Exported Programs with Torch-TensorRT

+

Pytorch 2.1 introduced torch.export APIs which +can export graphs from Pytorch programs into ExportedProgram objects. Torch-TensorRT dynamo +frontend compiles these ExportedProgram objects and optimizes them using TensorRT. Here’s a simple +usage of the dynamo frontend

+
import torch
+import torch_tensorrt
+
+model = MyModel().eval().cuda()
+inputs = [torch.randn((1, 3, 224, 224), dtype=torch.float32).cuda()]
+exp_program = torch.export.export(model, tuple(inputs))
+trt_gm = torch_tensorrt.dynamo.compile(exp_program, inputs) # Output is a torch.fx.GraphModule
+trt_gm(*inputs)
+
+
+
+

Note

+

torch_tensorrt.dynamo.compile is the main API for users to interact with Torch-TensorRT dynamo frontend. The input type of the model should be ExportedProgram (ideally the output of torch.export.export or torch_tensorrt.dynamo.trace (discussed in the section below)) and output type is a torch.fx.GraphModule object.

+
+
+

Customizeable Settings

+

There are lot of options for users to customize their settings for optimizing with TensorRT. +Some of the frequently used options are as follows:

+
    +
  • inputs - For static shapes, this can be a list of torch tensors or torch_tensorrt.Input objects. For dynamic shapes, this should be a list of torch_tensorrt.Input objects.

  • +
  • enabled_precisions - Set of precisions that TensorRT builder can use during optimization.

  • +
  • truncate_long_and_double - Truncates long and double values to int and floats respectively.

  • +
  • torch_executed_ops - Operators which are forced to be executed by Torch.

  • +
  • min_block_size - Minimum number of consecutive operators required to be executed as a TensorRT segment.

  • +
+

The complete list of options can be found here

+
+

Note

+

We do not support INT precision currently in Dynamo. Support for this currently exists in our Torchscript IR. We plan to implement similar support for dynamo in our next release.

+
+
+
+

Under the hood

+

Under the hood, torch_tensorrt.dynamo.compile performs the following on the graph.

+
    +
  • Lowering - Applies lowering passes to add/remove operators for optimal conversion.

  • +
  • Partitioning - Partitions the graph into Pytorch and TensorRT segments based on the min_block_size and torch_executed_ops field.

  • +
  • Conversion - Pytorch ops get converted into TensorRT ops in this phase.

  • +
  • Optimization - Post conversion, we build the TensorRT engine and embed this inside the pytorch graph.

  • +
+
+
+

Tracing

+

torch_tensorrt.dynamo.trace can be used to trace a Pytorch graphs and produce ExportedProgram. +This internally performs some decompositions of operators for downstream optimization. +The ExportedProgram can then be used with torch_tensorrt.dynamo.compile API. +If you have dynamic input shapes in your model, you can use this torch_tensorrt.dynamo.trace to export +the model with dynamic shapes. Alternatively, you can use torch.export with constraints directly as well.

+
import torch
+import torch_tensorrt
+
+inputs = [torch_tensorrt.Input(min_shape=(1, 3, 224, 224),
+                              opt_shape=(4, 3, 224, 224),
+                              max_shape=(8, 3, 224, 224),
+                              dtype=torch.float32)]
+model = MyModel().eval()
+exp_program = torch_tensorrt.dynamo.trace(model, inputs)
+
+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/dynamo/torch_compile.html b/docs/v2.2.0/dynamo/torch_compile.html new file mode 100644 index 0000000000..69bec63358 --- /dev/null +++ b/docs/v2.2.0/dynamo/torch_compile.html @@ -0,0 +1,903 @@ + + + + + + + + + + + + + TensorRT Backend for torch.compile — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • TensorRT Backend for torch.compile
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

TensorRT Backend for torch.compile

+

This guide presents the Torch-TensorRT torch.compile backend: a deep learning compiler which uses TensorRT to accelerate JIT-style workflows across a wide variety of models.

+
+

Key Features

+

The primary goal of the Torch-TensorRT torch.compile backend is to enable Just-In-Time compilation workflows by combining the simplicity of torch.compile API with the performance of TensorRT. Invoking the torch.compile backend is as simple as importing the torch_tensorrt package and specifying the backend:

+
import torch_tensorrt
+...
+optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False)
+
+
+
+

Note

+

Many additional customization options are available to the user. These will be discussed in further depth in this guide.

+
+

The backend can handle a variety of challenging model structures and offers a simple-to-use interface for effective acceleration of models. Additionally, it has many customization options to ensure the compilation process is fitting to the specific use case.

+
+
+

Customizeable Settings

+
+
+class torch_tensorrt.dynamo.CompilationSettings(precision: ~torch.dtype = torch.float32, debug: bool = False, workspace_size: int = 0, min_block_size: int = 5, torch_executed_ops: ~typing.Collection[~typing.Union[~typing.Callable[[...], ~typing.Any], str]] = <factory>, pass_through_build_failures: bool = False, max_aux_streams: ~typing.Optional[int] = None, version_compatible: bool = False, optimization_level: ~typing.Optional[int] = None, use_python_runtime: ~typing.Optional[bool] = False, truncate_long_and_double: bool = False, use_fast_partitioner: bool = True, enable_experimental_decompositions: bool = False, device: ~torch_tensorrt._Device.Device = <factory>, require_full_compilation: bool = False, disable_tf32: bool = False, sparse_weights: bool = False, refit: bool = False, engine_capability: ~tensorrt_bindings.tensorrt.EngineCapability = <EngineCapability.DEFAULT: 0>, num_avg_timing_iters: int = 1, dla_sram_size: int = 1048576, dla_local_dram_size: int = 1073741824, dla_global_dram_size: int = 536870912, output_format: str = 'exported_program')[source]
+

Compilation settings for Torch-TensorRT Dynamo Paths

+
+
Parameters
+
    +
  • precision (torch.dpython:type) – Model Layer precision

  • +
  • debug (bool) – Whether to print out verbose debugging information

  • +
  • workspace_size (python:int) – Workspace TRT is allowed to use for the module (0 is default)

  • +
  • min_block_size (python:int) – Minimum number of operators per TRT-Engine Block

  • +
  • torch_executed_ops (Collection[Target]) – Collection of operations to run in Torch, regardless of converter coverage

  • +
  • pass_through_build_failures (bool) – Whether to fail on TRT engine build errors (True) or not (False)

  • +
  • max_aux_streams (Optional[python:int]) – Maximum number of allowed auxiliary TRT streams for each engine

  • +
  • version_compatible (bool) – Provide version forward-compatibility for engine plan files

  • +
  • optimization_level (Optional[python:int]) – Builder optimization 0-5, higher levels imply longer build time, +searching for more optimization options. TRT defaults to 3

  • +
  • use_python_runtime (Optional[bool]) – Whether to strictly use Python runtime or C++ runtime. To auto-select a runtime +based on C++ dependency presence (preferentially choosing C++ runtime if available), leave the +argument as None

  • +
  • truncate_long_and_double (bool) – Whether to truncate int64/float64 TRT engine inputs or weights to int32/float32

  • +
  • use_fast_partitioner (bool) – Whether to use the fast or global graph partitioning system

  • +
  • enable_experimental_decompositions (bool) – Whether to enable all core aten decompositions +or only a selected subset of them

  • +
  • device (Device) – GPU to compile the model on

  • +
  • require_full_compilation (bool) – Whether to require the graph is fully compiled in TensorRT. +Only applicable for ir=”dynamo”; has no effect for torch.compile path

  • +
  • disable_tf32 (bool) – Whether to disable TF32 computation for TRT layers

  • +
  • sparse_weights (bool) – Whether to allow the builder to use sparse weights

  • +
  • refit (bool) – Whether to build a refittable engine

  • +
  • engine_capability (trt.EngineCapability) – Restrict kernel selection to safe gpu kernels or safe dla kernels

  • +
  • num_avg_timing_iters (python:int) – Number of averaging timing iterations used to select kernels

  • +
  • dla_sram_size (python:int) – Fast software managed RAM used by DLA to communicate within a layer.

  • +
  • dla_local_dram_size (python:int) – Host RAM used by DLA to share intermediate tensor data across operations

  • +
  • dla_global_dram_size (python:int) – Host RAM used by DLA to store weights and metadata for execution

  • +
  • output_format (str) – Output format of the result of TRT compilation. Options include “exported_program” (or) “ep” | “torchscript” (or) “ts” | “graph_module” (or) “fx”. Default is “exported_program”

  • +
+
+
+
+ +
+

Custom Setting Usage

+
import torch_tensorrt
+...
+optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False,
+                                options={"truncate_long_and_double": True,
+                                         "precision": torch.half,
+                                         "debug": True,
+                                         "min_block_size": 2,
+                                         "torch_executed_ops": {"torch.ops.aten.sub.Tensor"},
+                                         "optimization_level": 4,
+                                         "use_python_runtime": False,})
+
+
+
+

Note

+

Quantization/INT8 support is slated for a future release; currently, we support FP16 and FP32 precision layers.

+
+
+
+
+

Compilation

+

Compilation is triggered by passing inputs to the model, as so:

+
import torch_tensorrt
+...
+# Causes model compilation to occur
+first_outputs = optimized_model(*inputs)
+
+# Subsequent inference runs with the same, or similar inputs will not cause recompilation
+# For a full discussion of this, see "Recompilation Conditions" below
+second_outputs = optimized_model(*inputs)
+
+
+
+
+

After Compilation

+

The compilation object can be used for inference within the Python session, and will recompile according to the recompilation conditions detailed below. In addition to general inference, the compilation process can be a helpful tool in determining model performance, current operator coverage, and feasibility of serialization. Each of these points will be covered in detail below.

+
+

Model Performance

+

The optimized model returned from torch.compile is useful for model benchmarking since it can automatically handle changes in the compilation context, or differing inputs that could require recompilation. When benchmarking inputs of varying distributions, batch sizes, or other criteria, this can save time.

+
+
+

Operator Coverage

+

Compilation is also a useful tool in determining operator coverage for a particular model. For instance, the following compilation command will display the operator coverage for each graph, but will not compile the model - effectively providing a “dryrun” mechanism:

+
import torch_tensorrt
+...
+optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False,
+                                options={"debug": True,
+                                         "min_block_size": float("inf"),})
+
+
+

If key operators for your model are unsupported, see dynamo_conversion to contribute your own converters, or file an issue here: https://github.com/pytorch/TensorRT/issues.

+
+
+

Feasibility of Serialization

+

Compilation can also be helpful in demonstrating graph breaks and the feasibility of serialization of a particular model. For instance, if a model has no graph breaks and compiles successfully with the Torch-TensorRT backend, then that model should be compileable and serializeable via the torch_tensorrt Dynamo IR, as discussed in Dynamic shapes with Torch-TensorRT. To determine the number of graph breaks in a model, the torch._dynamo.explain function is very useful:

+
import torch
+import torch_tensorrt
+...
+explanation = torch._dynamo.explain(model)(*inputs)
+print(f"Graph breaks: {explanation.graph_break_count}")
+optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False, options={"truncate_long_and_double": True})
+
+
+
+
+
+

Dynamic Shape Support

+

The Torch-TensorRT torch.compile backend will currently require recompilation for each new batch size encountered, and it is preferred to use the dynamic=False argument when compiling with this backend. Full dynamic shape support is planned for a future release.

+
+
+

Recompilation Conditions

+

Once the model has been compiled, subsequent inference inputs with the same shape and data type, which traverse the graph in the same way will not require recompilation. Furthermore, each new recompilation will be cached for the duration of the Python session. For instance, if inputs of batch size 4 and 8 are provided to the model, causing two recompilations, no further recompilation would be necessary for future inputs with those batch sizes during inference within the same session. Support for engine cache serialization is planned for a future release.

+

Recompilation is generally triggered by one of two events: encountering inputs of different sizes or inputs which traverse the model code differently. The latter scenario can occur when the model code includes conditional logic, complex loops, or data-dependent-shapes. torch.compile handles guarding in both of these scenario and determines when recompilation is necessary.

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/fx/getting_started_with_fx_path.html b/docs/v2.2.0/fx/getting_started_with_fx_path.html new file mode 100644 index 0000000000..9d3c01ed74 --- /dev/null +++ b/docs/v2.2.0/fx/getting_started_with_fx_path.html @@ -0,0 +1,1058 @@ + + + + + + + + + + + + + Torch-TensorRT (FX Frontend) User Guide — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Torch-TensorRT (FX Frontend) User Guide
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Torch-TensorRT (FX Frontend) User Guide

+

Torch-TensorRT (FX Frontend) is a tool that can convert a PyTorch model through torch.fx to an +TensorRT engine optimized targeting running on Nvidia GPUs. TensorRT is the inference engine +developed by NVIDIA which composed of various kinds of optimization including kernel fusion, +graph optimization, low precision, etc.. This tool is developed in Python environment which allows this +workflow to be very accessible to researchers and engineers. There are a few stages that a +user want to use this tool and we will introduce them here.

+

> Torch-TensorRT (FX Frontend) is in Beta and currently it is recommended to work with PyTorch nightly.

+
# Test an example by
+$ python py/torch_tensorrt/fx/example/lower_example.py
+
+
+
+

Converting a PyTorch Model to TensorRT Engine

+

In general, users are welcome to use the compile() to finish the conversion from a model to tensorRT engine. It is a +wrapper API that consists of the major steps needed to finish this converison. Please refer to an example usage in lower_example.py file under examples/fx.

+
def compile(
+    module: nn.Module,
+    input,
+    max_batch_size=2048,
+    max_workspace_size=33554432,
+    explicit_batch_dimension=False,
+    lower_precision=LowerPrecision.FP16,
+    verbose_log=False,
+    timing_cache_prefix="",
+    save_timing_cache=False,
+    cuda_graph_batch_size=-1,
+    dynamic_batch=True,
+) -> nn.Module:
+
+    """
+    Takes in original module, input and lowering setting, run lowering workflow to turn module
+    into lowered module, or so called TRTModule.
+
+    Args:
+        module: Original module for lowering.
+        input: Input for module.
+        max_batch_size: Maximum batch size (must be >= 1 to be set, 0 means not set)
+        max_workspace_size: Maximum size of workspace given to TensorRT.
+        explicit_batch_dimension: Use explicit batch dimension in TensorRT if set True, otherwise use implicit batch dimension.
+        lower_precision: lower_precision config given to TRTModule.
+        verbose_log: Enable verbose log for TensorRT if set True.
+        timing_cache_prefix: Timing cache file name for timing cache used by fx2trt.
+        save_timing_cache: Update timing cache with current timing cache data if set to True.
+        cuda_graph_batch_size: Cuda graph batch size, default to be -1.
+        dynamic_batch: batch dimension (dim=0) is dynamic.
+    Returns:
+        A torch.nn.Module lowered by TensorRT.
+    """
+
+
+

In this section, we will go through an example to illustrate the major steps that fx path uses. +Users can refer to fx2trt_example.py file in examples/fx.

+
    +
  • Step 1: Trace the model with acc_tracer

  • +
+

Acc_tracer is a tracer inheritated from FX tracer. It comes with args normalizer to convert all args to kwargs and pass to TRT converters.

+
import torch_tensorrt.fx.tracer.acc_tracer.acc_tracer as acc_tracer
+
+# Build the model which needs to be a PyTorch nn.Module.
+my_pytorch_model = build_model()
+
+# Prepare inputs to the model. Inputs have to be a List of Tensors
+inputs = [Tensor, Tensor, ...]
+
+# Trace the model with acc_tracer.
+acc_mod = acc_tracer.trace(my_pytorch_model, inputs)
+
+
+

Common Errors:

+

symbolically traced variables cannot be used as inputs to control flow +This means the model contains dynamic control flow. Please refer to section “Dynamic Control Flow” in FX guide.

+
    +
  • Step 2: Build TensorRT engine

  • +
+

There are two different modes for how TensorRT handles batch dimension, explicit batch dimension and implicit batch dimension. This mode was used by early versions of TensorRT, and is now deprecated but continues to be supported for backwards compatibility. In explicit batch mode, all dimensions are explicit and can be dynamic, that is their length can change at execution time. Many new features, such as dynamic shapes and loops, are available only in this mode. User can still choose to use implicit batch mode when they set explicit_batch_dimension=False in compile(). We do not recommend to use it since it will lack of support in future TensorRT versions.

+

Explicit batch is the default mode and it must be set for dynamic shape. For most of vision task, user can choose to enable dynamic_batch in compile() if they want to get the similar effects as implicit mode where only batch dimension changes. It has some requirements: +1. Shapes of inputs, outputs and activations are fixed except batch dimension. +2. Inputs, outputs and activations have batch dimension as the major dimension. +3. All the operators in the model do not modify batch dimension (permute, transpose, split, etc.) or compute over batch dimension (sum, softmax, etc.).

+

For examples of the last path, if we have a 3D tensor t shaped as (batch, sequence, dimension), operations such as torch.transpose(0, 2). If any of these three are not satisfied, we’ll need to specify InputTensorSpec as inputs with dynamic range.

+
import deeplearning.trt.fx2trt.converter.converters
+from torch.fx.experimental.fx2trt.fx2trt import InputTensorSpec, TRTInterpreter
+
+# InputTensorSpec is a dataclass we use to store input information.
+# There're two ways we can build input_specs.
+# Option 1, build it manually.
+input_specs = [
+  InputTensorSpec(shape=(1, 2, 3), dtype=torch.float32),
+  InputTensorSpec(shape=(1, 4, 5), dtype=torch.float32),
+]
+# Option 2, build it using sample_inputs where user provide a sample
+inputs = [
+torch.rand((1,2,3), dtype=torch.float32),
+torch.rand((1,4,5), dtype=torch.float32),
+]
+input_specs = InputTensorSpec.from_tensors(inputs)
+
+# IMPORTANT: If dynamic shape is needed, we need to build it slightly differently.
+input_specs = [
+    InputTensorSpec(
+        shape=(-1, 2, 3),
+        dtype=torch.float32,
+        # Currently we only support one set of dynamic range. User may set other dimensions but it is not promised to work for any models
+        # (min_shape, optimize_target_shape, max_shape)
+        # For more information refer to fx/input_tensor_spec.py
+        shape_ranges = [
+            ((1, 2, 3), (4, 2, 3), (100, 2, 3)),
+        ],
+    ),
+    InputTensorSpec(shape=(1, 4, 5), dtype=torch.float32),
+]
+
+# Build a TRT interpreter. Set explicit_batch_dimension accordingly.
+interpreter = TRTInterpreter(
+    acc_mod, input_specs, explicit_batch_dimension=True/False
+)
+
+# The output of TRTInterpreter run() is wrapped as TRTInterpreterResult.
+# The TRTInterpreterResult contains required parameter to build TRTModule,
+# and other informational output from TRTInterpreter run.
+class TRTInterpreterResult(NamedTuple):
+    engine: Any
+    input_names: Sequence[str]
+    output_names: Sequence[str]
+    serialized_cache: bytearray
+
+#max_batch_size: set accordingly for maximum batch size you will use.
+#max_workspace_size: set to the maximum size we can afford for temporary buffer
+#lower_precision: the precision model layers are running on (TensorRT will choose the best perforamnce precision).
+#sparse_weights: allow the builder to examine weights and use optimized functions when weights have suitable sparsity
+#force_fp32_output: force output to be fp32
+#strict_type_constraints: Usually we should set it to False unless we want to control the precision of certain layer for numeric #reasons.
+#algorithm_selector: set up algorithm selection for certain layer
+#timing_cache: enable timing cache for TensorRT
+#profiling_verbosity: TensorRT logging level
+trt_interpreter_result = interpreter.run(
+    max_batch_size=64,
+    max_workspace_size=1 << 25,
+    sparse_weights=False,
+    force_fp32_output=False,
+    strict_type_constraints=False,
+    algorithm_selector=None,
+    timing_cache=None,
+    profiling_verbosity=None,
+)
+
+
+

Common Errors:

+

RuntimeError: Conversion of function xxx not currently supported! +- This means we don’t have the support for this xxx operator. Please refer to section “How to add a missing op” below for further instructions.

+
    +
  • Step 3: Run the model

  • +
+

One way is using TRTModule, which is basically a PyTorch nn.Module.

+
from torch_tensorrt.fx import TRTModule
+mod = TRTModule(
+    trt_interpreter_result.engine,
+    trt_interpreter_result.input_names,
+    trt_interpreter_result.output_names)
+# Just like all other PyTorch modules
+outputs = mod(*inputs)
+torch.save(mod, "trt.pt")
+reload_trt_mod = torch.load("trt.pt")
+reload_model_output = reload_trt_mod(*inputs)
+
+
+

So far, we give a detailed explanation of major steps in convterting a PyTorch model into TensorRT engine. Users are welcome to refer to the source code for some parameters explanations. In the converting scheme, there are two important actions in it. One is acc tracer which helps us to convert a PyTorch model to acc graph. The other is FX path converter which helps to convert the acc graph’s operation to corresponding TensorRT operation and build up the TensoRT engine for it.

+
+
+

Acc Tracer

+

Acc tracer is a custom FX symbolic tracer. It does a couple more things compare to the vanilla FX symbolic tracer. We mainly depend on it to convert PyTorch ops or builtin ops to acc ops. There are two main purposes for fx2trt to use acc ops:

+
    +
  1. there’re many ops that do similar things in PyTorch ops and builtin ops such like torch.add, builtin.add and torch.Tensor.add. Using acc tracer, we normalize these three ops to a single acc_ops.add. This helps reduce the number of converters we need to write.

  2. +
  3. acc ops only have kwargs which makes writing converter easier as we don’t need to add additional logic to find arguments in args and kwargs.

  4. +
+
+
+

FX2TRT

+

After symbolic tracing, we have the graph representation of a PyTorch model. fx2trt leverages the power of fx.Interpreter. fx.Interpreter goes through the whole graph node by node and calls the function that node represents. fx2trt overrides the original behavior of calling the function with invoking corresponding converts for each node. Each converter function adds corresponding TensorRT layer(s).

+

Below is an example of a converter function. The decorator is used to register this converter function with the corresponding node. In this example, we register this converter to a fx node whose target is acc_ops.sigmoid.

+
@tensorrt_converter(acc_ops.sigmoid)
+def acc_ops_sigmoid(network, target, args, kwargs, name):
+    """
+    network: TensorRT network. We'll be adding layers to it.
+
+    The rest arguments are attributes of fx node.
+    """
+    input_val = kwargs['input']
+
+    if not isinstance(input_val, trt.tensorrt.ITensor):
+        raise RuntimeError(f'Sigmoid received input {input_val} that is not part '
+                        'of the TensorRT region!')
+
+    layer = network.add_activation(input=input_val, type=trt.ActivationType.SIGMOID)
+    layer.name = name
+    return layer.get_output(0)
+
+
+
+

How to Add a Missing Op

+

You can actually add it wherever you want just need to remember import the file so that all acc ops and mapper will be registered before tracing with acc_tracer.

+
    +
  • Step 1. Add a new acc op

  • +
+

TODO: Need to explain more on the logistic of acc op like when we want to break down an op and when we want to reuse other ops.

+

In acc tracer, we convert nodes in the graph to acc ops if there’s a mapping registered for the node to an acc op.

+

In order to make the conversion to acc ops to happen, there’re two things required. One is that there should be an acc op function defined and the other is there should be a mapping registered.

+

Defining an acc op is simple, we first just need a function and register the function as an acc op via this decorator acc_normalizer.py. e.g. the following code adds an acc op named foo() which adds two given inputs.

+
# NOTE: all acc ops should only take kwargs as inputs, therefore we need the "*"
+# at the beginning.
+@register_acc_op
+def foo(*, input, other, alpha):
+    return input + alpha * other
+
+
+

There’re two ways to register a mapping. One is register_acc_op_mapping(). Let’s register a mapping from torch.add to foo() we just created above. We need to add decorator register_acc_op_mapping to it.

+
this_arg_is_optional = True
+
+@register_acc_op_mapping(
+    op_and_target=("call_function", torch.add),
+    arg_replacement_tuples=[
+        ("input", "input"),
+        ("other", "other"),
+        ("alpha", "alpha", this_arg_is_optional),
+    ],
+)
+@register_acc_op
+def foo(*, input, other, alpha=1.0):
+    return input + alpha * other
+
+
+

op_and_target determines which node will trigger this mapping. op and target are the attributes of FX node. In acc_normalization when we see a node with the same op and target as set in the op_and_target, we will trigger the mapping. Since we want to map from torch.add, then op would be call_function and target would be torch.add. arg_replacement_tuples determines how we construct kwargs for new acc op node using args and kwargs from original node. Each tuple in arg_replacement_tuples represents one argument mapping rule. It contains two or three elements. The third element is a boolean variable that determines whether this kwarg is optional in original node. We only need to specify the third element if it’s True. The first element is the argument name in original node which will be used as the acc op node’s argument whose name is the second element in the tuple. The sequence of the tuples does matter because the position of the tuple determines where the argument is in original node’s args. We use this information to map args from original node to kwargs in acc op node. +We don’t have to specify arg_replacement_tuples if none of the followings are true.

+
    +
  1. kwargs of original nodes and acc op nodes have different name.

  2. +
  3. there’re optional arguments.

  4. +
+

The other way to register a mapping is through register_custom_acc_mapper_fn(). This one is designed to reduce the redundant op registration as it allows you to use a function to map to one or more existing acc ops throught some combinations. In the function, you can do basically whatever you want. Let’s use an example to explain how it works.

+
@register_acc_op
+def foo(*, input, other, alpha=1.0):
+    return input + alpha * other
+
+@register_custom_acc_mapper_fn(
+    op_and_target=("call_function", torch.add),
+    arg_replacement_tuples=[
+        ("input", "input"),
+        ("other", "other"),
+        ("alpha", "alpha", this_arg_is_optional),
+    ],
+)
+def custom_mapper(node: torch.fx.Node, _: nn.Module) -> torch.fx.Node:
+    """
+    `node` is original node, which is a call_function node with target
+    being torch.add.
+    """
+    alpha = 1
+    if "alpha" in node.kwargs:
+        alpha = node.kwargs["alpha"]
+    foo_kwargs = {"input": node["input"], "other": node["other"], "alpha": alpha}
+    with node.graph.inserting_before(node):
+        foo_node = node.graph.call_function(foo, kwargs=foo_kwargs)
+        foo_node.meta = node.meta.copy()
+        return foo_node
+
+
+

In the custom mapper function, we construct an acc op node and return it. The node we returns here would take over all the children nodes of original nodes acc_normalizer.py.

+

The last step would be adding unit test for the new acc op or mapper function we added. The place to add the unit test is here test_acc_tracer.py.

+
    +
  • Step 2. Add a new converter

  • +
+

All the developed converters for acc ops are all in acc_op_converter.py. It could give you a good example of how the converter is added.

+

Essentially, the converter is the mapping mechanism that maps the acc ops to a TensorRT layer. If we are able to find all the TensorRT layers we need we can get start to add a converter for the node using TensorRT APIs.

+
@tensorrt_converter(acc_ops.sigmoid)
+def acc_ops_sigmoid(network, target, args, kwargs, name):
+    """
+    network: TensorRT network. We'll be adding layers to it.
+
+    The rest arguments are attributes of fx node.
+    """
+    input_val = kwargs['input']
+
+    if not isinstance(input_val, trt.tensorrt.ITensor):
+        raise RuntimeError(f'Sigmoid received input {input_val} that is not part '
+                        'of the TensorRT region!')
+
+    layer = network.add_activation(input=input_val, type=trt.ActivationType.SIGMOID)
+    layer.name = name
+    return layer.get_output(0)
+
+
+

We need to use tensorrt_converter decorator to register the converter. The argument for the decorator is the target of the fx node that we need to convert. In the converter, we can find the inputs to the fx node in kwargs. As in the example, the original node is acc_ops.sigmoid which only has one argument “input” in acc_ops.py. We get the input and check if it’s a TensorRT tensor. After that, we add a sigmoid layer to TensorRT network and return the output of the layer. The output we returned will be passed to the children nodes of acc_ops.sigmoid by fx.Interpreter.

+

What if we can not find corresponding layers in TensorRT that do the same thing as the node.

+

In this case, we would need to do a bit more work. TensorRT provides plugins which serves as custom layers. We have not implement this feature yet. We will update once it is enabled.

+

Last step would be adding the unit test for the new converter we added. User could add corresponding unit test in this folder.

+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/genindex.html b/docs/v2.2.0/genindex.html new file mode 100644 index 0000000000..71f79776ca --- /dev/null +++ b/docs/v2.2.0/genindex.html @@ -0,0 +1,1338 @@ + + + + + + + + + + + + Index — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ + +

Index

+ +
+ _ + | C + | D + | E + | F + | G + | I + | L + | M + | P + | R + | S + | T + | W + | X + +
+

_

+ + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

I

+ + + +
+ +

L

+ + + +
+ +

M

+ + +
+ +

P

+ + +
    +
  • + Python Enhancement Proposals + +
  • +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

W

+ + + +
+ +

X

+ + +
+ + + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/getting_started/getting_started_with_windows.html b/docs/v2.2.0/getting_started/getting_started_with_windows.html new file mode 100644 index 0000000000..b204603e74 --- /dev/null +++ b/docs/v2.2.0/getting_started/getting_started_with_windows.html @@ -0,0 +1,917 @@ + + + + + + + + + + + + + Building Torch-TensorRT on Windows — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Building Torch-TensorRT on Windows
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Building Torch-TensorRT on Windows

+

Torch-TensorRT has community support for Windows platform using CMake

+

Prerequisite:

+
    +
  • Microsoft Visual Studio

  • +
  • LibTorch

  • +
  • TensorRT

  • +
  • CUDA

  • +
  • cuDNN

  • +
+
+

Build configuration

+
    +
  • Open Microsoft Visual Studio

  • +
  • Open Torch-TensorRT source code folder

  • +
  • Open Manage configurations -> Edit JSON to open CMakeSettings.json file.

  • +
  • Configure the CMake build configurations. Following is an example configuration:

  • +
+
{
+  "configurations": [
+    {
+      "name": "x64-Debug",
+      "generator": "Ninja",
+      "configurationType": "Debug",
+      "inheritEnvironments": [ "msvc_x64_x64" ],
+      "buildRoot": "${projectDir}\\out\\build\\${name}",
+      "installRoot": "${projectDir}\\out\\install\\${name}",
+      "cmakeCommandArgs": "-S . -B out",
+      "buildCommandArgs": "cmake --build out",
+      "ctestCommandArgs": "",
+      "variables": [
+        {
+          "name": "CMAKE_MODULE_PATH",
+          "value": "$PWD\cmake\Modules",
+          "type": "FILEPATH"
+        },
+        {
+          "name": "Torch_DIR",
+          "value": "<Path to libtorch>\share\cmake\Torch",
+          "type": "FILEPATH"
+        },
+        {
+          "name": "TensorRT_ROOT",
+          "value": "<Path to TensorRT directory>",
+          "type": "FILEPATH"
+        },
+        {
+          "name": "CMAKE_BUILD_TYPE",
+          "value": "Release",
+          "type": " STRING"
+        }
+      ]
+    }
+  ]
+}
+
+
+
+
+

Compilation

+
    +
  • Click Build -> Build All or directly press Ctrl + Shift + B

  • +
+

Note: After successful compilation, the build artifacts will be present at buildRoot path configured.

+
+
+

Installation

+
    +
  • Build -> Install Torch-TensorRT

  • +
+

Note: After successful installation, the artifacts will be present at installRoot.

+
+
+
+

Building With Visual Studio Code

+
    +
  1. Install Visual Studio Code

  2. +
  3. Install Build Tools for Visual Studio 2022

    +
    +
      +
    • Select “Desktop Development with C++” +> Currently, this installs MSVC v143 - 2022. There are also options to install previous 2019/2017/2015 editions of MSVC +> License term “1b Build Tools additional use right” allows using Build Tools to compile Open Source Dependencies +> Also allows using Build Tools to develop and test Open Source Dependencies, to the minor extend of ensuring compatibility with Build Tools

    • +
    +
    +
  4. +
  5. Install CUDA (e.g. 11.7.1)

  6. +
  7. Install cuDNN (e.g. 8.5.0.96)

    +
    +
      +
    • Set cuDNN_ROOT_DIR

    • +
    +
    +
  8. +
  9. Install TensorRT (e.g 8.5.1.7)

    +
    +
      +
    • Set TensorRT_ROOT

    • +
    • Add TensorRT_ROOT\lib to PATH

    • +
    +
    +
  10. +
  11. Install “libtorch-win-shared-with-deps-latest.zip”

    +
    +
      +
    • Select build targeting the appropriate CUDA version

    • +
    • Set Torch_DIR

    • +
    • Add Torch_DIR\lib to PATH

    • +
    +
    +
  12. +
  13. Clone TensorRT repo

  14. +
  15. Install C++ and CMake Tools extensions from MS

    +
    +
      +
    • Change build to RelWithDebInfo

    • +
    +
    +
  16. +
  17. Update .vscode\settings.json

    +
    +
      +
    • Clean, configure, build

    • +
    +
    +
  18. +
+

e.g. /.vscode/settings.json

+
{
+    "cmake.generator": "Ninja",
+    "cmake.configureSettings": {
+        "CMAKE_MODULE_PATH": {
+            "type": "FILEPATH",
+            "value": "$PWD\\cmake\\Modules"
+        },
+        "CMAKE_CXX_FLAGS": {
+            "type": "STRING",
+            "value": "-D_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING"
+        },
+        "Torch_DIR": {
+            "type": "FILEPATH",
+            "value": "X:\\libtorch\\share\\cmake\\Torch"
+        },
+        "TensorRT_ROOT": {
+            "type": "FILEPATH",
+            "value": "X:\\path\\to\\tensorrt"
+        },
+        "cuDNN_ROOT_DIR": {
+            "type": "FILEPATH",
+            "value": "X:\\path\\to\\cudnn"
+        },
+        "CMAKE_CUDA_FLAGS": "-allow-unsupported-compiler"
+    },
+    "cmake.buildDirectory": "${workspaceFolder}/torch_tensorrt_build"
+}
+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/getting_started/installation.html b/docs/v2.2.0/getting_started/installation.html new file mode 100644 index 0000000000..67cdd1b86d --- /dev/null +++ b/docs/v2.2.0/getting_started/installation.html @@ -0,0 +1,1086 @@ + + + + + + + + + + + + + Installation — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Installation

+
+

Precompiled Binaries

+

Torch-TensorRT 2.x is centered primarily around Python. As such, precompiled releases can be found on pypi.org

+
+

Dependencies

+

You need to have CUDA, PyTorch, and TensorRT (python package is sufficient) installed to use Torch-TensorRT

+
+
+
+
+

Installing Torch-TensorRT

+

You can install the python package using

+
python -m pip install torch torch-tensorrt tensorrt
+
+
+
+
+

Installing Torch-TensorRT for a specific CUDA version

+

Similar to PyTorch, Torch-TensorRT has builds compiled for different versions of CUDA. These are distributed on PyTorch’s package index

+

For example CUDA 11.8

+
python -m pip install torch torch-tensorrt tensorrt --extra-index-url https://download.pytorch.org/whl/cu118
+
+
+
+
+

Installing Nightly Builds

+

Torch-TensorRT distributed nightlies targeting the PyTorch nightly. These can be installed from the PyTorch nightly package index (separated by CUDA version)

+
python -m pip install --pre torch torch-tensorrt tensorrt --extra-index-url https://download.pytorch.org/whl/nightly/cu121
+
+
+
+
+

C++ Precompiled Binaries (TorchScript Only)

+

Precompiled tarballs for releases are provided here: https://github.com/pytorch/TensorRT/releases

+
+
+
+

Compiling From Source

+
+

Dependencies for Compilation

+
    +
  • Torch-TensorRT is built with Bazel, so begin by installing it.

    +
    +
    +
    export BAZEL_VERSION=$(cat <PATH_TO_TORCHTRT_ROOT>/.bazelversion)
    +mkdir bazel
    +cd bazel
    +curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-dist.zip
    +unzip bazel-$BAZEL_VERSION-dist.zip
    +bash ./compile.sh
    +cp output/bazel /usr/local/bin/
    +
    +
    +
    +
  • +
  • You will also need to have CUDA installed on the system (or if running in a container, the system must have the CUDA driver installed and the container must have CUDA)

    +
    +
    +
    +
  • +
  • The correct LibTorch version will be pulled down for you by bazel.

    +
    +

    NOTE: By default bazel will pull the latest nightly from pytorch.org. For building main, this is usually sufficient however if there is a specific PyTorch you are targeting, +edit these locations with updated URLs/paths:

    + +
    +
  • +
  • cuDNN and TensorRT are not required to be installed on the system to build Torch-TensorRT, in fact this is preferable to ensure reproducable builds. Download the tarballs for cuDNN and TensorRT from https://developer.nvidia.com and update the paths in the WORKSPACE file here https://github.com/pytorch/TensorRT/blob/4e5b0f6e860910eb510fa70a76ee3eb9825e7a4d/WORKSPACE#L71

    +
    +

    For example:

    +
    http_archive(
    +    name = "cudnn",
    +    build_file = "@//third_party/cudnn/archive:BUILD",
    +    sha256 = "79d77a769c7e7175abc7b5c2ed5c494148c0618a864138722c887f95c623777c",
    +    strip_prefix = "cudnn-linux-x86_64-8.8.1.3_cuda12-archive",
    +    urls = [
    +        #"https://developer.nvidia.com/downloads/compute/cudnn/secure/8.8.1/local_installers/12.0/cudnn-linux-x86_64-8.8.1.3_cuda12-archive.tar.xz",
    +        "file:///<ABSOLUTE PATH TO FILE>/cudnn-linux-x86_64-8.8.1.3_cuda12-archive.tar.xz"
    +    ],
    +)
    +
    +http_archive(
    +    name = "tensorrt",
    +    build_file = "@//third_party/tensorrt/archive:BUILD",
    +    sha256 = "0f8157a5fc5329943b338b893591373350afa90ca81239cdadd7580cd1eba254",
    +    strip_prefix = "TensorRT-8.6.1.6",
    +    urls = [
    +        #"https://developer.nvidia.com/downloads/compute/machine-learning/tensorrt/secure/8.6.1/tars/TensorRT-8.6.1.6.Linux.x86_64-gnu.cuda-12.0.tar.gz",
    +        "file:///<ABSOLUTE PATH TO FILE>/TensorRT-8.6.1.6.Linux.x86_64-gnu.cuda-12.0.tar.gz"
    +    ],
    +)
    +
    +
    +
    +
  • +
+

If you have a local version of cuDNN and TensorRT installed, this can be used as well by commenting out the above lines and uncommenting the following lines https://github.com/pytorch/TensorRT/blob/4e5b0f6e860910eb510fa70a76ee3eb9825e7a4d/WORKSPACE#L114C1-L124C3

+
+
+

Building the Package

+

Once the WORKSPACE has been configured properly, all that is required to build torch-tensorrt is the following command

+
+
python -m pip install --pre . --extra-index-url https://download.pytorch.org/whl/nightly/cu121
+
+
+
+

To build the wheel file

+
+
python -m pip wheel --no-deps --pre . --extra-index-url https://download.pytorch.org/whl/nightly/cu121 -w dist
+
+
+
+
+
+

Building the C++ Library (TorchScript Only)

+
+

Release Build

+
bazel build //:libtorchtrt -c opt
+
+
+

A tarball with the include files and library can then be found in bazel-bin

+
+
+

Debug Build

+

To build with debug symbols use the following command

+
bazel build //:libtorchtrt -c dbg
+
+
+

A tarball with the include files and library can then be found in bazel-bin

+
+
+

Pre CXX11 ABI Build

+

To build using the pre-CXX11 ABI use the pre_cxx11_abi config

+
bazel build //:libtorchtrt --config pre_cxx11_abi -c [dbg/opt]
+
+
+

A tarball with the include files and library can then be found in bazel-bin

+
+
+

Choosing the Right ABI

+

Likely the most complicated thing about compiling Torch-TensorRT is selecting the correct ABI. There are two options +which are incompatible with each other, pre-cxx11-abi and the cxx11-abi. The complexity comes from the fact that while +the most popular distribution of PyTorch (wheels downloaded from pytorch.org/pypi directly) use the pre-cxx11-abi, most +other distributions you might encounter (e.g. ones from NVIDIA - NGC containers, and builds for Jetson as well as certain +libtorch builds and likely if you build PyTorch from source) use the cxx11-abi. It is important you compile Torch-TensorRT +using the correct ABI to function properly. Below is a table with general pairings of PyTorch distribution sources and the +recommended commands:

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

PyTorch Source

Recommended Python Compilation Command

Recommended C++ Compilation Command

PyTorch whl file from PyTorch.org

python -m pip install .

bazel build //:libtorchtrt -c opt –config pre_cxx11_abi

libtorch-shared-with-deps-*.zip from PyTorch.org

python -m pip install .

bazel build //:libtorchtrt -c opt –config pre_cxx11_abi

libtorch-cxx11-abi-shared-with-deps-*.zip from PyTorch.org

python setup.py bdist_wheel –use-cxx11-abi

bazel build //:libtorchtrt -c opt

PyTorch preinstalled in an NGC container

python setup.py bdist_wheel –use-cxx11-abi

bazel build //:libtorchtrt -c opt

PyTorch from the NVIDIA Forums for Jetson

python setup.py bdist_wheel –use-cxx11-abi

bazel build //:libtorchtrt -c opt

PyTorch built from Source

python setup.py bdist_wheel –use-cxx11-abi

bazel build //:libtorchtrt -c opt

+
+

NOTE: For all of the above cases you must correctly declare the source of PyTorch you intend to use in your WORKSPACE file for both Python and C++ builds. See below for more information

+
+
+
+
+

Building with CMake (TorchScript Only)

+

It is possible to build the API libraries (in cpp/) and the torchtrtc executable using CMake instead of Bazel. +Currently, the python API and the tests cannot be built with CMake. +Begin by installing CMake.

+
+
    +
  • Latest releases of CMake and instructions on how to install are available for different platforms +[on their website](https://cmake.org/download/).

  • +
+
+

A few useful CMake options include:

+
+
    +
  • CMake finders for TensorRT and cuDNN are provided in cmake/Modules. In order for CMake to use them, pass +-DCMAKE_MODULE_PATH=cmake/Modules when configuring the project with CMake.

  • +
  • Libtorch provides its own CMake finder. In case CMake doesn’t find it, pass the path to your install of +libtorch with -DTorch_DIR=<path to libtorch>/share/cmake/Torch

  • +
  • If TensorRT is not found with the provided cmake finder, specify -DTensorRT_ROOT=<path to TensorRT>

  • +
  • Finally, configure and build the project in a build directory of your choice with the following command +from the root of Torch-TensorRT project:

  • +
+
cmake -S. -B<build directory> \
+    [-DCMAKE_MODULE_PATH=cmake/Module] \
+    [-DTorch_DIR=<path to libtorch>/share/cmake/Torch] \
+    [-DTensorRT_ROOT=<path to TensorRT>] \
+    [-DCMAKE_BUILD_TYPE=Debug|Release]
+cmake --build <build directory>
+
+
+
+
+
+

Building Natively on aarch64 (Jetson)

+
+

Prerequisites

+

Install or compile a build of PyTorch/LibTorch for aarch64

+

NVIDIA hosts builds the latest release branch for Jetson here:

+
+
+
+
+

Enviorment Setup

+

To build natively on aarch64-linux-gnu platform, configure the WORKSPACE with local available dependencies.

+
    +
  1. Replace WORKSPACE with the corresponding WORKSPACE file in //toolchains/jp_workspaces

  2. +
  3. Configure the correct paths to directory roots containing local dependencies in the new_local_repository rules:

    +
    +

    NOTE: If you installed PyTorch using a pip package, the correct path is the path to the root of the python torch package. +In the case that you installed with sudo pip install this will be /usr/local/lib/python3.8/dist-packages/torch. +In the case you installed with pip install --user this will be $HOME/.local/lib/python3.8/site-packages/torch.

    +
    +
  4. +
+

In the case you are using NVIDIA compiled pip packages, set the path for both libtorch sources to the same path. This is because unlike +PyTorch on x86_64, NVIDIA aarch64 PyTorch uses the CXX11-ABI. If you compiled for source using the pre_cxx11_abi and only would like to +use that library, set the paths to the same path but when you compile make sure to add the flag --config=pre_cxx11_abi

+
new_local_repository(
+    name = "libtorch",
+    path = "/usr/local/lib/python3.8/dist-packages/torch",
+    build_file = "third_party/libtorch/BUILD"
+)
+
+new_local_repository(
+    name = "libtorch_pre_cxx11_abi",
+    path = "/usr/local/lib/python3.8/dist-packages/torch",
+    build_file = "third_party/libtorch/BUILD"
+)
+
+
+
+
+

Compile C++ Library and Compiler CLI

+
+

NOTE: Due to shifting dependency locations between Jetpack 4.5 and 4.6 there is a now a flag to inform bazel of the Jetpack version

+
--platforms //toolchains:jetpack_x.x
+
+
+
+

Compile Torch-TensorRT library using bazel command:

+
bazel build //:libtorchtrt --platforms //toolchains:jetpack_5.0
+
+
+
+
+

Compile Python API

+
+

NOTE: Due to shifting dependencies locations between Jetpack 4.5 and newer Jetpack verisons there is now a flag for setup.py which sets the jetpack version (default: 5.0)

+
+

Compile the Python API using the following command from the //py directory:

+
python3 setup.py install --use-cxx11-abi
+
+
+

If you have a build of PyTorch that uses Pre-CXX11 ABI drop the --use-cxx11-abi flag

+

If you are building for Jetpack 4.5 add the --jetpack-version 5.0 flag

+
+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/index.html b/docs/v2.2.0/index.html new file mode 100644 index 0000000000..8202b6d8d4 --- /dev/null +++ b/docs/v2.2.0/index.html @@ -0,0 +1,901 @@ + + + + + + + + + + + + + Torch-TensorRT — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Torch-TensorRT

+
+

In-framework compilation of PyTorch inference code for NVIDIA GPUs

+

Torch-TensorRT is a inference compiler for PyTorch, targeting NVIDIA GPUs via NVIDIA’s TensorRT Deep Learning Optimizer and Runtime. +It supports both just-in-time (JIT) compilation workflows via the torch.compile interface as well as ahead-of-time (AOT) workflows. +Torch-TensorRT integrates seamlessly into the PyTorch ecosystem supporting hybrid execution of optimized TensorRT code with standard PyTorch code.

+

More Information / System Architecture:

+ +
+
+

Getting Started

+ +
+
+
+
+

Dynamo Frontend

+ +
+
+
+
+

TorchScript Frontend

+ +
+
+
+
+

FX Frontend

+ +
+
+
+
+

User Guide

+ +
+
+
+
+

Tutorials

+ +
+
+
+
+

Python API Documenation

+ +
+
+
+
+

C++ API Documenation

+ +
+
+
+
+

CLI Documentation

+ +
+
+
+
+

Contributor Documentation

+ +
+
+
+
+

Indices

+ +
+
+
+
+

Legacy Further Information (TorchScript)

+ +
+
+ + +
+ +
+
+ + + + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/indices/supported_ops.html b/docs/v2.2.0/indices/supported_ops.html new file mode 100644 index 0000000000..0720be6d7e --- /dev/null +++ b/docs/v2.2.0/indices/supported_ops.html @@ -0,0 +1,1044 @@ + + + + + + + + + + + + + Operators Supported — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Operators Supported
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Operators Supported

+
+

Operators Currently Supported Through Converters

+
    +
  • aten::_convolution(Tensor input, Tensor weight, Tensor? bias, int[] stride, int[] padding, int[] dilation, bool transposed, int[] output_padding, int groups, bool benchmark, bool deterministic, bool cudnn_enabled, bool allow_tf32) -> (Tensor)

  • +
  • aten::_convolution.deprecated(Tensor input, Tensor weight, Tensor? bias, int[] stride, int[] padding, int[] dilation, bool transposed, int[] output_padding, int groups, bool benchmark, bool deterministic, bool cudnn_enabled) -> (Tensor)

  • +
  • aten::abs(Tensor self) -> (Tensor)

  • +
  • aten::acos(Tensor self) -> (Tensor)

  • +
  • aten::acosh(Tensor self) -> (Tensor)

  • +
  • aten::adaptive_avg_pool1d(Tensor self, int[1] output_size) -> (Tensor)

  • +
  • aten::adaptive_avg_pool2d(Tensor self, int[2] output_size) -> (Tensor)

  • +
  • aten::adaptive_avg_pool3d(Tensor self, int[3] output_size) -> (Tensor)

  • +
  • aten::adaptive_max_pool1d(Tensor self, int[2] output_size) -> (Tensor, Tensor)

  • +
  • aten::adaptive_max_pool2d(Tensor self, int[2] output_size) -> (Tensor, Tensor)

  • +
  • aten::adaptive_max_pool3d(Tensor self, int[3] output_size) -> (Tensor, Tensor)

  • +
  • aten::add.Scalar(Tensor self, Scalar other, Scalar alpha=1) -> (Tensor)

  • +
  • aten::add.Tensor(Tensor self, Tensor other, Scalar alpha=1) -> (Tensor)

  • +
  • aten::add_.Tensor(Tensor(a!) self, Tensor other, *, Scalar alpha=1) -> (Tensor(a!))

  • +
  • aten::argmax(Tensor self, int dim, bool keepdim=False) -> (Tensor)

  • +
  • aten::argmin(Tensor self, int dim, bool keepdim=False) -> (Tensor)

  • +
  • aten::asin(Tensor self) -> (Tensor)

  • +
  • aten::asinh(Tensor self) -> (Tensor)

  • +
  • aten::atan(Tensor self) -> (Tensor)

  • +
  • aten::atanh(Tensor self) -> (Tensor)

  • +
  • aten::avg_pool1d(Tensor self, int[1] kernel_size, int[1] stride=[], int[1] padding=[0], bool ceil_mode=False, bool count_include_pad=True) -> (Tensor)

  • +
  • aten::avg_pool2d(Tensor self, int[2] kernel_size, int[2] stride=[], int[2] padding=[0, 0], bool ceil_mode=False, bool count_include_pad=True, int? divisor_override=None) -> (Tensor)

  • +
  • aten::avg_pool3d(Tensor self, int[3] kernel_size, int[3] stride=[], int[3] padding=[], bool ceil_mode=False, bool count_include_pad=True, int? divisor_override=None) -> (Tensor)

  • +
  • aten::batch_norm(Tensor input, Tensor? gamma, Tensor? beta, Tensor? mean, Tensor? var, bool training, float momentum, float eps, bool cudnn_enabled) -> (Tensor)

  • +
  • aten::bitwise_not(Tensor self) -> (Tensor)

  • +
  • aten::bmm(Tensor self, Tensor mat2) -> (Tensor)

  • +
  • aten::cat(Tensor[] tensors, int dim=0) -> (Tensor)

  • +
  • aten::ceil(Tensor self) -> (Tensor)

  • +
  • aten::clamp(Tensor self, Scalar? min=None, Scalar? max=None) -> (Tensor)

  • +
  • aten::clamp_max(Tensor self, Scalar max) -> (Tensor)

  • +
  • aten::clamp_min(Tensor self, Scalar min) -> (Tensor)

  • +
  • aten::constant_pad_nd(Tensor self, int[] pad, Scalar value=0) -> (Tensor)

  • +
  • aten::cos(Tensor self) -> (Tensor)

  • +
  • aten::cosh(Tensor self) -> (Tensor)

  • +
  • aten::cumsum(Tensor self, int dim, *, int? dtype=None) -> (Tensor)

  • +
  • aten::div.Scalar(Tensor self, Scalar other) -> (Tensor)

  • +
  • aten::div.Tensor(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::div.Tensor_mode(Tensor self, Tensor other, *, str? rounding_mode) -> (Tensor)

  • +
  • aten::div_.Scalar(Tensor(a!) self, Scalar other) -> (Tensor(a!))

  • +
  • aten::div_.Tensor(Tensor(a!) self, Tensor other) -> (Tensor(a!))

  • +
  • aten::elu(Tensor self, Scalar alpha=1, Scalar scale=1, Scalar input_scale=1) -> (Tensor)

  • +
  • aten::embedding(Tensor weight, Tensor indices, int padding_idx=-1, bool scale_grad_by_freq=False, bool sparse=False) -> (Tensor)

  • +
  • aten::eq.Scalar(Tensor self, Scalar other) -> (Tensor)

  • +
  • aten::eq.Tensor(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::erf(Tensor self) -> (Tensor)

  • +
  • aten::exp(Tensor self) -> (Tensor)

  • +
  • aten::expand(Tensor(a) self, int[] size, *, bool implicit=False) -> (Tensor(a))

  • +
  • aten::expand_as(Tensor(a) self, Tensor other) -> (Tensor(a))

  • +
  • aten::fake_quantize_per_channel_affine(Tensor self, Tensor scale, Tensor zero_point, int axis, int quant_min, int quant_max) -> (Tensor)

  • +
  • aten::fake_quantize_per_tensor_affine(Tensor self, float scale, int zero_point, int quant_min, int quant_max) -> (Tensor)

  • +
  • aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor)

  • +
  • aten::floor(Tensor self) -> (Tensor)

  • +
  • aten::floor_divide(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::floor_divide.Scalar(Tensor self, Scalar other) -> (Tensor)

  • +
  • aten::ge.Scalar(Tensor self, Scalar other) -> (Tensor)

  • +
  • aten::ge.Tensor(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::gru_cell(Tensor input, Tensor hx, Tensor w_ih, Tensor w_hh, Tensor? b_ih=None, Tensor? b_hh=None) -> (Tensor)

  • +
  • aten::gt.Scalar(Tensor self, Scalar other) -> (Tensor)

  • +
  • aten::gt.Tensor(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::hardtanh(Tensor self, Scalar min_val=-1, Scalar max_val=1) -> (Tensor)

  • +
  • aten::hardtanh_(Tensor(a!) self, Scalar min_val=-1, Scalar max_val=1) -> (Tensor(a!))

  • +
  • aten::index.Tensor(Tensor self, Tensor?[] indices) -> (Tensor)

  • +
  • aten::instance_norm(Tensor input, Tensor? weight, Tensor? bias, Tensor? running_mean, Tensor? running_var, bool use_input_stats, float momentum, float eps, bool cudnn_enabled) -> (Tensor)

  • +
  • aten::layer_norm(Tensor input, int[] normalized_shape, Tensor? gamma, Tensor? beta, float eps, bool cudnn_enabled) -> (Tensor)

  • +
  • aten::le.Scalar(Tensor self, Scalar other) -> (Tensor)

  • +
  • aten::le.Tensor(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::leaky_relu(Tensor self, Scalar negative_slope=0.01) -> (Tensor)

  • +
  • aten::leaky_relu_(Tensor(a!) self, Scalar negative_slope=0.01) -> (Tensor(a!))

  • +
  • aten::linear(Tensor input, Tensor weight, Tensor? bias=None) -> (Tensor)

  • +
  • aten::log(Tensor self) -> (Tensor)

  • +
  • aten::lstm_cell(Tensor input, Tensor[] hx, Tensor w_ih, Tensor w_hh, Tensor? b_ih=None, Tensor? b_hh=None) -> (Tensor, Tensor)

  • +
  • aten::lt.Scalar(Tensor self, Scalar other) -> (Tensor)

  • +
  • aten::lt.Tensor(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::masked_fill.Scalar(Tensor self, Tensor mask, Scalar value) -> (Tensor)

  • +
  • aten::matmul(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::max(Tensor self) -> (Tensor)

  • +
  • aten::max.dim(Tensor self, int dim, bool keepdim=False) -> (Tensor values, Tensor indices)

  • +
  • aten::max.other(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::max_pool1d(Tensor self, int[1] kernel_size, int[1] stride=[], int[1] padding=[], int[1] dilation=[], bool ceil_mode=False) -> (Tensor)

  • +
  • aten::max_pool2d(Tensor self, int[2] kernel_size, int[2] stride=[], int[2] padding=[0, 0], int[2] dilation=[1, 1], bool ceil_mode=False) -> (Tensor)

  • +
  • aten::max_pool3d(Tensor self, int[3] kernel_size, int[3] stride=[], int[3] padding=[], int[3] dilation=[], bool ceil_mode=False) -> (Tensor)

  • +
  • aten::mean(Tensor self, *, int? dtype=None) -> (Tensor)

  • +
  • aten::mean.dim(Tensor self, int[] dim, bool keepdim=False, *, int? dtype=None) -> (Tensor)

  • +
  • aten::min(Tensor self) -> (Tensor)

  • +
  • aten::min.dim(Tensor self, int dim, bool keepdim=False) -> (Tensor values, Tensor indices)

  • +
  • aten::min.other(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::mul.Scalar(Tensor self, Scalar other) -> (Tensor)

  • +
  • aten::mul.Tensor(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::mul_.Tensor(Tensor(a!) self, Tensor other) -> (Tensor(a!))

  • +
  • aten::narrow(Tensor(a) self, int dim, int start, int length) -> (Tensor(a))

  • +
  • aten::narrow.Tensor(Tensor(a) self, int dim, Tensor start, int length) -> (Tensor(a))

  • +
  • aten::ne.Scalar(Tensor self, Scalar other) -> (Tensor)

  • +
  • aten::ne.Tensor(Tensor self, Tensor other) -> (Tensor)

  • +
  • aten::neg(Tensor self) -> (Tensor)

  • +
  • aten::norm.ScalarOpt_dim(Tensor self, Scalar? p, int[1] dim, bool keepdim=False) -> (Tensor)

  • +
  • aten::permute(Tensor(a) self, int[] dims) -> (Tensor(a))

  • +
  • aten::pixel_shuffle(Tensor self, int upscale_factor) -> (Tensor)

  • +
  • aten::pow.Tensor_Scalar(Tensor self, Scalar exponent) -> (Tensor)

  • +
  • aten::pow.Tensor_Tensor(Tensor self, Tensor exponent) -> (Tensor)

  • +
  • aten::prelu(Tensor self, Tensor weight) -> (Tensor)

  • +
  • aten::prod(Tensor self, *, int? dtype=None) -> (Tensor)

  • +
  • aten::prod.dim_int(Tensor self, int dim, bool keepdim=False, *, int? dtype=None) -> (Tensor)

  • +
  • aten::reciprocal(Tensor self) -> (Tensor)

  • +
  • aten::reflection_pad1d(Tensor self, int[2] padding) -> (Tensor)

  • +
  • aten::reflection_pad2d(Tensor self, int[4] padding) -> (Tensor)

  • +
  • aten::relu(Tensor input) -> (Tensor)

  • +
  • aten::relu_(Tensor(a!) self) -> (Tensor(a!))

  • +
  • aten::repeat(Tensor self, int[] repeats) -> (Tensor)

  • +
  • aten::repeat_interleave.self_int(Tensor self, int repeats, int? dim=None, *, int? output_size=None) -> (Tensor)

  • +
  • aten::replication_pad1d(Tensor self, int[2] padding) -> (Tensor)

  • +
  • aten::replication_pad2d(Tensor self, int[4] padding) -> (Tensor)

  • +
  • aten::replication_pad3d(Tensor self, int[6] padding) -> (Tensor)

  • +
  • aten::reshape(Tensor self, int[] shape) -> (Tensor)

  • +
  • aten::roll(Tensor self, int[1] shifts, int[1] dims=[]) -> (Tensor)

  • +
  • aten::rsub.Scalar(Tensor self, Scalar other, Scalar alpha=1) -> (Tensor)

  • +
  • aten::rsub.Tensor(Tensor self, Tensor other, Scalar alpha=1) -> (Tensor)

  • +
  • aten::scatter.src(Tensor self, int dim, Tensor index, Tensor src) -> (Tensor)

  • +
  • aten::scatter.value(Tensor self, int dim, Tensor index, Scalar value) -> (Tensor)

  • +
  • aten::select.int(Tensor(a) self, int dim, int index) -> (Tensor(a))

  • +
  • aten::sigmoid(Tensor input) -> (Tensor)

  • +
  • aten::sigmoid_(Tensor(a!) self) -> (Tensor(a!))

  • +
  • aten::sin(Tensor self) -> (Tensor)

  • +
  • aten::sinh(Tensor self) -> (Tensor)

  • +
  • aten::slice.Tensor(Tensor(a) self, int dim=0, int? start=None, int? end=None, int step=1) -> (Tensor(a))

  • +
  • aten::softmax.int(Tensor self, int dim, int? dtype=None) -> (Tensor)

  • +
  • aten::split(Tensor self, int[] split_sizes, int dim=0) -> (Tensor[])

  • +
  • aten::split.Tensor(Tensor(a) self, int split_size, int dim=0) -> (Tensor[])

  • +
  • aten::split.sizes(Tensor(a -> *) self, int[] split_size, int dim=0) -> (Tensor[])

  • +
  • aten::split_with_sizes(Tensor(a) self, int[] split_sizes, int dim=0) -> (Tensor[])

  • +
  • aten::sqrt(Tensor self) -> (Tensor)

  • +
  • aten::square(Tensor self) -> (Tensor)

  • +
  • aten::squeeze.dim(Tensor(a) self, int dim) -> (Tensor(a))

  • +
  • aten::stack(Tensor[] tensors, int dim=0) -> (Tensor)

  • +
  • aten::sub.Scalar(Tensor self, Scalar other, Scalar alpha=1) -> (Tensor)

  • +
  • aten::sub.Tensor(Tensor self, Tensor other, Scalar alpha=1) -> (Tensor)

  • +
  • aten::sub_.Tensor(Tensor(a!) self, Tensor other, *, Scalar alpha=1) -> (Tensor(a!))

  • +
  • aten::sum(Tensor self, *, int? dtype=None) -> (Tensor)

  • +
  • aten::sum.dim_IntList(Tensor self, int[1] dim, bool keepdim=False, *, int? dtype=None) -> (Tensor)

  • +
  • aten::t(Tensor self) -> (Tensor)

  • +
  • aten::tan(Tensor self) -> (Tensor)

  • +
  • aten::tanh(Tensor input) -> (Tensor)

  • +
  • aten::tanh_(Tensor(a!) self) -> (Tensor(a!))

  • +
  • aten::to.device(Tensor(a) self, Device device, int dtype, bool non_blocking=False, bool copy=False, int? memory_format=None) -> (Tensor(a))

  • +
  • aten::to.dtype(Tensor self, int dtype, bool non_blocking=False, bool copy=False, int? memory_format=None) -> (Tensor)

  • +
  • aten::to.other(Tensor self, Tensor other, bool non_blocking=False, bool copy=False, int? memory_format=None) -> (Tensor)

  • +
  • aten::to.prim_Device(Tensor(a) self, Device? device, int? dtype=None, bool non_blocking=False, bool copy=False) -> (Tensor(a|b))

  • +
  • aten::topk(Tensor self, int k, int dim=-1, bool largest=True, bool sorted=True) -> (Tensor values, Tensor indices)

  • +
  • aten::transpose.int(Tensor(a) self, int dim0, int dim1) -> (Tensor(a))

  • +
  • aten::unbind.int(Tensor(a -> *) self, int dim=0) -> (Tensor[])

  • +
  • aten::unsqueeze(Tensor(a) self, int dim) -> (Tensor(a))

  • +
  • aten::upsample_bilinear2d(Tensor self, int[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> (Tensor)

  • +
  • aten::upsample_bilinear2d.vec(Tensor input, int[]? output_size, bool align_corners, float[]? scale_factors) -> (Tensor)

  • +
  • aten::upsample_linear1d(Tensor self, int[1] output_size, bool align_corners, float? scales=None) -> (Tensor)

  • +
  • aten::upsample_linear1d.vec(Tensor input, int[]? output_size, bool align_corners, float[]? scale_factors) -> (Tensor)

  • +
  • aten::upsample_nearest1d(Tensor self, int[1] output_size, float? scales=None) -> (Tensor)

  • +
  • aten::upsample_nearest1d.vec(Tensor input, int[]? output_size, float[]? scale_factors) -> (Tensor)

  • +
  • aten::upsample_nearest2d(Tensor self, int[2] output_size, float? scales_h=None, float? scales_w=None) -> (Tensor)

  • +
  • aten::upsample_nearest2d.vec(Tensor input, int[]? output_size, float[]? scale_factors) -> (Tensor)

  • +
  • aten::upsample_nearest3d(Tensor self, int[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> (Tensor)

  • +
  • aten::upsample_nearest3d.vec(Tensor input, int[]? output_size, float[]? scale_factors) -> (Tensor)

  • +
  • aten::upsample_trilinear3d(Tensor self, int[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> (Tensor)

  • +
  • aten::upsample_trilinear3d.vec(Tensor input, int[]? output_size, bool align_corners, float[]? scale_factors) -> (Tensor)

  • +
  • aten::view(Tensor(a) self, int[] size) -> (Tensor(a))

  • +
  • trt::const(Tensor self) -> (Tensor)

  • +
+
+
+

Operators Currently Supported Through Evaluators

+
    +
  • aten::Bool.float(float b) -> (bool)

  • +
  • aten::Bool.int(int a) -> (bool)

  • +
  • aten::Float.Scalar(Scalar a) -> float

  • +
  • aten::Float.bool(bool a) -> float

  • +
  • aten::Float.int(int a) -> float

  • +
  • aten::Int.Scalar(Scalar a) -> int

  • +
  • aten::Int.bool(bool a) -> int

  • +
  • aten::Int.float(float a) -> int

  • +
  • aten::Int.int(int a) -> int

  • +
  • aten::__and__(int a, int b) -> (bool)

  • +
  • aten::__and__.bool(bool a, bool b) -> (bool)

  • +
  • aten::__derive_index(int idx, int start, int step) -> int

  • +
  • aten::__getitem__.t(t[](a) list, int idx) -> (t(*))

  • +
  • aten::__is__(t1 self, t2 obj) -> bool

  • +
  • aten::__isnot__(t1 self, t2 obj) -> bool

  • +
  • aten::__not__(bool self) -> bool

  • +
  • aten::__or__(int a, int b) -> (bool)

  • +
  • aten::__range_length(int lo, int hi, int step) -> int

  • +
  • aten::__round_to_zero_floordiv(int a, int b) -> (int)

  • +
  • aten::__xor__(int a, int b) -> (bool)

  • +
  • aten::add.float(float a, float b) -> (float)

  • +
  • aten::add.int(int a, int b) -> (int)

  • +
  • aten::add.str(str a, str b) -> (str)

  • +
  • aten::add_.t(t[](a!) self, t[] b) -> (t[])

  • +
  • aten::append.t(t[](a!) self, t(c -> *) el) -> (t[](a!))

  • +
  • +
    aten::arange(Scalar end, *, int? dtype=None, int? layout=None,

    Device? device=None, bool? pin_memory=None) -> (Tensor)

    +
    +
    +
  • +
  • +
    aten::arange.start(Scalar start, Scalar end, *, ScalarType? dtype=None,

    Layout? layout=None, Device? device=None, bool? pin_memory=None) -> (Tensor)

    +
    +
    +
  • +
  • +
    aten::arange.start_step(Scalar start, Scalar end, Scalar step, *, ScalarType? dtype=None,

    Layout? layout=None, Device? device=None, bool? pin_memory=None) -> (Tensor)

    +
    +
    +
  • +
  • aten::clone(Tensor self, *, int? memory_format=None) -> (Tensor)

  • +
  • aten::copy_(Tensor(a!) self, Tensor src, bool non_blocking=False) -> (Tensor(a!))

  • +
  • aten::dim(Tensor self) -> int

  • +
  • aten::div.float(float a, float b) -> (float)

  • +
  • aten::div.int(int a, int b) -> (float)

  • +
  • aten::eq.bool(bool a, bool b) -> (bool)

  • +
  • aten::eq.float(float a, float b) -> (bool)

  • +
  • aten::eq.float_int(float a, int b) -> (bool)

  • +
  • aten::eq.int(int a, int b) -> (bool)

  • +
  • aten::eq.int_float(int a, float b) -> (bool)

  • +
  • aten::eq.str(str a, str b) -> (bool)

  • +
  • aten::extend.t(t[](a!) self, t[] other) -> ()

  • +
  • aten::floor.float(float a) -> (int)

  • +
  • aten::floor.int(int a) -> (int)

  • +
  • aten::floordiv.float(float a, float b) -> (int)

  • +
  • aten::floordiv.int(int a, int b) -> (int)

  • +
  • aten::format(str self, …) -> (str)

  • +
  • aten::ge.bool(bool a, bool b) -> (bool)

  • +
  • aten::ge.float(float a, float b) -> (bool)

  • +
  • aten::ge.float_int(float a, int b) -> (bool)

  • +
  • aten::ge.int(int a, int b) -> (bool)

  • +
  • aten::ge.int_float(int a, float b) -> (bool)

  • +
  • aten::gt.bool(bool a, bool b) -> (bool)

  • +
  • aten::gt.float(float a, float b) -> (bool)

  • +
  • aten::gt.float_int(float a, int b) -> (bool)

  • +
  • aten::gt.int(int a, int b) -> (bool)

  • +
  • aten::gt.int_float(int a, float b) -> (bool)

  • +
  • aten::is_floating_point(Tensor self) -> (bool)

  • +
  • aten::le.bool(bool a, bool b) -> (bool)

  • +
  • aten::le.float(float a, float b) -> (bool)

  • +
  • aten::le.float_int(float a, int b) -> (bool)

  • +
  • aten::le.int(int a, int b) -> (bool)

  • +
  • aten::le.int_float(int a, float b) -> (bool)

  • +
  • aten::len.t(t[] a) -> (int)

  • +
  • aten::lt.bool(bool a, bool b) -> (bool)

  • +
  • aten::lt.float(float a, float b) -> (bool)

  • +
  • aten::lt.float_int(float a, int b) -> (bool)

  • +
  • aten::lt.int(int a, int b) -> (bool)

  • +
  • aten::lt.int_float(int a, float b) -> (bool)

  • +
  • aten::mul.float(float a, float b) -> (float)

  • +
  • aten::mul.int(int a, int b) -> (int)

  • +
  • aten::ne.bool(bool a, bool b) -> (bool)

  • +
  • aten::ne.float(float a, float b) -> (bool)

  • +
  • aten::ne.float_int(float a, int b) -> (bool)

  • +
  • aten::ne.int(int a, int b) -> (bool)

  • +
  • aten::ne.int_float(int a, float b) -> (bool)

  • +
  • aten::neg.int(int a) -> (int)

  • +
  • aten::numel(Tensor self) -> int

  • +
  • aten::pow.float(float a, float b) -> (float)

  • +
  • aten::pow.float_int(float a, int b) -> (float)

  • +
  • aten::pow.int(int a, int b) -> (float)

  • +
  • aten::pow.int_float(int a, float b) -> (float)

  • +
  • aten::size(Tensor self) -> (int[])

  • +
  • aten::size.int(Tensor self, int dim) -> (int)

  • +
  • aten::slice.t(t[] l, int start, int end=9223372036854775807, int step=1) -> (t[])

  • +
  • aten::sqrt.float(float a) -> (float)

  • +
  • aten::sqrt.int(int a) -> (float)

  • +
  • aten::sub.float(float a, float b) -> (float)

  • +
  • aten::sub.int(int a, int b) -> (int)

  • +
  • aten::tensor(t[] data, *, int? dtype=None, Device? device=None, bool requires_grad=False) -> (Tensor)

  • +
  • prim::TupleIndex(Any tup, int i) -> (Any)

  • +
  • prim::dtype(Tensor a) -> (int)

  • +
  • prim::max.bool(bool a, bool b) -> (bool)

  • +
  • prim::max.float(float a, float b) -> (bool)

  • +
  • prim::max.float_int(float a, int b) -> (bool)

  • +
  • prim::max.int(int a, int b) -> (bool)

  • +
  • prim::max.int_float(int a, float b) -> (bool)

  • +
  • prim::max.self_int(int[] self) -> (int)

  • +
  • prim::min.bool(bool a, bool b) -> (bool)

  • +
  • prim::min.float(float a, float b) -> (bool)

  • +
  • prim::min.float_int(float a, int b) -> (bool)

  • +
  • prim::min.int(int a, int b) -> (bool)

  • +
  • prim::min.int_float(int a, float b) -> (bool)

  • +
  • prim::min.self_int(int[] self) -> (int)

  • +
  • prim::shape(Tensor a) -> (int[])

  • +
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/objects.inv b/docs/v2.2.0/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..4e057594c6aaf71286bb3e7974bd57278ebb2ecb GIT binary patch literal 28629 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 literal 0 HcmV?d00001 diff --git a/docs/v2.2.0/py-modindex.html b/docs/v2.2.0/py-modindex.html new file mode 100644 index 0000000000..d63ae0d88f --- /dev/null +++ b/docs/v2.2.0/py-modindex.html @@ -0,0 +1,778 @@ + + + + + + + + + + + + Python Module Index — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+ + +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/py_api/dynamo.html b/docs/v2.2.0/py_api/dynamo.html new file mode 100644 index 0000000000..38100988a0 --- /dev/null +++ b/docs/v2.2.0/py_api/dynamo.html @@ -0,0 +1,952 @@ + + + + + + + + + + + + + torch_tensorrt.dynamo — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

torch_tensorrt.dynamo

+
+

Functions

+
+
+torch_tensorrt.dynamo.compile(exported_program: ~torch.export.exported_program.ExportedProgram, inputs: ~typing.Tuple[~typing.Any, ...], *, device: ~typing.Optional[~typing.Union[~torch_tensorrt._Device.Device, ~torch.device, str]] = None, disable_tf32: bool = False, sparse_weights: bool = False, enabled_precisions: ~typing.Union[~typing.Set[~torch.dtype], ~typing.Tuple[~torch.dtype]] = (torch.float32,), engine_capability: ~torch_tensorrt._C.EngineCapability = <EngineCapability.DEFAULT: 0>, refit: bool = False, debug: bool = False, num_avg_timing_iters: int = 1, workspace_size: int = 0, dla_sram_size: int = 1048576, dla_local_dram_size: int = 1073741824, dla_global_dram_size: int = 536870912, truncate_long_and_double: bool = False, require_full_compilation: bool = False, min_block_size: int = 5, torch_executed_ops: ~typing.Optional[~typing.Collection[~typing.Union[~typing.Callable[[...], ~typing.Any], str]]] = None, torch_executed_modules: ~typing.Optional[~typing.List[str]] = None, pass_through_build_failures: bool = False, max_aux_streams: ~typing.Optional[int] = None, version_compatible: bool = False, optimization_level: ~typing.Optional[int] = None, use_python_runtime: bool = False, use_fast_partitioner: bool = True, enable_experimental_decompositions: bool = False, output_format: str = 'exported_program', **kwargs: ~typing.Any) GraphModule[source]
+

Compile a TorchScript module for NVIDIA GPUs using TensorRT

+

Takes a existing TorchScript module and a set of settings to configure the compiler +and will convert methods to JIT Graphs which call equivalent TensorRT engines

+

Converts specifically the forward method of a TorchScript Module

+
+
Parameters
+
    +
  • exported_program (torch.export.ExportedProgram) – Source module, running torch.export on a torch.nn.Module

  • +
  • inputs (Tuple[Any, ...]) –

    List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using +torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum +to select device type.

    +
    input=[
    +    torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1
    +    torch_tensorrt.Input(
    +        min_shape=(1, 224, 224, 3),
    +        opt_shape=(1, 512, 512, 3),
    +        max_shape=(1, 1024, 1024, 3),
    +        dtype=torch.int32
    +        format=torch.channel_last
    +    ), # Dynamic input shape for input #2
    +    torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings
    +]
    +
    +
    +

  • +
+
+
Keyword Arguments
+
    +
  • device (Union(Device, torch.device, dict)) –

    Target device for TensorRT engines to run on

    +
    device=torch_tensorrt.Device("dla:1", allow_gpu_fallback=True)
    +
    +
    +

  • +
  • disable_tf32 (bool) – Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas

  • +
  • sparse_weights (bool) – Enable sparsity for convolution and fully connected layers.

  • +
  • enabled_precision (Set(Union(torch.dpython:type, torch_tensorrt.dpython:type))) – The set of datatypes that TensorRT can use when selecting kernels

  • +
  • refit (bool) – Enable refitting

  • +
  • debug (bool) – Enable debuggable engine

  • +
  • capability (EngineCapability) – Restrict kernel selection to safe gpu kernels or safe dla kernels

  • +
  • num_avg_timing_iters (python:int) – Number of averaging timing iterations used to select kernels

  • +
  • workspace_size (python:int) – Maximum size of workspace given to TensorRT

  • +
  • dla_sram_size (python:int) – Fast software managed RAM used by DLA to communicate within a layer.

  • +
  • dla_local_dram_size (python:int) – Host RAM used by DLA to share intermediate tensor data across operations

  • +
  • dla_global_dram_size (python:int) – Host RAM used by DLA to store weights and metadata for execution

  • +
  • truncate_long_and_double (bool) – Truncate weights provided in int64 or double (float64) to int32 and float32

  • +
  • calibrator (Union(torch_tensorrt._C.IInt8Calibrator, tensorrt.IInt8Calibrator)) – Calibrator object which will provide data to the PTQ system for INT8 Calibration

  • +
  • require_full_compilation (bool) – Require modules to be compiled end to end or return an error as opposed to returning a hybrid graph where operations that cannot be run in TensorRT are run in PyTorch

  • +
  • min_block_size (python:int) – The minimum number of contiguous TensorRT convertable operations in order to run a set of operations in TensorRT

  • +
  • torch_executed_ops (Collection[Target]) – Set of aten operators that must be run in PyTorch. An error will be thrown if this set is not empty but require_full_compilation is True

  • +
  • torch_executed_modules (List[str]) – List of modules that must be run in PyTorch. An error will be thrown if this list is not empty but require_full_compilation is True

  • +
  • pass_through_build_failures (bool) – Error out if there are issues during compilation (only applicable to torch.compile workflows)

  • +
  • max_aux_stream (Optional[python:int]) – Maximum streams in the engine

  • +
  • version_compatible (bool) – Build the TensorRT engines compatible with future versions of TensorRT (Restrict to lean runtime operators to provide version forward compatibility for the engines)

  • +
  • optimization_level – (Optional[int]): Setting a higher optimization level allows TensorRT to spend longer engine building time searching for more optimization options. The resulting engine may have better performance compared to an engine built with a lower optimization level. The default optimization level is 3. Valid values include integers from 0 to the maximum optimization level, which is currently 5. Setting it to be greater than the maximum level results in identical behavior to the maximum level.

  • +
  • use_python_runtime – (bool): Return a graph using a pure Python runtime, reduces options for serialization

  • +
  • use_fast_partitioner – (bool): Use the adjacency based partitioning scheme instead of the global partitioner. Adjacency partitioning is faster but may not be optiminal. Use the global paritioner (False) if looking for best performance

  • +
  • enable_experimental_decompositions (bool) – Use the full set of operator decompositions. These decompositions may not be tested but serve to make the grap easier to covert to TensorRT, potentially increasing the amount of graphs run in TensorRT.

  • +
  • output_format (str) – Output format of the result of TRT compilation. Options include “exported_program” (or) “ep” | “torchscript” (or) “ts” | “graph_module” (or) “fx”. Default is “exported_program”

  • +
  • **kwargs – Any,

  • +
+
+
Returns
+

Compiled FX Module, when run it will execute via TensorRT

+
+
Return type
+

torch.fx.GraphModule

+
+
+
+ +
+
+torch_tensorrt.dynamo.trace(mod: torch.nn.modules.module.Module | torch.fx.graph_module.GraphModule, inputs: Tuple[Any, ...], **kwargs: Any) ExportedProgram[source]
+

Exports a torch.export.ExportedProgram from a torch.nn.Module or torch.fx.GraphModule specifically targeting being compiled with Torch-TensorRT

+

Exports a torch.export.ExportedProgram from either a torch.nn.Module or torch.fx.GraphModule``. Runs specific operator decompositions geared towards +compilation by Torch-TensorRT’s dynamo frontend.

+
+
Parameters
+
    +
  • mod (torch.nn.Module | torch.fx.GraphModule) – Source module to later be compiled by Torch-TensorRT’s dynamo fronted

  • +
  • inputs (Tuple[Any, ...]) –

    List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using +torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum +to select device type.

    +
    input=[
    +    torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1
    +    torch_tensorrt.Input(
    +        min_shape=(1, 224, 224, 3),
    +        opt_shape=(1, 512, 512, 3),
    +        max_shape=(1, 1024, 1024, 3),
    +        dtype=torch.int32
    +        format=torch.channel_last
    +    ), # Dynamic input shape for input #2
    +    torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings
    +]
    +
    +
    +

  • +
+
+
Keyword Arguments
+
    +
  • device (Union(torch.device, dict)) –

    Target device for TensorRT engines to run on

    +
    device=torch.device("cuda:0")
    +
    +
    +

  • +
  • debug (bool) – Enable debuggable engine

  • +
  • enable_experimental_decompositions (bool) – Use the full set of operator decompositions. These decompositions may not be tested but serve to make the grap easier to covert to TensorRT, potentially increasing the amount of graphs run in TensorRT.

  • +
  • **kwargs – Any,

  • +
+
+
Returns
+

Compiled FX Module, when run it will execute via TensorRT

+
+
Return type
+

torch.fx.GraphModule

+
+
+
+ +
+
+torch_tensorrt.dynamo.export(gm: GraphModule, inputs: Sequence[Tensor], output_format: str) ExportedProgram[source]
+

Export the result of TensorRT compilation into the desired output format.

+
+
Parameters
+
    +
  • gm (torch.fx.GraphModule) – Compiled Torch-TensorRT module, generated by torch_tensorrt.dynamo.compile

  • +
  • inputs (torch.Tensor) – Torch input tensors

  • +
  • output_format (str) – Output format of the result of TRT compilation. Options include “exported_program” (or) “ep” | “torchscript” (or) “ts” | “graph_module” (or) “fx”. Default is “exported_program”

  • +
+
+
+
+ +
+
+

Classes

+
+
+class torch_tensorrt.dynamo.CompilationSettings(precision: ~torch.dtype = torch.float32, debug: bool = False, workspace_size: int = 0, min_block_size: int = 5, torch_executed_ops: ~typing.Collection[~typing.Union[~typing.Callable[[...], ~typing.Any], str]] = <factory>, pass_through_build_failures: bool = False, max_aux_streams: ~typing.Optional[int] = None, version_compatible: bool = False, optimization_level: ~typing.Optional[int] = None, use_python_runtime: ~typing.Optional[bool] = False, truncate_long_and_double: bool = False, use_fast_partitioner: bool = True, enable_experimental_decompositions: bool = False, device: ~torch_tensorrt._Device.Device = <factory>, require_full_compilation: bool = False, disable_tf32: bool = False, sparse_weights: bool = False, refit: bool = False, engine_capability: ~tensorrt_bindings.tensorrt.EngineCapability = <EngineCapability.DEFAULT: 0>, num_avg_timing_iters: int = 1, dla_sram_size: int = 1048576, dla_local_dram_size: int = 1073741824, dla_global_dram_size: int = 536870912, output_format: str = 'exported_program')[source]
+

Compilation settings for Torch-TensorRT Dynamo Paths

+
+
Parameters
+
    +
  • precision (torch.dpython:type) – Model Layer precision

  • +
  • debug (bool) – Whether to print out verbose debugging information

  • +
  • workspace_size (python:int) – Workspace TRT is allowed to use for the module (0 is default)

  • +
  • min_block_size (python:int) – Minimum number of operators per TRT-Engine Block

  • +
  • torch_executed_ops (Collection[Target]) – Collection of operations to run in Torch, regardless of converter coverage

  • +
  • pass_through_build_failures (bool) – Whether to fail on TRT engine build errors (True) or not (False)

  • +
  • max_aux_streams (Optional[python:int]) – Maximum number of allowed auxiliary TRT streams for each engine

  • +
  • version_compatible (bool) – Provide version forward-compatibility for engine plan files

  • +
  • optimization_level (Optional[python:int]) – Builder optimization 0-5, higher levels imply longer build time, +searching for more optimization options. TRT defaults to 3

  • +
  • use_python_runtime (Optional[bool]) – Whether to strictly use Python runtime or C++ runtime. To auto-select a runtime +based on C++ dependency presence (preferentially choosing C++ runtime if available), leave the +argument as None

  • +
  • truncate_long_and_double (bool) – Whether to truncate int64/float64 TRT engine inputs or weights to int32/float32

  • +
  • use_fast_partitioner (bool) – Whether to use the fast or global graph partitioning system

  • +
  • enable_experimental_decompositions (bool) – Whether to enable all core aten decompositions +or only a selected subset of them

  • +
  • device (Device) – GPU to compile the model on

  • +
  • require_full_compilation (bool) – Whether to require the graph is fully compiled in TensorRT. +Only applicable for ir=”dynamo”; has no effect for torch.compile path

  • +
  • disable_tf32 (bool) – Whether to disable TF32 computation for TRT layers

  • +
  • sparse_weights (bool) – Whether to allow the builder to use sparse weights

  • +
  • refit (bool) – Whether to build a refittable engine

  • +
  • engine_capability (trt.EngineCapability) – Restrict kernel selection to safe gpu kernels or safe dla kernels

  • +
  • num_avg_timing_iters (python:int) – Number of averaging timing iterations used to select kernels

  • +
  • dla_sram_size (python:int) – Fast software managed RAM used by DLA to communicate within a layer.

  • +
  • dla_local_dram_size (python:int) – Host RAM used by DLA to share intermediate tensor data across operations

  • +
  • dla_global_dram_size (python:int) – Host RAM used by DLA to store weights and metadata for execution

  • +
  • output_format (str) – Output format of the result of TRT compilation. Options include “exported_program” (or) “ep” | “torchscript” (or) “ts” | “graph_module” (or) “fx”. Default is “exported_program”

  • +
+
+
+
+ +
+
+class torch_tensorrt.dynamo.SourceIR(value)[source]
+

An enumeration.

+
+ +
+
+ + +
+ +
+ + +
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/py_api/fx.html b/docs/v2.2.0/py_api/fx.html new file mode 100644 index 0000000000..97a11a46e6 --- /dev/null +++ b/docs/v2.2.0/py_api/fx.html @@ -0,0 +1,831 @@ + + + + + + + + + + + + + torch_tensorrt.fx — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

torch_tensorrt.fx

+
+

Functions

+
+
+torch_tensorrt.fx.compile(module: Module, input, min_acc_module_size: int = 10, max_batch_size: int = 2048, max_workspace_size=33554432, explicit_batch_dimension=False, lower_precision=LowerPrecision.FP16, verbose_log=False, timing_cache_prefix='', save_timing_cache=False, cuda_graph_batch_size=- 1, dynamic_batch=True, is_aten=False, use_experimental_fx_rt=False, correctness_atol=0.1, correctness_rtol=0.1) Module[source]
+

Takes in original module, input and lowering setting, run lowering workflow to turn module +into lowered module, or so called TRTModule.

+
+
Parameters
+
    +
  • module – Original module for lowering.

  • +
  • input – Input for module.

  • +
  • max_batch_size – Maximum batch size (must be >= 1 to be set, 0 means not set)

  • +
  • min_acc_module_size – Minimal number of nodes for an accelerated submodule

  • +
  • max_workspace_size – Maximum size of workspace given to TensorRT.

  • +
  • explicit_batch_dimension – Use explicit batch dimension in TensorRT if set True, otherwise use implicit batch dimension.

  • +
  • lower_precision – lower_precision config given to TRTModule.

  • +
  • verbose_log – Enable verbose log for TensorRT if set True.

  • +
  • timing_cache_prefix – Timing cache file name for timing cache used by fx2trt.

  • +
  • save_timing_cache – Update timing cache with current timing cache data if set to True.

  • +
  • cuda_graph_batch_size – Cuda graph batch size, default to be -1.

  • +
  • dynamic_batch – batch dimension (dim=0) is dynamic.

  • +
  • use_experimental_fx_rt – Uses the next generation TRTModule which supports both Python and TorchScript based execution (including in C++).

  • +
+
+
Returns
+

A torch.nn.Module lowered by TensorRT.

+
+
+
+ +
+
+

Classes

+
+
+class torch_tensorrt.fx.TRTModule(engine=None, input_names=None, output_names=None, cuda_graph_batch_size=- 1)[source]
+
+ +
+
+class torch_tensorrt.fx.InputTensorSpec(shape: Sequence[int], dtype: dtype, device: device = device(type='cpu'), shape_ranges: List[Tuple[Sequence[int], Sequence[int], Sequence[int]]] = [], has_batch_dim: bool = True)[source]
+

This class contains the information of a input tensor.

+

shape: shape of the tensor.

+

dtype: dtyep of the tensor.

+
+
device: device of the tensor. This is only used to generate inputs to the given model

in order to run shape prop. For TensorRT engine, inputs have to be on cuda device.

+
+
shape_ranges: If dynamic shape is needed (shape has dimensions of -1), then this field

has to be provided (default is empty list). Every shape_range is a tuple of three +tuples ((min_input_shape), (optimized_input_shape), (max_input_shape)). Each shape_range +is used to populate a TensorRT optimization profile. +e.g. If the input shape varies from (1, 224) to (100, 224) and we want to optimize +for (25, 224) because it’s the most common input shape, then we set shape_ranges to +((1, 224), (25, 225), (100, 224)).

+
+
has_batch_dim: Whether the shape includes batch dimension. Batch dimension has to be provided

if the engine want to run with dynamic shape.

+
+
+
+ +
+
+class torch_tensorrt.fx.TRTInterpreter(module: GraphModule, input_specs: List[InputTensorSpec], explicit_batch_dimension: bool = False, explicit_precision: bool = False, logger_level=None)[source]
+
+ +
+
+class torch_tensorrt.fx.TRTInterpreterResult(engine, input_names, output_names, serialized_cache)[source]
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/py_api/logging.html b/docs/v2.2.0/py_api/logging.html new file mode 100644 index 0000000000..c24f11d155 --- /dev/null +++ b/docs/v2.2.0/py_api/logging.html @@ -0,0 +1,957 @@ + + + + + + + + + + + + + torch_tensorrt.logging — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

torch_tensorrt.logging

+
+
+class torch_tensorrt.logging.Level(value)[source]
+

Bases: Enum

+

Enum to set the minimum required logging level to print a message to stdout

+
+
+Debug = <LogLevel.DEBUG: 4>
+
+ +
+
+Error = <LogLevel.ERROR: 1>
+
+ +
+
+Graph = <LogLevel.GRAPH: 5>
+
+ +
+
+Info = <LogLevel.INFO: 3>
+
+ +
+
+InternalError = <LogLevel.INTERNAL_ERROR: 0>
+
+ +
+
+Warning = <LogLevel.WARNING: 2>
+
+ +
+ +
+
+class torch_tensorrt.logging.debug[source]
+

Bases: object

+

Context-manager to display full debug information through the logger

+

Example:

+
+
with torch_tensorrt.logging.debug():

model_trt = torch_tensorrt.compile(model, **spec)

+
+
+
+ +
+
+class torch_tensorrt.logging.errors[source]
+

Bases: object

+

Context-manager to limit displayed log messages to just errors and above

+

Example:

+
+
with torch_tensorrt.logging.errors():

outputs = model_torchtrt(inputs)

+
+
+
+ +
+
+torch_tensorrt.logging.get_is_colored_output_on() bool[source]
+

Get if colored output is enabled for logging

+
+
Returns
+

If colored output is one

+
+
Return type
+

bool

+
+
+
+ +
+
+torch_tensorrt.logging.get_logging_prefix() str[source]
+

Get the prefix set for logging messages

+
+
Returns
+

Prefix used for logger

+
+
Return type
+

str

+
+
+
+ +
+
+torch_tensorrt.logging.get_reportable_log_level() Level[source]
+

Get the level required for a message to be printed in the log

+
+
Returns
+

The enum representing the level required to print

+
+
Return type
+

Level

+
+
+
+ +
+
+class torch_tensorrt.logging.graphs[source]
+

Bases: object

+

Context-manager to display the results of intermediate lowering passes +as well as full debug information through the logger

+

Example:

+
+
with torch_tensorrt.logging.graphs():

model_trt = torch_tensorrt.compile(model, **spec)

+
+
+
+ +
+
+class torch_tensorrt.logging.info[source]
+

Bases: object

+

Context-manager to display all info and greater severity messages

+

Example:

+
+
with torch_tensorrt.logging.info():

model_trt = torch_tensorrt.compile(model, **spec)

+
+
+
+ +
+
+class torch_tensorrt.logging.internal_errors[source]
+

Bases: object

+

Context-manager to limit displayed log messages to just internal errors

+

Example:

+
+
with torch_tensorrt.logging.internal_errors():

outputs = model_torchtrt(inputs)

+
+
+
+ +
+
+torch_tensorrt.logging.log(level: Level, msg: str) None[source]
+

Add a new message to the log

+

Adds a new message to the log at a specified level. The message +will only get printed out if Level > reportable_log_level

+
+
Parameters
+
    +
  • level (Level) – Severity of the message

  • +
  • msg (str) – Actual message text

  • +
+
+
+
+ +
+
+torch_tensorrt.logging.set_is_colored_output_on(colored_output_on: bool) None[source]
+

Enable or disable color in the log output

+
+
Parameters
+

colored_output_on (bool) – If colored output should be enabled or not

+
+
+
+ +
+
+torch_tensorrt.logging.set_logging_prefix(prefix: str) None[source]
+

Set the prefix used when logging messages

+
+
Parameters
+

prefix (str) – Prefix to use for logging messages

+
+
+
+ +
+
+torch_tensorrt.logging.set_reportable_log_level(level: Level) None[source]
+

Set the level required for a message to be printed to the log

+
+
Parameters
+

level (Level) – The enum representing the level required to print

+
+
+
+ +
+
+class torch_tensorrt.logging.warnings[source]
+

Bases: object

+

Context-manager to limit displayed log messages to just warnings and above

+

Example:

+
+
with torch_tensorrt.logging.warnings():

model_trt = torch_tensorrt.compile(model, **spec)

+
+
+
+ +
+ + +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/py_api/ptq.html b/docs/v2.2.0/py_api/ptq.html new file mode 100644 index 0000000000..8654c1cd7e --- /dev/null +++ b/docs/v2.2.0/py_api/ptq.html @@ -0,0 +1,876 @@ + + + + + + + + + + + + + torch_tensorrt.ptq — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

torch_tensorrt.ptq

+
+
+class torch_tensorrt.ptq.CacheCalibrator(*args: Any, **kwargs: Any)[source]
+

Bases: object

+

Constructs a calibrator class in TensorRT which directly uses pre-existing cache file for calibration. +:param cache_file: path to cache file. +:param algo_type: choice of calibration algorithm.

+
+ +
+
+class torch_tensorrt.ptq.CalibrationAlgo(value)[source]
+

Bases: Enum

+

An enumeration.

+
+
+ENTROPY_CALIBRATION = <CalibrationAlgo.ENTROPY_CALIBRATION: 1>
+
+ +
+
+ENTROPY_CALIBRATION_2 = <CalibrationAlgo.ENTROPY_CALIBRATION_2: 2>
+
+ +
+
+LEGACY_CALIBRATION = <CalibrationAlgo.LEGACY_CALIBRATION: 0>
+
+ +
+
+MINMAX_CALIBRATION = <CalibrationAlgo.MINMAX_CALIBRATION: 3>
+
+ +
+ +
+
+class torch_tensorrt.ptq.DataLoaderCalibrator(*args: Any, **kwargs: Any)[source]
+

Bases: object

+

Constructs a calibrator class in TensorRT and uses pytorch dataloader to load/preproces +data which is passed during calibration. +:param dataloader: an instance of pytorch dataloader which iterates through a given dataset. +:param algo_type: choice of calibration algorithm. +:param cache_file: path to cache file. +:param use_cache: flag which enables usage of pre-existing cache. +:param device: device on which calibration data is copied to.

+
+ +
+
+torch_tensorrt.ptq.get_batch(self: object, _: Any) Optional[List[int]][source]
+
+ +
+
+torch_tensorrt.ptq.get_batch_size(self: object) int[source]
+
+ +
+
+torch_tensorrt.ptq.get_cache_mode_batch(self: object) None[source]
+
+ +
+
+torch_tensorrt.ptq.read_calibration_cache(self: object) bytes[source]
+
+ +
+
+torch_tensorrt.ptq.write_calibration_cache(self: object, cache: bytes) None[source]
+
+ +
+

Classes

+
+
+class torch_tensorrt.ptq.DataLoaderCalibrator(*args: Any, **kwargs: Any)[source]
+

Constructs a calibrator class in TensorRT and uses pytorch dataloader to load/preproces +data which is passed during calibration. +:param dataloader: an instance of pytorch dataloader which iterates through a given dataset. +:param algo_type: choice of calibration algorithm. +:param cache_file: path to cache file. +:param use_cache: flag which enables usage of pre-existing cache. +:param device: device on which calibration data is copied to.

+
+
+__init__(**kwargs: Any)[source]
+
+ +
+ +
+
+class torch_tensorrt.ptq.CacheCalibrator(*args: Any, **kwargs: Any)[source]
+

Constructs a calibrator class in TensorRT which directly uses pre-existing cache file for calibration. +:param cache_file: path to cache file. +:param algo_type: choice of calibration algorithm.

+
+
+__init__(**kwargs: Any)[source]
+
+ +
+ +
+
+

Enums

+
+
+class torch_tensorrt.ptq.CalibrationAlgo(value)[source]
+

An enumeration.

+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/py_api/torch_tensorrt.html b/docs/v2.2.0/py_api/torch_tensorrt.html new file mode 100644 index 0000000000..8f0d32dcdf --- /dev/null +++ b/docs/v2.2.0/py_api/torch_tensorrt.html @@ -0,0 +1,1135 @@ + + + + + + + + + + + + + torch_tensorrt — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

torch_tensorrt

+
+

Functions

+
+
+torch_tensorrt.set_device(gpu_id: int) None[source]
+
+ +
+
+torch_tensorrt.compile(module: Any, ir: str = 'default', inputs: Optional[Sequence[Input | torch.Tensor | InputTensorSpec]] = None, enabled_precisions: Optional[Set[torch.dtype | dtype]] = None, **kwargs: Any) Union[Module, ScriptModule, GraphModule, Callable[[...], Any]][source]
+

Compile a PyTorch module for NVIDIA GPUs using TensorRT

+

Takes a existing PyTorch module and a set of settings to configure the compiler +and using the path specified in ir lower and compile the module to TensorRT +returning a PyTorch Module back

+

Converts specifically the forward method of a Module

+
+
Parameters
+

module (Union(torch.nn.Module,torch.jit.ScriptModule) – Source module

+
+
Keyword Arguments
+
    +
  • inputs (List[Union(Input, torch.Tensor)]) –

    Required List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using +torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum +to select device type.

    +
    input=[
    +    torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1
    +    torch_tensorrt.Input(
    +        min_shape=(1, 224, 224, 3),
    +        opt_shape=(1, 512, 512, 3),
    +        max_shape=(1, 1024, 1024, 3),
    +        dtype=torch.int32
    +        format=torch.channel_last
    +    ), # Dynamic input shape for input #2
    +    torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings
    +]
    +
    +
    +

  • +
  • enabled_precision (Set(Union(torch.dpython:type, torch_tensorrt.dpython:type))) – The set of datatypes that TensorRT can use when selecting kernels

  • +
  • ir (str) – The requested strategy to compile. (Options: default - Let Torch-TensorRT decide, ts - TorchScript with scripting path)

  • +
  • **kwargs – Additional settings for the specific requested strategy (See submodules for more info)

  • +
+
+
Returns
+

Compiled Module, when run it will execute via TensorRT

+
+
Return type
+

torch.nn.Module

+
+
+
+ +
+
+torch_tensorrt.convert_method_to_trt_engine(module: Any, method_name: str = 'forward', inputs: Optional[Sequence[Input | torch.Tensor]] = None, ir: str = 'default', enabled_precisions: Optional[Set[torch.dtype | dtype]] = None, **kwargs: Any) bytes[source]
+

Convert a TorchScript module method to a serialized TensorRT engine

+

Converts a specified method of a module to a serialized TensorRT engine given a dictionary of conversion settings

+
+
Parameters
+

module (Union(torch.nn.Module,torch.jit.ScriptModule) – Source module

+
+
Keyword Arguments
+
    +
  • inputs (List[Union(Input, torch.Tensor)]) –

    Required List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using +torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum +to select device type.

    +
    input=[
    +    torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1
    +    torch_tensorrt.Input(
    +        min_shape=(1, 224, 224, 3),
    +        opt_shape=(1, 512, 512, 3),
    +        max_shape=(1, 1024, 1024, 3),
    +        dtype=torch.int32
    +        format=torch.channel_last
    +    ), # Dynamic input shape for input #2
    +    torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings
    +]
    +
    +
    +

  • +
  • enabled_precision (Set(Union(torch.dpython:type, torch_tensorrt.dpython:type))) – The set of datatypes that TensorRT can use when selecting kernels

  • +
  • ir (str) – The requested strategy to compile. (Options: default - Let Torch-TensorRT decide, ts - TorchScript with scripting path)

  • +
  • **kwargs – Additional settings for the specific requested strategy (See submodules for more info)

  • +
+
+
Returns
+

Serialized TensorRT engine, can either be saved to a file or deserialized via TensorRT APIs

+
+
Return type
+

bytes

+
+
+
+ +
+
+torch_tensorrt.get_build_info() str[source]
+

Returns a string containing the build information of torch_tensorrt distribution

+
+
Returns
+

String containing the build information for torch_tensorrt distribution

+
+
Return type
+

str

+
+
+
+ +
+
+torch_tensorrt.dump_build_info() None[source]
+

Prints build information about the torch_tensorrt distribution to stdout

+
+ +
+
+

Classes

+
+
+class torch_tensorrt.Input(*args: Any, **kwargs: Any)[source]
+

Defines an input to a module in terms of expected shape, data type and tensor format.

+
+
Variables
+
    +
  • shape_mode (torch_tensorrt.Input._ShapeMode) – Is input statically or dynamically shaped

  • +
  • shape (Tuple or Dict) –

    Either a single Tuple or a dict of tuples defining the input shape. +Static shaped inputs will have a single tuple. Dynamic inputs will have a dict of the form +``{

    +
    +

    ”min_shape”: Tuple, +“opt_shape”: Tuple, +“max_shape”: Tuple

    +
    +

    }``

    +

  • +
  • dtype (torch_tensorrt.dpython:type) – The expected data type of the input tensor (default: torch_tensorrt.dtype.float32)

  • +
  • format (TensorFormat) – The expected format of the input tensor (default: torch_tensorrt.TensorFormat.NCHW)

  • +
+
+
+
+
+__init__(*args: Any, **kwargs: Any) None[source]
+

__init__ Method for torch_tensorrt.Input

+

Input accepts one of a few construction patterns

+
+
Parameters
+

shape (Tuple or List, optional) – Static shape of input tensor

+
+
Keyword Arguments
+
    +
  • shape (Tuple or List, optional) – Static shape of input tensor

  • +
  • min_shape (Tuple or List, optional) – Min size of input tensor’s shape range +Note: All three of min_shape, opt_shape, max_shape must be provided, there must be no positional arguments, shape must not be defined and implictly this sets Input’s shape_mode to DYNAMIC

  • +
  • opt_shape (Tuple or List, optional) – Opt size of input tensor’s shape range +Note: All three of min_shape, opt_shape, max_shape must be provided, there must be no positional arguments, shape must not be defined and implictly this sets Input’s shape_mode to DYNAMIC

  • +
  • max_shape (Tuple or List, optional) – Max size of input tensor’s shape range +Note: All three of min_shape, opt_shape, max_shape must be provided, there must be no positional arguments, shape must not be defined and implictly this sets Input’s shape_mode to DYNAMIC

  • +
  • dtype (torch.dpython:type or torch_tensorrt.dpython:type) – Expected data type for input tensor (default: torch_tensorrt.dtype.float32)

  • +
  • format (torch.memory_format or TensorFormat) – The expected format of the input tensor (default: torch_tensorrt.TensorFormat.NCHW)

  • +
  • tensor_domain (Tuple(python:float, python:float), optional) – The domain of allowed values for the tensor, as interval notation: [tensor_domain[0], tensor_domain[1]). +Note: Entering “None” (or not specifying) will set the bound to [0, 2)

  • +
  • torch_tensor (torch.Tensor) – Holds a corresponding torch tensor with this Input.

  • +
  • name (str, optional) – Name of this input in the input nn.Module’s forward function. Used to specify dynamic shapes for the corresponding input in dynamo tracer.

  • +
+
+
+

Examples

+
    +
  • Input([1,3,32,32], dtype=torch.float32, format=torch.channel_last)

  • +
  • Input(shape=(1,3,32,32), dtype=torch_tensorrt.dtype.int32, format=torch_tensorrt.TensorFormat.NCHW)

  • +
  • Input(min_shape=(1,3,32,32), opt_shape=[2,3,32,32], max_shape=(3,3,32,32)) #Implicitly dtype=torch_tensorrt.dtype.float32, format=torch_tensorrt.TensorFormat.NCHW

  • +
+
+ +
+
+dtype: _enums.dtype = <dtype.unknown: 7>
+

torch_tensorrt.dtype.float32)

+
+
Type
+

The expected data type of the input tensor (default

+
+
+
+ +
+
+example_tensor(optimization_profile_field: Optional[str] = None) Tensor[source]
+

Get an example tensor of the shape specified by the Input object

+
+
Parameters
+

optimization_profile_field (Optional(str)) – Name of the field to use for shape in the case the Input is dynamically shaped

+
+
Returns
+

A PyTorch Tensor

+
+
+
+ +
+
+format: _enums.TensorFormat = <TensorFormat.contiguous: 0>
+

torch_tensorrt.TensorFormat.NCHW)

+
+
Type
+

The expected format of the input tensor (default

+
+
+
+ +
+
+classmethod from_tensor(t: Tensor, disable_memory_format_check: bool = False) Input[source]
+

Produce a Input which contains the information of the given PyTorch tensor.

+
+
Parameters
+
    +
  • tensor (torch.Tensor) – A PyTorch tensor.

  • +
  • disable_memory_format_check (bool) – Whether to validate the memory formats of input tensors

  • +
+
+
Returns
+

A Input object.

+
+
+
+ +
+
+classmethod from_tensors(ts: Sequence[Tensor], disable_memory_format_check: bool = False) List[Input][source]
+

Produce a list of Inputs which contain +the information of all the given PyTorch tensors.

+
+
Parameters
+
    +
  • tensors (Iterable[torch.Tensor]) – A list of PyTorch tensors.

  • +
  • disable_memory_format_check (bool) – Whether to validate the memory formats of input tensors

  • +
+
+
Returns
+

A list of Inputs.

+
+
+
+ +
+ +
+
+class torch_tensorrt.Device(*args: Any, **kwargs: Any)[source]
+

Defines a device that can be used to specify target devices for engines

+
+
Variables
+
    +
  • device_type (DeviceType) – Target device type (GPU or DLA). Set implicitly based on if dla_core is specified.

  • +
  • gpu_id (python:int) – Device ID for target GPU

  • +
  • dla_core (python:int) – Core ID for target DLA core

  • +
  • allow_gpu_fallback (bool) – Whether falling back to GPU if DLA cannot support an op should be allowed

  • +
+
+
+
+
+__init__(*args: Any, **kwargs: Any)[source]
+

__init__ Method for torch_tensorrt.Device

+

Device accepts one of a few construction patterns

+
+
Parameters
+

spec (str) – String with device spec e.g. “dla:0” for dla, core_id 0

+
+
Keyword Arguments
+
    +
  • gpu_id (python:int) – ID of target GPU (will get overrided if dla_core is specified to the GPU managing DLA). If specified, no positional arguments should be provided

  • +
  • dla_core (python:int) – ID of target DLA core. If specified, no positional arguments should be provided.

  • +
  • allow_gpu_fallback (bool) – Allow TensorRT to schedule operations on GPU if they are not supported on DLA (ignored if device type is not DLA)

  • +
+
+
+

Examples

+
    +
  • Device(“gpu:1”)

  • +
  • Device(“cuda:1”)

  • +
  • Device(“dla:0”, allow_gpu_fallback=True)

  • +
  • Device(gpu_id=0, dla_core=0, allow_gpu_fallback=True)

  • +
  • Device(dla_core=0, allow_gpu_fallback=True)

  • +
  • Device(gpu_id=1)

  • +
+
+ +
+
+dla_core: int = -1
+

Core ID for target DLA core

+
+ +
+
+gpu_id: int = -1
+

Device ID for target GPU

+
+ +
+ +
+
+

Enums

+
+
+class torch_tensorrt.dtype
+

Enum to specifiy operating precision for engine execution

+

Members:

+
+

float : 32 bit floating point number

+

float32 : 32 bit floating point number

+

half : 16 bit floating point number

+

float16 : 16 bit floating point number

+

int8 : 8 bit integer number

+

int32 : 32 bit integer number

+

long : 64 bit integer number

+

int64 : 64 bit integer number

+

double : 64 bit floating point number

+

float64 : 64 bit floating point number

+

bool : Boolean value

+

unknown : Unknown data type

+
+
+ +
+
+class torch_tensorrt.DeviceType
+

Device types that TensorRT can execute on

+

Members:

+
+

GPU : GPU device

+

DLA : DLA core

+
+
+ +
+
+class torch_tensorrt.EngineCapability
+

Enum to specify engine capability settings (selections of kernels to meet safety requirements)

+

Members:

+
+

safe_gpu : Use safety GPU kernels only

+

safe_dla : Use safety DLA kernels only

+

default : Use default behavior

+
+
+ +
+
+class torch_tensorrt.TensorFormat
+

Enum to specifiy the memory layout of tensors

+

Members:

+
+

contiguous : Contiguous memory layout (NCHW / Linear)

+

channels_last : Channels last memory layout (NHWC)

+
+
+ +
+
+

Submodules

+ +
+
+ + +
+ +
+ + +
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/py_api/ts.html b/docs/v2.2.0/py_api/ts.html new file mode 100644 index 0000000000..9d9fe5f755 --- /dev/null +++ b/docs/v2.2.0/py_api/ts.html @@ -0,0 +1,1028 @@ + + + + + + + + + + + + + torch_tensorrt.ts — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

torch_tensorrt.ts

+
+

Functions

+
+
+torch_tensorrt.ts.compile(module: ~torch.jit._script.ScriptModule, inputs: ~typing.Optional[~typing.Sequence[torch_tensorrt._Input.Input | torch.Tensor]] = None, input_signature: ~typing.Optional[~typing.Tuple[~typing.Union[~torch_tensorrt._Input.Input, ~torch.Tensor, ~typing.Sequence[~typing.Any]]]] = None, device: ~torch_tensorrt._Device.Device = Device(type=DeviceType.GPU, gpu_id=0), disable_tf32: bool = False, sparse_weights: bool = False, enabled_precisions: ~typing.Optional[~typing.Set[torch.dtype | torch_tensorrt._C.dtype]] = None, refit: bool = False, debug: bool = False, capability: ~torch_tensorrt._C.EngineCapability = <EngineCapability.default: 0>, num_avg_timing_iters: int = 1, workspace_size: int = 0, dla_sram_size: int = 1048576, dla_local_dram_size: int = 1073741824, dla_global_dram_size: int = 536870912, calibrator: ~typing.Optional[object] = None, truncate_long_and_double: bool = False, require_full_compilation: bool = False, min_block_size: int = 3, torch_executed_ops: ~typing.Optional[~typing.List[str]] = None, torch_executed_modules: ~typing.Optional[~typing.List[str]] = None, allow_shape_tensors: bool = False) ScriptModule[source]
+

Compile a TorchScript module for NVIDIA GPUs using TensorRT

+

Takes a existing TorchScript module and a set of settings to configure the compiler +and will convert methods to JIT Graphs which call equivalent TensorRT engines

+

Converts specifically the forward method of a TorchScript Module

+
+
Parameters
+

module (torch.jit.ScriptModule) – Source module, a result of tracing or scripting a PyTorch +torch.nn.Module

+
+
Keyword Arguments
+
    +
  • inputs (List[Union(Input, torch.Tensor)]) –

    Required List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using +torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum +to select device type.

    +
    input=[
    +    torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1
    +    torch_tensorrt.Input(
    +        min_shape=(1, 224, 224, 3),
    +        opt_shape=(1, 512, 512, 3),
    +        max_shape=(1, 1024, 1024, 3),
    +        dtype=torch.int32
    +        format=torch.channel_last
    +    ), # Dynamic input shape for input #2
    +    torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings
    +]
    +
    +
    +

  • +
  • Union (input_signature) –

    A formatted collection of input specifications for the module. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using +torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum to select device type. This API should be considered beta-level stable and may change in the future

    +
    input_signature=([
    +    torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1
    +    torch_tensorrt.Input(
    +        min_shape=(1, 224, 224, 3),
    +        opt_shape=(1, 512, 512, 3),
    +        max_shape=(1, 1024, 1024, 3),
    +        dtype=torch.int32
    +        format=torch.channel_last
    +    ), # Dynamic input shape for input #2
    +], torch.randn((1, 3, 224, 244))) # Use an example tensor and let torch_tensorrt infer settings for input #3
    +
    +
    +

  • +
  • device (Union(Device, torch.device, dict)) –

    Target device for TensorRT engines to run on

    +
    device=torch_tensorrt.Device("dla:1", allow_gpu_fallback=True)
    +
    +
    +

  • +
  • disable_tf32 (bool) – Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas

  • +
  • sparse_weights (bool) – Enable sparsity for convolution and fully connected layers.

  • +
  • enabled_precision (Set(Union(torch.dpython:type, torch_tensorrt.dpython:type))) – The set of datatypes that TensorRT can use when selecting kernels

  • +
  • refit (bool) – Enable refitting

  • +
  • debug (bool) – Enable debuggable engine

  • +
  • capability (EngineCapability) – Restrict kernel selection to safe gpu kernels or safe dla kernels

  • +
  • num_avg_timing_iters (python:int) – Number of averaging timing iterations used to select kernels

  • +
  • workspace_size (python:int) – Maximum size of workspace given to TensorRT

  • +
  • dla_sram_size (python:int) – Fast software managed RAM used by DLA to communicate within a layer.

  • +
  • dla_local_dram_size (python:int) – Host RAM used by DLA to share intermediate tensor data across operations

  • +
  • dla_global_dram_size (python:int) – Host RAM used by DLA to store weights and metadata for execution

  • +
  • truncate_long_and_double (bool) – Truncate weights provided in int64 or double (float64) to int32 and float32

  • +
  • calibrator (Union(torch_tensorrt._C.IInt8Calibrator, tensorrt.IInt8Calibrator)) – Calibrator object which will provide data to the PTQ system for INT8 Calibration

  • +
  • require_full_compilation (bool) – Require modules to be compiled end to end or return an error as opposed to returning a hybrid graph where operations that cannot be run in TensorRT are run in PyTorch

  • +
  • min_block_size (python:int) – The minimum number of contiguous TensorRT convertable operations in order to run a set of operations in TensorRT

  • +
  • torch_executed_ops (List[str]) – List of aten operators that must be run in PyTorch. An error will be thrown if this list is not empty but require_full_compilation is True

  • +
  • torch_executed_modules (List[str]) – List of modules that must be run in PyTorch. An error will be thrown if this list is not empty but require_full_compilation is True

  • +
  • allow_shape_tensors – (Experimental) Allow aten::size to output shape tensors using IShapeLayer in TensorRT

  • +
+
+
Returns
+

Compiled TorchScript Module, when run it will execute via TensorRT

+
+
Return type
+

torch.jit.ScriptModule

+
+
+
+ +
+
+torch_tensorrt.ts.convert_method_to_trt_engine(module: ~torch.jit._script.ScriptModule, method_name: str = 'forward', inputs: ~typing.Optional[~typing.Sequence[torch_tensorrt._Input.Input | torch.Tensor]] = None, device: ~torch_tensorrt._Device.Device = Device(type=DeviceType.GPU, gpu_id=0), disable_tf32: bool = False, sparse_weights: bool = False, enabled_precisions: ~typing.Optional[~typing.Set[torch.dtype | torch_tensorrt._C.dtype]] = None, refit: bool = False, debug: bool = False, capability: ~torch_tensorrt._C.EngineCapability = <EngineCapability.default: 0>, num_avg_timing_iters: int = 1, workspace_size: int = 0, dla_sram_size: int = 1048576, dla_local_dram_size: int = 1073741824, dla_global_dram_size: int = 536870912, truncate_long_and_double: int = False, calibrator: ~typing.Optional[object] = None, allow_shape_tensors: bool = False) bytes[source]
+

Convert a TorchScript module method to a serialized TensorRT engine

+

Converts a specified method of a module to a serialized TensorRT engine given a dictionary of conversion settings

+
+
Parameters
+

module (torch.jit.ScriptModule) – Source module, a result of tracing or scripting a PyTorch +torch.nn.Module

+
+
Keyword Arguments
+
    +
  • inputs (List[Union(Input, torch.Tensor)]) –

    Required List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using +torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum +to select device type.

    +
    input=[
    +    torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1
    +    torch_tensorrt.Input(
    +        min_shape=(1, 224, 224, 3),
    +        opt_shape=(1, 512, 512, 3),
    +        max_shape=(1, 1024, 1024, 3),
    +        dtype=torch.int32
    +        format=torch.channel_last
    +    ), # Dynamic input shape for input #2
    +    torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings
    +]
    +
    +
    +

  • +
  • method_name (str) – Name of method to convert

  • +
  • Union (input_signature) –

    A formatted collection of input specifications for the module. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using +torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum to select device type. This API should be considered beta-level stable and may change in the future

    +
    input_signature=([
    +    torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1
    +    torch_tensorrt.Input(
    +        min_shape=(1, 224, 224, 3),
    +        opt_shape=(1, 512, 512, 3),
    +        max_shape=(1, 1024, 1024, 3),
    +        dtype=torch.int32
    +        format=torch.channel_last
    +    ), # Dynamic input shape for input #2
    +], torch.randn((1, 3, 224, 244))) # Use an example tensor and let torch_tensorrt infer settings for input #3
    +
    +
    +

  • +
  • device (Union(Device, torch.device, dict)) –

    Target device for TensorRT engines to run on

    +
    device=torch_tensorrt.Device("dla:1", allow_gpu_fallback=True)
    +
    +
    +

  • +
  • disable_tf32 (bool) – Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas

  • +
  • sparse_weights (bool) – Enable sparsity for convolution and fully connected layers.

  • +
  • enabled_precision (Set(Union(torch.dpython:type, torch_tensorrt.dpython:type))) – The set of datatypes that TensorRT can use when selecting kernels

  • +
  • refit (bool) – Enable refitting

  • +
  • debug (bool) – Enable debuggable engine

  • +
  • capability (EngineCapability) – Restrict kernel selection to safe gpu kernels or safe dla kernels

  • +
  • num_avg_timing_iters (python:int) – Number of averaging timing iterations used to select kernels

  • +
  • workspace_size (python:int) – Maximum size of workspace given to TensorRT

  • +
  • dla_sram_size (python:int) – Fast software managed RAM used by DLA to communicate within a layer.

  • +
  • dla_local_dram_size (python:int) – Host RAM used by DLA to share intermediate tensor data across operations

  • +
  • dla_global_dram_size (python:int) – Host RAM used by DLA to store weights and metadata for execution

  • +
  • truncate_long_and_double (bool) – Truncate weights provided in int64 or double (float64) to int32 and float32

  • +
  • calibrator (Union(torch_tensorrt._C.IInt8Calibrator, tensorrt.IInt8Calibrator)) – Calibrator object which will provide data to the PTQ system for INT8 Calibration

  • +
  • allow_shape_tensors – (Experimental) Allow aten::size to output shape tensors using IShapeLayer in TensorRT

  • +
+
+
Returns
+

Serialized TensorRT engine, can either be saved to a file or deserialized via TensorRT APIs

+
+
Return type
+

bytes

+
+
+
+ +
+
+torch_tensorrt.ts.check_method_op_support(module: ScriptModule, method_name: str = 'forward') bool[source]
+

Checks to see if a method is fully supported by torch_tensorrt

+

Checks if a method of a TorchScript module can be compiled by torch_tensorrt, if not, a list of operators +that are not supported are printed out and the function returns false, else true.

+
+
Parameters
+
    +
  • module (torch.jit.ScriptModule) – Source module, a result of tracing or scripting a PyTorch +torch.nn.Module

  • +
  • method_name (str) – Name of method to check

  • +
+
+
Returns
+

True if supported Method

+
+
Return type
+

bool

+
+
+
+ +
+
+torch_tensorrt.ts.embed_engine_in_new_module(serialized_engine: bytes, input_binding_names: Optional[List[str]] = None, output_binding_names: Optional[List[str]] = None, device: Device = Device(type=DeviceType.GPU, gpu_id=0)) ScriptModule[source]
+

Takes a pre-built serialized TensorRT engine and embeds it within a TorchScript module

+

Takes a pre-built serialied TensorRT engine (as bytes) and embeds it within a TorchScript module. +Registers the forward method to execute the TensorRT engine with the function signature:

+
+

forward(Tensor[]) -> Tensor[]

+
+
+
TensorRT bindings either be explicitly specified using [in/out]put_binding_names or have names with the following format:
    +
  • [symbol].[index in input / output array]

  • +
+

ex. +- [x.0, x.1, x.2] -> [y.0]

+
+
+

Module can be save with engine embedded with torch.jit.save and moved / loaded according to torch_tensorrt portability rules

+
+
Parameters
+

serialized_engine (bytearray) – Serialized TensorRT engine from either torch_tensorrt or TensorRT APIs

+
+
Keyword Arguments
+
    +
  • input_binding_names (List[str]) – List of names of TensorRT bindings in order to be passed to the encompassing PyTorch module

  • +
  • output_binding_names (List[str]) – List of names of TensorRT bindings in order that should be returned from the encompassing PyTorch module

  • +
  • device (Union(Device, torch.device, dict)) – Target device to run engine on. Must be compatible with engine provided. Default: Current active device

  • +
+
+
Returns
+

New TorchScript module with engine embedded

+
+
Return type
+

torch.jit.ScriptModule

+
+
+
+ +
+
+torch_tensorrt.ts.TensorRTCompileSpec(inputs: ~typing.Optional[~typing.List[torch.Tensor | torch_tensorrt._Input.Input]] = None, input_signature: ~typing.Optional[~typing.Any] = None, device: torch.device | torch_tensorrt._Device.Device = Device(type=DeviceType.GPU, gpu_id=0), disable_tf32: bool = False, sparse_weights: bool = False, enabled_precisions: ~typing.Optional[~typing.Set[torch.dtype | torch_tensorrt._C.dtype]] = None, refit: bool = False, debug: bool = False, capability: ~torch_tensorrt._C.EngineCapability = <EngineCapability.default: 0>, num_avg_timing_iters: int = 1, workspace_size: int = 0, dla_sram_size: int = 1048576, dla_local_dram_size: int = 1073741824, dla_global_dram_size: int = 536870912, truncate_long_and_double: bool = False, calibrator: ~typing.Optional[object] = None, allow_shape_tensors: bool = False) <torch.ScriptClass object at 0x7fb370651af0>[source]
+

Utility to create a formated spec dictionary for using the PyTorch TensorRT backend

+
+
Keyword Arguments
+
    +
  • inputs (List[Union(Input, torch.Tensor)]) –

    Required List of specifications of input shape, dtype and memory layout for inputs to the module. This argument is required. Input Sizes can be specified as torch sizes, tuples or lists. dtypes can be specified using +torch datatypes or torch_tensorrt datatypes and you can use either torch devices or the torch_tensorrt device type enum +to select device type.

    +
    input=[
    +    torch_tensorrt.Input((1, 3, 224, 224)), # Static NCHW input shape for input #1
    +    torch_tensorrt.Input(
    +        min_shape=(1, 224, 224, 3),
    +        opt_shape=(1, 512, 512, 3),
    +        max_shape=(1, 1024, 1024, 3),
    +        dtype=torch.int32
    +        format=torch.channel_last
    +    ), # Dynamic input shape for input #2
    +    torch.randn((1, 3, 224, 244)) # Use an example tensor and let torch_tensorrt infer settings
    +]
    +
    +
    +

  • +
  • device (Union(Device, torch.device, dict)) –

    Target device for TensorRT engines to run on

    +
    device=torch_tensorrt.Device("dla:1", allow_gpu_fallback=True)
    +
    +
    +

  • +
  • disable_tf32 (bool) – Force FP32 layers to use traditional as FP32 format vs the default behavior of rounding the inputs to 10-bit mantissas before multiplying, but accumulates the sum using 23-bit mantissas

  • +
  • sparse_weights (bool) – Enable sparsity for convolution and fully connected layers.

  • +
  • enabled_precision (Set(Union(torch.dpython:type, torch_tensorrt.dpython:type))) – The set of datatypes that TensorRT can use when selecting kernels

  • +
  • refit (bool) – Enable refitting

  • +
  • debug (bool) – Enable debuggable engine

  • +
  • capability (EngineCapability) – Restrict kernel selection to safe gpu kernels or safe dla kernels

  • +
  • num_avg_timing_iters (python:int) – Number of averaging timing iterations used to select kernels

  • +
  • workspace_size (python:int) – Maximum size of workspace given to TensorRT

  • +
  • truncate_long_and_double (bool) – Truncate weights provided in int64 or double (float64) to int32 and float32

  • +
  • calibrator (Union(torch_tensorrt._C.IInt8Calibrator, tensorrt.IInt8Calibrator)) – Calibrator object which will provide data to the PTQ system for INT8 Calibration

  • +
  • allow_shape_tensors

    (Experimental) Allow aten::size to output shape tensors using IShapeLayer in TensorRT

    +
    +
    Returns:

    torch.classes.tensorrt.CompileSpec: List of methods and formated spec objects to be provided to torch._C._jit_to_tensorrt

    +
    +
    +

  • +
+
+
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/search.html b/docs/v2.2.0/search.html new file mode 100644 index 0000000000..3226b46059 --- /dev/null +++ b/docs/v2.2.0/search.html @@ -0,0 +1,751 @@ + + + + + + + + + + + + Search — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ + + + +
+ +
+ +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/searchindex.js b/docs/v2.2.0/searchindex.js new file mode 100644 index 0000000000..fb7b5a45ba --- /dev/null +++ b/docs/v2.2.0/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["_cpp_api/classtorch__tensorrt_1_1DataType","_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType","_cpp_api/classtorch__tensorrt_1_1TensorFormat","_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator","_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator","_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502","_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268","_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e","_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827","_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b","_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da","_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59","_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883","_cpp_api/dir_cpp","_cpp_api/dir_cpp_include","_cpp_api/dir_cpp_include_torch_tensorrt","_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558","_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb","_cpp_api/file_cpp_include_torch_tensorrt_logging.h","_cpp_api/file_cpp_include_torch_tensorrt_macros.h","_cpp_api/file_cpp_include_torch_tensorrt_ptq.h","_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h","_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3","_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650","_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a","_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2","_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8","_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5","_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc","_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c","_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178","_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797","_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9","_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9","_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528","_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384","_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1","_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2","_cpp_api/namespace_torch","_cpp_api/namespace_torch_tensorrt","_cpp_api/namespace_torch_tensorrt__logging","_cpp_api/namespace_torch_tensorrt__ptq","_cpp_api/namespace_torch_tensorrt__torchscript","_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h","_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h","_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h","_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h","_cpp_api/structtorch__tensorrt_1_1Device","_cpp_api/structtorch__tensorrt_1_1GraphInputs","_cpp_api/structtorch__tensorrt_1_1Input","_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec","_cpp_api/torch_tensort_cpp","_cpp_api/unabridged_orphan","cli/torchtrtc","contributors/conversion","contributors/dynamo_converters","contributors/lowering","contributors/partitioning","contributors/phases","contributors/runtime","contributors/system_overview","contributors/ts_converters","contributors/useful_links","contributors/writing_dynamo_aten_lowering_passes","dynamo/dynamo_export","dynamo/torch_compile","fx/getting_started_with_fx_path","getting_started/getting_started_with_windows","getting_started/installation","index","indices/supported_ops","py_api/dynamo","py_api/fx","py_api/logging","py_api/ptq","py_api/torch_tensorrt","py_api/ts","src/pytorch-sphinx-theme/docs/changelog","src/pytorch-sphinx-theme/docs/configuring","src/pytorch-sphinx-theme/docs/demo/api","src/pytorch-sphinx-theme/docs/demo/demo","src/pytorch-sphinx-theme/docs/demo/lists_tables","src/pytorch-sphinx-theme/docs/demo/long","src/pytorch-sphinx-theme/docs/demo/structure","src/pytorch-sphinx-theme/docs/index","src/pytorch-sphinx-theme/docs/installing","ts/creating_torchscript_module_in_python","ts/getting_started_with_cpp_api","ts/getting_started_with_python_api","ts/torchscript_frontend_from_pytorch","tutorials/_rendered_examples/dynamo/index","tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage","tutorials/_rendered_examples/dynamo/torch_compile_resnet_example","tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion","tutorials/_rendered_examples/dynamo/torch_compile_transformers_example","tutorials/_rendered_examples/index","tutorials/notebooks","tutorials/serving_torch_tensorrt_with_triton","user_guide/dynamic_shapes","user_guide/ptq","user_guide/runtime","user_guide/saving_models","user_guide/using_dla"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":5,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,nbsphinx:4,sphinx:56},filenames:["_cpp_api/classtorch__tensorrt_1_1DataType.rst","_cpp_api/classtorch__tensorrt_1_1Device_1_1DeviceType.rst","_cpp_api/classtorch__tensorrt_1_1TensorFormat.rst","_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8CacheCalibrator.rst","_cpp_api/classtorch__tensorrt_1_1ptq_1_1Int8Calibrator.rst","_cpp_api/define_macros_8h_1a18d295a837ac71add5578860b55e5502.rst","_cpp_api/define_macros_8h_1a282fd3c0b1c3a215148ae372070e1268.rst","_cpp_api/define_macros_8h_1a31398a6d4d27e28817afb0f0139e909e.rst","_cpp_api/define_macros_8h_1a35703561b26b1a9d2738ad7d58b27827.rst","_cpp_api/define_macros_8h_1abd1465eb38256d3f22cc1426b23d516b.rst","_cpp_api/define_macros_8h_1abe87b341f562fd1cf40b7672e4d759da.rst","_cpp_api/define_macros_8h_1ad19939408f7be171a74a89928b36eb59.rst","_cpp_api/define_macros_8h_1adad592a7b1b7eed529cdf6acd584c883.rst","_cpp_api/dir_cpp.rst","_cpp_api/dir_cpp_include.rst","_cpp_api/dir_cpp_include_torch_tensorrt.rst","_cpp_api/enum_logging_8h_1a130f65408ad8cbaee060f05e8db69558.rst","_cpp_api/enum_torch__tensorrt_8h_1a3fbe5d72e4fc624dbd038853079620eb.rst","_cpp_api/file_cpp_include_torch_tensorrt_logging.h.rst","_cpp_api/file_cpp_include_torch_tensorrt_macros.h.rst","_cpp_api/file_cpp_include_torch_tensorrt_ptq.h.rst","_cpp_api/file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst","_cpp_api/function_logging_8h_1a0593f776f469c20469e2f729fc7861a3.rst","_cpp_api/function_logging_8h_1a0c012cb374addd90eb1f42eaec570650.rst","_cpp_api/function_logging_8h_1a56e110feaaba2c3fd44bd201fd21a76a.rst","_cpp_api/function_logging_8h_1a7cb50492421ea9de4e3db895819df6f2.rst","_cpp_api/function_logging_8h_1ac46ac0901cb97e3ae6e93b45f24e90b8.rst","_cpp_api/function_logging_8h_1ad2efd47b6c3689e58ccc595680579ae5.rst","_cpp_api/function_logging_8h_1af8f3443813315af7901903d25dd495cc.rst","_cpp_api/function_ptq_8h_1a226e3c83379d1012cde8578c1c86b16c.rst","_cpp_api/function_ptq_8h_1a6186e305f47c1d94b6130ef6c7f7e178.rst","_cpp_api/function_torch__tensorrt_8h_1a5b405fd3bf3c8fc2e2a54cbbab979797.rst","_cpp_api/function_torch__tensorrt_8h_1a6e19490a08fb1553c9dd347a5ae79db9.rst","_cpp_api/function_torch__tensorrt_8h_1a81f9783517335dda877d8cfcf38987c9.rst","_cpp_api/function_torch__tensorrt_8h_1ac4ab8313ae72c2c899ea31548b528528.rst","_cpp_api/function_torch__tensorrt_8h_1ad1acd06eaeaffbbcf6e7ebf426891384.rst","_cpp_api/function_torch__tensorrt_8h_1ad6a4ee8ca6c8f6e5519eb1128ec7f4a1.rst","_cpp_api/function_torch__tensorrt_8h_1ae8d56472106eeef37fbe51ff7f40c9b2.rst","_cpp_api/namespace_torch.rst","_cpp_api/namespace_torch_tensorrt.rst","_cpp_api/namespace_torch_tensorrt__logging.rst","_cpp_api/namespace_torch_tensorrt__ptq.rst","_cpp_api/namespace_torch_tensorrt__torchscript.rst","_cpp_api/program_listing_file_cpp_include_torch_tensorrt_logging.h.rst","_cpp_api/program_listing_file_cpp_include_torch_tensorrt_macros.h.rst","_cpp_api/program_listing_file_cpp_include_torch_tensorrt_ptq.h.rst","_cpp_api/program_listing_file_cpp_include_torch_tensorrt_torch_tensorrt.h.rst","_cpp_api/structtorch__tensorrt_1_1Device.rst","_cpp_api/structtorch__tensorrt_1_1GraphInputs.rst","_cpp_api/structtorch__tensorrt_1_1Input.rst","_cpp_api/structtorch__tensorrt_1_1torchscript_1_1CompileSpec.rst","_cpp_api/torch_tensort_cpp.rst","_cpp_api/unabridged_orphan.rst","cli/torchtrtc.rst","contributors/conversion.rst","contributors/dynamo_converters.rst","contributors/lowering.rst","contributors/partitioning.rst","contributors/phases.rst","contributors/runtime.rst","contributors/system_overview.rst","contributors/ts_converters.rst","contributors/useful_links.rst","contributors/writing_dynamo_aten_lowering_passes.rst","dynamo/dynamo_export.rst","dynamo/torch_compile.rst","fx/getting_started_with_fx_path.rst","getting_started/getting_started_with_windows.rst","getting_started/installation.rst","index.rst","indices/supported_ops.rst","py_api/dynamo.rst","py_api/fx.rst","py_api/logging.rst","py_api/ptq.rst","py_api/torch_tensorrt.rst","py_api/ts.rst","src/pytorch-sphinx-theme/docs/changelog.rst","src/pytorch-sphinx-theme/docs/configuring.rst","src/pytorch-sphinx-theme/docs/demo/api.rst","src/pytorch-sphinx-theme/docs/demo/demo.rst","src/pytorch-sphinx-theme/docs/demo/lists_tables.rst","src/pytorch-sphinx-theme/docs/demo/long.rst","src/pytorch-sphinx-theme/docs/demo/structure.rst","src/pytorch-sphinx-theme/docs/index.rst","src/pytorch-sphinx-theme/docs/installing.rst","ts/creating_torchscript_module_in_python.rst","ts/getting_started_with_cpp_api.rst","ts/getting_started_with_python_api.rst","ts/torchscript_frontend_from_pytorch.rst","tutorials/_rendered_examples/dynamo/index.rst","tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.rst","tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.rst","tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.rst","tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.rst","tutorials/_rendered_examples/index.rst","tutorials/notebooks.rst","tutorials/serving_torch_tensorrt_with_triton.rst","user_guide/dynamic_shapes.rst","user_guide/ptq.rst","user_guide/runtime.rst","user_guide/saving_models.rst","user_guide/using_dla.rst"],objects:{"":[[5,0,1,"c.STR","STR"],[9,0,1,"c.TORCHTRT_API","TORCHTRT_API"],[11,0,1,"c.TORCHTRT_HIDDEN","TORCHTRT_HIDDEN"],[7,0,1,"c.TORCH_TENSORRT_MAJOR_VERSION","TORCH_TENSORRT_MAJOR_VERSION"],[8,0,1,"c.TORCH_TENSORRT_MINOR_VERSION","TORCH_TENSORRT_MINOR_VERSION"],[6,0,1,"c.TORCH_TENSORRT_PATCH_VERSION","TORCH_TENSORRT_PATCH_VERSION"],[12,0,1,"c.TORCH_TENSORRT_VERSION","TORCH_TENSORRT_VERSION"],[10,0,1,"c.XSTR","XSTR"],[0,1,1,"_CPPv4N14torch_tensorrt8DataTypeE","torch_tensorrt::DataType"],[0,2,1,"_CPPv4N14torch_tensorrt8DataType8DataTypeE5Value","torch_tensorrt::DataType::DataType"],[0,2,1,"_CPPv4N14torch_tensorrt8DataType8DataTypeEN3c1010ScalarTypeE","torch_tensorrt::DataType::DataType"],[0,2,1,"_CPPv4N14torch_tensorrt8DataType8DataTypeEv","torch_tensorrt::DataType::DataType"],[0,3,1,"_CPPv4N14torch_tensorrt8DataType8DataTypeE5Value","torch_tensorrt::DataType::DataType::t"],[0,3,1,"_CPPv4N14torch_tensorrt8DataType8DataTypeEN3c1010ScalarTypeE","torch_tensorrt::DataType::DataType::t"],[0,4,1,"_CPPv4N14torch_tensorrt8DataType5ValueE","torch_tensorrt::DataType::Value"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value5kBoolE","torch_tensorrt::DataType::Value::kBool"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value5kCharE","torch_tensorrt::DataType::Value::kChar"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value7kDoubleE","torch_tensorrt::DataType::Value::kDouble"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value6kFloatE","torch_tensorrt::DataType::Value::kFloat"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value5kHalfE","torch_tensorrt::DataType::Value::kHalf"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value4kIntE","torch_tensorrt::DataType::Value::kInt"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value5kLongE","torch_tensorrt::DataType::Value::kLong"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value8kUnknownE","torch_tensorrt::DataType::Value::kUnknown"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value5kBoolE","torch_tensorrt::DataType::kBool"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value5kCharE","torch_tensorrt::DataType::kChar"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value7kDoubleE","torch_tensorrt::DataType::kDouble"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value6kFloatE","torch_tensorrt::DataType::kFloat"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value5kHalfE","torch_tensorrt::DataType::kHalf"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value4kIntE","torch_tensorrt::DataType::kInt"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value5kLongE","torch_tensorrt::DataType::kLong"],[0,5,1,"_CPPv4N14torch_tensorrt8DataType5Value8kUnknownE","torch_tensorrt::DataType::kUnknown"],[0,2,1,"_CPPv4NK14torch_tensorrt8DataTypecv5ValueEv","torch_tensorrt::DataType::operator Value"],[0,2,1,"_CPPv4N14torch_tensorrt8DataTypecvbEv","torch_tensorrt::DataType::operator bool"],[0,2,1,"_CPPv4NK14torch_tensorrt8DataTypeneE8DataType","torch_tensorrt::DataType::operator!="],[0,2,1,"_CPPv4NK14torch_tensorrt8DataTypeneEN8DataType5ValueE","torch_tensorrt::DataType::operator!="],[0,3,1,"_CPPv4NK14torch_tensorrt8DataTypeneE8DataType","torch_tensorrt::DataType::operator!=::other"],[0,3,1,"_CPPv4NK14torch_tensorrt8DataTypeneEN8DataType5ValueE","torch_tensorrt::DataType::operator!=::other"],[0,2,1,"_CPPv4NK14torch_tensorrt8DataTypeeqE8DataType","torch_tensorrt::DataType::operator=="],[0,2,1,"_CPPv4NK14torch_tensorrt8DataTypeeqEN8DataType5ValueE","torch_tensorrt::DataType::operator=="],[0,3,1,"_CPPv4NK14torch_tensorrt8DataTypeeqE8DataType","torch_tensorrt::DataType::operator==::other"],[0,3,1,"_CPPv4NK14torch_tensorrt8DataTypeeqEN8DataType5ValueE","torch_tensorrt::DataType::operator==::other"],[47,1,1,"_CPPv4N14torch_tensorrt6DeviceE","torch_tensorrt::Device"],[47,2,1,"_CPPv4N14torch_tensorrt6Device6DeviceEv","torch_tensorrt::Device::Device"],[1,1,1,"_CPPv4N14torch_tensorrt6Device10DeviceTypeE","torch_tensorrt::Device::DeviceType"],[47,1,1,"_CPPv4N14torch_tensorrt6Device10DeviceTypeE","torch_tensorrt::Device::DeviceType"],[1,2,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeE5Value","torch_tensorrt::Device::DeviceType::DeviceType"],[1,2,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeEN3c1010DeviceTypeE","torch_tensorrt::Device::DeviceType::DeviceType"],[1,2,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeEv","torch_tensorrt::Device::DeviceType::DeviceType"],[47,2,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeE5Value","torch_tensorrt::Device::DeviceType::DeviceType"],[47,2,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeEN3c1010DeviceTypeE","torch_tensorrt::Device::DeviceType::DeviceType"],[47,2,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeEv","torch_tensorrt::Device::DeviceType::DeviceType"],[1,3,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeE5Value","torch_tensorrt::Device::DeviceType::DeviceType::t"],[1,3,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeEN3c1010DeviceTypeE","torch_tensorrt::Device::DeviceType::DeviceType::t"],[47,3,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeE5Value","torch_tensorrt::Device::DeviceType::DeviceType::t"],[47,3,1,"_CPPv4N14torch_tensorrt6Device10DeviceType10DeviceTypeEN3c1010DeviceTypeE","torch_tensorrt::Device::DeviceType::DeviceType::t"],[1,4,1,"_CPPv4N14torch_tensorrt6Device10DeviceType5ValueE","torch_tensorrt::Device::DeviceType::Value"],[47,4,1,"_CPPv4N14torch_tensorrt6Device10DeviceType5ValueE","torch_tensorrt::Device::DeviceType::Value"],[1,5,1,"_CPPv4N14torch_tensorrt6Device10DeviceType5Value4kDLAE","torch_tensorrt::Device::DeviceType::Value::kDLA"],[47,5,1,"_CPPv4N14torch_tensorrt6Device10DeviceType5Value4kDLAE","torch_tensorrt::Device::DeviceType::Value::kDLA"],[1,5,1,"_CPPv4N14torch_tensorrt6Device10DeviceType5Value4kGPUE","torch_tensorrt::Device::DeviceType::Value::kGPU"],[47,5,1,"_CPPv4N14torch_tensorrt6Device10DeviceType5Value4kGPUE","torch_tensorrt::Device::DeviceType::Value::kGPU"],[1,5,1,"_CPPv4N14torch_tensorrt6Device10DeviceType5Value4kDLAE","torch_tensorrt::Device::DeviceType::kDLA"],[1,5,1,"_CPPv4N14torch_tensorrt6Device10DeviceType5Value4kGPUE","torch_tensorrt::Device::DeviceType::kGPU"],[1,2,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypecv5ValueEv","torch_tensorrt::Device::DeviceType::operator Value"],[47,2,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypecv5ValueEv","torch_tensorrt::Device::DeviceType::operator Value"],[1,2,1,"_CPPv4N14torch_tensorrt6Device10DeviceTypecvbEv","torch_tensorrt::Device::DeviceType::operator bool"],[47,2,1,"_CPPv4N14torch_tensorrt6Device10DeviceTypecvbEv","torch_tensorrt::Device::DeviceType::operator bool"],[1,2,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypeneE10DeviceType","torch_tensorrt::Device::DeviceType::operator!="],[47,2,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypeneE10DeviceType","torch_tensorrt::Device::DeviceType::operator!="],[1,3,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypeneE10DeviceType","torch_tensorrt::Device::DeviceType::operator!=::other"],[47,3,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypeneE10DeviceType","torch_tensorrt::Device::DeviceType::operator!=::other"],[1,2,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypeeqE10DeviceType","torch_tensorrt::Device::DeviceType::operator=="],[47,2,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypeeqE10DeviceType","torch_tensorrt::Device::DeviceType::operator=="],[1,3,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypeeqE10DeviceType","torch_tensorrt::Device::DeviceType::operator==::other"],[47,3,1,"_CPPv4NK14torch_tensorrt6Device10DeviceTypeeqE10DeviceType","torch_tensorrt::Device::DeviceType::operator==::other"],[47,6,1,"_CPPv4N14torch_tensorrt6Device18allow_gpu_fallbackE","torch_tensorrt::Device::allow_gpu_fallback"],[47,6,1,"_CPPv4N14torch_tensorrt6Device11device_typeE","torch_tensorrt::Device::device_type"],[47,6,1,"_CPPv4N14torch_tensorrt6Device8dla_coreE","torch_tensorrt::Device::dla_core"],[47,6,1,"_CPPv4N14torch_tensorrt6Device6gpu_idE","torch_tensorrt::Device::gpu_id"],[17,4,1,"_CPPv4N14torch_tensorrt16EngineCapabilityE","torch_tensorrt::EngineCapability"],[17,5,1,"_CPPv4N14torch_tensorrt16EngineCapability15kDLA_STANDALONEE","torch_tensorrt::EngineCapability::kDLA_STANDALONE"],[17,5,1,"_CPPv4N14torch_tensorrt16EngineCapability7kSAFETYE","torch_tensorrt::EngineCapability::kSAFETY"],[17,5,1,"_CPPv4N14torch_tensorrt16EngineCapability9kSTANDARDE","torch_tensorrt::EngineCapability::kSTANDARD"],[48,1,1,"_CPPv4N14torch_tensorrt11GraphInputsE","torch_tensorrt::GraphInputs"],[48,6,1,"_CPPv4N14torch_tensorrt11GraphInputs15input_signatureE","torch_tensorrt::GraphInputs::input_signature"],[48,6,1,"_CPPv4N14torch_tensorrt11GraphInputs6inputsE","torch_tensorrt::GraphInputs::inputs"],[49,1,1,"_CPPv4N14torch_tensorrt5InputE","torch_tensorrt::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEN2at6TensorE","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input"],[49,2,1,"_CPPv4N14torch_tensorrt5Input5InputEv","torch_tensorrt::Input::Input"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::dtype"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::dtype"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::dtype"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::dtype"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::dtype"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::dtype"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::dtype"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::dtype"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::format"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::max_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::max_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::max_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::max_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::max_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::max_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::max_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::max_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::min_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::min_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::min_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::min_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::min_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::min_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::min_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::min_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::opt_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::opt_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::opt_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::opt_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::opt_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::opt_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::opt_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::opt_shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE12TensorFormat","torch_tensorrt::Input::Input::shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE8DataType12TensorFormat","torch_tensorrt::Input::Input::shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::shape"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN2at6TensorE","torch_tensorrt::Input::Input::tensor"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::tensor_domain"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::tensor_domain"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::tensor_domain"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputEN3c108ArrayRefI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::tensor_domain"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::tensor_domain"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEE8DataTypeNSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::tensor_domain"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::tensor_domain"],[49,3,1,"_CPPv4N14torch_tensorrt5Input5InputENSt6vectorI7int64_tEENSt6vectorIdEE12TensorFormat","torch_tensorrt::Input::Input::tensor_domain"],[49,6,1,"_CPPv4N14torch_tensorrt5Input5dtypeE","torch_tensorrt::Input::dtype"],[49,6,1,"_CPPv4N14torch_tensorrt5Input6formatE","torch_tensorrt::Input::format"],[49,6,1,"_CPPv4N14torch_tensorrt5Input9max_shapeE","torch_tensorrt::Input::max_shape"],[49,6,1,"_CPPv4N14torch_tensorrt5Input9min_shapeE","torch_tensorrt::Input::min_shape"],[49,6,1,"_CPPv4N14torch_tensorrt5Input9opt_shapeE","torch_tensorrt::Input::opt_shape"],[49,6,1,"_CPPv4N14torch_tensorrt5Input5shapeE","torch_tensorrt::Input::shape"],[49,6,1,"_CPPv4N14torch_tensorrt5Input13tensor_domainE","torch_tensorrt::Input::tensor_domain"],[2,1,1,"_CPPv4N14torch_tensorrt12TensorFormatE","torch_tensorrt::TensorFormat"],[2,2,1,"_CPPv4N14torch_tensorrt12TensorFormat12TensorFormatE5Value","torch_tensorrt::TensorFormat::TensorFormat"],[2,2,1,"_CPPv4N14torch_tensorrt12TensorFormat12TensorFormatEN2at12MemoryFormatE","torch_tensorrt::TensorFormat::TensorFormat"],[2,2,1,"_CPPv4N14torch_tensorrt12TensorFormat12TensorFormatEv","torch_tensorrt::TensorFormat::TensorFormat"],[2,3,1,"_CPPv4N14torch_tensorrt12TensorFormat12TensorFormatE5Value","torch_tensorrt::TensorFormat::TensorFormat::t"],[2,3,1,"_CPPv4N14torch_tensorrt12TensorFormat12TensorFormatEN2at12MemoryFormatE","torch_tensorrt::TensorFormat::TensorFormat::t"],[2,4,1,"_CPPv4N14torch_tensorrt12TensorFormat5ValueE","torch_tensorrt::TensorFormat::Value"],[2,5,1,"_CPPv4N14torch_tensorrt12TensorFormat5Value13kChannelsLastE","torch_tensorrt::TensorFormat::Value::kChannelsLast"],[2,5,1,"_CPPv4N14torch_tensorrt12TensorFormat5Value11kContiguousE","torch_tensorrt::TensorFormat::Value::kContiguous"],[2,5,1,"_CPPv4N14torch_tensorrt12TensorFormat5Value8kUnknownE","torch_tensorrt::TensorFormat::Value::kUnknown"],[2,5,1,"_CPPv4N14torch_tensorrt12TensorFormat5Value13kChannelsLastE","torch_tensorrt::TensorFormat::kChannelsLast"],[2,5,1,"_CPPv4N14torch_tensorrt12TensorFormat5Value11kContiguousE","torch_tensorrt::TensorFormat::kContiguous"],[2,5,1,"_CPPv4N14torch_tensorrt12TensorFormat5Value8kUnknownE","torch_tensorrt::TensorFormat::kUnknown"],[2,2,1,"_CPPv4NK14torch_tensorrt12TensorFormatcv5ValueEv","torch_tensorrt::TensorFormat::operator Value"],[2,2,1,"_CPPv4N14torch_tensorrt12TensorFormatcvbEv","torch_tensorrt::TensorFormat::operator bool"],[2,2,1,"_CPPv4NK14torch_tensorrt12TensorFormatneE12TensorFormat","torch_tensorrt::TensorFormat::operator!="],[2,2,1,"_CPPv4NK14torch_tensorrt12TensorFormatneEN12TensorFormat5ValueE","torch_tensorrt::TensorFormat::operator!="],[2,3,1,"_CPPv4NK14torch_tensorrt12TensorFormatneE12TensorFormat","torch_tensorrt::TensorFormat::operator!=::other"],[2,3,1,"_CPPv4NK14torch_tensorrt12TensorFormatneEN12TensorFormat5ValueE","torch_tensorrt::TensorFormat::operator!=::other"],[2,2,1,"_CPPv4NK14torch_tensorrt12TensorFormateqE12TensorFormat","torch_tensorrt::TensorFormat::operator=="],[2,2,1,"_CPPv4NK14torch_tensorrt12TensorFormateqEN12TensorFormat5ValueE","torch_tensorrt::TensorFormat::operator=="],[2,3,1,"_CPPv4NK14torch_tensorrt12TensorFormateqE12TensorFormat","torch_tensorrt::TensorFormat::operator==::other"],[2,3,1,"_CPPv4NK14torch_tensorrt12TensorFormateqEN12TensorFormat5ValueE","torch_tensorrt::TensorFormat::operator==::other"],[36,2,1,"_CPPv4N14torch_tensorrt15dump_build_infoEv","torch_tensorrt::dump_build_info"],[34,2,1,"_CPPv4N14torch_tensorrt14get_build_infoEv","torch_tensorrt::get_build_info"],[16,4,1,"_CPPv4N14torch_tensorrt7logging5LevelE","torch_tensorrt::logging::Level"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level6kDEBUGE","torch_tensorrt::logging::Level::kDEBUG"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level6kERRORE","torch_tensorrt::logging::Level::kERROR"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level6kGRAPHE","torch_tensorrt::logging::Level::kGRAPH"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level5kINFOE","torch_tensorrt::logging::Level::kINFO"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level15kINTERNAL_ERRORE","torch_tensorrt::logging::Level::kINTERNAL_ERROR"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level8kWARNINGE","torch_tensorrt::logging::Level::kWARNING"],[24,2,1,"_CPPv4N14torch_tensorrt7logging24get_is_colored_output_onEv","torch_tensorrt::logging::get_is_colored_output_on"],[22,2,1,"_CPPv4N14torch_tensorrt7logging18get_logging_prefixEv","torch_tensorrt::logging::get_logging_prefix"],[23,2,1,"_CPPv4N14torch_tensorrt7logging24get_reportable_log_levelEv","torch_tensorrt::logging::get_reportable_log_level"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level6kDEBUGE","torch_tensorrt::logging::kDEBUG"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level6kERRORE","torch_tensorrt::logging::kERROR"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level6kGRAPHE","torch_tensorrt::logging::kGRAPH"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level5kINFOE","torch_tensorrt::logging::kINFO"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level15kINTERNAL_ERRORE","torch_tensorrt::logging::kINTERNAL_ERROR"],[16,5,1,"_CPPv4N14torch_tensorrt7logging5Level8kWARNINGE","torch_tensorrt::logging::kWARNING"],[26,2,1,"_CPPv4N14torch_tensorrt7logging3logE5LevelNSt6stringE","torch_tensorrt::logging::log"],[26,3,1,"_CPPv4N14torch_tensorrt7logging3logE5LevelNSt6stringE","torch_tensorrt::logging::log::lvl"],[26,3,1,"_CPPv4N14torch_tensorrt7logging3logE5LevelNSt6stringE","torch_tensorrt::logging::log::msg"],[27,2,1,"_CPPv4N14torch_tensorrt7logging24set_is_colored_output_onEb","torch_tensorrt::logging::set_is_colored_output_on"],[27,3,1,"_CPPv4N14torch_tensorrt7logging24set_is_colored_output_onEb","torch_tensorrt::logging::set_is_colored_output_on::colored_output_on"],[28,2,1,"_CPPv4N14torch_tensorrt7logging18set_logging_prefixENSt6stringE","torch_tensorrt::logging::set_logging_prefix"],[28,3,1,"_CPPv4N14torch_tensorrt7logging18set_logging_prefixENSt6stringE","torch_tensorrt::logging::set_logging_prefix::prefix"],[25,2,1,"_CPPv4N14torch_tensorrt7logging24set_reportable_log_levelE5Level","torch_tensorrt::logging::set_reportable_log_level"],[25,3,1,"_CPPv4N14torch_tensorrt7logging24set_reportable_log_levelE5Level","torch_tensorrt::logging::set_reportable_log_level::lvl"],[3,1,1,"_CPPv4I0EN14torch_tensorrt3ptq19Int8CacheCalibratorE","torch_tensorrt::ptq::Int8CacheCalibrator"],[3,7,1,"_CPPv4I0EN14torch_tensorrt3ptq19Int8CacheCalibratorE","torch_tensorrt::ptq::Int8CacheCalibrator::Algorithm"],[3,2,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator19Int8CacheCalibratorERKNSt6stringE","torch_tensorrt::ptq::Int8CacheCalibrator::Int8CacheCalibrator"],[3,3,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator19Int8CacheCalibratorERKNSt6stringE","torch_tensorrt::ptq::Int8CacheCalibrator::Int8CacheCalibrator::cache_file_path"],[3,2,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator8getBatchEA_PvA_PKci","torch_tensorrt::ptq::Int8CacheCalibrator::getBatch"],[3,3,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator8getBatchEA_PvA_PKci","torch_tensorrt::ptq::Int8CacheCalibrator::getBatch::bindings"],[3,3,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator8getBatchEA_PvA_PKci","torch_tensorrt::ptq::Int8CacheCalibrator::getBatch::names"],[3,3,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator8getBatchEA_PvA_PKci","torch_tensorrt::ptq::Int8CacheCalibrator::getBatch::nbBindings"],[3,2,1,"_CPPv4NK14torch_tensorrt3ptq19Int8CacheCalibrator12getBatchSizeEv","torch_tensorrt::ptq::Int8CacheCalibrator::getBatchSize"],[3,2,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibratorcvPN8nvinfer115IInt8CalibratorEEv","torch_tensorrt::ptq::Int8CacheCalibrator::operator nvinfer1::IInt8Calibrator*"],[3,2,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator20readCalibrationCacheER6size_t","torch_tensorrt::ptq::Int8CacheCalibrator::readCalibrationCache"],[3,3,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator20readCalibrationCacheER6size_t","torch_tensorrt::ptq::Int8CacheCalibrator::readCalibrationCache::length"],[3,2,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator21writeCalibrationCacheEPKv6size_t","torch_tensorrt::ptq::Int8CacheCalibrator::writeCalibrationCache"],[3,3,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator21writeCalibrationCacheEPKv6size_t","torch_tensorrt::ptq::Int8CacheCalibrator::writeCalibrationCache::cache"],[3,3,1,"_CPPv4N14torch_tensorrt3ptq19Int8CacheCalibrator21writeCalibrationCacheEPKv6size_t","torch_tensorrt::ptq::Int8CacheCalibrator::writeCalibrationCache::length"],[4,1,1,"_CPPv4I00EN14torch_tensorrt3ptq14Int8CalibratorE","torch_tensorrt::ptq::Int8Calibrator"],[4,7,1,"_CPPv4I00EN14torch_tensorrt3ptq14Int8CalibratorE","torch_tensorrt::ptq::Int8Calibrator::Algorithm"],[4,7,1,"_CPPv4I00EN14torch_tensorrt3ptq14Int8CalibratorE","torch_tensorrt::ptq::Int8Calibrator::DataLoaderUniquePtr"],[4,2,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator14Int8CalibratorE19DataLoaderUniquePtrRKNSt6stringEb","torch_tensorrt::ptq::Int8Calibrator::Int8Calibrator"],[4,3,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator14Int8CalibratorE19DataLoaderUniquePtrRKNSt6stringEb","torch_tensorrt::ptq::Int8Calibrator::Int8Calibrator::cache_file_path"],[4,3,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator14Int8CalibratorE19DataLoaderUniquePtrRKNSt6stringEb","torch_tensorrt::ptq::Int8Calibrator::Int8Calibrator::dataloader"],[4,3,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator14Int8CalibratorE19DataLoaderUniquePtrRKNSt6stringEb","torch_tensorrt::ptq::Int8Calibrator::Int8Calibrator::use_cache"],[4,2,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator8getBatchEA_PvA_PKci","torch_tensorrt::ptq::Int8Calibrator::getBatch"],[4,3,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator8getBatchEA_PvA_PKci","torch_tensorrt::ptq::Int8Calibrator::getBatch::bindings"],[4,3,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator8getBatchEA_PvA_PKci","torch_tensorrt::ptq::Int8Calibrator::getBatch::names"],[4,3,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator8getBatchEA_PvA_PKci","torch_tensorrt::ptq::Int8Calibrator::getBatch::nbBindings"],[4,2,1,"_CPPv4NK14torch_tensorrt3ptq14Int8Calibrator12getBatchSizeEv","torch_tensorrt::ptq::Int8Calibrator::getBatchSize"],[4,2,1,"_CPPv4N14torch_tensorrt3ptq14Int8CalibratorcvPN8nvinfer115IInt8CalibratorEEv","torch_tensorrt::ptq::Int8Calibrator::operator nvinfer1::IInt8Calibrator*"],[4,2,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator20readCalibrationCacheER6size_t","torch_tensorrt::ptq::Int8Calibrator::readCalibrationCache"],[4,3,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator20readCalibrationCacheER6size_t","torch_tensorrt::ptq::Int8Calibrator::readCalibrationCache::length"],[4,2,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator21writeCalibrationCacheEPKv6size_t","torch_tensorrt::ptq::Int8Calibrator::writeCalibrationCache"],[4,3,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator21writeCalibrationCacheEPKv6size_t","torch_tensorrt::ptq::Int8Calibrator::writeCalibrationCache::cache"],[4,3,1,"_CPPv4N14torch_tensorrt3ptq14Int8Calibrator21writeCalibrationCacheEPKv6size_t","torch_tensorrt::ptq::Int8Calibrator::writeCalibrationCache::length"],[29,2,1,"_CPPv4I0EN14torch_tensorrt3ptq26make_int8_cache_calibratorE19Int8CacheCalibratorI9AlgorithmERKNSt6stringE","torch_tensorrt::ptq::make_int8_cache_calibrator"],[29,7,1,"_CPPv4I0EN14torch_tensorrt3ptq26make_int8_cache_calibratorE19Int8CacheCalibratorI9AlgorithmERKNSt6stringE","torch_tensorrt::ptq::make_int8_cache_calibrator::Algorithm"],[29,3,1,"_CPPv4I0EN14torch_tensorrt3ptq26make_int8_cache_calibratorE19Int8CacheCalibratorI9AlgorithmERKNSt6stringE","torch_tensorrt::ptq::make_int8_cache_calibrator::cache_file_path"],[30,2,1,"_CPPv4I00EN14torch_tensorrt3ptq20make_int8_calibratorE14Int8CalibratorI9Algorithm10DataLoaderE10DataLoaderRKNSt6stringEb","torch_tensorrt::ptq::make_int8_calibrator"],[30,7,1,"_CPPv4I00EN14torch_tensorrt3ptq20make_int8_calibratorE14Int8CalibratorI9Algorithm10DataLoaderE10DataLoaderRKNSt6stringEb","torch_tensorrt::ptq::make_int8_calibrator::Algorithm"],[30,7,1,"_CPPv4I00EN14torch_tensorrt3ptq20make_int8_calibratorE14Int8CalibratorI9Algorithm10DataLoaderE10DataLoaderRKNSt6stringEb","torch_tensorrt::ptq::make_int8_calibrator::DataLoader"],[30,3,1,"_CPPv4I00EN14torch_tensorrt3ptq20make_int8_calibratorE14Int8CalibratorI9Algorithm10DataLoaderE10DataLoaderRKNSt6stringEb","torch_tensorrt::ptq::make_int8_calibrator::cache_file_path"],[30,3,1,"_CPPv4I00EN14torch_tensorrt3ptq20make_int8_calibratorE14Int8CalibratorI9Algorithm10DataLoaderE10DataLoaderRKNSt6stringEb","torch_tensorrt::ptq::make_int8_calibrator::dataloader"],[30,3,1,"_CPPv4I00EN14torch_tensorrt3ptq20make_int8_calibratorE14Int8CalibratorI9Algorithm10DataLoaderE10DataLoaderRKNSt6stringEb","torch_tensorrt::ptq::make_int8_calibrator::use_cache"],[35,2,1,"_CPPv4N14torch_tensorrt10set_deviceEKi","torch_tensorrt::set_device"],[35,3,1,"_CPPv4N14torch_tensorrt10set_deviceEKi","torch_tensorrt::set_device::gpu_id"],[50,1,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpecE","torch_tensorrt::torchscript::CompileSpec"],[50,2,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec11CompileSpecEN5torch3jit6IValueE","torch_tensorrt::torchscript::CompileSpec::CompileSpec"],[50,2,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec11CompileSpecENSt6vectorI5InputEE","torch_tensorrt::torchscript::CompileSpec::CompileSpec"],[50,2,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec11CompileSpecENSt6vectorIN3c108ArrayRefI7int64_tEEEE","torch_tensorrt::torchscript::CompileSpec::CompileSpec"],[50,2,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec11CompileSpecENSt6vectorINSt6vectorI7int64_tEEEE","torch_tensorrt::torchscript::CompileSpec::CompileSpec"],[50,3,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec11CompileSpecENSt6vectorIN3c108ArrayRefI7int64_tEEEE","torch_tensorrt::torchscript::CompileSpec::CompileSpec::fixed_sizes"],[50,3,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec11CompileSpecENSt6vectorINSt6vectorI7int64_tEEEE","torch_tensorrt::torchscript::CompileSpec::CompileSpec::fixed_sizes"],[50,3,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec11CompileSpecEN5torch3jit6IValueE","torch_tensorrt::torchscript::CompileSpec::CompileSpec::input_signature"],[50,3,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec11CompileSpecENSt6vectorI5InputEE","torch_tensorrt::torchscript::CompileSpec::CompileSpec::inputs"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec19allow_shape_tensorsE","torch_tensorrt::torchscript::CompileSpec::allow_shape_tensors"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec10capabilityE","torch_tensorrt::torchscript::CompileSpec::capability"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec5debugE","torch_tensorrt::torchscript::CompileSpec::debug"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec6deviceE","torch_tensorrt::torchscript::CompileSpec::device"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec12disable_tf32E","torch_tensorrt::torchscript::CompileSpec::disable_tf32"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec20dla_global_dram_sizeE","torch_tensorrt::torchscript::CompileSpec::dla_global_dram_size"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec19dla_local_dram_sizeE","torch_tensorrt::torchscript::CompileSpec::dla_local_dram_size"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec13dla_sram_sizeE","torch_tensorrt::torchscript::CompileSpec::dla_sram_size"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec18enabled_precisionsE","torch_tensorrt::torchscript::CompileSpec::enabled_precisions"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec12graph_inputsE","torch_tensorrt::torchscript::CompileSpec::graph_inputs"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec14min_block_sizeE","torch_tensorrt::torchscript::CompileSpec::min_block_size"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec20num_avg_timing_itersE","torch_tensorrt::torchscript::CompileSpec::num_avg_timing_iters"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec14ptq_calibratorE","torch_tensorrt::torchscript::CompileSpec::ptq_calibrator"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec5refitE","torch_tensorrt::torchscript::CompileSpec::refit"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec24require_full_compilationE","torch_tensorrt::torchscript::CompileSpec::require_full_compilation"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec14sparse_weightsE","torch_tensorrt::torchscript::CompileSpec::sparse_weights"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec22torch_executed_modulesE","torch_tensorrt::torchscript::CompileSpec::torch_executed_modules"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec18torch_executed_opsE","torch_tensorrt::torchscript::CompileSpec::torch_executed_ops"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec24truncate_long_and_doubleE","torch_tensorrt::torchscript::CompileSpec::truncate_long_and_double"],[50,6,1,"_CPPv4N14torch_tensorrt11torchscript11CompileSpec14workspace_sizeE","torch_tensorrt::torchscript::CompileSpec::workspace_size"],[31,2,1,"_CPPv4N14torch_tensorrt11torchscript29check_method_operator_supportERKN5torch3jit6ModuleENSt6stringE","torch_tensorrt::torchscript::check_method_operator_support"],[31,3,1,"_CPPv4N14torch_tensorrt11torchscript29check_method_operator_supportERKN5torch3jit6ModuleENSt6stringE","torch_tensorrt::torchscript::check_method_operator_support::method_name"],[31,3,1,"_CPPv4N14torch_tensorrt11torchscript29check_method_operator_supportERKN5torch3jit6ModuleENSt6stringE","torch_tensorrt::torchscript::check_method_operator_support::module"],[32,2,1,"_CPPv4N14torch_tensorrt11torchscript7compileERKN5torch3jit6ModuleE11CompileSpec","torch_tensorrt::torchscript::compile"],[32,3,1,"_CPPv4N14torch_tensorrt11torchscript7compileERKN5torch3jit6ModuleE11CompileSpec","torch_tensorrt::torchscript::compile::info"],[32,3,1,"_CPPv4N14torch_tensorrt11torchscript7compileERKN5torch3jit6ModuleE11CompileSpec","torch_tensorrt::torchscript::compile::module"],[37,2,1,"_CPPv4N14torch_tensorrt11torchscript28convert_method_to_trt_engineERKN5torch3jit6ModuleENSt6stringE11CompileSpec","torch_tensorrt::torchscript::convert_method_to_trt_engine"],[37,3,1,"_CPPv4N14torch_tensorrt11torchscript28convert_method_to_trt_engineERKN5torch3jit6ModuleENSt6stringE11CompileSpec","torch_tensorrt::torchscript::convert_method_to_trt_engine::info"],[37,3,1,"_CPPv4N14torch_tensorrt11torchscript28convert_method_to_trt_engineERKN5torch3jit6ModuleENSt6stringE11CompileSpec","torch_tensorrt::torchscript::convert_method_to_trt_engine::method_name"],[37,3,1,"_CPPv4N14torch_tensorrt11torchscript28convert_method_to_trt_engineERKN5torch3jit6ModuleENSt6stringE11CompileSpec","torch_tensorrt::torchscript::convert_method_to_trt_engine::module"],[33,2,1,"_CPPv4N14torch_tensorrt11torchscript26embed_engine_in_new_moduleERKNSt6stringE6DeviceRKNSt6vectorINSt6stringEEERKNSt6vectorINSt6stringEEE","torch_tensorrt::torchscript::embed_engine_in_new_module"],[33,3,1,"_CPPv4N14torch_tensorrt11torchscript26embed_engine_in_new_moduleERKNSt6stringE6DeviceRKNSt6vectorINSt6stringEEERKNSt6vectorINSt6stringEEE","torch_tensorrt::torchscript::embed_engine_in_new_module::device"],[33,3,1,"_CPPv4N14torch_tensorrt11torchscript26embed_engine_in_new_moduleERKNSt6stringE6DeviceRKNSt6vectorINSt6stringEEERKNSt6vectorINSt6stringEEE","torch_tensorrt::torchscript::embed_engine_in_new_module::engine"],[33,3,1,"_CPPv4N14torch_tensorrt11torchscript26embed_engine_in_new_moduleERKNSt6stringE6DeviceRKNSt6vectorINSt6stringEEERKNSt6vectorINSt6stringEEE","torch_tensorrt::torchscript::embed_engine_in_new_module::input_binding_names"],[33,3,1,"_CPPv4N14torch_tensorrt11torchscript26embed_engine_in_new_moduleERKNSt6stringE6DeviceRKNSt6vectorINSt6stringEEERKNSt6vectorINSt6stringEEE","torch_tensorrt::torchscript::embed_engine_in_new_module::output_binding_names"],[75,8,0,"-","torch_tensorrt"]],"torch_tensorrt.Device":[[75,10,1,"","__init__"],[75,11,1,"","dla_core"],[75,11,1,"","gpu_id"]],"torch_tensorrt.Input":[[75,10,1,"","__init__"],[75,11,1,"","dtype"],[75,10,1,"","example_tensor"],[75,11,1,"","format"],[75,10,1,"","from_tensor"],[75,10,1,"","from_tensors"]],"torch_tensorrt.dynamo":[[71,9,1,"","CompilationSettings"],[71,9,1,"","SourceIR"],[71,12,1,"","compile"],[71,12,1,"","export"],[71,12,1,"","trace"]],"torch_tensorrt.fx":[[72,9,1,"","InputTensorSpec"],[72,9,1,"","TRTInterpreter"],[72,9,1,"","TRTInterpreterResult"],[72,9,1,"","TRTModule"],[72,12,1,"","compile"]],"torch_tensorrt.logging":[[73,9,1,"","Level"],[73,9,1,"","debug"],[73,9,1,"","errors"],[73,12,1,"","get_is_colored_output_on"],[73,12,1,"","get_logging_prefix"],[73,12,1,"","get_reportable_log_level"],[73,9,1,"","graphs"],[73,9,1,"","info"],[73,9,1,"","internal_errors"],[73,12,1,"","log"],[73,12,1,"","set_is_colored_output_on"],[73,12,1,"","set_logging_prefix"],[73,12,1,"","set_reportable_log_level"],[73,9,1,"","warnings"]],"torch_tensorrt.logging.Level":[[73,11,1,"","Debug"],[73,11,1,"","Error"],[73,11,1,"","Graph"],[73,11,1,"","Info"],[73,11,1,"","InternalError"],[73,11,1,"","Warning"]],"torch_tensorrt.ptq":[[74,9,1,"id1","CacheCalibrator"],[74,9,1,"id2","CalibrationAlgo"],[74,9,1,"id0","DataLoaderCalibrator"],[74,12,1,"","get_batch"],[74,12,1,"","get_batch_size"],[74,12,1,"","get_cache_mode_batch"],[74,12,1,"","read_calibration_cache"],[74,12,1,"","write_calibration_cache"]],"torch_tensorrt.ptq.CacheCalibrator":[[74,10,1,"","__init__"]],"torch_tensorrt.ptq.CalibrationAlgo":[[74,11,1,"","ENTROPY_CALIBRATION"],[74,11,1,"","ENTROPY_CALIBRATION_2"],[74,11,1,"","LEGACY_CALIBRATION"],[74,11,1,"","MINMAX_CALIBRATION"]],"torch_tensorrt.ptq.DataLoaderCalibrator":[[74,10,1,"","__init__"]],"torch_tensorrt.ts":[[76,12,1,"","TensorRTCompileSpec"],[76,12,1,"","check_method_op_support"],[76,12,1,"","compile"],[76,12,1,"","convert_method_to_trt_engine"],[76,12,1,"","embed_engine_in_new_module"]],torch_tensorrt:[[75,9,1,"","Device"],[75,9,1,"","DeviceType"],[75,9,1,"","EngineCapability"],[75,9,1,"","Input"],[75,9,1,"","TensorFormat"],[75,12,1,"","compile"],[75,12,1,"","convert_method_to_trt_engine"],[75,9,1,"","dtype"],[75,12,1,"","dump_build_info"],[101,8,0,"-","dynamo"],[72,8,0,"-","fx"],[75,12,1,"","get_build_info"],[73,8,0,"-","logging"],[74,8,0,"-","ptq"],[75,12,1,"","set_device"],[76,8,0,"-","ts"]]},objnames:{"0":["c","macro","C macro"],"1":["cpp","class","C++ class"],"10":["py","method","Python method"],"11":["py","attribute","Python attribute"],"12":["py","function","Python function"],"2":["cpp","function","C++ function"],"3":["cpp","functionParam","C++ function parameter"],"4":["cpp","enum","C++ enum"],"5":["cpp","enumerator","C++ enumerator"],"6":["cpp","member","C++ member"],"7":["cpp","templateParam","C++ template parameter"],"8":["py","module","Python module"],"9":["py","class","Python class"]},objtypes:{"0":"c:macro","1":"cpp:class","10":"py:method","11":"py:attribute","12":"py:function","2":"cpp:function","3":"cpp:functionParam","4":"cpp:enum","5":"cpp:enumerator","6":"cpp:member","7":"cpp:templateParam","8":"py:module","9":"py:class"},terms:{"0":[33,44,45,46,50,53,55,57,60,61,63,65,66,67,68,69,70,71,72,73,74,75,76,77,79,80,87,89,90,91,92,93,94,95,97,98,99,102],"000":[91,92,93,94],"0000":81,"01":[70,81,87],"0208":87,"03":81,"0358":87,"0383":87,"04":[87,97],"0435":87,"0464":87,"0530":87,"0678":87,"0805":87,"0818":87,"0932":87,"0f8157a5fc5329943b338b893591373350afa90ca81239cdadd7580cd1eba254":68,"0x7fb370651af0":76,"1":[3,4,33,45,46,49,50,53,55,56,57,59,61,63,64,65,66,67,68,70,71,72,73,74,75,76,77,78,80,81,84,86,87,88,89,92,94,96,98,99,101,102],"10":[50,68,71,72,76,84,86,87,96,97,99],"100":[66,72],"1000":97,"1012":56,"1013":56,"1024":[53,71,75,76,96],"1045":87,"1048576":[46,50,65,71,76],"1056":87,"1063":87,"1073741824":[46,50,65,71,76],"109":87,"11":[56,67,68,80,84,87,97],"119":86,"12":[56,57,68,80,84,86,87,97],"120":[86,87],"123":81,"129":86,"13":[80,84],"136":97,"137":86,"138":86,"14":[84,94,97,98],"1409":99,"15":[80,84],"1502":87,"1549":87,"1556":99,"16":[75,84,86,87,88],"1691":87,"17":84,"18":[84,87],"19":[81,84],"1994":99,"1b":67,"1d":56,"1e":53,"2":[33,44,55,57,61,64,65,66,68,69,70,71,73,74,75,76,78,80,81,84,86,87,90,91,94,95,98,99,101],"20":[57,84,92,94,98],"2009":99,"2010":99,"2012":81,"2014":99,"2015":67,"2017":67,"2019":67,"2020":[69,87],"2021":69,"2022":[67,69],"2023":99,"2048":[66,72],"2052":[91,92,94],"22":97,"224":[57,64,71,72,75,76,92,96,97,98,101],"225":[72,97],"229":97,"23":[50,56,71,76,81],"234375":97,"24":56,"244":[71,75,76],"248":56,"249":56,"25":[66,72,87],"256":97,"258":80,"27":[57,87],"28":87,"2802":87,"2822":80,"287":80,"29":87,"2c3":81,"3":[46,50,53,56,57,59,64,65,66,70,71,73,74,75,76,80,81,84,86,87,89,92,96,98,99,101,102],"30":[92,94],"300":[53,89],"31":87,"32":[53,75,86,87,88,99,102],"320":99,"32bit":53,"33":87,"33554432":[66,72],"346":87,"35":87,"36":87,"3677":56,"37":87,"38":86,"39":86,"3_cuda12":68,"3d":[55,66],"4":[57,59,64,65,66,68,70,73,78,80,81,84,87,91,93,94,98],"406":97,"429688":97,"4465":99,"456":97,"468750":97,"4822":99,"485":97,"4914":99,"4e5b0f6e860910eb510fa70a76ee3eb9825e7a4d":68,"5":[53,57,59,60,65,66,67,68,71,73,80,81,84,86,87,91,97,98],"50":96,"512":[53,71,75,76,96,98],"523438":97,"53":81,"536870912":[46,50,65,71,76],"539":87,"56":87,"576":87,"6":[56,57,59,68,70,84,86,87,98],"622":56,"64":[66,75,88],"64bit":53,"664062":97,"7":[55,57,59,60,67,75,84,87,91,92,94],"72048":68,"7302":81,"79d77a769c7e7175abc7b5c2ed5c494148c0618a864138722c887f95c623777c":68,"8":[3,53,56,64,65,67,68,75,80,81,84,87,92,97,98],"8000":97,"8001":97,"8002":97,"84":[86,87],"9":[84,87,97],"90":97,"92":97,"9223372036854775807":70,"96":67,"abstract":[59,61,81],"boolean":[66,75],"break":[65,66,80],"byte":[74,75,76,96],"case":[0,1,2,47,50,54,55,57,59,61,63,65,66,68,75,98,99,100],"catch":[56,87],"char":[3,4,45,53,87],"class":[17,29,30,45,46,47,52,59,61,65,66,73,76,80,81,86,87,88,91,96,98,99],"const":[0,1,2,3,4,29,30,31,32,33,35,37,45,46,47,56,61,70,87,99],"default":[0,1,2,3,4,16,29,30,33,44,46,47,49,50,53,55,57,63,65,66,68,71,72,75,76,78,79,80,87,88,89,98,99,100,101],"do":[54,55,56,57,61,64,66,79,81,86,87,88,99,102],"enum":[0,1,2,43,46,47,52,71,73,76,99],"export":[68,69,71,98,101],"final":[54,57,58,60,68,91,92,94,96],"float":[50,53,64,65,70,75,86,87,88,89,91,94,99],"function":[0,1,2,3,4,47,49,50,52,55,56,57,59,61,63,65,66,68,86,87,89,91,92,94,96,97,98,99,100,102],"import":[53,56,57,64,65,66,68,78,80,86,87,88,89,97,98,100,101],"int":[0,3,4,35,45,46,50,53,55,57,64,65,70,71,72,74,75,76,78,87,98],"long":[50,53,54,64,75,80,81],"new":[0,1,2,3,4,32,33,47,49,50,57,59,60,61,63,65,66,73,76,80,87,90,92,94,95,97,98,101],"public":[0,1,2,3,4,45,46,47,48,49,50,81,99],"return":[0,1,2,3,4,23,24,29,30,31,32,33,34,37,43,44,45,46,47,55,56,57,58,59,60,61,63,65,66,71,72,73,75,76,86,87,88,91,97,98,99,101],"short":[56,80,81,98],"static":[49,50,54,61,64,71,75,76,78,87],"super":[45,86,91,98],"switch":100,"throw":[53,56,87],"true":[0,1,2,4,47,50,56,57,61,63,65,66,70,71,72,75,76,78,81,87,89,91,92,93,94,97,98,99,100,102],"try":[60,80,81,87,89],"var":70,"void":[3,4,25,26,27,28,35,36,43,45,46],"while":[55,57,68,96,97,99,100],A:[4,29,30,32,33,48,49,55,56,57,61,66,68,72,75,76,81,93,97,99],And:87,As:[57,66,68,87],At:79,But:[80,87],By:[29,30,52,57,68,78,86,98],For:[54,57,63,64,65,66,68,72,78,80,81,86,87,89,91,96,97,98,99,100,101],If:[27,33,54,55,56,57,63,64,65,66,68,72,73,75,78,80,87,88,91,97,98,99,100,101,102],In:[0,1,2,47,54,55,57,58,59,60,61,65,66,68,80,81,83,88,90,95,96,97,98,99,100,101],Is:[24,75],It:[53,55,56,57,58,60,61,66,68,69,78,80,96,100],Its:[61,80],Not:3,On:57,One:[66,80,81,87,96,100],Or:80,Such:55,THE:80,TO:[68,87],That:80,Thats:87,The:[1,47,49,50,53,54,55,56,57,58,59,60,61,63,64,65,66,68,71,73,75,76,78,81,86,88,89,95,96,97,98,99,101],Then:[57,89,99],There:[4,54,55,60,61,63,64,66,67,68,81,86,96,97,98,99,100],These:[54,55,57,59,63,65,68,71,78,80,97,99,101],To:[1,47,53,55,57,65,68,71,78,86,87,88,89,97],Will:31,With:[78,80,87,97,99],_:[66,74,80],___torch_mangle_10:86,___torch_mangle_4847:59,___torch_mangle_5:86,___torch_mangle_9:86,__and__:70,__attribute__:44,__derive_index:70,__getitem__:70,__gnuc__:44,__init__:[63,74,75,80,86,91,98],__is__:70,__isnot__:70,__main__:[91,92,94],__name__:[91,92,94],__not__:70,__or__:70,__range_length:70,__round_to_zero_floordiv:70,__torch__:[59,86,87],__torch___pytorch_detection_ssd_src_model_ssd300_trt_engin:59,__torch___torchvision_models_resnet____torch_mangle_4847_resnet_trt_engin:59,__visibility__:44,__xor__:70,_all_:56,_aten_lowering_pass:63,_c:[71,76,89],_convolut:[70,87],_devic:[65,71,76],_dynamo:[65,91,92,94],_enum:75,_export:98,_input:76,_jit_to_backend:89,_jit_to_tensorrt:76,_leaky_relu:55,_remove_lowering_pass:63,_rendered_examples_jupyt:95,_rendered_examples_python:95,_script:76,_set:91,_shapemod:75,_theme:85,_validate_not_a_forked_repo:97,a1b:81,aarch64:60,ab:70,abi:100,abl:[54,56,61,63,66,89,99],about:[53,54,59,61,68,75,78,87,97,98],abov:[25,55,57,63,66,68,73,79,80,87,92,94,98],absolut:[53,68],ac:83,acc_mod:66,acc_norm:66,acc_op:66,acc_op_convert:66,acc_ops_sigmoid:66,acc_trac:66,acceler:[65,72,90,95,102],accept:[49,53,55,59,61,75,87,88,91],access:[56,61,66,78,87,89],accord:[61,65,76],accordingli:[66,78,98,100],account:[55,97],accumsan:83,accumul:[50,71,76],accuraci:[96,99],achiev:[57,96],aco:70,acosh:70,acoust:96,acquir:87,across:[50,53,56,57,65,71,76,78,98],acthardtanh:61,action:[66,80],activ:[66,76,80,87,96,99,100,102],activationtyp:[61,66],actual:[56,59,61,66,73,86,87],ad:[25,53,54,55,57,63,66,98],adaptive_avg_pool1d:70,adaptive_avg_pool2d:70,adaptive_avg_pool3d:70,adaptive_max_pool1d:70,adaptive_max_pool2d:70,adaptive_max_pool3d:70,adaptiveavgpool2d:98,add:[26,54,55,56,57,61,64,67,68,70,73,78,80,85,87,88,98],add_:[56,70,87],add_activ:66,addactiv:61,addit:[55,56,65,66,67,75,87,96,98,101],addition:65,addlay:87,addmm_replac:55,address:[81,98],addshuffl:87,adipisc:[81,83],adjac:[57,71,80],adjust:80,adopt:96,advanc:[81,90,95,99],advis:80,aenean:83,afford:66,aforement:97,after:[53,54,56,57,63,66,67,86,87,88,91,92,94,97,100],again:[45,59,61,80],against:[53,87],agx:46,ahead:[69,87],aim:56,alert:100,algo_typ:[74,99],algorithm:[3,4,29,30,45,66,74,99],algorithm_selector:66,alias:44,align:80,align_corn:70,aliquam:83,aliquet:[81,83],all:[16,43,44,45,46,50,53,55,56,57,59,63,65,66,67,68,71,73,75,80,81,86,87,88,95,96,97,99,100],alloc:61,allow:[49,50,53,54,55,56,57,63,65,66,67,71,75,76,78,92,94,100],allow_gpu_fallback:[46,47,71,75,76,89,99,102],allow_shape_tensor:[46,50,76],allow_tf32:70,almost:87,along:[55,98],alpha:[55,66,70,81],alreadi:[53,54,55,56,87,99],also:[29,54,55,61,63,65,67,68,78,80,81,87,88,95,96,99,101],altern:[49,57,63,64,88,96],although:80,altogeth:[57,78],alwai:[3,4,27,53,80],amet:[81,83],amount:71,an:[2,3,4,49,50,53,54,55,56,57,58,59,60,61,63,65,66,67,68,71,72,74,75,76,78,80,81,86,87,88,91,96,97,98,99,100,101],analogu:61,analysi:[57,98],analyt:78,analytics_id:78,ancient:80,ani:[49,53,54,55,61,63,65,66,70,71,74,75,76,78,80,87,88,98,99],ann:80,annot:[61,87],anonym:80,anoth:[80,81,86,88],ant:83,anyon:81,anyth:[80,81,100],aot:[69,87,98],api:[57,60,61,63,64,65,66,75,76,79,87,88,89,90,91,95,96,97,98,99,100],appear:[57,80],append:[70,98],appli:[63,64,99],applic:[1,29,47,53,56,60,65,71,87,88,89,100,102],apply_lowering_pass:[63,98],approach:57,appropri:67,apr:87,ar:[43,47,50,53,54,55,56,57,59,60,61,63,64,65,66,67,68,71,75,76,78,80,81,82,86,87,89,96,97,98,99,100],arab:81,arang:70,arbitrari:63,architectur:[68,69,96],archiv:68,arcu:[81,83],area:82,aren:87,arg0_1:98,arg:[54,55,63,66,74,75,84,87,96,98],arg_replacement_tupl:66,argc:87,argmax:70,argmin:70,argument:[49,53,55,56,59,61,63,65,66,71,75,76,80,81,87,88,98],argv:87,arithmet:57,around:[56,59,61,68,80,83,86],arrai:[3,4,33,54,55,76],arrayref:[46,49,50],artifact:67,arxiv:99,as_numpi:97,asin:70,asinh:70,aspect:53,assembl:[54,63,87],assign:[3,4,79],associ:[54,61,87,100],associatevalueandivalu:61,associatevalueandtensor:[61,87],assum:[33,89,98],atan:70,atanh:70,aten:[50,55,56,57,61,62,65,69,70,71,76,87,91,98],aten_:55,aten_ops_convolut:55,aten_trac:98,atol:53,attention_mask:98,attrdict:97,attribut:[55,56,57,59,66,80,87],auctor:83,audio:96,augu:83,author:[55,81],auto:[45,57,61,65,71,80,81,87,99,102],autocast:55,autodoc:[80,81],automat:[65,80,87,98],auxiliari:[65,71],avail:[53,55,61,63,65,66,68,71,78,102],averag:[50,53,65,71,76],avg:53,avg_pool1d:70,avg_pool2d:70,avg_pool3d:70,avgpool:98,awai:80,awaken:80,axi:70,b0:96,b:[67,68,70,81,97],b_hh:70,b_ih:70,back:[56,57,59,60,75,80,86,87],back_insert:45,backend:[63,76,79,89,90,91,93,94,95,98],backend_kwarg:91,background:[80,86],backlink:80,backward:66,bar:[78,80],base:[36,51,59,64,65,71,72,73,74,75,80,86,88,94,96,98,99],bash:68,basi:80,basic:[53,57,66,81,95,97],batch:[3,4,45,65,66,72,92,94,97,98,99,102],batch_norm:[61,70],batch_siz:[45,99],batched_data_:45,batchnorm:56,batchtyp:45,bathroom:80,bazel:[60,68],bazel_vers:68,bazelbuild:68,bazelisk:68,bazelvers:68,bdist_wheel:68,beat:81,becaus:[61,66,68,72,86,87],becom:61,bee:80,been:[54,61,65,68,81,87,101],befor:[50,55,56,57,60,61,66,71,76,87,97,101],begin:[45,66,68,80,91],beginn:86,begun:80,behav:82,behavior:[50,57,66,71,75,76,98,100,101],behind:80,being:[55,66,68,71,87],belong:80,below:[33,57,61,63,64,65,66,68,80,87,88,93,97],benchmark:[65,70],benefit:[61,87],bert:94,bertmodel:[94,98],besid:80,best:[66,71,80],beta:[55,66,70,76],better:[71,86,96],between:[55,56,57,61,68,80,81,99],bia:[56,70,87],bibendum:83,bibliograph:81,bigger:80,bin:68,binari:[45,99],binary_data:97,bind:[3,4,33,45,76,80],bird:97,bit:[50,61,66,71,75,76,87],bitbucket:78,bitbucket_url:78,bitwise_not:70,blandit:83,blank:80,blob:[55,62,68,78,99],block0:56,block1:56,block:[53,54,56,57,65,71,84],blog:69,blue:80,bmm:70,bodi:[55,80,81],bold:80,bool:[0,1,2,3,4,24,27,30,31,43,45,46,47,50,56,61,65,70,71,72,73,75,76,78,87,99],border:80,both:[55,57,65,68,69,72,78,80,86,99],bottom:78,bound:75,boundari:57,box:[80,98],bracket:80,branch:68,bread:80,brief:57,briefli:86,brontosaurus:80,browser:80,bsd:[43,44,45,46],buffer:[3,4,66],bui:81,build:[29,30,34,50,53,54,58,60,61,64,65,66,71,75,79,84,87,92,94,99],build_fil:68,build_model:66,buildcommandarg:67,builddirectori:67,builder:[64,65,66,71],builderconfig:46,buildroot:67,built:[33,53,59,60,68,71,76],builtin:66,button:[78,80],bytearrai:[66,76],c10:[0,1,46,47,49,50,87,99],c:[43,44,45,46,53,60,65,67,70,71,72,81,88,97,100,102],c_api:62,c_str:[61,87],cach:[3,4,29,30,45,53,65,66,72,74,87,99],cache_:45,cache_fil:[45,74,99],cache_file_path:[3,4,29,30,45],cache_file_path_:45,cache_size_:45,cachecalibr:[74,99],cackl:81,calcul:[49,54,57,87],calibr:[3,4,29,30,45,50,53,71,74,76,87,99],calibration_cache_fil:[29,30,99],calibration_dataload:[30,99],calibration_dataset:99,calibrationalgo:[74,99],call:[29,30,32,50,55,56,59,61,66,71,72,76,80,86,87,89,91,92,94,96,98,100],call_funct:[55,63,66,98],call_modul:55,callabl:[65,71,75],caller:63,callmethod:86,can:[0,1,4,29,30,37,47,48,49,50,53,54,55,56,57,58,59,60,61,63,64,65,66,68,71,75,76,78,80,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101],canada:81,cannot:[49,56,57,66,68,71,75,76,79,86,98],canon:78,canonical_url:78,capability_valid:55,capabl:[17,46,50,53,59,71,75,76,89],capbility_valid:55,capit:80,caption:[80,83],captur:98,cast:[3,4,56],castl:93,cat:[57,68,70],categor:55,caught:56,caus:[61,65,78,91,92,94,100],cd:[68,97],cdll:87,ceil:70,ceil_mod:70,cell:81,center:68,centercrop:97,cerr:87,certain:[66,68,91],cfg:57,chain:[55,61],challeng:[65,97],chanc:61,chang:[29,56,57,60,63,65,66,67,76,78,97,98,99,100],changelog:84,channel:[2,75,79],channel_last:[71,75,76,96],channels_last:75,charact:80,check:[0,1,31,47,53,56,61,66,76,87,97,100],check_method_op_support:76,check_method_operator_support:[21,42,46,51],checkmethodoperatorsupport:87,child:81,children:66,choic:[68,74],choos:[65,66,71,86],cifar10:99,cifar:99,clamp:70,clamp_max:70,clamp_min:70,class_count:97,classif:[86,87,96],classifi:[81,96],classification_index:97,classmethod:75,clean:[57,63,67,80,91,92,94],cleanli:57,clear:45,cli:[53,88],click:67,clickabl:80,clone:[63,67,70],cloned_placehold:63,close:87,closer:56,closet:80,cloud:93,cmake:67,cmake_build_typ:67,cmake_cuda_flag:67,cmake_cxx_flag:67,cmake_module_path:67,cmakecommandarg:67,cmakeset:67,cnn:96,co:[70,81,96],coalesc:63,code:[57,60,63,65,66,79,81,86,87,91,92,93,94,95,98,99],coeffici:96,collapse_navig:78,collat:81,collect:[55,57,65,71,76,87,88],colon:80,color:[24,27,73,80],colored_output_on:[27,43,73],column:81,com:[55,62,65,68,87,91,92,94,97,99,100],combin:[57,65,66],come:[66,68,79,97],command:[53,65,68,80,81,86,87,97],comment:[68,80],commodo:83,common:[54,56,66,72,80],common_subexpression_elimin:56,commonli:81,commun:[50,53,65,67,71,76,87],compar:[66,71,88],comparis:[0,2],comparison:[1,47],compat:[0,1,47,56,59,65,66,67,71,76],compil:[21,31,37,42,46,50,51,53,55,56,57,59,61,63,66,71,72,73,75,76,78,86,88,89,97,99,100,102],compilation_kwarg:94,compilationset:[65,71,91,101],compile_engine_and_inf:[91,92,94],compile_spec:[98,99,102],compilegraph:[87,99],compilesepc:33,compilespec:[3,4,21,32,37,42,46,51,57,76,87,99,102],compilespecstruct:51,complet:[57,64,86,87],complex:[48,50,65,68,86,88],complianc:53,compliat:99,complic:68,compon:[58,60,86,100],compos:[66,86,97,99],composit:[55,87],compound:96,comput:[50,65,66,68,71,80,96,99],compvi:93,conceiv:80,concept:95,concorr:97,condimentum:83,condit:[57,80],conf:[78,85],confer:69,confidence_scor:97,config:[66,68,72,97],configur:[32,37,49,63,68,71,75,76,84,87,97,98,99],configurationtyp:67,configureset:67,congu:83,connect:[56,71,76,80,97,102],consectetur:[81,83],consecut:[57,64],consid:[57,76,87],consider:97,consist:[56,66,80,100],consol:53,consolid:[57,86],constant:[54,55,56,57,87],constant_pad_nd:70,constexpr:[0,1,2,46,47],constraint:64,constraint_dim:98,construct:[0,1,2,3,4,47,49,50,54,55,56,58,60,61,66,74,75,80,81,87,99],constructor:[0,2,47,49,50,59,86],consult:79,consum:[4,54,86],contact:81,contain:[30,31,53,54,55,56,57,61,66,68,72,75,80,81,86,87,97,99,100],content:[84,97,99],context:[54,58,59,60,65,73,100],contextnet:96,contigu:[2,49,50,53,71,75,76],continu:[66,80,100],contribut:65,contributor:87,control:[63,66,86,100],conv1:[86,87],conv2:[86,87],conv2d:86,conv:[50,53,87],conv_nod:55,conval:83,convect:49,conveni:[63,94,96,99,100],convent:33,converison:66,convers:[55,56,57,59,64,66,75,76,87,98,101],conversioncontext:55,conversionctx:[55,61,87],convert:[3,4,31,32,37,53,56,57,58,60,64,65,69,71,75,76,88,89,92,94,96,100],convert_method_to_trt_engin:[21,42,46,51,75,76,89],converter_util:55,convertgraphtotrtengin:87,convien:50,convienc:[3,4,50],convolut:[71,76,99,102],convtert:66,coordin:60,copi:[45,61,66,70,74,81,97],copy_:70,copyright:[43,44,45,46,81,87],core:[46,53,56,57,60,65,71,75,87,102],core_id:75,corpor:[43,44,45,46],corpu:96,correct:[59,68,78],correctli:68,correctness_atol:72,correctness_rtol:72,correspod:55,correspond:[55,61,66,68,75,100],cosh:70,cost:[98,100],could:[57,65,66,92,94,100],count_include_pad:70,coupl:[54,60,66,100],cout:87,cover:[65,95,96],coverag:71,covert:71,cp:68,cpp:[14,15,43,44,45,46,52,56,60,68,87,99],cpp_frontend:99,cppdirectori:51,cppdoc:87,cpu:72,cra:83,crash:100,creat:[29,30,33,53,54,55,57,59,61,66,69,76,80,87,97,98],credit:87,criteria:[57,58,60,65],cross:80,cs:99,csrc:[56,62],cstddef:99,ctestcommandarg:67,ctrl:67,ctx:[55,61,87],ctype:87,cu118:68,cu121:68,cuda:[50,59,64,66,67,71,72,75,87,88,89,93,97,98,99,100,101],cuda_graph_batch_s:[66,72],cuda_runtim:[21,46],cudafloattyp:87,cudasetdevic:35,cudnn:[67,68],cudnn_en:70,cudnn_root_dir:67,cumsum:70,curabitur:83,curl:[68,80],current:[23,55,57,59,61,63,64,65,66,67,68,71,72,76,78,98],cursu:83,custom:[53,63,64,66,90,95],custom_class:[21,46],custom_mapp:66,customclasshold:[46,49],cut:80,cxx11:100,d:[53,80,81,87,102],d_silence_experimental_filesystem_deprecation_warn:67,dai:69,dapibu:83,data:[0,2,3,4,29,30,45,47,49,50,53,54,57,58,60,61,65,66,70,71,72,74,75,76,80,84,88,96,99],data_dir:99,data_item_1:79,data_typ:97,dataclass:[66,91],dataflow:[61,87],dataload:[4,29,30,45,50,74,99],dataloader_:45,dataloadercalibr:[74,99],dataloaderopt:99,dataloaderuniqueptr:[4,45],dataset:[29,74,96,99],datatyp:[1,21,39,46,47,49,50,51,71,75,76,88,97],datatypeclass:51,date:[63,81],david:81,dbg:68,dcmake_build_typ:68,dcmake_module_path:68,dead_code_elimin:56,deal:61,debug:[16,27,46,50,53,61,63,65,67,71,73,76,89,91,92,94],debugg:[53,71,76],decid:75,declar:68,decomp_t:98,decompos:55,decomposit:[64,65,71],deconvolut:102,decor:[55,63,66],decror:55,dedic:[56,81],deep:[61,65,69,78,99,102],deeplearn:[62,66],def:[55,63,66,80,86,88,91,97,98],defin:[0,1,2,3,4,16,17,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,44,47,48,49,50,52,53,55,66,75,78,86,87,88,91,94,96,99],definit:[52,55,61,80],deiti:80,delet:[0,1,2,46,47,56],delimit:56,demo:[80,99],demonstr:[65,80,81,82,96,97,99],demostr:96,denot:80,dep:[67,68],depend:[29,34,54,60,65,66,67,71,87,88,97,100],depickl:59,deploi:[58,60,69,87,97,99],deploy:[53,87,88,96,97,99,100,102],deprec:[66,70],depth:[65,78,96],descclassnam:80,descnam:80,describ:[50,57,61,86,89,90,95,97,98],descript:[57,81],deseri:[75,76,87],design:[66,96,102],desir:[63,71,81,99],desktop:67,destini:81,destroi:[61,81],destructor:61,detail:[65,66,86,87,97,98,100],detect:[49,59],determin:[55,56,65,66,98,100],determinist:70,develop:[55,66,67,68,69,80,81,87],deviat:53,devic:[21,33,35,39,46,50,51,53,59,65,70,71,72,74,75,76,88,89,93,96,99,102],device_typ:[46,47,75,89,99,102],deviceclass:51,devicetyp:[21,39,46,47,51,75,76,89,99,102],devicetypestruct:51,diam:83,dict:[55,71,75,76],dictionari:[55,75,76,89,91],dictum:83,dictumst:83,did:80,didn:80,differ:[29,56,57,60,65,66,68,78,86,100],diffus:[90,95],diffusionpipelin:93,dignissim:83,dilat:70,dim0:70,dim1:70,dim:[66,70,72,97,98],dim_int:70,dim_intlist:70,dimens:[49,56,66,72,96,98],direct:[63,84,100],direct_output:63,directli:[61,63,64,67,68,69,74,90,91,95,98,99],directori:[18,19,20,21,43,44,45,46,51,67,68,99],disabl:[53,65,71,73,78,79,100],disable_memory_format_check:75,disable_tf32:[46,50,65,71,76,99],disallow:63,disconnect:80,discret:80,discuss:[64,65,97],disjoint:55,disk:101,displai:[53,63,65,73,78,100],display_github:78,display_gitlab:78,display_vers:78,dist:68,distribut:[65,68,75,87,99,100],div:[57,70],div_:70,div_lgamma:57,divisor_overrid:70,django:79,dl:80,dl_open:100,dla:[1,46,47,50,53,65,69,71,75,76],dla_cor:[46,47,53,75,89,99,102],dla_global_dram_s:[46,50,53,65,71,76],dla_local_dram_s:[46,50,53,65,71,76],dla_sram_s:[46,50,53,65,71,76],dla_standalon:53,dlacor:53,dll:53,do_not_merg:57,doc:[60,62,68,78,79,80,85],docker:97,docsrc:60,docstr:[80,81,88,98],document:[43,44,45,46,51,60,78,80,81,85,86,87,89,97,99,100],docutil:[80,81],doe:[44,45,56,57,61,63,66,80,92,94,99],doesn:[68,80,86,87],dolor:[81,83],domain:[49,75,81,99],don:[61,66,78,80,81,97,98,99],done:[54,57,60,97],donec:[81,83],dont:43,dothismethod:80,dotpai:79,dotpayprovid:79,doubl:[46,49,50,53,64,71,75,76,80,100],down:[66,68,78],download:[68,84,91,92,93,94,95,97,99],downstream:[64,96],doxygen_should_skip_thi:[45,46],dpython:[65,71,75,76],dram:53,dream:81,driver:68,drop:[68,78],dryrun:65,dt:80,dtensorrt_root:68,dtorch_dir:68,dtyep:72,dtype:[46,49,50,53,64,65,66,70,71,72,75,76,88,94,96,98],dual:80,due:[3,4,68,79,80],dui:[81,83],dummi:98,dump:[36,53],dump_build_info:[21,39,46,51,75],dump_lowering_pass:63,durat:[65,80],dure:[50,53,55,57,61,64,65,71,74,96,98,99,100],dyanmo:87,dynam:[49,50,64,66,69,71,72,75,76,91,93,94],dynamic_batch:[66,72],dynamic_dim:98,dynamic_input:98,dynamo:[64,65,75,87,91,92,94,98],dynamo_convers:65,dynamo_tensorrt_convert:55,e:[29,30,53,56,61,66,67,68,72,75,86,87,99],each:[3,4,50,54,56,57,59,61,65,66,68,71,72,78,80,87,100],eager:98,eagerli:98,ear:80,earli:66,eas:44,easi:[53,54,56,87,99],easier:[55,58,60,61,66,71,87,99],easiest:68,easili:[3,4],echo:80,ecosystem:69,edg:[55,80],edit:[55,67,68,78],edu:99,effect:[55,56,65,66,71,78,87,96,99],effici:61,efficientnet:96,efficitur:83,eg:[55,97],egesta:83,eget:83,either:[48,49,53,61,63,71,75,76,78,80,86,87,88,101],el:70,eleifend:81,element:[59,66,80,81,84],element_typ:45,elementum:83,eliminate_dead_cod:63,elit:[81,83],elk:80,els:[44,45,49,76,80,81],elu:70,emb:[33,53,64,76,81],embed:[53,55,59,70,76,80,102],embed_engine_in_new_modul:[21,42,46,51,76],embedding_param_valid:55,emit:54,emphasi:80,empti:[50,71,72,76,81,86],emum:[16,17],en:78,enabl:[3,4,24,50,53,55,57,58,60,65,66,71,72,73,74,76,78,92,94,100],enable_experimental_decomposit:[65,71],enable_precis:87,enabled_precis:[46,50,64,71,75,76,87,88,89,91,92,94,97,99,102],enalbed_precis:102,encod:[59,96],encompass:76,encount:[57,65,68,91,92,94,98],encourag:97,end:[45,53,61,63,70,71,76,80,87,91,92,93,94,99],end_dim:[70,87],endif:[44,45,46],energi:80,enforc:[55,87],enforce_tensor_typ:55,engin:[0,1,17,32,33,37,46,47,49,50,53,54,57,58,60,63,64,65,71,72,75,76,78,87,88,89,92,94,98,99,100,102],engine_cap:[65,71],engine_converted_from_jit:87,enginecap:[21,39,46,50,51,65,71,75,76,89],english:96,enhanc:80,enim:83,ensur:[29,55,56,57,63,65,67,68],enter:[54,75],entir:80,entiti:80,entri:[50,61],entropi:[29,30,99],entropy_calibr:74,entropy_calibration_2:[74,99],enumer:[0,1,2,16,17,47,71,74],environ:[66,97],ep:[65,70,71,101],eq:[70,80],equat:80,equival:[32,58,60,61,71,76,86,87,92,94,99],equivil:37,erat:83,erf:70,eric:80,ero:83,error:[16,50,53,54,56,60,65,66,71,73,76,80,87,98],essenc:80,essenti:66,est:83,establish:55,et:83,etc:[66,78,80,102],etiam:83,eu:83,euismod:83,eval:[64,87,88,91,92,94,97,98,101],evalu:[58,59,60],evaluated_value_map:[54,61],even:87,event:[49,65],everi:[57,72,87,100],everyth:16,evolv:63,ex:[0,1,2,33,47,76,81,83],exact:97,exactli:98,examin:66,exampl:[49,57,59,60,61,66,67,68,69,71,73,75,76,78,79,81,84,86,87,88,90,91,92,93,94,95,97,99,100],example_tensor:75,exceedingli:80,except:66,exception_elimin:56,excerpt:81,excit:96,execpt:56,execut:[33,50,53,56,58,59,60,64,65,66,68,69,71,72,75,76,86,87,97,99],execute_engin:[59,87],exert:80,exeuct:59,exhaust:87,exist:[4,31,32,37,55,64,66,71,74,75,76,96,99],exit:[91,92,94,97],exp:70,exp_program:64,expand:[56,70],expand_a:70,expect:[49,55,56,61,75,87,88,96],experiment:[66,76],experimental_decomposit:98,explain:[65,66],explan:[65,66],explic:45,explicit:[0,1,2,3,4,46,47,56,66,72,80,99],explicit_batch_dimens:[66,72],explicit_precis:72,explicitli:[57,58,60,76,88,89,99],explict:45,explictli:0,explor:95,expon:70,exported_program:[65,71,101],exportedprogram:[64,71],expos:99,express:80,ext:[80,81],extend:[58,60,61,67,70,87,96],extens:67,extent:87,extern:[78,80],extra:[68,87],extract:[63,87,96],extrem:80,ey:80,f16:[53,87,102],f32:53,f:[63,65,66,80,86],facilisi:83,fact:68,facto:80,factori:[4,29,30,65,71,99],fail:[65,71,87,102],fake_quantize_per_channel_affin:70,fake_quantize_per_tensor_affin:70,fall:[69,75],fallback:[53,58,60,61,102],fals:[0,1,2,3,4,45,46,47,50,55,63,65,66,70,71,72,75,76,78,79,80,81,87,89,91,93,94,99,100],fame:83,familiar:97,far:[66,80],fashion:[87,96],fast:[50,53,65,71,76],faster:[71,96],faucibu:83,fc1:[86,87],fc2:[86,87],fc3:[86,87],fc:[50,53,56],feat:[86,87],featur:[53,57,66,87,89,93,96,99],fed:[3,4,49],feed:[29,30,87],feedforward:96,feli:83,feugiat:[81,83],few:[66,68,75,98],field:[3,4,64,72,75,99],fifth:81,figur:[57,81,83],file:[0,1,2,3,4,5,6,7,8,9,10,11,12,16,17,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,47,48,49,50,53,55,57,59,60,65,66,67,68,71,72,74,75,76,78,79,81,85,87,97,98,99],file_path:53,filepath:67,find:[4,66,68,87],finder:68,finibu:83,finish:66,first:[49,54,55,56,66,80,81,87,88,91,97,99],first_output:65,firstli:97,fit:[65,80],fix:[50,66,80,100,102],fixed_s:[46,50],flag:[53,57,58,60,68,74,88,100],flaten:50,flatten:[46,48,70,86,87,98],flatten_convert:87,flesh:97,float16:[53,75,93],float32:[49,50,53,64,65,66,71,75,76,98],float64:[65,71,75,76],float_int:70,floor:70,floor_divid:70,floordiv:70,flow:[61,66,80,86,96],flox:80,flush:80,fly:86,fold:81,folder:[66,67],follow:[33,53,55,57,59,63,64,65,66,67,68,76,78,80,81,85,86,87,90,95,96,97,98,99,100,101],foo:[66,80,81],foo_kwarg:66,foo_nod:66,forc:[53,64,66,71,76,78],force_fp32_output:66,forced_fallback_op:57,form:[54,75,80,88,97],format:[33,46,49,50,53,65,70,71,75,76,80,81,88,96,97,101],forth:81,forum:68,forward:[29,30,32,33,57,59,61,65,71,75,76,86,87,88,89,91,98,99],found:[43,44,45,46,64,68,80,87,99,100],four:[80,81],fp16:[0,49,50,53,65,66,72,87,88,93,102],fp32:[0,49,50,53,65,66,71,76,96,97,99],fp64:0,frac:80,freed:61,freeze_modul:56,frequent:64,friend:46,fringilla:83,from:[0,1,2,3,4,29,30,45,47,49,50,53,54,56,57,58,59,60,61,64,65,66,67,69,71,72,76,78,79,80,81,86,87,93,94,96,97,98,99,100],from_pretrain:[93,94,98],from_tensor:[66,75],front:[63,71],frontend:[64,71,88,90,92,94,95,98],frozen:55,fssl:68,fstream:[20,45],full:[46,50,53,61,65,71,73,87,91,92,93,94,97,99,100,102],fulli:[31,53,56,65,71,76,87,99,102],further:[57,65,66],furthermor:65,fusc:83,fuse_addmm_branch:56,fuse_flatten_linear:56,fuse_linear:56,fusion:[61,63,66],futur:[65,66,71,76,98],fx2trt:72,fx2trt_exampl:66,fx:[55,63,64,65,71,75,87,88,98,101],g:[29,30,53,56,66,67,68,72,75,80,99],g_:80,galleri:[91,92,93,94,95],gamma:70,gatewai:79,gather:57,gaurd:44,gcc:[60,87],ge:70,gear:[71,99],gener:[3,4,29,53,56,59,60,61,63,65,66,67,68,71,72,78,80,81,84,86,87,91,92,93,94,95,98,99],get:[0,1,2,3,4,23,34,45,47,56,57,61,63,64,66,73,75,87,96,97,99],get_batch:74,get_batch_impl:45,get_batch_s:74,get_build_info:[21,39,46,51,75],get_cache_mode_batch:74,get_decomposit:98,get_is_colored_output_on:[18,40,43,51,73],get_logging_prefix:[18,40,43,51,73],get_output:66,get_reportable_log_level:[18,40,43,51,73],getattr:[56,59,86,87],getbatch:[3,4,45],getbatchs:[3,4,45],getdimens:[61,87],getitem:55,getoutput:[61,87],git:84,github:[55,62,65,68,78,87,91,92,94,97,99,100],github_url:78,gitlab:78,gitlab_url:78,give:[66,78,80,98],given:[49,50,53,55,56,66,71,72,74,75,76,86,87,88,89,98],global:[26,53,65,71,87],gm:[63,71],gnu:68,go:[45,56,57,66,86,87,91,92,93,94,96,97],goal:[61,65],goe:[66,80],good:[45,61,66,80],goodger:81,googl:78,got:[80,87],gpu:[1,32,35,37,46,47,53,65,66,71,75,76,87,89,97,99,100,102],gpu_id:[35,46,47,53,75,76,89,99,102],grap:71,graph:[16,31,32,37,46,50,53,54,55,57,58,60,61,63,64,65,66,71,72,73,76,86,87,92,94,96,98],graph_break_count:65,graph_input:[46,50],graph_modul:[63,65,71,98,101],graphinput:[21,39,46,50,51],graphinputsstruct:51,graphmodul:[63,64,71,72,75,87,88,98],gravida:83,great:[80,87],greater:[55,71,73],greedi:57,group:[70,80,81],grpc:97,gru_cel:70,gt:70,gtc:69,guangzhou:81,guarante:57,guard:[56,65],guard_elimin:56,gui:80,guid:[65,79,95],gulf:97,gz:[68,80,81,99],h:[0,1,2,3,4,5,6,7,8,9,10,11,12,15,16,17,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,47,48,49,50,51,52,53,56,87,99],ha:[50,54,55,56,57,58,60,61,63,65,66,67,68,71,72,80,81,86,87,96,98,99,101],habit:83,habitass:83,hac:83,hack:45,hakaimagazin:97,half:[53,65,75,80,87,88,89,91,92,97,99,102],hand:97,handl:[55,56,57,59,65,66,98],happen:[66,86,98],hardtanh:[61,70],hardtanh_:70,hardwar:102,has_batch_dim:72,have:[29,33,45,53,54,55,56,57,61,63,64,66,68,71,72,75,76,80,86,87,88,92,94,96,97,98,99],haven:87,header:[78,80,81,87,97],heart:81,heaven:80,heck:80,heh:81,hehe:81,height:80,help:[27,53,54,61,65,66,87,96,100],helper:61,hendrerit:83,here:[45,54,55,57,59,64,65,66,68,78,80,81,86,87,97,98,99,100],hexagram:80,hfile:51,hi:[70,80,81],hidden:[44,78],high:[49,56,57,78],higher:[56,65,71,78,80,86],highli:[96,97],highlight:80,hinton:99,hit:57,hold:[47,48,49,54,61,75,99],holder:[59,82],holi:80,home:68,hood:60,hope:81,host:[50,53,65,68,71,76,97],how:[3,4,68,80,82,84,86,89,91,96,97,98,100],howev:[29,68,78,79,87,97,98],html:[62,68,80,86,99],html_theme:85,html_theme_opt:78,html_theme_path:85,http:[55,62,65,68,78,80,86,87,91,92,94,96,97,99,100],http_archiv:68,httpclient:97,hub:97,huggingfac:96,human:80,humankind:81,hx:70,hybrid:[69,71,76],hyperlink:80,hyphen:80,i8:53,i:[53,56,61,70,80,81,86,87,99],iaculi:83,icon:[78,80],id:[35,46,53,75,78,79,83,102],idea:[56,80],ideal:64,ident:[53,63,71],identifi:57,idx:70,ifndef:[45,46],ifstream:45,ignor:[55,75],iii:81,iint8calibr:[3,4,29,30,45,46,50,71,76,99],iint8entropycalibrator2:[3,4,29,30,45,99],iint8minmaxcalibr:[29,30,99],ilay:61,illustr:[55,66,96],imag:[93,97,99],imagenet:96,imagenett:96,images_:99,img1:97,img:97,img_path:97,imperdiet:83,impl:55,implement:[3,4,56,57,59,64,66,79,87,98,99,100],impli:[65,71],implic:56,implicit:[66,70,72,80],implicitli:75,implictli:75,improv:81,in_shap:87,in_tensor:86,incas:[45,98],includ:[13,15,16,34,36,43,44,45,46,52,53,55,57,58,59,60,63,65,66,68,71,72,78,80,86,87,90,95,99],includedirectori:51,includehidden:78,incompat:68,incorpor:81,increas:71,incur:100,indent:80,index:[33,62,63,68,69,70,76,78,84,99],indic:[70,78,80],indirect:80,individu:88,inetworkdefinit:[54,55],inf:65,infer:[56,65,66,71,75,76,87,90,91,95,96,98,99,100,101],inference_output:97,inferenceservercli:97,inferinput:97,inferrequestedoutput:97,info:[16,32,37,46,53,61,73,75,87],inform:[25,33,34,36,49,53,54,57,59,63,65,66,68,71,72,73,75,80,86,87,89,98,99],infrastructur:[97,99],ingest:60,inherit:[51,66,99],inheritenviron:67,initi:[80,91,92,94],injuri:80,inlin:[0,1,2,3,4,29,30,45,47,49,56,81,84,87],inner:[50,81,96],input0:[87,88],input1:[87,88,98],input2:[87,98],input:[3,4,21,29,33,39,45,46,48,50,51,53,54,55,56,57,59,61,63,64,65,66,70,71,72,73,75,76,81,86,87,88,89,91,96,97,98,99,101,102],input_0:[59,87],input_:55,input__0:97,input_binding_nam:[33,46,76],input_data:[86,88],input_file_path:[53,102],input_id:98,input_is_dynam:46,input_nam:[66,72,98],input_s:[57,87],input_scal:70,input_shap:[99,102],input_signatur:[46,48,50,76,88],input_spec:[53,66,72],input_tensor_spec:66,input_v:66,inputclass:51,inputrang:[57,87],inputs_bs2:98,inputtensorspec:[66,72,75],insert:[63,87,99],inserting_aft:63,inserting_befor:66,insid:[64,80,97],inspect:[61,86,87],instal:[69,84,87,97,100],installroot:67,instanc:[56,63,65,74,86,87,96],instance_norm:70,instanti:[58,59,60,61,87,93],instatin:[0,1,2,47],instead:[50,53,54,55,56,68,71,87,100],instnanti:59,instruct:[57,58,60,66,68,87,97,98],int32:[65,71,75,76,94,96,98],int64:[0,65,71,75,76],int64_t:[46,47,49,50,99,102],int8:[0,45,49,50,53,65,71,75,76,99,102],int8_t:[17,46],int8cachecalibr:[20,29,41,45,51],int8cachecalibratortempl:51,int8calibr:[3,20,30,41,45,51],int8calibratornamespac:51,int_float:70,integ:[71,75,83],integr:[69,91],intend:[68,91,92,93,94],intent:[56,80],interact:[64,80,91,92,93,94],interdum:83,interest:[56,80],interfac:[0,1,2,47,59,60,61,65,69,99],interfer:80,intermedi:[16,50,53,55,65,71,73,76,86,98],intern:[1,16,47,61,64,73,80,87,101],internal_error:73,internalerror:73,interpol:80,interpret:[59,66,80],interv:75,intro_to_torchscript_tutori:86,introduc:[64,66,96,98,101],introductori:69,invoc:91,invok:[63,65,66,86,87,100],involv:98,io:[45,97],iostream:[20,21,45,46,87],ipso:80,ipsum:[81,83],ipynb:[91,92,93,94],ir:[58,60,61,64,65,71,75,86,88,91,92,94],is_aten:72,is_floating_point:70,is_train:99,iscustomclass:61,ishap:50,ishapelay:76,isinst:[63,66],isn:[78,80],issu:[3,4,65,71,87,91,92,94,98],issubclass:63,istensor:61,istream_iter:45,it_:45,ital:80,item:[79,81],itensor:[54,55,61,66,87],iter:[20,45,50,53,54,65,71,74,75,76],its:[29,54,57,59,61,68,80,100],itself:[0,1,2,47,53,56,89,97],iv:81,ivalu:[46,48,50,54,59,61,87],jan:81,jetpack:68,jetpack_5:68,jetpack_x:68,jetson:96,jit:[31,32,33,37,46,48,50,53,54,56,57,58,59,60,61,62,65,69,71,75,76,86,87,88,89,97,101],jp_workspac:68,jpg:97,json:67,jump:97,jupyt:[91,92,93,94,95],just:[45,46,56,57,65,66,69,73,80,82,86,87,88,89,96,100],justo:[81,83],k:[70,99],kbool:[0,46],kchannelslast:[2,46],kchar:[0,46],kclip:61,kcontigu:[2,46,49],kcpu:[1,47],kcuda:[1,47,57,87],kdebug:[16,43,45],kdla:[1,46,47,102],kdla_standalon:[17,46],kdoubl:[0,46],keepdim:70,kei:[55,80,86,97],kept:81,kernel:[49,50,53,61,65,66,71,75,76],kernel_s:70,kerror:[16,43],keyboard:80,keyword:[55,63,71,75,76,91,94],kf16:[99,102],kfloat:[0,46,50],kgpu:[1,46,47],kgraph:[16,43,56],khalf:[0,46,87],ki8:99,kind:[54,66],kinfo:[16,43,45],kint:[0,46],kinternal_error:[16,43],klong:[0,46],know:[43,61,78,80],knowledg:80,kriz:99,krizhevski:99,ksafeti:[17,46],kstandard:[17,46,50],ktest:99,ktrain:99,kunknown:[0,2,46],kwarg:[55,66,71,74,75,96,98],kwarn:[16,43],l114c1:68,l124c3:68,l46:68,l53c1:68,l71:68,l:70,label:[80,96,97,99],lacinia:83,lack:[57,58,60,66],lacu:83,laid:87,lambda:[55,61,80,87,97],lang:79,languag:[79,80,81,86,97],laoreet:83,larg:[58,60,78,80,87,96,99],larger:[57,78,96],largest:70,last:[2,56,66,75],lastli:97,later:[29,71,87,101],latest:[67,68,78],latter:65,launch:97,layer:[47,50,53,54,56,61,63,65,66,71,76,87,96,97,98,99,102],layer_norm:70,layout:[2,49,70,71,75,76],ld_preload:100,le:70,lead:[80,100],leader:80,leaky_relu:[55,70],leaky_relu_:70,leaky_relu_convert:55,lean:71,learn:[65,68,69,87,97,99,102],leas:81,least:[80,81],leav:[56,63,65,71],lectu:[81,83],left:[78,80],legacy_calibr:74,legend:80,len:[63,70],lenet:[86,87],lenet_script:[86,87],lenetclassifi:86,lenetfeatextractor:86,length:[3,4,45,66,70,81,98],leo:83,let:[47,53,56,61,66,71,75,76,78,80,96,97],letter:[81,96],level:[18,23,25,26,40,43,45,51,55,56,57,60,65,66,71,73,76,84,86,97],levelnamespac:51,leverag:[66,90,95,99],lgamma:57,lib:[56,67,68,87],libero:[81,83],librari:[34,43,44,45,46,53,55,58,59,60,61,87],libtorch:[4,36,61,67,68,87,99],libtorch_pre_cxx11_abi:68,libtorchtrt:[53,68,87],libtorchtrt_plugin:100,libtorchtrt_runtim:100,licens:[43,44,45,46,67,87],light:80,ligula:83,like:[53,54,56,59,61,66,68,79,80,86,87,88,97,99,100],limit:[55,56,73,79,99],line:[53,68,81,87],linear:[2,57,70,75,86],link:[53,54,63,69,78,79,84,87,100],lint:63,linux:[60,68,87],list:[18,19,20,21,31,50,52,54,57,59,61,63,64,66,70,71,72,74,75,76,84,87,88,97],listconstruct:[54,57,59,87],listunpack:[59,87],liter:81,literal:81,literal_block:80,live:[61,80],ll:66,lo:70,load:[53,57,59,66,74,76,87,88,89,96,97,99,100,101],load_librari:100,loading_data_recip:99,loborti:[81,83],local:[53,56,68,78,87],local_instal:68,localhost:97,locat:[55,63,68,99],lock:79,log:[15,16,19,20,39,45,51,52,56,61,66,69,70,72,75,92,94],log_debug:61,logger:[63,73],logger_level:72,loggingenum:51,logic:[65,66],login:97,logist:66,loglevel:73,logo_onli:78,lone:81,longer:[65,71,78,100],look:[54,55,56,71,86,89,97,98,99],loop:[57,65,66],loop_unrol:56,lorem:[81,83],lose:78,loss:[96,99],lot:[61,64],low:[49,66],lower:[16,55,64,66,69,71,72,73,75,81,92,94,96,98,101],lower_exampl:66,lower_graph:56,lower_precis:[66,72],lower_tupl:56,loweralltupl:56,lowerprecis:[66,72],lowersimpletupl:56,lstm_cell:70,lt:70,ltorchtrt:100,luctu:83,lvl:[25,26,43],m:[68,81],machin:[59,68,97,99],macro:[5,6,7,8,9,10,11,12,15,18,20,21,43,45,46,51,52],mad:80,made:[56,58,60,80],maecena:83,magna:83,mai:[54,55,57,59,60,66,71,76,80,81,86,87,88,91,92,94,97,99,100],main:[55,56,57,58,59,60,61,64,66,68,78,80,82,87],mainli:66,maintain:[57,59,61],majest:93,majestic_castl:93,major:[60,66],make:[54,55,66,68,71,80,82,87,88,90,95,96,97,99,102],make_data_load:[4,99],make_int8_cache_calibr:[20,41,45,51,99],make_int8_calibr:[20,29,41,45,51,99],malesuada:83,man:[80,81],manag:[50,53,54,58,60,61,65,67,71,73,75,76,87,100],mangag:56,mani:[55,57,65,66,78,80,81],manipul:[55,63],mantissa:[50,71,76],manual:[66,79,80],map:[1,47,54,55,56,58,60,61,66,87,89,91,96,97,99],mapper:66,mark:[56,57,78],marknodesforfallback:56,markup:[81,84],markup_process:80,mask:70,masked_fil:70,massa:83,master:[62,68,99,100],mat1:55,mat2:[55,70],match:[55,56],math:84,matmul:[55,56,70,87],matrix:62,matter:66,matti:81,matur:60,mauri:[81,83],max:[49,53,61,70,75,78,98],max_aux_stream:[65,71],max_batch_s:[66,72,97],max_c:53,max_h:53,max_input_shap:72,max_n:53,max_pool1d:70,max_pool2d:[70,86,87],max_pool3d:70,max_shap:[46,49,64,66,71,75,76,88,96,98],max_val:[61,70],max_w:53,max_workspace_s:[66,72],maximu:83,maximum:[49,50,53,65,66,71,72,76,92,94,97],mayb:80,mb:53,md:62,me:[80,81],mean:[57,61,66,70,72,91,97,98],mechan:[61,65,66,96],medium:80,meet:75,member:[47,48,49,50,75],memeori:2,memori:[20,21,45,46,56,61,71,75,76,87,88],memory_format:[70,75],memoryformat:[2,46],men:80,mental:80,mention:98,menu:[53,78,80],menuselect:80,merg:57,messag:[16,25,26,53,73],meta:[66,84],metadata:[50,53,55,59,61,65,71,76,78],meth:80,method:[31,32,33,37,49,53,56,61,68,71,75,76,80,86,87,89,96],method_nam:[31,37,46,53,75,76,87],metu:83,mi:83,microsoft:67,middl:80,might:[56,68,78,98],min:[49,53,61,70,75,98],min_acc_module_s:72,min_block_s:[46,50,57,64,65,71,76,91,92,94],min_c:53,min_h:53,min_input_shap:72,min_n:53,min_shap:[46,49,64,66,71,75,76,88,96,98],min_val:[61,70],min_w:53,mind:80,mine:80,minim:[72,99],minimum:[49,50,53,57,64,65,71,73,76],minmax:[29,30,99],minmax_calibr:74,minor:67,minut:[91,92,93,94],misbuild:78,misc:55,mismatch:100,miss:[80,87],mix:98,mkdir:68,mm:97,mmb:80,mobilenet_v2:89,mobilenetv2:96,mock:98,mod:[53,57,66,71,84,87,99],mode:[66,88,98,99],mode_:99,model:[53,57,59,64,69,71,72,73,86,87,88,89,90,95,98,99],model_half:91,model_id:93,model_nam:97,model_output:98,model_repositori:97,model_torchtrt:73,model_trt:73,modif:[55,63],modifi:[55,57,63,66,81,98],modified_graph:63,modul:[31,32,33,37,46,50,53,57,58,59,60,61,65,66,67,68,69,71,72,75,76,79,80,81,88,89,91,96,98,99,101,102],modular:87,module_fallback:56,module_nam:53,molesti:83,momentum:70,morbi:83,more:[54,65,66,68,69,71,75,78,81,86,87,88,89,92,94,97,99,100],most:[60,66,68,72,97,100],mother:80,motion:80,mous:80,move:[30,45,56,59,76,87,99],ms:67,msg:[26,43,73],msvc:67,msvc_x64_x64:67,mu:80,much:[55,61,78,80,99],mul:[55,57,70],mul_:70,multi:53,multipl:[59,80,81,97,99,100],multipli:[50,71,76],must:[33,49,50,53,55,56,57,61,63,66,68,71,72,75,76,80,81,87,98,100],mutil:81,my:80,my_custom_pass:63,my_pytorch_model:66,myclass:80,mymodel:[57,64,88,98,101],mymodul:98,myself:81,n:[53,61,63,87,99],nabla:80,nam:[81,83],name:[3,4,31,33,37,45,55,57,59,61,66,67,68,72,75,76,80,81,86,87,89,97],namedtupl:66,namespac:[43,44,45,46,52,56,69,99],narrow:70,nativ:[55,60,62,87,98],native_funct:[55,62],natur:80,nav:[78,84],navig:78,navigation_depth:78,nbbind:[3,4,45],nchw:[2,71,75,76],ndarrai:55,ne:[56,70],nec:83,necessari:[43,63,65,100],need:[0,1,2,25,29,44,47,54,55,56,61,66,68,72,80,87,88,96,97,98,99,100],neg:70,negative_slop:70,neglig:100,nequ:[81,83],nest:[46,50,51,80,81],net:[55,61,80,81,87],netu:83,network:[29,30,55,61,66,87,96,97,99,102],neural:102,new_batch_size_input:92,new_batch_size_output:92,new_input:[92,94],new_lay:61,new_local_repositori:68,new_output:[92,94],new_siz:99,newer:68,next:[3,4,54,55,59,64,72,78,80,81,91,97,98,99],ngc:[68,97],nhwc:[2,53,75],nibh:[81,83],nickel:80,night:81,nightli:66,ninja:67,nisi:83,nisl:83,nlp:[29,30,99],nn:[56,62,66,71,72,75,76,86,87,88,91,98],node:[55,56,57,58,60,61,63,66,72,87,96,98],node_info:[61,87],noexcept:[3,4,45,99],non:[81,83,100],non_block:70,none:[61,65,66,70,71,72,73,74,75,76,78,80,91],nonetheless:80,nonexist:80,norm:70,normal:[0,1,2,47,66,80,86,87,97,99,102],normalized_shap:70,noskipw:45,notat:75,notatemoduleforfallback:56,note:[1,47,49,55,61,63,66,67,68,75,78,80,87,98,102],notebook:[60,69,91,92,93,94,95],now:[56,57,60,61,66,68,80,87,89,100],np:[55,97],nu:80,nulla:83,nullptr:[45,46,50],num:53,num_avg_timing_it:[46,50,65,71,76,89],num_it:53,num_op:53,num_us:98,num_work:99,number:[3,4,50,53,55,56,57,61,64,65,66,71,72,75,76,78,87,88,90,92,94,95,96],numel:70,numer:[53,66,81],numpi:[55,97],nunc:83,nvcr:97,nvidia:[32,37,43,44,45,46,53,62,66,68,71,75,76,87,91,92,94,97,102],nvinfer1:[3,4,29,30,45,46,50,61,99],nvinfer:[20,45],o:[68,80,97],obj:70,object:[0,1,2,3,4,47,49,50,53,59,61,63,64,65,71,73,74,75,76,89,98,99,101],obtain:96,obvious:86,occasion:[91,92,94],occur:65,odio:[81,83],off:[57,59],offer:[63,65],ofstream:[45,87],often:80,oh:81,ok:[80,87],okai:50,older:60,onc:[43,44,45,46,54,56,57,59,65,66,68,97,99,100],one:[48,55,56,61,65,66,73,75,80,86,87,88,91,92,94,97],ones:[43,57,58,60,68,80,87],onli:[1,3,4,16,29,45,47,49,53,55,56,57,60,61,65,66,71,72,73,75,80,98,99,100,102],onnx:56,onto:[53,59],op:[53,54,55,56,57,58,60,61,63,64,65,75,87,91,98,100],op_and_target:66,op_evalu:55,op_nam:53,opcod:55,open:[67,96,97],oper:[0,1,2,3,4,31,45,46,47,50,53,54,56,57,58,59,60,61,63,64,66,69,71,75,76,88,92,94,98,99,101,102],opoverload:55,opoverloadpacket:55,oppos:[71,76],opset:[58,60],opt:[49,68,75,98],opt_c:53,opt_h:53,opt_n:53,opt_shap:[46,49,64,71,75,76,88,96,98],opt_w:53,optim:[49,53,56,64,65,66,69,71,72,86,87,88,92,93,94,96,98],optimin:[49,71],optimiz:86,optimization_level:[65,71,91],optimization_profile_field:75,optimize_target_shap:66,optimized_input_shap:72,optimized_model:[65,91,92,94],optimized_model_custom:91,optimz:97,option:[45,49,53,57,58,60,63,64,65,66,67,68,71,74,75,76,80,84,91,93,99,100,101,102],orchestra:80,orci:83,order:[33,50,55,57,61,63,66,68,71,72,76,87,88],org:[62,68,78,80,86,87,99],organ:81,origin:[33,66,72],ornar:[81,83],os:46,ostream:46,other:[0,1,2,46,47,53,54,56,59,63,65,66,68,70,79,80,87,88,100],otherwis:[66,68,72,100],ouput:55,our:[57,60,64,86,87,97,98],out:[31,45,54,56,57,58,60,61,65,67,68,71,73,76,80,87,97,98],out_shap:87,out_tensor:[61,87],output0:56,output:[24,27,33,50,53,54,55,56,57,59,61,63,64,65,66,68,71,73,76,78,80,81,87,93,96,97,98,101],output__0:97,output_binding_nam:[33,46,76],output_file_path:[53,102],output_format:[65,71,101],output_nam:[66,72],output_pad:70,output_s:70,outself:87,outsid:80,over:[55,58,60,66,80,97],overal:[96,98],overhead:100,overrid:[3,4,29,30,45,55,66,75,99],overview:[62,69,91],own:[57,61,65,68,80,87,97],p:[53,70,87,97,102],packag:[53,56,65,87],pad:[70,98],padding_idx:70,page:[69,82,84,97],pair:[56,61,68,80,96,99],pane:80,paragraph:[81,84],param:[74,79],paramet:[0,1,2,3,4,25,26,27,29,30,31,32,33,35,37,47,49,50,54,55,56,61,65,66,71,72,73,75,76,84,86,87,101],paramt:55,parent:[14,15,18,19,20,21],parition:71,pars:[80,87],parser:80,part:[53,57,60,66,78,79,80,98],partial:[53,80],particular:[55,65,98],partit:[55,56,64,65,71,101],partition:[55,71],partitioninfo:57,pass:[33,54,55,57,58,59,60,61,64,65,66,68,69,73,74,76,86,87,99],pass_manag:63,pass_through_build_failur:[65,71],passlist:63,passmanag:63,past:80,patch:98,path:[4,13,14,15,29,30,53,65,66,67,68,71,74,75,86,87,97,99],path_to_torchtrt_root:68,pathwai:86,pattern:[61,75,87],payment:79,pbtxt:97,peephole_optimz:56,pellentesqu:83,peopl:80,pep:80,per:[65,71,100],perforamnc:66,perform:[29,30,55,63,64,71,96,97,98,99,100],permit:80,permut:[66,70],persist:80,pharetra:83,phase:[16,61,64,87,98,101],phasellu:83,phi:80,philosoph:80,phrase:80,pi:80,pick:86,pickler:59,piec:96,pil:97,pin:79,pin_memori:70,pip:[68,97],pipe:93,pipelin:[53,93,102],piplein:87,pixel_shuffl:70,pl:79,place:[49,56,63,66,80,81,82,99],placehold:[63,98],placerat:83,plan:[53,60,64,65,71,98],platea:83,platform:[46,53,60,67,68,97,102],pleas:[66,80,87,97,98],plugin:66,png:93,point:[65,75,78,79,80,87,97],pointer:[3,4,99],polish:79,pool:102,pop:59,popul:72,popular:[68,79,96],portabl:[59,76],portion:[57,80,93],porttitor:[81,83],posit:[53,55,66,75,78],possibl:[55,68,80,96,97],post:[29,30,50,53,64,69,87,98],posuer:[81,83],potenti:[50,71,83],pow:70,power:[66,80,87,96],pr:87,praesent:83,pragma:[43,44,45,46,99],pre:[33,56,74,76,99,100],pre_cxx11_abi:68,preced:[55,80],precis:[50,53,64,65,66,71,75,87,88,92,93,94,99,102],prefer:[55,65,68,87],preferenti:[65,71],prefix:[27,28,43,73,80],preinstal:68,prelu:70,prepar:[66,97],preprint:99,preproc:74,preprocess:[97,99],prerequisit:67,presenc:[65,71],present:[65,67],preserv:[80,86,99],prespect:86,press:[67,80],pretium:83,pretrain:[89,92,96,97],pretti:87,prev_next_buttons_loc:78,prevent:[50,53,55,57],previou:[55,67,78,91],previous:[29,33,87],prim:[54,56,57,59,70,86,87],prim_devic:70,primal:80,primari:[65,101],primarili:[55,60,68,87],print:[16,31,45,63,65,71,73,75,76,80,87,89,92,94,97],prior:[98,100],prioriti:55,privat:[3,4,45,46,99],problem:80,problemat:80,proce:97,proceed:97,process:[53,57,65,79,80,86,89,91,96,97,99,100],prod:70,produc:[49,54,55,59,61,64,75,80,87,96],product:50,profil:[49,72],profiling_verbos:66,program:[18,19,20,21,29,52,53,58,59,60,69,86],programm:80,progress:81,proin:83,project:[68,79,84],projectdir:67,promis:66,prompt:93,prop:72,properli:[55,68],properti:78,propog:56,prose:80,provid:[3,4,50,53,55,57,59,61,63,65,66,68,71,72,75,76,80,87,88,89,90,91,95,97,98,99,100,101],providi:[58,60],provok:80,pt:[53,66,87,97],ptq:[3,4,15,18,19,39,51,52,53,69,71,75,76],ptq_calibr:[3,4,46,50,99],ptqtemplat:51,publish:97,pull:[68,97],purchas:79,pure:[31,71],purpos:[66,96,97],puru:83,push:59,push_back:[45,57],put:[80,96],put_binding_nam:76,pwd:[67,97],py3:97,py:[55,56,60,63,66,68,78,80,85,86,87,91,92,93,94,98,99],pyindex:97,pypi:68,python3:[56,68,87],python:[53,57,60,63,65,66,71,72,75,76,80,81,87,89,91,92,93,94,95,96,97,100,102],python_api:62,pytorch:[33,49,50,53,55,56,57,58,59,60,61,64,65,68,71,74,75,76,86,87,88,90,95,97,98,99,100,101],pytorch_libtorch:97,pytorch_sphinx_them:[78,85],qat:96,quant_max:70,quant_min:70,quantiz:[29,30,53,65,69,87],quantizatiom:50,quartznet:96,question:87,qui:[81,83],quickli:[53,87,99],quisqu:83,quit:[61,87,96],quot:81,r:80,rais:[56,66],raiseexcept:56,ram:[50,53,65,71,76],rand:[66,87,91],randint:[94,98],randn:[57,64,71,75,76,87,89,92,98,101],rang:[49,50,53,66,75,96,98],rank:78,rather:56,raw:[55,78],re:[66,80],read:[3,4,29,30,45,78,80,99],read_calibration_cach:74,readcalibrationcach:[3,4,45],reader:80,realiz:59,realli:61,reason:[0,66,86],reattribut:81,rebuild:98,recalibr:29,receiv:66,recip:99,reciproc:70,recognit:[96,99],recomend:[29,30],recommend:[29,30,66,68,80,87,97],recompil:[63,92,94,98],record:[54,86],recurs:54,redistribut:81,reduc:[56,57,58,60,66,71,96,99],redund:66,ref:80,refer:[49,55,58,60,66,79,84,87,97,98,99],refit:[46,50,65,71,76,89],refitt:[65,71],reflect:46,reflection_pad1d:70,reflection_pad2d:70,regard:80,regardless:[65,71,81,92,94],region:66,regist:[33,55,59,61,66,76],register_acc_op:66,register_acc_op_map:66,register_custom_acc_mapper_fn:66,register_torch_trt_decomposit:55,registernodeconversionpattern:[61,87],registr:[63,66],registri:[54,55,87],reinterpret_cast:45,rel:[53,57],relat:[47,80,91,92,94],relationship:51,releas:[64,65,67,80,90,95,98],reload_model_output:66,reload_trt_mod:66,relu:[57,70,86,87,91],relu_:70,relwithdebinfo:67,remain:[56,99],rememb:66,remov:[63,64,78],remove_contigu:56,remove_dropout:56,remove_to:56,render:78,rent:81,reorder:57,repack:59,repair:63,repair_input_as_output:63,repeat:[53,70],repeat_interleav:70,replac:[55,57,63,68],replace_input_with:63,replication_pad1d:70,replication_pad2d:70,replication_pad3d:70,repo:67,report:[23,45],reportable_log_level:73,repositori:[60,78,85,97],repres:[49,50,55,61,66,73,80],represent:[56,61,66,86,96],reproduc:68,request:[75,87,97],requir:[29,50,53,54,55,56,64,65,66,68,71,73,75,76,78,87,97,98,99,100],require_full_compil:[46,50,65,71,76],requires_grad:70,research:66,reserv:[43,44,45,46],reset:[45,91,92,94,100],reshap:[70,97],resiz:97,resnet18:92,resnet50:97,resnet:[59,90,95,96,97],resnet_trt:59,resolut:96,resolv:[54,56,58,60,91,92,94],resourc:[54,99],respect:64,respons:[29,55,59,80,100],rest:[66,80,81],restrict:[50,65,71,76],restructuredtext:[80,81],result:[54,56,57,65,71,73,76,78,86,88,97,98],ret:56,reus:[56,66,99],revert:78,revis:[80,81,93],revisit:80,rewrit:[57,63],rfc:80,rho_:80,rhoncu:83,right:[43,44,45,46,56,60,61,67,80],risu:83,rm:97,rn50_preprocess:97,robust:98,role:80,roll:70,roman:81,room:80,root:[43,44,45,46,68,78,99],roughli:57,round:[50,71,76],rounding_mod:70,row:81,rst:[78,80],rsub:70,rtol:53,rule:[66,68,76],ruler:80,run:[1,37,47,50,53,54,55,56,57,58,59,60,61,65,66,68,71,72,75,76,80,86,87,88,89,91,92,93,94,96,97,98,99,100,101,102],running_mean:70,running_var:70,runtim:[65,69,71,87,91,92,94],runtimeerror:66,rutrum:[81,83],s:[49,50,57,59,61,64,66,67,68,69,71,72,75,78,80,81,86,87,96,97,99],sacrif:100,safe:[61,65,71,76],safe_dla:75,safe_gpu:75,safeti:[50,53,75],sage:80,sagitti:[81,83],sai:[81,96],said:80,same:[57,59,63,65,66,68,78,80,86,87,89,92,94,97,98,100,101],sampl:[66,80,88,91,92,93,94,97,99],sample_input:[63,66,91],sample_inputs_half:91,sapien:83,satisfi:[57,63,66],save:[29,45,53,59,65,66,69,75,76,87,88,93,96,97,100],save_timing_cach:[66,72],saw:87,scalar:[61,70],scalaropt_dim:70,scalartyp:[0,46,70],scale:[70,96,99],scale_factor:70,scale_grad_by_freq:[55,70],scales_d:70,scales_h:70,scales_w:70,scatter:70,scelerisqu:83,scenario:[63,65],schedul:[75,97],schema:[61,87],scheme:[66,71],scientist:80,scope:[56,91,92,94],scratch:29,scratch_spac:97,screen:78,script:[31,56,57,75,76,86,87,88,89,91,92,93,94,100],script_model:[86,89],scriptclass:76,scripted_model:102,scriptmodul:[75,76,87,88,101],scroll:[78,82],sdk:62,se:96,seamlessli:69,search:[65,69,71,78],second:[56,66,80,88,91,92,93,94],second_output:65,secondli:97,section:[64,66,78,80,81,82,84,87,97,98,99],secur:68,sed:[81,83],see:[31,56,57,59,63,65,66,68,75,76,80,86,87,88,91],seen:[80,81],segment:[57,64,92,94,96],segmentmodelwithdependencyawar:57,select:[17,29,30,37,50,53,59,65,66,67,68,70,71,75,76,79,82,88,99],self:[56,59,61,70,74,86,87,88,91,96,98,102],self_1:[59,87],self_int:70,sell:81,seller:79,seller_id:79,sem:83,semant:80,semper:83,send:97,senectu:83,sens:[80,87],sentenc:[80,96],sentinel:[0,2],separ:[57,58,60,68],seper:55,sequenc:[55,63,66,71,72,75,76,80,96,98],seri:57,serial:[33,37,53,58,60,71,75,76,87,101],seriali:76,serializ:[59,65,86],serialized_cach:[66,72],serialized_engin:76,seril:59,serv:[53,59,66,69,71],servic:80,session:[65,80],session_nam:80,set:[3,4,16,21,25,27,29,32,35,37,46,47,49,50,53,54,55,56,57,58,59,60,66,67,68,71,72,73,75,76,78,82,85,86,87,88,96,98,99,100,101,102],set_data_from_numpi:97,set_devic:[21,39,46,51,75,100],set_is_colored_output_on:[18,40,43,51,73],set_logging_prefix:[18,40,43,51,73],set_multi_device_safe_mod:100,set_reportable_log_level:[18,40,43,51,73],setalpha:61,setbeta:61,setnam:[61,87],setreshapedimens:87,setup:[44,97,99],sever:[16,26,73],sh:68,sha256:68,shape:[46,48,49,50,53,57,61,64,66,69,70,71,72,75,76,88,97,102],shape_mod:75,shape_rang:[66,72],share:[50,53,65,67,68,71,76],shell_command:80,shift:[67,68,70,80],ship:[87,100],shorthand:80,should:[0,3,4,29,46,50,53,54,55,56,57,58,60,61,64,65,66,73,75,76,78,80,83,97,99],show:[78,80,93,96],shown:[78,80,87],shuffl:[87,99],side:[55,56,78,87],sidebar:[78,84],sigmoid:[66,70],sigmoid_:70,sign:97,signatur:[55,76],signifi:[49,56],signific:80,significantli:[55,56,78],similar:[61,64,65,66,68,87,89,98,100],simonyan:99,simpil:99,simpl:[64,65,66,80,81,86,96,97],simplest:97,simpli:[56,91,96],simplic:65,simplifi:54,simul:96,sin:[70,80],sinc:[55,56,65,66,80,86,87,99],sing:80,singl:[49,53,56,57,66,75,80,86,87,99,100],singular:61,sinh:70,sink:80,sit:[81,83],site:[56,68,80,87],situat:55,six:80,sixth:81,size:[3,4,45,49,50,53,56,57,65,66,70,71,72,75,76,78,87,92,94,96,98,99],size_t:[3,4,45,99],skip:53,slash:78,slate:65,slice:70,slightli:[66,101],sm:59,small:[56,97],smaller:[96,98],so:[0,45,53,54,55,56,59,60,61,63,65,66,68,72,79,80,81,87,91,92,94,98,99],sodal:83,softmax:[56,66,70],softwar:[50,53,65,71,76,80],sole:[88,99],sollicitudin:83,solv:97,some:[54,55,56,57,58,59,60,61,63,64,66,79,80,87,98,99],some_funct:80,someth:[44,56,80,97],sometim:98,someurl:80,sort:[61,70,89],sourc:[43,44,45,46,55,60,65,66,67,71,72,73,74,75,76,91,92,93,94,95],sourceforg:[80,81],sourceir:71,space:[80,81,99],spaces_and_linebreak:80,span:81,spars:[53,55,65,70,71],sparse_weight:[46,50,65,66,71,76],sparsiti:[50,53,66,71,76],spec:[46,49,50,53,73,75,76,89],special:[55,57],specif:[32,50,55,56,58,60,63,65,71,75,76,80,95,96],specifi:[3,4,33,53,55,61,65,66,68,71,73,75,76,78,80,88,89,97,98],specifii:75,speech:96,speedup:96,spend:71,sphinx:[78,79,80,81,85,91,92,93,94,95],sphinx_rtd_them:[80,81],spin:97,spirit:80,split:[57,66,70],split_siz:70,split_with_s:70,sqrt:70,squar:70,squeez:[70,96],sram:53,src:[55,59,62,70],ss:45,ssd300_trt:59,ssd:59,ssd_trace:53,ssd_trt:53,sstream:[20,45],stabl:[62,76,78,90,95],stack:[59,70,99],stage:[54,66],stai:101,stand:[59,80],standalon:80,standard:[53,59,69,80,89,96,100],stapl:81,start:[54,57,66,70,81,87,89,96],start_dim:[70,87],start_step:70,state:[54,55,61,63,87],statement:[56,80],static_cast:45,statu:[45,81],std:[3,4,22,26,28,29,30,31,33,34,37,43,45,46,48,49,50,57,87,97,99,102],stdout:[36,73,75],steamlin:99,step:[57,66,70,96,98,99],stick:78,sticki:[78,84],sticky_navig:[78,82],still:[45,57,66,91,99],stitch:[57,87],stop:87,storag:99,store:[2,4,50,53,54,59,61,65,66,71,76,86,87,98],str:[19,44,45,51,55,65,66,70,71,73,75,76],straight:61,strang:80,strategi:[57,75],stream:[65,71],street:81,strict:100,strict_type_constraint:66,strictli:[65,71],stride:70,string:[3,4,18,20,21,22,26,28,29,30,31,33,34,37,43,45,46,50,55,57,59,61,67,75,78,87,99],stringstream:45,strip_prefix:68,strong:80,strongli:80,struct:[1,21,39,42,46,55,99],structur:[29,47,50,57,60,61,65,78,80,84,86,97],structuredtext:80,stub:81,stuff:80,style:[43,44,45,46,65,78,80,81],style_external_link:78,sub:[65,70,80,86,91],sub_:70,subdirectori:52,subexpress:56,subgraph:[50,53,54,55,56,61,63,87],subject:[60,63],submenu:84,submodul:[72,86,98],suboper:55,suboptim:57,subpackag:55,subscript:80,subsect:80,subsequ:65,subset:[55,65,71,96,99],substitut:80,subtitl:80,subtre:85,subword:96,success:67,successfulli:65,sudo:68,suffic:56,suffici:68,suggest:97,suitabl:66,sum:[50,66,70,71,76],superscript:80,supervis:96,suppli:80,support:[0,1,2,27,31,47,49,50,53,55,57,62,64,66,67,69,72,75,76,78,79,86,87,88,92,94,97,98,102],sure:[55,68,87,88,97,102],suscipit:[81,83],suspendiss:83,swap:98,sym_siz:98,symbol:[33,66,68,76,80,100],symbolic_trac:98,symlink:85,system:[54,61,63,65,68,69,71,76],t1:70,t2:70,t:[0,1,2,46,47,56,61,66,68,70,75,78,80,81,86,87,97,98,99],t_:80,tabl:[68,84],tag:[80,97],take:[31,32,33,37,54,55,58,59,60,61,63,66,71,72,75,76,78,80,87,89,91,96,98,99,101],taken:80,talk:69,tan:70,tanh:70,tanh_:70,tar:[68,80,99],tarbal:[68,87,99],target:[1,33,46,47,49,50,53,55,57,59,60,65,66,67,68,69,71,75,76,88,89,98,99,102],targets_:99,task:[29,30,66,96,99],techinqu:87,techniqu:[99,100],tell:[56,57,58,59,60,61,80],tellu:83,tem:53,templat:[20,41,45,46,51,78,87],temporari:66,tempu:83,tensor:[2,33,45,46,49,50,53,54,55,56,57,59,61,63,64,65,66,70,71,72,75,76,86,87,88,91,96,98,99],tensor_domain:[46,49,75],tensor_mod:70,tensor_scalar:70,tensor_tensor:70,tensorcontain:61,tensorformat:[21,39,46,49,51,75],tensorformatenum:51,tensorlist:[57,61],tensorrt:[0,1,3,4,29,30,31,32,33,36,37,45,46,47,49,50,53,54,55,56,57,58,60,61,63,71,72,74,75,76,86,90,91,93,99],tensorrt_bind:[65,71],tensorrt_convert:66,tensorrt_root:67,tensorrtcompilespec:[76,89],tensort:66,teo:53,term:[55,67,75,80,81,96,99],termin:[27,53,87],test:[53,57,60,66,67,68,71,80,81,96,97,99],test_acc_trac:66,test_ptq_dataloader_calibr:99,test_ptq_trt_calibr:99,test_py_modul:[80,84],test_segment:57,testing_dataload:99,testing_dataset:99,text:[73,81,83,96],tf32:[50,53,65,71],than:[55,56,71,79,80,96,100],thats:[54,99],the_model_repositori:97,thei:[47,53,54,55,56,59,61,66,75,78,80,88],them:[56,57,59,64,65,66,68,71,78,87,96,98],theori:[54,80],therebi:[55,59,96],therefor:[29,59,66,80,87,96,100],theres:100,therfor:100,theta:80,thi:[0,1,2,29,30,43,44,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,63,64,65,66,67,68,71,72,75,76,78,79,80,82,83,86,87,89,90,91,92,93,94,95,96,97,98,99,100,101],thicker:80,thin:80,thing1:80,thing2:80,thing3:80,thing:[66,68,80],think:[61,80],third:[66,81],third_parti:[60,68],this_arg_is_opt:66,those:[54,55,63,65,80],though:[53,60,61,86,87],thought:80,thread:100,three:[49,58,60,66,72,75,80,81,96,97],threshold:53,through:[49,54,55,56,57,59,66,73,74,80,87,88,96],throught:66,thrown:[50,71,76],thu:80,tile_to_repeat:56,time:[50,53,54,55,56,57,58,59,60,61,65,66,69,71,72,76,78,80,87,91,92,93,94,99],timing_cach:66,timing_cache_prefix:[66,72],tincidunt:83,tini:99,titles_onli:78,tmp:87,toctre:78,tocustomclass:61,todim:87,todo:[66,78],togeth:[54,61,87],token:[96,98],toler:53,too:[78,80,81],tool:[61,65,66,67,87,96],toolchain:[60,68],top:[60,78,82],topk:70,torch:[0,1,2,4,20,21,29,30,31,32,33,36,37,45,46,47,48,49,50,53,54,55,56,57,58,59,60,61,63,71,72,75,76,86,99,102],torch_compil:[91,92,94],torch_compile_advanced_usag:91,torch_compile_resnet_exampl:92,torch_compile_stable_diffus:93,torch_compile_transformers_exampl:94,torch_dir:67,torch_disabled_decomposit:55,torch_dtyp:93,torch_enabled_decomposit:55,torch_executed_modul:[46,50,57,71,76],torch_executed_op:[46,50,57,64,65,71,76,91,92,94],torch_input_1:98,torch_input_2:98,torch_scirpt_modul:86,torch_script_modul:87,torch_tensor:75,torch_tensorrt:[0,1,2,3,4,14,16,17,43,44,45,47,48,49,50,51,52,53,55,57,63,64,65,66,69,87,88,89,90,91,93,95,96,97,98,99,100,101,102],torch_tensorrt_build:67,torch_tensorrt_export:44,torch_tensorrt_major_vers:[19,44,51],torch_tensorrt_minor_vers:[19,44,51],torch_tensorrt_patch_vers:[19,44,51],torch_tensorrt_vers:[19,44,51],torch_tensorrtfil:51,torch_tensorrtnamespac:51,torchbind:59,torchdynamo:98,torchhub:97,torchscript:[19,21,39,44,46,50,51,53,57,58,59,60,64,65,71,72,75,76,88,96,98,102],torchscriptstruct:51,torchtrt:[44,57],torchtrt_api:[0,2,19,22,23,24,25,26,27,28,31,32,33,34,35,36,37,43,44,45,46,49,50,51],torchtrt_check:61,torchtrt_hidden:[19,44,51],torchtrt_runtime_exampl:100,torchtrt_unus:61,torchtrtc:[68,69,102],torchvis:[59,89,92,97,99],toronto:99,tortor:83,total:[91,92,93,94],totensor:[97,99],tovec:87,toward:[71,99],trace:[57,66,71,76,86,87,98,101],trace_input:98,traced_model:86,tracer:75,track:[61,99],tradit:[49,71,76,99],traget:32,trail:78,train:[29,30,50,53,69,70,87,88],trainabl:56,transcrib:96,transfer:79,transform:[87,90,95,97,98,99],transformed_img:97,transformers_trac:98,translat:87,transmit:80,transpos:[66,70],trash:80,travers:[57,58,60,65],treat:53,tree:[43,44,45,46,78,99,100],tri:55,trigger:[57,65,66,87,98],trim:99,tristiqu:83,triton:69,triton_to_np_dtyp:97,tritoncli:97,tritonserv:97,trt:[0,1,3,4,47,49,54,56,59,61,63,65,66,70,71,87,92,94,98,100],trt_ep:101,trt_gm:[64,98,101],trt_interpreter_result:66,trt_lenet_script:87,trt_mod:[57,87,98,99,102],trt_model:[57,89,97,101],trt_t:101,trt_ts_modul:[57,88],trtinterpret:[55,66,72],trtinterpreterresult:[66,72],trtmodul:[66,72],trttensor:55,truncat:[50,53,64,65,71,76],truncate_long_and_doubl:[46,50,64,65,71,76,93],truth:55,ts:[44,53,57,65,69,71,75,86,87,88,89,98,101],ts_model:[57,87],tt:80,tue:81,tup:70,tupl:[55,59,64,66,71,72,75,76,88],tupleconstruct:[56,59],tupleindex:70,tupleunpack:56,turn:[66,72],turpi:83,tutori:[86,99],two:[53,56,61,63,65,66,68,80,81,85,86,88,97,98,99],type:[0,1,2,30,50,51,53,54,57,59,61,63,64,65,66,67,71,72,73,75,76,80,87,88,96,99,101],type_fp32:97,typenam:[3,4,29,30,45],typic:[54,61,97],ugli:80,ui:79,uint64_t:[46,50],ultric:83,un:99,unabl:[61,87],unbind:70,unbroken:80,uncas:[94,96,98],uncom:68,undefin:98,under:[43,44,45,46,60,66,80],underli:[0,1,2,47,61],understand:98,unet:93,uniformli:96,union:[55,61,65,71,75,76,87],uniqu:[4,88],unique_ptr:[4,30],unit:66,unittest:98,univers:80,unknown:75,unless:66,unlik:[68,89],unlimit:78,unpack_addmm:56,unpack_log_softmax:56,unqiue_ptr:4,unreferenc:80,unrestrict:80,unsqueez:70,unstabl:60,unsupport:[31,50,55,65,67],unsur:61,untest:60,until:[54,57,60,61,68,98],unwrap:61,unwraptodoubl:61,unwraptoint:87,unzip:68,up:[54,56,57,58,59,60,63,66,80,86,91,92,94,96],updat:[66,67,68,72],upload:97,upon:[78,91,92,94],upper:81,upsample_bilinear2d:70,upsample_linear1d:70,upsample_nearest1d:70,upsample_nearest2d:70,upsample_nearest3d:70,upsample_trilinear3d:70,upscale_factor:70,upstream:87,uri:80,url:[68,78,97],urna:83,us:[0,1,2,3,4,29,30,32,35,37,44,45,46,47,49,50,53,54,55,57,59,60,61,63,64,65,66,67,68,69,71,72,73,74,75,76,78,79,80,81,86,90,95,97,98,99,100,101,102],usag:[64,66,74,80,87,90,95,98],use_cach:[3,4,30,45,74,99],use_cache_:45,use_cmake_generated_export_head:44,use_experimental_fx_rt:72,use_fast_partition:[65,71],use_input_stat:70,use_python_runtim:[65,71,91],use_subset:99,usecas:[88,95],user:[43,49,55,57,58,59,60,63,64,65,68,80,81,87,88,95,97,98,99,100],using_int:[70,87],usr:68,usual:[66,68,78],ut:83,utf:[80,81],util:[61,63,76,87,91,92,94,96,97,98,99],v0:[77,97],v143:67,v1:93,v2:[29,30,80],v:[53,81,97],valid:[1,47,57,61,63,71,75],valu:[0,1,2,16,17,46,47,49,54,57,59,61,64,67,70,71,73,74,75,78,87,91,92,94,96,98],value_tensor_map:[54,61],vanilla:66,vari:[65,72,98,101],variabl:[49,66,67,75],variant:100,varient:56,varieti:[65,97],variou:[66,102],variu:83,vcs_pageview_mod:78,vec:70,vector:[20,21,33,45,46,48,49,50,57,59,87,99,102],vehicula:83,vel:83,velit:83,venenati:83,verbios:53,verbos:[53,65,66,71,72,81,92,94],verbose_log:[66,72],veri:[65,66,81,82,89,97,99],verifi:57,verison:68,version:[34,36,60,63,65,66,67,71,78,81,96,97,98,101],version_compat:[65,71],vertic:[78,80],vestibulum:[81,83],vgg16:99,vgg:99,vi:80,via:[55,65,66,69,71,75,76,78,84,88,91,92,94,96,98,99,100,101],view:[70,78,98],virtual:99,vision:[66,97],visitor:78,vita:[81,83],vivamu:83,viverra:83,vm:81,volutpat:83,vs:[0,1,2,47,56,71,76,89],vscode:67,vulput:83,w:[53,68],w_hh:70,w_ih:70,wa:[56,59,63,66,80,87],wai:[53,65,66,68,86,87,90,95,96,99,100,101],walkthrough:96,want:[43,57,66,72,86,87,89,91,97,99],warn:[16,45,53,61,73],wash:80,we:[43,45,54,55,56,57,58,59,60,61,63,64,65,66,72,78,80,86,87,90,91,92,94,95,96,97,98,99,101],weak:80,web:80,websit:68,weight:[49,50,53,54,65,66,70,71,76,80,87,93,96],welcom:[66,87],well:[55,64,68,69,73,80,87,99,101],were:[87,100],wget:97,what:[4,55,56,66,80,86,87,88],whatev:[59,66],wheel:68,when:[27,45,46,47,53,54,56,57,58,59,60,61,65,66,68,71,73,75,76,78,80,82,86,87,96,98,99,100],where:[54,55,56,61,63,66,71,76,81,87,98,99],wherev:66,whether:[4,53,55,65,66,71,72,75,79,92,94,99,100],which:[1,2,29,32,37,47,50,54,55,56,57,58,59,60,61,63,64,65,66,68,71,72,74,75,76,78,80,81,86,87,88,89,91,96,97,98,99,100,101],white:80,whitespac:80,whl:68,who:80,whole:66,whose:[56,66],why:[80,100],wide:[65,84],width:[80,96],win:67,window:80,window_nam:80,wish:81,within:[50,53,58,60,65,71,76,78,80],without:[57,61,78,80,87,99,100],wl:100,wooden:80,word:[80,96],work:[45,56,60,61,66,80,81,91,98,99],worker:99,workflow:[65,66,69,71,72,87,89,92,93,94,96,98],workspac:[50,53,65,66,68,71,72,76,91,92,94],workspace_s:[46,50,53,65,71,76,92,94],workspacefold:67,world:80,would:[53,55,61,65,66,68,87,88,89,97,98,100],wp:97,wrap:[58,59,60,66,80,83,87,89,91,92,94],wrapper:[61,66],write:[3,4,29,30,45,66,69,80,87,97,99],write_calibration_cach:74,writecalibrationcach:[3,4,45],writing_convert:[54,87],wrote:80,www:[78,80,87,97,99],x64:67,x86:100,x86_64:[60,68],x9:56,x:[5,10,33,44,56,57,67,68,76,81,86,87,91,98,101],x_0:80,x_1:80,x_2:80,x_3:80,x_4:80,x_:80,x_lgamma:57,x_out:91,x_y_out:91,xavier:[46,102],xstr:[19,44,51],xx:97,xxx:66,xz:68,y:[33,57,76,81,91],y_lgamma:57,y_out:91,yahoo:81,yaml:[55,62],yet:[66,96],you:[0,1,2,29,30,47,49,50,53,54,55,56,57,59,60,61,64,66,68,71,75,76,78,80,81,82,86,87,88,89,90,95,96,97,98,99,100,101],your:[61,64,65,68,78,80,81,85,86,87,88,89,98,100],yourself:87,yy:97,z:81,zero:98,zero_point:70,zip:[59,67,68,95],zisserman:99},titles:["Class DataType","Class Device::DeviceType","Class TensorFormat","Template Class Int8CacheCalibrator","Template Class Int8Calibrator","Define STR","Define TORCH_TENSORRT_PATCH_VERSION","Define TORCH_TENSORRT_MAJOR_VERSION","Define TORCH_TENSORRT_MINOR_VERSION","Define TORCHTRT_API","Define XSTR","Define TORCHTRT_HIDDEN","Define TORCH_TENSORRT_VERSION","Directory cpp","Directory include","Directory torch_tensorrt","Enum Level","Enum EngineCapability","File logging.h","File macros.h","File ptq.h","File torch_tensorrt.h","Function torch_tensorrt::logging::get_logging_prefix","Function torch_tensorrt::logging::get_reportable_log_level","Function torch_tensorrt::logging::get_is_colored_output_on","Function torch_tensorrt::logging::set_reportable_log_level","Function torch_tensorrt::logging::log","Function torch_tensorrt::logging::set_is_colored_output_on","Function torch_tensorrt::logging::set_logging_prefix","Template Function torch_tensorrt::ptq::make_int8_cache_calibrator","Template Function torch_tensorrt::ptq::make_int8_calibrator","Function torch_tensorrt::torchscript::check_method_operator_support","Function torch_tensorrt::torchscript::compile","Function torch_tensorrt::torchscript::embed_engine_in_new_module","Function torch_tensorrt::get_build_info","Function torch_tensorrt::set_device","Function torch_tensorrt::dump_build_info","Function torch_tensorrt::torchscript::convert_method_to_trt_engine","Namespace torch","Namespace torch_tensorrt","Namespace torch_tensorrt::logging","Namespace torch_tensorrt::ptq","Namespace torch_tensorrt::torchscript","Program Listing for File logging.h","Program Listing for File macros.h","Program Listing for File ptq.h","Program Listing for File torch_tensorrt.h","Struct Device","Struct GraphInputs","Struct Input","Struct CompileSpec","Torch-TensorRT C++ API","Full API","torchtrtc","Conversion Phase","Writing Dynamo Converters","Lowering Phase","Partitioning Phase","Compiler Phases","Runtime Phase","System Overview","Writing TorchScript Converters","Useful Links for Torch-TensorRT Development","Writing Dynamo ATen Lowering Passes","Compiling Exported Programs with Torch-TensorRT","TensorRT Backend for torch.compile","Torch-TensorRT (FX Frontend) User Guide","Building Torch-TensorRT on Windows","Installation","Torch-TensorRT","Operators Supported","torch_tensorrt.dynamo","torch_tensorrt.fx","torch_tensorrt.logging","torch_tensorrt.ptq","torch_tensorrt","torch_tensorrt.ts","Changelog","Configuration","5. :mod:`test_py_module`","3. Paragraph Level Markup","4. Lists & Tables","1. Long Sticky Nav","1. Structural Elements","<no title>","Installation","Creating a TorchScript Module","Using Torch-TensorRT in C++","Using Torch-TensorRT in Python","Using Torch-TensorRT TorchScript Frontend Directly From PyTorch","Dynamo / torch.compile","Torch Compile Advanced Usage","Compiling ResNet using the Torch-TensorRT torch.compile Backend","Torch Compile Stable Diffusion","Compiling a Transformer using torch.compile and TensorRT","Torch-TensorRT Tutorials","Example notebooks","Serving a Torch-TensorRT model with Triton","Dynamic shapes with Torch-TensorRT","Post Training Quantization (PTQ)","Deploying Torch-TensorRT Programs","Saving models compiled with Torch-TensorRT","DLA"],titleterms:{"1":[82,97],"10":82,"11":82,"12":82,"13":82,"14":82,"15":82,"16":82,"17":82,"18":82,"19":82,"2":[82,83,97],"20":82,"3":[82,97],"4":82,"5":82,"6":82,"7":82,"8":82,"9":82,"class":[0,1,2,3,4,20,21,39,41,42,51,71,72,74,75],"default":91,"enum":[16,17,18,21,39,40,51,74,75],"export":64,"function":[18,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,39,40,41,42,51,62,71,72,75,76],"import":[91,92,93,94],"long":[82,84],"static":98,A:80,And:80,But:81,By:[18,19],In:69,Or:56,The:[80,87],To:56,With:67,aarch64:68,abi:[59,68],acc:66,acceler:96,add:66,addmm:[55,56],admonit:80,advanc:91,advic:61,after:65,an:84,api:[51,52,62,68,69],applic:99,arg:[61,79],argument:[92,94],aten:63,automat:57,avail:62,awar:[57,96],b:101,backend:[65,92],background:[59,61],base:[3,4,49,78],basic:63,bert:[96,98],binari:68,block:80,branch:56,build:[67,68,78,97],bullet:81,c:[51,62,68,69,87,96,99,101],can:81,capabl:55,caption:[81,84],center:80,ch:80,changelog:77,check_method_operator_support:31,choos:68,citat:[80,99],citrinet:96,cleanup:[91,92,94],cli:[68,69],client:97,cmake:68,code:[56,67,69,80],compil:[32,58,60,64,65,67,68,69,87,90,91,92,93,94,95,96,98,101],compilespec:50,compound:80,condit:65,configur:[67,78],constraint:98,construct:59,content:[18,19,20,21,39,40,41,42,78,79,80,81,82,83],context:[61,78],contigu:56,contract:[55,61],contributor:69,convers:[54,58,60,61],convert:[54,55,61,66,70,87],convert_method_to_trt_engin:37,convolut:55,coverag:65,cpp:[13,18,19,20,21,57],creat:[86,99],creativ:80,cuda:[68,91,92,94],current:70,custom:[65,87,91,98],customiz:[64,65],cxx11:68,data:79,datatyp:0,dead:56,debug:68,decomposit:55,deep:96,deeper:81,defin:[5,6,7,8,9,10,11,12,19,51],definit:[18,19,20,21,81,91,92,93,94],demo:84,depend:[57,68],deploi:[96,100],deseri:59,detect:96,develop:62,devic:[1,47,100],devicetyp:1,diffus:93,dimens:62,direct:80,directli:89,directori:[13,14,15,52],disk:86,dla:102,doctest:80,documen:69,document:[0,1,2,3,4,5,6,7,8,9,10,11,12,16,17,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,47,48,49,50,62,69,83,84],down:81,download:[80,85],driver:[91,92,94],dropout:56,dump_build_info:36,dynam:[65,96,98],dynamo:[55,63,69,71,90,95,101],easier:62,efficentnet:96,element:83,elimin:56,eliminatecommonsubexpress:56,embed_engine_in_new_modul:33,emphas:80,engin:[59,66],enginecap:17,enumer:81,envior:68,error:[91,92,94],evalu:[54,55,70],exampl:[55,63,80,82,96,98],execept:56,executor:59,expect:62,exportedprogram:101,face:96,fallback:[56,57],feasibl:65,featur:65,field:81,figur:80,file:[15,18,19,20,21,43,44,45,46,51,52],flatten:56,footnot:80,format:59,framework:69,freez:56,from:[68,89],frontend:[66,69,89,96],full:[51,52],further:69,fuse:56,fx2trt:66,fx:[66,69,72,96],gaurd:56,gener:79,get:69,get_build_info:34,get_is_colored_output_on:24,get_logging_prefix:22,get_reportable_log_level:23,giant:81,git:85,glossari:80,gpu:69,graph:[56,59],graphinput:48,graphmodul:101,grid:81,guarante:61,guid:[66,69],h:[18,19,20,21,43,44,45,46,57],have:81,hierarchi:51,hlist:81,hole:81,hood:[64,87,98],how:[66,78,99],html:78,hug:96,ien:80,imag:[80,81],implement:55,includ:[14,18,19,20,21],incred:84,index:79,indic:69,infer:[69,92,93,94,97],inform:69,inherit:[3,4,49],inlin:80,input:[49,92,94],instal:[67,68,85],int8:96,int8cachecalibr:3,int8calibr:4,ir:[62,98,101],jetson:68,kei:65,languag:96,layer:62,learn:96,legaci:69,lenet:96,level:[16,78,80,81],librari:[68,100],libtorchtrt:100,like:81,limit:98,line:80,linear:56,link:[62,80],list:[43,44,45,46,81],liter:80,log:[18,22,23,24,25,26,27,28,40,43,73],logsoftmax:56,loop:56,lower:[56,58,60,63],macro:[19,44],make_int8_cache_calibr:29,make_int8_calibr:30,markup:80,mask:96,math:80,menu:[82,84],meta:80,miss:66,mlm:96,mod:79,mode:100,model:[65,66,91,92,93,94,96,97,101],modul:[56,86,87],multi:100,namespac:[18,19,20,21,38,39,40,41,42,51],nativ:68,native_op:62,nav:82,nest:[1,47],nightli:68,node:54,note:[91,92,94],notebook:96,number:[80,81],nvidia:69,object:96,one:81,onli:68,op:[59,66],oper:[55,65,70,87],optim:97,optimz:56,option:[78,79,81,92,94],other:61,overview:60,own:99,packag:[68,100],page:78,paragraph:[80,83],paramet:79,partit:[57,58,60],partitoninfo:57,pass:[56,63],pattern:56,peephol:56,perform:65,phase:[54,56,57,58,59,60],plugin:100,post:99,pre:68,precompil:68,prerequisit:68,program:[43,44,45,46,64,100],project:78,ptq:[20,29,30,41,45,74,99],python:[62,68,69,86,88,99],pytorch:[62,66,69,89,96],quantiz:[96,99],queri:97,quickstart:87,quot:80,rabbit:81,read:62,recompil:65,redund:56,refer:80,regist:[63,87],registr:55,relationship:[1,3,4,47,49],releas:68,remov:56,repeat:56,replac:[56,80],requir:63,resnet50:96,resnet:92,respons:61,result:59,right:68,rubric:80,runtim:[58,59,60,100],safe:100,save:[86,101],second:81,section:83,segmentedblock:57,serial:[59,65],serv:[96,97],server:97,set:[64,65,91,97],set_devic:35,set_is_colored_output_on:27,set_logging_prefix:28,set_reportable_log_level:25,setup:68,shape:[65,96,98],shape_analysi:57,sidebar:80,so:100,sometim:62,sourc:68,specif:68,ssd:96,stabl:93,start:69,step:97,sticki:82,str:5,struct:[47,48,49,50,51],structur:83,studio:67,subdirectori:[13,14],submenu:82,submodul:75,subsect:83,subsubmenu:82,subsubsect:83,support:[65,70],system:60,tabl:[78,79,80,81,82,83],target:80,templat:[3,4,29,30],tensorformat:2,tensorrt:[51,59,62,64,65,66,67,68,69,87,88,89,92,94,95,96,97,98,100,101],test_py_modul:79,text:80,theme:[78,84],thi:[81,84],through:70,tile:56,titl:80,toc:78,topic:80,torch:[38,51,62,64,65,66,67,68,69,87,88,89,90,91,92,93,94,95,96,97,98,100,101],torch_compil:98,torch_tensorrt:[15,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,39,40,41,42,46,71,72,73,74,75,76,92,94],torch_tensorrt_major_vers:7,torch_tensorrt_minor_vers:8,torch_tensorrt_patch_vers:6,torch_tensorrt_vers:12,torchscript:[31,32,33,37,42,61,68,69,86,87,89,101],torchtrt_api:9,torchtrt_hidden:11,torchtrtc:[53,87],trace:64,tracer:66,train:[96,99],transform:[94,96],triton:97,ts:76,tupl:56,tutori:[69,95],type:[3,4,47,49,55],under:[64,87,98],unpack:56,unrol:56,unsupport:87,up:97,us:[56,62,87,88,89,91,92,94,96],usag:[65,91],user:[66,69],valid:55,version:[59,68],via:85,visual:67,wai:80,weight:61,what:61,wide:78,window:67,work:[86,87],workaround:98,write:[55,61,63],xstr:10,your:[97,99]}}) \ No newline at end of file diff --git a/docs/v2.2.0/src/pytorch-sphinx-theme/docs/changelog.html b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/changelog.html new file mode 100644 index 0000000000..83a1a053d7 --- /dev/null +++ b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/changelog.html @@ -0,0 +1,744 @@ + + + + + + + + + + + + + Changelog — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Changelog

+

v0.0.1

+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/src/pytorch-sphinx-theme/docs/configuring.html b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/configuring.html new file mode 100644 index 0000000000..426e72681b --- /dev/null +++ b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/configuring.html @@ -0,0 +1,847 @@ + + + + + + + + + + + + + Configuration — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Configuration

+

You can configure different parts of the theme.

+
+

Project-wide Configuration

+
+

HTML Theme Options

+

The theme’s project-wide options are defined in the pytorch_sphinx_theme/theme.conf +file of this repository, and can be defined in your project’s conf.py via +html_theme_options. For example:

+
html_theme_options = {
+    'canonical_url': '',
+    'analytics_id': '',
+    'logo_only': False,
+    'display_version': True,
+    'prev_next_buttons_location': 'bottom',
+    'style_external_links': False,
+    'vcs_pageview_mode': '',
+    # Toc options
+    'collapse_navigation': True,
+    'sticky_navigation': True,
+    'navigation_depth': 4,
+    'includehidden': True,
+    'titles_only': False
+}
+
+
+

The following options are available:

+
+

Base options

+
    +
  • canonical_url String. This will specify a canonical url +to let search engines know they should give higher ranking to latest version of the docs. +The url points to the root of the documentation and requires a trailing slash.

  • +
  • analytics_id String. Change the Google Analytics ID that is included on pages.

  • +
  • display_version Bool. With this disabled, the version number isn’t shown at the top of the sidebar.

  • +
  • prev_next_buttons_location String. can take the value bottom, top, both , or None +and will display the “Next” and “Previous” buttons accordingly.

  • +
  • style_external_links Bool. Add an icon next to external links. Defaults to False.

  • +
  • vcs_pageview_mode String. Changes how to view files when using display_github, display_gitlab, etc. +When using Github or Gitlab this can be: blob (default), edit, or raw, +on Bitbucket, this can be either: view (default) or edit.

  • +
+
+
+

TOC Options

+

These effect how we display the Table of Contents in the side bar. You can read more about them here: http://www.sphinx-doc.org/en/stable/templating.html#toctree

+
    +
  • collapse_navigation Bool. With this enabled, you will lose the [+] drop downs next to each section in the sidebar.

  • +
  • sticky_navigation Bool. This causes the sidebar to scroll with the main page content as you scroll the page.

  • +
  • navigation_depth Int. Indicate the max depth of the tree; by default, 4 levels are included; +set it to -1 to allow unlimited depth.

  • +
  • includehidden Bool. Specifies if the sidebar includes toctrees marked with the :hidden: option

  • +
  • titles_only Bool. If True, removes headers within a page from the sidebar.

  • +
+
+

Note

+

Setting collapse_navigation to False and using a high navigation_depth +can cause projects with many files and a deep file structure to generate HTML files +that are significantly larger in file size and much longer compilation times.

+
+
+
+
+

HTML Context Options

+

TODO.

+
+
+
+

Page-level Configuration

+

Pages support metadata that changes how the theme renders. +You can currently add the following:

+
    +
  • :github_url: This will force the “Edit on GitHub” to the configured URL

  • +
  • :bitbucket_url: This will force the “Edit on Bitbucket” to the configured URL

  • +
  • :gitlab_url: This will force the “Edit on GitLab” to the configured URL

  • +
+
+
+

How the Table of Contents builds

+

Currently the left menu will build based upon any toctree(s) defined in your index.rst file. +It outputs 2 levels of depth, which should give your visitors a high level of access to your +docs. If no toctrees are set the theme reverts to sphinx’s usual local toctree.

+

It’s important to note that if you don’t follow the same styling for your rST headers across +your documents, the toctree will misbuild, and the resulting menu might not show the correct +depth when it renders.

+

Also note that by default the table of contents is set with includehidden=True. This allows you +to set a hidden toc in your index file with the :hidden: property that will allow you +to build a toc without it rendering in your index.

+

By default, the navigation will “stick” to the screen as you scroll. However if your toc +is vertically too large, it will revert to static positioning. To disable the sticky nav +altogether change the setting in conf.py.

+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/api.html b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/api.html new file mode 100644 index 0000000000..28a728a24c --- /dev/null +++ b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/api.html @@ -0,0 +1,798 @@ + + + + + + + + + + + + + 5. :mod:`test_py_module` — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • 5. :mod:`test_py_module`
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

5. :mod:`test_py_module`

+ +
+

5.1. Generated Index

+

Part of the sphinx build process in generate and index file: Index.

+
+
+

5.2. Optional parameter args

+

At this point optional parameters cannot be generated from code. +However, some projects will manually do it, like so:

+

This example comes from django-payments module docs.

+
+
+payments.dotpay.DotpayProvider(seller_id, pin[, channel=0[, lock=False], lang='pl'])
+

This backend implements payments using a popular Polish gateway, Dotpay.pl.

+

Due to API limitations there is no support for transferring purchased items.

+
+
Param seller_id
+

Seller ID assigned by Dotpay

+
+
Param pin
+

PIN assigned by Dotpay

+
+
Param channel
+

Default payment channel (consult reference guide)

+
+
Param lang
+

UI language

+
+
Param lock
+

Whether to disable channels other than the default selected above

+
+
+
+ +
+
+

5.3. Data

+

Some data link :data:`Data_item_1`.

+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/demo.html b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/demo.html new file mode 100644 index 0000000000..a18829d662 --- /dev/null +++ b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/demo.html @@ -0,0 +1,1354 @@ + + + + + + + + + + + + + + + 3. Paragraph Level Markup — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • 3. Paragraph Level Markup
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

3. Paragraph Level Markup

+ +
+

3.1. Inline Markup

+

Paragraphs contain text and may contain inline markup: emphasis, strong emphasis, inline literals, +standalone hyperlinks (http://www.python.org), external hyperlinks (Python 5), internal cross-references (example), +external hyperlinks with embedded URIs (Python web site), footnote references +(manually numbered 1, anonymous auto-numbered 3, labeled auto-numbered 2, or symbolic *), +citation references (12), substitution references (EXAMPLE), and inline hyperlink targets +(see Targets below for a reference back to here). Character-level inline markup is also possible +(although exceedingly ugly!) in reStructuredText. Problems are indicated by |problematic| +text (generated by processing errors; this one is intentional).

+

Also with sphinx.ext.autodoc, which I use in the demo, I can link to test_py_module.test.Foo. +It will link you right my code documentation for it.

+

The default role for interpreted text is Title Reference. Here are some explicit interpreted text roles: +a PEP reference (PEP 287); an RFC reference (RFC 2822); a subscript; a superscript; +and explicit roles for standard inline markup.

+

GUI labels are a useful way to indicate that Some action is to be taken by the user. +The GUI label should not run over line-height so as not to interfere with text from adjacent lines.

+

Key-bindings indicate that the read is to press a button on the keyboard or mouse, +for example MMB and Shift-MMB. Another useful markup to indicate a user action +is to use menuselection this can be used to show short and long menus in software. +For example, and menuselection can be seen here that breaks is too long to fit on this line. +My ‣ Software ‣ Some menu ‣ Some sub menu 1 ‣ sub menu 2.

+

Let’s test wrapping and whitespace significance in inline literals: +This is an example of --inline-literal --text, --including some-- +strangely--hyphenated-words.  Adjust-the-width-of-your-browser-window +to see how the text is wrapped.  -- ---- --------  Now note    the +spacing    between the    words of    this sentence    (words +should    be grouped    in pairs).

+

If the --pep-references option was supplied, there should be a live link to PEP 258 here.

+
+
+

3.2. Math

+

This is a test. Here is an equation: +\(X_{0:5} = (X_0, X_1, X_2, X_3, X_4)\). +Here is another:

+
+(1)\[\nabla^2 f = +\frac{1}{r^2} \frac{\partial}{\partial r} +\left( r^2 \frac{\partial f}{\partial r} \right) + +\frac{1}{r^2 \sin \theta} \frac{\partial f}{\partial \theta} +\left( \sin \theta \, \frac{\partial f}{\partial \theta} \right) + +\frac{1}{r^2 \sin^2\theta} \frac{\partial^2 f}{\partial \phi^2}\]
+

You can add a link to equations like the one above (1) by using :eq:.

+
+
+

3.3. Meta

+
+
+

3.4. Blocks

+
+

3.4.1. Literal Blocks

+

Literal blocks are indicated with a double-colon (“::”) at the end of +the preceding paragraph (over there -->). They can be indented:

+
if literal_block:
+    text = 'is left as-is'
+    spaces_and_linebreaks = 'are preserved'
+    markup_processing = None
+
+
+

Or they can be quoted without indentation:

+
>> Great idea!
+>
+> Why didn't I think of that?
+
+
+
+
+

3.4.2. Line Blocks

+
+
This is a line block. It ends with a blank line.
+
+
Each new line begins with a vertical bar (“|”).
+
Line breaks and initial indents are preserved.
+
+
Continuation lines are wrapped portions of long lines; +they begin with a space in place of the vertical bar.
+
+
The left edge of a continuation line need not be aligned with +the left edge of the text above it.
+
+
+
+
This is a second line block.
+

+
Blank lines are permitted internally, but they must begin with a “|”.
+
+

Take it away, Eric the Orchestra Leader!

+
+
+
A one, two, a one two three four
+

+
Half a bee, philosophically,
+
+
must, ipso facto, half not be.
+
+
But half the bee has got to be,
+
+
vis a vis its entity. D’you see?
+

+
+
But can a bee be said to be
+
+
or not to be an entire bee,
+
+
when half the bee is not a bee,
+
+
due to some ancient injury?
+

+
+
+
+
Singing…
+
+
+
+
+

3.4.3. Block Quotes

+

Block quotes consist of indented body elements:

+
+

My theory by A. Elk. Brackets Miss, brackets. This theory goes +as follows and begins now. All brontosauruses are thin at one +end, much much thicker in the middle and then thin again at the +far end. That is my theory, it is mine, and belongs to me and I +own it, and what it is too.

+

—Anne Elk (Miss)

+
+
+
+

3.4.4. Doctest Blocks

+
>>> print 'Python-specific usage examples; begun with ">>>"'
+Python-specific usage examples; begun with ">>>"
+>>> print '(cut and pasted from interactive Python sessions)'
+(cut and pasted from interactive Python sessions)
+
+
+
+
+

3.4.5. Code Blocks

+
# parsed-literal test
+curl -O http://someurl/release-v2.2.0.tar-gz
+
+
Code Blocks can have captions.
+
{
+"windows": [
+    {
+    "panes": [
+        {
+        "shell_command": [
+            "echo 'did you know'",
+            "echo 'you can inline'"
+        ]
+        },
+        {
+        "shell_command": "echo 'single commands'"
+        },
+        "echo 'for panes'"
+    ],
+    "window_name": "long form"
+    }
+],
+"session_name": "shorthands"
+}
+
+
+
+
+

3.4.5.1. Emphasized lines with line numbers

+
1def some_function():
+2    interesting = False
+3    print 'This line is highlighted.'
+4    print 'This one is not...'
+5    print '...but this one is.'
+
+
+
+
+
+ +
+

3.6. References

+
+

3.6.1. Footnotes

+
+
1(1,2)
+

A footnote contains body elements, consistently indented by at +least 3 spaces.

+

This is the footnote’s second paragraph.

+
+
2(1,2)
+

Footnotes may be numbered, either manually (as in 1) or +automatically using a “#”-prefixed label. This footnote has a +label so it can be referred to from multiple places, both as a +footnote reference (2) and as a hyperlink reference +(label).

+
+
3
+

This footnote is numbered automatically and anonymously using a +label of “#” only.

+
+
*
+

Footnotes may also use symbols, specified with a “*” label. +Here’s a reference to the next footnote: .

+
+
+

This footnote shows the next symbol in the sequence.

+
+
4
+

Here’s an unreferenced footnote, with a reference to a +nonexistent footnote: [5]_.

+
+
+
+
+

3.6.2. Citations

+
+
11
+

This is the citation I made, let’s make this extremely long so that we can tell that it doesn’t follow the normal responsive table stuff.

+
+
12(1,2)
+

This citation has some code blocks in it, maybe some bold and +italics too. Heck, lets put a link to a meta citation 13 too.

+
+
13
+

This citation will have two backlinks.

+
+
+

Here’s a reference to the above, 12, and a [nonexistent] citation.

+

Here is another type of citation: citation

+
+
+

3.6.3. Glossary

+

This is a glossary with definition terms for thing like Writing:

+
+
Documentation

Provides users with the knowledge they need to use something.

+
+
Reading

The process of taking information into ones mind through the use of eyes.

+
+
Writing

The process of putting thoughts into a medium for other people to read.

+
+
+
+
+

3.6.4. Targets

+

This paragraph is pointed to by the explicit “example” target. +A reference can be found under Inline Markup, above. Inline +hyperlink targets are also possible.

+

Section headers are implicit targets, referred to by name. See +Targets, which is a subsection of `Body Elements`_.

+

Explicit external targets are interpolated into references such as “Python 5”.

+

Targets may be indirect and anonymous. Thus this phrase may also +refer to the Targets section.

+

Here’s a `hyperlink reference without a target`_, which generates an error.

+
+
+
+

3.7. Directives

+
+

3.7.1. Contents

+

These are just a sample of the many reStructuredText Directives. For others, please see: +http://docutils.sourceforge.net/docs/ref/rst/directives.html.

+
+
+

3.7.2. Centered text

+

You can create a statement with centered text with .. centered::

+

+This is centered text!

+
+

3.7.3. Images & Figures

+
+

3.7.3.1. Images

+

An image directive (also clickable – a hyperlink reference):

+../../../../_images/yi_jing_01_chien.jpg +
+
+

3.7.3.2. Figures

+
+reStructuredText, the markup syntax +
+

A figure is an image with a caption and/or a legend:

+
+ ++++ + + + + + + + + + + + +

re

Revised, revisited, based on ‘re’ module.

Structured

Structure-enhanced text, structuredtext.

Text

Well it is, isn’t it?

+

This paragraph is also part of the legend.

+
+
+
+

A figure directive with center alignment

+
+../../../../_images/yi_jing_01_chien.jpg +
+

This caption should be centered.

+
+
+
+
+
+

3.7.4. Admonitions

+
+

Attention

+

Directives at large.

+
+
+

Caution

+

Don’t take any wooden nickels.

+
+
+

Danger

+

Mad scientist at work!

+
+
+

Error

+

Does not compute.

+
+
+

Hint

+

It’s bigger than a bread box.

+
+
+

Important

+
    +
  • Wash behind your ears.

  • +
  • Clean up your room.

    +
      +
    • Including the closet.

    • +
    • The bathroom too.

      +
        +
      • Take the trash out of the bathroom.

      • +
      • Clean the sink.

      • +
      +
    • +
    +
  • +
  • Call your mother.

  • +
  • Back up your data.

  • +
+
+
+

Note

+

This is a note. +Equations within a note: +\(G_{\mu\nu} = 8 \pi G (T_{\mu\nu} + \rho_\Lambda g_{\mu\nu})\).

+
+
+

Tip

+

15% if the service is good.

+ +++ + + + + + + + + + + + + +

Example

Thing1

Thing2

Thing3

+
+
+

Warning

+

Strong prose may provoke extreme mental exertion. +Reader discretion is strongly advised.

+
+
+

And, by the way…

+

You can make up your own admonition too.

+
+
+
+

3.7.5. Topics, Sidebars, and Rubrics

+ +
+

Topic Title

+

This is a topic.

+
+

This is a rubric

+
+
+

3.7.6. Target Footnotes

+
+
5(1,2,3)
+

http://www.python.org/

+
+
+
+
+

3.7.7. Replacement Text

+

I recommend you try Python, the best language around 5.

+
+
+

3.7.8. Compound Paragraph

+
+

This paragraph contains a literal block:

+
Connecting... OK
+Transmitting data... OK
+Disconnecting... OK
+
+
+

and thus consists of a simple paragraph, a literal block, and +another simple paragraph. Nonetheless it is semantically one +paragraph.

+
+

This construct is called a compound paragraph and can be produced +with the “compound” directive.

+
+
+ +
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/lists_tables.html b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/lists_tables.html new file mode 100644 index 0000000000..938c1237bd --- /dev/null +++ b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/lists_tables.html @@ -0,0 +1,1329 @@ + + + + + + + + + + + + + 4. Lists & Tables — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • 4. Lists & Tables
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

4. Lists & Tables

+ +
+

4.1. Lists

+
+

4.1.1. Enumerated Lists

+
    +
  1. Arabic numerals.

    +
      +
    1. lower alpha)

      +
        +
      1. (lower roman)

        +
          +
        1. upper alpha.

          +
            +
          1. upper roman)

          2. +
          +
        2. +
        +
      2. +
      +
    2. +
    +
  2. +
  3. Lists that don’t start at 1:

    +
      +
    1. Three

    2. +
    3. Four

    4. +
    +
      +
    1. C

    2. +
    3. D

    4. +
    +
      +
    1. iii

    2. +
    3. iv

    4. +
    +
  4. +
  5. List items may also be auto-enumerated.

  6. +
+
+
+

4.1.2. Definition Lists

+
+
Term

Definition

+
+
Termclassifier

Definition paragraph 1.

+

Definition paragraph 2.

+
+
Term

Definition

+
+
+
+
+

4.1.3. Option Lists

+

For listing command-line options:

+
+
-a
+

command-line option “a”

+
+
-b file
+

options can have arguments +and long descriptions

+
+
--long
+

options can be long also

+
+
--input=file
+

long options can also have +arguments

+
+
--very-long-option
+

The description can also start on the next line.

+

The description may contain multiple body elements, +regardless of where it starts.

+
+
-x, -y, -z
+

Multiple options are an “option group”.

+
+
-v, --verbose
+

Commonly-seen: short & long options.

+
+
-1 file, --one=file, --two file
+

Multiple options with arguments.

+
+
/V
+

DOS/VMS-style options too

+
+
+

There must be at least two spaces between the option and the description.

+
+
+

4.1.4. Field list

+
+
Author
+

David Goodger

+
+
Address
+

123 Example Street +Example, EX Canada +A1B 2C3

+
+
Contact
+

docutils-develop@lists.sourceforge.net

+
+
Authors
+

Me; Myself; I

+
+
organization
+

humankind

+
+
date
+

$Date: 2012-01-03 19:23:53 +0000 (Tue, 03 Jan 2012) $

+
+
status
+

This is a “work in progress”

+
+
revision
+

$Revision: 7302 $

+
+
version
+

1

+
+
copyright
+

This document has been placed in the public domain. You +may do with it as you wish. You may copy, modify, +redistribute, reattribute, sell, buy, rent, lease, +destroy, or improve it, quote it at length, excerpt, +incorporate, collate, fold, staple, or mutilate it, or do +anything else to it that your or anyone else’s heart +desires.

+
+
field name
+

This is a generic bibliographic field.

+
+
field name 2
+

Generic bibliographic fields may contain multiple body elements.

+

Like this.

+
+
Dedication
+

For Docutils users & co-developers.

+
+
abstract
+

This document is a demonstration of the reStructuredText markup +language, containing examples of all basic reStructuredText +constructs and many advanced constructs.

+
+
+
+
+

4.1.5. Bullet Lists

+
    +
  • A bullet list

    +
      +
    • Nested bullet list.

    • +
    • Nested item 2.

    • +
    +
  • +
  • Item 2.

    +

    Paragraph 2 of item 2.

    +
      +
    • Nested bullet list.

    • +
    • Nested item 2.

      +
        +
      • Third level.

      • +
      • Item 2.

      • +
      +
    • +
    • Nested item 3.

    • +
    +
  • +
  • inline literall

  • +
  • inline literall

  • +
  • inline literall

  • +
+
+

4.1.5.1. Second list level

+
    +
  • here is a list in a second-level section.

  • +
  • yahoo

  • +
  • yahoo

    +
      +
    • yahoo

    • +
    • here is an inner bullet oh

      +
        +
      • one more with an inline literally. yahoo

        +

        heh heh. child. try to beat this embed:

        +
         1# -*- coding: utf-8 -*-
        + 2"""Test Module for sphinx_rtd_theme."""
        + 3
        + 4
        + 5class Foo:
        + 6
        + 7    """Docstring for class Foo.
        + 8
        + 9    This text tests for the formatting of docstrings generated from output
        +10    ``sphinx.ext.autodoc``. Which contain reST, but sphinx nests it in the
        +
        +
        +
      • +
      +
    • +
    • and another. yahoo

    • +
    • yahoo

    • +
    • hi

    • +
    +
  • +
  • and hehe

  • +
+
+
4.1.5.1.1. But deeper down the rabbit hole
+
    +
  • I kept saying that, “deeper down the rabbit hole”. yahoo

    +
      +
    • I cackle at night yahoo.

    • +
    +
  • +
  • I’m so lonely here in GZ guangzhou

  • +
  • A man of python destiny, hopes and dreams. yahoo

    + +
  • +
+
+
+
+
+

4.1.6. Hlists

+
    +
  • First item

  • +
  • Second item

  • +
  • Third item

  • +
+
    +
  • Forth item

  • +
  • Fifth item

  • +
  • Sixths item

  • +
+
+

Hlist with images

+
    +
  • +../../../../_images/yi_jing_01_chien.jpg +
    +

    This is a short caption for a figure.

    +
    +
    +
  • +
+
    +
  • +../../../../_images/yi_jing_01_chien.jpg +
    +

    This is a long caption for a figure. Lorem ipsum dolor sit amet, consectetur adipiscing elit. +Donec porttitor dolor in odio posuere, vitae ornare libero mattis. In lobortis justo vestibulum nibh aliquet, non.

    +
    +
    +
  • +
+
+
+
+

4.1.7. Numbered List

+
    +
  1. One,

  2. +
  3. Two.

  4. +
  5. Three with long text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. +Sed feugiat sagittis neque quis eleifend. Duis rutrum lectus sit amet mattis suscipit.

  6. +
+
    +
    1. +
    2. Using bullets and letters. (A)

    3. +
    +
  • +
    1. +
    2. Using bullets and letters. (B)

    3. +
    +
  • +
    1. +
    2. Using bullets and letters. (C)

    3. +
    +
  • +
+
+
+
+

4.2. Tables

+
+

4.2.1. Grid Tables

+

Here’s a grid table followed by a simple table:

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Header row, column 1 +(header rows optional)

Header 2

Header 3

Header 4

body row 1, column 1

column 2

column 3

column 4

body row 2

Cells may span columns.

body row 3

Cells may +span rows.

    +
  • Table cells

  • +
  • contain

  • +
  • body elements.

  • +
+

body row 4

body row 5

Cells may also be +empty: -->

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Inputs

Output

A

B

A or B

False

False

False

True

False

True

False

True

True

True

True

True

+
+

4.2.1.1. Giant Tables

+ ++++++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Header 1

Header 2

Header 3

Header 1

Header 2

Header 3

Header 1

Header 2

Header 3

Header 1

Header 2

Header 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

body row 1

column 2

column 3

+
+
+
+

4.2.2. List Tables

+ + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
List tables can have captions like this one.

List table

Header 1

Header 2

Header 3 long. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet mauris arcu.

Stub Row 1

Row 1

Column 2

Column 3 long. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet mauris arcu.

Stub Row 2

Row 2

Column 2

Column 3 long. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet mauris arcu.

Stub Row 3

Row 3

Column 2

Column 3 long. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sit amet mauris arcu.

+ + ++++ + + + + + +
This is a list table with images in it.
+../../../../_images/yi_jing_01_chien.jpg +
+

This is a short caption for a figure.

+
+
+
+../../../../_images/yi_jing_01_chien.jpg +
+

This is a long caption for a figure. Lorem ipsum dolor sit amet, consectetur adipiscing elit. +Donec porttitor dolor in odio posuere, vitae ornare libero mattis. In lobortis justo vestibulum nibh aliquet, non.

+
+
+
+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/long.html b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/long.html new file mode 100644 index 0000000000..6990d95c2d --- /dev/null +++ b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/long.html @@ -0,0 +1,1008 @@ + + + + + + + + + + + + + 1. Long Sticky Nav — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • 1. Long Sticky Nav
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

1. Long Sticky Nav

+ +

This section demonstrates how the ‘sticky_navigation’ setting behaves when the menu is very long. +When this section is selected, it will make the menu and the main area scroll when you are at the top of the page.

+
+

1.1. Example Menu 1

+

Just a place holder…

+
+
+

1.2. Example Menu 2

+

Just a place holder…

+
+
+

1.3. Example Menu 3

+

Just a place holder…

+
+
+

1.4. Example Menu 4

+

Just a place holder…

+
+
+

1.5. Example Menu 5

+

Just a place holder…

+
+
+

1.6. Example Menu 6

+

Just a place holder…

+
+
+

1.7. Example Menu 7

+

Just a place holder…

+
+
+

1.8. Example Menu 8

+

Just a place holder…

+
+
+

1.9. Example Menu 9

+

Just a place holder…

+
+
+

1.10. Example Menu 10

+

Just a place holder…

+
+
+

1.11. Example Menu 11

+

Just a place holder…

+
+
+

1.12. Example Menu 12

+

Just a place holder…

+
+
+

1.13. Example Menu 13

+

Just a place holder…

+
+
+

1.14. Example Menu 14

+

Just a place holder…

+
+
+

1.15. Example Menu 15

+

Just a place holder…

+
+
+

1.16. Example Menu 16

+

Just a place holder…

+
+
+

1.17. Example Menu 17

+

Just a place holder…

+
+
+

1.18. Example Menu 18

+

Just a place holder…

+
+
+

1.19. Example Menu 19

+

Just a place holder…

+
+
+

1.20. Example Menu 20

+

Just a place holder…

+
+
+

1.21. Example Submenu 1

+

Just a place holder…

+ + + + + +
+
+

1.22. Example Submenu 2

+

Just a place holder…

+
+

1.22.1. Submenu 1

+

Just a place holder…

+
+

1.22.1.1. Subsubmenu 1

+

Just a place holder…

+
+
+
+

1.22.2. Submenu 2

+

Just a place holder…

+
+

1.22.2.1. Subsubmenu 1

+

Just a place holder…

+
+
+
+

1.22.3. Submenu 3

+

Just a place holder…

+
+
+

1.22.4. Submenu 4

+

Just a place holder…

+
+
+

1.22.5. Submenu 5

+

Just a place holder…

+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/structure.html b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/structure.html new file mode 100644 index 0000000000..bd2a7b9565 --- /dev/null +++ b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/demo/structure.html @@ -0,0 +1,877 @@ + + + + + + + + + + + + + 1. Structural Elements — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • 1. Structural Elements
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

1. Structural Elements

+ +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lorem neque, interdum in ipsum nec, +finibus dictum velit. Ut eu efficitur arcu, id aliquam erat. In sit amet diam gravida, imperdiet tellus eu, +gravida nisl. Praesent aliquet odio eget libero elementum, quis rhoncus tellus tincidunt. +Suspendisse quis volutpat ipsum. Sed lobortis scelerisque tristique. Aenean condimentum risus tellus, +quis accumsan ipsum laoreet ut. Integer porttitor maximus suscipit. Mauris in posuere sapien. +Aliquam accumsan feugiat ligula, nec fringilla libero commodo sed. Proin et erat pharetra.

+
+

Etiam turpis ante, luctus sed velit tristique, finibus volutpat dui. Nam sagittis vel ante nec malesuada. +Praesent dignissim mi nec ornare elementum. Nunc eu augue vel sem dignissim cursus sed et nulla. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. +Pellentesque dictum dui sem, non placerat tortor rhoncus in. Sed placerat nulla at rhoncus iaculis.

+
+

1.1. Document Section

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed condimentum nulla vel neque venenatis, +nec placerat lorem placerat. Cras purus eros, gravida vitae tincidunt id, vehicula nec nulla. +Fusce aliquet auctor cursus. Phasellus ex neque, vestibulum non est vitae, viverra fringilla tortor. +Donec vestibulum convallis justo, a faucibus lorem vulputate vel. Aliquam cursus odio eu felis sodales aliquet. +Aliquam erat volutpat. Maecenas eget dictum mauris. Suspendisse arcu eros, condimentum eget risus sed, +luctus efficitur arcu. Cras ut dictum mi. Nulla congue interdum lorem, semper semper enim commodo nec.

+
+

1.1.1. Document Subsection

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam efficitur in eros et blandit. Nunc maximus, +nisl at auctor vestibulum, justo ex sollicitudin ligula, id faucibus urna orci tristique nisl. +Duis auctor rutrum orci, in ornare lacus condimentum quis. Quisque arcu velit, facilisis quis interdum ac, +hendrerit auctor mauris. Curabitur urna nibh, porttitor at ante sit amet, vestibulum interdum dolor. +Duis dictum elit orci, tincidunt imperdiet sem pellentesque et. In vehicula pellentesque varius. +Phasellus a turpis sollicitudin, bibendum massa et, imperdiet neque. Integer quis sapien in magna rutrum bibendum. +Integer cursus ex sed magna vehicula finibus. Proin tempus orci quis dolor tempus, nec condimentum odio vestibulum. +Etiam efficitur sollicitudin libero, tincidunt volutpat ligula interdum sed.

+
+

1.1.1.1. Document Subsubsection

+

Donec non rutrum lorem. Aenean sagittis metus at pharetra fringilla. Nunc sapien dolor, cursus sed nisi at, +pretium tristique lectus. Sed pellentesque leo lectus, et convallis ipsum euismod a. +Integer at leo vitae felis pretium aliquam fringilla quis odio. Sed pharetra enim accumsan feugiat pretium. +Maecenas at pharetra tortor. Morbi semper eget mi vel finibus. Cras rutrum nulla eros, id feugiat arcu pellentesque ut. +Sed finibus tortor ac nisi ultrices viverra. Duis feugiat malesuada sapien, at commodo ante porttitor ac. +Curabitur posuere mauris mi, vel ornare orci scelerisque sit amet. Suspendisse nec fringilla dui.

+
+
1.1.1.1.1. Document Paragraph
+

Pellentesque nec est in odio ultrices elementum. Vestibulum et hendrerit sapien, quis vulputate turpis. +Suspendisse potenti. Curabitur tristique sit amet lectus non viverra. Phasellus rutrum dapibus turpis sed imperdiet. +Mauris maximus viverra ante. Donec eu egestas mauris. Morbi vulputate tincidunt euismod. Integer vel porttitor neque. +Donec at lacus suscipit, lacinia lectus vel, sagittis lectus.

+
+
+
+
+
+
+

2. Structural Elements 2

+

Etiam turpis ante, luctus sed velit tristique, finibus volutpat dui. Nam sagittis vel ante nec malesuada. +Praesent dignissim mi nec ornare elementum. Nunc eu augue vel sem dignissim cursus sed et nulla. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. +Pellentesque dictum dui sem, non placerat tortor rhoncus in. Sed placerat nulla at rhoncus iaculis.

+
+

2.1. Document Section

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed condimentum nulla vel neque venenatis, +nec placerat lorem placerat. Cras purus eros, gravida vitae tincidunt id, vehicula nec nulla. +Fusce aliquet auctor cursus. Phasellus ex neque, vestibulum non est vitae, viverra fringilla tortor. +Donec vestibulum convallis justo, a faucibus lorem vulputate vel. Aliquam cursus odio eu felis sodales aliquet. +Aliquam erat volutpat. Maecenas eget dictum mauris. Suspendisse arcu eros, condimentum eget risus sed, +luctus efficitur arcu. Cras ut dictum mi. Nulla congue interdum lorem, semper semper enim commodo nec.

+
+

2.1.1. Document Subsection

+
+../../../../_images/yi_jing_01_chien.jpg +
+

This is a caption for a figure. Text should wrap around the caption.

+
+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam efficitur in eros et blandit. Nunc maximus, +nisl at auctor vestibulum, justo ex sollicitudin ligula, id faucibus urna orci tristique nisl. +Duis auctor rutrum orci, in ornare lacus condimentum quis. Quisque arcu velit, facilisis quis interdum ac, +hendrerit auctor mauris. Curabitur urna nibh, porttitor at ante sit amet, vestibulum interdum dolor. +Duis dictum elit orci, tincidunt imperdiet sem pellentesque et. In vehicula pellentesque varius. +Phasellus a turpis sollicitudin, bibendum massa et, imperdiet neque. Integer quis sapien in magna rutrum bibendum. +Integer cursus ex sed magna vehicula finibus. Proin tempus orci quis dolor tempus, nec condimentum odio vestibulum. +Etiam efficitur sollicitudin libero, tincidunt volutpat ligula interdum sed. Praesent congue sagittis nisl et suscipit. +Vivamus sagittis risus et egestas commodo.Cras venenatis arcu in pharetra interdum. +Donec quis metus porttitor tellus cursus lobortis. Quisque et orci magna. Fusce rhoncus mi mi, +at vehicula massa rhoncus quis. Mauris augue leo, pretium eget molestie vitae, efficitur nec nulla. +In hac habitasse platea dictumst. Sed sit amet imperdiet purus.

+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/src/pytorch-sphinx-theme/docs/index.html b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/index.html new file mode 100644 index 0000000000..f32b393f23 --- /dev/null +++ b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/index.html @@ -0,0 +1,834 @@ + + + + + + + + + + + + + <no title> — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ + + + + + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+
+
    +
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/src/pytorch-sphinx-theme/docs/installing.html b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/installing.html new file mode 100644 index 0000000000..3dcf3c829c --- /dev/null +++ b/docs/v2.2.0/src/pytorch-sphinx-theme/docs/installing.html @@ -0,0 +1,756 @@ + + + + + + + + + + + + + Installation — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Installation

+
+

Via Git or Download

+

Symlink or subtree the pytorch_sphinx_theme repository into your documentation at +docs/_themes/pytorch_sphinx_theme then add the following two settings to your Sphinx +conf.py file:

+
html_theme = "pytorch_sphinx_theme"
+html_theme_path = ["_themes", ]
+
+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/ts/creating_torchscript_module_in_python.html b/docs/v2.2.0/ts/creating_torchscript_module_in_python.html new file mode 100644 index 0000000000..58552b61ba --- /dev/null +++ b/docs/v2.2.0/ts/creating_torchscript_module_in_python.html @@ -0,0 +1,871 @@ + + + + + + + + + + + + + Creating a TorchScript Module — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Creating a TorchScript Module
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Creating a TorchScript Module

+

TorchScript is a way to create serializable and optimizable models from PyTorch code. +PyTorch has detailed documentation on how to do this https://pytorch.org/tutorials/beginner/Intro_to_TorchScript_tutorial.html but briefly here is the +here is key background information and the process:

+

PyTorch programs are based around Module s which can be used to compose higher level modules. Modules contain a constructor to set up the modules, parameters and sub-modules +and a forward function which describes how to use the parameters and submodules when the module is invoked.

+

For example, we can define a LeNet module like this:

+
 1import torch.nn as nn
+ 2import torch.nn.functional as F
+ 3
+ 4
+ 5class LeNetFeatExtractor(nn.Module):
+ 6    def __init__(self):
+ 7        super(LeNetFeatExtractor, self).__init__()
+ 8        self.conv1 = nn.Conv2d(1, 6, 3)
+ 9        self.conv2 = nn.Conv2d(6, 16, 3)
+10
+11    def forward(self, x):
+12        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
+13        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
+14        return x
+15
+16
+17class LeNetClassifier(nn.Module):
+18    def __init__(self):
+19        super(LeNetClassifier, self).__init__()
+20        self.fc1 = nn.Linear(16 * 6 * 6, 120)
+21        self.fc2 = nn.Linear(120, 84)
+22        self.fc3 = nn.Linear(84, 10)
+23
+24    def forward(self, x):
+25        x = torch.flatten(x, 1)
+26        x = F.relu(self.fc1(x))
+27        x = F.relu(self.fc2(x))
+28        x = self.fc3(x)
+29        return x
+30
+31
+32class LeNet(nn.Module):
+33    def __init__(self):
+34        super(LeNet, self).__init__()
+35        self.feat = LeNetFeatExtractor()
+36        self.classifer = LeNetClassifier()
+37
+38    def forward(self, x):
+39        x = self.feat(x)
+40        x = self.classifer(x)
+41        return x
+
+
+

.

+
+

Obviously you may want to consolidate such a simple model into a single module but we can see the composability of PyTorch here

+
+

From here are two pathways for going from PyTorch Python code to TorchScript code: Tracing and Scripting.

+

Tracing follows the path of execution when the module is called and records what happens. +To trace an instance of our LeNet module, we can call torch.jit.trace with an example input.

+
import torch
+
+model = LeNet()
+input_data = torch.empty([1, 1, 32, 32])
+traced_model = torch.jit.trace(model, input_data)
+
+
+

Scripting actually inspects your code with a compiler and generates an equivalent TorchScript program. The difference is that since tracing +is following the execution of your module, it cannot pick up control flow for instance. By working from the Python code, the compiler can +include these components. We can run the script compiler on our LeNet module by calling torch.jit.script

+
import torch
+
+model = LeNet()
+script_model = torch.jit.script(model)
+
+
+

There are reasons to use one path or another, the PyTorch documentation has information on how to choose. From a Torch-TensorRT prespective, there is +better support (i.e your module is more likely to compile) for traced modules because it doesn’t include all the complexities of a complete +programming language, though both paths supported.

+

After scripting or tracing your module, you are given back a TorchScript Module. This contains the code and parameters used to run the module stored +in a intermediate representation that Torch-TensorRT can consume.

+

Here is what the LeNet traced module IR looks like:

+
graph(%self.1 : __torch__.___torch_mangle_10.LeNet,
+    %input.1 : Float(1, 1, 32, 32)):
+    %129 : __torch__.___torch_mangle_9.LeNetClassifier = prim::GetAttr[name="classifer"](%self.1)
+    %119 : __torch__.___torch_mangle_5.LeNetFeatExtractor = prim::GetAttr[name="feat"](%self.1)
+    %137 : Tensor = prim::CallMethod[name="forward"](%119, %input.1)
+    %138 : Tensor = prim::CallMethod[name="forward"](%129, %137)
+    return (%138)
+
+
+

and the LeNet scripted module IR:

+
graph(%self : __torch__.LeNet,
+    %x.1 : Tensor):
+    %2 : __torch__.LeNetFeatExtractor = prim::GetAttr[name="feat"](%self)
+    %x.3 : Tensor = prim::CallMethod[name="forward"](%2, %x.1) # x.py:38:12
+    %5 : __torch__.LeNetClassifier = prim::GetAttr[name="classifer"](%self)
+    %x.5 : Tensor = prim::CallMethod[name="forward"](%5, %x.3) # x.py:39:12
+    return (%x.5)
+
+
+

You can see that the IR preserves the module structure we have in our python code.

+
+
+

Working with TorchScript in Python

+

TorchScript Modules are run the same way you run normal PyTorch modules. You can run the forward pass using the +forward method or just calling the module torch_scirpt_module(in_tensor) The JIT compiler will compile +and optimize the module on the fly and then returns the results.

+
+
+

Saving TorchScript Module to Disk

+

For either traced or scripted modules, you can save the module to disk with the following command

+
import torch
+
+model = LeNet()
+script_model = torch.jit.script(model)
+script_model.save("lenet_scripted.ts")
+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/ts/getting_started_with_cpp_api.html b/docs/v2.2.0/ts/getting_started_with_cpp_api.html new file mode 100644 index 0000000000..77f9541dcc --- /dev/null +++ b/docs/v2.2.0/ts/getting_started_with_cpp_api.html @@ -0,0 +1,1047 @@ + + + + + + + + + + + + + Using Torch-TensorRT in C++ — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Using Torch-TensorRT in C++
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Using Torch-TensorRT in C++

+

If you haven’t already, acquire a tarball of the library by following the instructions in Installation

+
+

Using Torch-TensorRT in C++

+

Torch-TensorRT C++ API accepts TorchScript modules (generated either from torch.jit.script or torch.jit.trace) as an input and returns +a Torchscript module (optimized using TensorRT), Dynamo compilation workflows will not be supported in the C++ API however, execution of +torch.jit.trace’d compiled FX GraphModules is supported for FX and Dyanmo workflows.

+

Please refer to Creating TorchScript modules in Python section to generate torchscript graphs.

+
+

[Torch-TensorRT Quickstart] Compiling TorchScript Modules with torchtrtc

+

An easy way to get started with Torch-TensorRT and to check if your model can be supported without extra work is to run it through +torchtrtc, which supports almost all features of the compiler from the command line including post training quantization +(given a previously created calibration cache). For example we can compile our lenet model by setting our preferred operating +precision and input size. This new TorchScript file can be loaded into Python (note: you need to import torch_tensorrt before loading +these compiled modules because the compiler extends the PyTorch the deserializer and runtime to execute compiled modules).

+
 torchtrtc -p f16 lenet_scripted.ts trt_lenet_scripted.ts "(1,1,32,32)"
+
+❯ python3
+Python 3.6.9 (default, Apr 18 2020, 01:56:04)
+[GCC 8.4.0] on linux
+Type "help", "copyright", "credits" or "license" for more information.
+>>> import torch
+>>> import torch_tensorrt
+>>> ts_model = torch.jit.load(“trt_lenet_scripted.ts”)
+>>> ts_model(torch.randn((1,1,32,32)).to(“cuda”).half())
+
+
+

You can learn more about torchtrtc usage here: torchtrtc

+
+
+

Working with TorchScript in C++

+

If we are developing an application to deploy with C++, we can save either our traced or scripted module using torch.jit.save +which will serialize the TorchScript code, weights and other information into a package. This is also where our dependency on Python ends.

+
torch_script_module.save("lenet.jit.pt")
+
+
+

From here we can now load our TorchScript module in C++

+
#include <torch/script.h> // One-stop header.
+
+#include <iostream>
+#include <memory>
+
+int main(int argc, const char* argv[]) {
+    torch::jit::Module module;
+    try {
+        // Deserialize the ScriptModule from a file using torch::jit::load().
+        module = torch::jit::load("<PATH TO SAVED TS MOD>");
+    }
+    catch (const c10::Error& e) {
+        std::cerr << "error loading the model\n";
+        return -1;
+    }
+
+    std::cout << "ok\n";
+
+
+

You can do full training and inference in C++ with PyTorch / LibTorch if you would like, you can even define your modules in C++ and +have access to the same powerful tensor library that backs PyTorch. (For more information: https://pytorch.org/cppdocs/). +For instance we can do inference with our LeNet module like this:

+
mod.eval();
+torch::Tensor in = torch::randn({1, 1, 32, 32});
+auto out = mod.forward(in);
+
+
+

and to run on the GPU:

+
mod.eval();
+mod.to(torch::kCUDA);
+torch::Tensor in = torch::randn({1, 1, 32, 32}, torch::kCUDA);
+auto out = mod.forward(in);
+
+
+

As you can see it is pretty similar to the Python API. When you call the forward method, you invoke the PyTorch JIT compiler, which will optimize and run your TorchScript code.

+
+
+

Compiling with Torch-TensorRT in C++

+

We are also at the point were we can compile and optimize our module with Torch-TensorRT, but instead of in a JIT fashion we must do it ahead-of-time (AOT) i.e. before we start doing actual inference work +since it takes a bit of time to optimize the module, it would not make sense to do this every time you run the module or even the first time you run it.

+

With our module loaded, we can feed it into the Torch-TensorRT compiler. When we do so we must provide some information on the expected input size and also configure any additional settings.

+
#include "torch/script.h"
+#include "torch_tensorrt/torch_tensorrt.h"
+...
+
+    mod.to(at::kCUDA);
+    mod.eval();
+
+    auto in = torch::randn({1, 1, 32, 32}, {torch::kCUDA});
+    auto trt_mod = torch_tensorrt::CompileGraph(mod, std::vector<torch_tensorrt::CompileSpec::InputRange>{{in.sizes()}});
+    auto out = trt_mod.forward({in});
+
+
+

Thats it! Now the graph runs primarily not with the JIT compiler but using TensorRT (though we execute the graph using the JIT runtime).

+

We can also set settings like operating precision to run in FP16.

+
#include "torch/script.h"
+#include "torch_tensorrt/torch_tensorrt.h"
+...
+
+    mod.to(at::kCUDA);
+    mod.eval();
+
+    auto in = torch::randn({1, 1, 32, 32}, {torch::kCUDA}).to(torch::kHALF);
+    auto input_sizes = std::vector<torch_tensorrt::CompileSpec::InputRange>({in.sizes()});
+    torch_tensorrt::CompileSpec info(input_sizes);
+    info.enable_precisions.insert(torch::kHALF);
+    auto trt_mod = torch_tensorrt::CompileGraph(mod, info);
+    auto out = trt_mod.forward({in});
+
+
+

And now we are running the module in FP16 precision. You can then save the module to load later.

+
trt_mod.save("<PATH TO SAVED TRT/TS MOD>")
+
+
+

Torch-TensorRT compiled TorchScript modules are loaded in the same way as normal TorchScript module. Make sure your deployment application is linked against libtorchtrt.so

+
#include "torch/script.h"
+#include "torch_tensorrt/torch_tensorrt.h"
+
+int main(int argc, const char* argv[]) {
+    torch::jit::Module module;
+    try {
+        // Deserialize the ScriptModule from a file using torch::jit::load().
+        module = torch::jit::load("<PATH TO SAVED TRT/TS MOD>");
+    }
+    catch (const c10::Error& e) {
+        std::cerr << "error loading the model\n";
+        return -1;
+    }
+
+    torch::Tensor in = torch::randn({1, 1, 32, 32}, torch::kCUDA);
+    auto out = mod.forward(in);
+
+    std::cout << "ok\n";
+}
+
+
+

If you want to save the engine produced by Torch-TensorRT to use in a TensorRT application you can use the ConvertGraphToTRTEngine API.

+
#include "torch/script.h"
+#include "torch_tensorrt/torch_tensorrt.h"
+...
+
+    mod.to(at::kCUDA);
+    mod.eval();
+
+    auto in = torch::randn({1, 1, 32, 32}, {torch::kCUDA}).to(torch::kHALF);
+    auto input_sizes = std::vector<torch_tensorrt::CompileSpec::InputRange>({in.sizes()});
+    torch_tensorrt::CompileSpec info(input_sizes);
+    info.enabled_precisions.insert(torch::kHALF);
+    auto trt_mod = torch_tensorrt::ConvertGraphToTRTEngine(mod, "forward", info);
+    std::ofstream out("/tmp/engine_converted_from_jit.trt");
+    out << engine;
+    out.close();
+
+
+
+
+

Under The Hood

+

When a module is provided to Torch-TensorRT, the compiler starts by mapping a graph like you saw above to a graph like this:

+
graph(%input.2 : Tensor):
+    %2 : Float(84, 10) = prim::Constant[value=<Tensor>]()
+    %3 : Float(120, 84) = prim::Constant[value=<Tensor>]()
+    %4 : Float(576, 120) = prim::Constant[value=<Tensor>]()
+    %5 : int = prim::Constant[value=-1]() # x.py:25:0
+    %6 : int[] = prim::Constant[value=annotate(List[int], [])]()
+    %7 : int[] = prim::Constant[value=[2, 2]]()
+    %8 : int[] = prim::Constant[value=[0, 0]]()
+    %9 : int[] = prim::Constant[value=[1, 1]]()
+    %10 : bool = prim::Constant[value=1]() # ~/.local/lib/python3.6/site-packages/torch/nn/modules/conv.py:346:0
+    %11 : int = prim::Constant[value=1]() # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0
+    %12 : bool = prim::Constant[value=0]() # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0
+    %self.classifer.fc3.bias : Float(10) = prim::Constant[value= 0.0464  0.0383  0.0678  0.0932  0.1045 -0.0805 -0.0435 -0.0818  0.0208 -0.0358 [ CUDAFloatType{10} ]]()
+    %self.classifer.fc2.bias : Float(84) = prim::Constant[value=<Tensor>]()
+    %self.classifer.fc1.bias : Float(120) = prim::Constant[value=<Tensor>]()
+    %self.feat.conv2.weight : Float(16, 6, 3, 3) = prim::Constant[value=<Tensor>]()
+    %self.feat.conv2.bias : Float(16) = prim::Constant[value=<Tensor>]()
+    %self.feat.conv1.weight : Float(6, 1, 3, 3) = prim::Constant[value=<Tensor>]()
+    %self.feat.conv1.bias : Float(6) = prim::Constant[value= 0.0530 -0.1691  0.2802  0.1502  0.1056 -0.1549 [ CUDAFloatType{6} ]]()
+    %input0.4 : Tensor = aten::_convolution(%input.2, %self.feat.conv1.weight, %self.feat.conv1.bias, %9, %8, %9, %12, %8, %11, %12, %12, %10) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/conv.py:346:0
+    %input0.5 : Tensor = aten::relu(%input0.4) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0
+    %input1.2 : Tensor = aten::max_pool2d(%input0.5, %7, %6, %8, %9, %12) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0
+    %input0.6 : Tensor = aten::_convolution(%input1.2, %self.feat.conv2.weight, %self.feat.conv2.bias, %9, %8, %9, %12, %8, %11, %12, %12, %10) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/conv.py:346:0
+    %input2.1 : Tensor = aten::relu(%input0.6) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0
+    %x.1 : Tensor = aten::max_pool2d(%input2.1, %7, %6, %8, %9, %12) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0
+    %input.1 : Tensor = aten::flatten(%x.1, %11, %5) # x.py:25:0
+    %27 : Tensor = aten::matmul(%input.1, %4)
+    %28 : Tensor = trt::const(%self.classifer.fc1.bias)
+    %29 : Tensor = aten::add_(%28, %27, %11)
+    %input0.2 : Tensor = aten::relu(%29) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0
+    %31 : Tensor = aten::matmul(%input0.2, %3)
+    %32 : Tensor = trt::const(%self.classifer.fc2.bias)
+    %33 : Tensor = aten::add_(%32, %31, %11)
+    %input1.1 : Tensor = aten::relu(%33) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0
+    %35 : Tensor = aten::matmul(%input1.1, %2)
+    %36 : Tensor = trt::const(%self.classifer.fc3.bias)
+    %37 : Tensor = aten::add_(%36, %35, %11)
+    return (%37)
+(CompileGraph)
+
+
+

The graph has now been transformed from a collection of modules, each managing their own parameters into a single graph with the parameters inlined +into the graph and all of the operations laid out. Torch-TensorRT has also executed a number of optimizations and mappings to make the graph easier to translate to TensorRT. +From here the compiler can assemble the TensorRT engine by following the dataflow through the graph.

+

When the graph construction phase is complete, Torch-TensorRT produces a serialized TensorRT engine. From here depending on the API, this engine is returned +to the user or moves into the graph construction phase. Here Torch-TensorRT creates a JIT Module to execute the TensorRT engine which will be instantiated and managed +by the Torch-TensorRT runtime.

+

Here is the graph that you get back after compilation is complete:

+
graph(%self_1 : __torch__.lenet, %input_0 : Tensor):
+    %1 : ...trt.Engine = prim::GetAttr[name="lenet"](%self_1)
+    %3 : Tensor[] = prim::ListConstruct(%input_0)
+    %4 : Tensor[] = trt::execute_engine(%3, %1)
+    %5 : Tensor = prim::ListUnpack(%4)
+    return (%5)
+
+
+

You can see the call where the engine is executed, after extracting the attribute containing the engine and constructing a list of inputs, then returns the tensors back to the user.

+
+
+

Working with Unsupported Operators

+

Torch-TensorRT is a new library and the PyTorch operator library is quite large, so there will be ops that aren’t supported natively by the compiler. You can either use the composition techinques +shown above to make modules are fully Torch-TensorRT supported and ones that are not and stitch the modules together in the deployment application or you can register converters for missing ops.

+
+

You can check support without going through the full compilation pipleine using the torch_tensorrt::CheckMethodOperatorSupport(const torch::jit::Module& module, std::string method_name) api +to see what operators are not supported. torchtrtc automatically checks modules with this method before starting compilation and will print out a list of operators that are not supported.

+
+
+

Registering Custom Converters

+

Operations are mapped to TensorRT through the use of modular converters, a function that takes a node from a the JIT graph and produces an equivalent layer or subgraph in TensorRT. +Torch-TensorRT ships with a library of these converters stored in a registry, that will be executed depending on the node being parsed. For instance a aten::relu(%input0.4) instruction will trigger +the relu converter to be run on it, producing an activation layer in the TensorRT graph. But since this library is not exhaustive you may need to write your own to get Torch-TensorRT +to support your module.

+

Shipped with the Torch-TensorRT distribution are the internal core API headers. You can therefore access the converter registry and add a converter for the op you need.

+

For example, if we try to compile a graph with a build of Torch-TensorRT that doesn’t support the flatten operation (aten::flatten) you may see this error:

+
terminate called after throwing an instance of 'torch_tensorrt::Error'
+what():  [enforce fail at core/conversion/conversion.cpp:109] Expected converter to be true but got false
+Unable to convert node: %input.1 : Tensor = aten::flatten(%x.1, %11, %5) # x.py:25:0 (conversion.AddLayer)
+Schema: aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor)
+Converter for aten::flatten requested, but no such converter was found.
+If you need a converter for this operator, you can try implementing one yourself
+or request a converter: https://www.github.com/NVIDIA/Torch-TensorRT/issues
+
+
+

We can register a converter for this operator in our application. All of the tools required to build a converter can be imported by including torch_tensorrt/core/conversion/converters/converters.h. +We start by creating an instance of the self-registering class torch_tensorrt::core::conversion::converters::RegisterNodeConversionPatterns() which will register converters +in the global converter registry, associating a function schema like aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor) with a lambda that +will take the state of the conversion, the node/operation in question to convert and all of the inputs to the node and produces as a side effect a new layer in the TensorRT network. +Arguments are passed as a vector of inspectable unions of TensorRT ITensors and Torch IValues in the order arguments are listed in the schema.

+

Below is a implementation of a aten::flatten converter that we can use in our application. You have full access to the Torch and TensorRT libraries in the converter implementation. So +for example we can quickly get the output size by just running the operation in PyTorch instead of implementing the full calculation outself like we do below for this flatten converter.

+
#include "torch/script.h"
+#include "torch_tensorrt/torch_tensorrt.h"
+#include "torch_tensorrt/core/conversion/converters/converters.h"
+
+static auto flatten_converter = torch_tensorrt::core::conversion::converters::RegisterNodeConversionPatterns()
+    .pattern({
+        "aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor)",
+        [](torch_tensorrt::core::conversion::ConversionCtx* ctx,
+           const torch::jit::Node* n,
+           torch_tensorrt::core::conversion::converters::args& args) -> bool {
+            auto in = args[0].ITensor();
+            auto start_dim = args[1].unwrapToInt();
+            auto end_dim = args[2].unwrapToInt();
+            auto in_shape = torch_tensorrt::core::util::toVec(in->getDimensions());
+            auto out_shape = torch::flatten(torch::rand(in_shape), start_dim, end_dim).sizes();
+
+            auto shuffle = ctx->net->addShuffle(*in);
+            shuffle->setReshapeDimensions(torch_tensorrt::core::util::toDims(out_shape));
+            shuffle->setName(torch_tensorrt::core::util::node_info(n).c_str());
+
+            auto out_tensor = ctx->AssociateValueAndTensor(n->outputs()[0], shuffle->getOutput(0));
+            return true;
+        }
+    });
+
+int main() {
+    ...
+
+
+

To use this converter in Python, it is recommended to use PyTorch’s C++ / CUDA Extention +template to wrap your library of converters into a .so that you can load with ctypes.CDLL() in your Python application.

+

You can find more information on all the details of writing converters in the contributors documentation (writing_converters). +If you find yourself with a large library of converter implementations, do consider upstreaming them, PRs are welcome and it would be great for the community to benefit as well.

+
+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/ts/getting_started_with_python_api.html b/docs/v2.2.0/ts/getting_started_with_python_api.html new file mode 100644 index 0000000000..062e93e835 --- /dev/null +++ b/docs/v2.2.0/ts/getting_started_with_python_api.html @@ -0,0 +1,824 @@ + + + + + + + + + + + + + Using Torch-TensorRT in Python — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Using Torch-TensorRT in Python
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Using Torch-TensorRT in Python

+

The Torch-TensorRT Python API supports a number of unique usecases compared to the CLI and C++ APIs which solely support TorchScript compilation.

+

Torch-TensorRT Python API can accept a torch.nn.Module, torch.jit.ScriptModule, or torch.fx.GraphModule as an input. +Depending on what is provided one of the two frontends (TorchScript or FX) will be selected to compile the module. Provided the +module type is supported, users may explicitly set which frontend they would like to use using the ir flag for compile. +If given a torch.nn.Module and the ir flag is set to either default or torchscript the module will be run through +torch.jit.script to convert the input module into a TorchScript module.

+

To compile your input torch.nn.Module with Torch-TensorRT, all you need to do is provide the module and inputs +to Torch-TensorRT and you will be returned an optimized TorchScript module to run or add into another PyTorch module. Inputs +is a list of torch_tensorrt.Input classes which define input Tensors’ shape, datatype and memory format. Alternatively, if your input is a more complex data type, such as a tuple or list of Tensors, you can use the input_signature argument to specify a collection-based input, such as (List[Tensor], Tuple[Tensor, Tensor]). See the second sample below for an example. You can also specify settings such as operating precision for the engine or target device. After compilation you can save the module just like any other module +to load in a deployment application. In order to load a TensorRT/TorchScript module, make sure you first import torch_tensorrt.

+
import torch_tensorrt
+
+...
+
+model = MyModel().eval()  # torch module needs to be in eval (not training) mode
+
+inputs = [
+    torch_tensorrt.Input(
+        min_shape=[1, 1, 16, 16],
+        opt_shape=[1, 1, 32, 32],
+        max_shape=[1, 1, 64, 64],
+        dtype=torch.half,
+    )
+]
+enabled_precisions = {torch.float, torch.half}  # Run with fp16
+
+trt_ts_module = torch_tensorrt.compile(
+    model, inputs=inputs, enabled_precisions=enabled_precisions
+)
+
+input_data = input_data.to("cuda").half()
+result = trt_ts_module(input_data)
+torch.jit.save(trt_ts_module, "trt_ts_module.ts")
+
+
+
# Sample using collection-based inputs via the input_signature argument
+import torch_tensorrt
+
+...
+
+model = MyModel().eval()
+
+# input_signature expects a tuple of individual input arguments to the module
+# The module below, for example, would have a docstring of the form:
+# def forward(self, input0: List[torch.Tensor], input1: Tuple[torch.Tensor, torch.Tensor])
+input_signature = (
+    [torch_tensorrt.Input(shape=[64, 64], dtype=torch.half), torch_tensorrt.Input(shape=[64, 64], dtype=torch.half)],
+    (torch_tensorrt.Input(shape=[64, 64], dtype=torch.half), torch_tensorrt.Input(shape=[64, 64], dtype=torch.half)),
+)
+enabled_precisions = {torch.float, torch.half}
+
+trt_ts_module = torch_tensorrt.compile(
+    model, input_signature=input_signature, enabled_precisions=enabled_precisions
+)
+
+input_data = input_data.to("cuda").half()
+result = trt_ts_module(input_data)
+torch.jit.save(trt_ts_module, "trt_ts_module.ts")
+
+
+
# Deployment application
+import torch
+import torch_tensorrt
+
+trt_ts_module = torch.jit.load("trt_ts_module.ts")
+input_data = input_data.to("cuda").half()
+result = trt_ts_module(input_data)
+
+
+

Torch-TensorRT Python API also provides torch_tensorrt.ts.compile which accepts a TorchScript module as input and torch_tensorrt.fx.compile which accepts a FX GraphModule as input.

+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/ts/torchscript_frontend_from_pytorch.html b/docs/v2.2.0/ts/torchscript_frontend_from_pytorch.html new file mode 100644 index 0000000000..e2d5e7d644 --- /dev/null +++ b/docs/v2.2.0/ts/torchscript_frontend_from_pytorch.html @@ -0,0 +1,791 @@ + + + + + + + + + + + + + Using Torch-TensorRT TorchScript Frontend Directly From PyTorch — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Using Torch-TensorRT TorchScript Frontend Directly From PyTorch
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Using Torch-TensorRT TorchScript Frontend Directly From PyTorch

+

You will now be able to directly access TensorRT from PyTorch APIs. The process to use this feature +is very similar to the compilation workflow described in Using Torch-TensorRT in Python

+

Start by loading torch_tensorrt into your application.

+
import torch
+import torch_tensorrt
+
+
+

Then given a TorchScript module, you can compile it with TensorRT using the torch._C._jit_to_backend("tensorrt", ...) API.

+
import torchvision.models as models
+
+model = models.mobilenet_v2(pretrained=True)
+script_model = torch.jit.script(model)
+
+
+

Unlike the compile API in Torch-TensorRT which assumes you are trying to compile the forward function of a module +or the convert_method_to_trt_engine which converts a specified function to a TensorRT engine, the backend API +will take a dictionary which maps names of functions to compile to Compilation Spec objects which wrap the same +sort of dictionary you would provide to compile. For more information on the compile spec dictionary take a look +at the documentation for the Torch-TensorRT TensorRTCompileSpec API.

+
spec = {
+    "forward": torch_tensorrt.ts.TensorRTCompileSpec(
+        **{
+            "inputs": [torch_tensorrt.Input([1, 3, 300, 300])],
+            "enabled_precisions": {torch.float, torch.half},
+            "refit": False,
+            "debug": False,
+            "device": {
+                "device_type": torch_tensorrt.DeviceType.GPU,
+                "gpu_id": 0,
+                "dla_core": 0,
+                "allow_gpu_fallback": True,
+            },
+            "capability": torch_tensorrt.EngineCapability.default,
+            "num_avg_timing_iters": 1,
+        }
+    )
+}
+
+
+

Now to compile with Torch-TensorRT, provide the target module objects and the spec dictionary to torch._C._jit_to_backend("tensorrt", ...)

+
trt_model = torch._C._jit_to_backend("tensorrt", script_model, spec)
+
+
+

To run explicitly call the function of the method you want to run (vs. how you can just call on the module itself in standard PyTorch)

+
input = torch.randn((1, 3, 300, 300)).to("cuda").to(torch.half)
+print(trt_model.forward(input))
+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/tutorials/_rendered_examples/dynamo/index.html b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/index.html new file mode 100644 index 0000000000..2e7fe5246c --- /dev/null +++ b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/index.html @@ -0,0 +1,765 @@ + + + + + + + + + + + + + Dynamo / torch.compile — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Dynamo / torch.compile
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Dynamo / torch.compile

+

Torch-TensorRT provides a backend for the new torch.compile API released in PyTorch 2.0. In the following examples we describe +a number of ways you can leverage this backend to accelerate inference.

+ +
+

Torch Compile Stable Diffusion

+
Torch Compile Stable Diffusion
+
+

Compiling ResNet using the Torch-TensorRT torch.compile Backend

+
Compiling ResNet using the Torch-TensorRT torch.compile Backend
+
+

Compiling a Transformer using torch.compile and TensorRT

+
Compiling a Transformer using torch.compile and TensorRT
+
+

Torch Compile Advanced Usage

+
Torch Compile Advanced Usage
+
+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.html b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.html new file mode 100644 index 0000000000..bd2769aa81 --- /dev/null +++ b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_advanced_usage.html @@ -0,0 +1,871 @@ + + + + + + + + + + + + + Torch Compile Advanced Usage — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Torch Compile Advanced Usage
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ + +
+

Torch Compile Advanced Usage

+

This interactive script is intended as an overview of the process by which torch_tensorrt.compile(…, ir=”torch_compile”, …) works, and how it integrates with the torch.compile API.

+
+

Imports and Model Definition

+
import torch
+import torch_tensorrt
+
+
+
# We begin by defining a model
+class Model(torch.nn.Module):
+    def __init__(self) -> None:
+        super().__init__()
+        self.relu = torch.nn.ReLU()
+
+    def forward(self, x: torch.Tensor, y: torch.Tensor):
+        x_out = self.relu(x)
+        y_out = self.relu(y)
+        x_y_out = x_out + y_out
+        return torch.mean(x_y_out)
+
+
+
+
+

Compilation with torch.compile Using Default Settings

+
# Define sample float inputs and initialize model
+sample_inputs = [torch.rand((5, 7)).cuda(), torch.rand((5, 7)).cuda()]
+model = Model().eval().cuda()
+
+
+
# Next, we compile the model using torch.compile
+# For the default settings, we can simply call torch.compile
+# with the backend "torch_tensorrt", and run the model on an
+# input to cause compilation, as so:
+optimized_model = torch.compile(model, backend="torch_tensorrt", dynamic=False)
+optimized_model(*sample_inputs)
+
+
+
+
+

Compilation with torch.compile Using Custom Settings

+
# First, we use Torch utilities to clean up the workspace
+# after the previous compile invocation
+torch._dynamo.reset()
+
+# Define sample half inputs and initialize model
+sample_inputs_half = [
+    torch.rand((5, 7)).half().cuda(),
+    torch.rand((5, 7)).half().cuda(),
+]
+model_half = Model().eval().cuda()
+
+
+
# If we want to customize certain options in the backend,
+# but still use the torch.compile call directly, we can provide
+# custom options to the backend via the "options" keyword
+# which takes in a dictionary mapping options to values.
+#
+# For accepted backend options, see the CompilationSettings dataclass:
+# py/torch_tensorrt/dynamo/_settings.py
+backend_kwargs = {
+    "enabled_precisions": {torch.half},
+    "debug": True,
+    "min_block_size": 2,
+    "torch_executed_ops": {"torch.ops.aten.sub.Tensor"},
+    "optimization_level": 4,
+    "use_python_runtime": False,
+}
+
+# Run the model on an input to cause compilation, as so:
+optimized_model_custom = torch.compile(
+    model_half,
+    backend="torch_tensorrt",
+    options=backend_kwargs,
+    dynamic=False,
+)
+optimized_model_custom(*sample_inputs_half)
+
+
+
+
+

Cleanup

+
# Finally, we use Torch utilities to clean up the workspace
+torch._dynamo.reset()
+
+
+
+
+

Cuda Driver Error Note

+

Occasionally, upon exiting the Python runtime after Dynamo compilation with torch_tensorrt, +one may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052 +and can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in:

+
if __name__ == '__main__':
+    compile_engine_and_infer()
+
+
+

Total running time of the script: ( 0 minutes 0.000 seconds)

+ +

Gallery generated by Sphinx-Gallery

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.html b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.html new file mode 100644 index 0000000000..1c4803381c --- /dev/null +++ b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_resnet_example.html @@ -0,0 +1,859 @@ + + + + + + + + + + + + + Compiling ResNet using the Torch-TensorRT torch.compile Backend — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Compiling ResNet using the Torch-TensorRT torch.compile Backend
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ + +
+

Compiling ResNet using the Torch-TensorRT torch.compile Backend

+

This interactive script is intended as a sample of the Torch-TensorRT workflow with torch.compile on a ResNet model.

+
+

Imports and Model Definition

+
import torch
+import torch_tensorrt
+import torchvision.models as models
+
+
+
# Initialize model with half precision and sample inputs
+model = models.resnet18(pretrained=True).half().eval().to("cuda")
+inputs = [torch.randn((1, 3, 224, 224)).to("cuda").half()]
+
+
+
+
+

Optional Input Arguments to torch_tensorrt.compile

+
# Enabled precision for TensorRT optimization
+enabled_precisions = {torch.half}
+
+# Whether to print verbose logs
+debug = True
+
+# Workspace size for TensorRT
+workspace_size = 20 << 30
+
+# Maximum number of TRT Engines
+# (Lower value allows more graph segmentation)
+min_block_size = 7
+
+# Operations to Run in Torch, regardless of converter support
+torch_executed_ops = {}
+
+
+
+
+

Compilation with torch_tensorrt.compile

+
# Build and compile the model with torch.compile, using Torch-TensorRT backend
+optimized_model = torch_tensorrt.compile(
+    model,
+    ir="torch_compile",
+    inputs=inputs,
+    enabled_precisions=enabled_precisions,
+    debug=debug,
+    workspace_size=workspace_size,
+    min_block_size=min_block_size,
+    torch_executed_ops=torch_executed_ops,
+)
+
+
+

Equivalently, we could have run the above via the torch.compile frontend, as so: +optimized_model = torch.compile(model, backend=”torch_tensorrt”, options={“enabled_precisions”: enabled_precisions, …}); optimized_model(*inputs)

+
+
+

Inference

+
# Does not cause recompilation (same batch size as input)
+new_inputs = [torch.randn((1, 3, 224, 224)).half().to("cuda")]
+new_outputs = optimized_model(*new_inputs)
+
+
+
# Does cause recompilation (new batch size)
+new_batch_size_inputs = [torch.randn((8, 3, 224, 224)).half().to("cuda")]
+new_batch_size_outputs = optimized_model(*new_batch_size_inputs)
+
+
+
+
+

Cleanup

+
# Finally, we use Torch utilities to clean up the workspace
+torch._dynamo.reset()
+
+
+
+
+

Cuda Driver Error Note

+

Occasionally, upon exiting the Python runtime after Dynamo compilation with torch_tensorrt, +one may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052 +and can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in:

+
if __name__ == '__main__':
+    compile_engine_and_infer()
+
+
+

Total running time of the script: ( 0 minutes 0.000 seconds)

+ +

Gallery generated by Sphinx-Gallery

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.html b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.html new file mode 100644 index 0000000000..e95143b6e3 --- /dev/null +++ b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_stable_diffusion.html @@ -0,0 +1,816 @@ + + + + + + + + + + + + + Torch Compile Stable Diffusion — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Torch Compile Stable Diffusion
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ + +
+

Torch Compile Stable Diffusion

+

This interactive script is intended as a sample of the Torch-TensorRT workflow with torch.compile on a Stable Diffusion model. A sample output is featured below:

+../../../_images/majestic_castle.png +
+

Imports and Model Definition

+
import torch
+from diffusers import DiffusionPipeline
+
+import torch_tensorrt
+
+model_id = "CompVis/stable-diffusion-v1-4"
+device = "cuda:0"
+
+# Instantiate Stable Diffusion Pipeline with FP16 weights
+pipe = DiffusionPipeline.from_pretrained(
+    model_id, revision="fp16", torch_dtype=torch.float16
+)
+pipe = pipe.to(device)
+
+backend = "torch_tensorrt"
+
+# Optimize the UNet portion with Torch-TensorRT
+pipe.unet = torch.compile(
+    pipe.unet,
+    backend=backend,
+    options={
+        "truncate_long_and_double": True,
+        "precision": torch.float16,
+    },
+    dynamic=False,
+)
+
+
+
+
+

Inference

+
prompt = "a majestic castle in the clouds"
+image = pipe(prompt).images[0]
+
+image.save("images/majestic_castle.png")
+image.show()
+
+
+

Total running time of the script: ( 0 minutes 0.000 seconds)

+ +

Gallery generated by Sphinx-Gallery

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.html b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.html new file mode 100644 index 0000000000..32acad7359 --- /dev/null +++ b/docs/v2.2.0/tutorials/_rendered_examples/dynamo/torch_compile_transformers_example.html @@ -0,0 +1,874 @@ + + + + + + + + + + + + + Compiling a Transformer using torch.compile and TensorRT — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Compiling a Transformer using torch.compile and TensorRT
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ + +
+

Compiling a Transformer using torch.compile and TensorRT

+

This interactive script is intended as a sample of the Torch-TensorRT workflow with torch.compile on a transformer-based model.

+
+

Imports and Model Definition

+
import torch
+import torch_tensorrt
+from transformers import BertModel
+
+
+
# Initialize model with float precision and sample inputs
+model = BertModel.from_pretrained("bert-base-uncased").eval().to("cuda")
+inputs = [
+    torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"),
+    torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"),
+]
+
+
+
+
+

Optional Input Arguments to torch_tensorrt.compile

+
# Enabled precision for TensorRT optimization
+enabled_precisions = {torch.float}
+
+# Whether to print verbose logs
+debug = True
+
+# Workspace size for TensorRT
+workspace_size = 20 << 30
+
+# Maximum number of TRT Engines
+# (Lower value allows more graph segmentation)
+min_block_size = 7
+
+# Operations to Run in Torch, regardless of converter support
+torch_executed_ops = {}
+
+
+
+
+

Compilation with torch.compile

+
# Define backend compilation keyword arguments
+compilation_kwargs = {
+    "enabled_precisions": enabled_precisions,
+    "debug": debug,
+    "workspace_size": workspace_size,
+    "min_block_size": min_block_size,
+    "torch_executed_ops": torch_executed_ops,
+}
+
+# Build and compile the model with torch.compile, using Torch-TensorRT backend
+optimized_model = torch.compile(
+    model,
+    backend="torch_tensorrt",
+    dynamic=False,
+    options=compilation_kwargs,
+)
+optimized_model(*inputs)
+
+
+

Equivalently, we could have run the above via the convenience frontend, as so: +torch_tensorrt.compile(model, ir=”torch_compile”, inputs=inputs, **compilation_kwargs)

+
+
+

Inference

+
# Does not cause recompilation (same batch size as input)
+new_inputs = [
+    torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"),
+    torch.randint(0, 2, (1, 14), dtype=torch.int32).to("cuda"),
+]
+new_outputs = optimized_model(*new_inputs)
+
+
+
# Does cause recompilation (new batch size)
+new_inputs = [
+    torch.randint(0, 2, (4, 14), dtype=torch.int32).to("cuda"),
+    torch.randint(0, 2, (4, 14), dtype=torch.int32).to("cuda"),
+]
+new_outputs = optimized_model(*new_inputs)
+
+
+
+
+

Cleanup

+
# Finally, we use Torch utilities to clean up the workspace
+torch._dynamo.reset()
+
+
+
+
+

Cuda Driver Error Note

+

Occasionally, upon exiting the Python runtime after Dynamo compilation with torch_tensorrt, +one may encounter a Cuda Driver Error. This issue is related to https://github.com/NVIDIA/TensorRT/issues/2052 +and can be resolved by wrapping the compilation/inference in a function and using a scoped call, as in:

+
if __name__ == '__main__':
+    compile_engine_and_infer()
+
+
+

Total running time of the script: ( 0 minutes 0.000 seconds)

+ +

Gallery generated by Sphinx-Gallery

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/tutorials/_rendered_examples/index.html b/docs/v2.2.0/tutorials/_rendered_examples/index.html new file mode 100644 index 0000000000..025f08ed3b --- /dev/null +++ b/docs/v2.2.0/tutorials/_rendered_examples/index.html @@ -0,0 +1,782 @@ + + + + + + + + + + + + + Torch-TensorRT Tutorials — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Torch-TensorRT Tutorials
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Torch-TensorRT Tutorials

+

The user guide covers the basic concepts and usage of Torch-TensorRT. +We also provide a number of tutorials to explore specific usecases and advanced concepts

+
+

Dynamo / torch.compile

+

Torch-TensorRT provides a backend for the new torch.compile API released in PyTorch 2.0. In the following examples we describe +a number of ways you can leverage this backend to accelerate inference.

+ +
+

Torch Compile Stable Diffusion

+
Torch Compile Stable Diffusion
+
+

Compiling ResNet using the Torch-TensorRT torch.compile Backend

+
Compiling ResNet using the Torch-TensorRT torch.compile Backend
+
+

Compiling a Transformer using torch.compile and TensorRT

+
Compiling a Transformer using torch.compile and TensorRT
+
+

Torch Compile Advanced Usage

+
Torch Compile Advanced Usage
+
+
+ +

Gallery generated by Sphinx-Gallery

+
+
+ + +
+ +
+
+ + + + +
+ + + +
+

+ © Copyright 2022, NVIDIA Corporation. + +

+
+ +
+ Built with Sphinx using a theme provided by Read the Docs. +
+ + +
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/tutorials/notebooks.html b/docs/v2.2.0/tutorials/notebooks.html new file mode 100644 index 0000000000..ac49e3a862 --- /dev/null +++ b/docs/v2.2.0/tutorials/notebooks.html @@ -0,0 +1,906 @@ + + + + + + + + + + + + + Example notebooks — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Example notebooks
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Example notebooks

+

There exists a number of notebooks which cover specific using specific features and models +with Torch-TensorRT

+
+

Notebooks

+
+

Compiling CitriNet with Torch-TensorRT

+

Citrinet is an acoustic model used for the speech to text recognition task. It is a version +of QuartzNet that extends ContextNet, utilizing subword encoding (via Word Piece tokenization) +and Squeeze-and-Excitation(SE) mechanism and are therefore smaller than QuartzNet models. CitriNet +models take in audio segments and transcribe them to letter, byte pair, or word piece sequences.

+

This notebook demonstrates the steps for optimizing a pretrained CitriNet model with Torch-TensorRT, +and running it to test the speedup obtained.

+ +
+
+

Compiling EfficentNet with Torch-TensorRT

+

EfficentNet is a feedforward CNN designed to achieve better performance and accuracy than alternative architectures +by using a “scaling method that uniformly scales all dimensions of depth/width/resolution using a simple yet highly effective compound coefficient”.

+

This notebook demonstrates the steps for optimizing a pretrained EfficentNet model with Torch-TensorRT, +and running it to test the speedup obtained.

+ +
+
+

Masked Language Modeling (MLM) with Hugging Face BERT Transformer accelerated by Torch-TensorRT

+

“BERT is a transformer model pretrained on a large corpus of English data in a self-supervised fashion. +This way, the model learns an inner representation of the English language that can then be used to extract +features useful for downstream tasks: if you have a dataset of labeled sentences for instance, you can train +a standard classifier using the features produced by the BERT model as inputs.” (https://huggingface.co/bert-base-uncased)

+

This notebook demonstrates the steps for optimizing a pretrained EfficentNet model with Torch-TensorRT, +and running it to test the speedup obtained.

+ +
+
+

Serving a model in C++ using Torch-TensorRT

+

This example shows how you can load a pretrained ResNet-50 model, convert it to a Torch-TensorRT +optimized model (via the Torch-TensorRT Python API), save the model as a torchscript module, and +then finally load and serve the model with the PyTorch C++ API.

+ +
+
+

Compiling ResNet50 with Torch-TensorRT

+

This notebook demonstrates the steps for compiling a TorchScript module with Torch-TensorRT on a +pretrained ResNet-50 network, and running it to test the speedup obtained.

+ +
+
+

Using Dynamic Shapes with Torch-TensorRT

+

Making use of Dynamic Shaped Tensors in Torch TensorRT is quite simple. Let’s say you are +using the torch_tensorrt.compile(...) function to compile a torchscript module. One +of the args in this function in this function is input: which defines an input to a +module in terms of expected shape, data type and tensor format: torch_tensorrt.Input.

+

For the purposes of this walkthrough we just need three kwargs: min_shape, opt_shape` and max_shape.

+
torch_tensorrt.Input(
+        min_shape=(1, 224, 224, 3),
+        opt_shape=(1, 512, 512, 3),
+        max_shape=(1, 1024, 1024, 3),
+        dtype=torch.int32
+        format=torch.channel_last
+    )
+...
+
+
+

In this example, we are going to use a simple ResNet model to demonstrate the use of the API.

+ +
+
+

Using the FX Frontend with Torch-TensorRT

+

The purpose of this example is to demostrate the overall flow of lowering a PyTorch model to TensorRT +conveniently with using FX.

+ +
+
+

Compiling a PyTorch model using FX Frontend with Torch-TensorRT

+

The purpose of this example is to demonstrate the overall flow of lowering a PyTorch +model to TensorRT via FX with existing FX based tooling

+ +
+
+

Compiling LeNet with Torch-TensorRT

+

This notebook demonstrates the steps for compiling a TorchScript module with Torch-TensorRT on a simple LeNet network.

+ +
+
+

Accelerate Deep Learning Models using Quantization in Torch-TensorRT

+

Model Quantization is a popular way of optimization which reduces the size of models thereby +accelerating inference, also opening up the possibilities of deployments on devices with lower +computation power such as Jetson. Simply put, quantization is a process of mapping input values

+
+

from a larger set to output values in a smaller set. In this notebook, we illustrate the workflow +that you can adopt while quantizing a deep learning model in Torch-TensorRT. The notebook takes +you through an example of Mobilenetv2 for a classification task on a subset of Imagenet Dataset +called Imagenette which has 10 classes.

+
+ +
+
+

Object Detection with Torch-TensorRT (SSD)

+

This notebook demonstrates the steps for compiling a TorchScript module with Torch-TensorRT on a pretrained SSD network, and running it to test the speedup obtained.

+ +
+
+

Deploying Quantization Aware Trained models in INT8 using Torch-TensorRT

+

Quantization Aware training (QAT) simulates quantization during training by +quantizing weights and activation layers. This will help to reduce the loss in +accuracy when we convert the network trained in FP32 to INT8 for faster inference. +QAT introduces additional nodes in the graph which will be used to learn the dynamic +ranges of weights and activation layers. In this notebook, we illustrate the following +steps from training to inference of a QAT model in Torch-TensorRT.

+ +
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/tutorials/serving_torch_tensorrt_with_triton.html b/docs/v2.2.0/tutorials/serving_torch_tensorrt_with_triton.html new file mode 100644 index 0000000000..13c05b2289 --- /dev/null +++ b/docs/v2.2.0/tutorials/serving_torch_tensorrt_with_triton.html @@ -0,0 +1,937 @@ + + + + + + + + + + + + + Serving a Torch-TensorRT model with Triton — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Serving a Torch-TensorRT model with Triton
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Serving a Torch-TensorRT model with Triton

+

Optimization and deployment go hand in hand in a discussion about Machine +Learning infrastructure. Once network level optimzation are done +to get the maximum performance, the next step would be to deploy it.

+

However, serving this optimized model comes with it’s own set of considerations +and challenges like: building an infrastructure to support concorrent model +executions, supporting clients over HTTP or gRPC and more.

+

The Triton Inference Server +solves the aforementioned and more. Let’s discuss step-by-step, the process of +optimizing a model with Torch-TensorRT, deploying it on Triton Inference +Server, and building a client to query the model.

+
+

Step 1: Optimize your model with Torch-TensorRT

+

Most Torch-TensorRT users will be familiar with this step. For the purpose of +this demonstration, we will be using a ResNet50 model from Torchhub.

+

Let’s first pull the NGC PyTorch Docker container. You may need to create +an account and get the API key from here. +Sign up and login with your key (follow the instructions +here after signing up).

+
# <xx.xx> is the yy:mm for the publishing tag for NVIDIA's Pytorch
+# container; eg. 22.04
+
+docker run -it --gpus all -v ${PWD}:/scratch_space nvcr.io/nvidia/pytorch:<xx.xx>-py3
+cd /scratch_space
+
+
+

Once inside the container, we can proceed to download a ResNet model from +Torchhub and optimize it with Torch-TensorRT.

+
import torch
+import torch_tensorrt
+torch.hub._validate_not_a_forked_repo=lambda a,b,c: True
+
+# load model
+model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True).eval().to("cuda")
+
+# Compile with Torch TensorRT;
+trt_model = torch_tensorrt.compile(model,
+    inputs= [torch_tensorrt.Input((1, 3, 224, 224))],
+    enabled_precisions= { torch.half} # Run with FP32
+)
+
+# Save the model
+torch.jit.save(trt_model, "model.pt")
+
+
+

After copying the model, exit the container. The next step in the process +is to set up a Triton Inference Server.

+
+
+

Step 2: Set Up Triton Inference Server

+

If you are new to the Triton Inference Server and want to learn more, we +highly recommend to checking our Github +Repository.

+

To use Triton, we need to make a model repository. A model repository, as the +name suggested, is a repository of the models the Inference server hosts. While +Triton can serve models from multiple repositories, in this example, we will +discuss the simplest possible form of the model repository.

+

The structure of this repository should look something like this:

+
model_repository
+|
++-- resnet50
+    |
+    +-- config.pbtxt
+    +-- 1
+        |
+        +-- model.pt
+
+
+

There are two files that Triton requires to serve the model: the model itself +and a model configuration file which is typically provided in config.pbtxt. +For the model we prepared in step 1, the following configuration can be used:

+
name: "resnet50"
+platform: "pytorch_libtorch"
+max_batch_size : 0
+input [
+  {
+    name: "input__0"
+    data_type: TYPE_FP32
+    dims: [ 3, 224, 224 ]
+    reshape { shape: [ 1, 3, 224, 224 ] }
+  }
+]
+output [
+  {
+    name: "output__0"
+    data_type: TYPE_FP32
+    dims: [ 1, 1000 ,1, 1]
+    reshape { shape: [ 1, 1000 ] }
+  }
+]
+
+
+

The config.pbtxt file is used to describe the exact model configuration +with details like the names and shapes of the input and output layer(s), +datatypes, scheduling and batching details and more. If you are new to Triton, +we highly encourage you to check out this section of our +documentation +for more details.

+

With the model repository setup, we can proceed to launch the Triton server +with the docker command below. Refer this page for the pull tag for the container.

+
# Make sure that the TensorRT version in the Triton container
+# and TensorRT version in the environment used to optimize the model
+# are the same.
+
+docker run --gpus all --rm -p 8000:8000 -p 8001:8001 -p 8002:8002 -v /full/path/to/the_model_repository/model_repository:/models nvcr.io/nvidia/tritonserver:<xx.yy>-py3 tritonserver --model-repository=/models
+
+
+

This should spin up a Triton Inference server. Next step, building a simple +http client to query the server.

+
+
+

Step 3: Building a Triton Client to Query the Server

+

Before proceeding, make sure to have a sample image on hand. If you don’t +have one, download an example image to test inference. In this section, we +will be going over a very basic client. For a variety of more fleshed out +examples, refer to the Triton Client Repository

+
wget  -O img1.jpg "https://www.hakaimagazine.com/wp-content/uploads/header-gulf-birds.jpg"
+
+
+

We then need to install dependencies for building a python client. These will +change from client to client. For a full list of all languages supported by Triton, +please refer to Triton’s client repository.

+
pip install torchvision
+pip install attrdict
+pip install nvidia-pyindex
+pip install tritonclient[all]
+
+
+

Let’s jump into the client. Firstly, we write a small preprocessing function to +resize and normalize the query image.

+
import numpy as np
+from torchvision import transforms
+from PIL import Image
+import tritonclient.http as httpclient
+from tritonclient.utils import triton_to_np_dtype
+
+# preprocessing function
+def rn50_preprocess(img_path="img1.jpg"):
+    img = Image.open(img_path)
+    preprocess = transforms.Compose([
+        transforms.Resize(256),
+        transforms.CenterCrop(224),
+        transforms.ToTensor(),
+        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
+    ])
+    return preprocess(img).numpy()
+
+transformed_img = rn50_preprocess()
+
+
+

Building a client requires three basic points. Firstly, we setup a connection +with the Triton Inference Server.

+
# Setting up client
+client = httpclient.InferenceServerClient(url="localhost:8000")
+
+
+

Secondly, we specify the names of the input and output layer(s) of our model.

+
inputs = httpclient.InferInput("input__0", transformed_img.shape, datatype="FP32")
+inputs.set_data_from_numpy(transformed_img, binary_data=True)
+
+outputs = httpclient.InferRequestedOutput("output__0", binary_data=True, class_count=1000)
+
+
+

Lastly, we send an inference request to the Triton Inference Server.

+
# Querying the server
+results = client.infer(model_name="resnet50", inputs=[inputs], outputs=[outputs])
+inference_output = results.as_numpy('output__0')
+print(inference_output[:5])
+
+
+

The output of the same should look like below:

+
[b'12.468750:90' b'11.523438:92' b'9.664062:14' b'8.429688:136'
+ b'8.234375:11']
+
+
+

The output format here is <confidence_score>:<classification_index>. +To learn how to map these to the label names and more, refer to Triton Inference Server’s +documentation.

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/user_guide/dynamic_shapes.html b/docs/v2.2.0/user_guide/dynamic_shapes.html new file mode 100644 index 0000000000..97e19e374c --- /dev/null +++ b/docs/v2.2.0/user_guide/dynamic_shapes.html @@ -0,0 +1,943 @@ + + + + + + + + + + + + + Dynamic shapes with Torch-TensorRT — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Dynamic shapes with Torch-TensorRT
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Dynamic shapes with Torch-TensorRT

+

By default, you can run a pytorch model with varied input shapes and the output shapes are determined eagerly. +However, Torch-TensorRT is an AOT compiler which requires some prior information about the input shapes to compile and optimize the model. +In the case of dynamic input shapes, we must provide the (min_shape, opt_shape, max_shape) arguments so that the model can be optimized for +these range of input shapes. An example usage of static and dynamic shapes is as follows.

+

NOTE: The following code uses Dynamo Frontend. Incase of Torchscript Frontend, please swap out ir=dynamo with ir=ts and the behavior is exactly the same.

+
import torch
+import torch_tensorrt
+
+model = MyModel().eval().cuda()
+# Compile with static shapes
+inputs = torch_tensorrt.Input(shape=[1, 3, 224, 224], dtype=torch.float32)
+# or compile with dynamic shapes
+inputs = torch_tensorrt.Input(min_shape=[1, 3, 224, 224],
+                              opt_shape=[4, 3, 224, 224],
+                              max_shape=[8, 3, 224, 224],
+                              dtype=torch.float32)
+trt_gm = torch_tensorrt.compile(model, ir="dynamo", inputs)
+
+
+
+

Under the hood

+

There are two phases of compilation when we use torch_tensorrt.compile API with ir=dynamo (default).

+
    +
  • aten_tracer.trace (which uses torch.export to trace the graph with the given inputs)

  • +
+

In the tracing phase, we use torch.export along with the constraints. In the case of +dynamic shaped inputs, the range can be provided to the tracing via constraints. Please +refer to this docstring +for detailed information on how to set constraints. In short, we create new inputs for +torch.export tracing and provide constraints on the min and max values(provided by the user), a particular dimension can take. +Please take a look at aten_tracer.py file to understand how this works under the hood.

+
    +
  • dynamo.compile (which compiles a torch.fx.GraphModule object using TensorRT)

  • +
+

In the conversion to TensorRT, we use the user provided dynamic shape inputs. +We perform shape analysis using dummy inputs (across min, opt and max shapes) and store the +intermediate output shapes which can be used in case the graph has a mix of Pytorch +and TensorRT submodules.

+
+
+

Custom Constraints

+

Given an input x = torch_tensorrt.Input(min_shape, opt_shape, max_shape, dtype), +Torch-TensorRT automatically sets the constraints during torch.export tracing as follows

+
for dim in constraint_dims:
+    if min_shape[dim] > 1:
+        constraints.append(min_shape[dim] <= dynamic_dim(trace_input, dim))
+    if max_shape[dim] > 1:
+        constraints.append(dynamic_dim(trace_input, dim) <= max_shape[dim])
+
+
+

Sometimes, we might need to set additional constraints and Torchdynamo errors out if we don’t specify them. +For example, in the case of BERT model compilation, there are two inputs and a constraint has to be set involving the sequence length size of these two inputs.

+
constraints.append(dynamic_dim(trace_inputs[0], 0) == dynamic_dim(trace_inputs[1], 0))
+
+
+

If you have to provide any custom constraints to your model, the overall workflow for model compilation using ir=dynamo would involve a few steps.

+
import torch
+import torch_tensorrt
+from torch_tensorrt.dynamo.lowering import apply_lowering_passes, get_decompositions
+# Assume the model has two inputs
+model = MyModel()
+torch_input_1 = torch.randn((1, 14), dtype=torch.int32).cuda()
+torch_input_2 = torch.randn((1, 14), dtype=torch.int32).cuda()
+
+dynamic_inputs = [torch_tensorrt.Input(min_shape=[1, 14],
+                    opt_shape=[4, 14],
+                    max_shape=[8, 14],
+                    dtype=torch.int32),
+                  torch_tensorrt.Input(min_shape=[1, 14],
+                    opt_shape=[4, 14],
+                    max_shape=[8, 14],
+                    dtype=torch.int32)]
+
+# Export the model with additional constraints
+constraints = []
+# The following constraints are automatically added by Torch-TensorRT in the
+# general case when you call torch_tensorrt.compile directly on MyModel()
+constraints.append(dynamic_dim(torch_input_1, 0) < 8)
+constraints.append(dynamic_dim(torch_input_2, 0) < 8)
+# This is an additional constraint as instructed by Torchdynamo
+constraints.append(dynamic_dim(torch_input_1, 0) == dynamic_dim(torch_input_2, 0))
+with unittest.mock.patch(
+    "torch._export.DECOMP_TABLE", get_decompositions(experimental_decompositions)
+):
+    graph_module = export(
+        model, (torch_input_1, torch_input_2), constraints=constraints
+    ).module()
+
+# Use the dynamo.compile API
+trt_mod = torch_tensorrt.dynamo.compile(graph_module, inputs=dynamic_inputs, **compile_spec)
+
+
+
+
+

Limitations

+

If there are operations in the graph that use the dynamic dimension of the input, Pytorch +introduces torch.ops.aten.sym_size.int ops in the graph. Currently, we cannot handle these operators and +the compilation results in undefined behavior. We plan to add support for these operators and implement +robust support for shape tensors in the next release. Here is an example of the limitation described above

+
import torch
+import torch_tensorrt
+
+class MyModule(torch.nn.Module):
+    def __init__(self):
+        super().__init__()
+        self.avgpool = torch.nn.AdaptiveAvgPool2d((1, 1))
+
+    def forward(self, x):
+        x = self.avgpool(x)
+        out = torch.flatten(x, 1)
+        return out
+
+model = MyModel().eval().cuda()
+# Compile with dynamic shapes
+inputs = torch_tensorrt.Input(min_shape=(1, 512, 1, 1),
+                     opt_shape=(4, 512, 1, 1),
+                     max_shape=(8, 512, 1, 1),
+                     dtype=torch.float32)
+trt_gm = torch_tensorrt.compile(model, ir="dynamo", inputs)
+
+
+

The traced graph of MyModule() looks as follows

+
Post export graph: graph():
+%arg0_1 : [num_users=2] = placeholder[target=arg0_1]
+%mean : [num_users=1] = call_function[target=torch.ops.aten.mean.dim](args = (%arg0_1, [-1, -2], True), kwargs = {})
+%sym_size : [num_users=1] = call_function[target=torch.ops.aten.sym_size.int](args = (%arg0_1, 0), kwargs = {})
+%view : [num_users=1] = call_function[target=torch.ops.aten.view.default](args = (%mean, [%sym_size, 512]), kwargs = {})
+return (view,)
+
+
+

Here the %sym_size node captures the dynamic batch and uses it in the aten.view layer. This requires shape tensors support +which would be a part of our next release.

+
+
+

Workaround (BERT static compilation example)

+

In the case where you encounter the issues mentioned in the Limitations section, +you can compile the model (static mode) with max input size that can be provided. In the cases of smaller inputs, +we can pad them accordingly. This is only a workaround until we address the limitations.

+
import torch
+import torch_tensorrt
+from transformers.utils.fx import symbolic_trace as transformers_trace
+
+model = BertModel.from_pretrained("bert-base-uncased").cuda().eval()
+
+# Input sequence length is 20.
+input1 = torch.randint(0, 5, (1, 20), dtype=torch.int32).to("cuda")
+input2 = torch.randint(0, 5, (1, 20), dtype=torch.int32).to("cuda")
+
+model = transformers_trace(model, input_names=["input_ids", "attention_mask"]).eval().cuda()
+trt_mod = torch_tensorrt.compile(model, inputs=[input1, input2], **compile_spec)
+model_outputs = model(input, input2)
+
+# If you have a sequence of length 14, pad 6 zero tokens and run inference
+# or recompile for sequence length of 14.
+input1 = torch.randint(0, 5, (1, 14), dtype=torch.int32).to("cuda")
+input2 = torch.randint(0, 5, (1, 14), dtype=torch.int32).to("cuda")
+trt_mod = torch_tensorrt.compile(model, inputs=[input1, input2], **compile_spec)
+model_outputs = model(input, input2)
+
+
+
+
+

Dynamic shapes with ir=torch_compile

+

torch_tensorrt.compile(model, inputs, ir="torch_compile") returns a torch.compile boxed function with the backend +configured to Tensorrt. In the case of ir=torch_compile, when the input size changes, Dynamo will trigger a recompilation +of the TensorRT engine automatically giving dynamic shape behavior similar to native PyTorch eager however with the cost of rebuilding +TRT engine. This limitation will be addressed in future versions of Torch-TensorRT.

+
import torch
+import torch_tensorrt
+
+model = MyModel().eval().cuda()
+inputs = torch.randn((1, 3, 224, 224), dtype=float32)
+trt_gm = torch_tensorrt.compile(model, ir="torch_compile", inputs)
+# Compilation happens when you call the model
+trt_gm(inputs)
+
+# Recompilation happens with modified batch size
+inputs_bs2 = torch.randn((2, 3, 224, 224), dtype=torch.float32)
+trt_gm = torch_tensorrt.compile(model, ir="torch_compile", inputs_bs2)
+
+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/user_guide/ptq.html b/docs/v2.2.0/user_guide/ptq.html new file mode 100644 index 0000000000..6c37ece072 --- /dev/null +++ b/docs/v2.2.0/user_guide/ptq.html @@ -0,0 +1,932 @@ + + + + + + + + + + + + + Post Training Quantization (PTQ) — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Post Training Quantization (PTQ)
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Post Training Quantization (PTQ)

+

Post Training Quantization (PTQ) is a technique to reduce the required computational resources for inference +while still preserving the accuracy of your model by mapping the traditional FP32 activation space to a reduced +INT8 space. TensorRT uses a calibration step which executes your model with sample data from the target domain +and track the activations in FP32 to calibrate a mapping to INT8 that minimizes the information loss between +FP32 inference and INT8 inference.

+

Users writing TensorRT applications are required to setup a calibrator class which will provide sample data to +the TensorRT calibrator. With Torch-TensorRT we look to leverage existing infrastructure in PyTorch to make implementing +calibrators easier.

+

LibTorch provides a DataLoader and Dataset API which steamlines preprocessing and batching input data. +These APIs are exposed via both C++ and Python interface which makes it easier for the end user. +For C++ interface, we use torch::Dataset and torch::data::make_data_loader objects to construct and perform pre-processing on datasets. +The equivalent functionality in python interface uses torch.utils.data.Dataset and torch.utils.data.DataLoader. +This section of the PyTorch documentation has more information https://pytorch.org/tutorials/advanced/cpp_frontend.html#loading-data and https://pytorch.org/tutorials/recipes/recipes/loading_data_recipe.html. +Torch-TensorRT uses Dataloaders as the base of a generic calibrator implementation. So you will be able to reuse or quickly +implement a torch::Dataset for your target domain, place it in a DataLoader and create a INT8 Calibrator +which you can provide to Torch-TensorRT to run INT8 Calibration during compliation of your module.

+
+

How to create your own PTQ application in C++

+

Here is an example interface of a torch::Dataset class for CIFAR10:

+
 1//cpp/ptq/datasets/cifar10.h
+ 2#pragma once
+ 3
+ 4#include "torch/data/datasets/base.h"
+ 5#include "torch/data/example.h"
+ 6#include "torch/types.h"
+ 7
+ 8#include <cstddef>
+ 9#include <string>
+10
+11namespace datasets {
+12// The CIFAR10 Dataset
+13class CIFAR10 : public torch::data::datasets::Dataset<CIFAR10> {
+14public:
+15    // The mode in which the dataset is loaded
+16    enum class Mode { kTrain, kTest };
+17
+18    // Loads CIFAR10 from un-tarred file
+19    // Dataset can be found https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz
+20    // Root path should be the directory that contains the content of tarball
+21    explicit CIFAR10(const std::string& root, Mode mode = Mode::kTrain);
+22
+23    // Returns the pair at index in the dataset
+24    torch::data::Example<> get(size_t index) override;
+25
+26    // The size of the dataset
+27    c10::optional<size_t> size() const override;
+28
+29    // The mode the dataset is in
+30    bool is_train() const noexcept;
+31
+32    // Returns all images stacked into a single tensor
+33    const torch::Tensor& images() const;
+34
+35    // Returns all targets stacked into a single tensor
+36    const torch::Tensor& targets() const;
+37
+38    // Trims the dataset to the first n pairs
+39    CIFAR10&& use_subset(int64_t new_size);
+40
+41
+42private:
+43    Mode mode_;
+44    torch::Tensor images_, targets_;
+45};
+46} // namespace datasets
+
+
+

This class’s implementation reads from the binary distribution of the CIFAR10 dataset and builds two tensors which hold the images and labels.

+

We use a subset of the dataset to use for calibration, since we don’t need the the full dataset for effective calibration and calibration does +some take time, then define the preprocessing to apply to the images in the dataset and create a DataLoader from the dataset which will batch the data:

+
auto calibration_dataset = datasets::CIFAR10(data_dir, datasets::CIFAR10::Mode::kTest)
+                                    .use_subset(320)
+                                    .map(torch::data::transforms::Normalize<>({0.4914, 0.4822, 0.4465},
+                                                                            {0.2023, 0.1994, 0.2010}))
+                                    .map(torch::data::transforms::Stack<>());
+auto calibration_dataloader = torch::data::make_data_loader(std::move(calibration_dataset),
+                                                            torch::data::DataLoaderOptions().batch_size(32)
+                                                                                            .workers(2));
+
+
+

Next we create a calibrator from the calibration_dataloader using the calibrator factory (found in torch_tensorrt/ptq.h):

+
#include "torch_tensorrt/ptq.h"
+...
+
+auto calibrator = torch_tensorrt::ptq::make_int8_calibrator(std::move(calibration_dataloader), calibration_cache_file, true);
+
+
+

Here we also define a location to write a calibration cache file to which we can use to reuse the calibration data without needing the dataset and whether or not +we should use the cache file if it exists. There also exists a torch_tensorrt::ptq::make_int8_cache_calibrator factory which creates a calibrator that uses the cache +only for cases where you may do engine building on a machine that has limited storage (i.e. no space for a full dataset) or to have a simpiler deployment application.

+

The calibrator factories create a calibrator that inherits from a nvinfer1::IInt8Calibrator virtual class (nvinfer1::IInt8EntropyCalibrator2 by default) which +defines the calibration algorithm used when calibrating. You can explicitly make the selection of calibration algorithm like this:

+
// MinMax Calibrator is geared more towards NLP tasks
+auto calibrator = torch_tensorrt::ptq::make_int8_calibrator<nvinfer1::IInt8MinMaxCalibrator>(std::move(calibration_dataloader), calibration_cache_file, true);
+
+
+

Then all thats required to setup the module for INT8 calibration is to set the following compile settings in the torch_tensorrt::CompileSpec struct and compiling the module:

+
std::vector<std::vector<int64_t>> input_shape = {{32, 3, 32, 32}};
+/// Configure settings for compilation
+auto compile_spec = torch_tensorrt::CompileSpec({input_shape});
+/// Set operating precision to INT8
+compile_spec.enabled_precisions.insert(torch::kF16);
+compile_spec.enabled_precisions.insert(torch::kI8);
+/// Use the TensorRT Entropy Calibrator
+compile_spec.ptq_calibrator = calibrator;
+
+auto trt_mod = torch_tensorrt::CompileGraph(mod, compile_spec);
+
+
+

If you have an existing Calibrator implementation for TensorRT you may directly set the ptq_calibrator field with a pointer to your calibrator and it will work as well. +From here not much changes in terms of how to execution works. You are still able to fully use LibTorch as the sole interface for inference. Data should remain +in FP32 precision when it’s passed into trt_mod.forward. There exists an example application in the Torch-TensorRT demo that takes you from training a VGG16 network on +CIFAR10 to deploying in INT8 with Torch-TensorRT here: https://github.com/pytorch/TensorRT/tree/master/cpp/ptq

+
+
+

How to create your own PTQ application in Python

+

Torch-TensorRT Python API provides an easy and convenient way to use pytorch dataloaders with TensorRT calibrators. DataLoaderCalibrator class can be used to create +a TensorRT calibrator by providing desired configuration. The following code demonstrates an example on how to use it

+
testing_dataset = torchvision.datasets.CIFAR10(
+    root="./data",
+    train=False,
+    download=True,
+    transform=transforms.Compose(
+        [
+            transforms.ToTensor(),
+            transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
+        ]
+    ),
+)
+
+testing_dataloader = torch.utils.data.DataLoader(
+    testing_dataset, batch_size=1, shuffle=False, num_workers=1
+)
+calibrator = torch_tensorrt.ptq.DataLoaderCalibrator(
+    testing_dataloader,
+    cache_file="./calibration.cache",
+    use_cache=False,
+    algo_type=torch_tensorrt.ptq.CalibrationAlgo.ENTROPY_CALIBRATION_2,
+    device=torch.device("cuda:0"),
+)
+
+trt_mod = torch_tensorrt.compile(model, inputs=[torch_tensorrt.Input((1, 3, 32, 32))],
+                                    enabled_precisions={torch.float, torch.half, torch.int8},
+                                    calibrator=calibrator,
+                                    device={
+                                         "device_type": torch_tensorrt.DeviceType.GPU,
+                                         "gpu_id": 0,
+                                         "dla_core": 0,
+                                         "allow_gpu_fallback": False,
+                                         "disable_tf32": False
+                                     })
+
+
+

In the cases where there is a pre-existing calibration cache file that users want to use, CacheCalibrator can be used without any dataloaders. The following example demonstrates how +to use CacheCalibrator to use in INT8 mode.

+
calibrator = torch_tensorrt.ptq.CacheCalibrator("./calibration.cache")
+
+trt_mod = torch_tensorrt.compile(model, inputs=[torch_tensorrt.Input([1, 3, 32, 32])],
+                                      enabled_precisions={torch.float, torch.half, torch.int8},
+                                      calibrator=calibrator)
+
+
+

If you already have an existing calibrator class (implemented directly using TensorRT API), you can directly set the calibrator field to your class which can be very convenient. +For a demo on how PTQ can be performed on a VGG network using Torch-TensorRT API, you can refer to https://github.com/pytorch/TensorRT/blob/master/tests/py/test_ptq_dataloader_calibrator.py +and https://github.com/pytorch/TensorRT/blob/master/tests/py/test_ptq_trt_calibrator.py

+
+

Citations

+

Krizhevsky, A., & Hinton, G. (2009). Learning multiple layers of features from tiny images.

+

Simonyan, K., & Zisserman, A. (2014). Very deep convolutional networks for large-scale image recognition. arXiv preprint arXiv:1409.1556.

+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/user_guide/runtime.html b/docs/v2.2.0/user_guide/runtime.html new file mode 100644 index 0000000000..759b91368c --- /dev/null +++ b/docs/v2.2.0/user_guide/runtime.html @@ -0,0 +1,820 @@ + + + + + + + + + + + + + Deploying Torch-TensorRT Programs — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Deploying Torch-TensorRT Programs
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Deploying Torch-TensorRT Programs

+

After compiling and saving Torch-TensorRT programs there is no longer a strict dependency on the full +Torch-TensorRT library. All that is required to run a compiled program is the runtime. There are therfore a couple +options to deploy your programs other than shipping the full Torch-TensorRT compiler with your applications.

+
+

Torch-TensorRT package / libtorchtrt.so

+

Once a program is compiled, you run it using the standard PyTorch APIs. All that is required is that the package +must be imported in python or linked in C++.

+
+
+

Runtime Library

+

Distributed with the C++ distribution is libtorchtrt_runtime.so. This library only contains the components +necessary to run Torch-TensorRT programs. Instead of linking libtorchtrt.so or importing torch_tensorrt you can +link libtorchtrt_runtime.so in your deployment programs or use DL_OPEN or LD_PRELOAD. For python +you can load the runtime with torch.ops.load_library("libtorchtrt_runtime.so"). You can then continue to use +programs just as you would otherwise via PyTorch API.

+
+

Note

+

If you are using the standard distribution of PyTorch in Python on x86, likely you will need the pre-cxx11-abi variant of libtorchtrt_runtime.so, check Installation documentation for more details.

+
+
+

Note

+

If you are linking libtorchtrt_runtime.so, likely using the following flags will help -Wl,--no-as-needed -ltorchtrt -Wl,--as-needed as theres no direct symbol dependency to anything in the Torch-TensorRT runtime for most Torch-TensorRT runtime applications

+
+

An example of how to use libtorchtrt_runtime.so can be found here: https://github.com/pytorch/TensorRT/tree/master/examples/torchtrt_runtime_example

+
+
+

Plugin Library

+

In the case you use Torch-TensorRT as a converter to a TensorRT engine and your engine uses plugins provided by Torch-TensorRT, Torch-TensorRT +ships the library libtorchtrt_plugins.so which contains the implementation of the TensorRT plugins used by Torch-TensorRT during +compilation. This library can be DL_OPEN or LD_PRELOAD similar to other TensorRT plugin libraries.

+
+
+

Multi Device Safe Mode

+

Multi-device safe mode is a setting in Torch-TensorRT which allows the user to determine whether +the runtime checks for device consistency prior to every inference call.

+

There is a non-negligible, fixed cost per-inference call when multi-device safe mode is enabled, which is why +it is now disabled by default. It can be controlled via the following convenience function which +doubles as a context manager.

+
# Enables Multi Device Safe Mode
+torch_tensorrt.runtime.set_multi_device_safe_mode(True)
+
+# Disables Multi Device Safe Mode [Default Behavior]
+torch_tensorrt.runtime.set_multi_device_safe_mode(False)
+
+# Enables Multi Device Safe Mode, then resets the safe mode to its prior setting
+with torch_tensorrt.runtime.set_multi_device_safe_mode(True):
+    ...
+
+
+

TensorRT requires that each engine be associated with the CUDA context in the active thread from which it is invoked. +Therefore, if the device were to change in the active thread, which may be the case when invoking +engines on multiple GPUs from the same Python process, safe mode will cause Torch-TensorRT to display +an alert and switch GPUs accordingly. If safe mode were not enabled, there could be a mismatch in the engine +device and CUDA context device, which could lead the program to crash.

+

One technique for managing multiple TRT engines on different GPUs while not sacrificing performance for +multi-device safe mode is to use Python threads. Each thread is responsible for all of the TRT engines +on a single GPU, and the default CUDA device on each thread corresponds to the GPU for which it is +responsible (can be set via torch.cuda.set_device(...)). In this way, multiple threads can be used in the same +Python script without needing to switch CUDA contexts and incur performance overhead.

+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/user_guide/saving_models.html b/docs/v2.2.0/user_guide/saving_models.html new file mode 100644 index 0000000000..700c774cb1 --- /dev/null +++ b/docs/v2.2.0/user_guide/saving_models.html @@ -0,0 +1,844 @@ + + + + + + + + + + + + + Saving models compiled with Torch-TensorRT — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ +
    + +
  • + + + Docs + + > +
  • + + +
  • Saving models compiled with Torch-TensorRT
  • + + +
  • + + + + + +
  • + +
+ + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

Saving models compiled with Torch-TensorRT

+

Saving models compiled with Torch-TensorRT varies slightly with the ir that has been used for compilation.

+
+

Dynamo IR

+

The output type of ir=dynamo compilation of Torch-TensorRT is torch.export.ExportedProgram object by default. +In addition, we provide a new parameter output_format in the CompilationSetting object provided before compilation. +The output_format can take the following options

+
    +
  • exported_program (or) ep : This is the default. Returns an ExportedProgram

  • +
  • torchscript (or) ts : This returns a TorchScript module

  • +
  • graph_module (or) fx : This returns a torch.fx.GraphModule which can be traced into Torchscript to save to disk.

  • +
+
+

a) Torchscript

+

If you set the output_format=”torchscript”, this will return a ScriptModule which can be serialized via torch.jit.save

+
import torch
+import torch_tensorrt
+
+model = MyModel().eval().cuda()
+inputs = [torch.randn((1, 3, 224, 224)).cuda()]
+# trt_ts is a torch.jit.ScriptModule object
+trt_ts = torch_tensorrt.compile(model, ir="dynamo", inputs, output_format="torchscript")
+torch.jit.save(trt_ts, "trt_model.ts")
+
+# Later, you can load it and run inference
+model = torch.jit.load("trt_model.ts").cuda()
+model(*inputs)
+
+
+
+
+

b) ExportedProgram

+

torch.export.ExportedProgram, a new format introduced in Pytorch 2.X is the default return type of Torch-TensorRT compilation.

+
import torch
+import torch_tensorrt
+
+model = MyModel().eval().cuda()
+inputs = [torch.randn((1, 3, 224, 224)).cuda()]
+# trt_ep is a torch.export.ExportedProgram object
+trt_ep = torch_tensorrt.compile(model, ir="dynamo", inputs)
+torch.export.save(trt_ep, "trt_model.ep")
+
+# Later, you can load it and run inference
+model = torch.export.load("trt_model.ep")
+model(*inputs)
+
+
+
+
+

c) GraphModule

+

We can also return a torch.fx.GraphModule object as the output of Torch-TensorRT compilation by setting output_format=”graph_module”. +Internally, partitioning, lowering, conversion phases operate using GraphModule objects. These can be either traced into a Torchscript modules or +exported into ExportedProgram objects

+
import torch
+import torch_tensorrt
+
+model = MyModel().eval().cuda()
+inputs = [torch.randn((1, 3, 224, 224)).cuda()]
+# trt_gm is a torch.fx.GraphModule object
+trt_gm = torch_tensorrt.compile(model, ir="dynamo", inputs, output_format="graph_module")
+
+
+
+
+
+

Torchscript IR

+

In Torch-TensorRT 1.X versions, the primary way to compile and run inference with Torch-TensorRT is using Torchscript IR. +For ir=ts, this behavior stays the same in 2.X versions as well.

+
import torch
+import torch_tensorrt
+
+model = MyModel().eval().cuda()
+inputs = [torch.randn((1, 3, 224, 224)).cuda()]
+trt_ts = torch_tensorrt.compile(model, ir="ts", inputs) # Output is a ScriptModule object
+torch.jit.save(trt_ts, "trt_model.ts")
+
+# Later, you can load it and run inference
+model = torch.jit.load("trt_model.ts").cuda()
+model(*inputs)
+
+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/docs/v2.2.0/user_guide/using_dla.html b/docs/v2.2.0/user_guide/using_dla.html new file mode 100644 index 0000000000..6c9c1f1159 --- /dev/null +++ b/docs/v2.2.0/user_guide/using_dla.html @@ -0,0 +1,788 @@ + + + + + + + + + + + + + DLA — Torch-TensorRT v2.2.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+
+ +
+ Shortcuts +
+
+ +
+
+ + + + + + +
+ +
+
+ +
+

DLA

+

DLA NVIDIA Deep Learning Accelerator is a fixed-function accelerator engine targeted for deep learning operations. DLA is designed to do full hardware acceleration of convolutional neural networks. DLA supports various layers such as convolution, deconvolution, fully-connected, activation, pooling, batch normalization, etc. torch_tensorrt supports compilation of TorchScript Module and deployment pipeline on the DLA hardware available on NVIDIA embedded platforms.

+

NOTE: DLA supports fp16 and int8 precision only.

+

Using DLA with torchtrtc

+
torchtrtc [input_file_path] [output_file_path] [input_shapes...] -p f16 -d dla {OPTIONS}
+
+
+

Using DLA in a C++ application

+
std::vector<std::vector<int64_t>> input_shape = {{32, 3, 32, 32}};
+auto compile_spec = torch_tensorrt::CompileSpec({input_shape});
+
+# Set a precision. DLA supports fp16 or int8 only
+compile_spec.enabled_precisions = {torch::kF16};
+compile_spec.device.device_type = torch_tensorrt::CompileSpec::DeviceType::kDLA;
+
+# Make sure the gpu id is set to Xavier id for DLA
+compile_spec.device.gpu_id = 0;
+
+# Set the DLA core id
+compile_spec.device.dla_core = 1;
+
+# If a layer fails to run on DLA it will fallback to GPU
+compile_spec.device.allow_gpu_fallback = true;
+
+
+

Using DLA in a python application

+
compile_spec = {
+    "inputs": [torch_tensorrt.Input(self.input.shape)],
+    "device": torch_tensorrt.Device("dla:0", allow_gpu_fallback=True),
+    "enalbed_precisions": {torch.half},
+}
+
+trt_mod = torch_tensorrt.compile(self.scripted_model, compile_spec)
+
+
+
+ + +
+ +
+ + +
+
+ +
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+

Docs

+

Access comprehensive developer documentation for PyTorch

+ View Docs +
+ +
+

Tutorials

+

Get in-depth tutorials for beginners and advanced developers

+ View Tutorials +
+ +
+

Resources

+

Find development resources and get your questions answered

+ View Resources +
+
+
+
+ + + + + + + + + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/py/ci/Dockerfile.ci b/py/ci/Dockerfile.ci index 96f2b90200..b4692d394e 100644 --- a/py/ci/Dockerfile.ci +++ b/py/ci/Dockerfile.ci @@ -3,8 +3,8 @@ ARG trt_version RUN echo -e "Installing with TensorRT ${trt_version}" -RUN yum install -y ninja-build tensorrt-${trt_version}.* - +RUN yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-rhel7.repo +RUN yum install -y ninja-build gettext tensorrt-${trt_version}.* RUN wget https://github.com/bazelbuild/bazelisk/releases/download/v1.17.0/bazelisk-linux-amd64 \ && mv bazelisk-linux-amd64 /usr/bin/bazel \ && chmod +x /usr/bin/bazel diff --git a/py/ci/soname_excludes.params b/py/ci/soname_excludes.params index a5eecb7c9a..477852c48a 100644 --- a/py/ci/soname_excludes.params +++ b/py/ci/soname_excludes.params @@ -19,6 +19,9 @@ --exclude libnvToolsExt-847d78f2.so --exclude libcudart-e409450e.so.11.0 --exclude libcudart-e409450e.so +--exclude libcudart-24af1308.so.12.1.55 +--exclude libcudart-24af1308.so.12.1 +--exclude libcudart-24af1308.so --exclude libgomp-a34b3233.so.1 --exclude libgomp-a34b3233.so --exclude libcudart.so.11 diff --git a/toolchains/ci_workspaces/WORKSPACE.x86_64.cu118.release.rhel b/toolchains/ci_workspaces/WORKSPACE.x86_64.cu118.release.rhel index 79c7575d2b..fd368f4dd4 100644 --- a/toolchains/ci_workspaces/WORKSPACE.x86_64.cu118.release.rhel +++ b/toolchains/ci_workspaces/WORKSPACE.x86_64.cu118.release.rhel @@ -58,17 +58,17 @@ new_local_repository( http_archive( name = "libtorch", build_file = "@//third_party/libtorch:BUILD", - sha256 = "174579a7ee2a506d063714160c5fc57da428f7935311ef511c8f19820eb14c86", + sha256 = "a2b0f51ff59ef2787a82c36bba67f7380236a6384dbbd2459c558989af27184f", strip_prefix = "libtorch", - urls = ["https://download.pytorch.org/libtorch/nightly/cu121/libtorch-cxx11-abi-shared-with-deps-2.1.0.dev20230731%2Bcu121.zip"], + urls = ["https://download.pytorch.org/libtorch/cu118/libtorch-cxx11-abi-shared-with-deps-2.2.0%2Bcu118.zip"], ) http_archive( name = "libtorch_pre_cxx11_abi", build_file = "@//third_party/libtorch:BUILD", - sha256 = "532217063c65354d5534211badadc9c370d889cb1c3fdb295c9b3d0f181bc0ba", + sha256 = "f9c887085207f9500357cae4324a53c3010b8890397db915d7dbefb9183c7964", strip_prefix = "libtorch", - urls = ["https://download.pytorch.org/libtorch/nightly/cu121/libtorch-shared-with-deps-2.1.0.dev20230731%2Bcu121.zip"], + urls = ["https://download.pytorch.org/libtorch/cu118/libtorch-shared-with-deps-2.2.0%2Bcu118.zip"], ) #################################################################################### diff --git a/toolchains/ci_workspaces/WORKSPACE.x86_64.cu121.release.rhel b/toolchains/ci_workspaces/WORKSPACE.x86_64.cu121.release.rhel index 2fc09e8219..045862c578 100644 --- a/toolchains/ci_workspaces/WORKSPACE.x86_64.cu121.release.rhel +++ b/toolchains/ci_workspaces/WORKSPACE.x86_64.cu121.release.rhel @@ -58,17 +58,17 @@ new_local_repository( http_archive( name = "libtorch", build_file = "@//third_party/libtorch:BUILD", - sha256 = "174579a7ee2a506d063714160c5fc57da428f7935311ef511c8f19820eb14c86", + sha256 = "1fcf1b4b841f5bb677d3bd4ee7ac72d2c4f630447cafc41067e8316de8dfe061", strip_prefix = "libtorch", - urls = ["https://download.pytorch.org/libtorch/nightly/cu121/libtorch-cxx11-abi-shared-with-deps-2.1.0.dev20230731%2Bcu121.zip"], + urls = ["https://download.pytorch.org/libtorch/cu121/libtorch-cxx11-abi-shared-with-deps-2.2.0%2Bcu121.zip"], ) http_archive( name = "libtorch_pre_cxx11_abi", build_file = "@//third_party/libtorch:BUILD", - sha256 = "532217063c65354d5534211badadc9c370d889cb1c3fdb295c9b3d0f181bc0ba", + sha256 = "0a1a034b1980199543ec5cbc8d42215f55b188ac188b3dac42d83aeb449922bb", strip_prefix = "libtorch", - urls = ["https://download.pytorch.org/libtorch/nightly/cu121/libtorch-shared-with-deps-2.1.0.dev20230731%2Bcu121.zip"], + urls = ["https://download.pytorch.org/libtorch/cu121/libtorch-shared-with-deps-2.2.0%2Bcu121.zip"], ) ####################################################################################