Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/view_cuda_dispatch.h +24 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/view_meta_dispatch.h +24 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/view_native.h +24 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/view_ops.h +39 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vsplit.h +35 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vsplit_compositeimplicitautograd_dispatch.h +24 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vsplit_native.h +22 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vsplit_ops.h +39 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vstack_native.h +22 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vstack_ops.h +39 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/where.h +59 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/xlogy_ops.h +105 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/xor.h +35 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/xor_compositeimplicitautograd_dispatch.h +26 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_cpu_dispatch.h +23 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_cuda_dispatch.h +23 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_meta_dispatch.h +23 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_native.h +28 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_ops.h +50 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros.h +131 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_compositeexplicitautograd_dispatch.h +34 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like.h +43 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like_compositeexplicitautograd_dispatch.h +26 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like_compositeimplicitautogradnestedtensor_dispatch.h +24 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like_native.h +22 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like_ops.h +39 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_native.h +25 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_ops.h +61 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/quantized/QTensorImpl.h +125 -0
- rtme/lib/python3.10/site-packages/torch/include/ATen/quantized/Quantizer.h +279 -0
- rtme/lib/python3.10/site-packages/torch/include/THC/THCAtomics.cuh +3 -0
- rtme/lib/python3.10/site-packages/torch/include/THC/THCDeviceUtils.cuh +3 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/Allocator.h +277 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/AutogradState.h +72 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/Backend.h +350 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/CPUAllocator.h +57 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/CompileTimeFunctionPointer.h +56 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/ConstantSymNodeImpl.h +79 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/CopyBytes.h +44 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/DefaultDtype.h +15 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/DefaultTensorOptions.h +44 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/Device.h +215 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/DeviceArray.h +24 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/DeviceGuard.h +195 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/DeviceType.h +117 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/DispatchKey.h +728 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/DispatchKeySet.h +928 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/DynamicCast.h +119 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/Event.h +124 -0
- rtme/lib/python3.10/site-packages/torch/include/c10/core/GeneratorImpl.h +107 -0
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/view_cuda_dispatch.h
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace cuda {
|
| 19 |
+
|
| 20 |
+
TORCH_API at::Tensor view(const at::Tensor & self, at::IntArrayRef size);
|
| 21 |
+
TORCH_API at::Tensor view_symint(const at::Tensor & self, c10::SymIntArrayRef size);
|
| 22 |
+
|
| 23 |
+
} // namespace cuda
|
| 24 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/view_meta_dispatch.h
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace meta {
|
| 19 |
+
|
| 20 |
+
TORCH_API at::Tensor view(const at::Tensor & self, at::IntArrayRef size);
|
| 21 |
+
TORCH_API at::Tensor view_symint(const at::Tensor & self, c10::SymIntArrayRef size);
|
| 22 |
+
|
| 23 |
+
} // namespace meta
|
| 24 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/view_native.h
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from NativeFunction.h
|
| 4 |
+
|
| 5 |
+
#include <c10/core/Scalar.h>
|
| 6 |
+
#include <c10/core/Storage.h>
|
| 7 |
+
#include <c10/core/TensorOptions.h>
|
| 8 |
+
#include <c10/util/Deprecated.h>
|
| 9 |
+
#include <c10/util/Optional.h>
|
| 10 |
+
#include <c10/core/QScheme.h>
|
| 11 |
+
#include <ATen/core/Reduction.h>
|
| 12 |
+
#include <ATen/core/Tensor.h>
|
| 13 |
+
#include <tuple>
|
| 14 |
+
#include <vector>
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
namespace at {
|
| 18 |
+
namespace native {
|
| 19 |
+
TORCH_API at::Tensor view(const at::Tensor & self, at::IntArrayRef size);
|
| 20 |
+
TORCH_API at::Tensor view_nested(const at::Tensor & self, at::IntArrayRef size);
|
| 21 |
+
TORCH_API at::Tensor mkldnn_view(const at::Tensor & self, at::IntArrayRef size);
|
| 22 |
+
TORCH_API at::Tensor view_dtype(const at::Tensor & self, at::ScalarType dtype);
|
| 23 |
+
} // namespace native
|
| 24 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/view_ops.h
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Operator.h
|
| 4 |
+
|
| 5 |
+
#include <tuple>
|
| 6 |
+
#include <vector>
|
| 7 |
+
|
| 8 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 9 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 10 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 11 |
+
#include <ATen/core/ATen_fwd.h>
|
| 12 |
+
|
| 13 |
+
namespace at {
|
| 14 |
+
namespace _ops {
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
struct TORCH_API view {
|
| 18 |
+
using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef);
|
| 19 |
+
using ptr_schema = schema*;
|
| 20 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 21 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::view")
|
| 22 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "")
|
| 23 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "view(Tensor(a) self, SymInt[] size) -> Tensor(a)")
|
| 24 |
+
static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef size);
|
| 25 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef size);
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
struct TORCH_API view_dtype {
|
| 29 |
+
using schema = at::Tensor (const at::Tensor &, at::ScalarType);
|
| 30 |
+
using ptr_schema = schema*;
|
| 31 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 32 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::view")
|
| 33 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "dtype")
|
| 34 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "view.dtype(Tensor(a) self, ScalarType dtype) -> Tensor(a)")
|
| 35 |
+
static at::Tensor call(const at::Tensor & self, at::ScalarType dtype);
|
| 36 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::ScalarType dtype);
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
}} // namespace at::_ops
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vsplit.h
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Function.h
|
| 4 |
+
|
| 5 |
+
#include <ATen/Context.h>
|
| 6 |
+
#include <ATen/DeviceGuard.h>
|
| 7 |
+
#include <ATen/TensorUtils.h>
|
| 8 |
+
#include <ATen/TracerMode.h>
|
| 9 |
+
#include <ATen/core/Generator.h>
|
| 10 |
+
#include <ATen/core/Reduction.h>
|
| 11 |
+
#include <ATen/core/Tensor.h>
|
| 12 |
+
#include <c10/core/Scalar.h>
|
| 13 |
+
#include <c10/core/Storage.h>
|
| 14 |
+
#include <c10/core/TensorOptions.h>
|
| 15 |
+
#include <c10/util/Deprecated.h>
|
| 16 |
+
#include <c10/util/Optional.h>
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
#include <ATen/ops/vsplit_ops.h>
|
| 21 |
+
|
| 22 |
+
namespace at {
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
// aten::vsplit.int(Tensor(a -> *) self, int sections) -> Tensor(a)[]
|
| 26 |
+
inline ::std::vector<at::Tensor> vsplit(const at::Tensor & self, int64_t sections) {
|
| 27 |
+
return at::_ops::vsplit_int::call(self, sections);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
// aten::vsplit.array(Tensor(a -> *) self, int[] indices) -> Tensor(a)[]
|
| 31 |
+
inline ::std::vector<at::Tensor> vsplit(const at::Tensor & self, at::IntArrayRef indices) {
|
| 32 |
+
return at::_ops::vsplit_array::call(self, indices);
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
}
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vsplit_compositeimplicitautograd_dispatch.h
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace compositeimplicitautograd {
|
| 19 |
+
|
| 20 |
+
TORCH_API ::std::vector<at::Tensor> vsplit(const at::Tensor & self, int64_t sections);
|
| 21 |
+
TORCH_API ::std::vector<at::Tensor> vsplit(const at::Tensor & self, at::IntArrayRef indices);
|
| 22 |
+
|
| 23 |
+
} // namespace compositeimplicitautograd
|
| 24 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vsplit_native.h
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from NativeFunction.h
|
| 4 |
+
|
| 5 |
+
#include <c10/core/Scalar.h>
|
| 6 |
+
#include <c10/core/Storage.h>
|
| 7 |
+
#include <c10/core/TensorOptions.h>
|
| 8 |
+
#include <c10/util/Deprecated.h>
|
| 9 |
+
#include <c10/util/Optional.h>
|
| 10 |
+
#include <c10/core/QScheme.h>
|
| 11 |
+
#include <ATen/core/Reduction.h>
|
| 12 |
+
#include <ATen/core/Tensor.h>
|
| 13 |
+
#include <tuple>
|
| 14 |
+
#include <vector>
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
namespace at {
|
| 18 |
+
namespace native {
|
| 19 |
+
TORCH_API ::std::vector<at::Tensor> vsplit(const at::Tensor & self, int64_t sections);
|
| 20 |
+
TORCH_API ::std::vector<at::Tensor> vsplit(const at::Tensor & self, at::IntArrayRef indices);
|
| 21 |
+
} // namespace native
|
| 22 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vsplit_ops.h
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Operator.h
|
| 4 |
+
|
| 5 |
+
#include <tuple>
|
| 6 |
+
#include <vector>
|
| 7 |
+
|
| 8 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 9 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 10 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 11 |
+
#include <ATen/core/ATen_fwd.h>
|
| 12 |
+
|
| 13 |
+
namespace at {
|
| 14 |
+
namespace _ops {
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
struct TORCH_API vsplit_int {
|
| 18 |
+
using schema = ::std::vector<at::Tensor> (const at::Tensor &, int64_t);
|
| 19 |
+
using ptr_schema = schema*;
|
| 20 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 21 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::vsplit")
|
| 22 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "int")
|
| 23 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "vsplit.int(Tensor(a -> *) self, int sections) -> Tensor(a)[]")
|
| 24 |
+
static ::std::vector<at::Tensor> call(const at::Tensor & self, int64_t sections);
|
| 25 |
+
static ::std::vector<at::Tensor> redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, int64_t sections);
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
struct TORCH_API vsplit_array {
|
| 29 |
+
using schema = ::std::vector<at::Tensor> (const at::Tensor &, at::IntArrayRef);
|
| 30 |
+
using ptr_schema = schema*;
|
| 31 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 32 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::vsplit")
|
| 33 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "array")
|
| 34 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "vsplit.array(Tensor(a -> *) self, int[] indices) -> Tensor(a)[]")
|
| 35 |
+
static ::std::vector<at::Tensor> call(const at::Tensor & self, at::IntArrayRef indices);
|
| 36 |
+
static ::std::vector<at::Tensor> redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::IntArrayRef indices);
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
}} // namespace at::_ops
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vstack_native.h
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from NativeFunction.h
|
| 4 |
+
|
| 5 |
+
#include <c10/core/Scalar.h>
|
| 6 |
+
#include <c10/core/Storage.h>
|
| 7 |
+
#include <c10/core/TensorOptions.h>
|
| 8 |
+
#include <c10/util/Deprecated.h>
|
| 9 |
+
#include <c10/util/Optional.h>
|
| 10 |
+
#include <c10/core/QScheme.h>
|
| 11 |
+
#include <ATen/core/Reduction.h>
|
| 12 |
+
#include <ATen/core/Tensor.h>
|
| 13 |
+
#include <tuple>
|
| 14 |
+
#include <vector>
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
namespace at {
|
| 18 |
+
namespace native {
|
| 19 |
+
TORCH_API at::Tensor vstack(at::TensorList tensors);
|
| 20 |
+
TORCH_API at::Tensor & vstack_out(at::TensorList tensors, at::Tensor & out);
|
| 21 |
+
} // namespace native
|
| 22 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/vstack_ops.h
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Operator.h
|
| 4 |
+
|
| 5 |
+
#include <tuple>
|
| 6 |
+
#include <vector>
|
| 7 |
+
|
| 8 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 9 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 10 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 11 |
+
#include <ATen/core/ATen_fwd.h>
|
| 12 |
+
|
| 13 |
+
namespace at {
|
| 14 |
+
namespace _ops {
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
struct TORCH_API vstack {
|
| 18 |
+
using schema = at::Tensor (at::TensorList);
|
| 19 |
+
using ptr_schema = schema*;
|
| 20 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 21 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::vstack")
|
| 22 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "")
|
| 23 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "vstack(Tensor[] tensors) -> Tensor")
|
| 24 |
+
static at::Tensor call(at::TensorList tensors);
|
| 25 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors);
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
struct TORCH_API vstack_out {
|
| 29 |
+
using schema = at::Tensor & (at::TensorList, at::Tensor &);
|
| 30 |
+
using ptr_schema = schema*;
|
| 31 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 32 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::vstack")
|
| 33 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "out")
|
| 34 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "vstack.out(Tensor[] tensors, *, Tensor(a!) out) -> Tensor(a!)")
|
| 35 |
+
static at::Tensor & call(at::TensorList tensors, at::Tensor & out);
|
| 36 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, at::Tensor & out);
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
}} // namespace at::_ops
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/where.h
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Function.h
|
| 4 |
+
|
| 5 |
+
#include <ATen/Context.h>
|
| 6 |
+
#include <ATen/DeviceGuard.h>
|
| 7 |
+
#include <ATen/TensorUtils.h>
|
| 8 |
+
#include <ATen/TracerMode.h>
|
| 9 |
+
#include <ATen/core/Generator.h>
|
| 10 |
+
#include <ATen/core/Reduction.h>
|
| 11 |
+
#include <ATen/core/Tensor.h>
|
| 12 |
+
#include <c10/core/Scalar.h>
|
| 13 |
+
#include <c10/core/Storage.h>
|
| 14 |
+
#include <c10/core/TensorOptions.h>
|
| 15 |
+
#include <c10/util/Deprecated.h>
|
| 16 |
+
#include <c10/util/Optional.h>
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
#include <ATen/ops/where_ops.h>
|
| 21 |
+
|
| 22 |
+
namespace at {
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
// aten::where.self(Tensor condition, Tensor self, Tensor other) -> Tensor
|
| 26 |
+
inline at::Tensor where(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other) {
|
| 27 |
+
return at::_ops::where_self::call(condition, self, other);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
// aten::where.self_out(Tensor condition, Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)
|
| 31 |
+
inline at::Tensor & where_out(at::Tensor & out, const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other) {
|
| 32 |
+
return at::_ops::where_self_out::call(condition, self, other, out);
|
| 33 |
+
}
|
| 34 |
+
// aten::where.self_out(Tensor condition, Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)
|
| 35 |
+
inline at::Tensor & where_outf(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other, at::Tensor & out) {
|
| 36 |
+
return at::_ops::where_self_out::call(condition, self, other, out);
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
// aten::where.ScalarSelf(Tensor condition, Scalar self, Tensor other) -> Tensor
|
| 40 |
+
inline at::Tensor where(const at::Tensor & condition, const at::Scalar & self, const at::Tensor & other) {
|
| 41 |
+
return at::_ops::where_ScalarSelf::call(condition, self, other);
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
// aten::where.ScalarOther(Tensor condition, Tensor self, Scalar other) -> Tensor
|
| 45 |
+
inline at::Tensor where(const at::Tensor & condition, const at::Tensor & self, const at::Scalar & other) {
|
| 46 |
+
return at::_ops::where_ScalarOther::call(condition, self, other);
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// aten::where.Scalar(Tensor condition, Scalar self, Scalar other) -> Tensor
|
| 50 |
+
inline at::Tensor where(const at::Tensor & condition, const at::Scalar & self, const at::Scalar & other) {
|
| 51 |
+
return at::_ops::where_Scalar::call(condition, self, other);
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
// aten::where(Tensor condition) -> Tensor[]
|
| 55 |
+
inline ::std::vector<at::Tensor> where(const at::Tensor & condition) {
|
| 56 |
+
return at::_ops::where::call(condition);
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
}
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/xlogy_ops.h
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Operator.h
|
| 4 |
+
|
| 5 |
+
#include <tuple>
|
| 6 |
+
#include <vector>
|
| 7 |
+
|
| 8 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 9 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 10 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 11 |
+
#include <ATen/core/ATen_fwd.h>
|
| 12 |
+
|
| 13 |
+
namespace at {
|
| 14 |
+
namespace _ops {
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
struct TORCH_API xlogy_Tensor {
|
| 18 |
+
using schema = at::Tensor (const at::Tensor &, const at::Tensor &);
|
| 19 |
+
using ptr_schema = schema*;
|
| 20 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 21 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::xlogy")
|
| 22 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "Tensor")
|
| 23 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "xlogy.Tensor(Tensor self, Tensor other) -> Tensor")
|
| 24 |
+
static at::Tensor call(const at::Tensor & self, const at::Tensor & other);
|
| 25 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Tensor & other);
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
struct TORCH_API xlogy_Scalar_Self {
|
| 29 |
+
using schema = at::Tensor (const at::Scalar &, const at::Tensor &);
|
| 30 |
+
using ptr_schema = schema*;
|
| 31 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 32 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::xlogy")
|
| 33 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "Scalar_Self")
|
| 34 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "xlogy.Scalar_Self(Scalar self, Tensor other) -> Tensor")
|
| 35 |
+
static at::Tensor call(const at::Scalar & self, const at::Tensor & other);
|
| 36 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Scalar & self, const at::Tensor & other);
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
struct TORCH_API xlogy_Scalar_Other {
|
| 40 |
+
using schema = at::Tensor (const at::Tensor &, const at::Scalar &);
|
| 41 |
+
using ptr_schema = schema*;
|
| 42 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 43 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::xlogy")
|
| 44 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "Scalar_Other")
|
| 45 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "xlogy.Scalar_Other(Tensor self, Scalar other) -> Tensor")
|
| 46 |
+
static at::Tensor call(const at::Tensor & self, const at::Scalar & other);
|
| 47 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Scalar & other);
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
struct TORCH_API xlogy__Tensor {
|
| 51 |
+
using schema = at::Tensor & (at::Tensor &, const at::Tensor &);
|
| 52 |
+
using ptr_schema = schema*;
|
| 53 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 54 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::xlogy_")
|
| 55 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "Tensor")
|
| 56 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "xlogy_.Tensor(Tensor(a!) self, Tensor other) -> Tensor(a!)")
|
| 57 |
+
static at::Tensor & call(at::Tensor & self, const at::Tensor & other);
|
| 58 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::Tensor & self, const at::Tensor & other);
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
struct TORCH_API xlogy__Scalar_Other {
|
| 62 |
+
using schema = at::Tensor & (at::Tensor &, const at::Scalar &);
|
| 63 |
+
using ptr_schema = schema*;
|
| 64 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 65 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::xlogy_")
|
| 66 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "Scalar_Other")
|
| 67 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "xlogy_.Scalar_Other(Tensor(a!) self, Scalar other) -> Tensor(a!)")
|
| 68 |
+
static at::Tensor & call(at::Tensor & self, const at::Scalar & other);
|
| 69 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::Tensor & self, const at::Scalar & other);
|
| 70 |
+
};
|
| 71 |
+
|
| 72 |
+
struct TORCH_API xlogy_OutTensor {
|
| 73 |
+
using schema = at::Tensor & (const at::Tensor &, const at::Tensor &, at::Tensor &);
|
| 74 |
+
using ptr_schema = schema*;
|
| 75 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 76 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::xlogy")
|
| 77 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "OutTensor")
|
| 78 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "xlogy.OutTensor(Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)")
|
| 79 |
+
static at::Tensor & call(const at::Tensor & self, const at::Tensor & other, at::Tensor & out);
|
| 80 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Tensor & other, at::Tensor & out);
|
| 81 |
+
};
|
| 82 |
+
|
| 83 |
+
struct TORCH_API xlogy_OutScalar_Self {
|
| 84 |
+
using schema = at::Tensor & (const at::Scalar &, const at::Tensor &, at::Tensor &);
|
| 85 |
+
using ptr_schema = schema*;
|
| 86 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 87 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::xlogy")
|
| 88 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "OutScalar_Self")
|
| 89 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "xlogy.OutScalar_Self(Scalar self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)")
|
| 90 |
+
static at::Tensor & call(const at::Scalar & self, const at::Tensor & other, at::Tensor & out);
|
| 91 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Scalar & self, const at::Tensor & other, at::Tensor & out);
|
| 92 |
+
};
|
| 93 |
+
|
| 94 |
+
struct TORCH_API xlogy_OutScalar_Other {
|
| 95 |
+
using schema = at::Tensor & (const at::Tensor &, const at::Scalar &, at::Tensor &);
|
| 96 |
+
using ptr_schema = schema*;
|
| 97 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 98 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::xlogy")
|
| 99 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "OutScalar_Other")
|
| 100 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "xlogy.OutScalar_Other(Tensor self, Scalar other, *, Tensor(a!) out) -> Tensor(a!)")
|
| 101 |
+
static at::Tensor & call(const at::Tensor & self, const at::Scalar & other, at::Tensor & out);
|
| 102 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Scalar & other, at::Tensor & out);
|
| 103 |
+
};
|
| 104 |
+
|
| 105 |
+
}} // namespace at::_ops
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/xor.h
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Function.h
|
| 4 |
+
|
| 5 |
+
#include <ATen/Context.h>
|
| 6 |
+
#include <ATen/DeviceGuard.h>
|
| 7 |
+
#include <ATen/TensorUtils.h>
|
| 8 |
+
#include <ATen/TracerMode.h>
|
| 9 |
+
#include <ATen/core/Generator.h>
|
| 10 |
+
#include <ATen/core/Reduction.h>
|
| 11 |
+
#include <ATen/core/Tensor.h>
|
| 12 |
+
#include <c10/core/Scalar.h>
|
| 13 |
+
#include <c10/core/Storage.h>
|
| 14 |
+
#include <c10/core/TensorOptions.h>
|
| 15 |
+
#include <c10/util/Deprecated.h>
|
| 16 |
+
#include <c10/util/Optional.h>
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
#include <ATen/ops/xor_ops.h>
|
| 21 |
+
|
| 22 |
+
namespace at {
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
// aten::__xor__.Scalar(Tensor self, Scalar other) -> Tensor
|
| 26 |
+
inline at::Tensor __xor__(const at::Tensor & self, const at::Scalar & other) {
|
| 27 |
+
return at::_ops::__xor___Scalar::call(self, other);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
// aten::__xor__.Tensor(Tensor self, Tensor other) -> Tensor
|
| 31 |
+
inline at::Tensor __xor__(const at::Tensor & self, const at::Tensor & other) {
|
| 32 |
+
return at::_ops::__xor___Tensor::call(self, other);
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
}
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/xor_compositeimplicitautograd_dispatch.h
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace compositeimplicitautograd {
|
| 19 |
+
|
| 20 |
+
TORCH_API at::Tensor __xor__(const at::Tensor & self, const at::Scalar & other);
|
| 21 |
+
TORCH_API at::Tensor & __ixor__(at::Tensor & self, const at::Scalar & other);
|
| 22 |
+
TORCH_API at::Tensor __xor__(const at::Tensor & self, const at::Tensor & other);
|
| 23 |
+
TORCH_API at::Tensor & __ixor__(at::Tensor & self, const at::Tensor & other);
|
| 24 |
+
|
| 25 |
+
} // namespace compositeimplicitautograd
|
| 26 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_cpu_dispatch.h
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace cpu {
|
| 19 |
+
|
| 20 |
+
TORCH_API at::Tensor & zero_(at::Tensor & self);
|
| 21 |
+
|
| 22 |
+
} // namespace cpu
|
| 23 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_cuda_dispatch.h
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace cuda {
|
| 19 |
+
|
| 20 |
+
TORCH_API at::Tensor & zero_(at::Tensor & self);
|
| 21 |
+
|
| 22 |
+
} // namespace cuda
|
| 23 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_meta_dispatch.h
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace meta {
|
| 19 |
+
|
| 20 |
+
TORCH_API at::Tensor & zero_(at::Tensor & self);
|
| 21 |
+
|
| 22 |
+
} // namespace meta
|
| 23 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_native.h
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from NativeFunction.h
|
| 4 |
+
|
| 5 |
+
#include <c10/core/Scalar.h>
|
| 6 |
+
#include <c10/core/Storage.h>
|
| 7 |
+
#include <c10/core/TensorOptions.h>
|
| 8 |
+
#include <c10/util/Deprecated.h>
|
| 9 |
+
#include <c10/util/Optional.h>
|
| 10 |
+
#include <c10/core/QScheme.h>
|
| 11 |
+
#include <ATen/core/Reduction.h>
|
| 12 |
+
#include <ATen/core/Tensor.h>
|
| 13 |
+
#include <tuple>
|
| 14 |
+
#include <vector>
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
namespace at {
|
| 18 |
+
namespace native {
|
| 19 |
+
TORCH_API at::Tensor zero(const at::Tensor & self);
|
| 20 |
+
TORCH_API at::Tensor & zero_out(const at::Tensor & self, at::Tensor & out);
|
| 21 |
+
TORCH_API at::Tensor & zero_(at::Tensor & self);
|
| 22 |
+
TORCH_API at::Tensor & zero_nested_(at::Tensor & self);
|
| 23 |
+
TORCH_API at::Tensor & zero_sparse_(at::Tensor & self);
|
| 24 |
+
TORCH_API at::Tensor & zero_sparse_csr_(at::Tensor & self);
|
| 25 |
+
TORCH_API at::Tensor & zero_meta_(at::Tensor & self);
|
| 26 |
+
TORCH_API at::Tensor & mkldnn_zero_(at::Tensor & self);
|
| 27 |
+
} // namespace native
|
| 28 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zero_ops.h
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Operator.h
|
| 4 |
+
|
| 5 |
+
#include <tuple>
|
| 6 |
+
#include <vector>
|
| 7 |
+
|
| 8 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 9 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 10 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 11 |
+
#include <ATen/core/ATen_fwd.h>
|
| 12 |
+
|
| 13 |
+
namespace at {
|
| 14 |
+
namespace _ops {
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
struct TORCH_API zero_ {
|
| 18 |
+
using schema = at::Tensor & (at::Tensor &);
|
| 19 |
+
using ptr_schema = schema*;
|
| 20 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 21 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::zero_")
|
| 22 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "")
|
| 23 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "zero_(Tensor(a!) self) -> Tensor(a!)")
|
| 24 |
+
static at::Tensor & call(at::Tensor & self);
|
| 25 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::Tensor & self);
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
struct TORCH_API zero_out {
|
| 29 |
+
using schema = at::Tensor & (const at::Tensor &, at::Tensor &);
|
| 30 |
+
using ptr_schema = schema*;
|
| 31 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 32 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::zero")
|
| 33 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "out")
|
| 34 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "zero.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!)")
|
| 35 |
+
static at::Tensor & call(const at::Tensor & self, at::Tensor & out);
|
| 36 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::Tensor & out);
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
struct TORCH_API zero {
|
| 40 |
+
using schema = at::Tensor (const at::Tensor &);
|
| 41 |
+
using ptr_schema = schema*;
|
| 42 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 43 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::zero")
|
| 44 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "")
|
| 45 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "zero(Tensor self) -> Tensor")
|
| 46 |
+
static at::Tensor call(const at::Tensor & self);
|
| 47 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self);
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
}} // namespace at::_ops
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros.h
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Function.h
|
| 4 |
+
|
| 5 |
+
#include <ATen/Context.h>
|
| 6 |
+
#include <ATen/DeviceGuard.h>
|
| 7 |
+
#include <ATen/TensorUtils.h>
|
| 8 |
+
#include <ATen/TracerMode.h>
|
| 9 |
+
#include <ATen/core/Generator.h>
|
| 10 |
+
#include <ATen/core/Reduction.h>
|
| 11 |
+
#include <ATen/core/Tensor.h>
|
| 12 |
+
#include <c10/core/Scalar.h>
|
| 13 |
+
#include <c10/core/Storage.h>
|
| 14 |
+
#include <c10/core/TensorOptions.h>
|
| 15 |
+
#include <c10/util/Deprecated.h>
|
| 16 |
+
#include <c10/util/Optional.h>
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
#include <ATen/ops/zeros_ops.h>
|
| 21 |
+
|
| 22 |
+
namespace at {
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
// aten::zeros.names(int[] size, *, Dimname[]? names, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor
|
| 26 |
+
inline at::Tensor zeros(at::IntArrayRef size, c10::optional<at::DimnameList> names, at::TensorOptions options={}) {
|
| 27 |
+
return at::_ops::zeros_names::call(size, names, optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt());
|
| 28 |
+
}
|
| 29 |
+
// aten::zeros.names(int[] size, *, Dimname[]? names, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor
|
| 30 |
+
inline at::Tensor zeros(at::IntArrayRef size, c10::optional<at::DimnameList> names, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory) {
|
| 31 |
+
return at::_ops::zeros_names::call(size, names, dtype, layout, device, pin_memory);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// aten::zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor
|
| 35 |
+
inline at::Tensor zeros(at::IntArrayRef size, at::TensorOptions options={}) {
|
| 36 |
+
return at::_ops::zeros::call(c10::fromIntArrayRefSlow(size), optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt());
|
| 37 |
+
}
|
| 38 |
+
namespace symint {
|
| 39 |
+
template <typename T, typename = std::enable_if_t<std::is_same<T, int64_t>::value>>
|
| 40 |
+
at::Tensor zeros(at::IntArrayRef size, at::TensorOptions options={}) {
|
| 41 |
+
return at::_ops::zeros::call(c10::fromIntArrayRefSlow(size), optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt());
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
// aten::zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor
|
| 46 |
+
inline at::Tensor zeros(at::IntArrayRef size, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory) {
|
| 47 |
+
return at::_ops::zeros::call(c10::fromIntArrayRefSlow(size), dtype, layout, device, pin_memory);
|
| 48 |
+
}
|
| 49 |
+
namespace symint {
|
| 50 |
+
template <typename T, typename = std::enable_if_t<std::is_same<T, int64_t>::value>>
|
| 51 |
+
at::Tensor zeros(at::IntArrayRef size, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory) {
|
| 52 |
+
return at::_ops::zeros::call(c10::fromIntArrayRefSlow(size), dtype, layout, device, pin_memory);
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
// aten::zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor
|
| 57 |
+
inline at::Tensor zeros_symint(c10::SymIntArrayRef size, at::TensorOptions options={}) {
|
| 58 |
+
return at::_ops::zeros::call(size, optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt());
|
| 59 |
+
}
|
| 60 |
+
namespace symint {
|
| 61 |
+
template <typename T, typename = std::enable_if_t<std::is_same<T, c10::SymInt>::value>>
|
| 62 |
+
at::Tensor zeros(c10::SymIntArrayRef size, at::TensorOptions options={}) {
|
| 63 |
+
return at::_ops::zeros::call(size, optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt());
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
// aten::zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor
|
| 68 |
+
inline at::Tensor zeros_symint(c10::SymIntArrayRef size, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory) {
|
| 69 |
+
return at::_ops::zeros::call(size, dtype, layout, device, pin_memory);
|
| 70 |
+
}
|
| 71 |
+
namespace symint {
|
| 72 |
+
template <typename T, typename = std::enable_if_t<std::is_same<T, c10::SymInt>::value>>
|
| 73 |
+
at::Tensor zeros(c10::SymIntArrayRef size, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory) {
|
| 74 |
+
return at::_ops::zeros::call(size, dtype, layout, device, pin_memory);
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
// aten::zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!)
|
| 79 |
+
inline at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size) {
|
| 80 |
+
return at::_ops::zeros_out::call(c10::fromIntArrayRefSlow(size), out);
|
| 81 |
+
}
|
| 82 |
+
namespace symint {
|
| 83 |
+
template <typename T, typename = std::enable_if_t<std::is_same<T, int64_t>::value>>
|
| 84 |
+
at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size) {
|
| 85 |
+
return at::_ops::zeros_out::call(c10::fromIntArrayRefSlow(size), out);
|
| 86 |
+
}
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
// aten::zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!)
|
| 90 |
+
inline at::Tensor & zeros_outf(at::IntArrayRef size, at::Tensor & out) {
|
| 91 |
+
return at::_ops::zeros_out::call(c10::fromIntArrayRefSlow(size), out);
|
| 92 |
+
}
|
| 93 |
+
namespace symint {
|
| 94 |
+
template <typename T, typename = std::enable_if_t<std::is_same<T, int64_t>::value>>
|
| 95 |
+
at::Tensor & zeros_outf(at::IntArrayRef size, at::Tensor & out) {
|
| 96 |
+
return at::_ops::zeros_out::call(c10::fromIntArrayRefSlow(size), out);
|
| 97 |
+
}
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
// aten::zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!)
|
| 101 |
+
inline at::Tensor & zeros_symint_out(at::Tensor & out, c10::SymIntArrayRef size) {
|
| 102 |
+
return at::_ops::zeros_out::call(size, out);
|
| 103 |
+
}
|
| 104 |
+
namespace symint {
|
| 105 |
+
template <typename T, typename = std::enable_if_t<std::is_same<T, c10::SymInt>::value>>
|
| 106 |
+
at::Tensor & zeros_out(at::Tensor & out, c10::SymIntArrayRef size) {
|
| 107 |
+
return at::_ops::zeros_out::call(size, out);
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
// aten::zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!)
|
| 112 |
+
inline at::Tensor & zeros_symint_outf(c10::SymIntArrayRef size, at::Tensor & out) {
|
| 113 |
+
return at::_ops::zeros_out::call(size, out);
|
| 114 |
+
}
|
| 115 |
+
namespace symint {
|
| 116 |
+
template <typename T, typename = std::enable_if_t<std::is_same<T, c10::SymInt>::value>>
|
| 117 |
+
at::Tensor & zeros_outf(c10::SymIntArrayRef size, at::Tensor & out) {
|
| 118 |
+
return at::_ops::zeros_out::call(size, out);
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
// aten::zeros.names_out(int[] size, *, Dimname[]? names, Tensor(a!) out) -> Tensor(a!)
|
| 123 |
+
inline at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size, c10::optional<at::DimnameList> names) {
|
| 124 |
+
return at::_ops::zeros_names_out::call(size, names, out);
|
| 125 |
+
}
|
| 126 |
+
// aten::zeros.names_out(int[] size, *, Dimname[]? names, Tensor(a!) out) -> Tensor(a!)
|
| 127 |
+
inline at::Tensor & zeros_outf(at::IntArrayRef size, c10::optional<at::DimnameList> names, at::Tensor & out) {
|
| 128 |
+
return at::_ops::zeros_names_out::call(size, names, out);
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
}
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_compositeexplicitautograd_dispatch.h
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace compositeexplicitautograd {
|
| 19 |
+
|
| 20 |
+
TORCH_API at::Tensor zeros(at::IntArrayRef size, c10::optional<at::DimnameList> names, at::TensorOptions options={});
|
| 21 |
+
TORCH_API at::Tensor zeros(at::IntArrayRef size, c10::optional<at::DimnameList> names, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory);
|
| 22 |
+
TORCH_API at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size, c10::optional<at::DimnameList> names);
|
| 23 |
+
TORCH_API at::Tensor & zeros_outf(at::IntArrayRef size, c10::optional<at::DimnameList> names, at::Tensor & out);
|
| 24 |
+
TORCH_API at::Tensor zeros(at::IntArrayRef size, at::TensorOptions options={});
|
| 25 |
+
TORCH_API at::Tensor zeros(at::IntArrayRef size, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory);
|
| 26 |
+
TORCH_API at::Tensor zeros_symint(c10::SymIntArrayRef size, at::TensorOptions options={});
|
| 27 |
+
TORCH_API at::Tensor zeros_symint(c10::SymIntArrayRef size, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory);
|
| 28 |
+
TORCH_API at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size);
|
| 29 |
+
TORCH_API at::Tensor & zeros_outf(at::IntArrayRef size, at::Tensor & out);
|
| 30 |
+
TORCH_API at::Tensor & zeros_symint_out(at::Tensor & out, c10::SymIntArrayRef size);
|
| 31 |
+
TORCH_API at::Tensor & zeros_symint_outf(c10::SymIntArrayRef size, at::Tensor & out);
|
| 32 |
+
|
| 33 |
+
} // namespace compositeexplicitautograd
|
| 34 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like.h
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Function.h
|
| 4 |
+
|
| 5 |
+
#include <ATen/Context.h>
|
| 6 |
+
#include <ATen/DeviceGuard.h>
|
| 7 |
+
#include <ATen/TensorUtils.h>
|
| 8 |
+
#include <ATen/TracerMode.h>
|
| 9 |
+
#include <ATen/core/Generator.h>
|
| 10 |
+
#include <ATen/core/Reduction.h>
|
| 11 |
+
#include <ATen/core/Tensor.h>
|
| 12 |
+
#include <c10/core/Scalar.h>
|
| 13 |
+
#include <c10/core/Storage.h>
|
| 14 |
+
#include <c10/core/TensorOptions.h>
|
| 15 |
+
#include <c10/util/Deprecated.h>
|
| 16 |
+
#include <c10/util/Optional.h>
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
#include <ATen/ops/zeros_like_ops.h>
|
| 21 |
+
|
| 22 |
+
namespace at {
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
// aten::zeros_like(Tensor self, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor
|
| 26 |
+
inline at::Tensor zeros_like(const at::Tensor & self, at::TensorOptions options={}, c10::optional<at::MemoryFormat> memory_format=c10::nullopt) {
|
| 27 |
+
return at::_ops::zeros_like::call(self, optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt(), c10::impl::check_tensor_options_and_extract_memory_format(options, memory_format));
|
| 28 |
+
}
|
| 29 |
+
// aten::zeros_like(Tensor self, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor
|
| 30 |
+
inline at::Tensor zeros_like(const at::Tensor & self, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory, c10::optional<at::MemoryFormat> memory_format) {
|
| 31 |
+
return at::_ops::zeros_like::call(self, dtype, layout, device, pin_memory, memory_format);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// aten::zeros_like.out(Tensor self, *, MemoryFormat? memory_format=None, Tensor(a!) out) -> Tensor(a!)
|
| 35 |
+
inline at::Tensor & zeros_like_out(at::Tensor & out, const at::Tensor & self, c10::optional<at::MemoryFormat> memory_format=c10::nullopt) {
|
| 36 |
+
return at::_ops::zeros_like_out::call(self, memory_format, out);
|
| 37 |
+
}
|
| 38 |
+
// aten::zeros_like.out(Tensor self, *, MemoryFormat? memory_format=None, Tensor(a!) out) -> Tensor(a!)
|
| 39 |
+
inline at::Tensor & zeros_like_outf(const at::Tensor & self, c10::optional<at::MemoryFormat> memory_format, at::Tensor & out) {
|
| 40 |
+
return at::_ops::zeros_like_out::call(self, memory_format, out);
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
}
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like_compositeexplicitautograd_dispatch.h
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace compositeexplicitautograd {
|
| 19 |
+
|
| 20 |
+
TORCH_API at::Tensor zeros_like(const at::Tensor & self, at::TensorOptions options={}, c10::optional<at::MemoryFormat> memory_format=c10::nullopt);
|
| 21 |
+
TORCH_API at::Tensor zeros_like(const at::Tensor & self, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory, c10::optional<at::MemoryFormat> memory_format);
|
| 22 |
+
TORCH_API at::Tensor & zeros_like_out(at::Tensor & out, const at::Tensor & self, c10::optional<at::MemoryFormat> memory_format=c10::nullopt);
|
| 23 |
+
TORCH_API at::Tensor & zeros_like_outf(const at::Tensor & self, c10::optional<at::MemoryFormat> memory_format, at::Tensor & out);
|
| 24 |
+
|
| 25 |
+
} // namespace compositeexplicitautograd
|
| 26 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like_compositeimplicitautogradnestedtensor_dispatch.h
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// @generated by torchgen/gen.py from DispatchKeyFunction.h
|
| 3 |
+
|
| 4 |
+
// NB: The implementing C++ file is RegisterDispatchKey.cpp
|
| 5 |
+
|
| 6 |
+
// The only #includes we need are for custom classes that have defaults in the C++ API
|
| 7 |
+
#include <c10/core/MemoryFormat.h>
|
| 8 |
+
#include <c10/core/Scalar.h>
|
| 9 |
+
#include <ATen/core/Reduction.h>
|
| 10 |
+
|
| 11 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 12 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 13 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 14 |
+
#include <ATen/core/ATen_fwd.h>
|
| 15 |
+
|
| 16 |
+
namespace at {
|
| 17 |
+
|
| 18 |
+
namespace compositeimplicitautogradnestedtensor {
|
| 19 |
+
|
| 20 |
+
TORCH_API at::Tensor zeros_like(const at::Tensor & self, at::TensorOptions options={}, c10::optional<at::MemoryFormat> memory_format=c10::nullopt);
|
| 21 |
+
TORCH_API at::Tensor zeros_like(const at::Tensor & self, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory, c10::optional<at::MemoryFormat> memory_format);
|
| 22 |
+
|
| 23 |
+
} // namespace compositeimplicitautogradnestedtensor
|
| 24 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like_native.h
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from NativeFunction.h
|
| 4 |
+
|
| 5 |
+
#include <c10/core/Scalar.h>
|
| 6 |
+
#include <c10/core/Storage.h>
|
| 7 |
+
#include <c10/core/TensorOptions.h>
|
| 8 |
+
#include <c10/util/Deprecated.h>
|
| 9 |
+
#include <c10/util/Optional.h>
|
| 10 |
+
#include <c10/core/QScheme.h>
|
| 11 |
+
#include <ATen/core/Reduction.h>
|
| 12 |
+
#include <ATen/core/Tensor.h>
|
| 13 |
+
#include <tuple>
|
| 14 |
+
#include <vector>
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
namespace at {
|
| 18 |
+
namespace native {
|
| 19 |
+
TORCH_API at::Tensor zeros_like(const at::Tensor & self, c10::optional<at::ScalarType> dtype={}, c10::optional<at::Layout> layout={}, c10::optional<at::Device> device={}, c10::optional<bool> pin_memory={}, c10::optional<at::MemoryFormat> memory_format=c10::nullopt);
|
| 20 |
+
TORCH_API at::Tensor & zeros_like_out(const at::Tensor & self, c10::optional<at::MemoryFormat> memory_format, at::Tensor & out);
|
| 21 |
+
} // namespace native
|
| 22 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_like_ops.h
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Operator.h
|
| 4 |
+
|
| 5 |
+
#include <tuple>
|
| 6 |
+
#include <vector>
|
| 7 |
+
|
| 8 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 9 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 10 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 11 |
+
#include <ATen/core/ATen_fwd.h>
|
| 12 |
+
|
| 13 |
+
namespace at {
|
| 14 |
+
namespace _ops {
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
struct TORCH_API zeros_like {
|
| 18 |
+
using schema = at::Tensor (const at::Tensor &, c10::optional<at::ScalarType>, c10::optional<at::Layout>, c10::optional<at::Device>, c10::optional<bool>, c10::optional<at::MemoryFormat>);
|
| 19 |
+
using ptr_schema = schema*;
|
| 20 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 21 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::zeros_like")
|
| 22 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "")
|
| 23 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "zeros_like(Tensor self, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor")
|
| 24 |
+
static at::Tensor call(const at::Tensor & self, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory, c10::optional<at::MemoryFormat> memory_format);
|
| 25 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory, c10::optional<at::MemoryFormat> memory_format);
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
struct TORCH_API zeros_like_out {
|
| 29 |
+
using schema = at::Tensor & (const at::Tensor &, c10::optional<at::MemoryFormat>, at::Tensor &);
|
| 30 |
+
using ptr_schema = schema*;
|
| 31 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 32 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::zeros_like")
|
| 33 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "out")
|
| 34 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "zeros_like.out(Tensor self, *, MemoryFormat? memory_format=None, Tensor(a!) out) -> Tensor(a!)")
|
| 35 |
+
static at::Tensor & call(const at::Tensor & self, c10::optional<at::MemoryFormat> memory_format, at::Tensor & out);
|
| 36 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::optional<at::MemoryFormat> memory_format, at::Tensor & out);
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
}} // namespace at::_ops
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_native.h
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from NativeFunction.h
|
| 4 |
+
|
| 5 |
+
#include <c10/core/Scalar.h>
|
| 6 |
+
#include <c10/core/Storage.h>
|
| 7 |
+
#include <c10/core/TensorOptions.h>
|
| 8 |
+
#include <c10/util/Deprecated.h>
|
| 9 |
+
#include <c10/util/Optional.h>
|
| 10 |
+
#include <c10/core/QScheme.h>
|
| 11 |
+
#include <ATen/core/Reduction.h>
|
| 12 |
+
#include <ATen/core/Tensor.h>
|
| 13 |
+
#include <tuple>
|
| 14 |
+
#include <vector>
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
namespace at {
|
| 18 |
+
namespace native {
|
| 19 |
+
TORCH_API at::Tensor zeros(at::IntArrayRef size, c10::optional<at::DimnameList> names, c10::optional<at::ScalarType> dtype={}, c10::optional<at::Layout> layout={}, c10::optional<at::Device> device={}, c10::optional<bool> pin_memory={});
|
| 20 |
+
TORCH_API at::Tensor & zeros_names_out(at::IntArrayRef size, c10::optional<at::DimnameList> names, at::Tensor & out);
|
| 21 |
+
TORCH_API at::Tensor zeros_symint(c10::SymIntArrayRef size, c10::optional<at::ScalarType> dtype={}, c10::optional<at::Layout> layout={}, c10::optional<at::Device> device={}, c10::optional<bool> pin_memory={});
|
| 22 |
+
TORCH_API at::Tensor & zeros_out(at::IntArrayRef size, at::Tensor & out);
|
| 23 |
+
TORCH_API at::Tensor & zeros_sparse_out(at::IntArrayRef size, at::Tensor & out);
|
| 24 |
+
} // namespace native
|
| 25 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/ops/zeros_ops.h
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// @generated by torchgen/gen.py from Operator.h
|
| 4 |
+
|
| 5 |
+
#include <tuple>
|
| 6 |
+
#include <vector>
|
| 7 |
+
|
| 8 |
+
// Forward declarations of any types needed in the operator signatures.
|
| 9 |
+
// We can't directly include these classes because it will cause circular include dependencies.
|
| 10 |
+
// This file is included by TensorBody.h, which defines the Tensor class.
|
| 11 |
+
#include <ATen/core/ATen_fwd.h>
|
| 12 |
+
|
| 13 |
+
namespace at {
|
| 14 |
+
namespace _ops {
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
struct TORCH_API zeros_names {
|
| 18 |
+
using schema = at::Tensor (at::IntArrayRef, c10::optional<at::DimnameList>, c10::optional<at::ScalarType>, c10::optional<at::Layout>, c10::optional<at::Device>, c10::optional<bool>);
|
| 19 |
+
using ptr_schema = schema*;
|
| 20 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 21 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::zeros")
|
| 22 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "names")
|
| 23 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "zeros.names(int[] size, *, Dimname[]? names, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor")
|
| 24 |
+
static at::Tensor call(at::IntArrayRef size, c10::optional<at::DimnameList> names, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory);
|
| 25 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, at::IntArrayRef size, c10::optional<at::DimnameList> names, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory);
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
struct TORCH_API zeros {
|
| 29 |
+
using schema = at::Tensor (c10::SymIntArrayRef, c10::optional<at::ScalarType>, c10::optional<at::Layout>, c10::optional<at::Device>, c10::optional<bool>);
|
| 30 |
+
using ptr_schema = schema*;
|
| 31 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 32 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::zeros")
|
| 33 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "")
|
| 34 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor")
|
| 35 |
+
static at::Tensor call(c10::SymIntArrayRef size, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory);
|
| 36 |
+
static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, c10::SymIntArrayRef size, c10::optional<at::ScalarType> dtype, c10::optional<at::Layout> layout, c10::optional<at::Device> device, c10::optional<bool> pin_memory);
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
struct TORCH_API zeros_out {
|
| 40 |
+
using schema = at::Tensor & (c10::SymIntArrayRef, at::Tensor &);
|
| 41 |
+
using ptr_schema = schema*;
|
| 42 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 43 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::zeros")
|
| 44 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "out")
|
| 45 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!)")
|
| 46 |
+
static at::Tensor & call(c10::SymIntArrayRef size, at::Tensor & out);
|
| 47 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, c10::SymIntArrayRef size, at::Tensor & out);
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
struct TORCH_API zeros_names_out {
|
| 51 |
+
using schema = at::Tensor & (at::IntArrayRef, c10::optional<at::DimnameList>, at::Tensor &);
|
| 52 |
+
using ptr_schema = schema*;
|
| 53 |
+
// See Note [static constexpr char* members for windows NVCC]
|
| 54 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(name, "aten::zeros")
|
| 55 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(overload_name, "names_out")
|
| 56 |
+
STATIC_CONSTEXPR_STR_INL_EXCEPT_WIN_CUDA(schema_str, "zeros.names_out(int[] size, *, Dimname[]? names, Tensor(a!) out) -> Tensor(a!)")
|
| 57 |
+
static at::Tensor & call(at::IntArrayRef size, c10::optional<at::DimnameList> names, at::Tensor & out);
|
| 58 |
+
static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::IntArrayRef size, c10::optional<at::DimnameList> names, at::Tensor & out);
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
}} // namespace at::_ops
|
rtme/lib/python3.10/site-packages/torch/include/ATen/quantized/QTensorImpl.h
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <ATen/quantized/Quantizer.h>
|
| 4 |
+
#include <c10/core/TensorImpl.h>
|
| 5 |
+
#include <c10/util/Exception.h>
|
| 6 |
+
|
| 7 |
+
namespace at {
|
| 8 |
+
|
| 9 |
+
/**
|
| 10 |
+
* QTensorImpl is a TensorImpl for Quantized Tensors, it stores Quantizer which
|
| 11 |
+
* specifies the quantization scheme and parameters, for more information please
|
| 12 |
+
* see ATen/quantized/Quantizer.h
|
| 13 |
+
*
|
| 14 |
+
* We'll use QTensor in code or documentation to refer to a Tensor with QTensorImpl.
|
| 15 |
+
*/
|
| 16 |
+
struct TORCH_API QTensorImpl : public c10::TensorImpl {
|
| 17 |
+
public:
|
| 18 |
+
QTensorImpl(
|
| 19 |
+
Storage&& storage,
|
| 20 |
+
DispatchKeySet key_set,
|
| 21 |
+
const caffe2::TypeMeta data_type,
|
| 22 |
+
QuantizerPtr quantizer);
|
| 23 |
+
|
| 24 |
+
// See Note [Enum ImplType]
|
| 25 |
+
QTensorImpl(
|
| 26 |
+
ImplType type,
|
| 27 |
+
Storage&& storage,
|
| 28 |
+
DispatchKeySet key_set,
|
| 29 |
+
const caffe2::TypeMeta data_type,
|
| 30 |
+
QuantizerPtr quantizer);
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
// TODO: Expose in PyTorch Frontend
|
| 34 |
+
QuantizerPtr quantizer() {
|
| 35 |
+
return quantizer_;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
void set_quantizer_(QuantizerPtr quantizer) {
|
| 39 |
+
quantizer_ = quantizer;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
/**
|
| 43 |
+
* Return a TensorImpl that is a shallow-copy of this TensorImpl.
|
| 44 |
+
*
|
| 45 |
+
* For usage of `version_counter` and `allow_tensor_metadata_change`,
|
| 46 |
+
* see NOTE [ TensorImpl Shallow-Copying ].
|
| 47 |
+
*/
|
| 48 |
+
c10::intrusive_ptr<TensorImpl> shallow_copy_and_detach(
|
| 49 |
+
const c10::VariableVersion& version_counter,
|
| 50 |
+
bool allow_tensor_metadata_change) const override {
|
| 51 |
+
auto impl = c10::make_intrusive<QTensorImpl>(
|
| 52 |
+
Storage(storage()), key_set(), data_type_, quantizer_);
|
| 53 |
+
copy_tensor_metadata(
|
| 54 |
+
/*src_impl=*/this,
|
| 55 |
+
/*dest_impl=*/impl.get(),
|
| 56 |
+
/*version_counter=*/version_counter,
|
| 57 |
+
/*allow_tensor_metadata_change=*/allow_tensor_metadata_change);
|
| 58 |
+
impl->refresh_numel();
|
| 59 |
+
impl->refresh_contiguous();
|
| 60 |
+
return impl;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
/**
|
| 64 |
+
* Return a TensorImpl that is a shallow-copy of this TensorImpl.
|
| 65 |
+
*
|
| 66 |
+
* For usage of `version_counter` and `allow_tensor_metadata_change`,
|
| 67 |
+
* see NOTE [ TensorImpl Shallow-Copying ].
|
| 68 |
+
*/
|
| 69 |
+
c10::intrusive_ptr<TensorImpl> shallow_copy_and_detach(
|
| 70 |
+
c10::VariableVersion&& version_counter,
|
| 71 |
+
bool allow_tensor_metadata_change) const override {
|
| 72 |
+
auto impl = c10::make_intrusive<QTensorImpl>(
|
| 73 |
+
Storage(storage()), key_set(), data_type_, quantizer_);
|
| 74 |
+
copy_tensor_metadata(
|
| 75 |
+
/*src_impl=*/this,
|
| 76 |
+
/*dest_impl=*/impl.get(),
|
| 77 |
+
/*version_counter=*/std::move(version_counter),
|
| 78 |
+
/*allow_tensor_metadata_change=*/allow_tensor_metadata_change);
|
| 79 |
+
impl->refresh_numel();
|
| 80 |
+
impl->refresh_contiguous();
|
| 81 |
+
return impl;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
/**
|
| 85 |
+
* Shallow-copies data from another TensorImpl into this TensorImpl.
|
| 86 |
+
*
|
| 87 |
+
* For why this function doesn't check this TensorImpl's `allow_tensor_metadata_change_`,
|
| 88 |
+
* see NOTE [ TensorImpl Shallow-Copying ].
|
| 89 |
+
*/
|
| 90 |
+
void shallow_copy_from(const c10::intrusive_ptr<TensorImpl>& impl) override {
|
| 91 |
+
AT_ASSERT(has_compatible_shallow_copy_type(impl->key_set()));
|
| 92 |
+
auto q_impl = static_cast<const QTensorImpl*>(impl.get());
|
| 93 |
+
copy_tensor_metadata(
|
| 94 |
+
/*src_impl=*/q_impl,
|
| 95 |
+
/*dest_impl=*/this,
|
| 96 |
+
/*version_counter=*/version_counter(),
|
| 97 |
+
/*allow_tensor_metadata_change=*/allow_tensor_metadata_change());
|
| 98 |
+
refresh_numel();
|
| 99 |
+
refresh_contiguous();
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
private:
|
| 103 |
+
QuantizerPtr quantizer_;
|
| 104 |
+
|
| 105 |
+
const char* tensorimpl_type_name() const override;
|
| 106 |
+
|
| 107 |
+
/**
|
| 108 |
+
* Copy the tensor metadata fields (e.g. sizes / strides / storage pointer / storage_offset)
|
| 109 |
+
* from one TensorImpl to another TensorImpl.
|
| 110 |
+
*
|
| 111 |
+
* For usage of `version_counter` and `allow_tensor_metadata_change`, see NOTE [ TensorImpl Shallow-Copying ].
|
| 112 |
+
*/
|
| 113 |
+
static void copy_tensor_metadata(
|
| 114 |
+
const QTensorImpl* src_q_impl,
|
| 115 |
+
QTensorImpl* dest_q_impl,
|
| 116 |
+
const c10::VariableVersion& version_counter,
|
| 117 |
+
bool allow_tensor_metadata_change) {
|
| 118 |
+
TensorImpl::copy_tensor_metadata(src_q_impl, dest_q_impl, version_counter, allow_tensor_metadata_change);
|
| 119 |
+
|
| 120 |
+
// OpaqueTensorImpl-specific fields.
|
| 121 |
+
dest_q_impl->quantizer_ = src_q_impl->quantizer_;
|
| 122 |
+
}
|
| 123 |
+
};
|
| 124 |
+
|
| 125 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/ATen/quantized/Quantizer.h
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/QScheme.h>
|
| 4 |
+
#include <c10/core/MemoryFormat.h>
|
| 5 |
+
#include <c10/macros/Macros.h>
|
| 6 |
+
#include <c10/util/Exception.h>
|
| 7 |
+
#include <c10/util/intrusive_ptr.h>
|
| 8 |
+
#include <c10/core/ScalarType.h>
|
| 9 |
+
#include <c10/core/TensorOptions.h>
|
| 10 |
+
|
| 11 |
+
#include <ATen/Tensor.h>
|
| 12 |
+
#include <ATen/TensorUtils.h>
|
| 13 |
+
|
| 14 |
+
#include <ATen/core/QuantizerBase.h>
|
| 15 |
+
|
| 16 |
+
#include <cmath>
|
| 17 |
+
#include <memory>
|
| 18 |
+
#include <utility>
|
| 19 |
+
|
| 20 |
+
namespace at {
|
| 21 |
+
|
| 22 |
+
/**
|
| 23 |
+
* UnknownQuantizer is a placeholder quantizer for functions that implement
|
| 24 |
+
* quantization in a two step process. First a tensor is allocated but with
|
| 25 |
+
* unknown quantizer, and then the quantization kernel decides what the final
|
| 26 |
+
* quantizer will be.
|
| 27 |
+
*/
|
| 28 |
+
struct TORCH_API UnknownQuantizer : public Quantizer {
|
| 29 |
+
explicit UnknownQuantizer(ScalarType scalar_type)
|
| 30 |
+
: Quantizer(scalar_type) {}
|
| 31 |
+
|
| 32 |
+
Tensor quantize(const Tensor& tensor) override;
|
| 33 |
+
Tensor dequantize(const Tensor& qtensor) override;
|
| 34 |
+
Tensor& dequantize_out(Tensor& rtensor, const Tensor& qtensor) override;
|
| 35 |
+
QScheme qscheme() const override;
|
| 36 |
+
bool equalTo(QuantizerPtr other) const override;
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
/**
|
| 40 |
+
* UniformQuantizer is the parent class for all uniform quantizers.
|
| 41 |
+
* These quantization scheme will map float value uniformly to
|
| 42 |
+
* the quantized value. For example, affine quantizer is
|
| 43 |
+
* the most commonly used scheme in this category.
|
| 44 |
+
*/
|
| 45 |
+
struct TORCH_API UniformQuantizer : public Quantizer {
|
| 46 |
+
explicit UniformQuantizer(ScalarType scalar_type) : Quantizer(scalar_type) {}
|
| 47 |
+
};
|
| 48 |
+
|
| 49 |
+
/**
|
| 50 |
+
* NonUniformQuantizer is the parent class for all non-uniform quantizers.
|
| 51 |
+
* These quantization scheme may map float value non-uniformly to the quantized
|
| 52 |
+
* value. K-means quantization is a representative example in this category.
|
| 53 |
+
*/
|
| 54 |
+
struct TORCH_API NonUniformQuantizer : public Quantizer {
|
| 55 |
+
explicit NonUniformQuantizer(ScalarType scalar_type) : Quantizer(scalar_type) {}
|
| 56 |
+
};
|
| 57 |
+
|
| 58 |
+
// There is also StochasticQuantizer which is uniform but not affine
|
| 59 |
+
|
| 60 |
+
/**
|
| 61 |
+
* AffineQuantizer uses affine transformation to do quantization.
|
| 62 |
+
*
|
| 63 |
+
* For quantize:
|
| 64 |
+
* Y = clamp(round(X / scale + zero_point), min, max)
|
| 65 |
+
* For dequantize:
|
| 66 |
+
* X = (Y - zero_point) * scale
|
| 67 |
+
*/
|
| 68 |
+
struct TORCH_API AffineQuantizer : public UniformQuantizer {
|
| 69 |
+
explicit AffineQuantizer(ScalarType scalar_type) : UniformQuantizer(scalar_type) {}
|
| 70 |
+
};
|
| 71 |
+
|
| 72 |
+
// Note that we will not have Symmetric Quantizer in backend to reduce
|
| 73 |
+
// complications in quantized kernel implementation.
|
| 74 |
+
|
| 75 |
+
/**
|
| 76 |
+
* PerTensorAffineQuantizer stores a scale and a zero_point, which is used for
|
| 77 |
+
* all the values in the Tensor.
|
| 78 |
+
*/
|
| 79 |
+
struct TORCH_API PerTensorAffineQuantizer : public AffineQuantizer {
|
| 80 |
+
explicit PerTensorAffineQuantizer(ScalarType scalar_type, double scale, int64_t zero_point)
|
| 81 |
+
: AffineQuantizer(scalar_type),
|
| 82 |
+
scale_(scale),
|
| 83 |
+
zero_point_(zero_point) {}
|
| 84 |
+
|
| 85 |
+
Tensor quantize(const Tensor& tensor) override;
|
| 86 |
+
Tensor dequantize(const Tensor& qtensor) override;
|
| 87 |
+
Tensor& dequantize_out(Tensor& rtensor, const Tensor& qtensor) override;
|
| 88 |
+
|
| 89 |
+
QScheme qscheme() const override {
|
| 90 |
+
return kPerTensorAffine;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
double scale() const {
|
| 94 |
+
return scale_;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
int64_t zero_point() const {
|
| 98 |
+
return zero_point_;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
bool equalTo(QuantizerPtr other) const override {
|
| 102 |
+
if (!other.get() || other->qscheme() != kPerTensorAffine) {
|
| 103 |
+
return false;
|
| 104 |
+
}
|
| 105 |
+
auto* other_per_tensor_affine =
|
| 106 |
+
static_cast<PerTensorAffineQuantizer*>(other.get());
|
| 107 |
+
return scalar_type() == other_per_tensor_affine->scalar_type() &&
|
| 108 |
+
scale() == other_per_tensor_affine->scale() &&
|
| 109 |
+
zero_point() == other_per_tensor_affine->zero_point();
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
private:
|
| 113 |
+
const double scale_;
|
| 114 |
+
// We use int64_t for consistency with Python
|
| 115 |
+
const int64_t zero_point_;
|
| 116 |
+
};
|
| 117 |
+
|
| 118 |
+
/**
|
| 119 |
+
* PerChannelAffineQuantizer is the same as PerTensorAffineQuantizer
|
| 120 |
+
* except that we have an independent scale and zero_point parameter
|
| 121 |
+
* for each channel.
|
| 122 |
+
*
|
| 123 |
+
* Also note that per channel quantization is mostly applied to output channels
|
| 124 |
+
* of weights since per-input channel of weight quantization or per-channel
|
| 125 |
+
* quantization for activations can't be efficiently supported in most of
|
| 126 |
+
* processors since it requires each multiplication result within a single
|
| 127 |
+
* dot-product to have a different scale.
|
| 128 |
+
*/
|
| 129 |
+
struct TORCH_API PerChannelAffineQuantizer : public AffineQuantizer {
|
| 130 |
+
explicit PerChannelAffineQuantizer(
|
| 131 |
+
ScalarType scalar_type,
|
| 132 |
+
Tensor scales,
|
| 133 |
+
Tensor zero_points,
|
| 134 |
+
int64_t axis)
|
| 135 |
+
: AffineQuantizer(scalar_type),
|
| 136 |
+
scales_(std::move(scales)),
|
| 137 |
+
zero_points_(std::move(zero_points)),
|
| 138 |
+
axis_(axis) {}
|
| 139 |
+
|
| 140 |
+
QScheme qscheme() const override {
|
| 141 |
+
return kPerChannelAffine;
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
Tensor scales() const {
|
| 145 |
+
return scales_;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
Tensor zero_points() const {
|
| 149 |
+
return zero_points_;
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
int64_t axis() const {
|
| 153 |
+
return axis_;
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
Tensor quantize(const Tensor& tensor) override;
|
| 157 |
+
Tensor dequantize(const Tensor& qtensor) override;
|
| 158 |
+
Tensor& dequantize_out(Tensor& rtensor, const Tensor& qtensor) override;
|
| 159 |
+
|
| 160 |
+
bool equalTo(QuantizerPtr other) const override {
|
| 161 |
+
if (!other.get() || other->qscheme() != kPerChannelAffine) {
|
| 162 |
+
return false;
|
| 163 |
+
}
|
| 164 |
+
auto* other_per_channel_affine =
|
| 165 |
+
static_cast<PerChannelAffineQuantizer*>(other.get());
|
| 166 |
+
return scalar_type() == other_per_channel_affine->scalar_type() &&
|
| 167 |
+
scales().equal(other_per_channel_affine->scales()) &&
|
| 168 |
+
zero_points().equal(other_per_channel_affine->zero_points()) &&
|
| 169 |
+
axis() == other_per_channel_affine->axis();
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
protected:
|
| 173 |
+
Tensor scales_;
|
| 174 |
+
Tensor zero_points_;
|
| 175 |
+
const int64_t axis_;
|
| 176 |
+
};
|
| 177 |
+
|
| 178 |
+
/**
|
| 179 |
+
* PerChannelAffineFloatQParamsQuantizer is the same as PerChannelAffineQuantizer
|
| 180 |
+
* except that it expects both scale and zero point to be floating point values.
|
| 181 |
+
*
|
| 182 |
+
* This quantizer uses the kPerChannelAffineFloatQParams qscheme which is a variant of
|
| 183 |
+
* kPerChannelAffine.
|
| 184 |
+
*
|
| 185 |
+
* The quantize equation in this case looks like -
|
| 186 |
+
* Xq = (Xf - zero_point) * inv_scale, where inv_scale = 1.0/scale
|
| 187 |
+
*
|
| 188 |
+
* Note: Usage of floating point zero point is useful in cases where 0 doesn't need to
|
| 189 |
+
* be exactly represented in the quantized space. We can get additional precision by
|
| 190 |
+
* using floating point values for zero point.
|
| 191 |
+
*/
|
| 192 |
+
struct TORCH_API PerChannelAffineFloatQParamsQuantizer : public PerChannelAffineQuantizer {
|
| 193 |
+
explicit PerChannelAffineFloatQParamsQuantizer(
|
| 194 |
+
ScalarType scalar_type,
|
| 195 |
+
Tensor scales,
|
| 196 |
+
Tensor zero_points,
|
| 197 |
+
int64_t axis)
|
| 198 |
+
: PerChannelAffineQuantizer(scalar_type,
|
| 199 |
+
scales,
|
| 200 |
+
zero_points,
|
| 201 |
+
axis) {}
|
| 202 |
+
|
| 203 |
+
QScheme qscheme() const override {
|
| 204 |
+
return kPerChannelAffineFloatQParams;
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
Tensor quantize(const Tensor& tensor) override;
|
| 208 |
+
Tensor dequantize(const Tensor& qtensor) override;
|
| 209 |
+
Tensor& dequantize_out(Tensor& rtensor, const Tensor& qtensor) override;
|
| 210 |
+
|
| 211 |
+
bool equalTo(QuantizerPtr other) const override {
|
| 212 |
+
if (!other.get() || other->qscheme() != kPerChannelAffineFloatQParams) {
|
| 213 |
+
return false;
|
| 214 |
+
}
|
| 215 |
+
auto* other_per_channel_float_qparams =
|
| 216 |
+
static_cast<PerChannelAffineFloatQParamsQuantizer*>(other.get());
|
| 217 |
+
return scalar_type() == other_per_channel_float_qparams->scalar_type() &&
|
| 218 |
+
scales().equal(other_per_channel_float_qparams->scales()) &&
|
| 219 |
+
zero_points().equal(other_per_channel_float_qparams->zero_points()) &&
|
| 220 |
+
axis() == other_per_channel_float_qparams->axis();
|
| 221 |
+
}
|
| 222 |
+
};
|
| 223 |
+
|
| 224 |
+
// This is an internal utility function for getting at the QTensorImpl,
|
| 225 |
+
// You should only use this for writing low level
|
| 226 |
+
// setters/getters for QTensorImpl fields; otherwise, you should use
|
| 227 |
+
// the low level setters/getters that were implemented using this.
|
| 228 |
+
// This may be called repeatedly, so make sure it's pretty cheap.
|
| 229 |
+
TORCH_API QTensorImpl* get_qtensorimpl(const TensorBase& self);
|
| 230 |
+
|
| 231 |
+
// double and int64_t are because of the native function API, we only have these
|
| 232 |
+
// argument types right now in native functions
|
| 233 |
+
TORCH_API QuantizerPtr
|
| 234 |
+
make_per_tensor_affine_quantizer(
|
| 235 |
+
double scale, int64_t zero_point, ScalarType scalar_type);
|
| 236 |
+
|
| 237 |
+
TORCH_API QuantizerPtr make_per_channel_affine_quantizer(
|
| 238 |
+
const Tensor& scales,
|
| 239 |
+
const Tensor& zero_points,
|
| 240 |
+
int64_t axis,
|
| 241 |
+
ScalarType scalar_type);
|
| 242 |
+
|
| 243 |
+
TORCH_API QuantizerPtr make_unknown_quantizer(ScalarType scalar_type);
|
| 244 |
+
|
| 245 |
+
// Create a Quantized Tensor given arguments for normal Tensor and a quantizer
|
| 246 |
+
TORCH_API Tensor new_qtensor(
|
| 247 |
+
IntArrayRef sizes,
|
| 248 |
+
const TensorOptions& options,
|
| 249 |
+
QuantizerPtr quantizer);
|
| 250 |
+
|
| 251 |
+
TORCH_API void set_quantizer_(const Tensor& self, ConstQuantizerPtr quantizer);
|
| 252 |
+
|
| 253 |
+
TORCH_API Tensor from_blob_quantized_per_tensor_affine(
|
| 254 |
+
void* data,
|
| 255 |
+
IntArrayRef sizes,
|
| 256 |
+
IntArrayRef strides,
|
| 257 |
+
std::function<void(void*)> deleter,
|
| 258 |
+
const float scale,
|
| 259 |
+
const int64_t zeroPoint,
|
| 260 |
+
const TensorOptions& options);
|
| 261 |
+
|
| 262 |
+
TORCH_API Tensor from_blob_quantized_per_tensor_affine(
|
| 263 |
+
void* data,
|
| 264 |
+
IntArrayRef sizes,
|
| 265 |
+
std::function<void(void*)> deleter,
|
| 266 |
+
const float scale,
|
| 267 |
+
const int64_t zeroPoint,
|
| 268 |
+
const TensorOptions& options);
|
| 269 |
+
|
| 270 |
+
TORCH_API Tensor from_blob_quantized_per_channel_affine(
|
| 271 |
+
void* data,
|
| 272 |
+
IntArrayRef sizes,
|
| 273 |
+
std::function<void(void*)> deleter,
|
| 274 |
+
const Tensor& scales,
|
| 275 |
+
const Tensor& zero_points,
|
| 276 |
+
const int64_t axis,
|
| 277 |
+
const TensorOptions& options);
|
| 278 |
+
|
| 279 |
+
} // namespace at
|
rtme/lib/python3.10/site-packages/torch/include/THC/THCAtomics.cuh
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// TODO: Remove once torchvision has been updated to use the ATen header
|
| 3 |
+
#include <ATen/cuda/Atomic.cuh>
|
rtme/lib/python3.10/site-packages/torch/include/THC/THCDeviceUtils.cuh
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
// TODO: Remove this header
|
| 3 |
+
#include <ATen/cuda/DeviceUtils.cuh>
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/Allocator.h
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <stddef.h>
|
| 4 |
+
#include <memory>
|
| 5 |
+
|
| 6 |
+
#include <c10/core/Device.h>
|
| 7 |
+
#include <c10/util/Exception.h>
|
| 8 |
+
#include <c10/util/ThreadLocalDebugInfo.h>
|
| 9 |
+
#include <c10/util/UniqueVoidPtr.h>
|
| 10 |
+
|
| 11 |
+
namespace c10 {
|
| 12 |
+
|
| 13 |
+
// A DataPtr is a unique pointer (with an attached deleter and some
|
| 14 |
+
// context for the deleter) to some memory, which also records what
|
| 15 |
+
// device is for its data.
|
| 16 |
+
//
|
| 17 |
+
// nullptr DataPtrs can still have a nontrivial device; this allows
|
| 18 |
+
// us to treat zero-size allocations uniformly with non-zero allocations.
|
| 19 |
+
//
|
| 20 |
+
class C10_API DataPtr {
|
| 21 |
+
private:
|
| 22 |
+
c10::detail::UniqueVoidPtr ptr_;
|
| 23 |
+
Device device_;
|
| 24 |
+
|
| 25 |
+
public:
|
| 26 |
+
// Choice of CPU here is arbitrary; if there's an "undefined" device
|
| 27 |
+
// we could use that too
|
| 28 |
+
DataPtr() : ptr_(), device_(DeviceType::CPU) {}
|
| 29 |
+
DataPtr(void* data, Device device) : ptr_(data), device_(device) {}
|
| 30 |
+
DataPtr(void* data, void* ctx, DeleterFnPtr ctx_deleter, Device device)
|
| 31 |
+
: ptr_(data, ctx, ctx_deleter), device_(device) {}
|
| 32 |
+
void* operator->() const {
|
| 33 |
+
return ptr_.get();
|
| 34 |
+
}
|
| 35 |
+
void clear() {
|
| 36 |
+
ptr_.clear();
|
| 37 |
+
}
|
| 38 |
+
void* get() const {
|
| 39 |
+
return ptr_.get();
|
| 40 |
+
}
|
| 41 |
+
void* mutable_get() {
|
| 42 |
+
return ptr_.get();
|
| 43 |
+
}
|
| 44 |
+
void* get_context() const {
|
| 45 |
+
return ptr_.get_context();
|
| 46 |
+
}
|
| 47 |
+
void* release_context() {
|
| 48 |
+
return ptr_.release_context();
|
| 49 |
+
}
|
| 50 |
+
std::unique_ptr<void, DeleterFnPtr>&& move_context() {
|
| 51 |
+
return ptr_.move_context();
|
| 52 |
+
}
|
| 53 |
+
operator bool() const {
|
| 54 |
+
return static_cast<bool>(ptr_);
|
| 55 |
+
}
|
| 56 |
+
template <typename T>
|
| 57 |
+
T* cast_context(DeleterFnPtr expected_deleter) const {
|
| 58 |
+
return ptr_.cast_context<T>(expected_deleter);
|
| 59 |
+
}
|
| 60 |
+
DeleterFnPtr get_deleter() const {
|
| 61 |
+
return ptr_.get_deleter();
|
| 62 |
+
}
|
| 63 |
+
/**
|
| 64 |
+
* Compare the deleter in a DataPtr to expected_deleter.
|
| 65 |
+
* If it matches, replace the deleter with new_deleter
|
| 66 |
+
* and return true; otherwise, does nothing and returns
|
| 67 |
+
* false.
|
| 68 |
+
*
|
| 69 |
+
* In general, it is not safe to unconditionally set the
|
| 70 |
+
* deleter on a DataPtr, because you don't know what
|
| 71 |
+
* the deleter is, and thus will have a hard time properly
|
| 72 |
+
* disposing of the deleter without storing the original
|
| 73 |
+
* deleter (this is difficult to do, because DeleterFnPtr
|
| 74 |
+
* is not a closure, and because the context on DataPtr is
|
| 75 |
+
* only a single word, you generally don't have enough
|
| 76 |
+
* space to store both the original deleter and its context).
|
| 77 |
+
* However, in some cases, you know /exactly/ what the deleter
|
| 78 |
+
* is, and you have a new deleter that manually wraps
|
| 79 |
+
* the old one. In this case, you can safely swap the deleter
|
| 80 |
+
* after asserting that the deleters line up.
|
| 81 |
+
*
|
| 82 |
+
* What are the requirements on new_deleter? It must still
|
| 83 |
+
* properly dispose of the void* pointer passed in as its argument,
|
| 84 |
+
* where void* is whatever the context of the original deleter
|
| 85 |
+
* is. So in general, you expect the new deleter to look something
|
| 86 |
+
* like this:
|
| 87 |
+
*
|
| 88 |
+
* [](void* ptr) {
|
| 89 |
+
* some_new_stuff(ptr);
|
| 90 |
+
* get_orig_allocator()->raw_deleter(ptr);
|
| 91 |
+
* }
|
| 92 |
+
*
|
| 93 |
+
* Note that it won't work to close over the original
|
| 94 |
+
* allocator; you don't have enough space to do that! Also,
|
| 95 |
+
* it's unsafe to assume that the passed in pointer in
|
| 96 |
+
* question is the memory pointer in question; it might not
|
| 97 |
+
* be; be sure to read the source code of the Allocator
|
| 98 |
+
* in question to confirm this.
|
| 99 |
+
*/
|
| 100 |
+
C10_NODISCARD bool compare_exchange_deleter(
|
| 101 |
+
DeleterFnPtr expected_deleter,
|
| 102 |
+
DeleterFnPtr new_deleter) {
|
| 103 |
+
return ptr_.compare_exchange_deleter(expected_deleter, new_deleter);
|
| 104 |
+
}
|
| 105 |
+
Device device() const {
|
| 106 |
+
return device_;
|
| 107 |
+
}
|
| 108 |
+
// Unsafely mutates the device on a DataPtr. Under normal use,
|
| 109 |
+
// you should never actually need to call this function.
|
| 110 |
+
// We need this for the implementation of the hack detailed
|
| 111 |
+
// in Note [Masquerading as CUDA]
|
| 112 |
+
void unsafe_set_device(Device device) {
|
| 113 |
+
device_ = device;
|
| 114 |
+
}
|
| 115 |
+
};
|
| 116 |
+
|
| 117 |
+
// NB: Device is NOT tested for here; a CUDA nullptr is as much a nullptr as a
|
| 118 |
+
// CPU nullptr
|
| 119 |
+
|
| 120 |
+
inline bool operator==(const DataPtr& dp, std::nullptr_t) noexcept {
|
| 121 |
+
return !dp;
|
| 122 |
+
}
|
| 123 |
+
inline bool operator==(std::nullptr_t, const DataPtr& dp) noexcept {
|
| 124 |
+
return !dp;
|
| 125 |
+
}
|
| 126 |
+
inline bool operator!=(const DataPtr& dp, std::nullptr_t) noexcept {
|
| 127 |
+
return dp;
|
| 128 |
+
}
|
| 129 |
+
inline bool operator!=(std::nullptr_t, const DataPtr& dp) noexcept {
|
| 130 |
+
return dp;
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
// Note [raw_allocate/raw_deallocate and Thrust]
|
| 134 |
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 135 |
+
// Thrust's support for custom allocators requires us to write something
|
| 136 |
+
// like this:
|
| 137 |
+
//
|
| 138 |
+
// class ThrustAllocator {
|
| 139 |
+
// char* allocate(size_t);
|
| 140 |
+
// void deallocate(char*, size_t);
|
| 141 |
+
// };
|
| 142 |
+
//
|
| 143 |
+
// This is not good for our unique_ptr based allocator interface, as
|
| 144 |
+
// there is no way to get to the context when we free.
|
| 145 |
+
//
|
| 146 |
+
// However, in some cases the context is exactly the same as
|
| 147 |
+
// the data pointer. In this case, we can support the "raw"
|
| 148 |
+
// allocate and deallocate interface. This is what
|
| 149 |
+
// raw_deleter signifies. By default, it returns a nullptr, which means that
|
| 150 |
+
// the raw interface is not implemented. Be sure to implement it whenever
|
| 151 |
+
// possible, or the raw interface will incorrectly reported as unsupported,
|
| 152 |
+
// when it is actually possible.
|
| 153 |
+
|
| 154 |
+
struct C10_API Allocator {
|
| 155 |
+
virtual ~Allocator() = default;
|
| 156 |
+
|
| 157 |
+
virtual DataPtr allocate(size_t n) const = 0;
|
| 158 |
+
|
| 159 |
+
// If this returns a non nullptr, it means that allocate()
|
| 160 |
+
// is guaranteed to return a unique_ptr with this deleter attached;
|
| 161 |
+
// it means the rawAllocate and rawDeallocate APIs are safe to use.
|
| 162 |
+
// This function MUST always return the same BoundDeleter.
|
| 163 |
+
virtual DeleterFnPtr raw_deleter() const {
|
| 164 |
+
return nullptr;
|
| 165 |
+
}
|
| 166 |
+
void* raw_allocate(size_t n) {
|
| 167 |
+
auto dptr = allocate(n);
|
| 168 |
+
AT_ASSERT(dptr.get() == dptr.get_context());
|
| 169 |
+
return dptr.release_context();
|
| 170 |
+
}
|
| 171 |
+
void raw_deallocate(void* ptr) {
|
| 172 |
+
auto d = raw_deleter();
|
| 173 |
+
AT_ASSERT(d);
|
| 174 |
+
d(ptr);
|
| 175 |
+
}
|
| 176 |
+
};
|
| 177 |
+
|
| 178 |
+
// This context is used to generate DataPtr which have arbitrary
|
| 179 |
+
// std::function deleters associated with them. In some user facing
|
| 180 |
+
// functions, we give a (user-friendly) interface for constructing
|
| 181 |
+
// tensors from external data which take an arbitrary std::function
|
| 182 |
+
// deleter. Grep for InefficientStdFunctionContext to find these
|
| 183 |
+
// occurrences.
|
| 184 |
+
//
|
| 185 |
+
// This context is inefficient because we have to do a dynamic
|
| 186 |
+
// allocation InefficientStdFunctionContext, on top of the dynamic
|
| 187 |
+
// allocation which is implied by std::function itself.
|
| 188 |
+
struct C10_API InefficientStdFunctionContext {
|
| 189 |
+
std::unique_ptr<void, std::function<void(void*)>> ptr_;
|
| 190 |
+
InefficientStdFunctionContext(
|
| 191 |
+
std::unique_ptr<void, std::function<void(void*)>>&& ptr)
|
| 192 |
+
: ptr_(std::move(ptr)) {}
|
| 193 |
+
static DataPtr makeDataPtr(
|
| 194 |
+
void* ptr,
|
| 195 |
+
const std::function<void(void*)>& deleter,
|
| 196 |
+
Device device);
|
| 197 |
+
};
|
| 198 |
+
|
| 199 |
+
/** Set the allocator for DeviceType `t`. The passed in allocator pointer is
|
| 200 |
+
* expected to have static lifetime; this function does NOT take ownership
|
| 201 |
+
* of the raw pointer. (The reason for this is to prevent existing pointers
|
| 202 |
+
* to an allocator of a particular device from being invalidated when
|
| 203 |
+
* SetAllocator is called.)
|
| 204 |
+
*
|
| 205 |
+
* Also note that this is not thread-safe, and we assume this function will
|
| 206 |
+
* only be called during initialization.
|
| 207 |
+
*
|
| 208 |
+
* The 'priority' flag is introduced when we want to overwrite the default
|
| 209 |
+
* allocator, since the allocators are set statically. The default priority
|
| 210 |
+
* is 0, which means the lowest. Only higher or equal priority can overwrite
|
| 211 |
+
* existing ones.
|
| 212 |
+
*/
|
| 213 |
+
C10_API void SetAllocator(DeviceType t, Allocator* alloc, uint8_t priority = 0);
|
| 214 |
+
C10_API Allocator* GetAllocator(const DeviceType& t);
|
| 215 |
+
|
| 216 |
+
template <DeviceType t>
|
| 217 |
+
struct AllocatorRegisterer {
|
| 218 |
+
explicit AllocatorRegisterer(Allocator* alloc) {
|
| 219 |
+
SetAllocator(t, alloc);
|
| 220 |
+
}
|
| 221 |
+
};
|
| 222 |
+
|
| 223 |
+
#define REGISTER_ALLOCATOR(t, f) \
|
| 224 |
+
namespace { \
|
| 225 |
+
static c10::AllocatorRegisterer<t> g_allocator_d(f); \
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
// An interface for reporting thread local memory usage
|
| 229 |
+
// per device
|
| 230 |
+
struct C10_API MemoryReportingInfoBase : public c10::DebugInfoBase {
|
| 231 |
+
MemoryReportingInfoBase();
|
| 232 |
+
~MemoryReportingInfoBase() override = default;
|
| 233 |
+
|
| 234 |
+
/**
|
| 235 |
+
* alloc_size corresponds to the size of the ptr.
|
| 236 |
+
*
|
| 237 |
+
* total_allocated corresponds to total allocated memory.
|
| 238 |
+
*
|
| 239 |
+
* total_reserved corresponds to total size of memory pool, both used and
|
| 240 |
+
* unused, if applicable.
|
| 241 |
+
*/
|
| 242 |
+
virtual void reportMemoryUsage(
|
| 243 |
+
void* ptr,
|
| 244 |
+
int64_t alloc_size,
|
| 245 |
+
size_t total_allocated,
|
| 246 |
+
size_t total_reserved,
|
| 247 |
+
Device device) = 0;
|
| 248 |
+
|
| 249 |
+
virtual void reportOutOfMemory(
|
| 250 |
+
int64_t alloc_size,
|
| 251 |
+
size_t total_allocated,
|
| 252 |
+
size_t total_reserved,
|
| 253 |
+
Device device);
|
| 254 |
+
|
| 255 |
+
virtual bool memoryProfilingEnabled() const = 0;
|
| 256 |
+
};
|
| 257 |
+
|
| 258 |
+
C10_API bool memoryProfilingEnabled();
|
| 259 |
+
C10_API void reportMemoryUsageToProfiler(
|
| 260 |
+
void* ptr,
|
| 261 |
+
int64_t alloc_size,
|
| 262 |
+
size_t total_allocated,
|
| 263 |
+
size_t total_reserved,
|
| 264 |
+
Device device);
|
| 265 |
+
|
| 266 |
+
C10_API void reportOutOfMemoryToProfiler(
|
| 267 |
+
int64_t alloc_size,
|
| 268 |
+
size_t total_allocated,
|
| 269 |
+
size_t total_reserved,
|
| 270 |
+
Device device);
|
| 271 |
+
|
| 272 |
+
// used to hold traceback information in allocators
|
| 273 |
+
struct GatheredContext {
|
| 274 |
+
virtual ~GatheredContext() = default;
|
| 275 |
+
};
|
| 276 |
+
|
| 277 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/AutogradState.h
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/macros/Export.h>
|
| 4 |
+
|
| 5 |
+
namespace c10 {
|
| 6 |
+
|
| 7 |
+
// Structure used to pack all the thread local boolean
|
| 8 |
+
// flags used by autograd
|
| 9 |
+
struct C10_API AutogradState {
|
| 10 |
+
static AutogradState& get_tls_state();
|
| 11 |
+
static void set_tls_state(AutogradState state);
|
| 12 |
+
|
| 13 |
+
AutogradState(
|
| 14 |
+
bool grad_mode,
|
| 15 |
+
bool inference_mode,
|
| 16 |
+
bool fw_grad_mode,
|
| 17 |
+
bool multithreading_enabled)
|
| 18 |
+
: grad_mode_(grad_mode),
|
| 19 |
+
inference_mode_(inference_mode),
|
| 20 |
+
fw_grad_mode_(fw_grad_mode),
|
| 21 |
+
multithreading_enabled_(multithreading_enabled),
|
| 22 |
+
view_replay_enabled_(false) {}
|
| 23 |
+
|
| 24 |
+
void set_grad_mode(bool enabled) {
|
| 25 |
+
grad_mode_ = enabled;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
void set_fw_grad_mode(bool enabled) {
|
| 29 |
+
fw_grad_mode_ = enabled;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
void set_inference_mode(bool enabled) {
|
| 33 |
+
inference_mode_ = enabled;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
void set_multithreading_enabled(bool multithreading_enabled) {
|
| 37 |
+
multithreading_enabled_ = multithreading_enabled;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
void set_view_replay_enabled(bool view_replay_enabled) {
|
| 41 |
+
view_replay_enabled_ = view_replay_enabled;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
bool get_grad_mode() const {
|
| 45 |
+
return grad_mode_;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
bool get_fw_grad_mode() const {
|
| 49 |
+
return fw_grad_mode_;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
bool get_inference_mode() const {
|
| 53 |
+
return inference_mode_;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
bool get_multithreading_enabled() const {
|
| 57 |
+
return multithreading_enabled_;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
bool get_view_replay_enabled() const {
|
| 61 |
+
return view_replay_enabled_;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
private:
|
| 65 |
+
bool grad_mode_ : 1;
|
| 66 |
+
bool inference_mode_ : 1;
|
| 67 |
+
bool fw_grad_mode_ : 1;
|
| 68 |
+
bool multithreading_enabled_ : 1;
|
| 69 |
+
bool view_replay_enabled_ : 1;
|
| 70 |
+
};
|
| 71 |
+
|
| 72 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/Backend.h
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/DeviceType.h>
|
| 4 |
+
#include <c10/core/DispatchKey.h>
|
| 5 |
+
#include <c10/core/DispatchKeySet.h>
|
| 6 |
+
#include <c10/util/Exception.h>
|
| 7 |
+
|
| 8 |
+
#include <stdexcept>
|
| 9 |
+
|
| 10 |
+
namespace c10 {
|
| 11 |
+
|
| 12 |
+
/**
|
| 13 |
+
* This legacy enum class defines the set of backends supported by old school,
|
| 14 |
+
* code generated Type-based ATen. A "backend" in this sense roughly
|
| 15 |
+
* corresponds to the cartesian product of (device type, layout), but restricted
|
| 16 |
+
* only to combinations which we actually have kernels for. Backend does NOT
|
| 17 |
+
* include dtype.
|
| 18 |
+
*
|
| 19 |
+
* The reason we are sunsetting this enum class is because it doesn't allow for
|
| 20 |
+
* open registration; e.g., if you want to add SparseXLA, you'd have to
|
| 21 |
+
* edit this enum; you wouldn't be able to do it out of tree. DispatchKey is
|
| 22 |
+
* the replacement for Backend which supports open registration.
|
| 23 |
+
*
|
| 24 |
+
* NB: The concept of 'Backend' here disagrees with the notion of backend
|
| 25 |
+
* exposed to users in torch.backends. Backend here is something like "CPU"
|
| 26 |
+
* or "SparseCUDA"; backend in torch.backends is something like "MKL" or
|
| 27 |
+
* "CUDNN".
|
| 28 |
+
*/
|
| 29 |
+
enum class Backend {
|
| 30 |
+
CPU,
|
| 31 |
+
CUDA,
|
| 32 |
+
HIP,
|
| 33 |
+
VE,
|
| 34 |
+
FPGA,
|
| 35 |
+
IPU,
|
| 36 |
+
XPU,
|
| 37 |
+
SparseCPU,
|
| 38 |
+
SparseCUDA,
|
| 39 |
+
SparseCsrCPU,
|
| 40 |
+
SparseCsrCUDA,
|
| 41 |
+
SparseHIP,
|
| 42 |
+
SparseVE,
|
| 43 |
+
SparseXPU,
|
| 44 |
+
SparsePrivateUse1,
|
| 45 |
+
ORT,
|
| 46 |
+
XLA,
|
| 47 |
+
Vulkan,
|
| 48 |
+
Metal,
|
| 49 |
+
Meta,
|
| 50 |
+
QuantizedCPU,
|
| 51 |
+
QuantizedCUDA,
|
| 52 |
+
QuantizedXPU,
|
| 53 |
+
QuantizedPrivateUse1,
|
| 54 |
+
Undefined,
|
| 55 |
+
MkldnnCPU,
|
| 56 |
+
MPS,
|
| 57 |
+
HPU,
|
| 58 |
+
Lazy,
|
| 59 |
+
MTIA,
|
| 60 |
+
PrivateUse1,
|
| 61 |
+
NumOptions
|
| 62 |
+
};
|
| 63 |
+
|
| 64 |
+
static inline Backend dispatchKeyToBackend(DispatchKey t) {
|
| 65 |
+
if (t == DispatchKey::CPU || t == DispatchKey::AutogradCPU) {
|
| 66 |
+
return Backend::CPU;
|
| 67 |
+
} else if (t == DispatchKey::CUDA || t == DispatchKey::AutogradCUDA) {
|
| 68 |
+
return Backend::CUDA;
|
| 69 |
+
} else if (t == DispatchKey::HIP) {
|
| 70 |
+
return Backend::HIP;
|
| 71 |
+
} else if (t == DispatchKey::VE) {
|
| 72 |
+
return Backend::VE;
|
| 73 |
+
} else if (t == DispatchKey::FPGA) {
|
| 74 |
+
return Backend::FPGA;
|
| 75 |
+
} else if (t == DispatchKey::ORT) {
|
| 76 |
+
return Backend::ORT;
|
| 77 |
+
} else if (t == DispatchKey::XLA || t == DispatchKey::AutogradXLA) {
|
| 78 |
+
return Backend::XLA;
|
| 79 |
+
} else if (t == DispatchKey::Lazy || t == DispatchKey::AutogradLazy) {
|
| 80 |
+
return Backend::Lazy;
|
| 81 |
+
} else if (t == DispatchKey::MPS || t == DispatchKey::AutogradMPS) {
|
| 82 |
+
return Backend::MPS;
|
| 83 |
+
} else if (t == DispatchKey::Vulkan) {
|
| 84 |
+
return Backend::Vulkan;
|
| 85 |
+
} else if (t == DispatchKey::Metal) {
|
| 86 |
+
return Backend::Metal;
|
| 87 |
+
} else if (t == DispatchKey::Meta) {
|
| 88 |
+
return Backend::Meta;
|
| 89 |
+
} else if (t == DispatchKey::SparseCPU) {
|
| 90 |
+
return Backend::SparseCPU;
|
| 91 |
+
} else if (t == DispatchKey::SparseCUDA) {
|
| 92 |
+
return Backend::SparseCUDA;
|
| 93 |
+
} else if (t == DispatchKey::SparseHIP) {
|
| 94 |
+
return Backend::SparseHIP;
|
| 95 |
+
} else if (t == DispatchKey::SparseVE) {
|
| 96 |
+
return Backend::SparseVE;
|
| 97 |
+
} else if (t == DispatchKey::SparsePrivateUse1) {
|
| 98 |
+
return Backend::SparsePrivateUse1;
|
| 99 |
+
} else if (t == DispatchKey::SparseCsrCPU) {
|
| 100 |
+
return Backend::SparseCsrCPU;
|
| 101 |
+
} else if (t == DispatchKey::SparseCsrCUDA) {
|
| 102 |
+
return Backend::SparseCsrCUDA;
|
| 103 |
+
} else if (t == DispatchKey::MkldnnCPU) {
|
| 104 |
+
return Backend::MkldnnCPU;
|
| 105 |
+
} else if (t == DispatchKey::QuantizedCPU) {
|
| 106 |
+
return Backend::QuantizedCPU;
|
| 107 |
+
} else if (t == DispatchKey::QuantizedCUDA) {
|
| 108 |
+
return Backend::QuantizedCUDA;
|
| 109 |
+
} else if (t == DispatchKey::IPU || t == DispatchKey::AutogradIPU) {
|
| 110 |
+
return Backend::IPU;
|
| 111 |
+
} else if (t == DispatchKey::XPU || t == DispatchKey::AutogradXPU) {
|
| 112 |
+
return Backend::XPU;
|
| 113 |
+
} else if (t == DispatchKey::SparseXPU) {
|
| 114 |
+
return Backend::SparseXPU;
|
| 115 |
+
} else if (t == DispatchKey::QuantizedXPU) {
|
| 116 |
+
return Backend::QuantizedXPU;
|
| 117 |
+
} else if (t == DispatchKey::QuantizedPrivateUse1) {
|
| 118 |
+
return Backend::QuantizedPrivateUse1;
|
| 119 |
+
} else if (t == DispatchKey::HPU || t == DispatchKey::AutogradHPU) {
|
| 120 |
+
return Backend::HPU;
|
| 121 |
+
} else if (t == DispatchKey::MTIA || t == DispatchKey::AutogradMTIA) {
|
| 122 |
+
return Backend::MTIA;
|
| 123 |
+
} else if (
|
| 124 |
+
t == DispatchKey::PrivateUse1 || t == DispatchKey::AutogradPrivateUse1) {
|
| 125 |
+
return Backend::PrivateUse1;
|
| 126 |
+
} else if (t == DispatchKey::Undefined) {
|
| 127 |
+
return Backend::Undefined;
|
| 128 |
+
} else {
|
| 129 |
+
TORCH_CHECK(false, "Unrecognized tensor type ID: ", t);
|
| 130 |
+
}
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
static inline DispatchKey backendToDispatchKey(Backend b) {
|
| 134 |
+
switch (b) {
|
| 135 |
+
case Backend::CPU:
|
| 136 |
+
return DispatchKey::CPU;
|
| 137 |
+
case Backend::CUDA:
|
| 138 |
+
return DispatchKey::CUDA;
|
| 139 |
+
case Backend::HIP:
|
| 140 |
+
return DispatchKey::HIP;
|
| 141 |
+
case Backend::VE:
|
| 142 |
+
return DispatchKey::VE;
|
| 143 |
+
case Backend::FPGA:
|
| 144 |
+
return DispatchKey::FPGA;
|
| 145 |
+
case Backend::ORT:
|
| 146 |
+
return DispatchKey::ORT;
|
| 147 |
+
case Backend::XLA:
|
| 148 |
+
return DispatchKey::XLA;
|
| 149 |
+
case Backend::Lazy:
|
| 150 |
+
return DispatchKey::Lazy;
|
| 151 |
+
case Backend::IPU:
|
| 152 |
+
return DispatchKey::IPU;
|
| 153 |
+
case Backend::XPU:
|
| 154 |
+
return DispatchKey::XPU;
|
| 155 |
+
case Backend::SparseXPU:
|
| 156 |
+
return DispatchKey::SparseXPU;
|
| 157 |
+
case Backend::SparseCPU:
|
| 158 |
+
return DispatchKey::SparseCPU;
|
| 159 |
+
case Backend::SparseCUDA:
|
| 160 |
+
return DispatchKey::SparseCUDA;
|
| 161 |
+
case Backend::SparseHIP:
|
| 162 |
+
return DispatchKey::SparseHIP;
|
| 163 |
+
case Backend::SparseVE:
|
| 164 |
+
return DispatchKey::SparseVE;
|
| 165 |
+
case Backend::SparsePrivateUse1:
|
| 166 |
+
return DispatchKey::SparsePrivateUse1;
|
| 167 |
+
case Backend::SparseCsrCPU:
|
| 168 |
+
return DispatchKey::SparseCsrCPU;
|
| 169 |
+
case Backend::SparseCsrCUDA:
|
| 170 |
+
return DispatchKey::SparseCsrCUDA;
|
| 171 |
+
case Backend::MkldnnCPU:
|
| 172 |
+
return DispatchKey::MkldnnCPU;
|
| 173 |
+
case Backend::Vulkan:
|
| 174 |
+
return DispatchKey::Vulkan;
|
| 175 |
+
case Backend::Metal:
|
| 176 |
+
return DispatchKey::Metal;
|
| 177 |
+
case Backend::Meta:
|
| 178 |
+
return DispatchKey::Meta;
|
| 179 |
+
case Backend::QuantizedCPU:
|
| 180 |
+
return DispatchKey::QuantizedCPU;
|
| 181 |
+
case Backend::QuantizedCUDA:
|
| 182 |
+
return DispatchKey::QuantizedCUDA;
|
| 183 |
+
case Backend::QuantizedPrivateUse1:
|
| 184 |
+
return DispatchKey::QuantizedPrivateUse1;
|
| 185 |
+
case Backend::Undefined:
|
| 186 |
+
return DispatchKey::Undefined;
|
| 187 |
+
case Backend::MPS:
|
| 188 |
+
return DispatchKey::MPS;
|
| 189 |
+
case Backend::HPU:
|
| 190 |
+
return DispatchKey::HPU;
|
| 191 |
+
case Backend::MTIA:
|
| 192 |
+
return DispatchKey::MTIA;
|
| 193 |
+
case Backend::PrivateUse1:
|
| 194 |
+
return DispatchKey::PrivateUse1;
|
| 195 |
+
default:
|
| 196 |
+
throw std::runtime_error("Unknown backend");
|
| 197 |
+
}
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
static inline DeviceType backendToDeviceType(Backend b) {
|
| 201 |
+
switch (b) {
|
| 202 |
+
case Backend::CPU:
|
| 203 |
+
case Backend::MkldnnCPU:
|
| 204 |
+
case Backend::SparseCPU:
|
| 205 |
+
case Backend::SparseCsrCPU:
|
| 206 |
+
case Backend::QuantizedCPU:
|
| 207 |
+
return DeviceType::CPU;
|
| 208 |
+
case Backend::CUDA:
|
| 209 |
+
case Backend::SparseCUDA:
|
| 210 |
+
case Backend::QuantizedCUDA:
|
| 211 |
+
case Backend::SparseCsrCUDA:
|
| 212 |
+
return DeviceType::CUDA;
|
| 213 |
+
case Backend::HIP:
|
| 214 |
+
return DeviceType::HIP;
|
| 215 |
+
case Backend::VE:
|
| 216 |
+
return DeviceType::VE;
|
| 217 |
+
case Backend::FPGA:
|
| 218 |
+
return DeviceType::FPGA;
|
| 219 |
+
case Backend::ORT:
|
| 220 |
+
return DeviceType::ORT;
|
| 221 |
+
case Backend::XLA:
|
| 222 |
+
return DeviceType::XLA;
|
| 223 |
+
case Backend::Lazy:
|
| 224 |
+
return DeviceType::Lazy;
|
| 225 |
+
case Backend::SparseHIP:
|
| 226 |
+
return DeviceType::HIP;
|
| 227 |
+
case Backend::SparseVE:
|
| 228 |
+
return DeviceType::VE;
|
| 229 |
+
case Backend::IPU:
|
| 230 |
+
return DeviceType::IPU;
|
| 231 |
+
case Backend::XPU:
|
| 232 |
+
case Backend::SparseXPU:
|
| 233 |
+
case Backend::QuantizedXPU:
|
| 234 |
+
return DeviceType::XPU;
|
| 235 |
+
case Backend::Vulkan:
|
| 236 |
+
return DeviceType::Vulkan;
|
| 237 |
+
case Backend::Metal:
|
| 238 |
+
return DeviceType::Metal;
|
| 239 |
+
case Backend::Meta:
|
| 240 |
+
return DeviceType::Meta;
|
| 241 |
+
case Backend::MPS:
|
| 242 |
+
return DeviceType::MPS;
|
| 243 |
+
case Backend::HPU:
|
| 244 |
+
return DeviceType::HPU;
|
| 245 |
+
case Backend::MTIA:
|
| 246 |
+
return DeviceType::MTIA;
|
| 247 |
+
case Backend::PrivateUse1:
|
| 248 |
+
case Backend::SparsePrivateUse1:
|
| 249 |
+
case Backend::QuantizedPrivateUse1:
|
| 250 |
+
return DeviceType::PrivateUse1;
|
| 251 |
+
case Backend::Undefined:
|
| 252 |
+
TORCH_CHECK(false, "Undefined backend is not a valid device type");
|
| 253 |
+
default:
|
| 254 |
+
TORCH_CHECK(false, "Unknown backend");
|
| 255 |
+
}
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
// TODO: This probably shouldn't actually be static inline
|
| 259 |
+
static inline const char* toString(Backend b) {
|
| 260 |
+
switch (b) {
|
| 261 |
+
case Backend::CPU:
|
| 262 |
+
return "CPU";
|
| 263 |
+
case Backend::CUDA:
|
| 264 |
+
return "CUDA";
|
| 265 |
+
case Backend::HIP:
|
| 266 |
+
return "HIP";
|
| 267 |
+
case Backend::VE:
|
| 268 |
+
return "VE";
|
| 269 |
+
case Backend::FPGA:
|
| 270 |
+
return "FPGA";
|
| 271 |
+
case Backend::XPU:
|
| 272 |
+
return "XPU";
|
| 273 |
+
case Backend::IPU:
|
| 274 |
+
return "IPU";
|
| 275 |
+
case Backend::ORT:
|
| 276 |
+
return "ORT";
|
| 277 |
+
case Backend::XLA:
|
| 278 |
+
return "XLA";
|
| 279 |
+
case Backend::Lazy:
|
| 280 |
+
return "Lazy";
|
| 281 |
+
case Backend::MPS:
|
| 282 |
+
return "MPS";
|
| 283 |
+
case Backend::SparseCPU:
|
| 284 |
+
return "SparseCPU";
|
| 285 |
+
case Backend::SparseCUDA:
|
| 286 |
+
return "SparseCUDA";
|
| 287 |
+
case Backend::SparseHIP:
|
| 288 |
+
return "SparseHIP";
|
| 289 |
+
case Backend::SparseVE:
|
| 290 |
+
return "SparseVE";
|
| 291 |
+
case Backend::SparseXPU:
|
| 292 |
+
return "SparseXPU";
|
| 293 |
+
case Backend::SparsePrivateUse1:
|
| 294 |
+
return "SparsePrivateUse1";
|
| 295 |
+
case Backend::SparseCsrCPU:
|
| 296 |
+
return "SparseCsrCPU";
|
| 297 |
+
case Backend::SparseCsrCUDA:
|
| 298 |
+
return "SparseCsrCUDA";
|
| 299 |
+
case Backend::MkldnnCPU:
|
| 300 |
+
return "MkldnnCPU";
|
| 301 |
+
case Backend::Vulkan:
|
| 302 |
+
return "Vulkan";
|
| 303 |
+
case Backend::Metal:
|
| 304 |
+
return "Metal";
|
| 305 |
+
case Backend::Meta:
|
| 306 |
+
return "Meta";
|
| 307 |
+
case Backend::QuantizedCPU:
|
| 308 |
+
return "QuantizedCPU";
|
| 309 |
+
case Backend::QuantizedCUDA:
|
| 310 |
+
return "QuantizedCUDA";
|
| 311 |
+
case Backend::QuantizedXPU:
|
| 312 |
+
return "QuantizedXPU";
|
| 313 |
+
case Backend::QuantizedPrivateUse1:
|
| 314 |
+
return "QuantizedPrivateUse1";
|
| 315 |
+
case Backend::HPU:
|
| 316 |
+
return "HPU";
|
| 317 |
+
case Backend::MTIA:
|
| 318 |
+
return "MTIA";
|
| 319 |
+
case Backend::PrivateUse1:
|
| 320 |
+
return "PrivateUseOne";
|
| 321 |
+
default:
|
| 322 |
+
return "UNKNOWN_BACKEND";
|
| 323 |
+
}
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
static inline bool isSparse(Backend b) {
|
| 327 |
+
switch (b) {
|
| 328 |
+
case Backend::SparseXPU:
|
| 329 |
+
case Backend::SparseCPU:
|
| 330 |
+
case Backend::SparseCUDA:
|
| 331 |
+
case Backend::SparseHIP:
|
| 332 |
+
case Backend::SparseVE:
|
| 333 |
+
case Backend::SparsePrivateUse1:
|
| 334 |
+
return true;
|
| 335 |
+
default:
|
| 336 |
+
return false;
|
| 337 |
+
}
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
static inline bool isSparseCsr(Backend b) {
|
| 341 |
+
switch (b) {
|
| 342 |
+
case Backend::SparseCsrCPU:
|
| 343 |
+
case Backend::SparseCsrCUDA:
|
| 344 |
+
return true;
|
| 345 |
+
default:
|
| 346 |
+
return false;
|
| 347 |
+
}
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/CPUAllocator.h
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <cstring>
|
| 4 |
+
#include <mutex>
|
| 5 |
+
#include <unordered_map>
|
| 6 |
+
|
| 7 |
+
#include <c10/core/Allocator.h>
|
| 8 |
+
#include <c10/util/Flags.h>
|
| 9 |
+
|
| 10 |
+
// TODO: rename to c10
|
| 11 |
+
C10_DECLARE_bool(caffe2_report_cpu_memory_usage);
|
| 12 |
+
|
| 13 |
+
namespace c10 {
|
| 14 |
+
|
| 15 |
+
using MemoryDeleter = void (*)(void*);
|
| 16 |
+
|
| 17 |
+
// A helper function that is basically doing nothing.
|
| 18 |
+
C10_API void NoDelete(void*);
|
| 19 |
+
|
| 20 |
+
// A simple struct that is used to report C10's memory allocation,
|
| 21 |
+
// deallocation status and out-of-memory events to the profiler
|
| 22 |
+
class C10_API ProfiledCPUMemoryReporter {
|
| 23 |
+
public:
|
| 24 |
+
ProfiledCPUMemoryReporter() = default;
|
| 25 |
+
void New(void* ptr, size_t nbytes);
|
| 26 |
+
void OutOfMemory(size_t nbytes);
|
| 27 |
+
void Delete(void* ptr);
|
| 28 |
+
|
| 29 |
+
private:
|
| 30 |
+
std::mutex mutex_;
|
| 31 |
+
std::unordered_map<void*, size_t> size_table_;
|
| 32 |
+
size_t allocated_ = 0;
|
| 33 |
+
size_t log_cnt_ = 0;
|
| 34 |
+
};
|
| 35 |
+
|
| 36 |
+
C10_API ProfiledCPUMemoryReporter& profiledCPUMemoryReporter();
|
| 37 |
+
|
| 38 |
+
// Get the CPU Allocator.
|
| 39 |
+
C10_API at::Allocator* GetCPUAllocator();
|
| 40 |
+
// Sets the CPU allocator to the given allocator: the caller gives away the
|
| 41 |
+
// ownership of the pointer.
|
| 42 |
+
C10_API void SetCPUAllocator(at::Allocator* alloc, uint8_t priority = 0);
|
| 43 |
+
|
| 44 |
+
// Get the Default CPU Allocator
|
| 45 |
+
C10_API at::Allocator* GetDefaultCPUAllocator();
|
| 46 |
+
|
| 47 |
+
// Get the Default Mobile CPU Allocator
|
| 48 |
+
C10_API at::Allocator* GetDefaultMobileCPUAllocator();
|
| 49 |
+
|
| 50 |
+
// The CPUCachingAllocator is experimental and might disappear in the future.
|
| 51 |
+
// The only place that uses it is in StaticRuntime.
|
| 52 |
+
// Set the CPU Caching Allocator
|
| 53 |
+
C10_API void SetCPUCachingAllocator(Allocator* alloc, uint8_t priority = 0);
|
| 54 |
+
// Get the CPU Caching Allocator
|
| 55 |
+
C10_API Allocator* GetCPUCachingAllocator();
|
| 56 |
+
|
| 57 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/CompileTimeFunctionPointer.h
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/util/TypeTraits.h>
|
| 4 |
+
|
| 5 |
+
namespace c10 {
|
| 6 |
+
|
| 7 |
+
/**
|
| 8 |
+
* Represent a function pointer as a C++ type.
|
| 9 |
+
* This allows using the function pointer as a type
|
| 10 |
+
* in a template and calling it from inside the template
|
| 11 |
+
* allows the compiler to inline the call because it
|
| 12 |
+
* knows the function pointer at compile time.
|
| 13 |
+
*
|
| 14 |
+
* Example 1:
|
| 15 |
+
* int add(int a, int b) {return a + b;}
|
| 16 |
+
* using Add = TORCH_FN_TYPE(add);
|
| 17 |
+
* template<class Func> struct Executor {
|
| 18 |
+
* int execute(int a, int b) {
|
| 19 |
+
* return Func::func_ptr()(a, b);
|
| 20 |
+
* }
|
| 21 |
+
* };
|
| 22 |
+
* Executor<Add> executor;
|
| 23 |
+
* EXPECT_EQ(3, executor.execute(1, 2));
|
| 24 |
+
*
|
| 25 |
+
* Example 2:
|
| 26 |
+
* int add(int a, int b) {return a + b;}
|
| 27 |
+
* template<class Func> int execute(Func, int a, int b) {
|
| 28 |
+
* return Func::func_ptr()(a, b);
|
| 29 |
+
* }
|
| 30 |
+
* EXPECT_EQ(3, execute(TORCH_FN(add), 1, 2));
|
| 31 |
+
*/
|
| 32 |
+
template <class FuncType_, FuncType_* func_ptr_>
|
| 33 |
+
struct CompileTimeFunctionPointer final {
|
| 34 |
+
static_assert(
|
| 35 |
+
guts::is_function_type<FuncType_>::value,
|
| 36 |
+
"TORCH_FN can only wrap function types.");
|
| 37 |
+
using FuncType = FuncType_;
|
| 38 |
+
|
| 39 |
+
static constexpr FuncType* func_ptr() {
|
| 40 |
+
return func_ptr_;
|
| 41 |
+
}
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
template <class T>
|
| 45 |
+
struct is_compile_time_function_pointer : std::false_type {};
|
| 46 |
+
template <class FuncType, FuncType* func_ptr>
|
| 47 |
+
struct is_compile_time_function_pointer<
|
| 48 |
+
CompileTimeFunctionPointer<FuncType, func_ptr>> : std::true_type {};
|
| 49 |
+
|
| 50 |
+
} // namespace c10
|
| 51 |
+
|
| 52 |
+
#define TORCH_FN_TYPE(func) \
|
| 53 |
+
::c10::CompileTimeFunctionPointer< \
|
| 54 |
+
std::remove_pointer_t<std::remove_reference_t<decltype(func)>>, \
|
| 55 |
+
func>
|
| 56 |
+
#define TORCH_FN(func) TORCH_FN_TYPE(func)()
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/ConstantSymNodeImpl.h
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <c10/core/SymNodeImpl.h>
|
| 2 |
+
#include <c10/util/variant.h>
|
| 3 |
+
|
| 4 |
+
namespace c10 {
|
| 5 |
+
|
| 6 |
+
// Unlike other SymNodeImpl, this cannot be "dispatched" conventionally,
|
| 7 |
+
// as it typically needs to defer to another SymNodeImpl
|
| 8 |
+
//
|
| 9 |
+
// Can either represent a bool, int (don't support float yet) this is useful
|
| 10 |
+
// for representing otherwise unrepresentable large negative integer constant.
|
| 11 |
+
template <typename T>
|
| 12 |
+
class C10_API ConstantSymNodeImpl : public SymNodeImpl {
|
| 13 |
+
static_assert(
|
| 14 |
+
std::is_same<T, int64_t>::value || std::is_same<T, bool>::value,
|
| 15 |
+
"ConstantSymNodeImpl can only accept int64_t or bool types");
|
| 16 |
+
|
| 17 |
+
public:
|
| 18 |
+
ConstantSymNodeImpl(T val) : value_(val) {}
|
| 19 |
+
|
| 20 |
+
bool is_int() override {
|
| 21 |
+
return std::is_same<T, int64_t>::value;
|
| 22 |
+
}
|
| 23 |
+
bool is_bool() override {
|
| 24 |
+
return std::is_same<T, bool>::value;
|
| 25 |
+
}
|
| 26 |
+
bool is_float() override {
|
| 27 |
+
return false;
|
| 28 |
+
}
|
| 29 |
+
int64_t guard_int(const char* file, int64_t line) override {
|
| 30 |
+
TORCH_CHECK(is_int(), "not an int");
|
| 31 |
+
return int_();
|
| 32 |
+
}
|
| 33 |
+
bool guard_bool(const char* file, int64_t line) override {
|
| 34 |
+
TORCH_CHECK(is_bool(), "not a bool");
|
| 35 |
+
return bool_();
|
| 36 |
+
}
|
| 37 |
+
double guard_float(const char* file, int64_t line) override {
|
| 38 |
+
TORCH_CHECK(false, "not a float");
|
| 39 |
+
}
|
| 40 |
+
int64_t int_() override {
|
| 41 |
+
TORCH_CHECK(is_int(), "not an int");
|
| 42 |
+
return c10::get<int64_t>(value_);
|
| 43 |
+
}
|
| 44 |
+
bool bool_() override {
|
| 45 |
+
TORCH_CHECK(is_bool(), "not a bool");
|
| 46 |
+
return c10::get<bool>(value_);
|
| 47 |
+
}
|
| 48 |
+
bool has_hint() override {
|
| 49 |
+
return true;
|
| 50 |
+
}
|
| 51 |
+
c10::SymNode eq(const c10::SymNode& other) override;
|
| 52 |
+
c10::SymNode ne(const c10::SymNode& other) override;
|
| 53 |
+
std::string str() override {
|
| 54 |
+
if (is_int()) {
|
| 55 |
+
return std::to_string(c10::get<int64_t>(value_));
|
| 56 |
+
} else {
|
| 57 |
+
return c10::get<bool>(value_) ? "true" : "false";
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
c10::optional<int64_t> constant_int() override {
|
| 61 |
+
if (is_int()) {
|
| 62 |
+
return c10::get<int64_t>(value_);
|
| 63 |
+
} else {
|
| 64 |
+
return c10::nullopt;
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
c10::optional<bool> constant_bool() override {
|
| 68 |
+
if (is_bool()) {
|
| 69 |
+
return c10::get<bool>(value_);
|
| 70 |
+
} else {
|
| 71 |
+
return c10::nullopt;
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
private:
|
| 76 |
+
c10::variant<int64_t, bool> value_;
|
| 77 |
+
};
|
| 78 |
+
|
| 79 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/CopyBytes.h
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/Device.h>
|
| 4 |
+
|
| 5 |
+
namespace c10 {
|
| 6 |
+
|
| 7 |
+
using CopyBytesFunction = void (*)(
|
| 8 |
+
size_t nbytes,
|
| 9 |
+
const void* src,
|
| 10 |
+
Device src_device,
|
| 11 |
+
void* dst,
|
| 12 |
+
Device dst_device);
|
| 13 |
+
|
| 14 |
+
struct C10_API _CopyBytesFunctionRegisterer {
|
| 15 |
+
_CopyBytesFunctionRegisterer(
|
| 16 |
+
DeviceType from,
|
| 17 |
+
DeviceType to,
|
| 18 |
+
CopyBytesFunction func_sync,
|
| 19 |
+
CopyBytesFunction func_async = nullptr);
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
#define REGISTER_COPY_BYTES_FUNCTION(from, to, ...) \
|
| 23 |
+
namespace { \
|
| 24 |
+
static _CopyBytesFunctionRegisterer C10_ANONYMOUS_VARIABLE( \
|
| 25 |
+
g_copy_function)(from, to, __VA_ARGS__); \
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
/*
|
| 29 |
+
* WARNING: Implementations for this function are currently registered from
|
| 30 |
+
* ATen and caffe2, not yet from c10. Don't use this if not either ATen
|
| 31 |
+
* or caffe2 is present as well.
|
| 32 |
+
* We can't move them yet, because the CUDA implementations aren't unified yet
|
| 33 |
+
* between ATen and caffe2.
|
| 34 |
+
* We're planning to move the implementations into c10/backend/xxx
|
| 35 |
+
* to make c10 self contained again.
|
| 36 |
+
*/
|
| 37 |
+
C10_API void CopyBytes(
|
| 38 |
+
size_t nbytes,
|
| 39 |
+
const void* src,
|
| 40 |
+
Device src_device,
|
| 41 |
+
void* dst,
|
| 42 |
+
Device dst_device,
|
| 43 |
+
bool async);
|
| 44 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/DefaultDtype.h
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/ScalarType.h>
|
| 4 |
+
#include <c10/macros/Export.h>
|
| 5 |
+
|
| 6 |
+
namespace caffe2 {
|
| 7 |
+
class TypeMeta;
|
| 8 |
+
} // namespace caffe2
|
| 9 |
+
|
| 10 |
+
namespace c10 {
|
| 11 |
+
C10_API void set_default_dtype(caffe2::TypeMeta dtype);
|
| 12 |
+
C10_API const caffe2::TypeMeta get_default_dtype();
|
| 13 |
+
C10_API ScalarType get_default_dtype_as_scalartype();
|
| 14 |
+
C10_API const caffe2::TypeMeta get_default_complex_dtype();
|
| 15 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/DefaultTensorOptions.h
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/Backend.h>
|
| 4 |
+
#include <c10/core/Device.h>
|
| 5 |
+
#include <c10/core/Layout.h>
|
| 6 |
+
#include <c10/core/ScalarType.h>
|
| 7 |
+
|
| 8 |
+
namespace c10 {
|
| 9 |
+
|
| 10 |
+
struct TensorOptions;
|
| 11 |
+
|
| 12 |
+
/// Like TensorOptions, but all fields are guaranteed to be filled.
|
| 13 |
+
struct DefaultTensorOptions {
|
| 14 |
+
DefaultTensorOptions() = default;
|
| 15 |
+
|
| 16 |
+
caffe2::TypeMeta dtype() const noexcept {
|
| 17 |
+
return dtype_;
|
| 18 |
+
}
|
| 19 |
+
Device device() const noexcept {
|
| 20 |
+
return device_;
|
| 21 |
+
}
|
| 22 |
+
Layout layout() const noexcept {
|
| 23 |
+
return layout_;
|
| 24 |
+
}
|
| 25 |
+
bool requires_grad() const noexcept {
|
| 26 |
+
return requires_grad_;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
// Defined in TensorOptions.h
|
| 30 |
+
inline DefaultTensorOptions& merge(const TensorOptions& options);
|
| 31 |
+
|
| 32 |
+
private:
|
| 33 |
+
caffe2::TypeMeta dtype_ = caffe2::TypeMeta::Make<float>(); // 64-bit
|
| 34 |
+
Device device_ = at::kCPU; // 32-bit
|
| 35 |
+
Layout layout_ = at::kStrided; // 8-bit
|
| 36 |
+
bool requires_grad_ = false; // 8-bit
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
inline const DefaultTensorOptions& getDefaultTensorOptions() {
|
| 40 |
+
static const auto options = DefaultTensorOptions();
|
| 41 |
+
return options;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/Device.h
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/DeviceType.h>
|
| 4 |
+
#include <c10/macros/Export.h>
|
| 5 |
+
#include <c10/util/Exception.h>
|
| 6 |
+
|
| 7 |
+
#include <cstddef>
|
| 8 |
+
#include <functional>
|
| 9 |
+
#include <iosfwd>
|
| 10 |
+
#include <string>
|
| 11 |
+
|
| 12 |
+
namespace c10 {
|
| 13 |
+
|
| 14 |
+
/// An index representing a specific device; e.g., the 1 in GPU 1.
|
| 15 |
+
/// A DeviceIndex is not independently meaningful without knowing
|
| 16 |
+
/// the DeviceType it is associated; try to use Device rather than
|
| 17 |
+
/// DeviceIndex directly.
|
| 18 |
+
using DeviceIndex = int8_t;
|
| 19 |
+
|
| 20 |
+
/// Represents a compute device on which a tensor is located. A device is
|
| 21 |
+
/// uniquely identified by a type, which specifies the type of machine it is
|
| 22 |
+
/// (e.g. CPU or CUDA GPU), and a device index or ordinal, which identifies the
|
| 23 |
+
/// specific compute device when there is more than one of a certain type. The
|
| 24 |
+
/// device index is optional, and in its defaulted state represents (abstractly)
|
| 25 |
+
/// "the current device". Further, there are two constraints on the value of the
|
| 26 |
+
/// device index, if one is explicitly stored:
|
| 27 |
+
/// 1. A negative index represents the current device, a non-negative index
|
| 28 |
+
/// represents a specific, concrete device,
|
| 29 |
+
/// 2. When the device type is CPU, the device index must be zero.
|
| 30 |
+
struct C10_API Device final {
|
| 31 |
+
using Type = DeviceType;
|
| 32 |
+
|
| 33 |
+
/// Constructs a new `Device` from a `DeviceType` and an optional device
|
| 34 |
+
/// index.
|
| 35 |
+
/* implicit */ Device(DeviceType type, DeviceIndex index = -1)
|
| 36 |
+
: type_(type), index_(index) {
|
| 37 |
+
validate();
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
/// Constructs a `Device` from a string description, for convenience.
|
| 41 |
+
/// The string supplied must follow the following schema:
|
| 42 |
+
/// `(cpu|cuda)[:<device-index>]`
|
| 43 |
+
/// where `cpu` or `cuda` specifies the device type, and
|
| 44 |
+
/// `:<device-index>` optionally specifies a device index.
|
| 45 |
+
/* implicit */ Device(const std::string& device_string);
|
| 46 |
+
|
| 47 |
+
/// Returns true if the type and index of this `Device` matches that of
|
| 48 |
+
/// `other`.
|
| 49 |
+
bool operator==(const Device& other) const noexcept {
|
| 50 |
+
return this->type_ == other.type_ && this->index_ == other.index_;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
/// Returns true if the type or index of this `Device` differs from that of
|
| 54 |
+
/// `other`.
|
| 55 |
+
bool operator!=(const Device& other) const noexcept {
|
| 56 |
+
return !(*this == other);
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
/// Sets the device index.
|
| 60 |
+
void set_index(DeviceIndex index) {
|
| 61 |
+
index_ = index;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
/// Returns the type of device this is.
|
| 65 |
+
DeviceType type() const noexcept {
|
| 66 |
+
return type_;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
/// Returns the optional index.
|
| 70 |
+
DeviceIndex index() const noexcept {
|
| 71 |
+
return index_;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
/// Returns true if the device has a non-default index.
|
| 75 |
+
bool has_index() const noexcept {
|
| 76 |
+
return index_ != -1;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
/// Return true if the device is of CUDA type.
|
| 80 |
+
bool is_cuda() const noexcept {
|
| 81 |
+
return type_ == DeviceType::CUDA;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
/// Return true if the device is of PrivateUse1 type.
|
| 85 |
+
bool is_privateuseone() const noexcept {
|
| 86 |
+
return type_ == DeviceType::PrivateUse1;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
/// Return true if the device is of MPS type.
|
| 90 |
+
bool is_mps() const noexcept {
|
| 91 |
+
return type_ == DeviceType::MPS;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
/// Return true if the device is of HIP type.
|
| 95 |
+
bool is_hip() const noexcept {
|
| 96 |
+
return type_ == DeviceType::HIP;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
/// Return true if the device is of VE type.
|
| 100 |
+
bool is_ve() const noexcept {
|
| 101 |
+
return type_ == DeviceType::VE;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
/// Return true if the device is of XPU type.
|
| 105 |
+
bool is_xpu() const noexcept {
|
| 106 |
+
return type_ == DeviceType::XPU;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
/// Return true if the device is of IPU type.
|
| 110 |
+
bool is_ipu() const noexcept {
|
| 111 |
+
return type_ == DeviceType::IPU;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
/// Return true if the device is of XLA type.
|
| 115 |
+
bool is_xla() const noexcept {
|
| 116 |
+
return type_ == DeviceType::XLA;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
/// Return true if the device is of MTIA type.
|
| 120 |
+
bool is_mtia() const noexcept {
|
| 121 |
+
return type_ == DeviceType::MTIA;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
/// Return true if the device is of HPU type.
|
| 125 |
+
bool is_hpu() const noexcept {
|
| 126 |
+
return type_ == DeviceType::HPU;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
/// Return true if the device is of Lazy type.
|
| 130 |
+
bool is_lazy() const noexcept {
|
| 131 |
+
return type_ == DeviceType::Lazy;
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
/// Return true if the device is of Vulkan type.
|
| 135 |
+
bool is_vulkan() const noexcept {
|
| 136 |
+
return type_ == DeviceType::Vulkan;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
/// Return true if the device is of Metal type.
|
| 140 |
+
bool is_metal() const noexcept {
|
| 141 |
+
return type_ == DeviceType::Metal;
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
/// Return true if the device is of ORT type.
|
| 145 |
+
bool is_ort() const noexcept {
|
| 146 |
+
return type_ == DeviceType::ORT;
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
/// Return true if the device is of META type.
|
| 150 |
+
bool is_meta() const noexcept {
|
| 151 |
+
return type_ == DeviceType::Meta;
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
/// Return true if the device is of CPU type.
|
| 155 |
+
bool is_cpu() const noexcept {
|
| 156 |
+
return type_ == DeviceType::CPU;
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
/// Return true if the device supports arbitrary strides.
|
| 160 |
+
bool supports_as_strided() const noexcept {
|
| 161 |
+
return type_ != DeviceType::IPU && type_ != DeviceType::XLA &&
|
| 162 |
+
type_ != DeviceType::Lazy && type_ != DeviceType::MTIA;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
/// Same string as returned from operator<<.
|
| 166 |
+
std::string str() const;
|
| 167 |
+
|
| 168 |
+
private:
|
| 169 |
+
DeviceType type_;
|
| 170 |
+
DeviceIndex index_ = -1;
|
| 171 |
+
void validate() {
|
| 172 |
+
// Removing these checks in release builds noticeably improves
|
| 173 |
+
// performance in micro-benchmarks.
|
| 174 |
+
// This is safe to do, because backends that use the DeviceIndex
|
| 175 |
+
// have a later check when we actually try to switch to that device.
|
| 176 |
+
TORCH_INTERNAL_ASSERT_DEBUG_ONLY(
|
| 177 |
+
index_ >= -1,
|
| 178 |
+
"Device index must be -1 or non-negative, got ",
|
| 179 |
+
static_cast<int>(index_));
|
| 180 |
+
TORCH_INTERNAL_ASSERT_DEBUG_ONLY(
|
| 181 |
+
!is_cpu() || index_ <= 0,
|
| 182 |
+
"CPU device index must be -1 or zero, got ",
|
| 183 |
+
static_cast<int>(index_));
|
| 184 |
+
}
|
| 185 |
+
};
|
| 186 |
+
|
| 187 |
+
C10_API std::ostream& operator<<(std::ostream& stream, const Device& device);
|
| 188 |
+
|
| 189 |
+
} // namespace c10
|
| 190 |
+
|
| 191 |
+
namespace std {
|
| 192 |
+
template <>
|
| 193 |
+
struct hash<c10::Device> {
|
| 194 |
+
size_t operator()(c10::Device d) const noexcept {
|
| 195 |
+
// Are you here because this static assert failed? Make sure you ensure
|
| 196 |
+
// that the bitmasking code below is updated accordingly!
|
| 197 |
+
static_assert(sizeof(c10::DeviceType) == 1, "DeviceType is not 8-bit");
|
| 198 |
+
static_assert(sizeof(c10::DeviceIndex) == 1, "DeviceIndex is not 8-bit");
|
| 199 |
+
// Note [Hazard when concatenating signed integers]
|
| 200 |
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 201 |
+
// We must first convert to a same-sized unsigned type, before promoting to
|
| 202 |
+
// the result type, to prevent sign extension when any of the values is -1.
|
| 203 |
+
// If sign extension occurs, you'll clobber all of the values in the MSB
|
| 204 |
+
// half of the resulting integer.
|
| 205 |
+
//
|
| 206 |
+
// Technically, by C/C++ integer promotion rules, we only need one of the
|
| 207 |
+
// uint32_t casts to the result type, but we put in both for explicitness's
|
| 208 |
+
// sake.
|
| 209 |
+
uint32_t bits = static_cast<uint32_t>(static_cast<uint8_t>(d.type()))
|
| 210 |
+
<< 16 |
|
| 211 |
+
static_cast<uint32_t>(static_cast<uint8_t>(d.index()));
|
| 212 |
+
return std::hash<uint32_t>{}(bits);
|
| 213 |
+
}
|
| 214 |
+
};
|
| 215 |
+
} // namespace std
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/DeviceArray.h
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <c10/core/Allocator.h>
|
| 2 |
+
|
| 3 |
+
namespace c10 {
|
| 4 |
+
|
| 5 |
+
template <typename T>
|
| 6 |
+
class DeviceArray {
|
| 7 |
+
public:
|
| 8 |
+
DeviceArray(c10::Allocator& allocator, size_t size)
|
| 9 |
+
: data_ptr_(allocator.allocate(size * sizeof(T))) {
|
| 10 |
+
static_assert(std::is_trivial<T>::value, "T must be a trivial type");
|
| 11 |
+
TORCH_INTERNAL_ASSERT(
|
| 12 |
+
0 == (reinterpret_cast<intptr_t>(data_ptr_.get()) % alignof(T)),
|
| 13 |
+
"c10::DeviceArray: Allocated memory is not aligned for this data type");
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
T* get() {
|
| 17 |
+
return static_cast<T*>(data_ptr_.get());
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
private:
|
| 21 |
+
c10::DataPtr data_ptr_;
|
| 22 |
+
};
|
| 23 |
+
|
| 24 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/DeviceGuard.h
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/impl/InlineDeviceGuard.h>
|
| 4 |
+
|
| 5 |
+
namespace c10 {
|
| 6 |
+
|
| 7 |
+
/// RAII guard that sets a certain default device in its constructor, and
|
| 8 |
+
/// changes it back to the device that was originally active upon destruction.
|
| 9 |
+
///
|
| 10 |
+
/// The device is always reset to the one that was active at the time of
|
| 11 |
+
/// construction of the guard. Even if you `set_device` after construction, the
|
| 12 |
+
/// destructor will still reset the device to the one that was active at
|
| 13 |
+
/// construction time.
|
| 14 |
+
///
|
| 15 |
+
/// This device guard does NOT have an uninitialized state; it is guaranteed
|
| 16 |
+
/// to reset a device on exit. If you are in a situation where you *might*
|
| 17 |
+
/// want to setup a guard (i.e., are looking for the moral equivalent
|
| 18 |
+
/// of optional<DeviceGuard>), see OptionalDeviceGuard.
|
| 19 |
+
class DeviceGuard {
|
| 20 |
+
public:
|
| 21 |
+
/// No default constructor; see Note [Omitted default constructor from RAII]
|
| 22 |
+
explicit DeviceGuard() = delete;
|
| 23 |
+
|
| 24 |
+
/// Set the current device to the passed Device.
|
| 25 |
+
explicit DeviceGuard(Device device) : guard_(device) {}
|
| 26 |
+
|
| 27 |
+
/// This constructor is for testing only.
|
| 28 |
+
explicit DeviceGuard(
|
| 29 |
+
Device device,
|
| 30 |
+
const impl::DeviceGuardImplInterface* impl)
|
| 31 |
+
: guard_(device, impl) {}
|
| 32 |
+
|
| 33 |
+
/// Copy is disallowed
|
| 34 |
+
DeviceGuard(const DeviceGuard&) = delete;
|
| 35 |
+
DeviceGuard& operator=(const DeviceGuard&) = delete;
|
| 36 |
+
|
| 37 |
+
/// Move is disallowed, as DeviceGuard does not have an uninitialized state,
|
| 38 |
+
/// which is required for moves on types with nontrivial destructors.
|
| 39 |
+
DeviceGuard(DeviceGuard&& other) = delete;
|
| 40 |
+
DeviceGuard& operator=(DeviceGuard&& other) = delete;
|
| 41 |
+
|
| 42 |
+
/// Sets the device to the given one. The specified device must be consistent
|
| 43 |
+
/// with the device type originally specified during guard construction.
|
| 44 |
+
///
|
| 45 |
+
/// TODO: The consistency check here is inconsistent with StreamGuard's
|
| 46 |
+
/// behavior with set_stream, where a stream on a different device than
|
| 47 |
+
/// the original one isn't an error; we just reset the stream and then
|
| 48 |
+
/// switch devices.
|
| 49 |
+
void reset_device(at::Device device) {
|
| 50 |
+
guard_.reset_device(device);
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
/// This method is for testing only.
|
| 54 |
+
void reset_device(
|
| 55 |
+
at::Device device,
|
| 56 |
+
const impl::DeviceGuardImplInterface* impl) {
|
| 57 |
+
guard_.reset_device(device, impl);
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
/// Sets the device index to the given one. The device type is inferred
|
| 61 |
+
/// from the original device type the guard was constructed with.
|
| 62 |
+
void set_index(DeviceIndex index) {
|
| 63 |
+
guard_.set_index(index);
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
/// Returns the device that was set at the time the guard was constructed.
|
| 67 |
+
Device original_device() const {
|
| 68 |
+
return guard_.original_device();
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
/// Returns the most recent device that was set using this device guard,
|
| 72 |
+
/// either from construction, or via set_device.
|
| 73 |
+
Device current_device() const {
|
| 74 |
+
return guard_.current_device();
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
private:
|
| 78 |
+
impl::InlineDeviceGuard<impl::VirtualGuardImpl> guard_;
|
| 79 |
+
};
|
| 80 |
+
|
| 81 |
+
/**
|
| 82 |
+
* A OptionalDeviceGuard is an RAII class that sets a device to some value on
|
| 83 |
+
* initialization, and resets the device to its original value on destruction.
|
| 84 |
+
* Morally, a OptionalDeviceGuard is equivalent to optional<DeviceGuard>, but
|
| 85 |
+
* with extra constructors and methods as appropriate.
|
| 86 |
+
*
|
| 87 |
+
* Besides its obvious use (optionally applying a DeviceGuard),
|
| 88 |
+
* OptionalDeviceGuard is often also used for the following idiom:
|
| 89 |
+
*
|
| 90 |
+
* OptionalDeviceGuard g;
|
| 91 |
+
* for (const auto& t : tensors) {
|
| 92 |
+
* g.set_device(t.device());
|
| 93 |
+
* do_something_with(t);
|
| 94 |
+
* }
|
| 95 |
+
*
|
| 96 |
+
* This usage is marginally more efficient than constructing a DeviceGuard every
|
| 97 |
+
* iteration of the for loop, as it avoids an unnecessary device reset.
|
| 98 |
+
*
|
| 99 |
+
* Unlike DeviceGuard, a OptionalDeviceGuard may be uninitialized. This occurs
|
| 100 |
+
* when you use the nullary constructor, or pass a nullopt to the constructor.
|
| 101 |
+
* Uninitialized OptionalDeviceGuards do *nothing*; they do not know what the
|
| 102 |
+
* original device was and they do not reset on destruction. This is why
|
| 103 |
+
* original_device() and current_device() return optional<Device> rather than
|
| 104 |
+
* Device (as they do in DeviceGuard), and also is why we didn't just
|
| 105 |
+
* provide OptionalDeviceGuard by default and hide DeviceGuard from users.
|
| 106 |
+
*
|
| 107 |
+
* The semantics of an OptionalDeviceGuard are exactly explained by thinking
|
| 108 |
+
* of it as an optional<DeviceGuard>. In particular, an initialized
|
| 109 |
+
* OptionalDeviceGuard doesn't restore device to its value at construction; it
|
| 110 |
+
* restores device to its value *at initialization*. So if you have the
|
| 111 |
+
* program:
|
| 112 |
+
*
|
| 113 |
+
* setDevice(1);
|
| 114 |
+
* OptionalDeviceGuard g;
|
| 115 |
+
* setDevice(2);
|
| 116 |
+
* g.reset_device(Device(DeviceType::CUDA, 3)); // initializes!
|
| 117 |
+
*
|
| 118 |
+
* On destruction, g will reset device to 2, rather than 1.
|
| 119 |
+
*
|
| 120 |
+
* An uninitialized OptionalDeviceGuard is distinct from a (initialized)
|
| 121 |
+
* DeviceGuard whose original_device_ and current_device_ match, since the
|
| 122 |
+
* DeviceGuard will still reset the device to original_device_.
|
| 123 |
+
*/
|
| 124 |
+
class OptionalDeviceGuard {
|
| 125 |
+
public:
|
| 126 |
+
/// Create an uninitialized guard. Set the guard later using reset_device.
|
| 127 |
+
explicit OptionalDeviceGuard() = default;
|
| 128 |
+
|
| 129 |
+
/// Initialize the guard, setting the current device to the passed Device.
|
| 130 |
+
explicit OptionalDeviceGuard(Device device) : guard_(device) {}
|
| 131 |
+
|
| 132 |
+
/// Initialize the guard if a Device is passed; otherwise leave the
|
| 133 |
+
/// guard uninitialized.
|
| 134 |
+
explicit OptionalDeviceGuard(optional<Device> device) : guard_(device) {}
|
| 135 |
+
|
| 136 |
+
/// Constructor for testing only.
|
| 137 |
+
explicit OptionalDeviceGuard(
|
| 138 |
+
Device device,
|
| 139 |
+
const impl::DeviceGuardImplInterface* impl)
|
| 140 |
+
: guard_(device, impl) {}
|
| 141 |
+
|
| 142 |
+
/// Copy is disallowed
|
| 143 |
+
OptionalDeviceGuard(const OptionalDeviceGuard&) = delete;
|
| 144 |
+
OptionalDeviceGuard& operator=(const OptionalDeviceGuard&) = delete;
|
| 145 |
+
|
| 146 |
+
/// Move is disallowed
|
| 147 |
+
/// See Note [Explicit initialization of optional fields]
|
| 148 |
+
/// and // Note [Move construction for RAII guards is tricky]
|
| 149 |
+
/// for rationale.
|
| 150 |
+
OptionalDeviceGuard(OptionalDeviceGuard&& other) = delete;
|
| 151 |
+
OptionalDeviceGuard& operator=(OptionalDeviceGuard&& other) = delete;
|
| 152 |
+
|
| 153 |
+
/// Sets the device to the given one. The specified device must be consistent
|
| 154 |
+
/// with the device type originally specified during guard construction.
|
| 155 |
+
void reset_device(at::Device device) {
|
| 156 |
+
guard_.reset_device(device);
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
/// For testing only
|
| 160 |
+
void reset_device(
|
| 161 |
+
at::Device device,
|
| 162 |
+
const impl::DeviceGuardImplInterface* impl) {
|
| 163 |
+
guard_.reset_device(device, impl);
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
/// Returns the device that was set at the time the guard was constructed.
|
| 167 |
+
optional<Device> original_device() const {
|
| 168 |
+
return guard_.original_device();
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
/// Returns the most recent device that was set using this device guard,
|
| 172 |
+
/// either from construction, or via reset_device.
|
| 173 |
+
optional<Device> current_device() const {
|
| 174 |
+
return guard_.current_device();
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
private:
|
| 178 |
+
impl::InlineOptionalDeviceGuard<impl::VirtualGuardImpl> guard_{};
|
| 179 |
+
};
|
| 180 |
+
|
| 181 |
+
// Note [Whither the DeviceGuard boilerplate]
|
| 182 |
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 183 |
+
// Design note: in principle, we could avoid these wrappers using:
|
| 184 |
+
//
|
| 185 |
+
// using DeviceGuard = impl::InlineDeviceGuard<impl::VirtualGuardImpl>;
|
| 186 |
+
// using OptionalDeviceGuard =
|
| 187 |
+
// impl::InlineOptionalDeviceGuard<impl::VirtualGuardImpl>;
|
| 188 |
+
//
|
| 189 |
+
// But the error messages are worse, and our users can't just look at the
|
| 190 |
+
// header file to find out what's going on. Furthermore, for specializations
|
| 191 |
+
// like CUDAStreamGuard, it can be profitable to replace some interfaces with
|
| 192 |
+
// refined types (e.g., return CUDAStream instead of Stream). So, we eat
|
| 193 |
+
// the boilerplate and write out the API explicitly.
|
| 194 |
+
|
| 195 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/DeviceType.h
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
// This is directly synchronized with caffe2/proto/caffe2.proto, but
|
| 4 |
+
// doesn't require me to figure out how to get Protobuf headers into
|
| 5 |
+
// ATen/core (which would require a lot more build system hacking.)
|
| 6 |
+
// If you modify me, keep me synchronized with that file.
|
| 7 |
+
|
| 8 |
+
#include <c10/macros/Export.h>
|
| 9 |
+
|
| 10 |
+
#include <functional>
|
| 11 |
+
#include <ostream>
|
| 12 |
+
|
| 13 |
+
namespace c10 {
|
| 14 |
+
|
| 15 |
+
// These contains all device types that also have a BackendComponent
|
| 16 |
+
// and therefore participate in per-backend functionality dispatch keys.
|
| 17 |
+
// This is most backends except PrivateUse2 and PrivateUse3
|
| 18 |
+
#define C10_FORALL_BACKEND_DEVICE_TYPES(_, extra) \
|
| 19 |
+
_(CPU, extra) \
|
| 20 |
+
_(CUDA, extra) \
|
| 21 |
+
_(HIP, extra) \
|
| 22 |
+
_(XLA, extra) \
|
| 23 |
+
_(MPS, extra) \
|
| 24 |
+
_(IPU, extra) \
|
| 25 |
+
_(XPU, extra) \
|
| 26 |
+
_(HPU, extra) \
|
| 27 |
+
_(VE, extra) \
|
| 28 |
+
_(Lazy, extra) \
|
| 29 |
+
_(Meta, extra) \
|
| 30 |
+
_(MTIA, extra) \
|
| 31 |
+
_(PrivateUse1, extra)
|
| 32 |
+
|
| 33 |
+
enum class DeviceType : int8_t {
|
| 34 |
+
CPU = 0,
|
| 35 |
+
CUDA = 1, // CUDA.
|
| 36 |
+
MKLDNN = 2, // Reserved for explicit MKLDNN
|
| 37 |
+
OPENGL = 3, // OpenGL
|
| 38 |
+
OPENCL = 4, // OpenCL
|
| 39 |
+
IDEEP = 5, // IDEEP.
|
| 40 |
+
HIP = 6, // AMD HIP
|
| 41 |
+
FPGA = 7, // FPGA
|
| 42 |
+
ORT = 8, // ONNX Runtime / Microsoft
|
| 43 |
+
XLA = 9, // XLA / TPU
|
| 44 |
+
Vulkan = 10, // Vulkan
|
| 45 |
+
Metal = 11, // Metal
|
| 46 |
+
XPU = 12, // XPU
|
| 47 |
+
MPS = 13, // MPS
|
| 48 |
+
Meta = 14, // Meta (tensors with no data)
|
| 49 |
+
HPU = 15, // HPU / HABANA
|
| 50 |
+
VE = 16, // SX-Aurora / NEC
|
| 51 |
+
Lazy = 17, // Lazy Tensors
|
| 52 |
+
IPU = 18, // Graphcore IPU
|
| 53 |
+
MTIA = 19, // Meta training and inference devices
|
| 54 |
+
PrivateUse1 = 20, // PrivateUse1 device
|
| 55 |
+
// NB: If you add more devices:
|
| 56 |
+
// - Change the implementations of DeviceTypeName and isValidDeviceType
|
| 57 |
+
// in DeviceType.cpp
|
| 58 |
+
// - Change the number below
|
| 59 |
+
COMPILE_TIME_MAX_DEVICE_TYPES = 21,
|
| 60 |
+
};
|
| 61 |
+
|
| 62 |
+
constexpr DeviceType kCPU = DeviceType::CPU;
|
| 63 |
+
constexpr DeviceType kCUDA = DeviceType::CUDA;
|
| 64 |
+
constexpr DeviceType kHIP = DeviceType::HIP;
|
| 65 |
+
constexpr DeviceType kFPGA = DeviceType::FPGA;
|
| 66 |
+
constexpr DeviceType kORT = DeviceType::ORT;
|
| 67 |
+
constexpr DeviceType kXLA = DeviceType::XLA;
|
| 68 |
+
constexpr DeviceType kMPS = DeviceType::MPS;
|
| 69 |
+
constexpr DeviceType kMeta = DeviceType::Meta;
|
| 70 |
+
constexpr DeviceType kVulkan = DeviceType::Vulkan;
|
| 71 |
+
constexpr DeviceType kMetal = DeviceType::Metal;
|
| 72 |
+
constexpr DeviceType kXPU = DeviceType::XPU;
|
| 73 |
+
constexpr DeviceType kHPU = DeviceType::HPU;
|
| 74 |
+
constexpr DeviceType kVE = DeviceType::VE;
|
| 75 |
+
constexpr DeviceType kLazy = DeviceType::Lazy;
|
| 76 |
+
constexpr DeviceType kIPU = DeviceType::IPU;
|
| 77 |
+
constexpr DeviceType kMTIA = DeviceType::MTIA;
|
| 78 |
+
constexpr DeviceType kPrivateUse1 = DeviceType::PrivateUse1;
|
| 79 |
+
|
| 80 |
+
// define explicit int constant
|
| 81 |
+
constexpr int COMPILE_TIME_MAX_DEVICE_TYPES =
|
| 82 |
+
static_cast<int>(DeviceType::COMPILE_TIME_MAX_DEVICE_TYPES);
|
| 83 |
+
|
| 84 |
+
static_assert(
|
| 85 |
+
COMPILE_TIME_MAX_DEVICE_TYPES <= 21,
|
| 86 |
+
"Hey! You seem to be adding a lot of new DeviceTypes. The intent was "
|
| 87 |
+
"for this constant to reflect the actual number of DeviceTypes we support "
|
| 88 |
+
"in PyTorch; it's important that this number is not too large as we "
|
| 89 |
+
"use this to allocate stack arrays in some places in our code. If you "
|
| 90 |
+
"are indeed just adding the 20th device type, feel free to change "
|
| 91 |
+
"the check to 32; but if you are adding some sort of extensible device "
|
| 92 |
+
"types registration, please be aware that you are affecting code that "
|
| 93 |
+
"this number is small. Try auditing uses of this constant.");
|
| 94 |
+
|
| 95 |
+
C10_API std::string DeviceTypeName(DeviceType d, bool lower_case = false);
|
| 96 |
+
|
| 97 |
+
C10_API bool isValidDeviceType(DeviceType d);
|
| 98 |
+
|
| 99 |
+
C10_API std::ostream& operator<<(std::ostream& stream, DeviceType type);
|
| 100 |
+
|
| 101 |
+
C10_API void register_privateuse1_backend(const std::string& backend_name);
|
| 102 |
+
C10_API std::string get_privateuse1_backend(bool lower_case = true);
|
| 103 |
+
|
| 104 |
+
} // namespace c10
|
| 105 |
+
|
| 106 |
+
namespace std {
|
| 107 |
+
template <>
|
| 108 |
+
struct hash<c10::DeviceType> {
|
| 109 |
+
std::size_t operator()(c10::DeviceType k) const {
|
| 110 |
+
return std::hash<int>()(static_cast<int>(k));
|
| 111 |
+
}
|
| 112 |
+
};
|
| 113 |
+
} // namespace std
|
| 114 |
+
|
| 115 |
+
namespace torch {
|
| 116 |
+
using c10::DeviceType;
|
| 117 |
+
}
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/DispatchKey.h
ADDED
|
@@ -0,0 +1,728 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/DeviceType.h>
|
| 4 |
+
#include <c10/macros/Export.h>
|
| 5 |
+
#include <cstdint>
|
| 6 |
+
#include <ostream>
|
| 7 |
+
#include <string>
|
| 8 |
+
|
| 9 |
+
namespace c10 {
|
| 10 |
+
|
| 11 |
+
// Semantically, each value of BackendComponent identifies a "backend" for our
|
| 12 |
+
// dispatch. Some functionalities that we may dispatch to are allowed to
|
| 13 |
+
// register different handlers for each backend. The BackendComponent is then
|
| 14 |
+
// used to figure out which backend implementation to dispatch to.
|
| 15 |
+
|
| 16 |
+
// In implementation terms, the backend component identifies a specific "bit" in
|
| 17 |
+
// a DispatchKeySet. The bits in the DispatchKeySet are split between the bottom
|
| 18 |
+
// ~12 "BackendComponent" bits, while the remaining upper bits are assigned to
|
| 19 |
+
// functionalities. When we encounter a functionality bit that is known to be
|
| 20 |
+
// customizeable per-backend, then we also look at the lower BackendComponent
|
| 21 |
+
// bits and take the highest bit to determine which backend's implementation to
|
| 22 |
+
// use.
|
| 23 |
+
|
| 24 |
+
// WARNING! If you add a new backend component to the end of this list,
|
| 25 |
+
// make sure you register it before Meta.
|
| 26 |
+
// Meta must be at the end so that meta key in tls triggers meta kernels.
|
| 27 |
+
// (But you shouldn't: private use keys should have higher precedence than all
|
| 28 |
+
// built-in keys)
|
| 29 |
+
|
| 30 |
+
// If you add a new (non-privateuse) backend here,
|
| 31 |
+
// make sure to add an Autograd<Backend> fallthrough kernel
|
| 32 |
+
// in aten/src/ATen/core/VariableFallbackKernel.cpp
|
| 33 |
+
|
| 34 |
+
#define C10_FORALL_BACKEND_COMPONENTS(_, extra) \
|
| 35 |
+
_(CPU, extra) \
|
| 36 |
+
_(CUDA, extra) \
|
| 37 |
+
_(HIP, extra) \
|
| 38 |
+
_(XLA, extra) \
|
| 39 |
+
_(MPS, extra) \
|
| 40 |
+
_(IPU, extra) \
|
| 41 |
+
_(XPU, extra) \
|
| 42 |
+
_(HPU, extra) \
|
| 43 |
+
_(VE, extra) \
|
| 44 |
+
_(Lazy, extra) \
|
| 45 |
+
_(MTIA, extra) \
|
| 46 |
+
_(PrivateUse1, extra) \
|
| 47 |
+
_(PrivateUse2, extra) \
|
| 48 |
+
_(PrivateUse3, extra) \
|
| 49 |
+
_(Meta, extra)
|
| 50 |
+
|
| 51 |
+
// WARNING! If we add a new per-backend functionality key that has higher
|
| 52 |
+
// priority than Autograd, then make sure you update EndOfRuntimeBackendKeys
|
| 53 |
+
|
| 54 |
+
#define C10_FORALL_FUNCTIONALITY_KEYS(_) \
|
| 55 |
+
_(Dense, ) \
|
| 56 |
+
_(Quantized, Quantized) \
|
| 57 |
+
_(Sparse, Sparse) \
|
| 58 |
+
_(NestedTensor, NestedTensor) \
|
| 59 |
+
_(AutogradFunctionality, Autograd)
|
| 60 |
+
|
| 61 |
+
enum class BackendComponent : uint8_t {
|
| 62 |
+
|
| 63 |
+
// A "backend" is colloquially used to refer to handlers for dispatch
|
| 64 |
+
// which actually implement the numerics of an operation in question.
|
| 65 |
+
//
|
| 66 |
+
// Due to the nature of the enum, these backends are specified in
|
| 67 |
+
// an ordered way, but for most backends this order is not semantically
|
| 68 |
+
// meaningful (e.g., it's valid to reorder these backends without changing
|
| 69 |
+
// semantics). The only situation when backend ordering is meaningful
|
| 70 |
+
// is when the backend participates in multiple dispatch with another
|
| 71 |
+
// backend; e.g., CPU and CUDA (cuda must have higher priority).
|
| 72 |
+
|
| 73 |
+
// These keys don't correspond to individual kernels.
|
| 74 |
+
// Instead, they represent the backends that are allowed to override specific
|
| 75 |
+
// pieces of functionality:
|
| 76 |
+
// - dense kernels (e.g. DispatchKey::CPU)
|
| 77 |
+
// - sparse kernels (e.g. DispatchKey::SparseCPU)
|
| 78 |
+
// - quantized kernels (e.g. DispatchKey::QuantizedCPU)
|
| 79 |
+
// - autograd kernels (e.g. DispatchKey::AutogradCPU)
|
| 80 |
+
// We reserve space in the runtime operator table for this full cross product
|
| 81 |
+
// of
|
| 82 |
+
// [backends in this enum] x [keys below that are explicitly marked as having
|
| 83 |
+
// per-backend functionality]
|
| 84 |
+
//
|
| 85 |
+
// A meta tensor is a tensor without any data associated with it. (They
|
| 86 |
+
// have also colloquially been referred to as tensors on the "null" device).
|
| 87 |
+
// A meta tensor can be used to dry run operators without actually doing any
|
| 88 |
+
// computation, e.g., add on two meta tensors would give you another meta
|
| 89 |
+
// tensor with the output shape and dtype, but wouldn't actually add anything.
|
| 90 |
+
|
| 91 |
+
InvalidBit = 0,
|
| 92 |
+
#define DEFINE_BACKEND_COMPONENT(n, _) n##Bit,
|
| 93 |
+
C10_FORALL_BACKEND_COMPONENTS(DEFINE_BACKEND_COMPONENT, unused)
|
| 94 |
+
#undef DEFINE_BACKEND_COMPONENT
|
| 95 |
+
|
| 96 |
+
// Define an alias to represent end of backend dispatch keys.
|
| 97 |
+
// If you add new backend keys after PrivateUse3, please also update it here.
|
| 98 |
+
EndOfBackendKeys = MetaBit,
|
| 99 |
+
};
|
| 100 |
+
|
| 101 |
+
// Semantically, a dispatch key identifies a possible "level" in our
|
| 102 |
+
// dispatch, for which a handler may be registered. Each handler corresponds
|
| 103 |
+
// to a type of functionality.
|
| 104 |
+
//
|
| 105 |
+
// In implementation terms, the dispatch key identifies a specific "bit" in a
|
| 106 |
+
// DispatchKeySet. Higher bit indexes get handled by dispatching first (because
|
| 107 |
+
// we "count leading zeros" when we extract the highest priority dispatch
|
| 108 |
+
// key.)
|
| 109 |
+
//
|
| 110 |
+
// Note [DispatchKey Classification]
|
| 111 |
+
// This enum actually contains several types of keys, which are explained
|
| 112 |
+
// in more detail further down:
|
| 113 |
+
// (1) non-customizable backends (e.g. FPGA)
|
| 114 |
+
// (2) non-customizable functionalities (e.g. Functionalize)
|
| 115 |
+
// (3) functionalized that are customizable per backend (e.g. Dense, Sparse,
|
| 116 |
+
// AutogradFunctionality) (4) per-backend instances of customizable
|
| 117 |
+
// functionalities (e.g. CPU, SparseCPU, AutogradCPU) (5) alias keys (e.g.
|
| 118 |
+
// CompositeImplicitAutograd)
|
| 119 |
+
//
|
| 120 |
+
// Of the categories above, it's important to note:
|
| 121 |
+
// (a) which keys are assigned individual bits in a DispatchKeySet
|
| 122 |
+
// (b) which keys are assigned individual slots in the runtime operator table
|
| 123 |
+
// ("Runtime keys")
|
| 124 |
+
//
|
| 125 |
+
// (1), (2) and (3) all get their own dedicated bits in the DispatchKeySet.
|
| 126 |
+
// (1), (2) and (4) all get their own dedicated slots in the runtime operator
|
| 127 |
+
// table.
|
| 128 |
+
|
| 129 |
+
// See Note [DispatchKeySet Internal Representation] for more details.
|
| 130 |
+
//
|
| 131 |
+
// NOTE: Keep the list in sync with `DispatchKey` in torchgen/model.py
|
| 132 |
+
enum class DispatchKey : uint16_t {
|
| 133 |
+
|
| 134 |
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~ UNDEFINED ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
| 135 |
+
// This is not a "real" functionality, but it exists to give us a "nullopt"
|
| 136 |
+
// element we can return for cases when a DispatchKeySet contains no elements.
|
| 137 |
+
// You can think a more semantically accurate definition of DispatchKey is:
|
| 138 |
+
//
|
| 139 |
+
// using DispatchKey = optional<RealDispatchKey>
|
| 140 |
+
//
|
| 141 |
+
// and Undefined == nullopt. We didn't actually represent
|
| 142 |
+
// it this way because optional<RealDispatchKey> would take two
|
| 143 |
+
// words, when DispatchKey fits in eight bits.
|
| 144 |
+
|
| 145 |
+
Undefined = 0,
|
| 146 |
+
|
| 147 |
+
// Define an alias for Undefined to represent CatchAll (long term
|
| 148 |
+
// this will get eliminated, but for now it's convenient)
|
| 149 |
+
CatchAll = Undefined,
|
| 150 |
+
|
| 151 |
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~ Functionality Keys ~~~~~~~~~~~~~~~~~~~~~~ //
|
| 152 |
+
// Every value in the enum (up to EndOfFunctionalityKeys)
|
| 153 |
+
// corresponds to an individual "functionality" that can be dispatched to.
|
| 154 |
+
// This is represented in the DispatchKeySet by assigning each of these enum
|
| 155 |
+
// values
|
| 156 |
+
// to each of the remaining (64 - len(BackendComponent)) bits.
|
| 157 |
+
//
|
| 158 |
+
// Most of these functionalities have a single handler assigned to them,
|
| 159 |
+
// making them "runtime keys".
|
| 160 |
+
// That map to a single slot in the runtime operator table.
|
| 161 |
+
//
|
| 162 |
+
// A few functionalities are allowed to be customizable per backend.
|
| 163 |
+
// See [Note: Per-Backend Functionality Dispatch Keys] for details.
|
| 164 |
+
|
| 165 |
+
// See [Note: Per-Backend Functionality Dispatch Keys]
|
| 166 |
+
Dense,
|
| 167 |
+
|
| 168 |
+
// Below are non-extensible backends.
|
| 169 |
+
// These are backends that currently don't have their own overrides for
|
| 170 |
+
// Autograd/Sparse/Quantized kernels,
|
| 171 |
+
// and we therefore don't waste space in the runtime operator table allocating
|
| 172 |
+
// space for them.
|
| 173 |
+
// If any of these backends ever need to customize, e.g., Autograd, then we'll
|
| 174 |
+
// need to add a DispatchKey::*Bit for them.
|
| 175 |
+
|
| 176 |
+
// TODO: put this in BackendComponents
|
| 177 |
+
FPGA, // Xilinx support lives out of tree at
|
| 178 |
+
// https://gitlab.com/pytorch-complex/vitis_kernels
|
| 179 |
+
|
| 180 |
+
// TODO: put this in BackendComponents
|
| 181 |
+
// ONNX Runtime, lives out of tree at https://github.com/pytorch/ort and
|
| 182 |
+
// https://github.com/microsoft/onnxruntime, and is also used to test general
|
| 183 |
+
// backend/extension machinery in the core. cf:
|
| 184 |
+
// - test/cpp_extensions/ort_extension.cpp
|
| 185 |
+
// - test/test_torch.py
|
| 186 |
+
// - aten/src/ATen/test/extension_backend_test.cpp
|
| 187 |
+
ORT,
|
| 188 |
+
|
| 189 |
+
Vulkan, // TODO: put this in BackendComponents
|
| 190 |
+
Metal, // TODO: put this in BackendComponents
|
| 191 |
+
|
| 192 |
+
// See [Note: Per-Backend Functionality Dispatch Keys]
|
| 193 |
+
Quantized,
|
| 194 |
+
|
| 195 |
+
// This backend is to support custom RNGs; it lets you go
|
| 196 |
+
// to a different kernel if you pass in a generator that is not a
|
| 197 |
+
// traditional CPUGeneratorImpl/CUDAGeneratorImpl. To make use of this
|
| 198 |
+
// key:
|
| 199 |
+
// 1) set it as a second parameter of at::Generator constructor call in
|
| 200 |
+
// the user-defined PRNG class.
|
| 201 |
+
// 2) use it as a dispatch key while registering custom kernels
|
| 202 |
+
// (templatized kernels specialized for user-defined PRNG class)
|
| 203 |
+
// intended for out of tree use; tested by aten/src/ATen/test/rng_test.cpp
|
| 204 |
+
CustomRNGKeyId,
|
| 205 |
+
|
| 206 |
+
// TODO: Make Mkldnn a functionality key, so we can give it Meta
|
| 207 |
+
// support
|
| 208 |
+
// Here are backends which specify more specialized operators
|
| 209 |
+
// based on the layout of the tensor. Note that the sparse backends
|
| 210 |
+
// are one case where ordering matters: sparse multi-dispatches with
|
| 211 |
+
// the corresponding dense tensors, and must be handled before them.
|
| 212 |
+
MkldnnCPU, // registered at build/aten/src/ATen/RegisterMkldnnCPU.cpp
|
| 213 |
+
// NB: not to be confused with MKLDNN, which is Caffe2 only
|
| 214 |
+
|
| 215 |
+
// See [Note: Per-Backend Functionality Dispatch Keys]
|
| 216 |
+
Sparse,
|
| 217 |
+
|
| 218 |
+
// TODO: Make SparseCsr a functionality key
|
| 219 |
+
SparseCsrCPU,
|
| 220 |
+
SparseCsrCUDA,
|
| 221 |
+
|
| 222 |
+
NestedTensor,
|
| 223 |
+
|
| 224 |
+
// In some situations, it is not immediately obvious what the correct
|
| 225 |
+
// backend for function is, because the function in question doesn't
|
| 226 |
+
// have any "tensor" arguments. In this case, a BackendSelect function
|
| 227 |
+
// can be registered to implement the custom determination of the
|
| 228 |
+
// correct backend.
|
| 229 |
+
BackendSelect,
|
| 230 |
+
|
| 231 |
+
Python,
|
| 232 |
+
|
| 233 |
+
// Out-of-core key for Fake Tensor in torchdistx.
|
| 234 |
+
// See https://pytorch.org/torchdistx/latest/fake_tensor.html
|
| 235 |
+
// TODO: delete this in favor of Python-implemented fake tensor
|
| 236 |
+
Fake,
|
| 237 |
+
// See Note [Out-of-tree vmap+grad prototype]. The purpose of this key
|
| 238 |
+
// is to insert code after the "autograd subsystem" runs, so this key should
|
| 239 |
+
// be directly after ADInplaceOrView and all of the autograd keys.
|
| 240 |
+
FuncTorchDynamicLayerBackMode,
|
| 241 |
+
|
| 242 |
+
// Alias and mutation removal.
|
| 243 |
+
// If some backends want to opt into only alias removal or only mutation
|
| 244 |
+
// removal,
|
| 245 |
+
// we can consider adding separate keys dedicated to those individual passes.
|
| 246 |
+
// See Note [Functionalization Pass In Core] for details.
|
| 247 |
+
Functionalize,
|
| 248 |
+
|
| 249 |
+
// The named dispatch key is set for any tensors with named dimensions.
|
| 250 |
+
// Although we have a dispatch key for named tensors, for historical reasons,
|
| 251 |
+
// this dispatch key doesn't do any of the substantive functionality for named
|
| 252 |
+
// tensor (though, hypothetically, it could!) At the moment, it's just
|
| 253 |
+
// responsible for letting us give good error messages when operations
|
| 254 |
+
// don't support named tensors.
|
| 255 |
+
//
|
| 256 |
+
// NB: If you ever consider moving named tensor functionality into
|
| 257 |
+
// this dispatch key, note that it might be necessary add another dispatch
|
| 258 |
+
// key that triggers before composite operators, in case a composite operator
|
| 259 |
+
// has named dimension propagation that doesn't match that of its
|
| 260 |
+
// constituent parts.
|
| 261 |
+
// TODO: delete this once torchdim lands in functorch
|
| 262 |
+
Named,
|
| 263 |
+
|
| 264 |
+
// The Conjugate dispatch key is set for any tensors that need to perform
|
| 265 |
+
// conjugation
|
| 266 |
+
// This is implemented at a dispatch level right before any backends run
|
| 267 |
+
Conjugate,
|
| 268 |
+
|
| 269 |
+
// The Negative dispatch key is set for any tensors that need to perform
|
| 270 |
+
// negation
|
| 271 |
+
// This is implemented at a dispatch level right before any backends run
|
| 272 |
+
Negative,
|
| 273 |
+
|
| 274 |
+
ZeroTensor, // registered at build/aten/src/ATen/RegisterZeroTensor.cpp
|
| 275 |
+
|
| 276 |
+
// Note [ADInplaceOrView key]
|
| 277 |
+
// ADInplaceOrView key is used by inplace or view ops to register a kernel
|
| 278 |
+
// that does additional setup for future autograd computation.
|
| 279 |
+
//
|
| 280 |
+
// 1. For inplace ops this kernel does version bump
|
| 281 |
+
// 2. For view ops this kernel does `as_view` setup where we properly setup
|
| 282 |
+
// DifferentiableViewMeta on the view tensors.
|
| 283 |
+
//
|
| 284 |
+
// For other ops it's fallthrough kernel since there's no extra
|
| 285 |
+
// work to do.
|
| 286 |
+
//
|
| 287 |
+
// Note [Dream: skip VariableType kernel when requires_grad=false]
|
| 288 |
+
//
|
| 289 |
+
// In an ideal world where we can skip VariableType kernel for inputs
|
| 290 |
+
// with requires_grad=false, instead of a fallthrough kernel, we'll
|
| 291 |
+
// register a kernel shown below to all functional ops as well:
|
| 292 |
+
// torch::Tensor my_functional_op(...) {
|
| 293 |
+
// {
|
| 294 |
+
// // Note for every op in VariableType, you need to go through
|
| 295 |
+
// // `AutoDispatchBelowADInplaceOrView` guard exactly once to add the
|
| 296 |
+
// // key to TLS excluded set. If you don't go through it at all,
|
| 297 |
+
// // inplace/view ops called through `at::` inside your backend
|
| 298 |
+
// // kernel will dispatch to ADInplaceOrView kernels and do a lot
|
| 299 |
+
// // of extra work.
|
| 300 |
+
// at::AutoDispatchBelowADInplaceOrView guard;
|
| 301 |
+
// at::redispatch::my_functional_op(...);
|
| 302 |
+
// }
|
| 303 |
+
// }
|
| 304 |
+
// But this work is currently blocked since it adds an extra dispatch
|
| 305 |
+
// for all ops and it's non-trivial overhead at model level(a few percents).
|
| 306 |
+
// Thus our current approach takes advantage of the fact every kernel go
|
| 307 |
+
// through VariableType kernel first and pulls the
|
| 308 |
+
// `at::AutoDispatchBelowADInplaceOrView` guard of functional ops
|
| 309 |
+
// up to the `VariableType` kernel. Thus we only add the extra dispatch
|
| 310 |
+
// to view/inplace ops to minimize its perf impact to real models.
|
| 311 |
+
ADInplaceOrView,
|
| 312 |
+
// Note [Alias Dispatch Key : Autograd]
|
| 313 |
+
// All backends are oblivious to autograd; autograd is handled as a
|
| 314 |
+
// layer which happens on top of all backends. It inspects the autograd
|
| 315 |
+
// metadata of all inputs, determines what autograd metadata should be
|
| 316 |
+
// constructed by the output, and otherwise defers to the backend to
|
| 317 |
+
// actually do the numeric computation. Autograd contains
|
| 318 |
+
// the bulk of this logic.
|
| 319 |
+
|
| 320 |
+
// Autograd is now an alias dispatch key which by default maps to all
|
| 321 |
+
// backend-specific autograd keys.
|
| 322 |
+
// Backend-specific allow backends to override the default kernel registered
|
| 323 |
+
// to Autograd key as needed.
|
| 324 |
+
// For example, XLA wants to define autograd for einsum directly.
|
| 325 |
+
// Registering a custom autograd implementation at the XLA key won't work
|
| 326 |
+
// because we process Autograd before XLA. This key has higher priority and
|
| 327 |
+
// gets processed first. You generally should NOT redispatch after handling
|
| 328 |
+
// autograd here (since that would result in execution of the Autograd
|
| 329 |
+
// operator, which you're trying to skip). In AutogradXLA implementations,
|
| 330 |
+
// you are responsible for handling autograd yourself, or deferring to other
|
| 331 |
+
// operators which support autograd.
|
| 332 |
+
|
| 333 |
+
// Currently we only have backend-specific autograd keys for CPU/CUDA/XLA and
|
| 334 |
+
// reserved user-defined backends. All other in-tree backends share the
|
| 335 |
+
// AutogradOther key. We can add specific autograd key for those backends
|
| 336 |
+
// upon request.
|
| 337 |
+
AutogradOther,
|
| 338 |
+
|
| 339 |
+
// See [Note: Per-Backend Functionality Dispatch Keys]
|
| 340 |
+
AutogradFunctionality,
|
| 341 |
+
|
| 342 |
+
// NestedTensor is an example of something that isn't a "real backend"
|
| 343 |
+
// (because it mostly consists of redispatching kernels)
|
| 344 |
+
// but it would like to override autograd functionality in C++.
|
| 345 |
+
// We can handle cases like this by adding an extra functionality key
|
| 346 |
+
// exclusively for handling autograd for NestedTensor.
|
| 347 |
+
// lives out of tree at
|
| 348 |
+
// https://github.com/pytorch/nestedtensor
|
| 349 |
+
AutogradNestedTensor,
|
| 350 |
+
|
| 351 |
+
Tracer,
|
| 352 |
+
|
| 353 |
+
// TODO: make Autocast a functionality key
|
| 354 |
+
// Autocasting precedes VariableTypeId, to ensure casts are autograd-exposed
|
| 355 |
+
// and inputs are saved for backward in the post-autocast type.
|
| 356 |
+
AutocastCPU,
|
| 357 |
+
AutocastXPU,
|
| 358 |
+
AutocastIPU,
|
| 359 |
+
AutocastHPU,
|
| 360 |
+
AutocastXLA,
|
| 361 |
+
// AutocastXLA is only being used for TPUs. XLA GPUs continue to use
|
| 362 |
+
// AutocastCUDA.
|
| 363 |
+
AutocastCUDA,
|
| 364 |
+
AutocastPrivateUse1,
|
| 365 |
+
|
| 366 |
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ WRAPPERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
| 367 |
+
// There are a number of alternative modes which may want to handle before
|
| 368 |
+
// autograd; for example, error checking, tracing, profiling or vmap. They
|
| 369 |
+
// go here.
|
| 370 |
+
|
| 371 |
+
FuncTorchBatched, // See Note [Out-of-tree vmap+grad prototype]
|
| 372 |
+
FuncTorchVmapMode, // See Note [Out-of-tree vmap+grad prototype]
|
| 373 |
+
|
| 374 |
+
// This is the dispatch key for BatchedTensorImpl, which is used to implement
|
| 375 |
+
// batching rules for vmap.
|
| 376 |
+
Batched,
|
| 377 |
+
|
| 378 |
+
// When we are inside a vmap, all tensors dispatch on this key.
|
| 379 |
+
// See Note: [DispatchKey::VmapMode usage] for more details.
|
| 380 |
+
VmapMode,
|
| 381 |
+
|
| 382 |
+
FuncTorchGradWrapper, // See Note [Out-of-tree vmap+grad prototype]
|
| 383 |
+
|
| 384 |
+
// Out-of-core key for Deferred Module Initialization in torchdistx.
|
| 385 |
+
// See https://pytorch.org/torchdistx/latest/deferred_init.html
|
| 386 |
+
DeferredInit,
|
| 387 |
+
|
| 388 |
+
// Used by Python key logic to know the set of tls on entry to the dispatcher
|
| 389 |
+
// This kernel assumes it is the top-most non-functorch-related DispatchKey.
|
| 390 |
+
// If you add a key above, make sure to update the fallback implementation for
|
| 391 |
+
// this.
|
| 392 |
+
PythonTLSSnapshot,
|
| 393 |
+
|
| 394 |
+
// This key should be at the very top of the dispatcher
|
| 395 |
+
FuncTorchDynamicLayerFrontMode, // See Note [Out-of-tree vmap+grad prototype]
|
| 396 |
+
|
| 397 |
+
// TESTING: This is intended to be a generic testing tensor type id.
|
| 398 |
+
// Don't use it for anything real; its only acceptable use is within a single
|
| 399 |
+
// process test. Use it by creating a TensorImpl with this DispatchKey, and
|
| 400 |
+
// then registering operators to operate on this type id. See
|
| 401 |
+
// aten/src/ATen/core/dispatch/backend_fallback_test.cpp for a usage example.
|
| 402 |
+
TESTING_ONLY_GenericWrapper,
|
| 403 |
+
|
| 404 |
+
// TESTING: This is intended to be a generic testing tensor type id.
|
| 405 |
+
// Don't use it for anything real; its only acceptable use is within a ingle
|
| 406 |
+
// process test. Use it by toggling the mode on and off via
|
| 407 |
+
// TESTING_ONLY_tls_generic_mode_set_enabled and then registering operators
|
| 408 |
+
// to operate on this type id. See
|
| 409 |
+
// aten/src/ATen/core/dispatch/backend_fallback_test.cpp
|
| 410 |
+
// for a usage example
|
| 411 |
+
TESTING_ONLY_GenericMode,
|
| 412 |
+
|
| 413 |
+
// This key is used for pre-dispatch tracing in make_fx.
|
| 414 |
+
// It has lower priority than the PythonDispatcher key
|
| 415 |
+
// because we use the PythonDispatcher to intercept the key from python,
|
| 416 |
+
// and avoid having to implement it in C++.
|
| 417 |
+
PreDispatch,
|
| 418 |
+
|
| 419 |
+
// This is a bypass that allows you to skip running the C++ dispatcher
|
| 420 |
+
// entirely
|
| 421 |
+
PythonDispatcher,
|
| 422 |
+
|
| 423 |
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FIN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
| 424 |
+
EndOfFunctionalityKeys, // End of functionality keys.
|
| 425 |
+
|
| 426 |
+
// ~~~~~~~~~~~~~~ "Dense" Per-Backend Dispatch keys ~~~~~~~~~~~~~~~~~~~~ //
|
| 427 |
+
// Here are backends which you think of as traditionally specifying
|
| 428 |
+
// how to implement operations on some device.
|
| 429 |
+
|
| 430 |
+
#define DEFINE_PER_BACKEND_KEYS_FOR_BACKEND(n, prefix) prefix##n,
|
| 431 |
+
|
| 432 |
+
#define DEFINE_PER_BACKEND_KEYS(fullname, prefix) \
|
| 433 |
+
StartOf##fullname##Backends, \
|
| 434 |
+
C10_FORALL_BACKEND_COMPONENTS( \
|
| 435 |
+
DEFINE_PER_BACKEND_KEYS_FOR_BACKEND, prefix) \
|
| 436 |
+
EndOf##fullname##Backends = prefix##Meta,
|
| 437 |
+
|
| 438 |
+
C10_FORALL_FUNCTIONALITY_KEYS(DEFINE_PER_BACKEND_KEYS)
|
| 439 |
+
|
| 440 |
+
#undef DEFINE_PER_BACKEND_KEYS
|
| 441 |
+
#undef DEFINE_PER_BACKEND_KEYS_FOR_BACKEND
|
| 442 |
+
|
| 443 |
+
EndOfRuntimeBackendKeys = EndOfAutogradFunctionalityBackends,
|
| 444 |
+
|
| 445 |
+
// ~~~~~~~~~~~~~~~~~~~~~~ Alias Dispatch Keys ~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
| 446 |
+
// Note [Alias Dispatch Keys]
|
| 447 |
+
// Alias dispatch keys are synthetic dispatch keys which map to multiple
|
| 448 |
+
// runtime dispatch keys. Alisa keys have precedence, but they are always
|
| 449 |
+
// lower precedence than runtime keys. You can register a kernel to an
|
| 450 |
+
// alias key, the kernel might be populated to the mapped runtime keys
|
| 451 |
+
// during dispatch table computation.
|
| 452 |
+
// If a runtime dispatch key has multiple kernels from alias keys, which
|
| 453 |
+
// kernel wins is done based on the precedence of alias keys (but runtime
|
| 454 |
+
// keys always have precedence over alias keys).
|
| 455 |
+
// Alias keys won't be directly called during runtime.
|
| 456 |
+
|
| 457 |
+
// See Note [Alias Dispatch Key : Autograd]
|
| 458 |
+
Autograd,
|
| 459 |
+
CompositeImplicitAutograd, // registered at
|
| 460 |
+
// build/aten/src/ATen/RegisterCompositeImplicitAutograd.cpp
|
| 461 |
+
|
| 462 |
+
// Note: The alias keyset for FuncTorchBatchedDecomposition is disjoint from
|
| 463 |
+
// all
|
| 464 |
+
// other alias keysets
|
| 465 |
+
// and so precedence order doesn't matter
|
| 466 |
+
FuncTorchBatchedDecomposition, // registered at
|
| 467 |
+
// build/aten/src/ATen/RegisterFuncTorchBatchedDecomposition.cpp
|
| 468 |
+
// Note: The alias keyset for CompositeImplicitAutogradNestedTensor is
|
| 469 |
+
// disjoint from all other alias keysets
|
| 470 |
+
CompositeImplicitAutogradNestedTensor, // registered at
|
| 471 |
+
// build/aten/src/ATen/RegisterCompositeImplicitAutogradNestedTensor.cpp
|
| 472 |
+
CompositeExplicitAutograd, // registered at
|
| 473 |
+
// build/aten/src/ATen/RegisterCompositeExplicitAutograd.cpp
|
| 474 |
+
// See Note [CompositeExplicitAutogradNonFunctional Key]
|
| 475 |
+
CompositeExplicitAutogradNonFunctional, // registered at
|
| 476 |
+
// build/aten/src/ATen/RegisterCompositeExplicitAutograd.cpp
|
| 477 |
+
|
| 478 |
+
// Define an alias key to represent end of alias dispatch keys.
|
| 479 |
+
// If you add new alias keys after Autograd, please also update it here.
|
| 480 |
+
StartOfAliasKeys = Autograd,
|
| 481 |
+
EndOfAliasKeys = CompositeExplicitAutogradNonFunctional, //
|
| 482 |
+
|
| 483 |
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~ BC ALIASES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
| 484 |
+
// The aliases exist for backwards compatibility reasons, they shouldn't
|
| 485 |
+
// be used
|
| 486 |
+
CPUTensorId = CPU,
|
| 487 |
+
CUDATensorId = CUDA,
|
| 488 |
+
DefaultBackend = CompositeExplicitAutograd,
|
| 489 |
+
PrivateUse1_PreAutograd = AutogradPrivateUse1,
|
| 490 |
+
PrivateUse2_PreAutograd = AutogradPrivateUse2,
|
| 491 |
+
PrivateUse3_PreAutograd = AutogradPrivateUse3,
|
| 492 |
+
Autocast = AutocastCUDA,
|
| 493 |
+
};
|
| 494 |
+
|
| 495 |
+
// Note [Private use DispatchKey]
|
| 496 |
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 497 |
+
// Private use tensor IDs are preallocated tensor type IDs for use in user
|
| 498 |
+
// applications. Similar to private use fields in HTTP, they can be used
|
| 499 |
+
// by end users for experimental or private applications, without needing
|
| 500 |
+
// to "standardize" the tensor ID (which would be done by submitting a PR
|
| 501 |
+
// to PyTorch to add your type ID).
|
| 502 |
+
//
|
| 503 |
+
// Private use tensor IDs are appropriate to use if you want to experiment
|
| 504 |
+
// with adding a new tensor type (without having to patch PyTorch first) or
|
| 505 |
+
// have a private, non-distributed application that needs to make use of a
|
| 506 |
+
// new tensor type. Private use tensor IDs are NOT appropriate to use for
|
| 507 |
+
// libraries intended to be distributed to further users: please contact
|
| 508 |
+
// the PyTorch developers to get a type ID registered in this case.
|
| 509 |
+
//
|
| 510 |
+
// We provide two classes of private user tensor id: regular DispatchKeys
|
| 511 |
+
// and Autograd DispatchKeys. DispatchKeys serve the role of ordinary "backend"
|
| 512 |
+
// DispatchKeys; if you were adding support for a new type of accelerator, you
|
| 513 |
+
// would use a backend DispatchKey, and ideally automatically reuse
|
| 514 |
+
// AutogradOther definitions already defined in PyTorch. AutogradPrivateUse
|
| 515 |
+
// DispatchKeys serve as "wrapper" DispatchKeys: they are only necessary for
|
| 516 |
+
// tensors that compose multiple internal tensors, and for cases when the
|
| 517 |
+
// built-in autograd formulas for operators are not appropriate.
|
| 518 |
+
|
| 519 |
+
static_assert(
|
| 520 |
+
(static_cast<uint8_t>(BackendComponent::EndOfBackendKeys) +
|
| 521 |
+
static_cast<uint8_t>(DispatchKey::EndOfFunctionalityKeys)) <= 64,
|
| 522 |
+
"The BackendComponent and DispatchKey enums (below EndOfFunctionalityKeys)"
|
| 523 |
+
" both map to backend and functionality bits"
|
| 524 |
+
" into a 64-bit bitmask; you must have less than 64 total entries between them");
|
| 525 |
+
|
| 526 |
+
// Check if a DispatchKey is an alias mapping to other runtime keys.
|
| 527 |
+
constexpr bool isAliasDispatchKey(DispatchKey k) {
|
| 528 |
+
return k >= DispatchKey::StartOfAliasKeys && k <= DispatchKey::EndOfAliasKeys;
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
// [Note: Per-Backend Functionality Dispatch Keys]
|
| 532 |
+
// Check if a DispatchKey is a per-backend functionality key
|
| 533 |
+
// Any functionalities that can be customized per-backend should be added here.
|
| 534 |
+
// These keys correspond to functionalities that can be customized individually
|
| 535 |
+
// per backend. While they only take up one bit in the `DispatchKeySet` bitset,
|
| 536 |
+
// they map to (# backends) slots in the operator table.
|
| 537 |
+
// Each of these keys also has a separate set of "runtime keys" in the dispatch
|
| 538 |
+
// key enum, per backend, which *do* map to the individual operator table slots.
|
| 539 |
+
// For example, the "Sparse" key maps to an individual bit in the
|
| 540 |
+
// DispatchKeySet, while `SparseCPU`, `SparseCUDA`, etc all map to individual
|
| 541 |
+
// slots in the runtime operator table.
|
| 542 |
+
|
| 543 |
+
constexpr bool isPerBackendFunctionalityKey(DispatchKey k) {
|
| 544 |
+
if (k == DispatchKey::Dense || k == DispatchKey::Quantized ||
|
| 545 |
+
k == DispatchKey::Sparse || k == DispatchKey::AutogradFunctionality ||
|
| 546 |
+
k == DispatchKey::NestedTensor) {
|
| 547 |
+
return true;
|
| 548 |
+
} else {
|
| 549 |
+
return false;
|
| 550 |
+
}
|
| 551 |
+
}
|
| 552 |
+
|
| 553 |
+
// Note that this includes Undefined in the total count.
|
| 554 |
+
// BUT EndOfFunctionalityKeys is its own (placeholder) key.
|
| 555 |
+
// e.g. Undefined=0, Dense=1, Sparse=2, EndOfFunctionalityKeys=3.
|
| 556 |
+
// In the above example, there are 3 total functionality keys.
|
| 557 |
+
constexpr uint8_t num_functionality_keys =
|
| 558 |
+
static_cast<uint8_t>(DispatchKey::EndOfFunctionalityKeys);
|
| 559 |
+
|
| 560 |
+
constexpr uint8_t num_backends =
|
| 561 |
+
static_cast<uint8_t>(BackendComponent::EndOfBackendKeys);
|
| 562 |
+
|
| 563 |
+
// Note [No More Than 16 Backends]
|
| 564 |
+
// Search for this note to find places in the code where the "no more than 16
|
| 565 |
+
// backends" invariant is baked in.
|
| 566 |
+
static_assert(
|
| 567 |
+
static_cast<uint8_t>(BackendComponent::EndOfBackendKeys) <= 16,
|
| 568 |
+
"BackendComponent currently only supports <= 16 backends. If we really need to extend this, \
|
| 569 |
+
there are a few places where this invariant is baked in");
|
| 570 |
+
|
| 571 |
+
constexpr uint8_t numPerBackendFunctionalityKeys() {
|
| 572 |
+
uint8_t count = 0;
|
| 573 |
+
for (uint8_t k = 0; k <= num_functionality_keys; ++k) {
|
| 574 |
+
if (isPerBackendFunctionalityKey(static_cast<DispatchKey>(k)))
|
| 575 |
+
++count;
|
| 576 |
+
}
|
| 577 |
+
return count;
|
| 578 |
+
}
|
| 579 |
+
|
| 580 |
+
#if defined(C10_MOBILE_TRIM_DISPATCH_KEYS)
|
| 581 |
+
// See [Note: Trimmed Mobile Dispatch Keys]
|
| 582 |
+
constexpr uint16_t num_runtime_entries = 8;
|
| 583 |
+
#else
|
| 584 |
+
constexpr uint16_t num_runtime_entries = num_functionality_keys +
|
| 585 |
+
(numPerBackendFunctionalityKeys() * (num_backends - 1));
|
| 586 |
+
#endif
|
| 587 |
+
|
| 588 |
+
// See Note [No More Than 16 Backends]
|
| 589 |
+
constexpr uint16_t full_backend_mask =
|
| 590 |
+
(static_cast<uint16_t>(1) << num_backends) - 1;
|
| 591 |
+
|
| 592 |
+
C10_API const char* toString(DispatchKey);
|
| 593 |
+
C10_API const char* toString(BackendComponent);
|
| 594 |
+
C10_API std::ostream& operator<<(std::ostream&, DispatchKey);
|
| 595 |
+
C10_API std::ostream& operator<<(std::ostream&, BackendComponent);
|
| 596 |
+
|
| 597 |
+
C10_API DispatchKey getAutogradKeyFromBackend(BackendComponent k);
|
| 598 |
+
|
| 599 |
+
// Parses a string into a dispatch key.
|
| 600 |
+
// If the string cannot be correctly parsed, throws an exception.
|
| 601 |
+
C10_API c10::DispatchKey parseDispatchKey(const std::string& k);
|
| 602 |
+
|
| 603 |
+
// These are some convenience identifiers for dispatch keys which are
|
| 604 |
+
// shorter to type than their long counterparts. Note that some of these
|
| 605 |
+
// dispatch keys directly correspond to DeviceType; and most APIs that
|
| 606 |
+
// accept DispatchKey also accept DeviceType; e.g.,
|
| 607 |
+
// torch::dispatch(torch::kCPU, ...) is also valid.
|
| 608 |
+
constexpr DispatchKey kAutograd = DispatchKey::Autograd;
|
| 609 |
+
|
| 610 |
+
// See Note [The Ordering of Per-Backend Dispatch Keys Matters!]
|
| 611 |
+
// This function relies on the invariant that the dispatch keys between
|
| 612 |
+
// StartOfDenseBackends and EndOfRuntimeBackendKeys are ordered by backend
|
| 613 |
+
// in the same order as `BackendComponent`.
|
| 614 |
+
constexpr BackendComponent toBackendComponent(DispatchKey k) {
|
| 615 |
+
if (k >= DispatchKey::StartOfDenseBackends &&
|
| 616 |
+
k <= DispatchKey::EndOfDenseBackends) {
|
| 617 |
+
return static_cast<BackendComponent>(
|
| 618 |
+
static_cast<uint8_t>(k) -
|
| 619 |
+
static_cast<uint8_t>(DispatchKey::StartOfDenseBackends));
|
| 620 |
+
} else if (
|
| 621 |
+
k >= DispatchKey::StartOfQuantizedBackends &&
|
| 622 |
+
k <= DispatchKey::EndOfQuantizedBackends) {
|
| 623 |
+
return static_cast<BackendComponent>(
|
| 624 |
+
static_cast<uint8_t>(k) -
|
| 625 |
+
static_cast<uint8_t>(DispatchKey::StartOfQuantizedBackends));
|
| 626 |
+
} else if (
|
| 627 |
+
k >= DispatchKey::StartOfSparseBackends &&
|
| 628 |
+
k <= DispatchKey::EndOfSparseBackends) {
|
| 629 |
+
return static_cast<BackendComponent>(
|
| 630 |
+
static_cast<uint8_t>(k) -
|
| 631 |
+
static_cast<uint8_t>(DispatchKey::StartOfSparseBackends));
|
| 632 |
+
} else if (
|
| 633 |
+
k >= DispatchKey::StartOfNestedTensorBackends &&
|
| 634 |
+
k <= DispatchKey::EndOfNestedTensorBackends) {
|
| 635 |
+
return static_cast<BackendComponent>(
|
| 636 |
+
static_cast<uint8_t>(k) -
|
| 637 |
+
static_cast<uint8_t>(DispatchKey::StartOfNestedTensorBackends));
|
| 638 |
+
} else if (
|
| 639 |
+
k >= DispatchKey::StartOfAutogradFunctionalityBackends &&
|
| 640 |
+
k <= DispatchKey::EndOfAutogradFunctionalityBackends) {
|
| 641 |
+
return static_cast<BackendComponent>(
|
| 642 |
+
static_cast<uint8_t>(k) -
|
| 643 |
+
static_cast<uint8_t>(
|
| 644 |
+
DispatchKey::StartOfAutogradFunctionalityBackends));
|
| 645 |
+
} else {
|
| 646 |
+
return BackendComponent::InvalidBit;
|
| 647 |
+
}
|
| 648 |
+
}
|
| 649 |
+
|
| 650 |
+
constexpr DispatchKey toFunctionalityKey(DispatchKey k) {
|
| 651 |
+
if (k <= DispatchKey::EndOfFunctionalityKeys) {
|
| 652 |
+
return k;
|
| 653 |
+
} else if (k <= DispatchKey::EndOfDenseBackends) {
|
| 654 |
+
return DispatchKey::Dense;
|
| 655 |
+
} else if (k <= DispatchKey::EndOfQuantizedBackends) {
|
| 656 |
+
return DispatchKey::Quantized;
|
| 657 |
+
} else if (k <= DispatchKey::EndOfSparseBackends) {
|
| 658 |
+
return DispatchKey::Sparse;
|
| 659 |
+
} else if (k <= DispatchKey::EndOfNestedTensorBackends) {
|
| 660 |
+
return DispatchKey::NestedTensor;
|
| 661 |
+
} else if (k <= DispatchKey::EndOfAutogradFunctionalityBackends) {
|
| 662 |
+
return DispatchKey::AutogradFunctionality;
|
| 663 |
+
} else {
|
| 664 |
+
return DispatchKey::Undefined;
|
| 665 |
+
}
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
BackendComponent toBackendComponent(DeviceType device_type);
|
| 669 |
+
|
| 670 |
+
// Given (DispatchKey::Dense, BackendComponent::CUDABit), returns
|
| 671 |
+
// DispatchKey::CUDA.
|
| 672 |
+
// See Note [The Ordering of Per-Backend Dispatch Keys Matters!]
|
| 673 |
+
// This function relies on the invariant that the dispatch keys between
|
| 674 |
+
// StartOfDenseBackends and EndOfRuntimeBackendKeys are ordered by backend
|
| 675 |
+
// in the same order as `BackendComponent`.
|
| 676 |
+
constexpr DispatchKey toRuntimePerBackendFunctionalityKey(
|
| 677 |
+
DispatchKey functionality_k,
|
| 678 |
+
BackendComponent backend_k) {
|
| 679 |
+
if (functionality_k == DispatchKey::Dense) {
|
| 680 |
+
return static_cast<DispatchKey>(
|
| 681 |
+
static_cast<uint8_t>(DispatchKey::StartOfDenseBackends) +
|
| 682 |
+
static_cast<uint8_t>(backend_k));
|
| 683 |
+
}
|
| 684 |
+
if (functionality_k == DispatchKey::Sparse) {
|
| 685 |
+
return static_cast<DispatchKey>(
|
| 686 |
+
static_cast<uint8_t>(DispatchKey::StartOfSparseBackends) +
|
| 687 |
+
static_cast<uint8_t>(backend_k));
|
| 688 |
+
}
|
| 689 |
+
if (functionality_k == DispatchKey::Quantized) {
|
| 690 |
+
return static_cast<DispatchKey>(
|
| 691 |
+
static_cast<uint8_t>(DispatchKey::StartOfQuantizedBackends) +
|
| 692 |
+
static_cast<uint8_t>(backend_k));
|
| 693 |
+
}
|
| 694 |
+
if (functionality_k == DispatchKey::NestedTensor) {
|
| 695 |
+
return static_cast<DispatchKey>(
|
| 696 |
+
static_cast<uint8_t>(DispatchKey::StartOfNestedTensorBackends) +
|
| 697 |
+
static_cast<uint8_t>(backend_k));
|
| 698 |
+
}
|
| 699 |
+
if (functionality_k == DispatchKey::AutogradFunctionality) {
|
| 700 |
+
return static_cast<DispatchKey>(
|
| 701 |
+
static_cast<uint8_t>(
|
| 702 |
+
DispatchKey::StartOfAutogradFunctionalityBackends) +
|
| 703 |
+
static_cast<uint8_t>(backend_k));
|
| 704 |
+
}
|
| 705 |
+
return DispatchKey::Undefined;
|
| 706 |
+
}
|
| 707 |
+
|
| 708 |
+
} // namespace c10
|
| 709 |
+
|
| 710 |
+
namespace torch {
|
| 711 |
+
// Expose the constant, but not the TYPE (DispatchKey is an implementation
|
| 712 |
+
// detail!)
|
| 713 |
+
using c10::kAutograd;
|
| 714 |
+
} // namespace torch
|
| 715 |
+
|
| 716 |
+
// NB: You really shouldn't use this instance; this enum is guaranteed
|
| 717 |
+
// to be pretty small so a regular array should be acceptable.
|
| 718 |
+
namespace std {
|
| 719 |
+
template <>
|
| 720 |
+
struct hash<c10::DispatchKey> {
|
| 721 |
+
typedef size_t result_type;
|
| 722 |
+
typedef c10::DispatchKey argument_type;
|
| 723 |
+
|
| 724 |
+
size_t operator()(c10::DispatchKey x) const {
|
| 725 |
+
return static_cast<size_t>(x);
|
| 726 |
+
}
|
| 727 |
+
};
|
| 728 |
+
} // namespace std
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/DispatchKeySet.h
ADDED
|
@@ -0,0 +1,928 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
#include <c10/core/DispatchKey.h>
|
| 3 |
+
#include <c10/util/Exception.h>
|
| 4 |
+
#include <c10/util/Metaprogramming.h>
|
| 5 |
+
#include <c10/util/llvmMathExtras.h>
|
| 6 |
+
#include <array>
|
| 7 |
+
#include <ostream>
|
| 8 |
+
|
| 9 |
+
namespace c10 {
|
| 10 |
+
|
| 11 |
+
struct FunctionalityOffsetAndMask {
|
| 12 |
+
// empty constructor shouldn't be used; only needed to initialize
|
| 13 |
+
// the array before populating it.
|
| 14 |
+
FunctionalityOffsetAndMask() = default;
|
| 15 |
+
FunctionalityOffsetAndMask(uint16_t offset, uint16_t mask)
|
| 16 |
+
: offset(offset), mask(mask) {}
|
| 17 |
+
// This needs to big enough to cover the size of the operator table.
|
| 18 |
+
uint16_t offset{};
|
| 19 |
+
// See Note [No More Than 16 Backends]
|
| 20 |
+
// This mask needs to be big enough to mask all of the backend bits.
|
| 21 |
+
// We probably don't ever want to have more than 16 backend bits, so uint16_t
|
| 22 |
+
// should be enough.
|
| 23 |
+
uint16_t mask{};
|
| 24 |
+
};
|
| 25 |
+
static_assert(
|
| 26 |
+
c10::num_runtime_entries < 65536,
|
| 27 |
+
"The dispatcher currently only supports up to 2^16 runtime entries");
|
| 28 |
+
|
| 29 |
+
C10_API std::array<FunctionalityOffsetAndMask, num_functionality_keys>
|
| 30 |
+
initializeFunctionalityOffsetsAndMasks();
|
| 31 |
+
|
| 32 |
+
C10_ALWAYS_INLINE static const std::
|
| 33 |
+
array<FunctionalityOffsetAndMask, num_functionality_keys>&
|
| 34 |
+
offsetsAndMasks() {
|
| 35 |
+
static auto offsets_and_masks_ = initializeFunctionalityOffsetsAndMasks();
|
| 36 |
+
return offsets_and_masks_;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
// A representation of a set of DispatchKeys. A DispatchKeySet contains both
|
| 40 |
+
// "functionality" bits and "backend bits", and every tensor holds its own
|
| 41 |
+
// DispatchKeySet. The Dispatcher implements multiple dispatch by grabbing the
|
| 42 |
+
// keyset on every input tensor, or’ing them together, and dispatching to a
|
| 43 |
+
// specific piece of functionality. The functionality bits are *ordered*. When
|
| 44 |
+
// multiple functionality bits are set, we use the highest priority
|
| 45 |
+
// functionality. Similarly, multiple backend bits can theoretically be set if
|
| 46 |
+
// you call an operator with multiple tensors from difference devices (e.g. CPU
|
| 47 |
+
// and CUDA), although support for mixed device dispatch is limited (the only
|
| 48 |
+
// kernels that gracefully handle mixed device inputs for now are cuda kernels
|
| 49 |
+
// that take in a scalar cpu tensor).
|
| 50 |
+
|
| 51 |
+
// A representation of a set of DispatchKeys. A tensor may have multiple
|
| 52 |
+
// tensor type ids, e.g., a Variable tensor can also be a CPU tensor; the
|
| 53 |
+
// DispatchKeySet specifies what type ids apply. The internal representation is
|
| 54 |
+
// as a 64-bit bit set (this means only 64 tensor type ids are supported).
|
| 55 |
+
//
|
| 56 |
+
// As mentioned above, DispatchKeys are ordered; thus, we can ask questions like
|
| 57 |
+
// "what is the highest priority DispatchKey in the set"? (The set itself is
|
| 58 |
+
// not ordered; two sets with the same ids will always have the ids ordered in
|
| 59 |
+
// the same way.)
|
| 60 |
+
//
|
| 61 |
+
// Note [DispatchKeySet Internal Representation]
|
| 62 |
+
// Internally, dispatch keys are packed into 64-bit DispatchKeySet objects
|
| 63 |
+
// that get passed around at runtime.
|
| 64 |
+
// However, there isn't necessarily a 1-to-1 mapping between bits in the keyset
|
| 65 |
+
// and individual dispatch keys.
|
| 66 |
+
//
|
| 67 |
+
// First: why do we have this distinction, and why not map every dispatch key
|
| 68 |
+
// directly to a bit? This is mostly because we have several types of
|
| 69 |
+
// functionalities that different backends would like to customize. For example,
|
| 70 |
+
// we have:
|
| 71 |
+
// - "Dense": CPU, CUDA, XLA, ... (~12 keys)
|
| 72 |
+
// - "Sparse": SparseCPU, SparseCUDA, ...
|
| 73 |
+
// - "Quantized": QuantizedCPU, QuantizedCUDA, QuantizedXLA, ...
|
| 74 |
+
// - "Autograd": AutogradCPU, AutogradCUDA, Autograd XLA, ...
|
| 75 |
+
// The problem is that total number of keys grows quadratically with [#
|
| 76 |
+
// backends] x [# functionalities], making it very difficult to map each key
|
| 77 |
+
// directly to a bit in a bitset without dramatically increasing the size of the
|
| 78 |
+
// bitset over time.
|
| 79 |
+
//
|
| 80 |
+
// The two enums (BackendComponent and DispatchKey) can be divided roughly into
|
| 81 |
+
// 5 categories.
|
| 82 |
+
//
|
| 83 |
+
// (1) "Building block" keys
|
| 84 |
+
// (a) backends: jEverything in the BackendComponent enum (e.g. CPUBit,
|
| 85 |
+
// CUDABIt) (b) functionalities: (per-backend) functionality-bit DispatchKeys
|
| 86 |
+
// (e.g. AutogradFunctionality, Sparse, Dense)
|
| 87 |
+
// (2) "Runtime" keys
|
| 88 |
+
// (a) "non-customizable backends" (e.g. FPGA)
|
| 89 |
+
// (b) "non-customizable functionalities" (e.g. Functionalize)
|
| 90 |
+
// (c) "per-backend instances of customizable functionalities" (e.g. CPU,
|
| 91 |
+
// SparseCPU, AutogradCPU)
|
| 92 |
+
// (3) "Alias" DispatchKeys (see Note [Alias Dispatch Keys])
|
| 93 |
+
//
|
| 94 |
+
// (1) Building block keys always correspond to individual bits in a
|
| 95 |
+
// DispatchKeySet. They can also be combined in a DispatchKeySet to form actual
|
| 96 |
+
// runtime keys. e.g.
|
| 97 |
+
// auto dense_cpu_ks = DispatchKeySet({DispatchKey::CPUBit,
|
| 98 |
+
// DispatchKey::Dense});
|
| 99 |
+
// // The keyset has the runtime dense-cpu key.
|
| 100 |
+
// dense_cpu_ks.has(DispatchKey::CPU);
|
| 101 |
+
// // And it contains the building block keys too.
|
| 102 |
+
// dense_cpu_ks.has(DispatchKey::CPUBit);
|
| 103 |
+
// dense_cpu_ks.has(DispatchKey::Dense);
|
| 104 |
+
//
|
| 105 |
+
// Not every backend and not every functionality counts as a "building block
|
| 106 |
+
// key". This is mostly to give us more levers to pull in the design space.
|
| 107 |
+
// Backend keys and functionality keys that count as "building blocks" will
|
| 108 |
+
// contribute to a full cross product of functionality that can be overriden.
|
| 109 |
+
//
|
| 110 |
+
// For example, right now we have at least 12 "backend" building blocks (CPU,
|
| 111 |
+
// CUDA, XLA, ...) and at least 4 "functionality" building blocks (Dense,
|
| 112 |
+
// Sparse, Quantized, AutogradFunctionality, ...). These keys together allow
|
| 113 |
+
// every dispatcher operator to be customized in up to 12*4 different ways. Each
|
| 114 |
+
// of those requires a slot in the operator table of every dispatcher operator.
|
| 115 |
+
// Not every piece of functionality necessarily needs to be customizeable
|
| 116 |
+
// per-backend, and not every backend necessarily needs to be able to customize
|
| 117 |
+
// every type of functionality.
|
| 118 |
+
//
|
| 119 |
+
//
|
| 120 |
+
// (2) Every runtime key corresponds directly to a slot in an operator's runtime
|
| 121 |
+
// dispatch table, and you can directly register kernels to a runtime dispatch
|
| 122 |
+
// key.
|
| 123 |
+
//
|
| 124 |
+
// For per-backend functionalities like "Dense" or "AutogradFunctionality",
|
| 125 |
+
// you can think of the corresponding runtime dispatch keys as "instances" of
|
| 126 |
+
// that functionality, per backend. E.g. "CPU", "CUDA", "XLA", etc. are all
|
| 127 |
+
// runtime instances of the "Dense" building block key.
|
| 128 |
+
|
| 129 |
+
// (2a) and (2b) are represented identically in the DispatchKeySet logic:
|
| 130 |
+
// - backend-agnostic functionalities (e.g. FuncTorchBatched) are NOT
|
| 131 |
+
// customizeable per backend.
|
| 132 |
+
// In order to do so, we'd need to promote it to a per-backend functionality
|
| 133 |
+
// "building block" key.
|
| 134 |
+
// - non-customizeable backends (e.g. FPGA) can NOT customize existing
|
| 135 |
+
// functionality like Sparse, Autograd, etc.
|
| 136 |
+
// In order to do so, we'd need to promote it to a backend "building block"
|
| 137 |
+
// key.
|
| 138 |
+
//
|
| 139 |
+
// In both cases, these keys directly correspond to runtime slots in the
|
| 140 |
+
// operator table.
|
| 141 |
+
//
|
| 142 |
+
//
|
| 143 |
+
// (3) "Alias" keys
|
| 144 |
+
// See Note [Alias Dispatch Keys]
|
| 145 |
+
//
|
| 146 |
+
// Final note: for anyone making future changes to the Dispatcher +
|
| 147 |
+
// DispatchKeySet internals, there's a closed PR with a basic
|
| 148 |
+
// python-implementation of the Dispatcher that might be useful in quickly
|
| 149 |
+
// testing out and validating changes. See it at
|
| 150 |
+
// https://github.com/pytorch/pytorch/pull/68743
|
| 151 |
+
|
| 152 |
+
// An undefined tensor is one with an empty tensor type set.
|
| 153 |
+
class DispatchKeySet final {
|
| 154 |
+
public:
|
| 155 |
+
enum Full { FULL };
|
| 156 |
+
enum FullAfter { FULL_AFTER };
|
| 157 |
+
enum Raw { RAW };
|
| 158 |
+
|
| 159 |
+
// NB: default constructor representation as zero is MANDATORY as
|
| 160 |
+
// use of DispatchKeySet in TLS requires this.
|
| 161 |
+
constexpr DispatchKeySet() = default;
|
| 162 |
+
|
| 163 |
+
constexpr DispatchKeySet(Full)
|
| 164 |
+
: repr_((1ULL << (num_backends + num_functionality_keys - 1)) - 1) {}
|
| 165 |
+
|
| 166 |
+
constexpr DispatchKeySet(FullAfter, DispatchKey t)
|
| 167 |
+
// LSB after t are OK, but not t itself.
|
| 168 |
+
// "functionalities" have a notion of ordering (e.g. Autograd > Sparse >
|
| 169 |
+
// Quantized > Dense). But backends don't really have an ordering.
|
| 170 |
+
// Therefore, we're enforcing that FullAfter can only be used on
|
| 171 |
+
// "functionality" keys.
|
| 172 |
+
: repr_(
|
| 173 |
+
(1ULL
|
| 174 |
+
<< (num_backends + static_cast<uint8_t>(toFunctionalityKey(t)) -
|
| 175 |
+
1)) -
|
| 176 |
+
1) {
|
| 177 |
+
*this = add(DispatchKey::PythonDispatcher);
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
// Public version of DispatchKeySet(uint64_t) API; external users
|
| 181 |
+
// must be explicit when they do this!
|
| 182 |
+
constexpr DispatchKeySet(Raw, uint64_t x) : repr_(x) {}
|
| 183 |
+
|
| 184 |
+
constexpr explicit DispatchKeySet(BackendComponent k) {
|
| 185 |
+
if (k == BackendComponent::InvalidBit) {
|
| 186 |
+
repr_ = 0;
|
| 187 |
+
} else {
|
| 188 |
+
repr_ = 1ULL << (static_cast<uint8_t>(k) - 1);
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
constexpr explicit DispatchKeySet(DispatchKey k) {
|
| 193 |
+
if (k == DispatchKey::Undefined) {
|
| 194 |
+
// Case 1: handle Undefined specifically
|
| 195 |
+
repr_ = 0;
|
| 196 |
+
} else if (k <= DispatchKey::EndOfFunctionalityKeys) {
|
| 197 |
+
// Case 2: handle "functionality-only" keys
|
| 198 |
+
// These keys have a functionality bit set, but no backend bits
|
| 199 |
+
// These can technically be either:
|
| 200 |
+
// - valid runtime keys (e.g. DispatchKey::AutogradOther,
|
| 201 |
+
// DispatchKey::FuncTorchBatched, etc)
|
| 202 |
+
// - "building block" keys that aren't actual runtime keys (e.g.
|
| 203 |
+
// DispatchKey::Dense or Sparse)
|
| 204 |
+
uint64_t functionality_val = 1ULL
|
| 205 |
+
<< (num_backends + static_cast<uint8_t>(k) - 1);
|
| 206 |
+
repr_ = functionality_val;
|
| 207 |
+
} else if (k <= DispatchKey::EndOfRuntimeBackendKeys) {
|
| 208 |
+
// Case 3: "runtime" keys that have a functionality bit AND a backend bit.
|
| 209 |
+
// First compute which bit to flip for the functionality.
|
| 210 |
+
auto functionality_k = toFunctionalityKey(k);
|
| 211 |
+
// The - 1 is because Undefined is technically a "functionality" that
|
| 212 |
+
// doesn't show up in the bitset. So e.g. Dense is technically the second
|
| 213 |
+
// functionality, but the lowest functionality bit.
|
| 214 |
+
uint64_t functionality_val = 1ULL
|
| 215 |
+
<< (num_backends + static_cast<uint8_t>(functionality_k) - 1);
|
| 216 |
+
|
| 217 |
+
// then compute which bit to flip for the backend
|
| 218 |
+
// Case 4a: handle the runtime instances of "per-backend functionality"
|
| 219 |
+
// keys For example, given DispatchKey::CPU, we should set:
|
| 220 |
+
// - the Dense functionality bit
|
| 221 |
+
// - the CPUBit backend bit
|
| 222 |
+
// first compute which bit to flip for the backend
|
| 223 |
+
auto backend_k = toBackendComponent(k);
|
| 224 |
+
uint64_t backend_val = backend_k == BackendComponent::InvalidBit
|
| 225 |
+
? 0
|
| 226 |
+
: 1ULL << (static_cast<uint8_t>(backend_k) - 1);
|
| 227 |
+
repr_ = functionality_val + backend_val;
|
| 228 |
+
} else {
|
| 229 |
+
// At this point, we should have covered every case except for alias keys.
|
| 230 |
+
// Technically it would be possible to add alias dispatch keys to a
|
| 231 |
+
// DispatchKeySet, but the semantics are a little confusing and this
|
| 232 |
+
// currently isn't needed anywhere.
|
| 233 |
+
repr_ = 0;
|
| 234 |
+
}
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
constexpr uint64_t keys_to_repr(std::initializer_list<DispatchKey> ks) {
|
| 238 |
+
uint64_t repr = 0;
|
| 239 |
+
for (auto k : ks) {
|
| 240 |
+
repr |= DispatchKeySet(k).repr_;
|
| 241 |
+
}
|
| 242 |
+
return repr;
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
constexpr uint64_t backend_bits_to_repr(
|
| 246 |
+
std::initializer_list<BackendComponent> ks) {
|
| 247 |
+
uint64_t repr = 0;
|
| 248 |
+
for (auto k : ks) {
|
| 249 |
+
repr |= DispatchKeySet(k).repr_;
|
| 250 |
+
}
|
| 251 |
+
return repr;
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
explicit constexpr DispatchKeySet(std::initializer_list<DispatchKey> ks)
|
| 255 |
+
: repr_(keys_to_repr(ks)) {}
|
| 256 |
+
|
| 257 |
+
explicit constexpr DispatchKeySet(std::initializer_list<BackendComponent> ks)
|
| 258 |
+
// Note: for some reason, putting this logic directly in the constructor
|
| 259 |
+
// appears to fail to compile on CUDA 10.1.
|
| 260 |
+
// See an example internal failure at
|
| 261 |
+
// https://www.internalfb.com/intern/skycastle/run/76561193669136035/artifact/actionlog.76561193742069401.stderr
|
| 262 |
+
: repr_(backend_bits_to_repr(ks)) {}
|
| 263 |
+
|
| 264 |
+
// Test if a DispatchKey is in the set
|
| 265 |
+
inline bool has(DispatchKey t) const {
|
| 266 |
+
TORCH_INTERNAL_ASSERT_DEBUG_ONLY(t != DispatchKey::Undefined);
|
| 267 |
+
return has_all(DispatchKeySet(t));
|
| 268 |
+
}
|
| 269 |
+
constexpr bool has_backend(BackendComponent t) const {
|
| 270 |
+
return has_all(DispatchKeySet(t));
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
// Test if a DispatchKey is in the set
|
| 274 |
+
// Given a DispatchKeySet of functionality keys and (potentially) backend
|
| 275 |
+
// keys, tests if all of them are in the current set.
|
| 276 |
+
constexpr bool has_all(DispatchKeySet ks) const {
|
| 277 |
+
return static_cast<bool>((repr_ & ks.repr_) == ks.repr_);
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
// Given a DispatchKeySet of functionality keys and (potentially) backend
|
| 281 |
+
// keys, tests if any of them are in the current set. This could technically
|
| 282 |
+
// be pretty easily implemented using has(). It is strictly a perf
|
| 283 |
+
// optimization though. There are many places in the code base where we want
|
| 284 |
+
// to test for multiple functionality keys together. HOWEVER, runtime
|
| 285 |
+
// per-backend functionality keys aren't allowed to be used with this
|
| 286 |
+
// function, because you can end up with weird results. e.g.
|
| 287 |
+
// DispatchKeySet(DispatchKey::AutogradCPU).has_any(DispatchKeySet(DispatchKey::CPU))
|
| 288 |
+
// would return true.
|
| 289 |
+
inline bool has_any(DispatchKeySet ks) const {
|
| 290 |
+
TORCH_INTERNAL_ASSERT_DEBUG_ONLY(
|
| 291 |
+
// Either there are no backend bits in the input keyset
|
| 292 |
+
((ks.repr_ & full_backend_mask) == 0) ||
|
| 293 |
+
// or there are no per-backend-functionality bits
|
| 294 |
+
// See [Note: Per-Backend Functionality Dispatch Keys]
|
| 295 |
+
((ks &
|
| 296 |
+
DispatchKeySet({
|
| 297 |
+
DispatchKey::Dense,
|
| 298 |
+
DispatchKey::Quantized,
|
| 299 |
+
DispatchKey::Sparse,
|
| 300 |
+
DispatchKey::AutogradFunctionality,
|
| 301 |
+
})
|
| 302 |
+
.repr_) == 0));
|
| 303 |
+
return static_cast<bool>((repr_ & ks.repr_) != 0);
|
| 304 |
+
}
|
| 305 |
+
// Test if DispatchKeySet is a superset of ks.
|
| 306 |
+
bool isSupersetOf(DispatchKeySet ks) const {
|
| 307 |
+
return (repr_ & ks.repr_) == ks.repr_;
|
| 308 |
+
}
|
| 309 |
+
// Perform set union
|
| 310 |
+
constexpr DispatchKeySet operator|(DispatchKeySet other) const {
|
| 311 |
+
return DispatchKeySet(repr_ | other.repr_);
|
| 312 |
+
}
|
| 313 |
+
// Perform set intersection
|
| 314 |
+
constexpr DispatchKeySet operator&(DispatchKeySet other) const {
|
| 315 |
+
return DispatchKeySet(repr_ & other.repr_);
|
| 316 |
+
}
|
| 317 |
+
// Compute the set difference self - other,
|
| 318 |
+
// but ONLY for the functionality keys.
|
| 319 |
+
// Any backend bits set on self will remain unchanged.
|
| 320 |
+
// See Note [Removing keys from DispatchKeySet Only Affects Functionality
|
| 321 |
+
// Keys]
|
| 322 |
+
constexpr DispatchKeySet operator-(DispatchKeySet other) const {
|
| 323 |
+
return DispatchKeySet(repr_ & (full_backend_mask | ~other.repr_));
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
// Compute self ^ other
|
| 327 |
+
constexpr DispatchKeySet operator^(DispatchKeySet other) const {
|
| 328 |
+
return DispatchKeySet(repr_ ^ other.repr_);
|
| 329 |
+
}
|
| 330 |
+
bool operator==(DispatchKeySet other) const {
|
| 331 |
+
return repr_ == other.repr_;
|
| 332 |
+
}
|
| 333 |
+
bool operator!=(DispatchKeySet other) const {
|
| 334 |
+
return repr_ != other.repr_;
|
| 335 |
+
}
|
| 336 |
+
// Add a DispatchKey to the DispatchKey set. Does NOT mutate,
|
| 337 |
+
// returns the extended DispatchKeySet!
|
| 338 |
+
C10_NODISCARD constexpr DispatchKeySet add(DispatchKey t) const {
|
| 339 |
+
return *this | DispatchKeySet(t);
|
| 340 |
+
}
|
| 341 |
+
C10_NODISCARD constexpr DispatchKeySet add(DispatchKeySet ks) const {
|
| 342 |
+
return *this | ks;
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
+
// Remove a DispatchKey from the DispatchKey set.
|
| 346 |
+
// This is generally not an operation you should be doing
|
| 347 |
+
// (it's used to implement the printing overload, operator<<)
|
| 348 |
+
//
|
| 349 |
+
// Note [Removing keys from DispatchKeySet Only Affects Functionality Keys]
|
| 350 |
+
// Only functionality bits are allowed to be removed from a keyset.
|
| 351 |
+
// For now, we're only allowing removal of "functionality bits" from the
|
| 352 |
+
// keyset, which is specifically needed by the fallthrough key calculation
|
| 353 |
+
// logic. Why is removing backend bits problematic? Consider this example:
|
| 354 |
+
//
|
| 355 |
+
// DispatchKeySet([DispatchKey.CPU, DispatchKey.AutogradCUDA,
|
| 356 |
+
// DispatchKey.CUDA]).remove(DispatchKey.AutogradCUDA)
|
| 357 |
+
// DispatchKeySet([DispatchKey.CPU,
|
| 358 |
+
// DispatchKey.AutogradCUDA]).remove(DispatchKey.AutogradCUDA)
|
| 359 |
+
//
|
| 360 |
+
// What do we want to happen?
|
| 361 |
+
// Technically, we'd like it to be true that after removal,
|
| 362 |
+
// the first keyset still has the CUDA dispatch key while the second doesn't.
|
| 363 |
+
// Unfortunately there's no way to represent that, because the two keysets are
|
| 364 |
+
// represented the same way internally: functionality bits: Autograd, Dense
|
| 365 |
+
// backend bits: CPU, CUDA
|
| 366 |
+
//
|
| 367 |
+
// Instead, remove(DispatchKey.AutogradCPU) will only remove the "Autograd"
|
| 368 |
+
// bit from the bitset.
|
| 369 |
+
C10_NODISCARD constexpr DispatchKeySet remove(DispatchKey t) const {
|
| 370 |
+
return DispatchKeySet(
|
| 371 |
+
repr_ & ~(DispatchKeySet(t).repr_ & ~full_backend_mask));
|
| 372 |
+
}
|
| 373 |
+
// You're allowed to remove a backend bit from a DispatchKeySet,
|
| 374 |
+
// but you have to be explicit about it (remove_backend() instead of
|
| 375 |
+
// remove()).
|
| 376 |
+
constexpr DispatchKeySet remove_backend(BackendComponent b) const {
|
| 377 |
+
return DispatchKeySet(repr_ & ~(DispatchKeySet(b).repr_));
|
| 378 |
+
}
|
| 379 |
+
// Is the set empty? (AKA undefined tensor)
|
| 380 |
+
bool empty() const {
|
| 381 |
+
return repr_ == 0;
|
| 382 |
+
}
|
| 383 |
+
uint64_t raw_repr() {
|
| 384 |
+
return repr_;
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
DispatchKey highestFunctionalityKey() const {
|
| 388 |
+
auto functionality_idx = indexOfHighestBit();
|
| 389 |
+
// This means that none of the functionality bits were set.
|
| 390 |
+
if (functionality_idx < num_backends)
|
| 391 |
+
return DispatchKey::Undefined;
|
| 392 |
+
// The first num_backend bits in the keyset don't correspond to real
|
| 393 |
+
// dispatch keys.
|
| 394 |
+
return static_cast<DispatchKey>(functionality_idx - num_backends);
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
// This is similar like toBackendComponent(DispatchKey), but less restrictive.
|
| 398 |
+
// toBackendComponent() errors out if the key that it was passed has no
|
| 399 |
+
// backend bits, which is useful for error checking. We need a version of that
|
| 400 |
+
// here that can also handle "fake" backends like FPGA, because they need to
|
| 401 |
+
// map to the AutogradOther key. For those backends, we return
|
| 402 |
+
// BackendComponent::InvalidBit.
|
| 403 |
+
BackendComponent highestBackendKey() const {
|
| 404 |
+
// mask to mask out functionality bits
|
| 405 |
+
auto backend_idx =
|
| 406 |
+
DispatchKeySet(repr_ & full_backend_mask).indexOfHighestBit();
|
| 407 |
+
// all zeros across the backend bits means that no backend bits are set.
|
| 408 |
+
if (backend_idx == 0)
|
| 409 |
+
return BackendComponent::InvalidBit;
|
| 410 |
+
return static_cast<BackendComponent>(backend_idx);
|
| 411 |
+
}
|
| 412 |
+
|
| 413 |
+
// returns the DispatchKey of highest priority in the set.
|
| 414 |
+
DispatchKey highestPriorityTypeId() const {
|
| 415 |
+
auto functionality_k = highestFunctionalityKey();
|
| 416 |
+
if (isPerBackendFunctionalityKey(functionality_k)) {
|
| 417 |
+
return toRuntimePerBackendFunctionalityKey(
|
| 418 |
+
functionality_k, highestBackendKey());
|
| 419 |
+
}
|
| 420 |
+
return functionality_k;
|
| 421 |
+
}
|
| 422 |
+
|
| 423 |
+
// Returns the index of the most-significant bit in the keyset.
|
| 424 |
+
// This is used to as part of the calculation into the operator table to get:
|
| 425 |
+
// - the highest "functionality" bit in the keyset.
|
| 426 |
+
// - the highest "backend" bit in the keyset.
|
| 427 |
+
uint8_t indexOfHighestBit() const {
|
| 428 |
+
return 64 - llvm::countLeadingZeros(repr_);
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
#if defined(C10_MOBILE_TRIM_DISPATCH_KEYS)
|
| 432 |
+
// [Note: Trimmed Mobile Dispatch Keys]
|
| 433 |
+
/**
|
| 434 |
+
* The method below maps the dispatch key in the enum DispatchKey to an
|
| 435 |
+
* integer index in the dispatchTable_ array in OperatorEntry. The array
|
| 436 |
+
* is trimmed for mobile to reduce peak memory usage since it's
|
| 437 |
+
* unnecessary to reserve additional space for dispatch keys that will
|
| 438 |
+
* never be used on mobile.
|
| 439 |
+
*/
|
| 440 |
+
int getDispatchTableIndexForDispatchKeySet() const {
|
| 441 |
+
auto dk = highestPriorityTypeId();
|
| 442 |
+
switch (dk) {
|
| 443 |
+
case DispatchKey::Undefined:
|
| 444 |
+
return 0;
|
| 445 |
+
case DispatchKey::CPU:
|
| 446 |
+
return 1;
|
| 447 |
+
case DispatchKey::QuantizedCPU:
|
| 448 |
+
return 2;
|
| 449 |
+
case DispatchKey::SparseCPU:
|
| 450 |
+
return 3;
|
| 451 |
+
case DispatchKey::BackendSelect:
|
| 452 |
+
return 4;
|
| 453 |
+
case DispatchKey::ADInplaceOrView:
|
| 454 |
+
return 5;
|
| 455 |
+
case DispatchKey::AutogradOther:
|
| 456 |
+
return 6;
|
| 457 |
+
case DispatchKey::AutogradCPU:
|
| 458 |
+
return 7;
|
| 459 |
+
default:
|
| 460 |
+
return -1;
|
| 461 |
+
}
|
| 462 |
+
}
|
| 463 |
+
#else
|
| 464 |
+
// returns the index in the operator table of highest priority key in the the
|
| 465 |
+
// keyset Note that we could in theory implement this using
|
| 466 |
+
// highestPriorityTypeId(), but this code is very hotpath and we can do it
|
| 467 |
+
// faster without it.
|
| 468 |
+
int getDispatchTableIndexForDispatchKeySet() const {
|
| 469 |
+
auto functionality_idx =
|
| 470 |
+
DispatchKeySet(repr_ >> num_backends).indexOfHighestBit();
|
| 471 |
+
auto offset_and_mask = offsetsAndMasks()[functionality_idx];
|
| 472 |
+
// Mask the functionality bits out first, then right-shift by 1.
|
| 473 |
+
// right-shifting by 1 because everything is zero-indexed.
|
| 474 |
+
// E.g. 000001 (CPU) should give us an offset of 0, 000010 (CUDA) should
|
| 475 |
+
// give us an offset of 1, etc.
|
| 476 |
+
auto backend_idx =
|
| 477 |
+
DispatchKeySet((repr_ & offset_and_mask.mask) >> 1).indexOfHighestBit();
|
| 478 |
+
return offset_and_mask.offset + backend_idx;
|
| 479 |
+
}
|
| 480 |
+
#endif
|
| 481 |
+
|
| 482 |
+
// returns the "index" of the highest priority backend in the keyset.
|
| 483 |
+
// This is pretty similar to getBackendKey(), but:
|
| 484 |
+
// - It's hotpath code (part of the runtime bitset calculation)
|
| 485 |
+
// - I's returns an integer index, not an enum value
|
| 486 |
+
// - Everything is shifted to the right by 1.
|
| 487 |
+
// BackendComponent::InvalidBit is technically the lowest enum value,
|
| 488 |
+
// but it isn't included in the runtime table. So CPUBit = 1, CUDABit = 2,
|
| 489 |
+
// etc.
|
| 490 |
+
uint64_t getBackendIndex() const {
|
| 491 |
+
return DispatchKeySet((repr_ & full_backend_mask) >> 1).indexOfHighestBit();
|
| 492 |
+
}
|
| 493 |
+
|
| 494 |
+
private:
|
| 495 |
+
constexpr DispatchKeySet(uint64_t repr) : repr_(repr) {}
|
| 496 |
+
uint64_t repr_ = 0;
|
| 497 |
+
|
| 498 |
+
public:
|
| 499 |
+
// STL iterator for DispatchKeySet. Iterates through all runtime DispatchKeys
|
| 500 |
+
// in the set. The iterator is only invalidated by the destruction of the
|
| 501 |
+
// underlying DispatchKeySet as the iterator stores a pointer to the raw
|
| 502 |
+
// representation of the DispatchKeySet. Note: When we encounter a per-backend
|
| 503 |
+
// functionality (e.g. Dense or Sparse), we will iterate through EVERY backend
|
| 504 |
+
// in the keyset, for that functionality. For example, if the next
|
| 505 |
+
// functionality key to iterate over is Autograd, and the backend bits in the
|
| 506 |
+
// keyset correspond to [BackendComponent::CPUBit, BackendComponent::CUDABit],
|
| 507 |
+
// then the next two keys we return will be DispatchKey::AutogradCPU,
|
| 508 |
+
// DispatchKey::AutogradCUDA (CPU first because it has lower precedence than
|
| 509 |
+
// CUDA in DispatchKey.h).
|
| 510 |
+
class iterator {
|
| 511 |
+
public:
|
| 512 |
+
using self_type = iterator;
|
| 513 |
+
using iterator_category = std::input_iterator_tag;
|
| 514 |
+
using value_type = DispatchKey;
|
| 515 |
+
using difference_type = ptrdiff_t;
|
| 516 |
+
using reference = value_type&;
|
| 517 |
+
using pointer = value_type*;
|
| 518 |
+
// final mask value should mask out the entire keyset
|
| 519 |
+
static const uint8_t end_iter_mask_val =
|
| 520 |
+
num_backends + num_functionality_keys;
|
| 521 |
+
// final key value should be the last DispatchKey
|
| 522 |
+
static const uint8_t end_iter_key_val = num_functionality_keys;
|
| 523 |
+
|
| 524 |
+
// current_dispatchkey_idx_ will iterate through all functionality bits.
|
| 525 |
+
// current_backendcomponent_idx_ will iterate through all backend bits.
|
| 526 |
+
explicit iterator(
|
| 527 |
+
const uint64_t* data_ptr,
|
| 528 |
+
uint8_t next_functionality = num_backends,
|
| 529 |
+
uint8_t next_backend = 0)
|
| 530 |
+
: data_ptr_(data_ptr),
|
| 531 |
+
next_functionality_(next_functionality),
|
| 532 |
+
next_backend_(next_backend),
|
| 533 |
+
// These are in an invalid state at construction time, and set by the
|
| 534 |
+
// first increment call
|
| 535 |
+
current_dispatchkey_idx_(end_iter_key_val),
|
| 536 |
+
current_backendcomponent_idx_(end_iter_key_val) {
|
| 537 |
+
// Go to the first key in the set
|
| 538 |
+
TORCH_INTERNAL_ASSERT(
|
| 539 |
+
next_functionality_ >= num_backends,
|
| 540 |
+
"num_backends=",
|
| 541 |
+
static_cast<uint32_t>(num_backends),
|
| 542 |
+
"next_functionality_=",
|
| 543 |
+
static_cast<uint32_t>(next_functionality_));
|
| 544 |
+
++(*this);
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
C10_API self_type& operator++();
|
| 548 |
+
|
| 549 |
+
self_type operator++(int) {
|
| 550 |
+
self_type previous_iterator = *this;
|
| 551 |
+
++(*this);
|
| 552 |
+
return previous_iterator;
|
| 553 |
+
}
|
| 554 |
+
|
| 555 |
+
bool operator==(const self_type& rhs) const {
|
| 556 |
+
return next_functionality_ == rhs.next_functionality_ &&
|
| 557 |
+
current_dispatchkey_idx_ == rhs.current_dispatchkey_idx_ &&
|
| 558 |
+
next_backend_ == rhs.next_backend_ &&
|
| 559 |
+
current_backendcomponent_idx_ == rhs.current_backendcomponent_idx_;
|
| 560 |
+
}
|
| 561 |
+
bool operator!=(const self_type& rhs) const {
|
| 562 |
+
return next_functionality_ != rhs.next_functionality_ ||
|
| 563 |
+
current_dispatchkey_idx_ != rhs.current_dispatchkey_idx_ ||
|
| 564 |
+
next_backend_ != rhs.next_backend_ ||
|
| 565 |
+
current_backendcomponent_idx_ != rhs.current_backendcomponent_idx_;
|
| 566 |
+
}
|
| 567 |
+
DispatchKey operator*() const {
|
| 568 |
+
auto functionality_key =
|
| 569 |
+
static_cast<DispatchKey>(current_dispatchkey_idx_);
|
| 570 |
+
if (isPerBackendFunctionalityKey(functionality_key)) {
|
| 571 |
+
auto next_key = toRuntimePerBackendFunctionalityKey(
|
| 572 |
+
functionality_key,
|
| 573 |
+
static_cast<BackendComponent>(current_backendcomponent_idx_));
|
| 574 |
+
// We expect all of the Dense, Sparse, Quantized, and Autograd keys to
|
| 575 |
+
// be ordered the same way with respect to their backends
|
| 576 |
+
TORCH_INTERNAL_ASSERT(
|
| 577 |
+
toBackendComponent(next_key) ==
|
| 578 |
+
static_cast<BackendComponent>(current_backendcomponent_idx_),
|
| 579 |
+
"Tried to map functionality key ",
|
| 580 |
+
toString(functionality_key),
|
| 581 |
+
" and backend bit ",
|
| 582 |
+
toString(
|
| 583 |
+
static_cast<BackendComponent>(current_backendcomponent_idx_)),
|
| 584 |
+
" to a runtime key, but ended up with ",
|
| 585 |
+
toString(next_key),
|
| 586 |
+
". This can happen if the order of the backend dispatch keys in DispatchKey.h isn't consistent.",
|
| 587 |
+
" Please double check that enum for inconsistencies.");
|
| 588 |
+
return next_key;
|
| 589 |
+
} else {
|
| 590 |
+
return functionality_key;
|
| 591 |
+
}
|
| 592 |
+
}
|
| 593 |
+
|
| 594 |
+
private:
|
| 595 |
+
const uint64_t* data_ptr_;
|
| 596 |
+
uint8_t next_functionality_;
|
| 597 |
+
uint8_t next_backend_;
|
| 598 |
+
uint8_t current_dispatchkey_idx_;
|
| 599 |
+
uint8_t current_backendcomponent_idx_;
|
| 600 |
+
};
|
| 601 |
+
|
| 602 |
+
public:
|
| 603 |
+
// Returns iterator to the first key in the set. If no keys are in the
|
| 604 |
+
// set, then will return the end iterator.
|
| 605 |
+
iterator begin() const {
|
| 606 |
+
return iterator(&repr_);
|
| 607 |
+
}
|
| 608 |
+
|
| 609 |
+
// We do not need to iterate beyond EndOfFunctionalityKeys so we will treat
|
| 610 |
+
// this as the end iterator.
|
| 611 |
+
iterator end() const {
|
| 612 |
+
return iterator(&repr_, iterator::end_iter_mask_val);
|
| 613 |
+
}
|
| 614 |
+
};
|
| 615 |
+
|
| 616 |
+
C10_API std::string toString(DispatchKeySet);
|
| 617 |
+
C10_API std::ostream& operator<<(std::ostream&, DispatchKeySet);
|
| 618 |
+
|
| 619 |
+
C10_API inline int getDispatchTableIndexForDispatchKey(DispatchKey k) {
|
| 620 |
+
return DispatchKeySet(k).getDispatchTableIndexForDispatchKeySet();
|
| 621 |
+
}
|
| 622 |
+
|
| 623 |
+
// Alias key DispatchKey::Autograd maps to
|
| 624 |
+
// (autograd_dispatch_keyset x full_backend_mask)
|
| 625 |
+
// NB: keys in this set also get associated with CompositeImplicitAutograd
|
| 626 |
+
//
|
| 627 |
+
// Note [autograd_dispatch_keyset Does Not Include Backend Bits]
|
| 628 |
+
// We don't want to include any backend bits (BackendComponent::CPUBit, etc)
|
| 629 |
+
// directly in autograd_dispatch_keyset.
|
| 630 |
+
// Why? keysets like autograd_dispatch_keyset are commonly used to remove
|
| 631 |
+
// autograd keys from a DispatchKeySet throughout the code base. However, you
|
| 632 |
+
// are only allowed to remove functionality bits from a keyset, not backend
|
| 633 |
+
// bits. See Note [Removing keys from DispatchKeySet Only Affects Functionality
|
| 634 |
+
// Keys] for details. To be consistent and avoid confusion, we're explicitly
|
| 635 |
+
// setting up autograd_dispatch_keyset to not have any backend bits.
|
| 636 |
+
constexpr DispatchKeySet autograd_dispatch_keyset = DispatchKeySet({
|
| 637 |
+
DispatchKey::AutogradFunctionality,
|
| 638 |
+
DispatchKey::AutogradOther,
|
| 639 |
+
DispatchKey::AutogradNestedTensor,
|
| 640 |
+
});
|
| 641 |
+
|
| 642 |
+
constexpr DispatchKeySet autocast_dispatch_keyset = DispatchKeySet({
|
| 643 |
+
DispatchKey::AutocastCPU,
|
| 644 |
+
DispatchKey::AutocastCUDA,
|
| 645 |
+
DispatchKey::AutocastXPU,
|
| 646 |
+
DispatchKey::AutocastIPU,
|
| 647 |
+
DispatchKey::AutocastHPU,
|
| 648 |
+
DispatchKey::AutocastXLA,
|
| 649 |
+
DispatchKey::AutocastPrivateUse1,
|
| 650 |
+
});
|
| 651 |
+
|
| 652 |
+
// See Note [TLS Initialization]
|
| 653 |
+
constexpr DispatchKeySet default_included_set = DispatchKeySet({
|
| 654 |
+
DispatchKey::BackendSelect,
|
| 655 |
+
DispatchKey::ADInplaceOrView,
|
| 656 |
+
});
|
| 657 |
+
|
| 658 |
+
constexpr DispatchKeySet default_excluded_set = DispatchKeySet({
|
| 659 |
+
DispatchKey::AutocastCPU,
|
| 660 |
+
DispatchKey::AutocastCUDA,
|
| 661 |
+
DispatchKey::AutocastXPU,
|
| 662 |
+
DispatchKey::AutocastIPU,
|
| 663 |
+
DispatchKey::AutocastHPU,
|
| 664 |
+
DispatchKey::AutocastXLA,
|
| 665 |
+
DispatchKey::AutocastPrivateUse1,
|
| 666 |
+
});
|
| 667 |
+
|
| 668 |
+
constexpr DispatchKeySet autograd_dispatch_keyset_with_ADInplaceOrView =
|
| 669 |
+
autograd_dispatch_keyset | DispatchKeySet(DispatchKey::ADInplaceOrView);
|
| 670 |
+
|
| 671 |
+
constexpr DispatchKeySet python_ks = DispatchKeySet({
|
| 672 |
+
DispatchKey::Python,
|
| 673 |
+
DispatchKey::PythonTLSSnapshot,
|
| 674 |
+
});
|
| 675 |
+
|
| 676 |
+
constexpr DispatchKeySet sparse_ks = DispatchKeySet(DispatchKey::Sparse);
|
| 677 |
+
|
| 678 |
+
constexpr DispatchKeySet sparse_csr_ks =
|
| 679 |
+
DispatchKeySet({DispatchKey::SparseCsrCPU, DispatchKey::SparseCsrCUDA});
|
| 680 |
+
|
| 681 |
+
constexpr DispatchKeySet mkldnn_ks = DispatchKeySet(DispatchKey::MkldnnCPU);
|
| 682 |
+
|
| 683 |
+
// backend dispatch keys that map to DispatchKey::AutogradOther
|
| 684 |
+
// NB: keys in this set also get associated with CompositeImplicitAutograd
|
| 685 |
+
constexpr DispatchKeySet autogradother_backends =
|
| 686 |
+
DispatchKeySet(
|
| 687 |
+
// HIP and VE aren't in this list: they now have their own backend bits
|
| 688 |
+
// which means that they can now have their own Autograd keys.
|
| 689 |
+
// Technically, HIP will now redispatch to its own custom AutogradHIP
|
| 690 |
+
// slot in the runtime table.
|
| 691 |
+
{DispatchKey::FPGA,
|
| 692 |
+
DispatchKey::ORT,
|
| 693 |
+
DispatchKey::Vulkan,
|
| 694 |
+
DispatchKey::Metal,
|
| 695 |
+
DispatchKey::SparseCsrCPU,
|
| 696 |
+
DispatchKey::SparseCsrCUDA,
|
| 697 |
+
DispatchKey::CustomRNGKeyId,
|
| 698 |
+
DispatchKey::MkldnnCPU,
|
| 699 |
+
// Sparse and Quantized backends also live here.
|
| 700 |
+
DispatchKey::Sparse,
|
| 701 |
+
DispatchKey::Quantized})
|
| 702 |
+
// Including the backend bits because this keyset is used during op
|
| 703 |
+
// registration, which requires looping over all runtime autogradother
|
| 704 |
+
// backend keys.
|
| 705 |
+
| DispatchKeySet(DispatchKeySet::RAW, full_backend_mask);
|
| 706 |
+
|
| 707 |
+
// The set of dispatch keys that come after autograd
|
| 708 |
+
// n.b. this relies on the fact that AutogradOther is currently the lowest
|
| 709 |
+
// Autograd key
|
| 710 |
+
constexpr DispatchKeySet after_autograd_keyset =
|
| 711 |
+
DispatchKeySet(DispatchKeySet::FULL_AFTER, c10::DispatchKey::AutogradOther);
|
| 712 |
+
|
| 713 |
+
// The set of dispatch keys that come after ADInplaceOrView
|
| 714 |
+
constexpr DispatchKeySet after_ADInplaceOrView_keyset = DispatchKeySet(
|
| 715 |
+
DispatchKeySet::FULL_AFTER,
|
| 716 |
+
c10::DispatchKey::ADInplaceOrView);
|
| 717 |
+
|
| 718 |
+
// The set of dispatch keys that come after Functionalize
|
| 719 |
+
constexpr DispatchKeySet after_func_keyset =
|
| 720 |
+
DispatchKeySet(DispatchKeySet::FULL_AFTER, c10::DispatchKey::Functionalize)
|
| 721 |
+
.remove(
|
| 722 |
+
// NOTE: we also need to remove ADInplaceOrView from the keyset when
|
| 723 |
+
// redispatching after the func kernels. This is because we're not
|
| 724 |
+
// calling the same op; we originally called an inplace op, and now
|
| 725 |
+
// we aren't. The original key calculation figured out which keys
|
| 726 |
+
// were Fallthrough based on the inplace op. That means that it did
|
| 727 |
+
// not include the ADInPlaceOrView kernel as a fallthrough key.
|
| 728 |
+
// However, we WANT the ADInPlaceOrView kernel to be ignored now
|
| 729 |
+
// that we're calling an out-of-place op. Re-invoking
|
| 730 |
+
// Dispatcher::call would re-run the Fallthrough key calculation and
|
| 731 |
+
// get us that, But at::redispatch is more performant. We can get
|
| 732 |
+
// away with it by explicitly removing the key here.
|
| 733 |
+
c10::DispatchKey::ADInplaceOrView);
|
| 734 |
+
|
| 735 |
+
constexpr DispatchKeySet backend_bitset_mask =
|
| 736 |
+
DispatchKeySet(DispatchKeySet::RAW, (1ULL << num_backends) - 1);
|
| 737 |
+
|
| 738 |
+
constexpr auto inplace_or_view_ks =
|
| 739 |
+
DispatchKeySet(DispatchKey::ADInplaceOrView);
|
| 740 |
+
constexpr auto autograd_cpu_ks = DispatchKeySet(DispatchKey::AutogradCPU);
|
| 741 |
+
constexpr auto autograd_ipu_ks = DispatchKeySet(DispatchKey::AutogradIPU);
|
| 742 |
+
constexpr auto autograd_xpu_ks = DispatchKeySet(DispatchKey::AutogradXPU);
|
| 743 |
+
constexpr auto autograd_cuda_ks = DispatchKeySet(DispatchKey::AutogradCUDA);
|
| 744 |
+
constexpr auto autograd_xla_ks = DispatchKeySet(DispatchKey::AutogradXLA);
|
| 745 |
+
constexpr auto autograd_lazy_ks = DispatchKeySet(DispatchKey::AutogradLazy);
|
| 746 |
+
constexpr auto autograd_meta_ks = DispatchKeySet(DispatchKey::AutogradMeta);
|
| 747 |
+
constexpr auto autograd_mps_ks = DispatchKeySet(DispatchKey::AutogradMPS);
|
| 748 |
+
constexpr auto autograd_hpu_ks = DispatchKeySet(DispatchKey::AutogradHPU);
|
| 749 |
+
constexpr auto autograd_privateuse1_ks =
|
| 750 |
+
DispatchKeySet(DispatchKey::AutogradPrivateUse1);
|
| 751 |
+
constexpr auto autograd_privateuse2_ks =
|
| 752 |
+
DispatchKeySet(DispatchKey::AutogradPrivateUse2);
|
| 753 |
+
constexpr auto autograd_privateuse3_ks =
|
| 754 |
+
DispatchKeySet(DispatchKey::AutogradPrivateUse3);
|
| 755 |
+
constexpr auto autograd_other_ks = DispatchKeySet(DispatchKey::AutogradOther);
|
| 756 |
+
constexpr auto autograd_nested =
|
| 757 |
+
DispatchKeySet(DispatchKey::AutogradNestedTensor);
|
| 758 |
+
// keyset corresponding to functorch keys that have their own dedicated
|
| 759 |
+
// TensorImpl subclass.
|
| 760 |
+
constexpr auto functorch_transforms_ks = DispatchKeySet(
|
| 761 |
+
{DispatchKey::FuncTorchBatched,
|
| 762 |
+
DispatchKey::FuncTorchVmapMode,
|
| 763 |
+
DispatchKey::Batched,
|
| 764 |
+
DispatchKey::VmapMode,
|
| 765 |
+
DispatchKey::FuncTorchGradWrapper});
|
| 766 |
+
|
| 767 |
+
constexpr auto functorch_batched_ks =
|
| 768 |
+
DispatchKeySet({DispatchKey::FuncTorchBatched});
|
| 769 |
+
|
| 770 |
+
// This keyset has:
|
| 771 |
+
// (1) the functionality bits corresponding to backends (dense, sparse,
|
| 772 |
+
// quantized) (2) all of the backend bits set
|
| 773 |
+
constexpr DispatchKeySet backend_functionality_keys =
|
| 774 |
+
DispatchKeySet({
|
| 775 |
+
DispatchKey::Dense,
|
| 776 |
+
DispatchKey::Quantized,
|
| 777 |
+
DispatchKey::Sparse,
|
| 778 |
+
}) |
|
| 779 |
+
DispatchKeySet(DispatchKeySet::RAW, full_backend_mask);
|
| 780 |
+
|
| 781 |
+
struct OpTableOffsetAndMask {
|
| 782 |
+
uint16_t offset;
|
| 783 |
+
uint16_t backend_mask;
|
| 784 |
+
};
|
| 785 |
+
|
| 786 |
+
static_assert(
|
| 787 |
+
num_backends <= 16,
|
| 788 |
+
"Right now we expect the number of backends not to exceed 16. In the (unlikely) event"
|
| 789 |
+
" that this changes, the size of OpTableOffsetAndMask::backend_mask needs to be increased too.");
|
| 790 |
+
|
| 791 |
+
// true if t is a backend dispatch key
|
| 792 |
+
C10_API bool isBackendDispatchKey(DispatchKey t);
|
| 793 |
+
|
| 794 |
+
// Resolve alias dispatch key to DispatchKeySet if applicable
|
| 795 |
+
C10_API DispatchKeySet getRuntimeDispatchKeySet(DispatchKey t);
|
| 796 |
+
|
| 797 |
+
// Resolve alias dispatch key to DispatchKeySet if applicable,
|
| 798 |
+
// and chek if k is a part of that set
|
| 799 |
+
C10_API bool runtimeDispatchKeySetHas(DispatchKey t, DispatchKey k);
|
| 800 |
+
|
| 801 |
+
// Returns a DispatchKeySet of all backend keys mapped to Autograd dispatch key
|
| 802 |
+
// t, DispatchKeySet is empty if t is not alias of DispatchKey::Autograd.
|
| 803 |
+
C10_API DispatchKeySet getBackendKeySetFromAutograd(DispatchKey t);
|
| 804 |
+
|
| 805 |
+
// Returns a DispatchKeySet of autograd related keys mapped to backend.
|
| 806 |
+
// for a given backend key, use the associated autograd key.
|
| 807 |
+
// for non-backend keys, use AutogradOther as a default.
|
| 808 |
+
// Note: it's convenient and fast to return a default here rather than (say)
|
| 809 |
+
// returning an optional<DispatchKey>, or throwing. But it makes callers
|
| 810 |
+
// responsible for either a) enforcing the invariant that only backend keys
|
| 811 |
+
// be passed as arguments, or b) interpreting our return value carefully.
|
| 812 |
+
inline DispatchKeySet getAutogradRelatedKeySetFromBackend(BackendComponent t) {
|
| 813 |
+
switch (t) {
|
| 814 |
+
case BackendComponent::CPUBit:
|
| 815 |
+
return inplace_or_view_ks | autograd_cpu_ks;
|
| 816 |
+
case BackendComponent::IPUBit:
|
| 817 |
+
return inplace_or_view_ks | autograd_ipu_ks;
|
| 818 |
+
case BackendComponent::XPUBit:
|
| 819 |
+
return inplace_or_view_ks | autograd_xpu_ks;
|
| 820 |
+
case BackendComponent::CUDABit:
|
| 821 |
+
return inplace_or_view_ks | autograd_cuda_ks;
|
| 822 |
+
case BackendComponent::XLABit:
|
| 823 |
+
return inplace_or_view_ks | autograd_xla_ks;
|
| 824 |
+
case BackendComponent::LazyBit:
|
| 825 |
+
return inplace_or_view_ks | autograd_lazy_ks;
|
| 826 |
+
case BackendComponent::MetaBit:
|
| 827 |
+
return inplace_or_view_ks | autograd_meta_ks;
|
| 828 |
+
case BackendComponent::MPSBit:
|
| 829 |
+
return inplace_or_view_ks | autograd_mps_ks;
|
| 830 |
+
case BackendComponent::HPUBit:
|
| 831 |
+
return inplace_or_view_ks | autograd_hpu_ks;
|
| 832 |
+
case BackendComponent::PrivateUse1Bit:
|
| 833 |
+
return inplace_or_view_ks | autograd_privateuse1_ks;
|
| 834 |
+
case BackendComponent::PrivateUse2Bit:
|
| 835 |
+
return inplace_or_view_ks | autograd_privateuse2_ks;
|
| 836 |
+
case BackendComponent::PrivateUse3Bit:
|
| 837 |
+
return inplace_or_view_ks | autograd_privateuse3_ks;
|
| 838 |
+
default:
|
| 839 |
+
return inplace_or_view_ks | autograd_other_ks;
|
| 840 |
+
}
|
| 841 |
+
}
|
| 842 |
+
|
| 843 |
+
// Returns a DispatchKeySet of autocast related keys mapped to backend.
|
| 844 |
+
inline DispatchKeySet getAutocastRelatedKeySetFromBackend(BackendComponent t) {
|
| 845 |
+
constexpr auto autocast_cpu_ks = DispatchKeySet(DispatchKey::AutocastCPU);
|
| 846 |
+
constexpr auto autocast_xpu_ks = DispatchKeySet(DispatchKey::AutocastXPU);
|
| 847 |
+
constexpr auto autocast_ipu_ks = DispatchKeySet(DispatchKey::AutocastIPU);
|
| 848 |
+
constexpr auto autocast_hpu_ks = DispatchKeySet(DispatchKey::AutocastHPU);
|
| 849 |
+
constexpr auto autocast_cuda_ks = DispatchKeySet(DispatchKey::AutocastCUDA);
|
| 850 |
+
constexpr auto autocast_xla_ks = DispatchKeySet(DispatchKey::AutocastXLA);
|
| 851 |
+
constexpr auto autocast_privateuse1_ks =
|
| 852 |
+
DispatchKeySet(DispatchKey::AutocastPrivateUse1);
|
| 853 |
+
switch (t) {
|
| 854 |
+
case BackendComponent::CPUBit:
|
| 855 |
+
return autocast_cpu_ks;
|
| 856 |
+
case BackendComponent::XPUBit:
|
| 857 |
+
return autocast_xpu_ks;
|
| 858 |
+
case BackendComponent::IPUBit:
|
| 859 |
+
return autocast_ipu_ks;
|
| 860 |
+
case BackendComponent::HPUBit:
|
| 861 |
+
return autocast_hpu_ks;
|
| 862 |
+
case BackendComponent::CUDABit:
|
| 863 |
+
return autocast_cuda_ks;
|
| 864 |
+
case BackendComponent::XLABit:
|
| 865 |
+
return autocast_xla_ks;
|
| 866 |
+
case BackendComponent::PrivateUse1Bit:
|
| 867 |
+
return autocast_privateuse1_ks;
|
| 868 |
+
default:
|
| 869 |
+
return DispatchKeySet();
|
| 870 |
+
}
|
| 871 |
+
}
|
| 872 |
+
|
| 873 |
+
// returns the "backend" DispatchKey of highest priority in the set.
|
| 874 |
+
// This is basically like highestBackendKey(), except that we have some
|
| 875 |
+
// "functionality" bits that correspond to backends (Sparse, Quantized)
|
| 876 |
+
inline DispatchKey highestPriorityBackendTypeId(DispatchKeySet ks) {
|
| 877 |
+
return (ks & backend_functionality_keys).highestPriorityTypeId();
|
| 878 |
+
}
|
| 879 |
+
|
| 880 |
+
// This API exists because we have a use case for checking
|
| 881 |
+
// getRuntimeDispatchKeySet(alias).has(DispatchKey::Undefined)
|
| 882 |
+
// in OperatorEntry.cpp but we disallow it in has() API.
|
| 883 |
+
C10_API bool isIncludedInAlias(DispatchKey k, DispatchKey alias);
|
| 884 |
+
|
| 885 |
+
// Historically, every tensor only had a single DispatchKey, and it was always
|
| 886 |
+
// something like CPU, and there wasn't any of this business where TLS
|
| 887 |
+
// could cause the DispatchKey of a tensor to change. But we still have some
|
| 888 |
+
// legacy code that is still using DispatchKey for things like instanceof
|
| 889 |
+
// checks; if at all possible, refactor the code to stop using DispatchKey in
|
| 890 |
+
// those cases.
|
| 891 |
+
static inline DispatchKey legacyExtractDispatchKey(DispatchKeySet s) {
|
| 892 |
+
// NB: If you add any extra keys that can be stored in TensorImpl on
|
| 893 |
+
// top of existing "backend" keys like CPU/CUDA, you need to add it
|
| 894 |
+
// here. At the moment, autograd keys and ADInplaceOrView key need this
|
| 895 |
+
// treatment;
|
| 896 |
+
return (s - autograd_dispatch_keyset_with_ADInplaceOrView -
|
| 897 |
+
autocast_dispatch_keyset -
|
| 898 |
+
DispatchKeySet(
|
| 899 |
+
{DispatchKey::Functionalize,
|
| 900 |
+
DispatchKey::PythonTLSSnapshot,
|
| 901 |
+
DispatchKey::Python}))
|
| 902 |
+
.highestPriorityTypeId();
|
| 903 |
+
}
|
| 904 |
+
|
| 905 |
+
template <class T>
|
| 906 |
+
using is_not_DispatchKeySet = guts::negation<std::is_same<DispatchKeySet, T>>;
|
| 907 |
+
|
| 908 |
+
// Given a function type, constructs a function_traits type that drops the first
|
| 909 |
+
// parameter type if the first parameter is of type DispatchKeySet. NB:
|
| 910 |
+
// DispatchKeySet is currently explicitly hidden from JIT (mainly to avoid
|
| 911 |
+
// pushing unnecessary arguments on the stack - see Note [ Plumbing Keys Through
|
| 912 |
+
// the Dispatcher] for details). If at any point in the future we need to expose
|
| 913 |
+
// this type to JIT, revisit the usage of this type alias.
|
| 914 |
+
template <class FuncType>
|
| 915 |
+
using remove_DispatchKeySet_arg_from_func = guts::make_function_traits_t<
|
| 916 |
+
typename guts::infer_function_traits_t<FuncType>::return_type,
|
| 917 |
+
typename std::conditional_t<
|
| 918 |
+
std::is_same<
|
| 919 |
+
DispatchKeySet,
|
| 920 |
+
typename guts::typelist::head_with_default_t<
|
| 921 |
+
void,
|
| 922 |
+
typename guts::infer_function_traits_t<
|
| 923 |
+
FuncType>::parameter_types>>::value,
|
| 924 |
+
guts::typelist::drop_if_nonempty_t<
|
| 925 |
+
typename guts::infer_function_traits_t<FuncType>::parameter_types,
|
| 926 |
+
1>,
|
| 927 |
+
typename guts::infer_function_traits_t<FuncType>::parameter_types>>;
|
| 928 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/DynamicCast.h
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/ScalarType.h>
|
| 4 |
+
#include <c10/macros/Macros.h>
|
| 5 |
+
#include <c10/util/Load.h>
|
| 6 |
+
#include <c10/util/TypeCast.h>
|
| 7 |
+
|
| 8 |
+
namespace c10 {
|
| 9 |
+
|
| 10 |
+
// Dynamic type casting utils:
|
| 11 |
+
// - fetch_and_cast
|
| 12 |
+
// - cast_and_store
|
| 13 |
+
//
|
| 14 |
+
// fetch_and_cast fetch a value with dynamic type specified by a ScalarType
|
| 15 |
+
// from a void pointer and cast it to a static type.
|
| 16 |
+
//
|
| 17 |
+
// cast_and_store casts a static typed value into dynamic type specified
|
| 18 |
+
// by a ScalarType, and store it into a void pointer.
|
| 19 |
+
//
|
| 20 |
+
// NOTE:
|
| 21 |
+
//
|
| 22 |
+
// Dynamic casting allows us to support type promotion without blowing up
|
| 23 |
+
// the combination space: For example, without dynamic cast, in order to
|
| 24 |
+
// implement `add_` with type promotion, we would need something like
|
| 25 |
+
//
|
| 26 |
+
// AT_DISPATCH_ALL_TYPES(output.dtype(),
|
| 27 |
+
// AT_DISPATCH_ALL_TYPES(input1.dtype(),
|
| 28 |
+
// AT_DISPATCH_ALL_TYPES(input2.dtype(),
|
| 29 |
+
// [](arg0_t a, arg1_t b) -> out_t { return a + b; }
|
| 30 |
+
// )
|
| 31 |
+
// )
|
| 32 |
+
// )
|
| 33 |
+
//
|
| 34 |
+
// If we support N dtypes, the above code would generate the a+b kernel for
|
| 35 |
+
// all the N * N * N different supported types, the compilation time and
|
| 36 |
+
// binary size would become horrible.
|
| 37 |
+
//
|
| 38 |
+
// Dynamic casting might sounds like a bad idea in terms of performance.
|
| 39 |
+
// Especially if you ever do it in a loop, you are going to do a billion tests.
|
| 40 |
+
// But in practice it is not as bad as it might look:
|
| 41 |
+
//
|
| 42 |
+
// - on CPU, this is a branch that always has the same outcome, therefore
|
| 43 |
+
// hopefully the branch predictor could do the job pretty well
|
| 44 |
+
// - on GPU, these branches will not diverge, so we could still have the same
|
| 45 |
+
// warp executing the same line of code
|
| 46 |
+
// - Most kernels, like `add`, are bandwidth bound, adding a few clock cycles to
|
| 47 |
+
// check an integer does not hurt the performance much because the ALUs would
|
| 48 |
+
// wait for load instructions anyway.
|
| 49 |
+
//
|
| 50 |
+
// For the discussion and benchmark, refer to:
|
| 51 |
+
// - https://github.com/pytorch/pytorch/pull/28343
|
| 52 |
+
// - https://github.com/pytorch/pytorch/pull/28344
|
| 53 |
+
// - https://github.com/pytorch/pytorch/pull/28345
|
| 54 |
+
//
|
| 55 |
+
|
| 56 |
+
#ifdef C10_HOST_DEVICE
|
| 57 |
+
#define ERROR_UNSUPPORTED_CAST CUDA_KERNEL_ASSERT(false);
|
| 58 |
+
#else
|
| 59 |
+
#define ERROR_UNSUPPORTED_CAST TORCH_CHECK(false, "Unexpected scalar type");
|
| 60 |
+
#endif
|
| 61 |
+
|
| 62 |
+
// Fetch a value with dynamic type src_type from ptr, and cast it to static type
|
| 63 |
+
// dest_t.
|
| 64 |
+
#define FETCH_AND_CAST_CASE(type, scalartype) \
|
| 65 |
+
case ScalarType::scalartype: \
|
| 66 |
+
return c10::convert<dest_t>(c10::load<type>(ptr));
|
| 67 |
+
|
| 68 |
+
template <typename dest_t>
|
| 69 |
+
C10_HOST_DEVICE inline dest_t fetch_and_cast(
|
| 70 |
+
const ScalarType src_type,
|
| 71 |
+
const void* ptr) {
|
| 72 |
+
switch (src_type) {
|
| 73 |
+
AT_FORALL_SCALAR_TYPES_WITH_COMPLEX(FETCH_AND_CAST_CASE)
|
| 74 |
+
default:
|
| 75 |
+
ERROR_UNSUPPORTED_CAST
|
| 76 |
+
}
|
| 77 |
+
return dest_t(0); // just to avoid compiler warning
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
// Cast a value with static type src_t into dynamic dest_type, and store it to
|
| 81 |
+
// ptr.
|
| 82 |
+
#define CAST_AND_STORE_CASE(type, scalartype) \
|
| 83 |
+
case ScalarType::scalartype: \
|
| 84 |
+
*(type*)ptr = c10::convert<type>(value); \
|
| 85 |
+
return;
|
| 86 |
+
template <typename src_t>
|
| 87 |
+
C10_HOST_DEVICE inline void cast_and_store(
|
| 88 |
+
const ScalarType dest_type,
|
| 89 |
+
void* ptr,
|
| 90 |
+
src_t value) {
|
| 91 |
+
switch (dest_type) {
|
| 92 |
+
AT_FORALL_SCALAR_TYPES_WITH_COMPLEX(CAST_AND_STORE_CASE)
|
| 93 |
+
default:;
|
| 94 |
+
}
|
| 95 |
+
ERROR_UNSUPPORTED_CAST
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
#define DEFINE_UNCASTABLE(T, scalartype_) \
|
| 99 |
+
template <> \
|
| 100 |
+
C10_HOST_DEVICE inline T fetch_and_cast<T>( \
|
| 101 |
+
const ScalarType src_type, const void* ptr) { \
|
| 102 |
+
CUDA_KERNEL_ASSERT(ScalarType::scalartype_ == src_type); \
|
| 103 |
+
return c10::load<T>(ptr); \
|
| 104 |
+
} \
|
| 105 |
+
template <> \
|
| 106 |
+
C10_HOST_DEVICE inline void cast_and_store<T>( \
|
| 107 |
+
const ScalarType dest_type, void* ptr, T value) { \
|
| 108 |
+
CUDA_KERNEL_ASSERT(ScalarType::scalartype_ == dest_type); \
|
| 109 |
+
*(T*)ptr = value; \
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
AT_FORALL_QINT_TYPES(DEFINE_UNCASTABLE)
|
| 113 |
+
|
| 114 |
+
#undef FETCH_AND_CAST_CASE
|
| 115 |
+
#undef CAST_AND_STORE_CASE
|
| 116 |
+
#undef DEFINE_UNCASTABLE
|
| 117 |
+
#undef ERROR_UNSUPPORTED_CAST
|
| 118 |
+
|
| 119 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/Event.h
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <c10/core/impl/InlineEvent.h>
|
| 4 |
+
#include <c10/core/impl/VirtualGuardImpl.h>
|
| 5 |
+
|
| 6 |
+
namespace c10 {
|
| 7 |
+
|
| 8 |
+
/**
|
| 9 |
+
* A backend-generic movable, not copyable, not thread-safe event.
|
| 10 |
+
*
|
| 11 |
+
* The design of this event follows that of CUDA and HIP events. These events
|
| 12 |
+
* are recorded and waited on by streams and can be rerecorded to,
|
| 13 |
+
* each rerecording essentially creating a new version of the event.
|
| 14 |
+
* For example, if (in CPU time), stream X is asked to record E,
|
| 15 |
+
* stream Y waits on E, and stream X is asked to record E again, then Y will
|
| 16 |
+
* wait for X to finish the first call to record and not the second, because
|
| 17 |
+
* it's waiting on the first version of event E, not the second.
|
| 18 |
+
* Querying an event only returns the status of its most recent version.
|
| 19 |
+
*
|
| 20 |
+
* Backend-generic events are implemented by this class and
|
| 21 |
+
* impl::InlineEvent. In addition to these events there are also
|
| 22 |
+
* some backend-specific events, like ATen's CUDAEvent. Each of these
|
| 23 |
+
* classes has its own use.
|
| 24 |
+
*
|
| 25 |
+
* impl::InlineEvent<...> or a backend-specific event should be
|
| 26 |
+
* preferred when the backend is known at compile time and known to
|
| 27 |
+
* be compiled. Backend-specific events may have additional functionality.
|
| 28 |
+
*
|
| 29 |
+
* This Event should be used if a particular backend may not be available,
|
| 30 |
+
* or the backend required is not known at compile time.
|
| 31 |
+
*
|
| 32 |
+
* These generic events are built on top of DeviceGuardImpls, analogous
|
| 33 |
+
* to DeviceGuard and InlineDeviceGuard. The name "DeviceGuardImpls,"
|
| 34 |
+
* is no longer entirely accurate, as these classes implement the
|
| 35 |
+
* backend-specific logic for a generic backend interface.
|
| 36 |
+
*
|
| 37 |
+
* See DeviceGuardImplInterface.h for a list of all supported flags.
|
| 38 |
+
*/
|
| 39 |
+
|
| 40 |
+
struct Event final {
|
| 41 |
+
// Constructors
|
| 42 |
+
Event() = delete;
|
| 43 |
+
Event(
|
| 44 |
+
const DeviceType _device_type,
|
| 45 |
+
const EventFlag _flag = EventFlag::PYTORCH_DEFAULT)
|
| 46 |
+
: impl_{_device_type, _flag} {}
|
| 47 |
+
|
| 48 |
+
// Copy constructor and copy assignment operator (deleted)
|
| 49 |
+
Event(const Event&) = delete;
|
| 50 |
+
Event& operator=(const Event&) = delete;
|
| 51 |
+
|
| 52 |
+
// Move constructor and move assignment operator
|
| 53 |
+
Event(Event&& other) noexcept : impl_{std::move(other.impl_)} {}
|
| 54 |
+
Event& operator=(Event&& other) noexcept {
|
| 55 |
+
impl_.swap(std::move(other.impl_));
|
| 56 |
+
return *this;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
// Destructor
|
| 60 |
+
~Event() = default;
|
| 61 |
+
|
| 62 |
+
// Getters
|
| 63 |
+
Device device() const noexcept {
|
| 64 |
+
return Device(device_type(), device_index());
|
| 65 |
+
}
|
| 66 |
+
DeviceType device_type() const noexcept {
|
| 67 |
+
return impl_.device_type();
|
| 68 |
+
}
|
| 69 |
+
DeviceIndex device_index() const noexcept {
|
| 70 |
+
return impl_.device_index();
|
| 71 |
+
}
|
| 72 |
+
EventFlag flag() const noexcept {
|
| 73 |
+
return impl_.flag();
|
| 74 |
+
}
|
| 75 |
+
bool was_marked_for_recording() const noexcept {
|
| 76 |
+
return impl_.was_marked_for_recording();
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
/**
|
| 80 |
+
* Calls record() if and only if record() has never been called for this
|
| 81 |
+
* event. Note: because Event is not thread-safe recordOnce() may call
|
| 82 |
+
* record() multiple times if called from multiple threads.
|
| 83 |
+
*/
|
| 84 |
+
void recordOnce(const Stream& stream) {
|
| 85 |
+
impl_.recordOnce(stream);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
/**
|
| 89 |
+
* Increments the event's version and enqueues a job with this version
|
| 90 |
+
* in the stream's work queue. When the stream process that job
|
| 91 |
+
* it notifies all streams waiting on / blocked by that version of the
|
| 92 |
+
* event to continue and marks that version as recorded.
|
| 93 |
+
* */
|
| 94 |
+
void record(const Stream& stream) {
|
| 95 |
+
impl_.record(stream);
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
/**
|
| 99 |
+
* Does nothing if the event has not been scheduled to be recorded.
|
| 100 |
+
* If the event was previously enqueued to be recorded, a command
|
| 101 |
+
* to wait for the version of the event that exists at the time of this call
|
| 102 |
+
* is inserted in the stream's work queue.
|
| 103 |
+
* When the stream reaches this command it will stop processing
|
| 104 |
+
* additional commands until that version of the event is marked as recorded.
|
| 105 |
+
*/
|
| 106 |
+
void block(const Stream& stream) const {
|
| 107 |
+
impl_.block(stream);
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
/**
|
| 111 |
+
* Returns true if (and only if)
|
| 112 |
+
* (1) the event has never been scheduled to be recorded
|
| 113 |
+
* (2) the current version is marked as recorded.
|
| 114 |
+
* Returns false otherwise.
|
| 115 |
+
*/
|
| 116 |
+
bool query() const {
|
| 117 |
+
return impl_.query();
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
private:
|
| 121 |
+
impl::InlineEvent<impl::VirtualGuardImpl> impl_;
|
| 122 |
+
};
|
| 123 |
+
|
| 124 |
+
} // namespace c10
|
rtme/lib/python3.10/site-packages/torch/include/c10/core/GeneratorImpl.h
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <stdint.h>
|
| 4 |
+
#include <mutex>
|
| 5 |
+
|
| 6 |
+
#include <c10/core/Device.h>
|
| 7 |
+
#include <c10/core/DispatchKeySet.h>
|
| 8 |
+
#include <c10/core/TensorImpl.h>
|
| 9 |
+
#include <c10/macros/Export.h>
|
| 10 |
+
#include <c10/util/intrusive_ptr.h>
|
| 11 |
+
#include <c10/util/python_stub.h>
|
| 12 |
+
|
| 13 |
+
/**
|
| 14 |
+
* Note [Generator]
|
| 15 |
+
* ~~~~~~~~~~~~~~~~
|
| 16 |
+
* A Pseudo Random Number Generator (PRNG) is an engine that uses an algorithm
|
| 17 |
+
* to generate a seemingly random sequence of numbers, that may be later be used
|
| 18 |
+
* in creating a random distribution. Such an engine almost always maintains a
|
| 19 |
+
* state and requires a seed to start off the creation of random numbers. Often
|
| 20 |
+
* times, users have found it beneficial to be able to explicitly create,
|
| 21 |
+
* retain, and destroy PRNG states and also be able to have control over the
|
| 22 |
+
* seed value.
|
| 23 |
+
*
|
| 24 |
+
* A Generator in ATen gives users the ability to read, write and modify a PRNG
|
| 25 |
+
* engine. For instance, it does so by letting users seed a PRNG engine, fork
|
| 26 |
+
* the state of the engine, etc.
|
| 27 |
+
*
|
| 28 |
+
* By default, there is one generator per device, and a device's generator is
|
| 29 |
+
* lazily created. A user can use the torch.Generator() api to create their own
|
| 30 |
+
* generator. Currently torch.Generator() can only create a CPUGeneratorImpl.
|
| 31 |
+
*/
|
| 32 |
+
|
| 33 |
+
/**
|
| 34 |
+
* Note [Acquire lock when using random generators]
|
| 35 |
+
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 36 |
+
* Generator and its derived classes are NOT thread-safe. Please note that most
|
| 37 |
+
* of the places where we have inserted locking for generators are historically
|
| 38 |
+
* based, and we haven't actually checked that everything is truly thread safe
|
| 39 |
+
* (and it probably isn't). Please use the public mutex_ when using any methods
|
| 40 |
+
* from these classes, except for the read-only methods. You can learn about the
|
| 41 |
+
* usage by looking into the unittests (aten/src/ATen/cpu_generator_test.cpp)
|
| 42 |
+
* and other places where we have used lock_guard.
|
| 43 |
+
*
|
| 44 |
+
* TODO: Look into changing the threading semantics of Generators in ATen (e.g.,
|
| 45 |
+
* making them non-thread safe and instead making the generator state
|
| 46 |
+
* splittable, to accommodate forks into other threads).
|
| 47 |
+
*/
|
| 48 |
+
|
| 49 |
+
namespace c10 {
|
| 50 |
+
|
| 51 |
+
// The default seed is selected to be a large number
|
| 52 |
+
// with good distribution of 0s and 1s in bit representation
|
| 53 |
+
constexpr uint64_t default_rng_seed_val = 67280421310721;
|
| 54 |
+
|
| 55 |
+
struct C10_API GeneratorImpl : public c10::intrusive_ptr_target {
|
| 56 |
+
// Constructors
|
| 57 |
+
GeneratorImpl(Device device_in, DispatchKeySet key_set);
|
| 58 |
+
|
| 59 |
+
// Delete all copy and move assignment in favor of clone()
|
| 60 |
+
// method
|
| 61 |
+
GeneratorImpl(const GeneratorImpl& other) = delete;
|
| 62 |
+
GeneratorImpl(GeneratorImpl&& other) = delete;
|
| 63 |
+
GeneratorImpl& operator=(const GeneratorImpl& other) = delete;
|
| 64 |
+
|
| 65 |
+
~GeneratorImpl() override = default;
|
| 66 |
+
c10::intrusive_ptr<GeneratorImpl> clone() const;
|
| 67 |
+
|
| 68 |
+
// Common methods for all generators
|
| 69 |
+
virtual void set_current_seed(uint64_t seed) = 0;
|
| 70 |
+
virtual void set_offset(uint64_t offset) = 0;
|
| 71 |
+
virtual uint64_t get_offset() const = 0;
|
| 72 |
+
virtual uint64_t current_seed() const = 0;
|
| 73 |
+
virtual uint64_t seed() = 0;
|
| 74 |
+
virtual void set_state(const c10::TensorImpl& new_state) = 0;
|
| 75 |
+
virtual c10::intrusive_ptr<c10::TensorImpl> get_state() const = 0;
|
| 76 |
+
Device device() const;
|
| 77 |
+
|
| 78 |
+
// See Note [Acquire lock when using random generators]
|
| 79 |
+
std::mutex mutex_;
|
| 80 |
+
|
| 81 |
+
DispatchKeySet key_set() const {
|
| 82 |
+
return key_set_;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
inline void set_pyobj(PyObject* pyobj) noexcept {
|
| 86 |
+
pyobj_ = pyobj;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
inline PyObject* pyobj() const noexcept {
|
| 90 |
+
return pyobj_;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
protected:
|
| 94 |
+
Device device_;
|
| 95 |
+
DispatchKeySet key_set_;
|
| 96 |
+
PyObject* pyobj_ = nullptr;
|
| 97 |
+
|
| 98 |
+
virtual GeneratorImpl* clone_impl() const = 0;
|
| 99 |
+
};
|
| 100 |
+
|
| 101 |
+
namespace detail {
|
| 102 |
+
|
| 103 |
+
C10_API uint64_t getNonDeterministicRandom(bool is_cuda = false);
|
| 104 |
+
|
| 105 |
+
} // namespace detail
|
| 106 |
+
|
| 107 |
+
} // namespace c10
|