diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_copy_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_copy_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..20cf4e4b04df3052f1e4f1b608f5921ec4a6ebd3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_copy_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor unsqueeze_copy(const at::Tensor & self, int64_t dim); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_copy_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_copy_native.h new file mode 100644 index 0000000000000000000000000000000000000000..fcfd8458b0ea2f9f5350058df81036817f242295 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_copy_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor & unsqueeze_copy_out(const at::Tensor & self, int64_t dim, at::Tensor & out); +TORCH_API at::Tensor unsqueeze_copy(const at::Tensor & self, int64_t dim); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_copy_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_copy_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..a444f4f2a0fbb0efffd9b27e941d01efd66c585d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_copy_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API unsqueeze_copy { + using schema = at::Tensor (const at::Tensor &, int64_t); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::unsqueeze_copy"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "unsqueeze_copy(Tensor self, int dim) -> Tensor"; + static at::Tensor call(const at::Tensor & self, int64_t dim); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, int64_t dim); +}; + +struct TORCH_API unsqueeze_copy_out { + using schema = at::Tensor & (const at::Tensor &, int64_t, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::unsqueeze_copy"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "unsqueeze_copy.out(Tensor self, int dim, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, int64_t dim, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, int64_t dim, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_native.h new file mode 100644 index 0000000000000000000000000000000000000000..ee4f1c7e8f03673dff756b013e00a237f7c54615 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_native.h @@ -0,0 +1,30 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor unsqueeze(const at::Tensor & self, int64_t dim); +TORCH_API at::Tensor unsqueeze_nested(const at::Tensor & self, int64_t dim); +TORCH_API at::Tensor unsqueeze_sparse(const at::Tensor & self, int64_t dim); +TORCH_API at::Tensor unsqueeze_quantized(const at::Tensor & self, int64_t dim); +TORCH_API at::Tensor & unsqueeze_(at::Tensor & self, int64_t dim); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..dbffca2bb8d09fc1c70114a1199e81e0f3b15173 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/unsqueeze_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API unsqueeze { + using schema = at::Tensor (const at::Tensor &, int64_t); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::unsqueeze"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "unsqueeze(Tensor(a) self, int dim) -> Tensor(a)"; + static at::Tensor call(const at::Tensor & self, int64_t dim); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, int64_t dim); +}; + +struct TORCH_API unsqueeze_ { + using schema = at::Tensor & (at::Tensor &, int64_t); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::unsqueeze_"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "unsqueeze_(Tensor(a!) self, int dim) -> Tensor(a!)"; + static at::Tensor & call(at::Tensor & self, int64_t dim); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::Tensor & self, int64_t dim); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d.h new file mode 100644 index 0000000000000000000000000000000000000000..40ac94660d1123313c0918aa5f985dae27c4eaae --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d.h @@ -0,0 +1,119 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_bicubic2d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_bicubic2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bicubic2d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_bicubic2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bicubic2d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors); + } +} + +// aten::upsample_bicubic2d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_bicubic2d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bicubic2d_vec::call(input, output_size, align_corners, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_bicubic2d(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bicubic2d_vec::call(input, output_size, align_corners, scale_factors); + } +} + +// aten::upsample_bicubic2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bicubic2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_bicubic2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w, out); + } +} + +// aten::upsample_bicubic2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bicubic2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_bicubic2d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_bicubic2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_bicubic2d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w, out); + } +} + +// aten::upsample_bicubic2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bicubic2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_out::call(self, output_size, align_corners, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_bicubic2d_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_out::call(self, output_size, align_corners, scales_h, scales_w, out); + } +} + +// aten::upsample_bicubic2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bicubic2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_bicubic2d_out::call(self, output_size, align_corners, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_bicubic2d_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_bicubic2d_out::call(self, output_size, align_corners, scales_h, scales_w, out); + } +} + +// aten::upsample_bicubic2d(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_bicubic2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_bicubic2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w); + } +} + +// aten::upsample_bicubic2d(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_bicubic2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d::call(self, output_size, align_corners, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_bicubic2d(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d::call(self, output_size, align_corners, scales_h, scales_w); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward.h new file mode 100644 index 0000000000000000000000000000000000000000..0f2be3c3bc850bbe6bc41b570c55db02906003e8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward.h @@ -0,0 +1,97 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_bicubic2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_bicubic2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_bicubic2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_bicubic2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_bicubic2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_bicubic2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_bicubic2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_bicubic2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_bicubic2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_bicubic2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_bicubic2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_bicubic2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_bicubic2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_bicubic2d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_bicubic2d_backward_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_bicubic2d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_bicubic2d_backward(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_bicubic2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_bicubic2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w); + } +} + +// aten::upsample_bicubic2d_backward(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_bicubic2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_backward::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_bicubic2d_backward(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bicubic2d_backward::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..7567f31cd9b7e4a53538ce181be7c8795a0a22ae --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_bicubic2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bicubic2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..9f1194aac6e7656eff0f5e07e7b8ba285fb4d21b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_bicubic2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bicubic2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_bicubic2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..173fc82eebb383b7fbc07bd2f1ca11cb4b1eee44 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_bicubic2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bicubic2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_bicubic2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..cffa012cdb346f2f1b4cc2a4f80e482905e21303 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_bicubic2d_backward : public at::impl::MetaBase { + + + void meta(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..2cc5944f4909fb480a05e69f56f1a1d6ecd7239a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_bicubic2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bicubic2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_bicubic2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_native.h new file mode 100644 index 0000000000000000000000000000000000000000..0333a84df7da19ecc48abe14f0376c712dbc464a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_native.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +struct TORCH_API structured_upsample_bicubic2d_backward_out_cpu : public at::meta::structured_upsample_bicubic2d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +struct TORCH_API structured_upsample_bicubic2d_backward_out_cuda : public at::meta::structured_upsample_bicubic2d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..aefc2b33321600afc15565f6f4016088716cae40 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_backward_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_bicubic2d_backward_grad_input { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bicubic2d_backward"; + static constexpr const char* overload_name = "grad_input"; + static constexpr const char* schema_str = "upsample_bicubic2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +}; + +struct TORCH_API upsample_bicubic2d_backward { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bicubic2d_backward"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_bicubic2d_backward(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..3c1a3374e93b41491d0cb65acb35406f31c0c878 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_bicubic2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bicubic2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..13e4c4df03bea4d18249e33b89df39d6546aa749 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_compositeimplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor upsample_bicubic2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +TORCH_API at::Tensor upsample_bicubic2d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c260c16ac44aef7cfe42b886d8c24af67e868959 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_bicubic2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bicubic2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_bicubic2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..5a3d7de31f90b7e867cdc1f09a5867aa68419625 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_bicubic2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bicubic2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_bicubic2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..3c60a3842083af9404286d3f0e6cb3d2f68e9525 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_bicubic2d : public at::impl::MetaBase { + + + void meta(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..8cdc9d3ac5b3d2dbdfe80644e1bdd0685c3a8822 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_bicubic2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bicubic2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_bicubic2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bicubic2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_native.h new file mode 100644 index 0000000000000000000000000000000000000000..96cf2dced986f8d15e99413a0d6117276bf538c6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_native.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +TORCH_API at::Tensor upsample_bicubic2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +struct TORCH_API structured_upsample_bicubic2d_out_cpu : public at::meta::structured_upsample_bicubic2d { +void impl(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +struct TORCH_API structured_upsample_bicubic2d_out_cuda : public at::meta::structured_upsample_bicubic2d { +void impl(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..9dcb9d4b6a016b9b393e4f88a6d7b6a82100bbb9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bicubic2d_ops.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_bicubic2d_vec { + using schema = at::Tensor (const at::Tensor &, at::OptionalSymIntArrayRef, bool, ::std::optional>); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bicubic2d"; + static constexpr const char* overload_name = "vec"; + static constexpr const char* schema_str = "upsample_bicubic2d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor"; + static at::Tensor call(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +}; + +struct TORCH_API upsample_bicubic2d_out { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bicubic2d"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "upsample_bicubic2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +}; + +struct TORCH_API upsample_bicubic2d { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bicubic2d"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_bicubic2d(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d.h new file mode 100644 index 0000000000000000000000000000000000000000..8225001fee5d5a8b87d438a1ae1884e2d5a26edf --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d.h @@ -0,0 +1,163 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_bilinear2d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_bilinear2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bilinear2d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_bilinear2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bilinear2d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors); + } +} + +// aten::upsample_bilinear2d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_bilinear2d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bilinear2d_vec::call(input, output_size, align_corners, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_bilinear2d(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bilinear2d_vec::call(input, output_size, align_corners, scale_factors); + } +} + +// aten::upsample_bilinear2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w, out); + } +} + +// aten::upsample_bilinear2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_bilinear2d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_bilinear2d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w, out); + } +} + +// aten::upsample_bilinear2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_out::call(self, output_size, align_corners, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_out::call(self, output_size, align_corners, scales_h, scales_w, out); + } +} + +// aten::upsample_bilinear2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_bilinear2d_out::call(self, output_size, align_corners, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_bilinear2d_out::call(self, output_size, align_corners, scales_h, scales_w, out); + } +} + +// aten::upsample_bilinear2d(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_bilinear2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_bilinear2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_h, scales_w); + } +} + +// aten::upsample_bilinear2d(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_bilinear2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d::call(self, output_size, align_corners, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_bilinear2d(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d::call(self, output_size, align_corners, scales_h, scales_w); + } +} + +// aten::upsample_bilinear2d.vec_out(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bilinear2d_vec_out::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors, out); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bilinear2d_vec_out::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors, out); + } +} + +// aten::upsample_bilinear2d.vec_out(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_outf(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors, at::Tensor & out) { + return at::_ops::upsample_bilinear2d_vec_out::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors, out); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_outf(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors, at::Tensor & out) { + return at::_ops::upsample_bilinear2d_vec_out::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors, out); + } +} + +// aten::upsample_bilinear2d.vec_out(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_symint_out(at::Tensor & out, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bilinear2d_vec_out::call(input, output_size, align_corners, scale_factors, out); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_bilinear2d_vec_out::call(input, output_size, align_corners, scale_factors, out); + } +} + +// aten::upsample_bilinear2d.vec_out(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_symint_outf(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors, at::Tensor & out) { + return at::_ops::upsample_bilinear2d_vec_out::call(input, output_size, align_corners, scale_factors, out); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_outf(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors, at::Tensor & out) { + return at::_ops::upsample_bilinear2d_vec_out::call(input, output_size, align_corners, scale_factors, out); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward.h new file mode 100644 index 0000000000000000000000000000000000000000..999d76e19fbf1d46452cdf7f76c9aa4a04c7cae9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward.h @@ -0,0 +1,97 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_bilinear2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_bilinear2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_bilinear2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_bilinear2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_bilinear2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_bilinear2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_bilinear2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_bilinear2d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_bilinear2d_backward_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_bilinear2d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_bilinear2d_backward(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_bilinear2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_bilinear2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_h, scales_w); + } +} + +// aten::upsample_bilinear2d_backward(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_bilinear2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_backward::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_bilinear2d_backward(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_bilinear2d_backward::call(grad_output, output_size, input_size, align_corners, scales_h, scales_w); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..dd09103fab6e507446596c770b57a4f4ca8022bb --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_bilinear2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bilinear2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..f004bb80205b771fbe18a3f372ddbe36f7ebe273 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_bilinear2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bilinear2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_bilinear2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..131ced8a9a8ab26d6dbee953432b04f08eb93782 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_bilinear2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bilinear2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_bilinear2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..83a31a20a91d7d300a3754b1b37cccb1985d1036 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_bilinear2d_backward : public at::impl::MetaBase { + + + void meta(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..ca0646904f0ff8eeed27dfed8d7ba6d038ff0958 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_bilinear2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bilinear2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_bilinear2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_native.h new file mode 100644 index 0000000000000000000000000000000000000000..a3c668a4752ea18b1e04515a17bdef5dfe026585 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_native.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +struct TORCH_API structured_upsample_bilinear2d_backward_out_cpu : public at::meta::structured_upsample_bilinear2d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +struct TORCH_API structured_upsample_bilinear2d_backward_out_cuda : public at::meta::structured_upsample_bilinear2d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..19df49aa5e2d052fdbd28cde1f86f78131901f19 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_backward_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_bilinear2d_backward_grad_input { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bilinear2d_backward"; + static constexpr const char* overload_name = "grad_input"; + static constexpr const char* schema_str = "upsample_bilinear2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +}; + +struct TORCH_API upsample_bilinear2d_backward { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bilinear2d_backward"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_bilinear2d_backward(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..cc556695c6c0d95f8c1fc6692c25d51db00eb6e7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_compositeexplicitautograd_dispatch.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +TORCH_API at::Tensor & upsample_bilinear2d_outf(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors, at::Tensor & out); +TORCH_API at::Tensor & upsample_bilinear2d_symint_out(at::Tensor & out, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +TORCH_API at::Tensor & upsample_bilinear2d_symint_outf(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..26131cf94bb7acb6b525a6cb3fd3a6d548411e3a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_bilinear2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bilinear2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..889234bdd5b2d8a886c5fa3f0a4b864131831648 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_compositeimplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor upsample_bilinear2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +TORCH_API at::Tensor upsample_bilinear2d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c270c71d8bf4b094667812f687ac35881ac21efc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_bilinear2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bilinear2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_bilinear2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..524f6144614ea68067462f4a9422bc27b6075d6d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_bilinear2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bilinear2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_bilinear2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..34e5002a71453a6e2376ee034e5216167c7cf04c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_bilinear2d : public at::impl::MetaBase { + + + void meta(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..8d2905d80cd04a9e19a7f5f0ff07dba8e4bd87c1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_bilinear2d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_bilinear2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_bilinear2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_bilinear2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_native.h new file mode 100644 index 0000000000000000000000000000000000000000..8df5f990b4b9ac40643e7ab350de394bce7c6688 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_native.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +TORCH_API at::Tensor upsample_bilinear2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +TORCH_API at::Tensor & upsample_bilinear2d_vec_out_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors, at::Tensor & out); +struct TORCH_API structured_upsample_bilinear2d_out_cpu : public at::meta::structured_upsample_bilinear2d { +void impl(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +struct TORCH_API structured_upsample_bilinear2d_out_cuda : public at::meta::structured_upsample_bilinear2d { +void impl(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +TORCH_API at::Tensor upsample_bilinear2d_quantized_cpu(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..3d4d8f5f1644c9678985e15aba4b9343b2ad1438 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_bilinear2d_ops.h @@ -0,0 +1,67 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_bilinear2d_vec { + using schema = at::Tensor (const at::Tensor &, at::OptionalSymIntArrayRef, bool, ::std::optional>); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bilinear2d"; + static constexpr const char* overload_name = "vec"; + static constexpr const char* schema_str = "upsample_bilinear2d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor"; + static at::Tensor call(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +}; + +struct TORCH_API upsample_bilinear2d_out { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bilinear2d"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "upsample_bilinear2d.out(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +}; + +struct TORCH_API upsample_bilinear2d { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bilinear2d"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_bilinear2d(Tensor self, SymInt[2] output_size, bool align_corners, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_h, ::std::optional scales_w); +}; + +struct TORCH_API upsample_bilinear2d_vec_out { + using schema = at::Tensor & (const at::Tensor &, at::OptionalSymIntArrayRef, bool, ::std::optional>, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_bilinear2d"; + static constexpr const char* overload_name = "vec_out"; + static constexpr const char* schema_str = "upsample_bilinear2d.vec_out(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d.h new file mode 100644 index 0000000000000000000000000000000000000000..0ee4220cd4224bf95cf5bdab450708089f0148d4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d.h @@ -0,0 +1,119 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_linear1d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_linear1d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_linear1d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_linear1d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_linear1d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors); + } +} + +// aten::upsample_linear1d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_linear1d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_linear1d_vec::call(input, output_size, align_corners, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_linear1d(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_linear1d_vec::call(input, output_size, align_corners, scale_factors); + } +} + +// aten::upsample_linear1d.out(Tensor self, SymInt[1] output_size, bool align_corners, float? scales=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_linear1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales, out); +} +namespace symint { + template >> + at::Tensor & upsample_linear1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales, out); + } +} + +// aten::upsample_linear1d.out(Tensor self, SymInt[1] output_size, bool align_corners, float? scales=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_linear1d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out) { + return at::_ops::upsample_linear1d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales, out); +} +namespace symint { + template >> + at::Tensor & upsample_linear1d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out) { + return at::_ops::upsample_linear1d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales, out); + } +} + +// aten::upsample_linear1d.out(Tensor self, SymInt[1] output_size, bool align_corners, float? scales=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_linear1d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_out::call(self, output_size, align_corners, scales, out); +} +namespace symint { + template >> + at::Tensor & upsample_linear1d_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_out::call(self, output_size, align_corners, scales, out); + } +} + +// aten::upsample_linear1d.out(Tensor self, SymInt[1] output_size, bool align_corners, float? scales=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_linear1d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out) { + return at::_ops::upsample_linear1d_out::call(self, output_size, align_corners, scales, out); +} +namespace symint { + template >> + at::Tensor & upsample_linear1d_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out) { + return at::_ops::upsample_linear1d_out::call(self, output_size, align_corners, scales, out); + } +} + +// aten::upsample_linear1d(Tensor self, SymInt[1] output_size, bool align_corners, float? scales=None) -> Tensor +inline at::Tensor upsample_linear1d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales); +} +namespace symint { + template >> + at::Tensor upsample_linear1d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales); + } +} + +// aten::upsample_linear1d(Tensor self, SymInt[1] output_size, bool align_corners, float? scales=None) -> Tensor +inline at::Tensor upsample_linear1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d::call(self, output_size, align_corners, scales); +} +namespace symint { + template >> + at::Tensor upsample_linear1d(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d::call(self, output_size, align_corners, scales); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward.h new file mode 100644 index 0000000000000000000000000000000000000000..73dbbded94d6a2b1ba11da4cb359923721565a1e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward.h @@ -0,0 +1,97 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_linear1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, bool align_corners, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_linear1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_linear1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales, grad_input); + } +} + +// aten::upsample_linear1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, bool align_corners, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_linear1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input) { + return at::_ops::upsample_linear1d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_linear1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input) { + return at::_ops::upsample_linear1d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales, grad_input); + } +} + +// aten::upsample_linear1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, bool align_corners, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_linear1d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_linear1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales, grad_input); + } +} + +// aten::upsample_linear1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, bool align_corners, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_linear1d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input) { + return at::_ops::upsample_linear1d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_linear1d_backward_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input) { + return at::_ops::upsample_linear1d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales, grad_input); + } +} + +// aten::upsample_linear1d_backward(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, bool align_corners, float? scales=None) -> Tensor +inline at::Tensor upsample_linear1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales); +} +namespace symint { + template >> + at::Tensor upsample_linear1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales); + } +} + +// aten::upsample_linear1d_backward(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, bool align_corners, float? scales=None) -> Tensor +inline at::Tensor upsample_linear1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_backward::call(grad_output, output_size, input_size, align_corners, scales); +} +namespace symint { + template >> + at::Tensor upsample_linear1d_backward(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_linear1d_backward::call(grad_output, output_size, input_size, align_corners, scales); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..26c8b6a460d120a133c23010b588b2ab4419df7b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_linear1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_linear1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..fa38aac682803ec787b559fcaa4d09da219f8365 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_linear1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_linear1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_linear1d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..5d1451c1146120e8c24a4c59458d99564b6d6b08 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_linear1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_linear1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_linear1d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..6bf17a9c4a00c5ec0bb071d41229ec6183d0f539 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_linear1d_backward : public at::impl::MetaBase { + + + void meta(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..83a80deb1156a1491a79f4e5405395d0f3c3a8d4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_linear1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_linear1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_linear1d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_native.h new file mode 100644 index 0000000000000000000000000000000000000000..37114ae8ff7f7612168de7a7c529cec27e490e1d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_native.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +struct TORCH_API structured_upsample_linear1d_backward_out_cpu : public at::meta::structured_upsample_linear1d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales, const at::Tensor & grad_input); +}; +struct TORCH_API structured_upsample_linear1d_backward_out_cuda : public at::meta::structured_upsample_linear1d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales, const at::Tensor & grad_input); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..cda2cbde8c53a8f3703931c788acc5762e70b82c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_backward_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_linear1d_backward_grad_input { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, bool, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_linear1d_backward"; + static constexpr const char* overload_name = "grad_input"; + static constexpr const char* schema_str = "upsample_linear1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, bool align_corners, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales, at::Tensor & grad_input); +}; + +struct TORCH_API upsample_linear1d_backward { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, bool, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_linear1d_backward"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_linear1d_backward(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, bool align_corners, float? scales=None) -> Tensor"; + static at::Tensor call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..9298cdc9d0e886598b39370bd543f1036efaf8a8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_linear1d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_linear1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..dedde02e9299c881bffc8d4951159b65b202a96c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_compositeimplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor upsample_linear1d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +TORCH_API at::Tensor upsample_linear1d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..6b44b64280b4695959ef444183859830cc10fdc7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_linear1d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_linear1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out); +TORCH_API at::Tensor & upsample_linear1d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..e13cebb02eeebe3e9b8b96ea87230090e4e30341 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_linear1d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_linear1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out); +TORCH_API at::Tensor & upsample_linear1d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..0de429f521175a31df14b381c89d3ec889952564 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_linear1d : public at::impl::MetaBase { + + + void meta(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c909c54eef262420323e148c2b63a5f2d1dc72ee --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_linear1d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_linear1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out); +TORCH_API at::Tensor & upsample_linear1d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_linear1d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_native.h new file mode 100644 index 0000000000000000000000000000000000000000..02e8bcb17eeb0d3ff130f5d0bda9f044f04dfdd1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_native.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +TORCH_API at::Tensor upsample_linear1d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +struct TORCH_API structured_upsample_linear1d_out_cpu : public at::meta::structured_upsample_linear1d { +void impl(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales, const at::Tensor & out); +}; +struct TORCH_API structured_upsample_linear1d_out_cuda : public at::meta::structured_upsample_linear1d { +void impl(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales, const at::Tensor & out); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..9e07763db4202d756a97085c9b6f4b27aaf24bd6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_linear1d_ops.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_linear1d_vec { + using schema = at::Tensor (const at::Tensor &, at::OptionalSymIntArrayRef, bool, ::std::optional>); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_linear1d"; + static constexpr const char* overload_name = "vec"; + static constexpr const char* schema_str = "upsample_linear1d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor"; + static at::Tensor call(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +}; + +struct TORCH_API upsample_linear1d_out { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, bool, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_linear1d"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "upsample_linear1d.out(Tensor self, SymInt[1] output_size, bool align_corners, float? scales=None, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales, at::Tensor & out); +}; + +struct TORCH_API upsample_linear1d { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, bool, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_linear1d"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_linear1d(Tensor self, SymInt[1] output_size, bool align_corners, float? scales=None) -> Tensor"; + static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d.h new file mode 100644 index 0000000000000000000000000000000000000000..389a9f180043415daa024a6a9a835f93372b267c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d.h @@ -0,0 +1,119 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_nearest1d.vec(Tensor input, SymInt[]? output_size, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_nearest1d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest1d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_nearest1d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest1d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors); + } +} + +// aten::upsample_nearest1d.vec(Tensor input, SymInt[]? output_size, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_nearest1d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest1d_vec::call(input, output_size, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_nearest1d(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest1d_vec::call(input, output_size, scale_factors); + } +} + +// aten::upsample_nearest1d.out(Tensor self, SymInt[1] output_size, float? scales=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales, out); + } +} + +// aten::upsample_nearest1d.out(Tensor self, SymInt[1] output_size, float? scales=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest1d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales, at::Tensor & out) { + return at::_ops::upsample_nearest1d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest1d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales, at::Tensor & out) { + return at::_ops::upsample_nearest1d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales, out); + } +} + +// aten::upsample_nearest1d.out(Tensor self, SymInt[1] output_size, float? scales=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest1d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_out::call(self, output_size, scales, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest1d_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_out::call(self, output_size, scales, out); + } +} + +// aten::upsample_nearest1d.out(Tensor self, SymInt[1] output_size, float? scales=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest1d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales, at::Tensor & out) { + return at::_ops::upsample_nearest1d_out::call(self, output_size, scales, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest1d_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales, at::Tensor & out) { + return at::_ops::upsample_nearest1d_out::call(self, output_size, scales, out); + } +} + +// aten::upsample_nearest1d(Tensor self, SymInt[1] output_size, float? scales=None) -> Tensor +inline at::Tensor upsample_nearest1d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d::call(self, c10::fromIntArrayRefSlow(output_size), scales); +} +namespace symint { + template >> + at::Tensor upsample_nearest1d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d::call(self, c10::fromIntArrayRefSlow(output_size), scales); + } +} + +// aten::upsample_nearest1d(Tensor self, SymInt[1] output_size, float? scales=None) -> Tensor +inline at::Tensor upsample_nearest1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d::call(self, output_size, scales); +} +namespace symint { + template >> + at::Tensor upsample_nearest1d(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d::call(self, output_size, scales); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward.h new file mode 100644 index 0000000000000000000000000000000000000000..01c552f55bf44b240088568f4bfd941a03d65a0f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward.h @@ -0,0 +1,97 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_nearest1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales, grad_input); + } +} + +// aten::upsample_nearest1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input) { + return at::_ops::upsample_nearest1d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input) { + return at::_ops::upsample_nearest1d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales, grad_input); + } +} + +// aten::upsample_nearest1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest1d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_backward_grad_input::call(grad_output, output_size, input_size, scales, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_backward_grad_input::call(grad_output, output_size, input_size, scales, grad_input); + } +} + +// aten::upsample_nearest1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest1d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input) { + return at::_ops::upsample_nearest1d_backward_grad_input::call(grad_output, output_size, input_size, scales, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest1d_backward_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input) { + return at::_ops::upsample_nearest1d_backward_grad_input::call(grad_output, output_size, input_size, scales, grad_input); + } +} + +// aten::upsample_nearest1d_backward(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, float? scales=None) -> Tensor +inline at::Tensor upsample_nearest1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales); +} +namespace symint { + template >> + at::Tensor upsample_nearest1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales); + } +} + +// aten::upsample_nearest1d_backward(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, float? scales=None) -> Tensor +inline at::Tensor upsample_nearest1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_backward::call(grad_output, output_size, input_size, scales); +} +namespace symint { + template >> + at::Tensor upsample_nearest1d_backward(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt) { + return at::_ops::upsample_nearest1d_backward::call(grad_output, output_size, input_size, scales); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..3a169bc0d2ede249cfce05a2107a2c118323a86f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_nearest1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_nearest1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..437dff895a4b8da0667d42f818c749f222729f0e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_nearest1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_nearest1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_nearest1d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..ac24b84be07fc0b8416a7a820d762d45c5bcfed2 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_nearest1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_nearest1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_nearest1d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..12686ac2022b78af3dfa150e2695bb1384035cbd --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_nearest1d_backward : public at::impl::MetaBase { + + + void meta(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, ::std::optional scales); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..4f8eef1267d118d2e81f7bd2e8959843e9673d4c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_nearest1d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_nearest1d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_nearest1d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_native.h new file mode 100644 index 0000000000000000000000000000000000000000..936578ade5401ebf6cf064f6114c779334d72d11 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_native.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +struct TORCH_API structured_upsample_nearest1d_backward_out_cpu : public at::meta::structured_upsample_nearest1d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, ::std::optional scales, const at::Tensor & grad_input); +}; +struct TORCH_API structured_upsample_nearest1d_backward_out_cuda : public at::meta::structured_upsample_nearest1d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, ::std::optional scales, const at::Tensor & grad_input); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..7cd68bdfefe543733eb903a97da51d485e12ed2d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_backward_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_nearest1d_backward_grad_input { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest1d_backward"; + static constexpr const char* overload_name = "grad_input"; + static constexpr const char* schema_str = "upsample_nearest1d_backward.grad_input(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, float? scales=None, *, Tensor(a!) grad_input) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales, at::Tensor & grad_input); +}; + +struct TORCH_API upsample_nearest1d_backward { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest1d_backward"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_nearest1d_backward(Tensor grad_output, SymInt[1] output_size, SymInt[3] input_size, float? scales=None) -> Tensor"; + static at::Tensor call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..40534fe242122157e117d2ee5589f0cda85e7a83 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_nearest1d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_nearest1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..f254550920e3034430d37db3791c35d6ab660d88 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_compositeimplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor upsample_nearest1d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors); +TORCH_API at::Tensor upsample_nearest1d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..01574185a95ec4f559339dbd126ed2069835838f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_nearest1d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_nearest1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest1d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales, at::Tensor & out); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..12f13a8bc47d7a5e2416f2cc09520d41a86fe97c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_nearest1d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_nearest1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest1d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales, at::Tensor & out); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..a1ca55c19d7e0f84b8b2987e5f8ada665647d2f5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_nearest1d : public at::impl::MetaBase { + + + void meta(const at::Tensor & self, at::ArrayRef output_size, ::std::optional scales); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..588272d84a381f3f13cab4d6346fe9e3d1e6ff68 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_nearest1d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor upsample_nearest1d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest1d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest1d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales, at::Tensor & out); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_native.h new file mode 100644 index 0000000000000000000000000000000000000000..bcbeea703c05029c0eee1eacf1f43f875bef92a4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_native.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +TORCH_API at::Tensor upsample_nearest1d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors); +struct TORCH_API structured_upsample_nearest1d_out_cpu : public at::meta::structured_upsample_nearest1d { +void impl(const at::Tensor & self, at::ArrayRef output_size, ::std::optional scales, const at::Tensor & out); +}; +struct TORCH_API structured_upsample_nearest1d_out_cuda : public at::meta::structured_upsample_nearest1d { +void impl(const at::Tensor & self, at::ArrayRef output_size, ::std::optional scales, const at::Tensor & out); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..302b5b60a61f5edf5fb5aa89d2813f903378dbe6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest1d_ops.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_nearest1d_vec { + using schema = at::Tensor (const at::Tensor &, at::OptionalSymIntArrayRef, ::std::optional>); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest1d"; + static constexpr const char* overload_name = "vec"; + static constexpr const char* schema_str = "upsample_nearest1d.vec(Tensor input, SymInt[]? output_size, float[]? scale_factors) -> Tensor"; + static at::Tensor call(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); +}; + +struct TORCH_API upsample_nearest1d_out { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest1d"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "upsample_nearest1d.out(Tensor self, SymInt[1] output_size, float? scales=None, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales, at::Tensor & out); +}; + +struct TORCH_API upsample_nearest1d { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest1d"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_nearest1d(Tensor self, SymInt[1] output_size, float? scales=None) -> Tensor"; + static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d.h new file mode 100644 index 0000000000000000000000000000000000000000..bbaf23048ae7105b230a8a06ad2be99a6af1992c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d.h @@ -0,0 +1,163 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_nearest2d.vec(Tensor input, SymInt[]? output_size, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_nearest2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest2d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_nearest2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest2d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors); + } +} + +// aten::upsample_nearest2d.vec(Tensor input, SymInt[]? output_size, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_nearest2d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest2d_vec::call(input, output_size, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_nearest2d(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest2d_vec::call(input, output_size, scale_factors); + } +} + +// aten::upsample_nearest2d.out(Tensor self, SymInt[2] output_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales_h, scales_w, out); + } +} + +// aten::upsample_nearest2d.out(Tensor self, SymInt[2] output_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_nearest2d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_nearest2d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales_h, scales_w, out); + } +} + +// aten::upsample_nearest2d.out(Tensor self, SymInt[2] output_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_out::call(self, output_size, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_out::call(self, output_size, scales_h, scales_w, out); + } +} + +// aten::upsample_nearest2d.out(Tensor self, SymInt[2] output_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_nearest2d_out::call(self, output_size, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_nearest2d_out::call(self, output_size, scales_h, scales_w, out); + } +} + +// aten::upsample_nearest2d(Tensor self, SymInt[2] output_size, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_nearest2d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d::call(self, c10::fromIntArrayRefSlow(output_size), scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_nearest2d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d::call(self, c10::fromIntArrayRefSlow(output_size), scales_h, scales_w); + } +} + +// aten::upsample_nearest2d(Tensor self, SymInt[2] output_size, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_nearest2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d::call(self, output_size, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_nearest2d(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d::call(self, output_size, scales_h, scales_w); + } +} + +// aten::upsample_nearest2d.vec_out(Tensor input, SymInt[]? output_size, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest2d_vec_out::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest2d_vec_out::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors, out); + } +} + +// aten::upsample_nearest2d.vec_out(Tensor input, SymInt[]? output_size, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_outf(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors, at::Tensor & out) { + return at::_ops::upsample_nearest2d_vec_out::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_outf(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors, at::Tensor & out) { + return at::_ops::upsample_nearest2d_vec_out::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors, out); + } +} + +// aten::upsample_nearest2d.vec_out(Tensor input, SymInt[]? output_size, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_symint_out(at::Tensor & out, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest2d_vec_out::call(input, output_size, scale_factors, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest2d_vec_out::call(input, output_size, scale_factors, out); + } +} + +// aten::upsample_nearest2d.vec_out(Tensor input, SymInt[]? output_size, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_symint_outf(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors, at::Tensor & out) { + return at::_ops::upsample_nearest2d_vec_out::call(input, output_size, scale_factors, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_outf(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors, at::Tensor & out) { + return at::_ops::upsample_nearest2d_vec_out::call(input, output_size, scale_factors, out); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward.h new file mode 100644 index 0000000000000000000000000000000000000000..38fc0a9d028a242fc127e6b4c734b99ef4e7e98b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward.h @@ -0,0 +1,97 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_nearest2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_h, scales_w, grad_input); + } +} + +// aten::upsample_nearest2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_nearest2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_nearest2d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_h, scales_w, grad_input); + } +} + +// aten::upsample_nearest2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_backward_grad_input::call(grad_output, output_size, input_size, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_backward_grad_input::call(grad_output, output_size, input_size, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_nearest2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_nearest2d_backward_grad_input::call(grad_output, output_size, input_size, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest2d_backward_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_nearest2d_backward_grad_input::call(grad_output, output_size, input_size, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_nearest2d_backward(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_nearest2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_nearest2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_h, scales_w); + } +} + +// aten::upsample_nearest2d_backward(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_nearest2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_backward::call(grad_output, output_size, input_size, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_nearest2d_backward(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest2d_backward::call(grad_output, output_size, input_size, scales_h, scales_w); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c21fa6fce0354eedb02bce96d453619eaee2b528 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_nearest2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..1fd288476d105d8580480f7703fb629f49fae3b4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_nearest2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_nearest2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..32acc46c70e5429bde3bffb8eacc1d442d841790 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_nearest2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_nearest2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..74e473789eee2e45465cb0b88b3627005d9a860a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_nearest2d_backward : public at::impl::MetaBase { + + + void meta(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..fabc870de3c432fccb8ad0c943515fb00771c265 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_nearest2d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest2d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_nearest2d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_native.h new file mode 100644 index 0000000000000000000000000000000000000000..96da9990830352814a822051a70331ddb86740af --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_native.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +struct TORCH_API structured_upsample_nearest2d_backward_out_cpu : public at::meta::structured_upsample_nearest2d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +struct TORCH_API structured_upsample_nearest2d_backward_out_cuda : public at::meta::structured_upsample_nearest2d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..25c6ea0cd91b57098ba5164169b61657ab28727c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_backward_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_nearest2d_backward_grad_input { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest2d_backward"; + static constexpr const char* overload_name = "grad_input"; + static constexpr const char* schema_str = "upsample_nearest2d_backward.grad_input(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +}; + +struct TORCH_API upsample_nearest2d_backward { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest2d_backward"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_nearest2d_backward(Tensor grad_output, SymInt[2] output_size, SymInt[4] input_size, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_h, ::std::optional scales_w); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..3e5d2cb4b2a174021cfa41cf2441f6fa6cd4c351 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_compositeexplicitautograd_dispatch.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors); +TORCH_API at::Tensor & upsample_nearest2d_outf(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest2d_symint_out(at::Tensor & out, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); +TORCH_API at::Tensor & upsample_nearest2d_symint_outf(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..426a4702501033eefb2f657e8719be3ad1736729 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_nearest2d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..ec40c4c6359ecbdd836ad35a96cd8c495a7efcc2 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_compositeimplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor upsample_nearest2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors); +TORCH_API at::Tensor upsample_nearest2d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..1079ca478abeab92be748e6e7f96271b9f6caf41 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_nearest2d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..a3751c24239df36554b5562e559817eaac564e56 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_nearest2d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..0e31a98531ddd57e726e2792ff902c9e26d3f959 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_nearest2d : public at::impl::MetaBase { + + + void meta(const at::Tensor & self, at::ArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..ac89ede4e35134cd5deabd97fe223c251128e903 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_nearest2d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest2d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest2d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest2d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_native.h new file mode 100644 index 0000000000000000000000000000000000000000..96c8b6c16ab718f28e88c1cff8a1353f895f168d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_native.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +TORCH_API at::Tensor upsample_nearest2d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors); +TORCH_API at::Tensor & upsample_nearest2d_vec_out_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors, at::Tensor & out); +struct TORCH_API structured_upsample_nearest2d_out_cpu : public at::meta::structured_upsample_nearest2d { +void impl(const at::Tensor & self, at::ArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +struct TORCH_API structured_upsample_nearest2d_out_cuda : public at::meta::structured_upsample_nearest2d { +void impl(const at::Tensor & self, at::ArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +TORCH_API at::Tensor upsample_nearest2d_quantized_cpu(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..64c08a20386dd154ff42449e59c6a7a407b4d33e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest2d_ops.h @@ -0,0 +1,67 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_nearest2d_vec { + using schema = at::Tensor (const at::Tensor &, at::OptionalSymIntArrayRef, ::std::optional>); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest2d"; + static constexpr const char* overload_name = "vec"; + static constexpr const char* schema_str = "upsample_nearest2d.vec(Tensor input, SymInt[]? output_size, float[]? scale_factors) -> Tensor"; + static at::Tensor call(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); +}; + +struct TORCH_API upsample_nearest2d_out { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest2d"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "upsample_nearest2d.out(Tensor self, SymInt[2] output_size, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +}; + +struct TORCH_API upsample_nearest2d { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest2d"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_nearest2d(Tensor self, SymInt[2] output_size, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_h, ::std::optional scales_w); +}; + +struct TORCH_API upsample_nearest2d_vec_out { + using schema = at::Tensor & (const at::Tensor &, at::OptionalSymIntArrayRef, ::std::optional>, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest2d"; + static constexpr const char* overload_name = "vec_out"; + static constexpr const char* schema_str = "upsample_nearest2d.vec_out(Tensor input, SymInt[]? output_size, float[]? scale_factors, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d.h new file mode 100644 index 0000000000000000000000000000000000000000..acd6f77998f30763f21fdb626e57cbfe037c9ed9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d.h @@ -0,0 +1,119 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_nearest3d.vec(Tensor input, SymInt[]? output_size, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_nearest3d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest3d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_nearest3d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest3d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, scale_factors); + } +} + +// aten::upsample_nearest3d.vec(Tensor input, SymInt[]? output_size, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_nearest3d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest3d_vec::call(input, output_size, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_nearest3d(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors) { + return at::_ops::upsample_nearest3d_vec::call(input, output_size, scale_factors); + } +} + +// aten::upsample_nearest3d.out(Tensor self, SymInt[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales_d, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales_d, scales_h, scales_w, out); + } +} + +// aten::upsample_nearest3d.out(Tensor self, SymInt[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest3d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_nearest3d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales_d, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest3d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_nearest3d_out::call(self, c10::fromIntArrayRefSlow(output_size), scales_d, scales_h, scales_w, out); + } +} + +// aten::upsample_nearest3d.out(Tensor self, SymInt[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest3d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_out::call(self, output_size, scales_d, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest3d_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_out::call(self, output_size, scales_d, scales_h, scales_w, out); + } +} + +// aten::upsample_nearest3d.out(Tensor self, SymInt[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_nearest3d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_nearest3d_out::call(self, output_size, scales_d, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_nearest3d_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_nearest3d_out::call(self, output_size, scales_d, scales_h, scales_w, out); + } +} + +// aten::upsample_nearest3d(Tensor self, SymInt[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_nearest3d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d::call(self, c10::fromIntArrayRefSlow(output_size), scales_d, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_nearest3d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d::call(self, c10::fromIntArrayRefSlow(output_size), scales_d, scales_h, scales_w); + } +} + +// aten::upsample_nearest3d(Tensor self, SymInt[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_nearest3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d::call(self, output_size, scales_d, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_nearest3d(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d::call(self, output_size, scales_d, scales_h, scales_w); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward.h new file mode 100644 index 0000000000000000000000000000000000000000..bdf738987c9bd8f242c0cafab1574fab0dedf493 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward.h @@ -0,0 +1,97 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_nearest3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_d, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_d, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_nearest3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_nearest3d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_d, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_nearest3d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_d, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_nearest3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest3d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_backward_grad_input::call(grad_output, output_size, input_size, scales_d, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_backward_grad_input::call(grad_output, output_size, input_size, scales_d, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_nearest3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_nearest3d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_nearest3d_backward_grad_input::call(grad_output, output_size, input_size, scales_d, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_nearest3d_backward_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_nearest3d_backward_grad_input::call(grad_output, output_size, input_size, scales_d, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_nearest3d_backward(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_nearest3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_d, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_nearest3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), scales_d, scales_h, scales_w); + } +} + +// aten::upsample_nearest3d_backward(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_nearest3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_backward::call(grad_output, output_size, input_size, scales_d, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_nearest3d_backward(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_nearest3d_backward::call(grad_output, output_size, input_size, scales_d, scales_h, scales_w); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..d20e921c5880e8dc495e809ed534278aabbbb038 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_nearest3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..cd61e676bc604ddcb2287efb5df71f18c913aca9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_nearest3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_nearest3d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..5345d24bd6292d3ec7b55666fa4a86d0cfae3601 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_nearest3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_nearest3d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..f509fe9a7b4b775ac8ae85a5694b33416b333a97 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_nearest3d_backward : public at::impl::MetaBase { + + + void meta(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..bf1547ad23bf9c441192d4bc0285e2820a145e3f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_nearest3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_nearest3d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_native.h new file mode 100644 index 0000000000000000000000000000000000000000..d86636f95dd8b6c3de2425ded0a58505fdb1620b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_native.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +struct TORCH_API structured_upsample_nearest3d_backward_out_cpu : public at::meta::structured_upsample_nearest3d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +struct TORCH_API structured_upsample_nearest3d_backward_out_cuda : public at::meta::structured_upsample_nearest3d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..f33ced5afa8b0560f5b2eafa9a5656fa8f36afb1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_backward_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_nearest3d_backward_grad_input { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, ::std::optional, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest3d_backward"; + static constexpr const char* overload_name = "grad_input"; + static constexpr const char* schema_str = "upsample_nearest3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +}; + +struct TORCH_API upsample_nearest3d_backward { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, ::std::optional, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest3d_backward"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_nearest3d_backward(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c3997e5328354ff04daf3ea3afad9357517aea83 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_nearest3d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..88e9eca4c5400351270f0a36a4e5bb33babc56d8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_compositeimplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor upsample_nearest3d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors); +TORCH_API at::Tensor upsample_nearest3d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..709673dda5f6df65317d88e46f51a44a1b75ef50 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_nearest3d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest3d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..7a9a7f47d3ddffbd78dfd11502f019d759f4190e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_nearest3d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest3d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..ba56efd75b79e00d71c900afd57e0f2b37548b38 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_nearest3d : public at::impl::MetaBase { + + + void meta(const at::Tensor & self, at::ArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..4c62d49fe755691783aa8d4b62dc115ac1b0206e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_nearest3d(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_nearest3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_outf(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_nearest3d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_nearest3d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_native.h new file mode 100644 index 0000000000000000000000000000000000000000..d41a487310eee56094668f83a52207664e7f31a4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_native.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +TORCH_API at::Tensor upsample_nearest3d(const at::Tensor & input, at::OptionalIntArrayRef output_size, ::std::optional> scale_factors); +struct TORCH_API structured_upsample_nearest3d_out_cpu : public at::meta::structured_upsample_nearest3d { +void impl(const at::Tensor & self, at::ArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +struct TORCH_API structured_upsample_nearest3d_out_cuda : public at::meta::structured_upsample_nearest3d { +void impl(const at::Tensor & self, at::ArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +TORCH_API at::Tensor upsample_nearest3d_quantized_cpu(const at::Tensor & self, at::IntArrayRef output_size, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..510830315658c3fef143d4ffccbcf3991586cd6b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_nearest3d_ops.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_nearest3d_vec { + using schema = at::Tensor (const at::Tensor &, at::OptionalSymIntArrayRef, ::std::optional>); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest3d"; + static constexpr const char* overload_name = "vec"; + static constexpr const char* schema_str = "upsample_nearest3d.vec(Tensor input, SymInt[]? output_size, float[]? scale_factors) -> Tensor"; + static at::Tensor call(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, ::std::optional> scale_factors); +}; + +struct TORCH_API upsample_nearest3d_out { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, ::std::optional, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest3d"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "upsample_nearest3d.out(Tensor self, SymInt[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +}; + +struct TORCH_API upsample_nearest3d { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, ::std::optional, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_nearest3d"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_nearest3d(Tensor self, SymInt[3] output_size, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d.h new file mode 100644 index 0000000000000000000000000000000000000000..bdab3e9cd380872fe9f2b4e9cb527e9733e5ad17 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d.h @@ -0,0 +1,119 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_trilinear3d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_trilinear3d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_trilinear3d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_trilinear3d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_trilinear3d_vec::call(input, output_size.has_value() ? ::std::make_optional(c10::fromIntArrayRefSlow(*output_size)) : ::std::nullopt, align_corners, scale_factors); + } +} + +// aten::upsample_trilinear3d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor +inline at::Tensor upsample_trilinear3d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_trilinear3d_vec::call(input, output_size, align_corners, scale_factors); +} +namespace symint { + template >> + at::Tensor upsample_trilinear3d(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors) { + return at::_ops::upsample_trilinear3d_vec::call(input, output_size, align_corners, scale_factors); + } +} + +// aten::upsample_trilinear3d.out(Tensor self, SymInt[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_trilinear3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_d, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_trilinear3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_d, scales_h, scales_w, out); + } +} + +// aten::upsample_trilinear3d.out(Tensor self, SymInt[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_trilinear3d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_trilinear3d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_d, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_trilinear3d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_trilinear3d_out::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_d, scales_h, scales_w, out); + } +} + +// aten::upsample_trilinear3d.out(Tensor self, SymInt[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_trilinear3d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_out::call(self, output_size, align_corners, scales_d, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_trilinear3d_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_out::call(self, output_size, align_corners, scales_d, scales_h, scales_w, out); + } +} + +// aten::upsample_trilinear3d.out(Tensor self, SymInt[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & upsample_trilinear3d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_trilinear3d_out::call(self, output_size, align_corners, scales_d, scales_h, scales_w, out); +} +namespace symint { + template >> + at::Tensor & upsample_trilinear3d_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out) { + return at::_ops::upsample_trilinear3d_out::call(self, output_size, align_corners, scales_d, scales_h, scales_w, out); + } +} + +// aten::upsample_trilinear3d(Tensor self, SymInt[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_trilinear3d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_d, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_trilinear3d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d::call(self, c10::fromIntArrayRefSlow(output_size), align_corners, scales_d, scales_h, scales_w); + } +} + +// aten::upsample_trilinear3d(Tensor self, SymInt[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_trilinear3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d::call(self, output_size, align_corners, scales_d, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_trilinear3d(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d::call(self, output_size, align_corners, scales_d, scales_h, scales_w); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward.h new file mode 100644 index 0000000000000000000000000000000000000000..ba1e1d2d9f660adabc90ad7fbcac651e9a970ea6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward.h @@ -0,0 +1,97 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::upsample_trilinear3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_trilinear3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_d, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_trilinear3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_d, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_trilinear3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_trilinear3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_trilinear3d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_d, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_trilinear3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_trilinear3d_backward_grad_input::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_d, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_trilinear3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_trilinear3d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_d, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_trilinear3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_d, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_trilinear3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!) +inline at::Tensor & upsample_trilinear3d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_trilinear3d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_d, scales_h, scales_w, grad_input); +} +namespace symint { + template >> + at::Tensor & upsample_trilinear3d_backward_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input) { + return at::_ops::upsample_trilinear3d_backward_grad_input::call(grad_output, output_size, input_size, align_corners, scales_d, scales_h, scales_w, grad_input); + } +} + +// aten::upsample_trilinear3d_backward(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_trilinear3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_d, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_trilinear3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_backward::call(grad_output, c10::fromIntArrayRefSlow(output_size), c10::fromIntArrayRefSlow(input_size), align_corners, scales_d, scales_h, scales_w); + } +} + +// aten::upsample_trilinear3d_backward(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor +inline at::Tensor upsample_trilinear3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_backward::call(grad_output, output_size, input_size, align_corners, scales_d, scales_h, scales_w); +} +namespace symint { + template >> + at::Tensor upsample_trilinear3d_backward(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt) { + return at::_ops::upsample_trilinear3d_backward::call(grad_output, output_size, input_size, align_corners, scales_d, scales_h, scales_w); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..4317ed8cb66c432c22c87b40591e147e3d8c0621 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_trilinear3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_trilinear3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..2dd0707a025128b97c936c36c3d05daade0d4da0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_trilinear3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_trilinear3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_trilinear3d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..038c9c5aee71e4150a070777a48a52e9278e7643 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_trilinear3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_trilinear3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_trilinear3d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..4812b4a9b6ce70215c947356f279f3baa0555d28 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_trilinear3d_backward : public at::impl::MetaBase { + + + void meta(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..3c19177a5d9071258009fc658053bc9e5e5ec789 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_trilinear3d_backward(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_trilinear3d_backward_symint(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_backward_out(at::Tensor & grad_input, const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_backward_outf(const at::Tensor & grad_output, at::IntArrayRef output_size, at::IntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +TORCH_API at::Tensor & upsample_trilinear3d_backward_symint_out(at::Tensor & grad_input, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_backward_symint_outf(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_native.h new file mode 100644 index 0000000000000000000000000000000000000000..41eaaf73af5cd41384a105b731a7ad2568c8d4ad --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_native.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +struct TORCH_API structured_upsample_trilinear3d_backward_out_cpu : public at::meta::structured_upsample_trilinear3d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +struct TORCH_API structured_upsample_trilinear3d_backward_out_cuda : public at::meta::structured_upsample_trilinear3d_backward { +void impl(const at::Tensor & grad_output, at::ArrayRef output_size, at::ArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & grad_input); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..0d55b75b0d7bdc4abcbd6db43aef3f2e195b06af --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_backward_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_trilinear3d_backward_grad_input { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_trilinear3d_backward"; + static constexpr const char* overload_name = "grad_input"; + static constexpr const char* schema_str = "upsample_trilinear3d_backward.grad_input(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) grad_input) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & grad_input); +}; + +struct TORCH_API upsample_trilinear3d_backward { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_trilinear3d_backward"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_trilinear3d_backward(Tensor grad_output, SymInt[3] output_size, SymInt[5] input_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad_output, c10::SymIntArrayRef output_size, c10::SymIntArrayRef input_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..4f06e1f80bdefc52a807e33543ce487f8c415edc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor upsample_trilinear3d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_trilinear3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..28b4b8fa6efd8250a4070146df8b58904dd987a7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_compositeimplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor upsample_trilinear3d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +TORCH_API at::Tensor upsample_trilinear3d_symint(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..a7854d6fa03043cdc6f0fc0404ab7435c81c5549 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_cpu_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor upsample_trilinear3d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_trilinear3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_trilinear3d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..883f0cfa96f21d73ee425f1f14a0fe459058e338 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_cuda_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor upsample_trilinear3d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_trilinear3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_trilinear3d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..36b1f6b33beac561a2d3475590888e25bde7a9fc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_upsample_trilinear3d : public at::impl::MetaBase { + + + void meta(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..af3812a208335bc657a90461945764ebdcaa826a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_meta_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor upsample_trilinear3d(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor upsample_trilinear3d_symint(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_outf(const at::Tensor & self, at::IntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +TORCH_API at::Tensor & upsample_trilinear3d_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d=::std::nullopt, ::std::optional scales_h=::std::nullopt, ::std::optional scales_w=::std::nullopt); +TORCH_API at::Tensor & upsample_trilinear3d_symint_outf(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_native.h new file mode 100644 index 0000000000000000000000000000000000000000..4ea9ec827a273033f3c19258f057ffb98222f093 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_native.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +TORCH_API at::Tensor upsample_trilinear3d(const at::Tensor & input, at::OptionalIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +struct TORCH_API structured_upsample_trilinear3d_out_cpu : public at::meta::structured_upsample_trilinear3d { +void impl(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +struct TORCH_API structured_upsample_trilinear3d_out_cuda : public at::meta::structured_upsample_trilinear3d { +void impl(const at::Tensor & self, at::ArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, const at::Tensor & out); +}; +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..f8680715e78b4aec28a8e923037ed8179df48c1c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/upsample_trilinear3d_ops.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API upsample_trilinear3d_vec { + using schema = at::Tensor (const at::Tensor &, at::OptionalSymIntArrayRef, bool, ::std::optional>); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_trilinear3d"; + static constexpr const char* overload_name = "vec"; + static constexpr const char* schema_str = "upsample_trilinear3d.vec(Tensor input, SymInt[]? output_size, bool align_corners, float[]? scale_factors) -> Tensor"; + static at::Tensor call(const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & input, at::OptionalSymIntArrayRef output_size, bool align_corners, ::std::optional> scale_factors); +}; + +struct TORCH_API upsample_trilinear3d_out { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_trilinear3d"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "upsample_trilinear3d.out(Tensor self, SymInt[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w, at::Tensor & out); +}; + +struct TORCH_API upsample_trilinear3d { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef, bool, ::std::optional, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::upsample_trilinear3d"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "upsample_trilinear3d(Tensor self, SymInt[3] output_size, bool align_corners, float? scales_d=None, float? scales_h=None, float? scales_w=None) -> Tensor"; + static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef output_size, bool align_corners, ::std::optional scales_d, ::std::optional scales_h, ::std::optional scales_w); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward.h new file mode 100644 index 0000000000000000000000000000000000000000..31c4167ef52d72a3ed566528fd80cf3214d642a9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward.h @@ -0,0 +1,53 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::value_selecting_reduction_backward(Tensor grad, int dim, Tensor indices, SymInt[] sizes, bool keepdim) -> Tensor +inline at::Tensor value_selecting_reduction_backward(const at::Tensor & grad, int64_t dim, const at::Tensor & indices, at::IntArrayRef sizes, bool keepdim) { + return at::_ops::value_selecting_reduction_backward::call(grad, dim, indices, c10::fromIntArrayRefSlow(sizes), keepdim); +} +namespace symint { + template >> + at::Tensor value_selecting_reduction_backward(const at::Tensor & grad, int64_t dim, const at::Tensor & indices, at::IntArrayRef sizes, bool keepdim) { + return at::_ops::value_selecting_reduction_backward::call(grad, dim, indices, c10::fromIntArrayRefSlow(sizes), keepdim); + } +} + +// aten::value_selecting_reduction_backward(Tensor grad, int dim, Tensor indices, SymInt[] sizes, bool keepdim) -> Tensor +inline at::Tensor value_selecting_reduction_backward_symint(const at::Tensor & grad, int64_t dim, const at::Tensor & indices, c10::SymIntArrayRef sizes, bool keepdim) { + return at::_ops::value_selecting_reduction_backward::call(grad, dim, indices, sizes, keepdim); +} +namespace symint { + template >> + at::Tensor value_selecting_reduction_backward(const at::Tensor & grad, int64_t dim, const at::Tensor & indices, c10::SymIntArrayRef sizes, bool keepdim) { + return at::_ops::value_selecting_reduction_backward::call(grad, dim, indices, sizes, keepdim); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..d36bf74f1321f1af544716ff916eca3f79902a9c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward_compositeimplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor value_selecting_reduction_backward(const at::Tensor & grad, int64_t dim, const at::Tensor & indices, at::IntArrayRef sizes, bool keepdim); +TORCH_API at::Tensor value_selecting_reduction_backward_symint(const at::Tensor & grad, int64_t dim, const at::Tensor & indices, c10::SymIntArrayRef sizes, bool keepdim); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward_native.h new file mode 100644 index 0000000000000000000000000000000000000000..52b6db18dca64418111bd9fd65ab041d51e6159d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor value_selecting_reduction_backward_symint(const at::Tensor & grad, int64_t dim, const at::Tensor & indices, c10::SymIntArrayRef sizes, bool keepdim); +TORCH_API at::Tensor value_selecting_reduction_backward_nested_symint(const at::Tensor & grad, int64_t dim, const at::Tensor & indices, c10::SymIntArrayRef sizes, bool keepdim); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..751db3a71347db69e3dc7339bd3d5f2e4d5f4729 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/value_selecting_reduction_backward_ops.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API value_selecting_reduction_backward { + using schema = at::Tensor (const at::Tensor &, int64_t, const at::Tensor &, c10::SymIntArrayRef, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::value_selecting_reduction_backward"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "value_selecting_reduction_backward(Tensor grad, int dim, Tensor indices, SymInt[] sizes, bool keepdim) -> Tensor"; + static at::Tensor call(const at::Tensor & grad, int64_t dim, const at::Tensor & indices, c10::SymIntArrayRef sizes, bool keepdim); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & grad, int64_t dim, const at::Tensor & indices, c10::SymIntArrayRef sizes, bool keepdim); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values.h new file mode 100644 index 0000000000000000000000000000000000000000..d4bbc26c99ba9634d462aba1db550376481a12d4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..1aeeb0828d0f96dfc73743cb8b36ff56c454dcb9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_compositeexplicitautograd_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor values(const at::Tensor & self); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy.h new file mode 100644 index 0000000000000000000000000000000000000000..719e764f209c95d0fffe6fd789a2e506a2bc9e03 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::values_copy(Tensor self) -> Tensor +inline at::Tensor values_copy(const at::Tensor & self) { + return at::_ops::values_copy::call(self); +} + +// aten::values_copy.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & values_copy_out(at::Tensor & out, const at::Tensor & self) { + return at::_ops::values_copy_out::call(self, out); +} +// aten::values_copy.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & values_copy_outf(const at::Tensor & self, at::Tensor & out) { + return at::_ops::values_copy_out::call(self, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..2f6638dad7bc3898d86c85ee555e112495dd1140 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_compositeexplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor & values_copy_out(at::Tensor & out, const at::Tensor & self); +TORCH_API at::Tensor & values_copy_outf(const at::Tensor & self, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..f740afcf0b25217e2510411eca318b0b8395bf74 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor values_copy(const at::Tensor & self); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_native.h new file mode 100644 index 0000000000000000000000000000000000000000..49880afcf9264eaf01e55b16901d8e3f01c01c77 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor & values_copy_out(const at::Tensor & self, at::Tensor & out); +TORCH_API at::Tensor values_copy(const at::Tensor & self); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..b20c8d6901558b16aff645dd92a7a2380db05267 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_copy_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API values_copy { + using schema = at::Tensor (const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::values_copy"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "values_copy(Tensor self) -> Tensor"; + static at::Tensor call(const at::Tensor & self); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self); +}; + +struct TORCH_API values_copy_out { + using schema = at::Tensor & (const at::Tensor &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::values_copy"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "values_copy.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_native.h new file mode 100644 index 0000000000000000000000000000000000000000..e9a2d43eb885988a455de3dfb0030bfd9a25d381 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_native.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor values_default(const at::Tensor & self); +TORCH_API at::Tensor values_nested(const at::Tensor & self); +TORCH_API at::Tensor values_sparse(const at::Tensor & self); +TORCH_API at::Tensor values_sparse_csr(const at::Tensor & self); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..bd6f7f3c24611e1ca290e7fe73ca28faf4ecba2c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/values_ops.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API values { + using schema = at::Tensor (const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::values"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "values(Tensor(a) self) -> Tensor(a)"; + static at::Tensor call(const at::Tensor & self); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander.h new file mode 100644 index 0000000000000000000000000000000000000000..065a9b06324a7fbea96478991d3c38c23cd34fc3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::vander(Tensor x, int? N=None, bool increasing=False) -> Tensor +inline at::Tensor vander(const at::Tensor & x, ::std::optional N=::std::nullopt, bool increasing=false) { + return at::_ops::vander::call(x, N, increasing); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c02ca370e0cf59b5ee18194de4e8f09cee87f502 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander_compositeimplicitautograd_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor vander(const at::Tensor & x, ::std::optional N=::std::nullopt, bool increasing=false); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander_native.h new file mode 100644 index 0000000000000000000000000000000000000000..b0fe0cb1191115fc34d918a7b2b93f56e121cbd9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander_native.h @@ -0,0 +1,26 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor vander(const at::Tensor & x, ::std::optional N=::std::nullopt, bool increasing=false); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..638f69b7cf49454b412e61cea8aeec0878bdab19 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vander_ops.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API vander { + using schema = at::Tensor (const at::Tensor &, ::std::optional, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::vander"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "vander(Tensor x, int? N=None, bool increasing=False) -> Tensor"; + static at::Tensor call(const at::Tensor & x, ::std::optional N, bool increasing); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & x, ::std::optional N, bool increasing); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var.h new file mode 100644 index 0000000000000000000000000000000000000000..e4659597688a763b73d6c965eacb0546e3d896e1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var.h @@ -0,0 +1,92 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::var(Tensor self, bool unbiased=True) -> Tensor +inline at::Tensor var(const at::Tensor & self, bool unbiased) { + return at::_ops::var::call(self, unbiased); +} + +// aten::var.dim(Tensor self, int[1]? dim, bool unbiased=True, bool keepdim=False) -> Tensor +inline at::Tensor var(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim=false) { + return at::_ops::var_dim::call(self, dim, unbiased, keepdim); +} + +// aten::var.correction(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False) -> Tensor +inline at::Tensor var(const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false) { + return at::_ops::var_correction::call(self, dim, correction, keepdim); +} + +// aten::var.out(Tensor self, int[1]? dim, bool unbiased=True, bool keepdim=False, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & var_out(at::Tensor & out, const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim=false) { + return at::_ops::var_out::call(self, dim, unbiased, keepdim, out); +} +// aten::var.out(Tensor self, int[1]? dim, bool unbiased=True, bool keepdim=False, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & var_outf(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim, at::Tensor & out) { + return at::_ops::var_out::call(self, dim, unbiased, keepdim, out); +} + +// aten::var.correction_out(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & var_out(at::Tensor & out, const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false) { + return at::_ops::var_correction_out::call(self, dim, correction, keepdim, out); +} +// aten::var.correction_out(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & var_outf(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out) { + return at::_ops::var_correction_out::call(self, dim, correction, keepdim, out); +} + +// aten::var.names_dim(Tensor self, Dimname[1] dim, bool unbiased=True, bool keepdim=False) -> Tensor +inline at::Tensor var(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim=false) { + return at::_ops::var_names_dim::call(self, dim, unbiased, keepdim); +} + +// aten::var.names_out(Tensor self, Dimname[1] dim, bool unbiased=True, bool keepdim=False, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & var_out(at::Tensor & out, const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim=false) { + return at::_ops::var_names_out::call(self, dim, unbiased, keepdim, out); +} +// aten::var.names_out(Tensor self, Dimname[1] dim, bool unbiased=True, bool keepdim=False, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & var_outf(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim, at::Tensor & out) { + return at::_ops::var_names_out::call(self, dim, unbiased, keepdim, out); +} + +// aten::var.correction_names(Tensor self, Dimname[1] dim, *, Scalar? correction=None, bool keepdim=False) -> Tensor +inline at::Tensor var(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction=::std::nullopt, bool keepdim=false) { + return at::_ops::var_correction_names::call(self, dim, correction, keepdim); +} + +// aten::var.correction_names_out(Tensor self, Dimname[1] dim, *, Scalar? correction=None, bool keepdim=False, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & var_out(at::Tensor & out, const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction=::std::nullopt, bool keepdim=false) { + return at::_ops::var_correction_names_out::call(self, dim, correction, keepdim, out); +} +// aten::var.correction_names_out(Tensor self, Dimname[1] dim, *, Scalar? correction=None, bool keepdim=False, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & var_outf(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction, bool keepdim, at::Tensor & out) { + return at::_ops::var_correction_names_out::call(self, dim, correction, keepdim, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..e7f99054990b9dff40eb5054f41c5a301724b069 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_compositeimplicitautograd_dispatch.h @@ -0,0 +1,37 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor var(const at::Tensor & self, bool unbiased); +TORCH_API at::Tensor var(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim=false); +TORCH_API at::Tensor & var_out(at::Tensor & out, const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim=false); +TORCH_API at::Tensor & var_outf(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim, at::Tensor & out); +TORCH_API at::Tensor var(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim=false); +TORCH_API at::Tensor & var_out(at::Tensor & out, const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim=false); +TORCH_API at::Tensor & var_outf(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim, at::Tensor & out); +TORCH_API at::Tensor var(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API at::Tensor & var_out(at::Tensor & out, const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API at::Tensor & var_outf(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction, bool keepdim, at::Tensor & out); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..2ba4de4e36ae063d9632434a638c08b50b2c61a1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_cpu_dispatch.h @@ -0,0 +1,30 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor var(const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API at::Tensor & var_out(at::Tensor & out, const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API at::Tensor & var_outf(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..95e4c3c5fc3158a16cbb75e2e3535c7563b67229 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_cuda_dispatch.h @@ -0,0 +1,30 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor var(const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API at::Tensor & var_out(at::Tensor & out, const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API at::Tensor & var_outf(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean.h new file mode 100644 index 0000000000000000000000000000000000000000..96516d1fdfbe453fb1edd2993bf79a555d91203d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean.h @@ -0,0 +1,65 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::var_mean(Tensor self, bool unbiased=True) -> (Tensor, Tensor) +inline ::std::tuple var_mean(const at::Tensor & self, bool unbiased) { + return at::_ops::var_mean::call(self, unbiased); +} + +// aten::var_mean.dim(Tensor self, int[1]? dim, bool unbiased=True, bool keepdim=False) -> (Tensor, Tensor) +inline ::std::tuple var_mean(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim=false) { + return at::_ops::var_mean_dim::call(self, dim, unbiased, keepdim); +} + +// aten::var_mean.correction(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False) -> (Tensor, Tensor) +inline ::std::tuple var_mean(const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false) { + return at::_ops::var_mean_correction::call(self, dim, correction, keepdim); +} + +// aten::var_mean.names_dim(Tensor self, Dimname[1] dim, bool unbiased=True, bool keepdim=False) -> (Tensor, Tensor) +inline ::std::tuple var_mean(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim=false) { + return at::_ops::var_mean_names_dim::call(self, dim, unbiased, keepdim); +} + +// aten::var_mean.correction_names(Tensor self, Dimname[1] dim, *, Scalar? correction=None, bool keepdim=False) -> (Tensor, Tensor) +inline ::std::tuple var_mean(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction=::std::nullopt, bool keepdim=false) { + return at::_ops::var_mean_correction_names::call(self, dim, correction, keepdim); +} + +// aten::var_mean.correction_out(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False, Tensor(a!) out0, Tensor(b!) out1) -> (Tensor(a!), Tensor(b!)) +inline ::std::tuple var_mean_out(at::Tensor & out0, at::Tensor & out1, const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false) { + return at::_ops::var_mean_correction_out::call(self, dim, correction, keepdim, out0, out1); +} +// aten::var_mean.correction_out(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False, Tensor(a!) out0, Tensor(b!) out1) -> (Tensor(a!), Tensor(b!)) +inline ::std::tuple var_mean_outf(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out0, at::Tensor & out1) { + return at::_ops::var_mean_correction_out::call(self, dim, correction, keepdim, out0, out1); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..b3295d1a19bc7b5a1c8077e767ff5ea18137d37b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_compositeexplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API ::std::tuple var_mean_out(at::Tensor & out0, at::Tensor & out1, const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API ::std::tuple var_mean_outf(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out0, at::Tensor & out1); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..77a5f6d4c6556bb4e1c47d4c1b1c3a5610c35c76 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_compositeimplicitautograd_dispatch.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API ::std::tuple var_mean(const at::Tensor & self, bool unbiased); +TORCH_API ::std::tuple var_mean(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim=false); +TORCH_API ::std::tuple var_mean(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim=false); +TORCH_API ::std::tuple var_mean(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction=::std::nullopt, bool keepdim=false); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..5fc5e6edaf5df0639b080986371cfabee8ee62fd --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_cpu_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API ::std::tuple var_mean(const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c26ae44db129bf9d8fa63ae44ac27ef9d35423e9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_cuda_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API ::std::tuple var_mean(const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_native.h new file mode 100644 index 0000000000000000000000000000000000000000..816bf84c37b09666c29ea4a686f8da500c54a784 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_native.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API ::std::tuple var_mean(const at::Tensor & self, bool unbiased=true); +TORCH_API ::std::tuple var_mean(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased=true, bool keepdim=false); +TORCH_API ::std::tuple var_mean_correction_out(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out0, at::Tensor & out1); +TORCH_API ::std::tuple var_mean(const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API ::std::tuple var_mean(const at::Tensor & self, at::DimnameList dim, bool unbiased=true, bool keepdim=false); +TORCH_API ::std::tuple var_mean(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..284326515f8446fb937b9950c307562e85389629 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_mean_ops.h @@ -0,0 +1,89 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API var_mean { + using schema = ::std::tuple (const at::Tensor &, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var_mean"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "var_mean(Tensor self, bool unbiased=True) -> (Tensor, Tensor)"; + static ::std::tuple call(const at::Tensor & self, bool unbiased); + static ::std::tuple redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, bool unbiased); +}; + +struct TORCH_API var_mean_dim { + using schema = ::std::tuple (const at::Tensor &, at::OptionalIntArrayRef, bool, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var_mean"; + static constexpr const char* overload_name = "dim"; + static constexpr const char* schema_str = "var_mean.dim(Tensor self, int[1]? dim, bool unbiased=True, bool keepdim=False) -> (Tensor, Tensor)"; + static ::std::tuple call(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim); + static ::std::tuple redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim); +}; + +struct TORCH_API var_mean_correction { + using schema = ::std::tuple (const at::Tensor &, at::OptionalIntArrayRef, const ::std::optional &, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var_mean"; + static constexpr const char* overload_name = "correction"; + static constexpr const char* schema_str = "var_mean.correction(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False) -> (Tensor, Tensor)"; + static ::std::tuple call(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim); + static ::std::tuple redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim); +}; + +struct TORCH_API var_mean_names_dim { + using schema = ::std::tuple (const at::Tensor &, at::DimnameList, bool, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var_mean"; + static constexpr const char* overload_name = "names_dim"; + static constexpr const char* schema_str = "var_mean.names_dim(Tensor self, Dimname[1] dim, bool unbiased=True, bool keepdim=False) -> (Tensor, Tensor)"; + static ::std::tuple call(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim); + static ::std::tuple redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim); +}; + +struct TORCH_API var_mean_correction_names { + using schema = ::std::tuple (const at::Tensor &, at::DimnameList, const ::std::optional &, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var_mean"; + static constexpr const char* overload_name = "correction_names"; + static constexpr const char* schema_str = "var_mean.correction_names(Tensor self, Dimname[1] dim, *, Scalar? correction=None, bool keepdim=False) -> (Tensor, Tensor)"; + static ::std::tuple call(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction, bool keepdim); + static ::std::tuple redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction, bool keepdim); +}; + +struct TORCH_API var_mean_correction_out { + using schema = ::std::tuple (const at::Tensor &, at::OptionalIntArrayRef, const ::std::optional &, bool, at::Tensor &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var_mean"; + static constexpr const char* overload_name = "correction_out"; + static constexpr const char* schema_str = "var_mean.correction_out(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False, Tensor(a!) out0, Tensor(b!) out1) -> (Tensor(a!), Tensor(b!))"; + static ::std::tuple call(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out0, at::Tensor & out1); + static ::std::tuple redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out0, at::Tensor & out1); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_native.h new file mode 100644 index 0000000000000000000000000000000000000000..10e2daa44ac09b3d2827c1e668c5de0fa7d867dc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_native.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor var(const at::Tensor & self, bool unbiased=true); +TORCH_API at::Tensor var(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased=true, bool keepdim=false); +TORCH_API at::Tensor & var_out(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim, at::Tensor & out); +TORCH_API at::Tensor var(const at::Tensor & self, at::OptionalIntArrayRef dim=::std::nullopt, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API at::Tensor & var_out(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out); +TORCH_API at::Tensor var(const at::Tensor & self, at::DimnameList dim, bool unbiased=true, bool keepdim=false); +TORCH_API at::Tensor & var_out(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim, at::Tensor & out); +TORCH_API at::Tensor var(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction=::std::nullopt, bool keepdim=false); +TORCH_API at::Tensor & var_out(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction, bool keepdim, at::Tensor & out); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..b61b7ba2fee5d61dd3f40e6fd8d1fdd9745c2f0a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/var_ops.h @@ -0,0 +1,122 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API var { + using schema = at::Tensor (const at::Tensor &, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "var(Tensor self, bool unbiased=True) -> Tensor"; + static at::Tensor call(const at::Tensor & self, bool unbiased); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, bool unbiased); +}; + +struct TORCH_API var_dim { + using schema = at::Tensor (const at::Tensor &, at::OptionalIntArrayRef, bool, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var"; + static constexpr const char* overload_name = "dim"; + static constexpr const char* schema_str = "var.dim(Tensor self, int[1]? dim, bool unbiased=True, bool keepdim=False) -> Tensor"; + static at::Tensor call(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim); +}; + +struct TORCH_API var_correction { + using schema = at::Tensor (const at::Tensor &, at::OptionalIntArrayRef, const ::std::optional &, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var"; + static constexpr const char* overload_name = "correction"; + static constexpr const char* schema_str = "var.correction(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False) -> Tensor"; + static at::Tensor call(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim); +}; + +struct TORCH_API var_out { + using schema = at::Tensor & (const at::Tensor &, at::OptionalIntArrayRef, bool, bool, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "var.out(Tensor self, int[1]? dim, bool unbiased=True, bool keepdim=False, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::OptionalIntArrayRef dim, bool unbiased, bool keepdim, at::Tensor & out); +}; + +struct TORCH_API var_correction_out { + using schema = at::Tensor & (const at::Tensor &, at::OptionalIntArrayRef, const ::std::optional &, bool, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var"; + static constexpr const char* overload_name = "correction_out"; + static constexpr const char* schema_str = "var.correction_out(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::OptionalIntArrayRef dim, const ::std::optional & correction, bool keepdim, at::Tensor & out); +}; + +struct TORCH_API var_names_dim { + using schema = at::Tensor (const at::Tensor &, at::DimnameList, bool, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var"; + static constexpr const char* overload_name = "names_dim"; + static constexpr const char* schema_str = "var.names_dim(Tensor self, Dimname[1] dim, bool unbiased=True, bool keepdim=False) -> Tensor"; + static at::Tensor call(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim); +}; + +struct TORCH_API var_names_out { + using schema = at::Tensor & (const at::Tensor &, at::DimnameList, bool, bool, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var"; + static constexpr const char* overload_name = "names_out"; + static constexpr const char* schema_str = "var.names_out(Tensor self, Dimname[1] dim, bool unbiased=True, bool keepdim=False, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::DimnameList dim, bool unbiased, bool keepdim, at::Tensor & out); +}; + +struct TORCH_API var_correction_names { + using schema = at::Tensor (const at::Tensor &, at::DimnameList, const ::std::optional &, bool); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var"; + static constexpr const char* overload_name = "correction_names"; + static constexpr const char* schema_str = "var.correction_names(Tensor self, Dimname[1] dim, *, Scalar? correction=None, bool keepdim=False) -> Tensor"; + static at::Tensor call(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction, bool keepdim); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction, bool keepdim); +}; + +struct TORCH_API var_correction_names_out { + using schema = at::Tensor & (const at::Tensor &, at::DimnameList, const ::std::optional &, bool, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::var"; + static constexpr const char* overload_name = "correction_names_out"; + static constexpr const char* schema_str = "var.correction_names_out(Tensor self, Dimname[1] dim, *, Scalar? correction=None, bool keepdim=False, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction, bool keepdim, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::DimnameList dim, const ::std::optional & correction, bool keepdim, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot.h new file mode 100644 index 0000000000000000000000000000000000000000..21c3d7327778db44154a89eb0c27b1d31fa2f3b4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::vdot(Tensor self, Tensor other) -> Tensor +inline at::Tensor vdot(const at::Tensor & self, const at::Tensor & other) { + return at::_ops::vdot::call(self, other); +} + +// aten::vdot.out(Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & vdot_out(at::Tensor & out, const at::Tensor & self, const at::Tensor & other) { + return at::_ops::vdot_out::call(self, other, out); +} +// aten::vdot.out(Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & vdot_outf(const at::Tensor & self, const at::Tensor & other, at::Tensor & out) { + return at::_ops::vdot_out::call(self, other, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..a0116ab76d50ee40a117153fc34dc42cff5c9750 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_compositeexplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor & vdot_out(at::Tensor & out, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & vdot_outf(const at::Tensor & self, const at::Tensor & other, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..adece70c0cd2fa0385bd17312448a6d6251c1358 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_cpu_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor vdot(const at::Tensor & self, const at::Tensor & other); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..4cf92f24d63d1ead05331a57b7aac6f74165a40d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_cuda_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor vdot(const at::Tensor & self, const at::Tensor & other); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_native.h new file mode 100644 index 0000000000000000000000000000000000000000..77d5e6fa43bb8a0c009599b06de3c523dbfb99a8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_native.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor & vdot_out(const at::Tensor & self, const at::Tensor & other, at::Tensor & out); +TORCH_API at::Tensor vdot(const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor vdot_cuda(const at::Tensor & self, const at::Tensor & other); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..8ced44d2a190b83f6fdd884b1df215725762cadc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vdot_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API vdot { + using schema = at::Tensor (const at::Tensor &, const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::vdot"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "vdot(Tensor self, Tensor other) -> Tensor"; + static at::Tensor call(const at::Tensor & self, const at::Tensor & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Tensor & other); +}; + +struct TORCH_API vdot_out { + using schema = at::Tensor & (const at::Tensor &, const at::Tensor &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::vdot"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "vdot.out(Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, const at::Tensor & other, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Tensor & other, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view.h new file mode 100644 index 0000000000000000000000000000000000000000..9bfe1dca8714dbdf93cbe57c6c14b3ac9fcaddb7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +namespace symint { + template >> + at::Tensor view(const at::Tensor & self, at::IntArrayRef size) { + return at::_ops::view::call(self, c10::fromIntArrayRefSlow(size)); + } +} + +namespace symint { + template >> + at::Tensor view(const at::Tensor & self, c10::SymIntArrayRef size) { + return at::_ops::view::call(self, size); + } +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as.h new file mode 100644 index 0000000000000000000000000000000000000000..88331dea6a94e7880564d66017aeacd8ce806088 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex.h new file mode 100644 index 0000000000000000000000000000000000000000..103df5055d18aa2babc2eb9664b1b57e349baa86 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::view_as_complex(Tensor(a) self) -> Tensor(a) +inline at::Tensor view_as_complex(const at::Tensor & self) { + return at::_ops::view_as_complex::call(self); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy.h new file mode 100644 index 0000000000000000000000000000000000000000..87d25c1dcd4f185e35f46f714d1ec32f805c00d7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::view_as_complex_copy(Tensor self) -> Tensor +inline at::Tensor view_as_complex_copy(const at::Tensor & self) { + return at::_ops::view_as_complex_copy::call(self); +} + +// aten::view_as_complex_copy.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_as_complex_copy_out(at::Tensor & out, const at::Tensor & self) { + return at::_ops::view_as_complex_copy_out::call(self, out); +} +// aten::view_as_complex_copy.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_as_complex_copy_outf(const at::Tensor & self, at::Tensor & out) { + return at::_ops::view_as_complex_copy_out::call(self, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..6ef9119defc4bc816254885cda7ffb786474720d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_compositeexplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor & view_as_complex_copy_out(at::Tensor & out, const at::Tensor & self); +TORCH_API at::Tensor & view_as_complex_copy_outf(const at::Tensor & self, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..9bcf9a855579103198e56f11d3c50c5d5213cb49 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor view_as_complex_copy(const at::Tensor & self); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_native.h new file mode 100644 index 0000000000000000000000000000000000000000..643cb7388a3e7d644ada67c5e045b8fb53317e1d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor & view_as_complex_copy_out(const at::Tensor & self, at::Tensor & out); +TORCH_API at::Tensor view_as_complex_copy(const at::Tensor & self); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..d9abbee7ce30a60d6ca25a9b6914c8246a7cde19 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_copy_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API view_as_complex_copy { + using schema = at::Tensor (const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_as_complex_copy"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "view_as_complex_copy(Tensor self) -> Tensor"; + static at::Tensor call(const at::Tensor & self); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self); +}; + +struct TORCH_API view_as_complex_copy_out { + using schema = at::Tensor & (const at::Tensor &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_as_complex_copy"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "view_as_complex_copy.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..a3b4ff76f5afc1edd038d0fdc1dc8f6b22746c5e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_cpu_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor view_as_complex(const at::Tensor & self); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..7460df92c779dd9c7d1869a684ee495593cf80ac --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_cuda_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor view_as_complex(const at::Tensor & self); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..e339556c570e1dc2e5dffa89b011ad77f0ba49e1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_meta_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor view_as_complex(const at::Tensor & self); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_native.h new file mode 100644 index 0000000000000000000000000000000000000000..3ff1f3f859904e5a9936ab6d888e931836737eb0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor view_as_complex(const at::Tensor & self); +TORCH_API at::Tensor view_as_complex_sparse(const at::Tensor & self); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..bd56675ef504fd670f0c1475522a03ff14aa4010 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_complex_ops.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API view_as_complex { + using schema = at::Tensor (const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_as_complex"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "view_as_complex(Tensor(a) self) -> Tensor(a)"; + static at::Tensor call(const at::Tensor & self); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..e1a51f15bd65c99588600e68e5ce5fc25afacbe9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_compositeimplicitautograd_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor view_as(const at::Tensor & self, const at::Tensor & other); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_native.h new file mode 100644 index 0000000000000000000000000000000000000000..1e6034883e3b059b201aeb2f1831c98518b0fe59 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_native.h @@ -0,0 +1,26 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor view_as(const at::Tensor & self, const at::Tensor & other); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..b087a8e9dfc29c955f7151ef6f2251c32b4341f9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_ops.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API view_as { + using schema = at::Tensor (const at::Tensor &, const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_as"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "view_as(Tensor(a) self, Tensor other) -> Tensor(a)"; + static at::Tensor call(const at::Tensor & self, const at::Tensor & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Tensor & other); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real.h new file mode 100644 index 0000000000000000000000000000000000000000..fe61e8c7f6492e8ec98308959abdacd247064026 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::view_as_real(Tensor(a) self) -> Tensor(a) +inline at::Tensor view_as_real(const at::Tensor & self) { + return at::_ops::view_as_real::call(self); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy.h new file mode 100644 index 0000000000000000000000000000000000000000..7622dbff775464e82728560b143a3387851e7431 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::view_as_real_copy(Tensor self) -> Tensor +inline at::Tensor view_as_real_copy(const at::Tensor & self) { + return at::_ops::view_as_real_copy::call(self); +} + +// aten::view_as_real_copy.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_as_real_copy_out(at::Tensor & out, const at::Tensor & self) { + return at::_ops::view_as_real_copy_out::call(self, out); +} +// aten::view_as_real_copy.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_as_real_copy_outf(const at::Tensor & self, at::Tensor & out) { + return at::_ops::view_as_real_copy_out::call(self, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..1bd6367e33028bcf7756da79f1eef60e3f63df82 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_compositeexplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor & view_as_real_copy_out(at::Tensor & out, const at::Tensor & self); +TORCH_API at::Tensor & view_as_real_copy_outf(const at::Tensor & self, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..dfd4aa3c7a8676ab9a13aa42d753b28072af240c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor view_as_real_copy(const at::Tensor & self); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_native.h new file mode 100644 index 0000000000000000000000000000000000000000..37c82a432d26fe6ecd85d97484205f8294ba2f81 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor & view_as_real_copy_out(const at::Tensor & self, at::Tensor & out); +TORCH_API at::Tensor view_as_real_copy(const at::Tensor & self); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..7d46b7fc87cae03114007d9dc5fc242e9a74eed9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_copy_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API view_as_real_copy { + using schema = at::Tensor (const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_as_real_copy"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "view_as_real_copy(Tensor self) -> Tensor"; + static at::Tensor call(const at::Tensor & self); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self); +}; + +struct TORCH_API view_as_real_copy_out { + using schema = at::Tensor & (const at::Tensor &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_as_real_copy"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "view_as_real_copy.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..93930e2319529293892c092dbe969c726d22d97e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_cpu_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor view_as_real(const at::Tensor & self); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..831781f271fae9e0429b6ae8550673b885de91c3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_cuda_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor view_as_real(const at::Tensor & self); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..9fca166e21a6e632282acf1f8ce5bac6de4ece3c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_meta_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor view_as_real(const at::Tensor & self); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_native.h new file mode 100644 index 0000000000000000000000000000000000000000..851b96ebf9db54367ed75b9c6ce23b5a394b31b0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor view_as_real(const at::Tensor & self); +TORCH_API at::Tensor view_as_real_sparse(const at::Tensor & self); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..01f1e80f05037523cb5e96a4a98b30d742b1a44a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_as_real_ops.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API view_as_real { + using schema = at::Tensor (const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_as_real"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "view_as_real(Tensor(a) self) -> Tensor(a)"; + static at::Tensor call(const at::Tensor & self); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..349cfc74469ab3c48513179764961eb4d73aa88a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_compositeexplicitautograd_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor view(const at::Tensor & self, at::ScalarType dtype); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy.h new file mode 100644 index 0000000000000000000000000000000000000000..6c5bae444bc61bc7d9f2ff505feede9256d76d88 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy.h @@ -0,0 +1,111 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::view_copy(Tensor self, SymInt[] size) -> Tensor +inline at::Tensor view_copy(const at::Tensor & self, at::IntArrayRef size) { + return at::_ops::view_copy::call(self, c10::fromIntArrayRefSlow(size)); +} +namespace symint { + template >> + at::Tensor view_copy(const at::Tensor & self, at::IntArrayRef size) { + return at::_ops::view_copy::call(self, c10::fromIntArrayRefSlow(size)); + } +} + +// aten::view_copy(Tensor self, SymInt[] size) -> Tensor +inline at::Tensor view_copy_symint(const at::Tensor & self, c10::SymIntArrayRef size) { + return at::_ops::view_copy::call(self, size); +} +namespace symint { + template >> + at::Tensor view_copy(const at::Tensor & self, c10::SymIntArrayRef size) { + return at::_ops::view_copy::call(self, size); + } +} + +// aten::view_copy.dtype(Tensor self, ScalarType dtype) -> Tensor +inline at::Tensor view_copy(const at::Tensor & self, at::ScalarType dtype) { + return at::_ops::view_copy_dtype::call(self, dtype); +} + +// aten::view_copy.out(Tensor self, SymInt[] size, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_copy_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef size) { + return at::_ops::view_copy_out::call(self, c10::fromIntArrayRefSlow(size), out); +} +namespace symint { + template >> + at::Tensor & view_copy_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef size) { + return at::_ops::view_copy_out::call(self, c10::fromIntArrayRefSlow(size), out); + } +} + +// aten::view_copy.out(Tensor self, SymInt[] size, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_copy_outf(const at::Tensor & self, at::IntArrayRef size, at::Tensor & out) { + return at::_ops::view_copy_out::call(self, c10::fromIntArrayRefSlow(size), out); +} +namespace symint { + template >> + at::Tensor & view_copy_outf(const at::Tensor & self, at::IntArrayRef size, at::Tensor & out) { + return at::_ops::view_copy_out::call(self, c10::fromIntArrayRefSlow(size), out); + } +} + +// aten::view_copy.out(Tensor self, SymInt[] size, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_copy_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef size) { + return at::_ops::view_copy_out::call(self, size, out); +} +namespace symint { + template >> + at::Tensor & view_copy_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef size) { + return at::_ops::view_copy_out::call(self, size, out); + } +} + +// aten::view_copy.out(Tensor self, SymInt[] size, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_copy_symint_outf(const at::Tensor & self, c10::SymIntArrayRef size, at::Tensor & out) { + return at::_ops::view_copy_out::call(self, size, out); +} +namespace symint { + template >> + at::Tensor & view_copy_outf(const at::Tensor & self, c10::SymIntArrayRef size, at::Tensor & out) { + return at::_ops::view_copy_out::call(self, size, out); + } +} + +// aten::view_copy.dtype_out(Tensor self, ScalarType dtype, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_copy_out(at::Tensor & out, const at::Tensor & self, at::ScalarType dtype) { + return at::_ops::view_copy_dtype_out::call(self, dtype, out); +} +// aten::view_copy.dtype_out(Tensor self, ScalarType dtype, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & view_copy_outf(const at::Tensor & self, at::ScalarType dtype, at::Tensor & out) { + return at::_ops::view_copy_dtype_out::call(self, dtype, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c241f3964bf4c7185a71cdff0c5c86b85d298fbc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_compositeexplicitautograd_dispatch.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor & view_copy_out(at::Tensor & out, const at::Tensor & self, at::IntArrayRef size); +TORCH_API at::Tensor & view_copy_outf(const at::Tensor & self, at::IntArrayRef size, at::Tensor & out); +TORCH_API at::Tensor & view_copy_symint_out(at::Tensor & out, const at::Tensor & self, c10::SymIntArrayRef size); +TORCH_API at::Tensor & view_copy_symint_outf(const at::Tensor & self, c10::SymIntArrayRef size, at::Tensor & out); +TORCH_API at::Tensor & view_copy_out(at::Tensor & out, const at::Tensor & self, at::ScalarType dtype); +TORCH_API at::Tensor & view_copy_outf(const at::Tensor & self, at::ScalarType dtype, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c23ccc99e3df0e952961f829f1fb4d19d1af8bf9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,30 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor view_copy(const at::Tensor & self, at::IntArrayRef size); +TORCH_API at::Tensor view_copy_symint(const at::Tensor & self, c10::SymIntArrayRef size); +TORCH_API at::Tensor view_copy(const at::Tensor & self, at::ScalarType dtype); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_native.h new file mode 100644 index 0000000000000000000000000000000000000000..f83ee680abe75ff7fc72c64ed81dc12f77f9342a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_native.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor & view_copy_out_symint(const at::Tensor & self, c10::SymIntArrayRef size, at::Tensor & out); +TORCH_API at::Tensor view_copy_symint(const at::Tensor & self, c10::SymIntArrayRef size); +TORCH_API at::Tensor & view_copy_dtype_out(const at::Tensor & self, at::ScalarType dtype, at::Tensor & out); +TORCH_API at::Tensor view_copy_dtype(const at::Tensor & self, at::ScalarType dtype); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..25f9ceeb021b33ca4df27c5d8674622b2f91cea4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_copy_ops.h @@ -0,0 +1,67 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API view_copy { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_copy"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "view_copy(Tensor self, SymInt[] size) -> Tensor"; + static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef size); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef size); +}; + +struct TORCH_API view_copy_dtype { + using schema = at::Tensor (const at::Tensor &, at::ScalarType); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_copy"; + static constexpr const char* overload_name = "dtype"; + static constexpr const char* schema_str = "view_copy.dtype(Tensor self, ScalarType dtype) -> Tensor"; + static at::Tensor call(const at::Tensor & self, at::ScalarType dtype); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::ScalarType dtype); +}; + +struct TORCH_API view_copy_out { + using schema = at::Tensor & (const at::Tensor &, c10::SymIntArrayRef, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_copy"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "view_copy.out(Tensor self, SymInt[] size, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, c10::SymIntArrayRef size, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef size, at::Tensor & out); +}; + +struct TORCH_API view_copy_dtype_out { + using schema = at::Tensor & (const at::Tensor &, at::ScalarType, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view_copy"; + static constexpr const char* overload_name = "dtype_out"; + static constexpr const char* schema_str = "view_copy.dtype_out(Tensor self, ScalarType dtype, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, at::ScalarType dtype, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::ScalarType dtype, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..9e4f7e415c020d28dd1be06e0b6301d07892bc12 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_cpu_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor view(const at::Tensor & self, at::IntArrayRef size); +TORCH_API at::Tensor view_symint(const at::Tensor & self, c10::SymIntArrayRef size); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..478891cf530988fd79779f75bf74b444f441163c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_cuda_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor view(const at::Tensor & self, at::IntArrayRef size); +TORCH_API at::Tensor view_symint(const at::Tensor & self, c10::SymIntArrayRef size); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..cad667e2f0f57bd702a77c63632a7e67190ec6a0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_meta_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor view(const at::Tensor & self, at::IntArrayRef size); +TORCH_API at::Tensor view_symint(const at::Tensor & self, c10::SymIntArrayRef size); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_native.h new file mode 100644 index 0000000000000000000000000000000000000000..34b22d4c8f7d9baf2b8418ed9b184b56a586e151 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_native.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor view(const at::Tensor & self, at::IntArrayRef size); +TORCH_API at::Tensor view_nested(const at::Tensor & self, at::IntArrayRef size); +TORCH_API at::Tensor mkldnn_view(const at::Tensor & self, at::IntArrayRef size); +TORCH_API at::Tensor view_dtype(const at::Tensor & self, at::ScalarType dtype); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..36de89dbd9c766814ebecca3cfffe7e0f2d2c4de --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/view_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API view { + using schema = at::Tensor (const at::Tensor &, c10::SymIntArrayRef); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "view(Tensor(a) self, SymInt[] size) -> Tensor(a)"; + static at::Tensor call(const at::Tensor & self, c10::SymIntArrayRef size); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, c10::SymIntArrayRef size); +}; + +struct TORCH_API view_dtype { + using schema = at::Tensor (const at::Tensor &, at::ScalarType); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::view"; + static constexpr const char* overload_name = "dtype"; + static constexpr const char* schema_str = "view.dtype(Tensor(a) self, ScalarType dtype) -> Tensor(a)"; + static at::Tensor call(const at::Tensor & self, at::ScalarType dtype); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::ScalarType dtype); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit.h new file mode 100644 index 0000000000000000000000000000000000000000..54a26e4e3da828e7334c5897e1882cef17a6d89a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit.h @@ -0,0 +1,41 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::vsplit.int(Tensor(a -> *) self, int sections) -> Tensor(a)[] +inline ::std::vector vsplit(const at::Tensor & self, int64_t sections) { + return at::_ops::vsplit_int::call(self, sections); +} + +// aten::vsplit.array(Tensor(a -> *) self, int[] indices) -> Tensor(a)[] +inline ::std::vector vsplit(const at::Tensor & self, at::IntArrayRef indices) { + return at::_ops::vsplit_array::call(self, indices); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..d14aead0649fe848b2e525da375e4b85e5f92df3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit_compositeimplicitautograd_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API ::std::vector vsplit(const at::Tensor & self, int64_t sections); +TORCH_API ::std::vector vsplit(const at::Tensor & self, at::IntArrayRef indices); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit_native.h new file mode 100644 index 0000000000000000000000000000000000000000..721292f36174bf5877e42ec48559c1acbbc9df8e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API ::std::vector vsplit(const at::Tensor & self, int64_t sections); +TORCH_API ::std::vector vsplit(const at::Tensor & self, at::IntArrayRef indices); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..81f818d759255e5d82f720eea582dda91058f1cc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vsplit_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API vsplit_int { + using schema = ::std::vector (const at::Tensor &, int64_t); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::vsplit"; + static constexpr const char* overload_name = "int"; + static constexpr const char* schema_str = "vsplit.int(Tensor(a -> *) self, int sections) -> Tensor(a)[]"; + static ::std::vector call(const at::Tensor & self, int64_t sections); + static ::std::vector redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, int64_t sections); +}; + +struct TORCH_API vsplit_array { + using schema = ::std::vector (const at::Tensor &, at::IntArrayRef); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::vsplit"; + static constexpr const char* overload_name = "array"; + static constexpr const char* schema_str = "vsplit.array(Tensor(a -> *) self, int[] indices) -> Tensor(a)[]"; + static ::std::vector call(const at::Tensor & self, at::IntArrayRef indices); + static ::std::vector redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::IntArrayRef indices); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack.h new file mode 100644 index 0000000000000000000000000000000000000000..181e5b9a66a52491cbe6f755a38ee2fedd71ac36 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::vstack(Tensor[] tensors) -> Tensor +inline at::Tensor vstack(at::TensorList tensors) { + return at::_ops::vstack::call(tensors); +} + +// aten::vstack.out(Tensor[] tensors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & vstack_out(at::Tensor & out, at::TensorList tensors) { + return at::_ops::vstack_out::call(tensors, out); +} +// aten::vstack.out(Tensor[] tensors, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & vstack_outf(at::TensorList tensors, at::Tensor & out) { + return at::_ops::vstack_out::call(tensors, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..e951290f0619e6ebb69ab2b98c4befa67bce2563 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack_compositeimplicitautograd_dispatch.h @@ -0,0 +1,30 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor vstack(at::TensorList tensors); +TORCH_API at::Tensor & vstack_out(at::Tensor & out, at::TensorList tensors); +TORCH_API at::Tensor & vstack_outf(at::TensorList tensors, at::Tensor & out); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack_native.h new file mode 100644 index 0000000000000000000000000000000000000000..4b50a1bcb0ff23da4dfa24f211ee82a0666b3b6b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor vstack(at::TensorList tensors); +TORCH_API at::Tensor & vstack_out(at::TensorList tensors, at::Tensor & out); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..2ca29925d3ca3f78593d23e7105385d1b37690e0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/vstack_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API vstack { + using schema = at::Tensor (at::TensorList); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::vstack"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "vstack(Tensor[] tensors) -> Tensor"; + static at::Tensor call(at::TensorList tensors); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors); +}; + +struct TORCH_API vstack_out { + using schema = at::Tensor & (at::TensorList, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::vstack"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "vstack.out(Tensor[] tensors, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(at::TensorList tensors, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::TensorList tensors, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where.h new file mode 100644 index 0000000000000000000000000000000000000000..98b602d9fd4fc1a05b13f230abe9815bafe01bf5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where.h @@ -0,0 +1,65 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::where.self(Tensor condition, Tensor self, Tensor other) -> Tensor +inline at::Tensor where(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other) { + return at::_ops::where_self::call(condition, self, other); +} + +// aten::where.self_out(Tensor condition, Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & where_out(at::Tensor & out, const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other) { + return at::_ops::where_self_out::call(condition, self, other, out); +} +// aten::where.self_out(Tensor condition, Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & where_outf(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other, at::Tensor & out) { + return at::_ops::where_self_out::call(condition, self, other, out); +} + +// aten::where.ScalarSelf(Tensor condition, Scalar self, Tensor other) -> Tensor +inline at::Tensor where(const at::Tensor & condition, const at::Scalar & self, const at::Tensor & other) { + return at::_ops::where_ScalarSelf::call(condition, self, other); +} + +// aten::where.ScalarOther(Tensor condition, Tensor self, Scalar other) -> Tensor +inline at::Tensor where(const at::Tensor & condition, const at::Tensor & self, const at::Scalar & other) { + return at::_ops::where_ScalarOther::call(condition, self, other); +} + +// aten::where.Scalar(Tensor condition, Scalar self, Scalar other) -> Tensor +inline at::Tensor where(const at::Tensor & condition, const at::Scalar & self, const at::Scalar & other) { + return at::_ops::where_Scalar::call(condition, self, other); +} + +// aten::where(Tensor condition) -> Tensor[] +inline ::std::vector where(const at::Tensor & condition) { + return at::_ops::where::call(condition); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..fadff04886c6035cb1c4d93ace2d770ac67c95a8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_compositeimplicitautograd_dispatch.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor where(const at::Tensor & condition, const at::Scalar & self, const at::Tensor & other); +TORCH_API at::Tensor where(const at::Tensor & condition, const at::Tensor & self, const at::Scalar & other); +TORCH_API at::Tensor where(const at::Tensor & condition, const at::Scalar & self, const at::Scalar & other); +TORCH_API ::std::vector where(const at::Tensor & condition); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..29ff03ba091ed90e9d48278066b2e39fb19024d1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_cpu_dispatch.h @@ -0,0 +1,30 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor where(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & where_out(at::Tensor & out, const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & where_outf(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other, at::Tensor & out); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..2cb48cb4c7c866d667250a19f8fbfe0f7235101c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_cuda_dispatch.h @@ -0,0 +1,30 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor where(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & where_out(at::Tensor & out, const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & where_outf(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other, at::Tensor & out); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_native.h new file mode 100644 index 0000000000000000000000000000000000000000..9ad14f353a1bb242425f721608bf8643f5345db3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_native.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor where(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & where_self_out(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other, at::Tensor & out); +TORCH_API at::Tensor NestedTensor_where(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & NestedTensor_where_out(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other, at::Tensor & out); +TORCH_API at::Tensor where(const at::Tensor & condition, const at::Scalar & self, const at::Tensor & other); +TORCH_API at::Tensor where(const at::Tensor & condition, const at::Tensor & self, const at::Scalar & other); +TORCH_API at::Tensor where(const at::Tensor & condition, const at::Scalar & self, const at::Scalar & other); +TORCH_API ::std::vector where(const at::Tensor & condition); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..4fdef5d5895e977c082233ab102f48aa5d7bd39a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/where_ops.h @@ -0,0 +1,89 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API where_self { + using schema = at::Tensor (const at::Tensor &, const at::Tensor &, const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::where"; + static constexpr const char* overload_name = "self"; + static constexpr const char* schema_str = "where.self(Tensor condition, Tensor self, Tensor other) -> Tensor"; + static at::Tensor call(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other); +}; + +struct TORCH_API where_self_out { + using schema = at::Tensor & (const at::Tensor &, const at::Tensor &, const at::Tensor &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::where"; + static constexpr const char* overload_name = "self_out"; + static constexpr const char* schema_str = "where.self_out(Tensor condition, Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & condition, const at::Tensor & self, const at::Tensor & other, at::Tensor & out); +}; + +struct TORCH_API where_ScalarSelf { + using schema = at::Tensor (const at::Tensor &, const at::Scalar &, const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::where"; + static constexpr const char* overload_name = "ScalarSelf"; + static constexpr const char* schema_str = "where.ScalarSelf(Tensor condition, Scalar self, Tensor other) -> Tensor"; + static at::Tensor call(const at::Tensor & condition, const at::Scalar & self, const at::Tensor & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & condition, const at::Scalar & self, const at::Tensor & other); +}; + +struct TORCH_API where_ScalarOther { + using schema = at::Tensor (const at::Tensor &, const at::Tensor &, const at::Scalar &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::where"; + static constexpr const char* overload_name = "ScalarOther"; + static constexpr const char* schema_str = "where.ScalarOther(Tensor condition, Tensor self, Scalar other) -> Tensor"; + static at::Tensor call(const at::Tensor & condition, const at::Tensor & self, const at::Scalar & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & condition, const at::Tensor & self, const at::Scalar & other); +}; + +struct TORCH_API where_Scalar { + using schema = at::Tensor (const at::Tensor &, const at::Scalar &, const at::Scalar &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::where"; + static constexpr const char* overload_name = "Scalar"; + static constexpr const char* schema_str = "where.Scalar(Tensor condition, Scalar self, Scalar other) -> Tensor"; + static at::Tensor call(const at::Tensor & condition, const at::Scalar & self, const at::Scalar & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & condition, const at::Scalar & self, const at::Scalar & other); +}; + +struct TORCH_API where { + using schema = ::std::vector (const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::where"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "where(Tensor condition) -> Tensor[]"; + static ::std::vector call(const at::Tensor & condition); + static ::std::vector redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & condition); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy.h new file mode 100644 index 0000000000000000000000000000000000000000..9fac974572e1c68d94a417f29a2b9140f9a758ed --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy.h @@ -0,0 +1,83 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::xlogy.Tensor(Tensor self, Tensor other) -> Tensor +inline at::Tensor xlogy(const at::Tensor & self, const at::Tensor & other) { + return at::_ops::xlogy_Tensor::call(self, other); +} + +// aten::xlogy.Scalar_Self(Scalar self, Tensor other) -> Tensor +inline at::Tensor xlogy(const at::Scalar & self, const at::Tensor & other) { + return at::_ops::xlogy_Scalar_Self::call(self, other); +} + +// aten::xlogy.Scalar_Other(Tensor self, Scalar other) -> Tensor +inline at::Tensor xlogy(const at::Tensor & self, const at::Scalar & other) { + return at::_ops::xlogy_Scalar_Other::call(self, other); +} + +// aten::xlogy_.Tensor(Tensor(a!) self, Tensor other) -> Tensor(a!) +inline at::Tensor & xlogy_(at::Tensor & self, const at::Tensor & other) { + return at::_ops::xlogy__Tensor::call(self, other); +} + +// aten::xlogy_.Scalar_Other(Tensor(a!) self, Scalar other) -> Tensor(a!) +inline at::Tensor & xlogy_(at::Tensor & self, const at::Scalar & other) { + return at::_ops::xlogy__Scalar_Other::call(self, other); +} + +// aten::xlogy.OutTensor(Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & xlogy_out(at::Tensor & out, const at::Tensor & self, const at::Tensor & other) { + return at::_ops::xlogy_OutTensor::call(self, other, out); +} +// aten::xlogy.OutTensor(Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & xlogy_outf(const at::Tensor & self, const at::Tensor & other, at::Tensor & out) { + return at::_ops::xlogy_OutTensor::call(self, other, out); +} + +// aten::xlogy.OutScalar_Self(Scalar self, Tensor other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & xlogy_out(at::Tensor & out, const at::Scalar & self, const at::Tensor & other) { + return at::_ops::xlogy_OutScalar_Self::call(self, other, out); +} +// aten::xlogy.OutScalar_Self(Scalar self, Tensor other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & xlogy_outf(const at::Scalar & self, const at::Tensor & other, at::Tensor & out) { + return at::_ops::xlogy_OutScalar_Self::call(self, other, out); +} + +// aten::xlogy.OutScalar_Other(Tensor self, Scalar other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & xlogy_out(at::Tensor & out, const at::Tensor & self, const at::Scalar & other) { + return at::_ops::xlogy_OutScalar_Other::call(self, other, out); +} +// aten::xlogy.OutScalar_Other(Tensor self, Scalar other, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & xlogy_outf(const at::Tensor & self, const at::Scalar & other, at::Tensor & out) { + return at::_ops::xlogy_OutScalar_Other::call(self, other, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..c4536feeb5e8026b666b11fac3f707a7bda33038 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_compositeexplicitautograd_dispatch.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor xlogy(const at::Scalar & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_out(at::Tensor & out, const at::Scalar & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_outf(const at::Scalar & self, const at::Tensor & other, at::Tensor & out); +TORCH_API at::Tensor xlogy(const at::Tensor & self, const at::Scalar & other); +TORCH_API at::Tensor & xlogy_out(at::Tensor & out, const at::Tensor & self, const at::Scalar & other); +TORCH_API at::Tensor & xlogy_outf(const at::Tensor & self, const at::Scalar & other, at::Tensor & out); +TORCH_API at::Tensor & xlogy_(at::Tensor & self, const at::Scalar & other); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_compositeexplicitautogradnonfunctional_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_compositeexplicitautogradnonfunctional_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..b9be4a1b1435445c63aad9843c7dec23f4b4e2a2 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_compositeexplicitautogradnonfunctional_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautogradnonfunctional { + +TORCH_API at::Tensor xlogy(const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_(at::Tensor & self, const at::Tensor & other); + +} // namespace compositeexplicitautogradnonfunctional +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..09707c8e2fd23ae1ee8b42fac029851ea237a3af --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_cpu_dispatch.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor xlogy(const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_out(at::Tensor & out, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_outf(const at::Tensor & self, const at::Tensor & other, at::Tensor & out); +TORCH_API at::Tensor & xlogy_(at::Tensor & self, const at::Tensor & other); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..2e4e2027321aa2c84d9cbc60c42fbe3a053d786b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_cuda_dispatch.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor xlogy(const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_out(at::Tensor & out, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_outf(const at::Tensor & self, const at::Tensor & other, at::Tensor & out); +TORCH_API at::Tensor & xlogy_(at::Tensor & self, const at::Tensor & other); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_meta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_meta.h new file mode 100644 index 0000000000000000000000000000000000000000..2e2626e28358e9c8d842bd76f83ba1ba9cbe0503 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_meta.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeMetaFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace meta { + +struct TORCH_API structured_xlogy_Tensor : public TensorIteratorBase { + + + void meta(const at::Tensor & self, const at::Tensor & other); +}; + +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..735be7dfd0441a52e2c5a78b67c241748666baca --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_meta_dispatch.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor xlogy(const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_out(at::Tensor & out, const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_outf(const at::Tensor & self, const at::Tensor & other, at::Tensor & out); +TORCH_API at::Tensor & xlogy_(at::Tensor & self, const at::Tensor & other); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_native.h new file mode 100644 index 0000000000000000000000000000000000000000..132a13c547ea2218e456378d75fa463ce1a13e58 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_native.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at { +namespace native { +struct TORCH_API structured_xlogy_out : public at::meta::structured_xlogy_Tensor { +void impl(const at::Tensor & self, const at::Tensor & other, const at::Tensor & out); +}; +TORCH_API at::Tensor xlogy(const at::Scalar & self, const at::Tensor & other); +TORCH_API at::Tensor & xlogy_out(const at::Scalar & self, const at::Tensor & other, at::Tensor & out); +TORCH_API at::Tensor xlogy(const at::Tensor & self, const at::Scalar & other); +TORCH_API at::Tensor & xlogy_out(const at::Tensor & self, const at::Scalar & other, at::Tensor & out); +TORCH_API at::Tensor & xlogy_(at::Tensor & self, const at::Scalar & other); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..de881978ddf8b9898e0ce21650cc77459c7b1601 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xlogy_ops.h @@ -0,0 +1,111 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API xlogy_Tensor { + using schema = at::Tensor (const at::Tensor &, const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::xlogy"; + static constexpr const char* overload_name = "Tensor"; + static constexpr const char* schema_str = "xlogy.Tensor(Tensor self, Tensor other) -> Tensor"; + static at::Tensor call(const at::Tensor & self, const at::Tensor & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Tensor & other); +}; + +struct TORCH_API xlogy_Scalar_Self { + using schema = at::Tensor (const at::Scalar &, const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::xlogy"; + static constexpr const char* overload_name = "Scalar_Self"; + static constexpr const char* schema_str = "xlogy.Scalar_Self(Scalar self, Tensor other) -> Tensor"; + static at::Tensor call(const at::Scalar & self, const at::Tensor & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Scalar & self, const at::Tensor & other); +}; + +struct TORCH_API xlogy_Scalar_Other { + using schema = at::Tensor (const at::Tensor &, const at::Scalar &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::xlogy"; + static constexpr const char* overload_name = "Scalar_Other"; + static constexpr const char* schema_str = "xlogy.Scalar_Other(Tensor self, Scalar other) -> Tensor"; + static at::Tensor call(const at::Tensor & self, const at::Scalar & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Scalar & other); +}; + +struct TORCH_API xlogy__Tensor { + using schema = at::Tensor & (at::Tensor &, const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::xlogy_"; + static constexpr const char* overload_name = "Tensor"; + static constexpr const char* schema_str = "xlogy_.Tensor(Tensor(a!) self, Tensor other) -> Tensor(a!)"; + static at::Tensor & call(at::Tensor & self, const at::Tensor & other); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::Tensor & self, const at::Tensor & other); +}; + +struct TORCH_API xlogy__Scalar_Other { + using schema = at::Tensor & (at::Tensor &, const at::Scalar &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::xlogy_"; + static constexpr const char* overload_name = "Scalar_Other"; + static constexpr const char* schema_str = "xlogy_.Scalar_Other(Tensor(a!) self, Scalar other) -> Tensor(a!)"; + static at::Tensor & call(at::Tensor & self, const at::Scalar & other); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::Tensor & self, const at::Scalar & other); +}; + +struct TORCH_API xlogy_OutTensor { + using schema = at::Tensor & (const at::Tensor &, const at::Tensor &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::xlogy"; + static constexpr const char* overload_name = "OutTensor"; + static constexpr const char* schema_str = "xlogy.OutTensor(Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, const at::Tensor & other, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Tensor & other, at::Tensor & out); +}; + +struct TORCH_API xlogy_OutScalar_Self { + using schema = at::Tensor & (const at::Scalar &, const at::Tensor &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::xlogy"; + static constexpr const char* overload_name = "OutScalar_Self"; + static constexpr const char* schema_str = "xlogy.OutScalar_Self(Scalar self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Scalar & self, const at::Tensor & other, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Scalar & self, const at::Tensor & other, at::Tensor & out); +}; + +struct TORCH_API xlogy_OutScalar_Other { + using schema = at::Tensor & (const at::Tensor &, const at::Scalar &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::xlogy"; + static constexpr const char* overload_name = "OutScalar_Other"; + static constexpr const char* schema_str = "xlogy.OutScalar_Other(Tensor self, Scalar other, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, const at::Scalar & other, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Scalar & other, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor.h new file mode 100644 index 0000000000000000000000000000000000000000..80dc5b3ba7e2906b77b74ecd03cd46db6dc894cb --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor.h @@ -0,0 +1,41 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::__xor__.Scalar(Tensor self, Scalar other) -> Tensor +inline at::Tensor __xor__(const at::Tensor & self, const at::Scalar & other) { + return at::_ops::__xor___Scalar::call(self, other); +} + +// aten::__xor__.Tensor(Tensor self, Tensor other) -> Tensor +inline at::Tensor __xor__(const at::Tensor & self, const at::Tensor & other) { + return at::_ops::__xor___Tensor::call(self, other); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor_compositeimplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor_compositeimplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..9a70f0c795309fe590f14d6e2ebd5faf47adc1ab --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor_compositeimplicitautograd_dispatch.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautograd { + +TORCH_API at::Tensor __xor__(const at::Tensor & self, const at::Scalar & other); +TORCH_API at::Tensor & __ixor__(at::Tensor & self, const at::Scalar & other); +TORCH_API at::Tensor __xor__(const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & __ixor__(at::Tensor & self, const at::Tensor & other); + +} // namespace compositeimplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor_native.h new file mode 100644 index 0000000000000000000000000000000000000000..5409814eb2b3b53fc40052d6fdcab32f0fea10bf --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor_native.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor __xor__(const at::Tensor & self, const at::Scalar & other); +TORCH_API at::Tensor & __ixor__(at::Tensor & self, const at::Scalar & other); +TORCH_API at::Tensor __xor__(const at::Tensor & self, const at::Tensor & other); +TORCH_API at::Tensor & __ixor__(at::Tensor & self, const at::Tensor & other); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..33cde2fe7a2092169b2efef97731956ff1631780 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/xor_ops.h @@ -0,0 +1,67 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API __xor___Scalar { + using schema = at::Tensor (const at::Tensor &, const at::Scalar &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::__xor__"; + static constexpr const char* overload_name = "Scalar"; + static constexpr const char* schema_str = "__xor__.Scalar(Tensor self, Scalar other) -> Tensor"; + static at::Tensor call(const at::Tensor & self, const at::Scalar & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Scalar & other); +}; + +struct TORCH_API __xor___Tensor { + using schema = at::Tensor (const at::Tensor &, const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::__xor__"; + static constexpr const char* overload_name = "Tensor"; + static constexpr const char* schema_str = "__xor__.Tensor(Tensor self, Tensor other) -> Tensor"; + static at::Tensor call(const at::Tensor & self, const at::Tensor & other); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, const at::Tensor & other); +}; + +struct TORCH_API __ixor___Scalar { + using schema = at::Tensor & (at::Tensor &, const at::Scalar &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::__ixor__"; + static constexpr const char* overload_name = "Scalar"; + static constexpr const char* schema_str = "__ixor__.Scalar(Tensor(a!) self, Scalar other) -> Tensor(a!)"; + static at::Tensor & call(at::Tensor & self, const at::Scalar & other); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::Tensor & self, const at::Scalar & other); +}; + +struct TORCH_API __ixor___Tensor { + using schema = at::Tensor & (at::Tensor &, const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::__ixor__"; + static constexpr const char* overload_name = "Tensor"; + static constexpr const char* schema_str = "__ixor__.Tensor(Tensor(a!) self, Tensor other) -> Tensor(a!)"; + static at::Tensor & call(at::Tensor & self, const at::Tensor & other); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::Tensor & self, const at::Tensor & other); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero.h new file mode 100644 index 0000000000000000000000000000000000000000..9cb89bf96a592c91aedfd4fad33f25b2ddbef542 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero.h @@ -0,0 +1,50 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::zero_(Tensor(a!) self) -> Tensor(a!) +inline at::Tensor & zero_(at::Tensor & self) { + return at::_ops::zero_::call(self); +} + +// aten::zero.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zero_out(at::Tensor & out, const at::Tensor & self) { + return at::_ops::zero_out::call(self, out); +} +// aten::zero.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zero_outf(const at::Tensor & self, at::Tensor & out) { + return at::_ops::zero_out::call(self, out); +} + +// aten::zero(Tensor self) -> Tensor +inline at::Tensor zero(const at::Tensor & self) { + return at::_ops::zero::call(self); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..dfb2ae5c91aeb0c48e11e35cc3b7eb09054a56ad --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_compositeexplicitautograd_dispatch.h @@ -0,0 +1,30 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor zero(const at::Tensor & self); +TORCH_API at::Tensor & zero_out(at::Tensor & out, const at::Tensor & self); +TORCH_API at::Tensor & zero_outf(const at::Tensor & self, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_cpu_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_cpu_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..0275a6411b1ed0a1213aa55759f5f880f6578463 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_cpu_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cpu { + +TORCH_API at::Tensor & zero_(at::Tensor & self); + +} // namespace cpu +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_cuda_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_cuda_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..2fb750d56f9e4b157ba3769324e02d3bfc2c5dc0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_cuda_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace cuda { + +TORCH_API at::Tensor & zero_(at::Tensor & self); + +} // namespace cuda +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_meta_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_meta_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..d973fe0c229d1748d9f9b83e281b897a7539318c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_meta_dispatch.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace meta { + +TORCH_API at::Tensor & zero_(at::Tensor & self); + +} // namespace meta +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_native.h new file mode 100644 index 0000000000000000000000000000000000000000..388a6963d0ed77e0632b546e17fba69057ec4491 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_native.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor zero(const at::Tensor & self); +TORCH_API at::Tensor & zero_out(const at::Tensor & self, at::Tensor & out); +TORCH_API at::Tensor & zero_(at::Tensor & self); +TORCH_API at::Tensor & zero_meta_(at::Tensor & self); +TORCH_API at::Tensor & zero_nested_(at::Tensor & self); +TORCH_API at::Tensor & zero_sparse_(at::Tensor & self); +TORCH_API at::Tensor & zero_sparse_csr_(at::Tensor & self); +TORCH_API at::Tensor & mkldnn_zero_(at::Tensor & self); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..a06946acc48659e431e3b873699013148ce8d9d3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zero_ops.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API zero_ { + using schema = at::Tensor & (at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::zero_"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "zero_(Tensor(a!) self) -> Tensor(a!)"; + static at::Tensor & call(at::Tensor & self); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::Tensor & self); +}; + +struct TORCH_API zero_out { + using schema = at::Tensor & (const at::Tensor &, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::zero"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "zero.out(Tensor self, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, at::Tensor & out); +}; + +struct TORCH_API zero { + using schema = at::Tensor (const at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::zero"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "zero(Tensor self) -> Tensor"; + static at::Tensor call(const at::Tensor & self); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros.h new file mode 100644 index 0000000000000000000000000000000000000000..5422f75da4345f769cdb01d23a429595f3c0e09f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros.h @@ -0,0 +1,137 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::zeros.names(int[] size, *, Dimname[]? names, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor +inline at::Tensor zeros(at::IntArrayRef size, ::std::optional names, at::TensorOptions options={}) { + return at::_ops::zeros_names::call(size, names, c10::optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt()); +} +// aten::zeros.names(int[] size, *, Dimname[]? names, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor +inline at::Tensor zeros(at::IntArrayRef size, ::std::optional names, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory) { + return at::_ops::zeros_names::call(size, names, dtype, layout, device, pin_memory); +} + +// aten::zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor +inline at::Tensor zeros(at::IntArrayRef size, at::TensorOptions options={}) { + return at::_ops::zeros::call(c10::fromIntArrayRefSlow(size), c10::optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt()); +} +namespace symint { + template >> + at::Tensor zeros(at::IntArrayRef size, at::TensorOptions options={}) { + return at::_ops::zeros::call(c10::fromIntArrayRefSlow(size), c10::optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt()); + } +} + +// aten::zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor +inline at::Tensor zeros(at::IntArrayRef size, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory) { + return at::_ops::zeros::call(c10::fromIntArrayRefSlow(size), dtype, layout, device, pin_memory); +} +namespace symint { + template >> + at::Tensor zeros(at::IntArrayRef size, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory) { + return at::_ops::zeros::call(c10::fromIntArrayRefSlow(size), dtype, layout, device, pin_memory); + } +} + +// aten::zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor +inline at::Tensor zeros_symint(c10::SymIntArrayRef size, at::TensorOptions options={}) { + return at::_ops::zeros::call(size, c10::optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt()); +} +namespace symint { + template >> + at::Tensor zeros(c10::SymIntArrayRef size, at::TensorOptions options={}) { + return at::_ops::zeros::call(size, c10::optTypeMetaToScalarType(options.dtype_opt()), options.layout_opt(), options.device_opt(), options.pinned_memory_opt()); + } +} + +// aten::zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor +inline at::Tensor zeros_symint(c10::SymIntArrayRef size, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory) { + return at::_ops::zeros::call(size, dtype, layout, device, pin_memory); +} +namespace symint { + template >> + at::Tensor zeros(c10::SymIntArrayRef size, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory) { + return at::_ops::zeros::call(size, dtype, layout, device, pin_memory); + } +} + +// aten::zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size) { + return at::_ops::zeros_out::call(c10::fromIntArrayRefSlow(size), out); +} +namespace symint { + template >> + at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size) { + return at::_ops::zeros_out::call(c10::fromIntArrayRefSlow(size), out); + } +} + +// aten::zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zeros_outf(at::IntArrayRef size, at::Tensor & out) { + return at::_ops::zeros_out::call(c10::fromIntArrayRefSlow(size), out); +} +namespace symint { + template >> + at::Tensor & zeros_outf(at::IntArrayRef size, at::Tensor & out) { + return at::_ops::zeros_out::call(c10::fromIntArrayRefSlow(size), out); + } +} + +// aten::zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zeros_symint_out(at::Tensor & out, c10::SymIntArrayRef size) { + return at::_ops::zeros_out::call(size, out); +} +namespace symint { + template >> + at::Tensor & zeros_out(at::Tensor & out, c10::SymIntArrayRef size) { + return at::_ops::zeros_out::call(size, out); + } +} + +// aten::zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zeros_symint_outf(c10::SymIntArrayRef size, at::Tensor & out) { + return at::_ops::zeros_out::call(size, out); +} +namespace symint { + template >> + at::Tensor & zeros_outf(c10::SymIntArrayRef size, at::Tensor & out) { + return at::_ops::zeros_out::call(size, out); + } +} + +// aten::zeros.names_out(int[] size, *, Dimname[]? names, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size, ::std::optional names) { + return at::_ops::zeros_names_out::call(size, names, out); +} +// aten::zeros.names_out(int[] size, *, Dimname[]? names, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zeros_outf(at::IntArrayRef size, ::std::optional names, at::Tensor & out) { + return at::_ops::zeros_names_out::call(size, names, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..036bc155dbdfb17b8963682f73323c080bd37617 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_compositeexplicitautograd_dispatch.h @@ -0,0 +1,39 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor zeros(at::IntArrayRef size, ::std::optional names, at::TensorOptions options={}); +TORCH_API at::Tensor zeros(at::IntArrayRef size, ::std::optional names, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory); +TORCH_API at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size, ::std::optional names); +TORCH_API at::Tensor & zeros_outf(at::IntArrayRef size, ::std::optional names, at::Tensor & out); +TORCH_API at::Tensor zeros(at::IntArrayRef size, at::TensorOptions options={}); +TORCH_API at::Tensor zeros(at::IntArrayRef size, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory); +TORCH_API at::Tensor zeros_symint(c10::SymIntArrayRef size, at::TensorOptions options={}); +TORCH_API at::Tensor zeros_symint(c10::SymIntArrayRef size, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory); +TORCH_API at::Tensor & zeros_out(at::Tensor & out, at::IntArrayRef size); +TORCH_API at::Tensor & zeros_outf(at::IntArrayRef size, at::Tensor & out); +TORCH_API at::Tensor & zeros_symint_out(at::Tensor & out, c10::SymIntArrayRef size); +TORCH_API at::Tensor & zeros_symint_outf(c10::SymIntArrayRef size, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like.h new file mode 100644 index 0000000000000000000000000000000000000000..4329bee7d593f710bb4bce1a8e2858387ab682e0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like.h @@ -0,0 +1,49 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Function.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + +namespace at { + + +// aten::zeros_like(Tensor self, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor +inline at::Tensor zeros_like(const at::Tensor & self, at::TensorOptions options={}, ::std::optional memory_format=::std::nullopt) { + return at::_ops::zeros_like::call(self, c10::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)); +} +// aten::zeros_like(Tensor self, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor +inline at::Tensor zeros_like(const at::Tensor & self, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory, ::std::optional memory_format) { + return at::_ops::zeros_like::call(self, dtype, layout, device, pin_memory, memory_format); +} + +// aten::zeros_like.out(Tensor self, *, MemoryFormat? memory_format=None, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zeros_like_out(at::Tensor & out, const at::Tensor & self, ::std::optional memory_format=::std::nullopt) { + return at::_ops::zeros_like_out::call(self, memory_format, out); +} +// aten::zeros_like.out(Tensor self, *, MemoryFormat? memory_format=None, Tensor(a!) out) -> Tensor(a!) +inline at::Tensor & zeros_like_outf(const at::Tensor & self, ::std::optional memory_format, at::Tensor & out) { + return at::_ops::zeros_like_out::call(self, memory_format, out); +} + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_compositeexplicitautograd_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_compositeexplicitautograd_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..6eea28cb4c7b43d2260a71e204f5be7e719c49d9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_compositeexplicitautograd_dispatch.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeexplicitautograd { + +TORCH_API at::Tensor zeros_like(const at::Tensor & self, at::TensorOptions options={}, ::std::optional memory_format=::std::nullopt); +TORCH_API at::Tensor zeros_like(const at::Tensor & self, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory, ::std::optional memory_format); +TORCH_API at::Tensor & zeros_like_out(at::Tensor & out, const at::Tensor & self, ::std::optional memory_format=::std::nullopt); +TORCH_API at::Tensor & zeros_like_outf(const at::Tensor & self, ::std::optional memory_format, at::Tensor & out); + +} // namespace compositeexplicitautograd +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_compositeimplicitautogradnestedtensor_dispatch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_compositeimplicitautogradnestedtensor_dispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..a19709ee6e3fd4421f8914892c48832efc6c665a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_compositeimplicitautogradnestedtensor_dispatch.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// @generated by torchgen/gen.py from DispatchKeyFunction.h + +// NB: The implementing C++ file is RegisterDispatchKey.cpp + +// The only #includes we need are for custom classes that have defaults in the C++ API +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { + +namespace compositeimplicitautogradnestedtensor { + +TORCH_API at::Tensor zeros_like(const at::Tensor & self, at::TensorOptions options={}, ::std::optional memory_format=::std::nullopt); +TORCH_API at::Tensor zeros_like(const at::Tensor & self, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory, ::std::optional memory_format); + +} // namespace compositeimplicitautogradnestedtensor +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_native.h new file mode 100644 index 0000000000000000000000000000000000000000..2636829546dc5b3b208087a9113ad8f55d461035 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_native.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor zeros_like(const at::Tensor & self, ::std::optional dtype={}, ::std::optional layout={}, ::std::optional device={}, ::std::optional pin_memory={}, ::std::optional memory_format=::std::nullopt); +TORCH_API at::Tensor & zeros_like_out(const at::Tensor & self, ::std::optional memory_format, at::Tensor & out); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..71f0129cfdfb8f065caf76e8c640629eccbbd603 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_like_ops.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API zeros_like { + using schema = at::Tensor (const at::Tensor &, ::std::optional, ::std::optional, ::std::optional, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::zeros_like"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "zeros_like(Tensor self, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor"; + static at::Tensor call(const at::Tensor & self, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory, ::std::optional memory_format); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory, ::std::optional memory_format); +}; + +struct TORCH_API zeros_like_out { + using schema = at::Tensor & (const at::Tensor &, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::zeros_like"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "zeros_like.out(Tensor self, *, MemoryFormat? memory_format=None, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(const at::Tensor & self, ::std::optional memory_format, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, const at::Tensor & self, ::std::optional memory_format, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_native.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_native.h new file mode 100644 index 0000000000000000000000000000000000000000..c432f23fd43ce8dc9556dd4e6213709c3548aec4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_native.h @@ -0,0 +1,30 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from NativeFunction.h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace at { +namespace native { +TORCH_API at::Tensor zeros(at::IntArrayRef size, ::std::optional names, ::std::optional dtype={}, ::std::optional layout={}, ::std::optional device={}, ::std::optional pin_memory={}); +TORCH_API at::Tensor & zeros_names_out(at::IntArrayRef size, ::std::optional names, at::Tensor & out); +TORCH_API at::Tensor zeros_symint(c10::SymIntArrayRef size, ::std::optional dtype={}, ::std::optional layout={}, ::std::optional device={}, ::std::optional pin_memory={}); +TORCH_API at::Tensor & zeros_out(at::IntArrayRef size, at::Tensor & out); +TORCH_API at::Tensor & zeros_sparse_out(at::IntArrayRef size, at::Tensor & out); +} // namespace native +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_ops.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_ops.h new file mode 100644 index 0000000000000000000000000000000000000000..b470cd5774fe486a96e69309bdb1e1821ce78120 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/ops/zeros_ops.h @@ -0,0 +1,67 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// @generated by torchgen/gen.py from Operator.h + +#include +#include +#include + +// Forward declarations of any types needed in the operator signatures. +// We can't directly include these classes because it will cause circular include dependencies. +// This file is included by TensorBody.h, which defines the Tensor class. +#include + +namespace at { +namespace _ops { + + +struct TORCH_API zeros_names { + using schema = at::Tensor (at::IntArrayRef, ::std::optional, ::std::optional, ::std::optional, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::zeros"; + static constexpr const char* overload_name = "names"; + static constexpr const char* schema_str = "zeros.names(int[] size, *, Dimname[]? names, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor"; + static at::Tensor call(at::IntArrayRef size, ::std::optional names, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, at::IntArrayRef size, ::std::optional names, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory); +}; + +struct TORCH_API zeros { + using schema = at::Tensor (c10::SymIntArrayRef, ::std::optional, ::std::optional, ::std::optional, ::std::optional); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::zeros"; + static constexpr const char* overload_name = ""; + static constexpr const char* schema_str = "zeros(SymInt[] size, *, ScalarType? dtype=None, Layout? layout=None, Device? device=None, bool? pin_memory=None) -> Tensor"; + static at::Tensor call(c10::SymIntArrayRef size, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory); + static at::Tensor redispatch(c10::DispatchKeySet dispatchKeySet, c10::SymIntArrayRef size, ::std::optional dtype, ::std::optional layout, ::std::optional device, ::std::optional pin_memory); +}; + +struct TORCH_API zeros_out { + using schema = at::Tensor & (c10::SymIntArrayRef, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::zeros"; + static constexpr const char* overload_name = "out"; + static constexpr const char* schema_str = "zeros.out(SymInt[] size, *, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(c10::SymIntArrayRef size, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, c10::SymIntArrayRef size, at::Tensor & out); +}; + +struct TORCH_API zeros_names_out { + using schema = at::Tensor & (at::IntArrayRef, ::std::optional, at::Tensor &); + using ptr_schema = schema*; + // See Note [static constexpr char* members for windows NVCC] + static constexpr const char* name = "aten::zeros"; + static constexpr const char* overload_name = "names_out"; + static constexpr const char* schema_str = "zeros.names_out(int[] size, *, Dimname[]? names, Tensor(a!) out) -> Tensor(a!)"; + static at::Tensor & call(at::IntArrayRef size, ::std::optional names, at::Tensor & out); + static at::Tensor & redispatch(c10::DispatchKeySet dispatchKeySet, at::IntArrayRef size, ::std::optional names, at::Tensor & out); +}; + +}} // namespace at::_ops + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/quantized/QTensorImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/quantized/QTensorImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..036c73e6760f565f0d58dbe1b76f9e339e4a5a64 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/quantized/QTensorImpl.h @@ -0,0 +1,130 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace at { + +/** + * QTensorImpl is a TensorImpl for Quantized Tensors, it stores Quantizer which + * specifies the quantization scheme and parameters, for more information please + * see ATen/quantized/Quantizer.h + * + * We'll use QTensor in code or documentation to refer to a Tensor with QTensorImpl. + */ +struct TORCH_API QTensorImpl : public c10::TensorImpl { + public: + QTensorImpl( + Storage&& storage, + DispatchKeySet key_set, + const caffe2::TypeMeta data_type, + QuantizerPtr quantizer); + + // See Note [Enum ImplType] + QTensorImpl( + ImplType type, + Storage&& storage, + DispatchKeySet key_set, + const caffe2::TypeMeta data_type, + QuantizerPtr quantizer); + + + // TODO: Expose in PyTorch Frontend + QuantizerPtr quantizer() { + return quantizer_; + } + + void set_quantizer_(QuantizerPtr quantizer) { + quantizer_ = quantizer; + } + + /** + * Return a TensorImpl that is a shallow-copy of this TensorImpl. + * + * For usage of `version_counter` and `allow_tensor_metadata_change`, + * see NOTE [ TensorImpl Shallow-Copying ]. + */ + c10::intrusive_ptr shallow_copy_and_detach( + const c10::VariableVersion& version_counter, + bool allow_tensor_metadata_change) const override { + auto impl = c10::make_intrusive( + Storage(storage()), key_set(), data_type_, quantizer_); + copy_tensor_metadata( + /*src_q_impl=*/this, + /*dest_q_impl=*/impl.get(), + /*version_counter=*/version_counter, + /*allow_tensor_metadata_change=*/allow_tensor_metadata_change); + impl->refresh_numel(); + impl->refresh_contiguous(); + return impl; + } + + /** + * Return a TensorImpl that is a shallow-copy of this TensorImpl. + * + * For usage of `version_counter` and `allow_tensor_metadata_change`, + * see NOTE [ TensorImpl Shallow-Copying ]. + */ + c10::intrusive_ptr shallow_copy_and_detach( + c10::VariableVersion&& version_counter, + bool allow_tensor_metadata_change) const override { + auto impl = c10::make_intrusive( + Storage(storage()), key_set(), data_type_, quantizer_); + copy_tensor_metadata( + /*src_q_impl=*/this, + /*dest_q_impl=*/impl.get(), + /*version_counter=*/std::move(version_counter), + /*allow_tensor_metadata_change=*/allow_tensor_metadata_change); + impl->refresh_numel(); + impl->refresh_contiguous(); + return impl; + } + + /** + * Shallow-copies data from another TensorImpl into this TensorImpl. + * + * For why this function doesn't check this TensorImpl's `allow_tensor_metadata_change_`, + * see NOTE [ TensorImpl Shallow-Copying ]. + */ + void shallow_copy_from(const c10::intrusive_ptr& impl) override { + AT_ASSERT(has_compatible_shallow_copy_type(impl->key_set())); + auto q_impl = static_cast(impl.get()); + copy_tensor_metadata( + /*src_q_impl=*/q_impl, + /*dest_q_impl=*/this, + /*version_counter=*/version_counter(), + /*allow_tensor_metadata_change=*/allow_tensor_metadata_change()); + refresh_numel(); + refresh_contiguous(); + } + + private: + QuantizerPtr quantizer_; + + const char* tensorimpl_type_name() const override; + + /** + * Copy the tensor metadata fields (e.g. sizes / strides / storage pointer / storage_offset) + * from one TensorImpl to another TensorImpl. + * + * For usage of `version_counter` and `allow_tensor_metadata_change`, see NOTE [ TensorImpl Shallow-Copying ]. + */ + static void copy_tensor_metadata( + const QTensorImpl* src_q_impl, + QTensorImpl* dest_q_impl, + const c10::VariableVersion& version_counter, + bool allow_tensor_metadata_change) { + TensorImpl::copy_tensor_metadata(src_q_impl, dest_q_impl, version_counter, allow_tensor_metadata_change); + + // OpaqueTensorImpl-specific fields. + dest_q_impl->quantizer_ = src_q_impl->quantizer_; + } +}; + +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/quantized/Quantizer.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/quantized/Quantizer.h new file mode 100644 index 0000000000000000000000000000000000000000..787f69064348d095ec856205b15a69172194c44b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/quantized/Quantizer.h @@ -0,0 +1,284 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +namespace at { + +/** + * UnknownQuantizer is a placeholder quantizer for functions that implement + * quantization in a two step process. First a tensor is allocated but with + * unknown quantizer, and then the quantization kernel decides what the final + * quantizer will be. + */ +struct TORCH_API UnknownQuantizer : public Quantizer { + explicit UnknownQuantizer(ScalarType scalar_type) + : Quantizer(scalar_type) {} + + Tensor quantize(const Tensor& tensor) override; + Tensor dequantize(const Tensor& qtensor) override; + Tensor& dequantize_out(Tensor& rtensor, const Tensor& qtensor) override; + QScheme qscheme() const override; + bool equalTo(QuantizerPtr other) const override; +}; + +/** + * UniformQuantizer is the parent class for all uniform quantizers. + * These quantization scheme will map float value uniformly to + * the quantized value. For example, affine quantizer is + * the most commonly used scheme in this category. + */ +struct TORCH_API UniformQuantizer : public Quantizer { + explicit UniformQuantizer(ScalarType scalar_type) : Quantizer(scalar_type) {} +}; + +/** + * NonUniformQuantizer is the parent class for all non-uniform quantizers. + * These quantization scheme may map float value non-uniformly to the quantized + * value. K-means quantization is a representative example in this category. + */ +struct TORCH_API NonUniformQuantizer : public Quantizer { + explicit NonUniformQuantizer(ScalarType scalar_type) : Quantizer(scalar_type) {} +}; + +// There is also StochasticQuantizer which is uniform but not affine + +/** + * AffineQuantizer uses affine transformation to do quantization. + * + * For quantize: + * Y = clamp(round(X / scale + zero_point), min, max) + * For dequantize: + * X = (Y - zero_point) * scale + */ +struct TORCH_API AffineQuantizer : public UniformQuantizer { + explicit AffineQuantizer(ScalarType scalar_type) : UniformQuantizer(scalar_type) {} +}; + +// Note that we will not have Symmetric Quantizer in backend to reduce +// complications in quantized kernel implementation. + +/** + * PerTensorAffineQuantizer stores a scale and a zero_point, which is used for + * all the values in the Tensor. + */ +struct TORCH_API PerTensorAffineQuantizer : public AffineQuantizer { + explicit PerTensorAffineQuantizer(ScalarType scalar_type, double scale, int64_t zero_point) + : AffineQuantizer(scalar_type), + scale_(scale), + zero_point_(zero_point) {} + + Tensor quantize(const Tensor& tensor) override; + Tensor dequantize(const Tensor& qtensor) override; + Tensor& dequantize_out(Tensor& rtensor, const Tensor& qtensor) override; + + QScheme qscheme() const override { + return kPerTensorAffine; + } + + double scale() const { + return scale_; + } + + int64_t zero_point() const { + return zero_point_; + } + + bool equalTo(QuantizerPtr other) const override { + if (!other.get() || other->qscheme() != kPerTensorAffine) { + return false; + } + auto* other_per_tensor_affine = + static_cast(other.get()); + return scalar_type() == other_per_tensor_affine->scalar_type() && + scale() == other_per_tensor_affine->scale() && + zero_point() == other_per_tensor_affine->zero_point(); + } + + private: + const double scale_; + // We use int64_t for consistency with Python + const int64_t zero_point_; +}; + +/** + * PerChannelAffineQuantizer is the same as PerTensorAffineQuantizer + * except that we have an independent scale and zero_point parameter + * for each channel. + * + * Also note that per channel quantization is mostly applied to output channels + * of weights since per-input channel of weight quantization or per-channel + * quantization for activations can't be efficiently supported in most of + * processors since it requires each multiplication result within a single + * dot-product to have a different scale. + */ +struct TORCH_API PerChannelAffineQuantizer : public AffineQuantizer { + explicit PerChannelAffineQuantizer( + ScalarType scalar_type, + Tensor scales, + Tensor zero_points, + int64_t axis) + : AffineQuantizer(scalar_type), + scales_(std::move(scales)), + zero_points_(std::move(zero_points)), + axis_(axis) {} + + QScheme qscheme() const override { + return kPerChannelAffine; + } + + Tensor scales() const { + return scales_; + } + + Tensor zero_points() const { + return zero_points_; + } + + int64_t axis() const { + return axis_; + } + + Tensor quantize(const Tensor& tensor) override; + Tensor dequantize(const Tensor& qtensor) override; + Tensor& dequantize_out(Tensor& rtensor, const Tensor& qtensor) override; + + bool equalTo(QuantizerPtr other) const override { + if (!other.get() || other->qscheme() != kPerChannelAffine) { + return false; + } + auto* other_per_channel_affine = + static_cast(other.get()); + return scalar_type() == other_per_channel_affine->scalar_type() && + scales().equal(other_per_channel_affine->scales()) && + zero_points().equal(other_per_channel_affine->zero_points()) && + axis() == other_per_channel_affine->axis(); + } + + protected: + Tensor scales_; + Tensor zero_points_; + const int64_t axis_; +}; + +/** + * PerChannelAffineFloatQParamsQuantizer is the same as PerChannelAffineQuantizer + * except that it expects both scale and zero point to be floating point values. + * + * This quantizer uses the kPerChannelAffineFloatQParams qscheme which is a variant of + * kPerChannelAffine. + * + * The quantize equation in this case looks like - + * Xq = (Xf - zero_point) * inv_scale, where inv_scale = 1.0/scale + * + * Note: Usage of floating point zero point is useful in cases where 0 doesn't need to + * be exactly represented in the quantized space. We can get additional precision by + * using floating point values for zero point. + */ +struct TORCH_API PerChannelAffineFloatQParamsQuantizer : public PerChannelAffineQuantizer { + explicit PerChannelAffineFloatQParamsQuantizer( + ScalarType scalar_type, + Tensor scales, + Tensor zero_points, + int64_t axis) + : PerChannelAffineQuantizer(scalar_type, + scales, + zero_points, + axis) {} + + QScheme qscheme() const override { + return kPerChannelAffineFloatQParams; + } + + Tensor quantize(const Tensor& tensor) override; + Tensor dequantize(const Tensor& qtensor) override; + Tensor& dequantize_out(Tensor& rtensor, const Tensor& qtensor) override; + + bool equalTo(QuantizerPtr other) const override { + if (!other.get() || other->qscheme() != kPerChannelAffineFloatQParams) { + return false; + } + auto* other_per_channel_float_qparams = + static_cast(other.get()); + return scalar_type() == other_per_channel_float_qparams->scalar_type() && + scales().equal(other_per_channel_float_qparams->scales()) && + zero_points().equal(other_per_channel_float_qparams->zero_points()) && + axis() == other_per_channel_float_qparams->axis(); + } +}; + +// This is an internal utility function for getting at the QTensorImpl, +// You should only use this for writing low level +// setters/getters for QTensorImpl fields; otherwise, you should use +// the low level setters/getters that were implemented using this. +// This may be called repeatedly, so make sure it's pretty cheap. +TORCH_API QTensorImpl* get_qtensorimpl(const TensorBase& self); + +// double and int64_t are because of the native function API, we only have these +// argument types right now in native functions +TORCH_API QuantizerPtr +make_per_tensor_affine_quantizer( + double scale, int64_t zero_point, ScalarType scalar_type); + +TORCH_API QuantizerPtr make_per_channel_affine_quantizer( + const Tensor& scales, + const Tensor& zero_points, + int64_t axis, + ScalarType scalar_type); + +TORCH_API QuantizerPtr make_unknown_quantizer(ScalarType scalar_type); + +// Create a Quantized Tensor given arguments for normal Tensor and a quantizer +TORCH_API Tensor new_qtensor( + IntArrayRef sizes, + const TensorOptions& options, + QuantizerPtr quantizer); + +TORCH_API void set_quantizer_(const Tensor& self, ConstQuantizerPtr quantizer); + +TORCH_API Tensor from_blob_quantized_per_tensor_affine( + void* data, + IntArrayRef sizes, + IntArrayRef strides, + std::function deleter, + const float scale, + const int64_t zeroPoint, + const TensorOptions& options); + +TORCH_API Tensor from_blob_quantized_per_tensor_affine( + void* data, + IntArrayRef sizes, + std::function deleter, + const float scale, + const int64_t zeroPoint, + const TensorOptions& options); + +TORCH_API Tensor from_blob_quantized_per_channel_affine( + void* data, + IntArrayRef sizes, + std::function deleter, + const Tensor& scales, + const Tensor& zero_points, + const int64_t axis, + const TensorOptions& options); + +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/record_function.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/record_function.h new file mode 100644 index 0000000000000000000000000000000000000000..8d006547bd7f54ab3f935499404cf9e5a0d58216 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/record_function.h @@ -0,0 +1,799 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace c10 { +class TORCH_API OperatorHandle; +} + +namespace at { + +// Function name to record NCCL metadata +extern TORCH_API const std::string kParamCommsCallName; + +// Kind of record function scope; +enum class C10_API_ENUM RecordScope : uint8_t { + // c10/ATen ops, autograd nodes + FUNCTION = 0, + // Functions/nodes called from the autograd + BACKWARD_FUNCTION, + // TorchScript functions, methods + TORCHSCRIPT_FUNCTION, + // Kernel Function dtype Tag + KERNEL_FUNCTION_DTYPE, + // Torchbind custom class, + CUSTOM_CLASS, + // Generic Build Feature + BUILD_FEATURE, + // Kernel Function dtype Tag + LITE_INTERPRETER, + // User defined scope (e.g. with record_function()) + USER_SCOPE, + // Scopes for static runtime, a specialized TorchScript interpreter + STATIC_RUNTIME_OP, + STATIC_RUNTIME_MODEL, + NUM_SCOPES, // must be the last in the list +}; + +} // namespace at + +namespace std { +template <> +struct hash { + size_t operator()(const at::RecordScope& sc) const noexcept { + return static_cast(sc); + } +}; +} // namespace std + +namespace at { + +struct TORCH_API StringView { + StringView() : StringView(nullptr) {} + explicit StringView(const char* str_ptr) + : owned_str_ptr_(nullptr), str_ptr_(str_ptr) {} + explicit StringView(std::string str) + : owned_str_ptr_(std::make_shared(std::move(str))), + str_ptr_(owned_str_ptr_->c_str()) {} + + const char* str() const { + return str_ptr_; + } + + friend std::ostream& operator<<(std::ostream& os, const StringView& dt) { + os << dt.str(); + return os; + } + + friend bool operator==(const StringView& lhs, const StringView& rhs) { + return strcmp(lhs.str(), rhs.str()) == 0; + } + + friend bool operator!=(const StringView& lhs, const StringView& rhs) { + return !(lhs == rhs); + } + + private: + std::shared_ptr owned_str_ptr_; + const char* str_ptr_; +}; + +// Soft limit on the number of callbacks to use; +constexpr std::size_t kSoftLimitCallbacks = 4; + +// An abstract base class for various observer contexts that can be attached to +// the RecordFunction. +struct ObserverContext { + virtual ~ObserverContext() = default; + + protected: + ObserverContext() = default; +}; + +typedef c10::SmallVector CallbackHandles; +typedef c10::SmallVector, kSoftLimitCallbacks> + ObserverContextList; +typedef uint64_t RecordFunctionHandle; +struct RecordFunction; + +// +// PyTorch callbacks/observers API: +// + +/** + * RecordFunctionCallback represents a pair of callbacks to be used with + * RecordFunction, members: + * start, end - the callbacks to run when entering and exiting the scope; + * optionally, the start callback may return an ObserverContext which will + * be passed to the end callback, use appropriate constructor accordingly. + * needs_inputs - whether the callbacks need the inputs passed from the + * observed function/range; NOTE: passing the inputs incurs an additional + * overhead; sampling_probability - if not 1.0, then the callback is + * probabilistically sampled to run; NOTE: start and end callbacks always run as + * a pair and are sampled together; scopes - types of scopes to execute the + * callbacks on (see RecordScope); passing empty set means the callbacks will be + * executed for all possible scope types should_run - optional function that + * returns whether this callback should run; overwrites the effect of setting + * sampling_probability + */ +class TORCH_API RecordFunctionCallback { + public: + using StartCallback = + std::unique_ptr (*)(const RecordFunction&); + using EndCallback = void (*)(const RecordFunction&, ObserverContext*); + + // This interface supports observers that require passing an ObserverContext + // between start and end callbacks. + explicit RecordFunctionCallback( + StartCallback start, + EndCallback end = nullptr) + : start_(start), end_(end) { + scopes_.fill(true); + } + + RecordFunctionCallback& needsInputs(bool needs_inputs) { + needs_inputs_ = needs_inputs; + return *this; + } + + RecordFunctionCallback& needsOutputs(bool needs_outputs) { + needs_outputs_ = needs_outputs; + return *this; + } + + RecordFunctionCallback& needsIds(bool needs_ids) { + needs_ids_ = needs_ids; + return *this; + } + + RecordFunctionCallback& samplingProb(double sampling_prob) { + TORCH_CHECK( + sampling_prob >= 0.0 && sampling_prob <= 1.0, + "Invalid sampling probability"); + sampling_prob_ = sampling_prob; + return *this; + } + + RecordFunctionCallback& scopes( + const std::unordered_set>& scopes) { + if (!scopes.empty()) { + scopes_.fill(false); + for (auto sc : scopes) { + scopes_[static_cast(sc)] = true; + } + } else { + scopes_.fill(true); + } + return *this; + } + + bool needsInputs() const { + return needs_inputs_; + } + + bool needsOutputs() const { + return needs_outputs_; + } + + bool needsIds() const { + return needs_ids_; + } + + double samplingProb() const { + return sampling_prob_; + } + + bool checkScope(RecordScope sc) const { + return scopes_[(size_t)sc]; + } + + StartCallback start() const { + return start_; + } + + EndCallback end() const { + return end_; + } + + private: + StartCallback start_; + EndCallback end_; + double sampling_prob_ = 1.0; + std::array(RecordScope::NUM_SCOPES)> scopes_ = {}; + bool needs_inputs_ = false; + bool needs_outputs_ = false; + bool needs_ids_ = false; +}; + +// Notes: +// - two types of callbacks are provided: thread local and global +// - thread local callbacks are added/removed only for the given thread +// and are stored locally for each thread and separately from the list +// of the global callbacks +// - global callbacks are stored in a single per process list and are +// invoked by every RecordFunction, in addition to the thread local +// callbacks specific to the given thread +// - we allow the added callbacks to be sampled, by specifying a sampling +// probability for each callback pair, if the start callback is +// not picked to run, the corresponding end callback won't be called +// - a typical use case for the global callbacks is passive monitoring +// in the background (e.g. fleet-wide monitoring), without focusing on +// the specific piece of code +// - in contrast, thread local callbacks are enabled locally, on demand, +// for the specific piece of code (range) and are not sampled +// - a typical use case for thread local callbacks is profiler and code +// execution tracer +// - note, thread local callbacks are automatically propagated with +// ThreadLocalState across JIT continuations and async tasks (at::launch) + +typedef uint64_t CallbackHandle; + +constexpr CallbackHandle INVALID_CALLBACK_HANDLE{0}; + +// It is unnecessary to use atomic operations for enabling +// thread-local function callbacks. Moreover, it prevents saving to +// ThreadLocalState because std::atomic is non-copyable. +struct RecordFunctionCallbacksEntry { + RecordFunctionCallbacksEntry(RecordFunctionCallback cb, CallbackHandle h) + : callback_(cb), handle_(h) {} + + RecordFunctionCallback callback_; + bool enabled_{true}; + CallbackHandle handle_; +}; + +// Holds pairs (callbacks, unique_id) +using RecordFunctionCallbacks = std::vector; + +// Generated by the callback managers to determine which functions to run. +struct StepCallbacks { + StepCallbacks() = default; + StepCallbacks(uint64_t thread_id, RecordScope scope) + : thread_id_{thread_id}, scope_{scope} {} + + bool empty() const { + return callbacks_.empty(); + } + + struct StartEndPair { + RecordFunctionCallback::StartCallback start_; + RecordFunctionCallback::EndCallback end_; + }; + + using StartEndPairs = c10::SmallVector; + + StartEndPairs callbacks_; + uint64_t thread_id_{0}; + RecordScope scope_{RecordScope::FUNCTION}; + bool needs_inputs_{false}; + bool needs_outputs_{false}; + bool needs_ids_{false}; +}; + +struct TORCH_API RecordFunction { + // Default constructor is used with before function called afterwards: + // scope - record scope that this function tracks + // pre_sampled - whether this RecordFunction was already pre-sampled with + // kLowProb probability + explicit RecordFunction(RecordScope scope = RecordScope::FUNCTION); + explicit RecordFunction(StepCallbacks&& step_callbacks); + + using schema_ref_t = std::reference_wrapper; + using FunctionDescriptor = std::variant; + + void before( + FunctionDescriptor fn, + c10::ArrayRef args, + int64_t current_sequence_nr = -1) { + if (!isActive()) { + return; + } + inputs_ = args; + before(fn, current_sequence_nr); + } + + void before( + FunctionDescriptor fn, + c10::ArrayRef args, + const std::unordered_map* kwargs, + int64_t current_sequence_nr = -1) { + if (!isActive()) { + return; + } + kwinputs_ = *kwargs; + before(fn, args, current_sequence_nr); + } + + void before( + FunctionDescriptor fn, + const std::unordered_map* kwargs, + int64_t current_sequence_nr = -1) { + if (!isActive()) { + return; + } + kwinputs_ = *kwargs; + before(fn, current_sequence_nr); + } + + void before( + FunctionDescriptor fn, + const std::vector* args, + int64_t current_sequence_nr = -1) { + before( + fn, + c10::ArrayRef(args->data(), args->size()), + current_sequence_nr); + } + + void before( + FunctionDescriptor fn, + const std::vector* args, + const std::unordered_map* kwargs, + int64_t current_sequence_nr = -1) { + if (!isActive()) { + return; + } + kwinputs_ = *kwargs; + before(std::move(fn), args, current_sequence_nr); + } + + // Destructor calls end callbacks + virtual ~RecordFunction(); + + RecordFunction(const RecordFunction&) = delete; + RecordFunction& operator=(const RecordFunction&) = delete; + RecordFunction(RecordFunction&&) = delete; + RecordFunction& operator=(RecordFunction&&) = delete; + + const char* name() const; + const char* overload_name() const; + + int64_t seqNr() const { + return sequence_nr_; + } + + c10::ArrayRef inputs() const { +#ifndef NDEBUG + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + inputs_valid_, "Called inputs() outside RecordFunction start callback"); +#endif + return inputs_; + } + + std::unordered_map kwinputs() const { +#ifndef NDEBUG + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + inputs_valid_, + "Called kwinputs() outside RecordFunction start callback"); +#endif + return kwinputs_; + } + + const std::vector& outputs() const { + return outputs_; + } + + void setOutputs(std::vector&& outputs) { + outputs_ = std::move(outputs); + } + + void setOutputs(c10::ArrayRef outputs) { + outputs_ = outputs.vec(); + } + + size_t num_inputs() const; + size_t num_outputs() const; + + // Retrieves the thread_id that this RecordFunction ran start callbacks with. + // Useful for writing thread safe end callbacks that may be potentially + // executed in a different thread (async ops) + uint64_t threadId() const { + return step_callbacks_.thread_id_; + } + + // For backward functions - thread id of the corresponding forward function, + // or zero otherwise; + // used alongside with sequence number to correlate backward functions with + // the forward ones + uint64_t forwardThreadId() const { + return fwd_thread_id_; + } + + void setForwardThreadId(uint64_t thread_id) { + fwd_thread_id_ = thread_id; + } + + RecordScope scope() const { + return step_callbacks_.scope_; + } + + // Returns logical thread_id for the current thread + static uint64_t currentThreadId(); + + // Internal functions, do not use directly; + // used in python's context manager + + // before functions initialize RecordFunction members and call + // start callbacks + void before(FunctionDescriptor schema, int64_t sequence_nr = -1); + + // Sets node ID for distributed profiling + static void setDefaultNodeId(int64_t defaultNodeId); + // Gets node ID for distributed profiling + static int64_t getDefaultNodeId(); + + // Calls end callbacks. After end(), accessors will no longer provide useful + // results. + void end(); + + // Internal-only, used only force async event for distributed events + // profiling. + void _setAsync(); + + // Returns whether this RecordFunction corresponds to an async event or not. + bool isAsync() const; + + // Returns whether this RecordFunction corresponds to NCCL metadata collection + // or not. + bool isNcclMeta() const { + return is_nccl_meta_; + } + + // Internal-only, used to denote out variant used for Static Runtime execution + void _setStaticRuntimeOutVariant(); + bool isStaticRuntimeOutVariant() const; + + RecordFunctionHandle handle() const { + return handle_; + } + + std::optional operator_name() const; + + // This method returns a copy of the FunctionSchema and can be expensive. + std::optional operator_schema() const; + + void setHandle(RecordFunctionHandle handle) { + handle_ = handle; + } + + // Whether this RecordFunction runs any callbacks. + bool isActive() const { + return !step_callbacks_.empty(); + } + + bool needsInputs() const { + return step_callbacks_.needs_inputs_; + } + + bool needsOutputs() const { + return step_callbacks_.needs_outputs_; + } + + int64_t debugHandle() const { + return debug_handle_; + } + + void setDebugHandle(int64_t debug_handle) { + debug_handle_ = debug_handle; + } + + void invalidateInputs() { +#ifndef NDEBUG + inputs_valid_ = false; +#endif + } + + private: + void runStartCallbacks(); + + StepCallbacks step_callbacks_; + + // In cases when RecordFunction might be active but we chose not to + // use the observers (e.g. operator is not observed), this boolean + // flag is used to check whether the start callbacks were called + bool called_start_callbacks_ = false; + +#ifndef NDEBUG + bool inputs_valid_ = false; +#endif + + // Stores various ObserverContext objects with event metadata for callbacks. + ObserverContextList ctx_; + + std::variant fn_; + + int64_t sequence_nr_ = -1; + c10::ArrayRef inputs_; + std::unordered_map kwinputs_; + std::vector outputs_; + + // For backward functions - thread id of the forward function + uint64_t fwd_thread_id_ = 0; + + // Unique id for this RecordFunction, used in callbacks to track start + // and end of ranges + RecordFunctionHandle handle_{0}; + + // Whether this record_function corresponds to an async event or not. Async + // events can complete in different threads or follow a future-like pattern + // of use. + bool is_async_{false}; + + // Debug handles are used for lazy annotation of module hierarchy + // and callstack. + // This is specifically is useful for mobile runtime, where generated + // debug handles can be lazily symbolicated using debug information + int64_t debug_handle_{-1}; + + // Whether this RecordFunction is used for an out variant run with + // Static Runtime + bool is_static_runtime_out_variant_{false}; + + // Whether this RecordFunction is used for NCCL metadata collection + bool is_nccl_meta_{false}; +}; + +TORCH_API StepCallbacks getStepCallbacks(RecordScope scope); + +TORCH_API std::optional getStepCallbacksUnlessEmpty( + RecordScope scope); + +namespace detail { +template +void record_function_with_scope( + RecordFunction& guard, + RecordFunction::FunctionDescriptor fn, + const Inputs& inputs, + Args&&... args) { + if (guard.needsInputs()) { + guard.before( + fn, + c10::ArrayRef(inputs.data(), inputs.size()), + std::forward(args)...); + } else { + guard.before(fn, std::forward(args)...); + } +} + +template +void record_function_with_scope_and_debug_handle( + RecordFunction& guard, + RecordFunction::FunctionDescriptor fn, + int64_t debug_handle, + const Inputs& inputs, + Args&&... args) { + guard.setDebugHandle(debug_handle); + if (guard.needsInputs()) { + guard.before( + fn, + c10::ArrayRef(inputs.data(), inputs.size()), + std::forward(args)...); + } else { + guard.before(fn, std::forward(args)...); + } +} + +template +void record_function_with_scope( + RecordFunction& guard, + RecordFunction::FunctionDescriptor fn, + c10::ArrayRef inputs, + Args&&... args) { + return record_function_with_scope, Args...>( + guard, fn, inputs, std::forward(args)...); +} + +template +void record_function_with_scope_and_debug_handle( + RecordFunction& guard, + RecordFunction::FunctionDescriptor fn, + int64_t debug_handle, + c10::ArrayRef inputs, + Args&&... args) { + return record_function_with_scope_and_debug_handle< + c10::ArrayRef, + Args...>(guard, fn, debug_handle, inputs, std::forward(args)...); +} + +} // namespace detail + +// optional argument - function's seq_no +#define RECORD_FUNCTION_WITH_SCOPE(scope, fn, inputs, ...) \ + at::RecordFunction guard(scope); \ + if (guard.isActive()) { \ + ::at::detail::record_function_with_scope( \ + guard, fn, inputs, ##__VA_ARGS__); \ + } + +#define RECORD_FUNCTION_WITH_SCOPE_INPUTS_OUTPUTS( \ + scope, fn, inputs, outputs, ...) \ + at::RecordFunction guard(scope); \ + if (guard.isActive()) { \ + if (guard.needsInputs()) { \ + guard.before(fn, inputs, ##__VA_ARGS__); \ + } else { \ + guard.before(fn, ##__VA_ARGS__); \ + } \ + if (guard.needsOutputs()) { \ + guard.setOutputs(outputs); \ + } \ + } + +#define RECORD_FUNCTION(fn, inputs, ...) \ + RECORD_FUNCTION_WITH_SCOPE( \ + at::RecordScope::FUNCTION, fn, inputs, ##__VA_ARGS__) + +#define RECORD_TORCHSCRIPT_FUNCTION(mn, inputs) \ + RECORD_FUNCTION_WITH_SCOPE(at::RecordScope::TORCHSCRIPT_FUNCTION, mn, inputs) + +#define RECORD_FUNCTION_WITH_INPUTS_OUTPUTS(fn, inputs, outputs, ...) \ + RECORD_FUNCTION_WITH_SCOPE_INPUTS_OUTPUTS( \ + at::RecordScope::FUNCTION, fn, inputs, outputs, ##__VA_ARGS__) + +// Custom user scopes in C++; similar to Python's 'with record_function("..."):' +#define RECORD_USER_SCOPE(fn) \ + RECORD_FUNCTION_WITH_SCOPE( \ + at::RecordScope::USER_SCOPE, fn, c10::ArrayRef{}) + +// RECORD_USER_SCOPE with inputs +#define RECORD_USER_SCOPE_WITH_INPUTS(fn, inputs) \ + RECORD_FUNCTION_WITH_SCOPE(at::RecordScope::USER_SCOPE, fn, inputs) + +#define RECORD_USER_SCOPE_WITH_KWARGS_ONLY(fn, kwargs) \ + RECORD_FUNCTION_WITH_SCOPE( \ + at::RecordScope::USER_SCOPE, \ + fn, \ + c10::ArrayRef{}, \ + kwargs) + +// Helper macro to pass in debug handle that is used to +// post process events +#define RECORD_WITH_SCOPE_DEBUG_HANDLE_AND_INPUTS( \ + scope, fn, debug_handle, inputs, ...) \ + at::RecordFunction guard(scope); \ + if (guard.isActive()) { \ + ::at::detail::record_function_with_scope_and_debug_handle( \ + guard, fn, debug_handle, inputs, ##__VA_ARGS__); \ + } + +// Helper macros to record LITE INTERPRETER scope events with debug handles +#define RECORD_EDGE_SCOPE_WITH_DEBUG_HANDLE_AND_INPUTS( \ + fn, debug_handle, inputs) \ + RECORD_WITH_SCOPE_DEBUG_HANDLE_AND_INPUTS( \ + at::RecordScope::LITE_INTERPRETER, fn, debug_handle, inputs) + +// Bookend to the RECORD_FUNCTION macros. Use this after the kernel +// launch to let the profiler bind the outputs to the op that produced +// them. Note that guard is declared by RECORD_FUNCTION so this macro +// needs to be called from the same scope as RECORD_FUNCTION +#define RECORD_OUTPUTS(outputs) \ + if (guard.needsOutputs()) { \ + guard.setOutputs( \ + std::vector(outputs.begin(), outputs.end())); \ + } + +/** + * addThreadLocalCallback adds a thread local callback to run with + * RecordFunction, returns handle to use with removeThreadLocalCallback + */ +TORCH_API CallbackHandle addThreadLocalCallback(RecordFunctionCallback cb); + +/** + * hasThreadLocalCallbacks returns whether there're callbacks registered + * with addThreadLocalCallback + */ +TORCH_API bool hasThreadLocalCallbacks(); + +/** + * clearThreadLocalCallbacks removes all thread local callbacks + */ +TORCH_API void clearThreadLocalCallbacks(); + +/** + * addGlobalCallback adds a global callback to run with RecordFunction: + * + * only during the program initialization + */ +TORCH_API CallbackHandle addGlobalCallback(RecordFunctionCallback cb); + +/** + * removeCallback removes a callback given the handle returned by + * addThreadLocalCallback or addGlobalCallback; + * + * no other code can run simultaneously + */ +TORCH_API void removeCallback(CallbackHandle handle); + +/** + * Prevent the given callback from executing. If handle is invalid, + * does nothing. + */ +TORCH_API void disableCallback(CallbackHandle handle); + +/** + * Allow the given callback, previously disabled with disableCallback, to + * execute again. If handle is invalid, does nothing. + */ +TORCH_API void reenableCallback(CallbackHandle handle); + +/** + * hasGlobalCallbacks returns whether there're global callbacks + * registered with pushGlobalCallback + */ +TORCH_API bool hasGlobalCallbacks(); + +/** + * clearGlobalCallbacks removes all global callbacks + */ +TORCH_API void clearGlobalCallbacks(); + +// for both thread local and global callbacks +TORCH_API bool hasCallbacks(); +TORCH_API void clearCallbacks(); + +/** + * enableRecordFunction enables RecordFunction thread locally + */ +TORCH_API void enableRecordFunction(bool enable = true); + +/** + * isRecordFunctionEnabled returns whether RecordFunction + * is enabled thread locally + */ +TORCH_API bool isRecordFunctionEnabled(); + +class TORCH_API RecordFunctionGuard { + public: + explicit RecordFunctionGuard(bool is_enabled = true) + : prev_value_(isRecordFunctionEnabled()) { + enableRecordFunction(is_enabled); + } + + RecordFunctionGuard(RecordFunctionGuard&& other) = delete; + RecordFunctionGuard(const RecordFunctionGuard&) = delete; + RecordFunctionGuard& operator=(const RecordFunctionGuard&) = delete; + RecordFunctionGuard& operator=(RecordFunctionGuard&&) = delete; + virtual ~RecordFunctionGuard() { + enableRecordFunction(prev_value_); + } + + private: + bool prev_value_ = false; +}; + +class TORCH_API DisableRecordFunctionGuard : public RecordFunctionGuard { + public: + DisableRecordFunctionGuard() : RecordFunctionGuard(false) {} + ~DisableRecordFunctionGuard() override = default; +}; + +struct TORCH_API RecordFunctionTLS { + // Thread local vector of callbacks, holds pairs (callbacks, unique_id); + // must be sorted in increasing handles order + RecordFunctionCallbacks sorted_tls_callbacks_; + + bool tls_record_function_enabled_ = true; +}; + +TORCH_API const RecordFunctionTLS& get_record_function_tls_(); + +TORCH_API void set_record_function_tls_(const RecordFunctionTLS& tls); + +TORCH_API void set_record_function_seed_for_testing(uint32_t seed); + +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/CachingHostAllocator.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/CachingHostAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..c153824e0607ef92b0828c1a670ad5d7644d2c9c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/CachingHostAllocator.h @@ -0,0 +1,43 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace at::xpu { + +C10_DEPRECATED_MESSAGE( + "at::xpu::getCachingHostAllocator() is deprecated. Please use at::getHostAllocator(at::kXPU) instead.") +inline TORCH_XPU_API at::HostAllocator* getCachingHostAllocator() { + return at::getHostAllocator(at::kXPU); +} + +C10_DEPRECATED_MESSAGE( + "at::xpu::CachingHostAllocator_recordEvent(...) is deprecated. Please use at::getHostAllocator(at::kXPU)->record_event(...) instead.") +inline TORCH_XPU_API bool CachingHostAllocator_recordEvent( + void* ptr, + void* ctx, + c10::xpu::XPUStream stream) { + return getHostAllocator(at::kXPU)->record_event(ptr, ctx, stream.unwrap()); +} + +C10_DEPRECATED_MESSAGE( + "at::xpu::CachingHostAllocator_emptyCache() is deprecated. Please use at::getHostAllocator(at::kXPU)->empty_cache() instead.") +inline TORCH_XPU_API void CachingHostAllocator_emptyCache() { + getHostAllocator(at::kXPU)->empty_cache(); +} + +C10_DEPRECATED_MESSAGE( + "at::xpu::HostAlloc(...) is deprecated. Please use at::getHostAllocator(at::kXPU)->allocate(...) instead.") +inline TORCH_XPU_API at::DataPtr HostAlloc(size_t size) { + return getHostAllocator(at::kXPU)->allocate(size); +} + +} // namespace at::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/EmptyTensor.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/EmptyTensor.h new file mode 100644 index 0000000000000000000000000000000000000000..5d16cda15f6dc29eded375dee033303cae4d1d07 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/EmptyTensor.h @@ -0,0 +1,47 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include + +namespace at::detail { + +TORCH_XPU_API TensorBase empty_xpu( + IntArrayRef size, + ScalarType dtype, + std::optional device_opt, + std::optional memory_format_opt); + +TORCH_XPU_API TensorBase empty_xpu( + IntArrayRef size, + std::optional dtype_opt, + std::optional layout_opt, + std::optional device_opt, + std::optional pin_memory_opt, + std::optional memory_format_opt); + +TORCH_XPU_API TensorBase +empty_xpu(IntArrayRef size, const TensorOptions& options); + +TORCH_XPU_API TensorBase empty_strided_xpu( + IntArrayRef size, + IntArrayRef stride, + ScalarType dtype, + std::optional device_opt); + +TORCH_XPU_API TensorBase empty_strided_xpu( + IntArrayRef size, + IntArrayRef stride, + std::optional dtype_opt, + std::optional layout_opt, + std::optional device_opt, + std::optional pin_memory_opt); + +TORCH_XPU_API TensorBase empty_strided_xpu( + IntArrayRef size, + IntArrayRef stride, + const TensorOptions& options); + +} // namespace at::detail + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/PeerToPeerAccess.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/PeerToPeerAccess.h new file mode 100644 index 0000000000000000000000000000000000000000..8b93bdfd23fa83c679db2c877099ba1c4dc120cb --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/PeerToPeerAccess.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include + +namespace at::xpu { +namespace detail { +// Initialize the peer-to-peer access cache for XPU devices. +inline void init_p2p_access_cache(c10::DeviceIndex num_devices) { + c10::xpu::detail::init_p2p_access_cache(num_devices); +} +} // namespace detail + +// Query if peer-to-peer access is available between two devices. +// This wrapper ensures XPU lazy initialization before forwarding to c10. +inline bool get_p2p_access( + c10::DeviceIndex dev, + c10::DeviceIndex dev_to_access) { + at::globalContext().lazyInitDevice(c10::DeviceType::XPU); + return c10::xpu::get_p2p_access(dev, dev_to_access); +} + +} // namespace at::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/PhiloxXpuState.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/PhiloxXpuState.h new file mode 100644 index 0000000000000000000000000000000000000000..f3f602fe3dd5a6c3ebb9d20f8e51a4f246679977 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/PhiloxXpuState.h @@ -0,0 +1,50 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +namespace at { + +struct PhiloxXpuState { + PhiloxXpuState() = default; + PhiloxXpuState(uint64_t seed, uint64_t offset) { + seed_.val = seed; + offset_.val = offset; + } + // for graph capture + PhiloxXpuState( + int64_t* seed, + int64_t* offset_extragraph, + uint32_t offset_intragraph) { + seed_.ptr = seed; + offset_.ptr = offset_extragraph; + offset_intragraph_ = offset_intragraph; + captured_ = true; + } + + union Payload { + uint64_t val; + int64_t* ptr; + }; + + Payload seed_{}; + Payload offset_{}; + uint32_t offset_intragraph_ = 0; + bool captured_ = false; +}; + +namespace xpu::philox { +inline std::tuple unpack(at::PhiloxXpuState arg) { + if (arg.captured_) { + return std::make_tuple( + static_cast(*arg.seed_.ptr), + static_cast(*(arg.offset_.ptr) + arg.offset_intragraph_)); + } else { + return std::make_tuple(arg.seed_.val, arg.offset_.val); + } +} + +} // namespace xpu::philox +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/PinnedMemoryAllocator.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/PinnedMemoryAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..0ef4066089c40bbc28001edf111209932b995864 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/PinnedMemoryAllocator.h @@ -0,0 +1,16 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace at::xpu { + +inline TORCH_XPU_API at::HostAllocator* getPinnedMemoryAllocator() { + return at::getHostAllocator(at::kXPU); +} +} // namespace at::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUContext.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUContext.h new file mode 100644 index 0000000000000000000000000000000000000000..049b4f68267552a98ce8e07210dd7d3aa8e80e91 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUContext.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace at::xpu { + +// XPU is available if we compiled with XPU. +inline bool is_available() { + return c10::xpu::device_count() > 0; +} + +TORCH_XPU_API DeviceProp* getCurrentDeviceProperties(); + +TORCH_XPU_API DeviceProp* getDeviceProperties(DeviceIndex device); + +TORCH_XPU_API int32_t getGlobalIdxFromDevice(DeviceIndex device); + +TORCH_XPU_API bool canDeviceAccessPeer(DeviceIndex device, DeviceIndex peer); + +} // namespace at::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUDevice.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUDevice.h new file mode 100644 index 0000000000000000000000000000000000000000..63b56c86c6ed26d2877eb4534dd831007830dbb4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUDevice.h @@ -0,0 +1,18 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace at::xpu { + +inline Device getDeviceFromPtr(void* ptr) { + auto device = c10::xpu::get_device_idx_from_pointer(ptr); + return {c10::DeviceType::XPU, device}; +} + +} // namespace at::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUEvent.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..be5c5b83169f0a632d913e08b161ab19bafb6421 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUEvent.h @@ -0,0 +1,8 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUGeneratorImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUGeneratorImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..b9ce7d6c6e8bd2a5335c0ebe6e3a69e2277957f2 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUGeneratorImpl.h @@ -0,0 +1,88 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +namespace at { + +namespace xpu { +struct XPUGraphImpl; +} + +struct XPUGeneratorState : public c10::intrusive_ptr_target { + uint64_t seed_; + uint64_t philox_offset_per_thread_; + uint32_t offset_intragraph_; + bool capturing_{}; + std::unordered_set registered_graphs_; + at::TensorBase seed_extragraph_{}; + at::TensorBase offset_extragraph_{}; + + XPUGeneratorState( + uint64_t seed = default_rng_seed_val, + uint64_t philox_offset_per_thread = 0, + uint32_t offset_intragraph = 0) + : seed_(seed), + philox_offset_per_thread_(philox_offset_per_thread), + offset_intragraph_(offset_intragraph) {} + + void increase(uint64_t increment); + void register_graph(xpu::XPUGraphImpl* graph); + void unregister_graph(xpu::XPUGraphImpl* graph); + void capture_prologue(); + uint64_t capture_epilogue(); + void replay_prologue(uint64_t wholegraph_increment); + + c10::intrusive_ptr clone(); +}; + +struct TORCH_XPU_API XPUGeneratorImpl : public GeneratorImpl { + // Constructors + XPUGeneratorImpl(DeviceIndex device_index = -1); + XPUGeneratorImpl( + DeviceIndex device_index, + c10::intrusive_ptr state_); + ~XPUGeneratorImpl() override = default; + + // XPUGeneratorImpl methods + std::shared_ptr clone() const; + void set_current_seed(uint64_t seed) override; + void set_offset(uint64_t offset) override; + uint64_t get_offset() const override; + uint64_t current_seed() const override; + uint64_t seed() override; + void set_state(const c10::TensorImpl& new_state) override; + c10::intrusive_ptr get_state() const override; + void graphsafe_set_state( + const c10::intrusive_ptr& state) override; + c10::intrusive_ptr graphsafe_get_state() const override; + + void set_philox_offset_per_thread(uint64_t offset); + uint64_t philox_offset_per_thread() const; + + void register_graph(xpu::XPUGraphImpl* graph); + void unregister_graph(xpu::XPUGraphImpl* graph); + PhiloxXpuState philox_xpu_state(uint64_t increment); + std::pair philox_engine_inputs(uint64_t increment); + static c10::DeviceType device_type(); + + private: + XPUGeneratorImpl* clone_impl() const override; + c10::intrusive_ptr state_; +}; + +namespace xpu::detail { + +TORCH_XPU_API const Generator& getDefaultXPUGenerator(DeviceIndex device = -1); + +TORCH_XPU_API Generator createXPUGenerator(DeviceIndex device = -1); + +} // namespace xpu::detail +} // namespace at + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUGraph.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUGraph.h new file mode 100644 index 0000000000000000000000000000000000000000..2047633281288c4a71e6400e39060f0933177000 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUGraph.h @@ -0,0 +1,123 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace at::xpu { + +TORCH_XPU_API MempoolId_t graph_pool_handle(); + +using xpuGraph_t = sycl::ext::oneapi::experimental::command_graph< + sycl::ext::oneapi::experimental::graph_state::modifiable>; +using xpuGraphExec_t = sycl::ext::oneapi::experimental::command_graph< + sycl::ext::oneapi::experimental::graph_state::executable>; + +struct TORCH_XPU_API XPUGraphImpl : public at::GraphImplInterface { + XPUGraphImpl(const GraphImplArgs& args = {}); + ~XPUGraphImpl() override; + + C10_DISABLE_COPY_AND_ASSIGN(XPUGraphImpl); + + void register_generator_state( + c10::intrusive_ptr state); + void register_generator_state(const at::Generator& generator); + + void capture_begin( + MempoolId_t pool = {0, 0}, + GraphCaptureMode capture_mode = GraphCaptureMode::Default) override; + void capture_end() override; + void instantiate() override; + void replay() override; + void reset() override; + MempoolId_t pool() const override; + void enable_debug_mode() override; + void debug_dump(const std::string& debug_path) override; + xpuGraph_t* raw_xpu_graph(); + xpuGraphExec_t* raw_xpu_graph_exec(); + + protected: + std::unique_ptr graph_; + std::unique_ptr graph_exec_; + + bool has_graph_ = false; + bool capture_ended_ = false; + bool has_graph_exec_ = false; + MempoolId_t mempool_id_; + at::xpu::XPUStream capture_stream_; + + // GeneratorState and whole graph offset increments mapping + ska::flat_hash_map, uint64_t> + captured_generator_states_; + + static constexpr c10::DeviceIndex UNDEFINED_DEVICE = -1; + c10::DeviceIndex capture_dev_{UNDEFINED_DEVICE}; + + bool keep_graph_; +}; + +struct TORCH_XPU_API XPUGraph { + XPUGraph(bool keep_graph = false) { + GraphImplArgs args; + args.keep_graph = keep_graph; + impl_ = std::make_unique(args); + } + ~XPUGraph() = default; + + C10_DISABLE_COPY_AND_ASSIGN(XPUGraph); + XPUGraph(XPUGraph&& other) = delete; + XPUGraph& operator=(XPUGraph&& other) = delete; + + void register_generator_state( + c10::intrusive_ptr state) { + impl_->register_generator_state(state); + } + void register_generator_state(const at::Generator& generator) { + impl_->register_generator_state(generator); + } + void capture_begin(MempoolId_t pool = {0, 0}) { + impl_->capture_begin(pool); + } + void capture_end() { + impl_->capture_end(); + } + void instantiate() { + impl_->instantiate(); + } + void replay() { + impl_->replay(); + } + void reset() { + impl_->reset(); + } + MempoolId_t pool() const { + return impl_->pool(); + } + void enable_debug_mode() { + impl_->enable_debug_mode(); + } + void debug_dump(const std::string& debug_path) { + impl_->debug_dump(debug_path); + } + xpuGraph_t* raw_xpu_graph() { + return impl_->raw_xpu_graph(); + } + xpuGraphExec_t* raw_xpu_graph_exec() { + return impl_->raw_xpu_graph_exec(); + } + + private: + std::unique_ptr impl_; +}; + +} // namespace at::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUGraphsUtils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUGraphsUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..8b61e894d54d97ee140049b356477a82d38fd6b7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUGraphsUtils.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace at::xpu { + +inline CaptureStatus currentStreamCaptureStatus() { + return c10::xpu::currentStreamCaptureStatusMayInitCtx(); +} + +inline void assertNotCapturing(const std::string& attempt) { + auto status = currentStreamCaptureStatus(); + TORCH_CHECK( + status == CaptureStatus::Executing, + attempt, + " during XPU graph capture. If you need this call to be captured, " + "please file an issue. " + "Current xpuStreamCaptureStatus: ", + status); +} + +} // namespace at::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUScaledBlas.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUScaledBlas.h new file mode 100644 index 0000000000000000000000000000000000000000..6d5ca8f5a8b84be19dd0916b6c9dbe4ef431cbb5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUScaledBlas.h @@ -0,0 +1,100 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include +#include +#include +#include +#include +#include +#define TORCH_ASSERT_ONLY_METHOD_OPERATORS +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef USE_MSLK +#include +#endif + +#ifndef AT_PER_OPERATOR_HEADERS +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +using at::blas::ScalingType; + +namespace at::native::onednn::scaled { + +/** + * Track concrete implementations available + */ +enum class ScaledGemmImplementation { + NONE = 0, + TENSORWISE_TENSORWISE = 1, + ROWWISE_ROWWISE = 2, +}; + +/** + * Convert passed int (enum) from python back into a + * strictly-typed enum + */ +template +std::vector convert_int_to_enum(ArrayType& v) { + std::vector converted; + converted.reserve(v.size()); + + for (auto vi : v) { + converted.push_back(static_cast(vi)); + } + return converted; +} + +bool check_tensorwise_recipe( + c10::ScalarType, + std::vector&, + ArrayRef&, + c10::ScalarType, + std::vector&, + ArrayRef&); + +bool check_rowwise_recipe( + c10::ScalarType, + std::vector&, + ArrayRef&, + c10::ScalarType, + std::vector&, + ArrayRef&); + +} // namespace at::native::onednn::scaled + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUUtils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..5fbfb10205b8f7960ef3fdbe8281a33bf068ba81 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/XPUUtils.h @@ -0,0 +1,26 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace at::xpu { + +// Check if every tensor in a list of tensors matches the current device. +inline bool check_device(ArrayRef ts) { + if (ts.empty()) { + return true; + } + Device curDevice = Device(kXPU, current_device()); + for (const Tensor& t : ts) { + if (t.device() != curDevice) { + return false; + } + } + return true; +} + +} // namespace at::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/detail/LazyLevelZero.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/detail/LazyLevelZero.h new file mode 100644 index 0000000000000000000000000000000000000000..fa8a71acdf9125905830bdc9217120fb4ac77705 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/detail/LazyLevelZero.h @@ -0,0 +1,16 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +namespace at::xpu { +// Forward-declares at::xpu::LevelZero +struct LevelZero; + +namespace detail { +extern LevelZero lazyLevelZero; +} // namespace detail + +} // namespace at::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/detail/XPUHooks.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/detail/XPUHooks.h new file mode 100644 index 0000000000000000000000000000000000000000..189431cd115699fe2f4b3acb9bca9b024de43699 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ATen/xpu/detail/XPUHooks.h @@ -0,0 +1,39 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace at::xpu::detail { + +// The real implementation of XPUHooksInterface +struct XPUHooks : public at::XPUHooksInterface { + XPUHooks(at::XPUHooksArgs) {} + void init() const override; + bool hasXPU() const override; + std::string showConfig() const override; + int32_t getGlobalIdxFromDevice(const at::Device& device) const override; + const Generator& getDefaultGenerator( + DeviceIndex device_index = -1) const override; + Generator getNewGenerator(DeviceIndex device_index = -1) const override; + Device getDeviceFromPtr(void* data) const override; + c10::DeviceIndex getNumGPUs() const override; + DeviceIndex current_device() const override; + void deviceSynchronize(DeviceIndex device_index) const override; + Allocator* getPinnedMemoryAllocator() const override; + + bool isBuilt() const override { + return true; + } + bool isAvailable() const override; + bool isPinnedPtr(const void* data) const override; + bool hasPrimaryContext(DeviceIndex device_index) const override; + DeviceIndex deviceCount() const override; + DeviceIndex getCurrentDevice() const override; + const at::xpu::LevelZero& level_zero() const override; +}; + +} // namespace at::xpu::detail + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/THC/THCAtomics.cuh b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/THC/THCAtomics.cuh new file mode 100644 index 0000000000000000000000000000000000000000..cb269d477f2c8d906d0c5c3e101189cb85c971d3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/THC/THCAtomics.cuh @@ -0,0 +1,8 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// TODO: Remove once torchvision has been updated to use the ATen header +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/THC/THCDeviceUtils.cuh b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/THC/THCDeviceUtils.cuh new file mode 100644 index 0000000000000000000000000000000000000000..251098b34aec9c7a11706c03213c2a5035bf5050 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/THC/THCDeviceUtils.cuh @@ -0,0 +1,8 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// TODO: Remove this header +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/advisor-annotate.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/advisor-annotate.h new file mode 100644 index 0000000000000000000000000000000000000000..3a99056bb382f1871433470f3b7809741bcc03d5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/advisor-annotate.h @@ -0,0 +1,525 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (C) 2005-2019 Intel Corporation + * SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause + */ + +/* This file defines macros and inline functions used by + * the Intel(R) Advisor XE "Dependencies Modeling" and + * "Suitability Modeling" analysis, and are in described + * in the "Annotations" section of the help. + * + * Expansion Options + * + * There are several options you can used to control how advisor-annotate.h + * is included. To use these, define the option prior to including + * advisor-annotate.h. e.g. + * #define ANNOTATE_DECLARE + * #include "advisor-annotate.h" + * + * Controlling inclusion of windows.h + * + * windows.h is included for declarations for LoadLibrary, GetProcSymbol, + * but this can have interactions with user code, such as conflicting + * definitions of types. There are two general approaches to work around + * this if this triggers problems building your application: + * + * 1. Reduce the amount declared by windows.h by using the following: + * #define NOMINMAX + * #define WIN32_LEAN_AND_MEAN + * prior to including advisor-annotate.h in your code. + * The first avoids problems with STL min/max in particular + * This is sufficient in some cases, and may be the easiest. + * + * 2. Use a declaration/definition approach, where all uses of advisor-annotate.h + * other than one, generate a set of declarations, and windows.h is only + * needed in a single implementation module. In this model, all includes + * of advisor-annotate.h except one specify ANNOTATE_DECLARE, which causes + * advisor-annotate.h to declare an external routine, and not include + * windows.h. A final include of advisor-annotate.h than specifies + * ANNOTATE_DEFINE, to actually define the global routine to resolve + * the external reference. This one include is the only one that winds up + * using windows.h. If necessary, this can be placed in a file by itself. + * + * An example using this mechanism: + * + * ... + * // Some header(s) used in places in your system where you want + * // to be able to use annotations + * #define ANNOTATE_DECLARE + * #include "advisor-annotate.h" + * ... + * // annotation uses + * ANNOTATE_SITE_BEGIN(MySite1) + * ... + * ANNOTATE_SITE_END(MySite1) + * ... + * + * ... + * // A single implementation file (.cpp/.cxx) causes windows.h + * // to be included, and the support routine to be defined as a + * // global routine called from the various annotation uses. + * #define ANNOTATE_DEFINE + * #include "advisor-annotate.h" + * ... + * + * Null expansion of annotations + * + * Some people may find it useful to have no expansion for annotations, + * if you have a project that you want to build without any annotation + * effects at all. (e.g. if you have a project where you want to have + * some annotations in a shared source pool, but only particular + * developers are actually building with the annotations enabled.) + * Defining ANNOTATE_EXPAND_NULL avoids declaring comdat routines, + * and avoids any textual expansion for annotation macros. + */ + +#ifndef _ADVISOR_ANNOTATE_H_ +#define _ADVISOR_ANNOTATE_H_ + +/* Version of the annotations. + * The presence of this macro serves to idetify the annotation definition + * file and the form of annotations. + */ +#define INTEL_ADVISOR_ANNOTATION_VERSION 1.0 + +#ifdef ANNOTATE_EXPAND_NULL + +#define ANNOTATE_SITE_BEGIN(_SITE) +#define ANNOTATE_SITE_END(...) +#define ANNOTATE_TASK_BEGIN(_TASK) +#define ANNOTATE_TASK_END(...) +#define ANNOTATE_ITERATION_TASK(_TASK) +#define ANNOTATE_LOCK_ACQUIRE(_ADDR) +#define ANNOTATE_LOCK_RELEASE(_ADDR) +#define ANNOTATE_RECORD_ALLOCATION(_ADDR, _SIZE) +#define ANNOTATE_RECORD_DEALLOCATION(_ADDR) +#define ANNOTATE_INDUCTION_USES(_ADDR, _SIZE) +#define ANNOTATE_REDUCTION_USES(_ADDR, _SIZE) +#define ANNOTATE_OBSERVE_USES(_ADDR, _SIZE) +#define ANNOTATE_CLEAR_USES(_ADDR) +#define ANNOTATE_DISABLE_OBSERVATION_PUSH +#define ANNOTATE_DISABLE_OBSERVATION_POP +#define ANNOTATE_DISABLE_COLLECTION_PUSH +#define ANNOTATE_DISABLE_COLLECTION_POP +#define ANNOTATE_AGGREGATE_TASK(_COUNT) + +#else /* ANNOTATE_EXPAND_NULL */ + +#if defined(WIN32) || defined(_WIN32) + +#define ANNOTATEAPI __cdecl + +#ifndef ANNOTATE_DECLARE +#include + +typedef HMODULE lib_t; + +#define __itt_get_proc(lib, name) GetProcAddress(lib, name) +#define __itt_load_lib(name) LoadLibraryA(name) +#define __itt_unload_lib(handle) FreeLibrary(handle) +#define __itt_system_error() (int)GetLastError() +#endif /* ANNOTATE_DECLARE */ + +#else /* defined(WIN32) || defined(_WIN32) */ + +#if defined _M_IX86 || __i386__ +# define ANNOTATEAPI __attribute__ ((cdecl)) +#else +# define ANNOTATEAPI /* actual only on x86 platform */ +#endif + + +#ifndef ANNOTATE_DECLARE +#include +#include +#include + +typedef void* lib_t; + +#define __itt_get_proc(lib, name) dlsym(lib, name) +#define __itt_load_lib(name) dlopen(name, RTLD_LAZY) +#define __itt_unload_lib(handle) dlclose(handle) +#define __itt_system_error() errno +#endif /* ANNOTATE_DECLARE */ + +#endif /* defined(WIN32) || defined(_WIN32) */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef _ITTNOTIFY_H_ + +/* Handles for sites and tasks. + */ +typedef void* __itt_model_site; /* handle for lexical site */ +typedef void* __itt_model_site_instance; /* handle for dynamic instance */ +typedef void* __itt_model_task; /* handle for lexical site */ +typedef void* __itt_model_task_instance; /* handle for dynamic instance */ + +typedef enum { + __itt_model_disable_observation, + __itt_model_disable_collection +} __itt_model_disable; + +#endif /* _ITTNOTIFY_H_ */ + +/*** Use the routines in libittnotify.dll. ***/ + +/* Basic approach: + * For the case of calling the dll, there is an __annotate_routine function + * declared as a comdat in each compilation unit with annotations present. + * That routine in turn has an internal static structure that is initialized + * once to contain the address of functions occuring in libittnotify.dll. + * Each time an annotation macro is invoked, that causes a call to the + * __annotate_routine function to get addresses of the routines, followed + * by calling the specific routine, provided the address is non-null. + */ + +/* This set of macros generates calls that are part of application images, + * which call the __itt_model_xxx routines in the dynamically loaded + * libittnotify.dll. + */ +#ifndef _ITTNOTIFY_H_ +#define ITT_NOTIFY_DECL(_text) _text +#else +#define ITT_NOTIFY_DECL(_text) +#endif + +/* For C++, a static initialization is used */ +#if defined(__cplusplus) && defined(WIN32) +#define _ANNOTATE_ROUTINES_ADDR __annotate_routines_s +#else +#define _ANNOTATE_ROUTINES_ADDR __annotate_routines_init( __annotate_routines() ) +#endif /* __cplusplus */ + + +#define _ANNOTATE_DECLARE_0(_BASENAME) \ +typedef void (ANNOTATEAPI * __annotate_##_BASENAME##_t)(); \ +static __inline void ANNOTATEAPI __annotate_##_BASENAME##_t_nop() { }; \ +ITT_NOTIFY_DECL( extern void ANNOTATEAPI __itt_model_##_BASENAME(); ) + +#define _ANNOTATE_DECLARE_0_INT(_BASENAME) \ +typedef int (ANNOTATEAPI * __annotate_##_BASENAME##_t)(); \ +static __inline int ANNOTATEAPI __annotate_##_BASENAME##_t_nop() { return 0; }; \ +ITT_NOTIFY_DECL( extern void ANNOTATEAPI __itt_model_##_BASENAME(); ) + +#define _ANNOTATE_CALL_0(_BASENAME) { _ANNOTATE_ROUTINES_ADDR->_BASENAME(); } + +#define _ANNOTATE_DECLARE_1(_BASENAME, _P1TYPE) \ +typedef void (ANNOTATEAPI * __annotate_##_BASENAME##_t)(_P1TYPE p1); \ +static __inline void ANNOTATEAPI __annotate_##_BASENAME##_t_nop(_P1TYPE p1) { (void)p1; }; \ +ITT_NOTIFY_DECL( extern void ANNOTATEAPI __itt_model_##_BASENAME(_P1TYPE p1); ) + +#define _ANNOTATE_CALL_1(_BASENAME, _P1) { _ANNOTATE_ROUTINES_ADDR->_BASENAME(_P1); } + +#define _ANNOTATE_DECLARE_2(_BASENAME, _P1TYPE, _P2TYPE) \ +typedef void (ANNOTATEAPI * __annotate_##_BASENAME##_t)(_P1TYPE p1, _P2TYPE p2); \ +static __inline void ANNOTATEAPI __annotate_##_BASENAME##_t_nop(_P1TYPE p1, _P2TYPE p2) { (void)p1; (void)p2; }; \ +ITT_NOTIFY_DECL( extern void ANNOTATEAPI __itt_model_##_BASENAME(_P1TYPE p1, _P2TYPE p2); ) + +#define _ANNOTATE_CALL_2(_BASENAME, _P1, _P2) { _ANNOTATE_ROUTINES_ADDR->_BASENAME((_P1), (_P2)); } + +/*** Declare routines appropriately based on usage style ***/ + +/* Depending on above, this will either expand to comdats that are + * used directly, or comdats that call routines in libittnotify.dll + */ +_ANNOTATE_DECLARE_1(site_beginA, const char *) +_ANNOTATE_DECLARE_0(site_end_2) +_ANNOTATE_DECLARE_1(task_beginA, const char *) +_ANNOTATE_DECLARE_0(task_end_2) +_ANNOTATE_DECLARE_1(iteration_taskA, const char *) +_ANNOTATE_DECLARE_1(lock_acquire_2, void *) +_ANNOTATE_DECLARE_1(lock_release_2, void *) +_ANNOTATE_DECLARE_2(record_allocation, void *, size_t) +_ANNOTATE_DECLARE_1(record_deallocation, void *) +_ANNOTATE_DECLARE_2(induction_uses, void *, size_t) +_ANNOTATE_DECLARE_2(reduction_uses, void *, size_t) +_ANNOTATE_DECLARE_2(observe_uses, void *, size_t) +_ANNOTATE_DECLARE_1(clear_uses, void *) +_ANNOTATE_DECLARE_1(disable_push, __itt_model_disable) +_ANNOTATE_DECLARE_0(disable_pop) +_ANNOTATE_DECLARE_1(aggregate_task, size_t) +_ANNOTATE_DECLARE_0_INT(is_collection_disabled) + +/* All of the symbols potentially in the library + */ +struct __annotate_routines { + volatile int initialized; + __annotate_site_beginA_t site_beginA; + __annotate_site_end_2_t site_end_2; + __annotate_task_beginA_t task_beginA; + __annotate_task_end_2_t task_end_2; + __annotate_iteration_taskA_t iteration_taskA; + __annotate_lock_acquire_2_t lock_acquire_2; + __annotate_lock_release_2_t lock_release_2; + __annotate_record_allocation_t record_allocation; + __annotate_record_deallocation_t record_deallocation; + __annotate_induction_uses_t induction_uses; + __annotate_reduction_uses_t reduction_uses; + __annotate_observe_uses_t observe_uses; + __annotate_clear_uses_t clear_uses; + __annotate_disable_push_t disable_push; + __annotate_disable_pop_t disable_pop; + __annotate_aggregate_task_t aggregate_task; + __annotate_is_collection_disabled_t is_collection_disabled; +}; + +/* This comdat-ed routine means there is a single instance of the function pointer + * structure per image + */ +static __inline struct __annotate_routines* __annotate_routines() +{ + static struct __annotate_routines __annotate_routines; + return &__annotate_routines; +} + +/* This routine is called to get the address of an initialized + * set of function pointers for the annotation routines. + */ + +#ifdef ANNOTATE_DECLARE +extern struct __annotate_routines* ANNOTATEAPI __annotate_routines_init(struct __annotate_routines* itt); +#else +#ifdef ANNOTATE_DEFINE + /* */ +#else + static __inline +#endif +struct __annotate_routines* +ANNOTATEAPI +__annotate_routines_init(struct __annotate_routines* itt) { + + if (itt->initialized) { + return itt; + } else { + + /* Initialized by first invocation + * This assumes that the code here can be executed successfully + * by multiple threads, should that ever happen. + */ + int do_disable_pop = 0; + char* lib_name = NULL; + lib_t itt_notify = 0; + + if (sizeof(void*) > 4) { + lib_name = getenv("INTEL_LIBITTNOTIFY64"); + } else { + lib_name = getenv("INTEL_LIBITTNOTIFY32"); + } + + if (lib_name) { + itt_notify = __itt_load_lib(lib_name); + } else { +#if defined(WIN32) || defined(_WIN32) + itt_notify = __itt_load_lib("libittnotify.dll"); +#elif defined(__APPLE__) + itt_notify = __itt_load_lib("libittnotify.dylib"); +#else + itt_notify = __itt_load_lib("libittnotify.so"); +#endif + } + + if (itt_notify != NULL) { + /* The static variables initialized and itt are reported as race conditions + * or inconsistent lock usage by Dependencies Modeling in some obscure cases + * involving multiple dlls. Ignoring this initialization phase gets rid of + * this problem. + */ + __annotate_disable_push_t disable_push; + __annotate_is_collection_disabled_t is_collection_disabled; + disable_push = (__annotate_disable_push_t) __itt_get_proc(itt_notify, "__itt_model_disable_push"); + is_collection_disabled = (__annotate_is_collection_disabled_t) __itt_get_proc(itt_notify, "__itt_model_is_collection_disabled"); + if (disable_push) { + if ( ! (is_collection_disabled && is_collection_disabled()) ) + { + // disable collection only if it is not disabled already (for example, started paused) + disable_push(__itt_model_disable_observation); + do_disable_pop = 1; + } + } + itt->site_beginA = (__annotate_site_beginA_t) __itt_get_proc(itt_notify, "__itt_model_site_beginA"); + itt->site_end_2 = (__annotate_site_end_2_t) __itt_get_proc(itt_notify, "__itt_model_site_end_2"); + itt->task_beginA = (__annotate_task_beginA_t) __itt_get_proc(itt_notify, "__itt_model_task_beginA"); + itt->task_end_2 = (__annotate_task_end_2_t) __itt_get_proc(itt_notify, "__itt_model_task_end_2"); + itt->iteration_taskA = (__annotate_iteration_taskA_t) __itt_get_proc(itt_notify, "__itt_model_iteration_taskA"); + itt->lock_acquire_2 = (__annotate_lock_acquire_2_t) __itt_get_proc(itt_notify, "__itt_model_lock_acquire_2"); + itt->lock_release_2 = (__annotate_lock_release_2_t) __itt_get_proc(itt_notify, "__itt_model_lock_release_2"); + itt->record_allocation = (__annotate_record_allocation_t) __itt_get_proc(itt_notify, "__itt_model_record_allocation"); + itt->record_deallocation = (__annotate_record_deallocation_t)__itt_get_proc(itt_notify, "__itt_model_record_deallocation"); + itt->induction_uses = (__annotate_induction_uses_t) __itt_get_proc(itt_notify, "__itt_model_induction_uses"); + itt->reduction_uses = (__annotate_reduction_uses_t) __itt_get_proc(itt_notify, "__itt_model_reduction_uses"); + itt->observe_uses = (__annotate_observe_uses_t) __itt_get_proc(itt_notify, "__itt_model_observe_uses"); + itt->clear_uses = (__annotate_clear_uses_t) __itt_get_proc(itt_notify, "__itt_model_clear_uses"); + itt->disable_push = disable_push; + itt->disable_pop = (__annotate_disable_pop_t) __itt_get_proc(itt_notify, "__itt_model_disable_pop"); + itt->aggregate_task = (__annotate_aggregate_task_t) __itt_get_proc(itt_notify, "__itt_model_aggregate_task"); + itt->is_collection_disabled = is_collection_disabled; + } + /* No-op routine for any that didn't get resolved */ + if (!itt->site_beginA) itt->site_beginA = __annotate_site_beginA_t_nop; + if (!itt->site_end_2) itt->site_end_2 = __annotate_site_end_2_t_nop; + if (!itt->task_beginA) itt->task_beginA = __annotate_task_beginA_t_nop; + if (!itt->task_end_2) itt->task_end_2 = __annotate_task_end_2_t_nop; + if (!itt->iteration_taskA) itt->iteration_taskA = __annotate_iteration_taskA_t_nop; + if (!itt->lock_acquire_2) itt->lock_acquire_2 = __annotate_lock_acquire_2_t_nop; + if (!itt->lock_release_2) itt->lock_release_2 = __annotate_lock_release_2_t_nop; + if (!itt->record_allocation) itt->record_allocation = __annotate_record_allocation_t_nop; + if (!itt->record_deallocation) itt->record_deallocation=__annotate_record_deallocation_t_nop; + if (!itt->induction_uses) itt->induction_uses = __annotate_induction_uses_t_nop; + if (!itt->reduction_uses) itt->reduction_uses = __annotate_reduction_uses_t_nop; + if (!itt->observe_uses) itt->observe_uses = __annotate_observe_uses_t_nop; + if (!itt->clear_uses) itt->clear_uses = __annotate_clear_uses_t_nop; + if (!itt->disable_push) itt->disable_push = __annotate_disable_push_t_nop; + if (!itt->disable_pop) itt->disable_pop = __annotate_disable_pop_t_nop; + if (!itt->aggregate_task) itt->aggregate_task = __annotate_aggregate_task_t_nop; + if (!itt->is_collection_disabled) itt->is_collection_disabled = __annotate_is_collection_disabled_t_nop; + + itt->initialized = 1; + + if (do_disable_pop) { + itt->disable_pop(); + } + } + return itt; +} +#endif /* ANNOTATE_DECLARE */ + +/* For C++ only, use a class to force initialization */ + +#if defined(__cplusplus) && defined(WIN32) +/* Force one-shot initialization so individual calls don't need it */ +static struct __annotate_routines* __annotate_routines_s = __annotate_routines_init( __annotate_routines() ); +#endif + +/* For C++, allow the Annotate::SiteBegin(x) form. For Windows CLR, this is the default + * expansion for the macros (with no-inline) to get the best call stacks in the tools. */ +#if defined(__cplusplus) +/* Ensure this code is managed and non-inlinable */ +#if defined(WIN32) && defined(__CLR_VER) +#pragma managed(push, on) +#define ANNOTATE_CLR_NOINLINE __declspec(noinline) +#else +#define ANNOTATE_CLR_NOINLINE +#endif +class Annotate { +public: + static ANNOTATE_CLR_NOINLINE void SiteBegin(const char* site) { _ANNOTATE_ROUTINES_ADDR->site_beginA(site); } + static ANNOTATE_CLR_NOINLINE void SiteEnd() { _ANNOTATE_ROUTINES_ADDR->site_end_2(); } + static ANNOTATE_CLR_NOINLINE void TaskBegin(const char* task) { _ANNOTATE_ROUTINES_ADDR->task_beginA(task); } + static ANNOTATE_CLR_NOINLINE void TaskEnd() { _ANNOTATE_ROUTINES_ADDR->task_end_2(); } + static ANNOTATE_CLR_NOINLINE void IterationTask(const char* task) { _ANNOTATE_ROUTINES_ADDR->iteration_taskA(task); } + static ANNOTATE_CLR_NOINLINE void LockAcquire(void* lockId) { _ANNOTATE_ROUTINES_ADDR->lock_acquire_2(lockId); } + static ANNOTATE_CLR_NOINLINE void LockRelease(void* lockId) { _ANNOTATE_ROUTINES_ADDR->lock_release_2(lockId); } + static ANNOTATE_CLR_NOINLINE void RecordAllocation(void *p, size_t s) { _ANNOTATE_ROUTINES_ADDR->record_allocation(p, s); } + static ANNOTATE_CLR_NOINLINE void RecordDeallocation(void *p) { _ANNOTATE_ROUTINES_ADDR->record_deallocation(p); } + static ANNOTATE_CLR_NOINLINE void InductionUses(void *p, size_t s) { _ANNOTATE_ROUTINES_ADDR->induction_uses(p, s); } + static ANNOTATE_CLR_NOINLINE void ReductionUses(void *p, size_t s) { _ANNOTATE_ROUTINES_ADDR->reduction_uses(p, s); } + static ANNOTATE_CLR_NOINLINE void ObserveUses(void *p, size_t s) { _ANNOTATE_ROUTINES_ADDR->observe_uses(p, s); } + static ANNOTATE_CLR_NOINLINE void ClearUses(void *p) { _ANNOTATE_ROUTINES_ADDR->clear_uses(p); } + static ANNOTATE_CLR_NOINLINE void DisablePush(__itt_model_disable d) { _ANNOTATE_ROUTINES_ADDR->disable_push(d); } + static ANNOTATE_CLR_NOINLINE void DisablePop() { _ANNOTATE_ROUTINES_ADDR->disable_pop(); } + static ANNOTATE_CLR_NOINLINE void AggregateTask(size_t c) { _ANNOTATE_ROUTINES_ADDR->aggregate_task(c); } +}; +#if defined(WIN32) && defined(__CLR_VER) +#pragma managed(pop) +#endif +#undef ANNOTATE_CLR_NOINLINE +#endif + +#if defined(__cplusplus) && defined(WIN32) && defined(__CLR_VER) + +#define ANNOTATE_SITE_BEGIN(_SITE) Annotate::SiteBegin(#_SITE) +#define ANNOTATE_SITE_END(...) Annotate::SiteEnd() +#define ANNOTATE_TASK_BEGIN(_TASK) Annotate::TaskBegin(#_TASK) +#define ANNOTATE_TASK_END(...) Annotate::TaskEnd() +#define ANNOTATE_ITERATION_TASK(_TASK) Annotate::IterationTask(#_TASK) +#define ANNOTATE_LOCK_ACQUIRE(_ADDR) Annotate::LockAcquire(_ADDR) +#define ANNOTATE_LOCK_RELEASE(_ADDR) Annotate::LockRelease(_ADDR) +#define ANNOTATE_RECORD_ALLOCATION(_ADDR, _SIZE) Annotate::RecordAllocation((_ADDR), (_SIZE)) +#define ANNOTATE_RECORD_DEALLOCATION(_ADDR) Annotate::RecordDeallocation(_ADDR) +#define ANNOTATE_INDUCTION_USES(_ADDR, _SIZE) Annotate::InductionUses((_ADDR), (_SIZE)) +#define ANNOTATE_REDUCTION_USES(_ADDR, _SIZE) Annotate::ReductionUses((_ADDR), (_SIZE)) +#define ANNOTATE_OBSERVE_USES(_ADDR, _SIZE) Annotate::ObserveUses((_ADDR), (_SIZE)) +#define ANNOTATE_CLEAR_USES(_ADDR) Annotate::ClearUses(_ADDR) +#define ANNOTATE_DISABLE_OBSERVATION_PUSH Annotate::DisablePush(itt_model_disable_observation) +#define ANNOTATE_DISABLE_OBSERVATION_POP Annotate::DisablePop() +#define ANNOTATE_DISABLE_COLLECTION_PUSH Annotate::DisablePush(__itt_model_disable_collection) +#define ANNOTATE_DISABLE_COLLECTION_POP Annotate::DisablePop() +#define ANNOTATE_AGGREGATE_TASK(_COUNT) Annotate::AggregateTask(_COUNT) + +#else + +/* Mark the start of a site (region) to be analyzed by the tool */ +#define ANNOTATE_SITE_BEGIN(_SITE) _ANNOTATE_CALL_1(site_beginA, #_SITE) + +/* Mark the end of a site (region) to be analyzed by the tool and + * indicate a WaitForAll task synchronization */ +#define ANNOTATE_SITE_END(...) _ANNOTATE_CALL_0(site_end_2) + +/* Mark the beginning of a region of code that constitutes a task */ +#define ANNOTATE_TASK_BEGIN(_TASK) _ANNOTATE_CALL_1(task_beginA, #_TASK) + +/* Mark the end of a region of code that constitutes a task */ +#define ANNOTATE_TASK_END(...) _ANNOTATE_CALL_0(task_end_2) + +/* Mark the break between one task and the next task (a "split" description model + * rather than a "begin/end" description model. */ +#define ANNOTATE_ITERATION_TASK(_TASK) _ANNOTATE_CALL_1(iteration_taskA, #_TASK) + +/* Acquire a lock identified by lockId */ +#define ANNOTATE_LOCK_ACQUIRE(_ADDR) _ANNOTATE_CALL_1(lock_acquire_2, (_ADDR)) + +/* Release a lock identified by lockId */ +#define ANNOTATE_LOCK_RELEASE(_ADDR) _ANNOTATE_CALL_1(lock_release_2, (_ADDR)) + +/* Record user allocation of memory */ +#define ANNOTATE_RECORD_ALLOCATION(_ADDR, _SIZE) _ANNOTATE_CALL_2(record_allocation, (_ADDR), (_SIZE)) + +/* Record user deallocation of memory */ +#define ANNOTATE_RECORD_DEALLOCATION(_ADDR) _ANNOTATE_CALL_1(record_deallocation, (_ADDR)) + +/* Denote storage as an inductive value */ +#define ANNOTATE_INDUCTION_USES(_ADDR, _SIZE) _ANNOTATE_CALL_2(induction_uses, (_ADDR), (_SIZE)) + +/* Denote storage as a reduction */ +#define ANNOTATE_REDUCTION_USES(_ADDR, _SIZE) _ANNOTATE_CALL_2(reduction_uses, (_ADDR), (_SIZE)) + +/* Record all observations of uses */ +#define ANNOTATE_OBSERVE_USES(_ADDR, _SIZE) _ANNOTATE_CALL_2(observe_uses, (_ADDR), (_SIZE)) + +/* Clear handling of values */ +#define ANNOTATE_CLEAR_USES(_ADDR) _ANNOTATE_CALL_1(clear_uses, (_ADDR)) + +/* Push disable of observations */ +#define ANNOTATE_DISABLE_OBSERVATION_PUSH _ANNOTATE_CALL_1(disable_push, __itt_model_disable_observation) + +/* Pop disable of observations */ +#define ANNOTATE_DISABLE_OBSERVATION_POP _ANNOTATE_CALL_0(disable_pop) + +/* Push disable of collection */ +#define ANNOTATE_DISABLE_COLLECTION_PUSH _ANNOTATE_CALL_1(disable_push, __itt_model_disable_collection) + +/* Pop disable of collection */ +#define ANNOTATE_DISABLE_COLLECTION_POP _ANNOTATE_CALL_0(disable_pop) + +/* Task aggregation */ +#define ANNOTATE_AGGREGATE_TASK(_COUNT) _ANNOTATE_CALL_1(aggregate_task, (_COUNT)) + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ANNOTATE_EXPAND_NULL */ + +#endif /* _ADVISOR_ANNOTATE_H_ */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Allocator.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Allocator.h new file mode 100644 index 0000000000000000000000000000000000000000..59f186a002eef63a63bbcfa31410f6751baca7e9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Allocator.h @@ -0,0 +1,456 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +using CaptureId_t = unsigned long long; +// first is set if the instance is created by CUDAGraph::capture_begin. +// second is set if the instance is created by at::cuda::graph_pool_handle. +using MempoolId_t = std::pair; + +struct MempoolIdHash { + std::size_t operator()(const MempoolId_t& mempool_id) const noexcept { + return mempool_id.first != 0 ? mempool_id.first : mempool_id.second; + } +}; + +// A DataPtr is a unique pointer (with an attached deleter and some +// context for the deleter) to some memory, which also records what +// device is for its data. +// +// nullptr DataPtrs can still have a nontrivial device; this allows +// us to treat zero-size allocations uniformly with non-zero allocations. +// +class C10_API DataPtr { + private: + c10::detail::UniqueVoidPtr ptr_; + Device device_; + + public: + // Choice of CPU here is arbitrary; if there's an "undefined" device + // we could use that too + DataPtr() : device_(DeviceType::CPU) {} + DataPtr(void* data, Device device) : ptr_(data), device_(device) {} + DataPtr(void* data, void* ctx, DeleterFnPtr ctx_deleter, Device device) + : ptr_(data, ctx, ctx_deleter), device_(device) {} + void* operator->() const { + return ptr_.get(); + } + C10_ALWAYS_INLINE bool /* success */ unsafe_reset_data_and_ctx( + void* new_data_and_ctx) { + return ptr_.unsafe_reset_data_and_ctx(new_data_and_ctx); + } + void clear() { + ptr_.clear(); + } + void* get() const { + return ptr_.get(); + } + void* mutable_get() { + return ptr_.get(); + } + void* get_context() const { + return ptr_.get_context(); + } + void* release_context() { + return ptr_.release_context(); + } + std::unique_ptr&& move_context() { + return ptr_.move_context(); + } + operator bool() const { + return static_cast(ptr_); + } + template + T* cast_context(DeleterFnPtr expected_deleter) const { + return ptr_.cast_context(expected_deleter); + } + DeleterFnPtr get_deleter() const { + return ptr_.get_deleter(); + } + /** + * Compare the deleter in a DataPtr to expected_deleter. + * If it matches, replace the deleter with new_deleter + * and return true; otherwise, does nothing and returns + * false. + * + * In general, it is not safe to unconditionally set the + * deleter on a DataPtr, because you don't know what + * the deleter is, and thus will have a hard time properly + * disposing of the deleter without storing the original + * deleter (this is difficult to do, because DeleterFnPtr + * is not a closure, and because the context on DataPtr is + * only a single word, you generally don't have enough + * space to store both the original deleter and its context). + * However, in some cases, you know /exactly/ what the deleter + * is, and you have a new deleter that manually wraps + * the old one. In this case, you can safely swap the deleter + * after asserting that the deleters line up. + * + * What are the requirements on new_deleter? It must still + * properly dispose of the void* pointer passed in as its argument, + * where void* is whatever the context of the original deleter + * is. So in general, you expect the new deleter to look something + * like this: + * + * [](void* ptr) { + * some_new_stuff(ptr); + * get_orig_allocator()->raw_deleter(ptr); + * } + * + * Note that it won't work to close over the original + * allocator; you don't have enough space to do that! Also, + * it's unsafe to assume that the passed in pointer in + * question is the memory pointer in question; it might not + * be; be sure to read the source code of the Allocator + * in question to confirm this. + */ + [[nodiscard]] bool compare_exchange_deleter( + DeleterFnPtr expected_deleter, + DeleterFnPtr new_deleter) { + return ptr_.compare_exchange_deleter(expected_deleter, new_deleter); + } + Device device() const { + return device_; + } + // Unsafely mutates the device on a DataPtr. Under normal use, + // you should never actually need to call this function. + // We used to need this for the implementation of the hack detailed + // in Note [Masquerading as CUDA], but that hack has been removed. + // Other uses of this function now exist so it cannot be deprecated. + void unsafe_set_device(Device device) { + device_ = device; + } +}; + +// NB: Device is NOT tested for here; a CUDA nullptr is as much a nullptr as a +// CPU nullptr + +inline bool operator==(const DataPtr& dp, std::nullptr_t) noexcept { + return !dp; +} +inline bool operator==(std::nullptr_t, const DataPtr& dp) noexcept { + return !dp; +} +inline bool operator!=(const DataPtr& dp, std::nullptr_t) noexcept { + return dp; +} +inline bool operator!=(std::nullptr_t, const DataPtr& dp) noexcept { + return dp; +} + +// Note [raw_allocate/raw_deallocate and Thrust] +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Thrust's support for custom allocators requires us to write something +// like this: +// +// class ThrustAllocator { +// char* allocate(size_t); +// void deallocate(char*, size_t); +// }; +// +// This is not good for our unique_ptr based allocator interface, as +// there is no way to get to the context when we free. +// +// However, in some cases the context is exactly the same as +// the data pointer. In this case, we can support the "raw" +// allocate and deallocate interface. This is what +// raw_deleter signifies. By default, it returns a nullptr, which means that +// the raw interface is not implemented. Be sure to implement it whenever +// possible, or the raw interface will incorrectly reported as unsupported, +// when it is actually possible. + +// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions) +struct C10_API Allocator { + virtual ~Allocator() = default; + + virtual DataPtr allocate(size_t n) = 0; + + // Clones an allocation that came from this allocator. + // + // To perform the copy, this function calls `copy_data`, which + // must be implemented by derived classes. + // + // Note that this explicitly ignores any context that may have been + // attached to the input data. + // + // Requires: input data was allocated by the same allocator. + DataPtr clone(const void* data, std::size_t n); + + // Checks if DataPtr has a simple context, not wrapped with any out of the + // ordinary contexts. + virtual bool is_simple_data_ptr(const DataPtr& data_ptr) const; + + // If this returns a non nullptr, it means that allocate() + // is guaranteed to return a unique_ptr with this deleter attached; + // it means the rawAllocate and rawDeallocate APIs are safe to use. + // This function MUST always return the same BoundDeleter. + virtual DeleterFnPtr raw_deleter() const { + return nullptr; + } + void* raw_allocate(size_t n) { + auto dptr = allocate(n); + AT_ASSERT(dptr.get() == dptr.get_context()); + return dptr.release_context(); + } + void raw_deallocate(void* ptr) { + auto d = raw_deleter(); + AT_ASSERT(d); + d(ptr); + } + + // Copies data from one allocation to another. + // Pure virtual, so derived classes must define behavior. + // Derived class implementation can simply call `default_copy_data` + // to use `std::memcpy`. + // + // Requires: src and dest were allocated by this allocator + // Requires: src and dest both have length >= count + virtual void copy_data(void* dest, const void* src, std::size_t count) + const = 0; + + protected: + // Uses `std::memcpy` to copy data. + // Child classes can use this as `copy_data` when an alternative copy + // API is not needed. + void default_copy_data(void* dest, const void* src, std::size_t count) const; +}; + +// This context is used to generate DataPtr which have arbitrary +// std::function deleters associated with them. In some user facing +// functions, we give a (user-friendly) interface for constructing +// tensors from external data which take an arbitrary std::function +// deleter. Grep for InefficientStdFunctionContext to find these +// occurrences. +// +// This context is inefficient because we have to do a dynamic +// allocation InefficientStdFunctionContext, on top of the dynamic +// allocation which is implied by std::function itself. +struct C10_API InefficientStdFunctionContext { + void* ptr_{nullptr}; + std::function deleter_; + InefficientStdFunctionContext(void* ptr, std::function deleter) + : ptr_(ptr), deleter_(std::move(deleter)) {} + InefficientStdFunctionContext(const InefficientStdFunctionContext&) = delete; + InefficientStdFunctionContext(InefficientStdFunctionContext&& rhs) noexcept + : ptr_(std::exchange(rhs.ptr_, nullptr)), + deleter_(std::move(rhs.deleter_)) {} + InefficientStdFunctionContext& operator=( + const InefficientStdFunctionContext&) = delete; + // NOLINTNEXTLINE(*-noexcept-move-*) + InefficientStdFunctionContext& operator=( + InefficientStdFunctionContext&& rhs) { + this->~InefficientStdFunctionContext(); + ptr_ = std::exchange(rhs.ptr_, nullptr); + deleter_ = std::move(rhs.deleter_); + return *this; + } + ~InefficientStdFunctionContext() { + if (deleter_) { + deleter_(ptr_); + } + } + static DataPtr makeDataPtr( + void* ptr, + std::function deleter, + Device device); +}; + +/** Set the allocator for DeviceType `t`. The passed in allocator pointer is + * expected to have static lifetime; this function does NOT take ownership + * of the raw pointer. (The reason for this is to prevent existing pointers + * to an allocator of a particular device from being invalidated when + * SetAllocator is called.) + * + * Also note that this is not thread-safe, and we assume this function will + * only be called during initialization. + * + * The 'priority' flag is introduced when we want to overwrite the default + * allocator, since the allocators are set statically. The default priority + * is 0, which means the lowest. Only higher or equal priority can overwrite + * existing ones. + */ +C10_API void SetAllocator(DeviceType t, Allocator* alloc, uint8_t priority = 0); +C10_API Allocator* GetAllocator(const DeviceType& t); + +template +struct AllocatorRegisterer { + explicit AllocatorRegisterer(Allocator* alloc) { + SetAllocator(t, alloc); + } +}; + +#define REGISTER_ALLOCATOR(t, f) \ + namespace { \ + static c10::AllocatorRegisterer g_allocator_d(f); \ + } + +// An interface for reporting thread local memory usage +// per device +struct C10_API MemoryReportingInfoBase : public c10::DebugInfoBase { + /** + * alloc_size corresponds to the size of the ptr. + * + * total_allocated corresponds to total allocated memory. + * + * total_reserved corresponds to total size of memory pool, both used and + * unused, if applicable. + */ + virtual void reportMemoryUsage( + void* ptr, + int64_t alloc_size, + size_t total_allocated, + size_t total_reserved, + Device device) = 0; + + virtual void reportOutOfMemory( + int64_t alloc_size, + size_t total_allocated, + size_t total_reserved, + Device device); + + virtual bool memoryProfilingEnabled() const = 0; +}; + +C10_API bool memoryProfilingEnabled(); +C10_API void reportMemoryUsageToProfiler( + void* ptr, + int64_t alloc_size, + size_t total_allocated, + size_t total_reserved, + Device device); + +C10_API void reportOutOfMemoryToProfiler( + int64_t alloc_size, + size_t total_allocated, + size_t total_reserved, + Device device); + +// used to hold traceback information in allocators +// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions) +struct GatheredContext { + virtual ~GatheredContext() = default; +}; + +namespace CachingAllocator { +struct Stat { + void increase(size_t amount) { + current += static_cast(amount); + peak = std::max(current, peak); + allocated += static_cast(amount); + } + + void decrease(size_t amount) { + current -= static_cast(amount); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + current >= 0, + "Negative tracked stat in device allocator (likely logic error)."); + freed += static_cast(amount); + } + + void reset_accumulated() { + allocated = 0; + freed = 0; + } + + void reset_peak() { + peak = current; + } + + int64_t current = 0; + int64_t peak = 0; + int64_t allocated = 0; + int64_t freed = 0; +}; + +enum struct StatType : uint64_t { + AGGREGATE = 0, + SMALL_POOL = 1, + LARGE_POOL = 2, + NUM_TYPES = 3 // remember to update this whenever a new stat type is added +}; + +using StatArray = std::array(StatType::NUM_TYPES)>; +using StatTypes = std::array(StatType::NUM_TYPES)>; + +template +void for_each_selected_stat_type(const StatTypes& stat_types, Func f) { + for (const auto stat_type : c10::irange(stat_types.size())) { + if (stat_types[stat_type]) { + f(stat_type); + } + } +} + +// Structure for keeping timing information +struct DurationStat { + void increase(int64_t amount) { + total += amount; + count += 1; + max = std::max(amount, max); + if (min == 0) { + min = amount; + } else { + min = std::min(amount, min); + } + } + + void reset_accumulated() { + total = 0; + count = 0; + } + + void reset_peak() { + min = 0; + max = 0; + } + + int64_t total = 0; + int64_t max = 0; + int64_t min = 0; + int64_t count = 0; +}; + +// Size pretty-printer +inline std::string format_size(uint64_t size) { + std::ostringstream os; + os.precision(2); + os << std::fixed; + if (size <= 1024) { + os << size << " bytes"; + } else if (size <= 1048576) { + os << (static_cast(size) / 1024.0); + os << " KiB"; + } else if (size <= 1073741824ULL) { + os << static_cast(size) / 1048576.0; + os << " MiB"; + } else { + os << static_cast(size) / 1073741824.0; + os << " GiB"; + } + return os.str(); +} + +} // namespace CachingAllocator +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/AllocatorConfig.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/AllocatorConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..d683f98a5022c1c0eb5a67a677f31b8da530b016 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/AllocatorConfig.h @@ -0,0 +1,399 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace c10::CachingAllocator { + +// "small" allocations are packed in 2 MiB blocks +constexpr size_t kSmallBuffer = 2097152; +// all sizes are rounded to at least 512 bytes +constexpr size_t kMinBlockSize = 512; +// largest "small" allocation is 1 MiB +constexpr size_t kSmallSize = 1048576; +// allocations between 1 and 10 MiB may use kLargeBuffer +constexpr size_t kMinLargeAlloc = 10485760; +// round up large allocations to 2 MiB +constexpr size_t kRoundLarge = 2097152; + +// A utility class for tokenizing allocator configuration strings into discrete +// parts. For example, the config string: +// "key1:val1,key2:[val2,val3]" +// is tokenized into: +// "key1", ":", "val1", ",", "key2", ":", "[", "val2", ",", "val3", "]", +// +// Tokens include keys, values, and special characters (':', ',', '[', ']'). +// Whitespace is ignored. +class ConfigTokenizer { + public: + explicit ConfigTokenizer(const std::string& env) { + std::string buffer; + for (char ch : env) { + if (ch == ',' || ch == ':' || ch == '[' || ch == ']') { + if (!buffer.empty()) { + config_.emplace_back(std::move(buffer)); + buffer.clear(); + } + config_.emplace_back(1, ch); + } else if (!std::isspace(static_cast(ch))) { + buffer += ch; + } + } + if (!buffer.empty()) { + config_.emplace_back(std::move(buffer)); + } + } + + const std::string& operator[](size_t i) const { + TORCH_INTERNAL_ASSERT( + i < config_.size(), "Index out of bounds in ConfigTokenizer"); + return config_[i]; + } + + size_t size() const { + return config_.size(); + } + + bool checkToken(size_t i, const std::string& token) const { + checkIndex(i); + return config_[i] == token; + } + + size_t toSizeT(size_t i) const { + checkIndex(i); + return std::stoull(config_[i]); + } + + double toDouble(size_t i) const { + checkIndex(i); + return std::stod(config_[i]); + } + + bool toBool(size_t i) const { + checkIndex(i); + const auto& token = config_[i]; + if (token == "True") { + return true; + } else if (token == "False") { + return false; + } else { + TORCH_CHECK_VALUE( + false, + "Expected 'True' or 'False' at index ", + i, + " in ConfigTokenizer but got '", + token, + "'"); + } + } + + // Skips the current token group and returns the index of the value token. + // Assumes the current index `i` points to a key name in a key-value pair. + size_t skipKey(size_t i) const { + // Expect a colon after the key + checkToken(++i, ":"); + + ++i; // Move to the value + checkIndex(i); + if (config_[i] != "[") { + // Value is a single token (not a list) -> return its index + return i; + } + + // Skip tokens inside the list until matching ']' + // NOLINTNEXTLINE(bugprone-inc-dec-in-conditions) + while (++i < config_.size() && config_[i] != "]") { + } + + TORCH_INTERNAL_ASSERT( + i < config_.size(), + "Expected closing bracket ']' in ConfigTokenizer but reached end of config"); + + return i; // Return the index of the closing ']' + } + + private: + void checkIndex(size_t i) const { + TORCH_INTERNAL_ASSERT( + i < config_.size(), "Index out of bounds in ConfigTokenizer"); + } + + std::vector config_; +}; + +/** + * Note [AcceleratorAllocatorConfig design] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This class configures memory allocation for both device and host memory. A + * single `AcceleratorAllocatorConfig` instance is shared across all accelerator + * backends, such as CUDA and XPU, under the assumption that relevant + * environment variables apply uniformly to all accelerators. Device-specific + * configuration extensions are supported via hooks (see + * `registerDeviceConfigParserHook`). + * + * Recommended design: + * - Place common configurations in `AcceleratorAllocatorConfig`. + * - Extend backend-specific configurations in corresponding device-specific + * classes, such as `CUDAAllocatorConfig`, etc. + * + * Scope: + * - Configuration options must be environment-variable driven. + * + * Naming Convention: + * - Public API names in `AcceleratorAllocatorConfig` should be device-generic. + * - Members prefixed with `pinned_` are specific to the host/pinned allocator. + * - Environment variable names should be generic across backends. + * - Comma-separated key-value pairs in the format: `key:value`. Use square + * brackets `[]` for list values Example: `key1:123, key2:[val1,val2]` + * + * Environment Variables: + * - The primary environment variable for configuration is `PYTORCH_ALLOC_CONF`. + * - For backward compatibility, `PYTORCH_CUDA_ALLOC_CONF` is also supported + * with lower priority. + */ + +class C10_API AcceleratorAllocatorConfig { + public: + static AcceleratorAllocatorConfig& instance(); + + C10_DISABLE_COPY_AND_ASSIGN(AcceleratorAllocatorConfig); + AcceleratorAllocatorConfig(AcceleratorAllocatorConfig&&) = delete; + AcceleratorAllocatorConfig& operator=(AcceleratorAllocatorConfig&&) = delete; + ~AcceleratorAllocatorConfig() = default; + + /* Device allocator settings */ + + static size_t large_segment_size() { + return instance().large_segment_size_; + } + + // Returns the maximum block size (in MB) that is allowed to be split. The + // default is unlimited (all blocks can be split). + static size_t max_split_size() { + return instance().max_split_size_; + } + + // Returns the maximum block size (in MB) that is allowed to be rounded up + // without requiring splitting when searching for a free block. The default is + // 20 MiB. + static size_t max_non_split_rounding_size() { + return instance().max_non_split_rounding_size_; + } + + // Return the number of divisions used when rounding up allocation sizes (in + // MB) to the nearest power-of-2 boundary. + static size_t roundup_power2_divisions(size_t size); + + // Returns the vector of division factors used for rounding up allocation + // sizes. These divisions apply to size intervals between 1MB and 64GB. + static const std::vector& roundup_power2_divisions() { + return instance().roundup_power2_divisions_; + } + + // Returns the threshold that triggers garbage collection when the ratio of + // used memory to maximum allowed memory exceeds this value. The default is 0, + // meaning no garbage collection is triggered. The value should be in the + // range (0.0, 1.0). + static double garbage_collection_threshold() { + return instance().garbage_collection_threshold_; + } + + // Returns whether the expandable segment feature is enabled. This allows the + // allocator to start with one segment that grows as needed, rather than + // creating a new segment for each allocation. Default is false (expandable + // segments disabled). + static bool use_expandable_segments() { + return instance().use_expandable_segments_; + } + + /* Host allocator settings */ + + // Returns whether the pinned host allocator uses background threads for + // processing events. This is useful for improving performance in scenarios + // where many small allocations are made. Default is false (background threads + // disabled). + static bool pinned_use_background_threads() { + return instance().pinned_use_background_threads_; + } + + /* Settings for both device and host allocator */ + + // Returns the current allocator settings as a string. This string is useful + // to expand device-specific allocator configurations + static std::string last_allocator_settings() { + std::lock_guard lock(instance().last_allocator_settings_mutex_); + return instance().last_allocator_settings_; + } + + // Use `Construct On First Use Idiom` to avoid `Static Initialization Order` + // issue. + static std::unordered_set& getMutableKeys() { + static std::unordered_set keys{ + "large_segment_size_mb", + "max_split_size_mb", + "max_non_split_rounding_mb", + "garbage_collection_threshold", + "roundup_power2_divisions", + "expandable_segments", + "pinned_use_background_threads"}; + return keys; + } + + // Returns the set of valid keys for the allocator configuration. + // This set is used to validate the presence and correctness of keys in + // device-specific configuration parsers. + static const std::unordered_set& getKeys() { + return getMutableKeys(); + } + + // Optional hook for parsing additional device-specific allocator settings. + // This allows backends (e.g., CUDA, XPU) to register a custom parser for + // their own environment configuration extensions. + static std::function& getConfigParserHook() { + static std::function hook{nullptr}; + return hook; + } + + // Registers a device-specific configuration parser hook and its key. This + // allows backends to parse additional device-specific configuration options + // from the environment variable. The hook should be a function that takes a + // string (the environment variable value) and parses it to set + // device-specific configuration options. The hook will be called when the + // environment variable is parsed. If a hook is already registered, it will be + // replaced with the new one. + static void registerDeviceConfigParserHook( + std::function&& hook, + const std::unordered_set& keys) { + getConfigParserHook() = std::move(hook); + auto& mutable_keys = getMutableKeys(); + for (auto& key : keys) { + TORCH_CHECK_VALUE( + mutable_keys.insert(key).second, + "Duplicated key '", + key, + "' found in device-specific configuration parser hook registration"); + } + } + + // Calls the registered device-specific configuration parser hook with the + // provided environment string. This allows backends to parse additional + // device-specific configuration options from the environment variable. + // If no hook is registered, this function does nothing. + static void callDeviceConfigParserHook(const std::string& env) { + if (getConfigParserHook()) { + getConfigParserHook()(env); + } + } + + // Parses the environment variable `env` to update the allocator settings. + // If the environment variable is not set, it does nothing. + // The configuration string should be a comma-separated list of key-value + // pairs, where each key is a configuration option and the value is the + // corresponding setting. For example: + // "max_split_size_mb:100,max_non_split_rounding_mb:20,garbage_collection_threshold:0.5,roundup_power2_divisions:[64:8,256:4,1024:4,>:1],expandable_segments:true,pinned_use_background_threads:true" + void parseArgs(const std::string& env); + + private: + AcceleratorAllocatorConfig(); + + /* Internal functions for device allocator */ + + // Parse `large_segment_size_mb` from environment variable. + size_t parseLargeSegmentSize(const ConfigTokenizer& tokenizer, size_t i); + // Parse `max_split_size_mb` from environment variable. + size_t parseMaxSplitSize(const ConfigTokenizer& tokenizer, size_t i); + // Parse `max_non_split_rounding_mb` from environment variable. + size_t parseMaxNonSplitRoundingSize( + const ConfigTokenizer& tokenizer, + size_t i); + // Parse `garbage_collection_threshold` from environment variable. + size_t parseGarbageCollectionThreshold( + const ConfigTokenizer& tokenizer, + size_t i); + // Parse `roundup_power2_divisions` from environment variable. + size_t parseRoundUpPower2Divisions( + const ConfigTokenizer& tokenizer, + size_t i); + // Parse `expandable_segments` from environment variable. + size_t parseExpandableSegments(const ConfigTokenizer& tokenizer, size_t i); + + /* Internal functions for host allocator */ + + // Parse `pinned_use_background_threads` from environment variable. + size_t parsePinnedUseBackgroundThreads( + const ConfigTokenizer& tokenizer, + size_t i); + + /* The following members are specifically used for the device allocator. */ + + // "large" allocations may be packed in blocks of this size + std::atomic large_segment_size_{20971520}; // 20 MB by default + // The maximum block size that is allowed to be split. + std::atomic max_split_size_{std::numeric_limits::max()}; + // The maximum allowable extra size of a memory block without requiring + // splitting when searching for a free block. + std::atomic max_non_split_rounding_size_; + // Used to store how memory allocations of different sizes should be rounded + // up to the nearest power of 2 divisions. + std::vector roundup_power2_divisions_; + // The threshold that triggers garbage collection when the ratio of used + // memory to maximum allowed memory exceeds this value. + std::atomic garbage_collection_threshold_{0}; + // A flag to enable expandable segments feature. + std::atomic use_expandable_segments_{false}; + + /* The following members are specifically used for the host allocator. */ + + // A flag to enable background thread for processing events. + std::atomic pinned_use_background_threads_{false}; + + /* The following members are used for both device and host allocator. */ + + // Record the last allocator config environment setting. + std::mutex last_allocator_settings_mutex_; + std::string last_allocator_settings_; +}; + +C10_API inline void setAllocatorSettings(const std::string& env) { + AcceleratorAllocatorConfig::instance().parseArgs(env); + AcceleratorAllocatorConfig::callDeviceConfigParserHook(env); +} + +C10_API inline std::string getAllocatorSettings() { + return AcceleratorAllocatorConfig::instance().last_allocator_settings(); +} + +struct DeviceConfigParserHookRegistry { + explicit DeviceConfigParserHookRegistry( + std::function&& hook, + const std::unordered_set& keys) { + // Use static method to avoid static initialization order fiasco issues + AcceleratorAllocatorConfig::registerDeviceConfigParserHook( + std::move(hook), keys); + } +}; + +// Assume each config parser has `parseArgs` and `getKeys` methods +#define REGISTER_ALLOCATOR_CONFIG_PARSE_HOOK(parser_cls) \ + namespace { \ + static at::CachingAllocator::DeviceConfigParserHookRegistry \ + g_device_config_parse_hook_registry_instance( \ + [](const std::string& env) { \ + parser_cls::instance().parseArgs(env); \ + }, \ + parser_cls::getKeys()); \ + } + +} // namespace c10::CachingAllocator + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/AutogradState.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/AutogradState.h new file mode 100644 index 0000000000000000000000000000000000000000..9d596b01d233dad00702dcad5269f146672861c5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/AutogradState.h @@ -0,0 +1,90 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10 { + +// Structure used to pack all the thread local boolean +// flags used by autograd +struct C10_API AutogradState { + static AutogradState& get_tls_state(); + static void set_tls_state(AutogradState state); + + AutogradState( + bool grad_mode, + bool inference_mode, + bool fw_grad_mode, + bool multithreading_enabled) + : graph_exec_group_(std::nullopt), + grad_mode_(grad_mode), + inference_mode_(inference_mode), + fw_grad_mode_(fw_grad_mode), + multithreading_enabled_(multithreading_enabled), + view_replay_enabled_(false) {} + + void set_grad_mode(bool enabled) { + grad_mode_ = enabled; + } + + void set_fw_grad_mode(bool enabled) { + fw_grad_mode_ = enabled; + } + + void set_inference_mode(bool enabled) { + inference_mode_ = enabled; + } + + void set_multithreading_enabled(bool multithreading_enabled) { + multithreading_enabled_ = multithreading_enabled; + } + + void set_view_replay_enabled(bool view_replay_enabled) { + view_replay_enabled_ = view_replay_enabled; + } + + void set_graph_exec_group(std::optional group) { + graph_exec_group_ = std::move(group); + } + + bool get_grad_mode() const { + return grad_mode_; + } + + bool get_fw_grad_mode() const { + return fw_grad_mode_; + } + + bool get_inference_mode() const { + return inference_mode_; + } + + bool get_multithreading_enabled() const { + return multithreading_enabled_; + } + + bool get_view_replay_enabled() const { + return view_replay_enabled_; + } + + const std::optional& get_graph_exec_group() const { + return graph_exec_group_; + } + + private: + std::optional graph_exec_group_; + bool grad_mode_ : 1; + bool inference_mode_ : 1; + bool fw_grad_mode_ : 1; + bool multithreading_enabled_ : 1; + // NOLINTNEXTLINE(cppcoreguidelines-use-default-member-init) + bool view_replay_enabled_ : 1; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Backend.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Backend.h new file mode 100644 index 0000000000000000000000000000000000000000..d26c0089ae024b876be0df2821e3f562737ff35d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Backend.h @@ -0,0 +1,414 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +#include + +C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-enum") + +namespace c10 { + +/** + * This legacy enum class defines the set of backends supported by old school, + * code generated Type-based ATen. A "backend" in this sense roughly + * corresponds to the cartesian product of (device type, layout), but restricted + * only to combinations which we actually have kernels for. Backend does NOT + * include dtype. + * + * The reason we are sunsetting this enum class is because it doesn't allow for + * open registration; e.g., if you want to add SparseXLA, you'd have to + * edit this enum; you wouldn't be able to do it out of tree. DispatchKey is + * the replacement for Backend which supports open registration. + * + * NB: The concept of 'Backend' here disagrees with the notion of backend + * exposed to users in torch.backends. Backend here is something like "CPU" + * or "SparseCUDA"; backend in torch.backends is something like "MKL" or + * "CUDNN". + */ +enum class Backend { + CPU, + CUDA, + HIP, + VE, + FPGA, + IPU, + XPU, + SparseCPU, + SparseCUDA, + SparseCsrCPU, + SparseCsrCUDA, + SparseCsrMPS, + SparseMPS, + SparseHIP, + SparseVE, + SparseXPU, + SparsePrivateUse1, + SparseCsrHIP, + SparseCsrVE, + SparseCsrXPU, + SparseCsrPrivateUse1, + MAIA, + XLA, + Vulkan, + Metal, + Meta, + QuantizedCPU, + QuantizedCUDA, + QuantizedXPU, + QuantizedPrivateUse1, + Undefined, + MkldnnCPU, + MPS, + HPU, + Lazy, + MTIA, + PrivateUse1, + NumOptions +}; + +inline Backend dispatchKeyToBackend(DispatchKey t) { + if (t == DispatchKey::CPU || t == DispatchKey::AutogradCPU) { + return Backend::CPU; + } else if (t == DispatchKey::CUDA || t == DispatchKey::AutogradCUDA) { + return Backend::CUDA; + } else if (t == DispatchKey::HIP) { + return Backend::HIP; + } else if (t == DispatchKey::VE) { + return Backend::VE; + } else if (t == DispatchKey::FPGA) { + return Backend::FPGA; + } else if (t == DispatchKey::MAIA || t == DispatchKey::AutogradMAIA) { + return Backend::MAIA; + } else if (t == DispatchKey::XLA || t == DispatchKey::AutogradXLA) { + return Backend::XLA; + } else if (t == DispatchKey::Lazy || t == DispatchKey::AutogradLazy) { + return Backend::Lazy; + } else if (t == DispatchKey::MPS || t == DispatchKey::AutogradMPS) { + return Backend::MPS; + } else if (t == DispatchKey::Vulkan) { + return Backend::Vulkan; + } else if (t == DispatchKey::Metal) { + return Backend::Metal; + } else if (t == DispatchKey::Meta) { + return Backend::Meta; + } else if (t == DispatchKey::SparseCPU) { + return Backend::SparseCPU; + } else if (t == DispatchKey::SparseCUDA) { + return Backend::SparseCUDA; + } else if (t == DispatchKey::SparseMPS) { + return Backend::SparseMPS; + } else if (t == DispatchKey::SparseCsrMPS) { + return Backend::SparseCsrMPS; + } else if (t == DispatchKey::SparseHIP) { + return Backend::SparseHIP; + } else if (t == DispatchKey::SparseVE) { + return Backend::SparseVE; + } else if (t == DispatchKey::SparsePrivateUse1) { + return Backend::SparsePrivateUse1; + } else if (t == DispatchKey::SparseCsrCPU) { + return Backend::SparseCsrCPU; + } else if (t == DispatchKey::SparseCsrCUDA) { + return Backend::SparseCsrCUDA; + } else if (t == DispatchKey::SparseCsrHIP) { + return Backend::SparseCsrHIP; + } else if (t == DispatchKey::SparseCsrVE) { + return Backend::SparseCsrVE; + } else if (t == DispatchKey::SparseCsrPrivateUse1) { + return Backend::SparseCsrPrivateUse1; + } else if (t == DispatchKey::MkldnnCPU) { + return Backend::MkldnnCPU; + } else if (t == DispatchKey::QuantizedCPU) { + return Backend::QuantizedCPU; + } else if (t == DispatchKey::QuantizedCUDA) { + return Backend::QuantizedCUDA; + } else if (t == DispatchKey::IPU || t == DispatchKey::AutogradIPU) { + return Backend::IPU; + } else if (t == DispatchKey::XPU || t == DispatchKey::AutogradXPU) { + return Backend::XPU; + } else if (t == DispatchKey::SparseXPU) { + return Backend::SparseXPU; + } else if (t == DispatchKey::SparseCsrXPU) { + return Backend::SparseCsrXPU; + } else if (t == DispatchKey::QuantizedXPU) { + return Backend::QuantizedXPU; + } else if (t == DispatchKey::QuantizedPrivateUse1) { + return Backend::QuantizedPrivateUse1; + } else if (t == DispatchKey::HPU || t == DispatchKey::AutogradHPU) { + return Backend::HPU; + } else if (t == DispatchKey::MTIA || t == DispatchKey::AutogradMTIA) { + return Backend::MTIA; + } else if ( + t == DispatchKey::PrivateUse1 || t == DispatchKey::AutogradPrivateUse1) { + return Backend::PrivateUse1; + } else if (t == DispatchKey::Undefined) { + return Backend::Undefined; + } else { + TORCH_CHECK(false, "Unrecognized tensor type ID: ", t); + } +} + +inline DispatchKey backendToDispatchKey(Backend b) { + switch (b) { + case Backend::CPU: + return DispatchKey::CPU; + case Backend::CUDA: + return DispatchKey::CUDA; + case Backend::HIP: + return DispatchKey::HIP; + case Backend::VE: + return DispatchKey::VE; + case Backend::FPGA: + return DispatchKey::FPGA; + case Backend::MAIA: + return DispatchKey::MAIA; + case Backend::XLA: + return DispatchKey::XLA; + case Backend::Lazy: + return DispatchKey::Lazy; + case Backend::IPU: + return DispatchKey::IPU; + case Backend::XPU: + return DispatchKey::XPU; + case Backend::SparseXPU: + return DispatchKey::SparseXPU; + case Backend::SparseCsrXPU: + return DispatchKey::SparseCsrXPU; + case Backend::SparseCPU: + return DispatchKey::SparseCPU; + case Backend::SparseCUDA: + return DispatchKey::SparseCUDA; + case Backend::SparseMPS: + return DispatchKey::SparseMPS; + case Backend::SparseCsrMPS: + return DispatchKey::SparseCsrMPS; + case Backend::SparseHIP: + return DispatchKey::SparseHIP; + case Backend::SparseVE: + return DispatchKey::SparseVE; + case Backend::SparsePrivateUse1: + return DispatchKey::SparsePrivateUse1; + case Backend::SparseCsrCPU: + return DispatchKey::SparseCsrCPU; + case Backend::SparseCsrCUDA: + return DispatchKey::SparseCsrCUDA; + case Backend::SparseCsrHIP: + return DispatchKey::SparseCsrHIP; + case Backend::SparseCsrVE: + return DispatchKey::SparseCsrVE; + case Backend::SparseCsrPrivateUse1: + return DispatchKey::SparseCsrPrivateUse1; + case Backend::MkldnnCPU: + return DispatchKey::MkldnnCPU; + case Backend::Vulkan: + return DispatchKey::Vulkan; + case Backend::Metal: + return DispatchKey::Metal; + case Backend::Meta: + return DispatchKey::Meta; + case Backend::QuantizedCPU: + return DispatchKey::QuantizedCPU; + case Backend::QuantizedCUDA: + return DispatchKey::QuantizedCUDA; + case Backend::QuantizedPrivateUse1: + return DispatchKey::QuantizedPrivateUse1; + case Backend::Undefined: + return DispatchKey::Undefined; + case Backend::MPS: + return DispatchKey::MPS; + case Backend::HPU: + return DispatchKey::HPU; + case Backend::MTIA: + return DispatchKey::MTIA; + case Backend::PrivateUse1: + return DispatchKey::PrivateUse1; + default: + TORCH_CHECK(false, "Unknown backend"); + } +} + +inline DeviceType backendToDeviceType(Backend b) { + switch (b) { + case Backend::CPU: + case Backend::MkldnnCPU: + case Backend::SparseCPU: + case Backend::SparseCsrCPU: + case Backend::QuantizedCPU: + return DeviceType::CPU; + case Backend::CUDA: + case Backend::SparseCUDA: + case Backend::QuantizedCUDA: + case Backend::SparseCsrCUDA: + return DeviceType::CUDA; + case Backend::HIP: + return DeviceType::HIP; + case Backend::VE: + return DeviceType::VE; + case Backend::FPGA: + return DeviceType::FPGA; + case Backend::MAIA: + return DeviceType::MAIA; + case Backend::XLA: + return DeviceType::XLA; + case Backend::Lazy: + return DeviceType::Lazy; + case Backend::SparseHIP: + return DeviceType::HIP; + case Backend::SparseVE: + return DeviceType::VE; + case Backend::SparseCsrHIP: + return DeviceType::HIP; + case Backend::SparseCsrVE: + return DeviceType::VE; + case Backend::IPU: + return DeviceType::IPU; + case Backend::XPU: + case Backend::SparseXPU: + case Backend::SparseCsrXPU: + case Backend::QuantizedXPU: + return DeviceType::XPU; + case Backend::Vulkan: + return DeviceType::Vulkan; + case Backend::Metal: + return DeviceType::Metal; + case Backend::Meta: + return DeviceType::Meta; + case Backend::MPS: + case Backend::SparseMPS: + case Backend::SparseCsrMPS: + return DeviceType::MPS; + case Backend::HPU: + return DeviceType::HPU; + case Backend::MTIA: + return DeviceType::MTIA; + case Backend::PrivateUse1: + case Backend::SparsePrivateUse1: + case Backend::SparseCsrPrivateUse1: + case Backend::QuantizedPrivateUse1: + return DeviceType::PrivateUse1; + case Backend::Undefined: + TORCH_CHECK(false, "Undefined backend is not a valid device type"); + default: + TORCH_CHECK(false, "Unknown backend"); + } +} + +inline const char* toString(Backend b) { + switch (b) { + case Backend::CPU: + return "CPU"; + case Backend::CUDA: + return "CUDA"; + case Backend::HIP: + return "HIP"; + case Backend::VE: + return "VE"; + case Backend::FPGA: + return "FPGA"; + case Backend::XPU: + return "XPU"; + case Backend::IPU: + return "IPU"; + case Backend::MAIA: + return "MAIA"; + case Backend::XLA: + return "XLA"; + case Backend::Lazy: + return "Lazy"; + case Backend::MPS: + return "MPS"; + case Backend::SparseCPU: + return "SparseCPU"; + case Backend::SparseCUDA: + return "SparseCUDA"; + case Backend::SparseMPS: + return "SparseMPS"; + case Backend::SparseCsrMPS: + return "SparseCsrMPS"; + case Backend::SparseHIP: + return "SparseHIP"; + case Backend::SparseVE: + return "SparseVE"; + case Backend::SparseXPU: + return "SparseXPU"; + case Backend::SparsePrivateUse1: + return "SparsePrivateUse1"; + case Backend::SparseCsrCPU: + return "SparseCsrCPU"; + case Backend::SparseCsrCUDA: + return "SparseCsrCUDA"; + case Backend::SparseCsrHIP: + return "SparseCsrHIP"; + case Backend::SparseCsrVE: + return "SparseCsrVE"; + case Backend::SparseCsrXPU: + return "SparseCsrXPU"; + case Backend::SparseCsrPrivateUse1: + return "SparseCsrPrivateUse1"; + case Backend::MkldnnCPU: + return "MkldnnCPU"; + case Backend::Vulkan: + return "Vulkan"; + case Backend::Metal: + return "Metal"; + case Backend::Meta: + return "Meta"; + case Backend::QuantizedCPU: + return "QuantizedCPU"; + case Backend::QuantizedCUDA: + return "QuantizedCUDA"; + case Backend::QuantizedXPU: + return "QuantizedXPU"; + case Backend::QuantizedPrivateUse1: + return "QuantizedPrivateUse1"; + case Backend::HPU: + return "HPU"; + case Backend::MTIA: + return "MTIA"; + case Backend::PrivateUse1: + return "PrivateUseOne"; + default: + return "UNKNOWN_BACKEND"; + } +} + +inline bool isSparse(Backend b) { + switch (b) { + case Backend::SparseXPU: + case Backend::SparseCPU: + case Backend::SparseCUDA: + case Backend::SparseMPS: + case Backend::SparseHIP: + case Backend::SparseVE: + case Backend::SparsePrivateUse1: + return true; + default: + return false; + } +} + +inline bool isSparseCsr(Backend b) { + switch (b) { + case Backend::SparseCsrXPU: + case Backend::SparseCsrCPU: + case Backend::SparseCsrCUDA: + case Backend::SparseCsrHIP: + case Backend::SparseCsrVE: + case Backend::SparseCsrPrivateUse1: + return true; + default: + return false; + } +} + +} // namespace c10 + +C10_DIAGNOSTIC_POP() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CPUAllocator.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CPUAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..d43d48e32ee794092b23a488cbb8518a6d5d2623 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CPUAllocator.h @@ -0,0 +1,64 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +// TODO: rename to c10 +C10_DECLARE_bool(caffe2_report_cpu_memory_usage); + +namespace c10 { + +using MemoryDeleter = void (*)(void*); + +// A helper function that is basically doing nothing. +C10_API void NoDelete(void* /*unused*/); + +// A simple struct that is used to report C10's memory allocation, +// deallocation status and out-of-memory events to the profiler +class C10_API ProfiledCPUMemoryReporter { + public: + ProfiledCPUMemoryReporter() = default; + void New(void* ptr, size_t nbytes); + void OutOfMemory(size_t nbytes); + void Delete(void* ptr); + + private: + std::mutex mutex_; + std::unordered_map size_table_; + size_t allocated_ = 0; + size_t log_cnt_ = 0; +}; + +C10_API ProfiledCPUMemoryReporter& profiledCPUMemoryReporter(); + +// Get the CPU Allocator. +C10_API at::Allocator* GetCPUAllocator(); +// Sets the CPU allocator to the given allocator: the caller gives away the +// ownership of the pointer. +C10_API void SetCPUAllocator(at::Allocator* alloc, uint8_t priority = 0); + +// Get the Default CPU Allocator +C10_API at::Allocator* GetDefaultCPUAllocator(); + +// Get the Default Mobile CPU Allocator +C10_API at::Allocator* GetDefaultMobileCPUAllocator(); + +// The CPUCachingAllocator is experimental and might disappear in the future. +// The only place that uses it is in StaticRuntime. +// Set the CPU Caching Allocator +C10_API void SetCPUCachingAllocator(Allocator* alloc, uint8_t priority = 0); +// Get the CPU Caching Allocator +C10_API Allocator* GetCPUCachingAllocator(); + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CachingDeviceAllocator.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CachingDeviceAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..9c51ea8a30ff6938427ffa71794f4ef129888c80 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CachingDeviceAllocator.h @@ -0,0 +1,265 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10::CachingDeviceAllocator { + +using namespace c10::CachingAllocator; + +// Struct containing memory allocator summary statistics for a device. +struct DeviceStats { + // COUNT: allocations requested by client code + StatArray allocation; + // COUNT: number of allocated segments from device memory allocation. + StatArray segment; + // COUNT: number of active memory blocks (allocated or used by stream) + StatArray active; + // COUNT: number of inactive, split memory blocks (unallocated but can't be + // released via device memory deallocation) + StatArray inactive_split; + + // SUM: bytes allocated by this memory allocator + StatArray allocated_bytes; + // SUM: bytes reserved by this memory allocator (both free and used) + StatArray reserved_bytes; + // SUM: bytes within active memory blocks + StatArray active_bytes; + // SUM: bytes within inactive, split memory blocks + StatArray inactive_split_bytes; + // SUM: bytes requested by client code + StatArray requested_bytes; + + // COUNT: total number of failed calls to device malloc necessitating cache + // flushes. + int64_t num_alloc_retries = 0; + + // COUNT: total number of OOMs (i.e. failed calls to device memory allocation + // after cache flush) + int64_t num_ooms = 0; + + // COUNT: total number of oversize blocks allocated from pool + Stat oversize_allocations; + + // COUNT: total number of oversize blocks requiring malloc + Stat oversize_segments; + + // COUNT: total number of synchronize_and_free_events() calls + int64_t num_sync_all_streams = 0; + + // COUNT: total number of device memory allocation calls. This includes both + // mapped and malloced memory. + int64_t num_device_alloc = 0; + + // COUNT: total number of device memory deallocation calls. This includes both + // un-mapped and free memory. + int64_t num_device_free = 0; + + // COUNT: total number of allocations rejected by OOM preemption policy + int64_t num_oom_rejections = 0; + + // SIZE: maximum block size that is allowed to be split. + int64_t max_split_size = 0; +}; + +using CreateContextFn = std::shared_ptr (*)(); + +enum struct RecordContext { + NEVER = 0, + STATE = 1, // only keep stacks for active allocations + ALLOC = 2, // additionally keep stacks for allocations in the trace history + ALL = 3, // additionally record stacks for when something is freed +}; + +// Struct containing information about an allocation block, i.e., a subrange +// of a device allocation (such as one obtained via cudaMalloc). +struct BlockInfo { + size_t size = 0; + size_t requested_size = 0; + int32_t gc_counter = 0; + bool allocated = false; + bool active = false; + std::shared_ptr + context_when_allocated; // per-watcher context +}; + +// Struct holding information about a memory segment (i.e., a single contiguous +// device allocation, such as one created by cudaMalloc). +struct SegmentInfo { + c10::DeviceIndex device = 0; + int32_t registration_counter = -1; + size_t address = 0; + size_t total_size = 0; + size_t requested_size = 0; // Unrounded, actually requested size + size_t allocated_size = 0; + size_t active_size = 0; + void* stream = nullptr; // Records the address of the underlying stream + bool is_large = false; + bool is_expandable = false; + MempoolId_t owner_private_pool_id = {0, 0}; + std::vector blocks; + std::shared_ptr context_when_allocated; +}; + +union trace_time_ { + time_t t_; + approx_time_t approx_t_; +}; + +struct TraceEntry { + enum Action { + ALLOC, // API made to the caching allocator for new memory + FREE_REQUESTED, // API call made to the caching allocator to free memory + FREE_COMPLETED, // The allocator might have to delay a free because + // it is still in use on another stream via record_stream + // This event is generated when a free actually completes. + SEGMENT_ALLOC, // a call to device allocation to get more memory from the OS + SEGMENT_FREE, // a call to device deallocation to return memory to the OS + // (e.g. to defragment or empty_caches) + SEGMENT_MAP, // a call to cuMemMap (used with expandable_segments) + SEGMENT_UNMAP, // unmap part of a segment (used with expandable segments) + SNAPSHOT, // a call to snapshot, used to correlate memory snapshots to trace + // events + OOM // the allocator threw an OutOfMemoryError (addr_ is the amount of free + // bytes reported by device memory) + }; + TraceEntry( + Action action, + c10::DeviceIndex device, + size_t addr, + size_t size, + void* stream, + MempoolId_t mempool, + approx_time_t time, + std::shared_ptr context = nullptr, + std::string compile_context = "", + std::string user_metadata = "") + : action_(action), + device_(device), + addr_(addr), + context_(std::move(context)), + stream_(stream), + size_(size), + mempool_(std::move(mempool)), + compile_context_(std::move(compile_context)), + user_metadata_(std::move(user_metadata)) { + time_.approx_t_ = time; + } + Action action_; + c10::DeviceIndex device_; + // For most actions, this is a memory address. For OOM, it represents the + // amount of free memory (in bytes). For SNAPSHOT, it is an unused parameter + // (just set to 0). + size_t addr_; + std::shared_ptr context_; + void* stream_{}; + size_t size_; + MempoolId_t mempool_; + trace_time_ time_{}; + std::string compile_context_; + std::string user_metadata_; +}; + +inline TraceEntry::Action parseTraceEntryAction(std::string_view action) { + constexpr std::pair kActionTable[] = { + {"alloc", TraceEntry::Action::ALLOC}, + {"free_requested", TraceEntry::Action::FREE_REQUESTED}, + {"free_completed", TraceEntry::Action::FREE_COMPLETED}, + {"segment_alloc", TraceEntry::Action::SEGMENT_ALLOC}, + {"segment_free", TraceEntry::Action::SEGMENT_FREE}, + {"segment_map", TraceEntry::Action::SEGMENT_MAP}, + {"segment_unmap", TraceEntry::Action::SEGMENT_UNMAP}, + {"snapshot", TraceEntry::Action::SNAPSHOT}, + {"oom", TraceEntry::Action::OOM}, + }; + for (const auto& [k, v] : kActionTable) { + if (action == k) + return v; + } + TORCH_CHECK(false, "Unknown TraceEntry action: ", action); +} + +// Calls made by record_function will save annotations +struct AnnotationEntry { + AnnotationEntry(c10::DeviceIndex device, approx_time_t time) + : device_(device) { + time_.approx_t_ = time; + } + + void recordUserMetadata(const std::string& name, std::string value) { + metadata_[name] = std::move(value); + } + + c10::DeviceIndex device_; + trace_time_ time_{}; + std::unordered_map metadata_; +}; + +using AllocatorTraceTracker = std::function; + +} // namespace c10::CachingDeviceAllocator + +namespace c10 { + +using CaptureId_t = unsigned long long; + +// first is set if the instance is created by Graph mode capture_begin. +// second is set if the instance is created by Graph mode graph_pool_handle. +using MempoolId_t = std::pair; + +struct C10_API DeviceAllocator : public c10::Allocator { + DeviceAllocator(); + ~DeviceAllocator() override; + + // Returns true if the allocator has been properly initialized and is ready + // for use + virtual bool initialized() = 0; + + // Releases all cached device memory from the specified memory pool back to + // the system + virtual void emptyCache(MempoolId_t mempool_id = {0, 0}) = 0; + + // Associates a memory allocation with a stream to establish dependency + // tracking. Prevents memory reuse until all operations on the specified + // stream complete + virtual void recordStream(const DataPtr& ptr, c10::Stream stream) = 0; + + // Retrieves comprehensive memory statistics for the specified device, + // including allocation patterns, usage metrics + virtual CachingDeviceAllocator::DeviceStats getDeviceStats( + c10::DeviceIndex device) = 0; + + // Resets cumulative allocation statistics for the specified device to zero + virtual void resetAccumulatedStats(c10::DeviceIndex device) = 0; + + // Resets peak memory usage statistics for the specified device + virtual void resetPeakStats(c10::DeviceIndex device) = 0; + + // Return the free memory size and total memory size in bytes for the + // specified device. + virtual std::pair getMemoryInfo(c10::DeviceIndex device) { + TORCH_CHECK_NOT_IMPLEMENTED( + false, "getMemoryInfo is not implemented for this allocator yet."); + } +}; + +// This function is used to get the DeviceAllocator for a specific device type +// and keep backward compatibility with c10::GetAllocator. +C10_API inline DeviceAllocator* getDeviceAllocator(const DeviceType& t) { + TORCH_CHECK( + t != DeviceType::CPU, + "getDeviceAllocator is not supported for CPU device type."); + auto* allocator = c10::GetAllocator(t); + auto* device_allocator = dynamic_cast(allocator); + TORCH_INTERNAL_ASSERT( + device_allocator, "Allocator for ", t, " is not a DeviceAllocator."); + return device_allocator; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CompileTimeFunctionPointer.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CompileTimeFunctionPointer.h new file mode 100644 index 0000000000000000000000000000000000000000..28dd52759e8de0f4f2f2947e96ccd0dd7467a95c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CompileTimeFunctionPointer.h @@ -0,0 +1,62 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10 { + +/** + * Represent a function pointer as a C++ type. + * This allows using the function pointer as a type + * in a template and calling it from inside the template + * allows the compiler to inline the call because it + * knows the function pointer at compile time. + * + * Example 1: + * int add(int a, int b) {return a + b;} + * using Add = TORCH_FN_TYPE(add); + * template struct Executor { + * int execute(int a, int b) { + * return Func::func_ptr()(a, b); + * } + * }; + * Executor executor; + * EXPECT_EQ(3, executor.execute(1, 2)); + * + * Example 2: + * int add(int a, int b) {return a + b;} + * template int execute(Func, int a, int b) { + * return Func::func_ptr()(a, b); + * } + * EXPECT_EQ(3, execute(TORCH_FN(add), 1, 2)); + */ +template +struct CompileTimeFunctionPointer final { + static_assert( + guts::is_function_type::value, + "TORCH_FN can only wrap function types."); + using FuncType = FuncType_; + + static constexpr FuncType* func_ptr() { + return func_ptr_; + } +}; + +template +struct is_compile_time_function_pointer : std::false_type {}; +template +struct is_compile_time_function_pointer< + CompileTimeFunctionPointer> : std::true_type {}; + +} // namespace c10 + +#define TORCH_FN_TYPE(func) \ + ::c10::CompileTimeFunctionPointer< \ + std::remove_pointer_t>, \ + func> +#define TORCH_FN(func) TORCH_FN_TYPE(func)() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/ConstantSymNodeImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/ConstantSymNodeImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..f0c6266e6da1963130034ec147968310dfc9ea8a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/ConstantSymNodeImpl.h @@ -0,0 +1,117 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +// Unlike other SymNodeImpl, this cannot be "dispatched" conventionally, +// as it typically needs to defer to another SymNodeImpl +// +// Can either represent a bool, int (don't support float yet) this is useful +// for representing otherwise unrepresentable large negative integer constant. +template +class C10_API ConstantSymNodeImpl : public SymNodeImpl { + static_assert( + ::std::is_same_v || ::std::is_same_v, + "ConstantSymNodeImpl can only accept int64_t or bool types"); + + public: + ConstantSymNodeImpl(T val) : value_(val) {} + + bool is_int() override { + return is_int_(); + } + bool is_bool() override { + return is_bool_(); + } + bool is_float() override { + return false; + } + int64_t guard_int( + const char* file [[maybe_unused]], + int64_t line [[maybe_unused]]) override { + TORCH_CHECK(is_int(), "not an int"); + return int_(); + } + bool guard_bool( + const char* file [[maybe_unused]], + int64_t line [[maybe_unused]]) override { + TORCH_CHECK(is_bool(), "not a bool"); + return bool_(); + } + double guard_float( + const char* file [[maybe_unused]], + int64_t line [[maybe_unused]]) override { + TORCH_CHECK(false, "not a float"); + } + int64_t int_() override { + TORCH_CHECK(is_int(), "not an int"); + return ::std::get(value_); + } + bool bool_() override { + TORCH_CHECK(is_bool(), "not a bool"); + return ::std::get(value_); + } + bool has_hint() override { + return true; + } + c10::SymNode eq(const c10::SymNode& other) override; + c10::SymNode ne(const c10::SymNode& other) override; + c10::SymNode ge(const c10::SymNode& other) override; + c10::SymNode le(const c10::SymNode& other) override; + c10::SymNode lt(const c10::SymNode& other) override; + c10::SymNode gt(const c10::SymNode& other) override; + c10::SymNode mul(const c10::SymNode& other) override; + c10::SymNode sym_and(const c10::SymNode& other) override; + c10::SymNode sym_or(const c10::SymNode& other) override; + ::std::string str() override { + if constexpr (is_int_()) { + return ::std::to_string(::std::get(value_)); + } else { + return ::std::get(value_) ? "true" : "false"; + } + } + std::optional constant_int() override { + if constexpr (is_int_()) { + return ::std::get(value_); + } else { + return std::nullopt; + } + } + std::optional constant_bool() override { + if constexpr (is_bool_()) { + return ::std::get(value_); + } else { + return std::nullopt; + } + } + bool is_constant() override { + return true; + } + bool is_symbolic() override { + return false; + } + + private: + ::std::variant value_; + + static constexpr bool is_int_() { + return ::std::is_same_v; + } + static constexpr bool is_bool_() { + return ::std::is_same_v; + } +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Contiguity.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Contiguity.h new file mode 100644 index 0000000000000000000000000000000000000000..014903df018c3db2b2df40ca72ee4cd40ebf21c6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Contiguity.h @@ -0,0 +1,314 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include +#include +#include +#include + +#include +#include + +namespace c10 { + +template +bool _compute_contiguous(ArrayRef sizes, ArrayRef strides, T numel) { + if (numel == 0) { + return true; + } + + T expected_stride = 1; + // NB: make sure we do signed arithmetic + for (int64_t d = int64_t(sizes.size()) - 1; d >= 0; d--) { + const auto& size_d = sizes[d]; + if (size_d == 1) { + continue; + } + + if (strides[d] != expected_stride) { + return false; + } + expected_stride *= size_d; + } + return true; +} + +// Return a SymBool with underlying symbolic expression that represents +// contiguity. Guaranteed not to throw DDE, may returns a symbolic expressions +// or symbolic True. +inline static c10::SymBool _compute_contiguous_sym( + ArrayRef sizes, + ArrayRef strides, + const c10::SymInt& numel) { + // If this return true, the tensor is contiguous indeed. Otherwise it could be + // either. + auto is_contiguous_or_false = [&]() { + if (TORCH_GUARD_OR_FALSE(sym_eq(numel, 0))) { + return true; + } + + // When calculating the expected stride, we can choose to multiply + // with max(1, size[d]) or size[d]. Regardless, this is ok for this + // function. Why? + // (1) If size[d] == 0, then the tensor is contiguous and if + // we return true or false it won't break this function. + // (2) If size[d] is not 0, then max(1,size[d]) and size[d] are equal. + // Therefore, if we choose to use max(1, size[d]) or size[d] to + // calculate the expected stride, the result is the same. + // + // We symbolically check both paths to maximize the cases where this + // function returns true. This is because make_contiguous_strides_for adds + // the max symbolically, and in some other situations the max might not be + // there. And we want to ensure we return true in both cases. + c10::SymInt expected_stride = 1; + c10::SymInt expected_stride_max = 1; + // NB: make sure we do signed arithmetic + for (int64_t d = int64_t(sizes.size()) - 1; d >= 0; d--) { + if (TORCH_GUARD_OR_FALSE(sym_eq(sizes[d], 1))) { + continue; + } + + if (TORCH_GUARD_OR_TRUE(sym_ne(strides[d], expected_stride)) && + TORCH_GUARD_OR_TRUE(sym_ne(strides[d], expected_stride_max))) { + return false; + } + expected_stride_max *= sizes[d].max(1); + expected_stride *= sizes[d]; + } + return true; + }; + + // We try to minimize creating large symbolic expressions when not needed to + // avoid symbolic evaluation perf issues. + if (is_contiguous_or_false()) { + return c10::SymBool(true); + } + + // Build a single expression that represents contiguity and return it. + c10::SymBool is_empty = sym_eq(numel, 0); + c10::SymBool is_contiguous_cond = true; + + c10::SymInt expected_stride = 1; + for (int64_t d = int64_t(sizes.size()) - 1; d >= 0; d--) { + const auto& size_d = sizes[d]; + is_contiguous_cond = is_contiguous_cond.sym_and( + size_d.sym_eq(1).sym_or(sym_eq(strides[d], expected_stride))); + expected_stride = expected_stride * size_d; + } + return is_contiguous_cond.sym_or(is_empty); +} + +// When T is SymInt this function may throw a data dependent error. +// _compute_channels_last_contiguous_2d_sym does not. Only use this function +// when inputs are hinted. +template +bool _compute_channels_last_contiguous_2d( + ArrayRef sizes, + ArrayRef strides) { + // Please don't combine these code, constant array is used here to let + // compiler fully unroll the loop to get better performance + switch (sizes.size()) { + case 4: { + T expected = 1; + for (auto& d : {1, 3, 2, 0}) { + const auto& size_d = sizes[d]; + if (size_d != 1) { + if (strides[d] != expected) { + return false; + } + expected *= size_d; + } + } + return true; + } + // NOLINTNEXTLINE(bugprone-branch-clone) + case 3: + // TODO dim == 3 case will be enabled once it is fully tested + return false; + default: + return false; + } +} + +// Return a SymBool with underlying symbolic expression that represents +// contiguity. Guaranteed not to throw DDE, may returns a symbolic expressions +// or symbolic True. +inline static c10::SymBool _compute_channels_last_contiguous_2d_sym( + ArrayRef sizes, + ArrayRef strides) { + switch (sizes.size()) { + case 4: { + // When this function return True, result always true. When it return + // False, result could be False or data dependent. + auto guard_or_false = [&]() { + c10::SymInt expected = 1; + for (auto& d : {1, 3, 2, 0}) { + const auto& size_d = sizes[d]; + // Not taking this branch could make this return False instead of True + // but not vice-versa. so its ok. + if (TORCH_GUARD_OR_FALSE(sym_eq(sizes[d], 1))) { + continue; + } + // Taking this branch could make this return False instead of True + // but not vice-versa. so its ok. + if (TORCH_GUARD_OR_TRUE(sym_ne(strides[d], expected))) { + return false; + } + expected *= size_d; + } + return true; + }; + + // We try to minimize creating large symbolic expressions when not needed + // to avoid symbolic evaluation perf issues. + if (guard_or_false()) { + return c10::SymBool(true); + } + + // Result is either false, or data dependent. + c10::SymInt expected_stride = 1; + c10::SymBool cond = true; + + for (auto& d : {1, 3, 2, 0}) { + const auto& size_d = sizes[d]; + cond = cond.sym_and( + size_d.sym_eq(1).sym_or(sym_eq(strides[d], expected_stride))); + expected_stride *= size_d; + } + return cond; + } + // NOLINTNEXTLINE(bugprone-branch-clone) + case 3: + // TODO dim == 3 case will be enabled once it is fully tested + return c10::SymBool(false); + default: + return c10::SymBool(false); + } +} + +// When T is SymInt this function may throw a data dependent error. +// _compute_channels_last_contiguous_3d_sym does not. Only use this function +// when inputs are hinted. +template +bool _compute_channels_last_contiguous_3d( + ArrayRef sizes, + ArrayRef strides) { + // Please don't combine these code, constant array is used here to let + // compiler fully unroll the loop to get better performance + switch (sizes.size()) { + case 5: { + T expected = 1; + for (auto& d : {1, 4, 3, 2, 0}) { + const auto& size_d = sizes[d]; + if (size_d != 1) { + if (strides[d] != expected) { + return false; + } + expected *= size_d; + } + } + return true; + } + // NOLINTNEXTLINE(bugprone-branch-clone) + case 4: + // TODO dim == 4 case will be enabled once it is fully tested + return false; + default: + return false; + } +} + +inline static c10::SymBool _compute_channels_last_contiguous_3d_sym( + ArrayRef sizes, + ArrayRef strides) { + switch (sizes.size()) { + case 5: { + // When this function return True, result always true. When it return + // False, result could be False or data dependent. + auto guard_or_false = [&]() { + c10::SymInt expected = 1; + for (auto& d : {1, 4, 3, 2, 0}) { + const auto& size_d = sizes[d]; + // Not taking this branch could make this return False instead of True + // but not vice-versa. so its ok. + if (TORCH_GUARD_OR_FALSE(sym_eq(sizes[d], 1))) { + continue; + } + // Taking this branch could make this return False instead of True + // but not vice-versa. so its ok. + if (TORCH_GUARD_OR_TRUE(sym_ne(strides[d], expected))) { + return false; + } + expected *= size_d; + } + return true; + }; + + // We try to minimize creating large symbolic expressions when not needed + // to avoid symbolic evaluation perf issues. + if (guard_or_false()) { + return c10::SymBool(true); + } + + // Result is either false, or data dependent. + c10::SymInt expected_stride = 1; + c10::SymBool cond = true; + + for (auto& d : {1, 4, 3, 2, 0}) { + const auto& size_d = sizes[d]; + cond = cond.sym_and( + size_d.sym_eq(1).sym_or(sym_eq(strides[d], expected_stride))); + expected_stride *= size_d; + } + return cond; + } + // NOLINTNEXTLINE(bugprone-branch-clone) + case 4: + // TODO dim == 4 case will be enabled once it is fully tested + return c10::SymBool(false); + default: + return c10::SymBool(false); + } +} + +template +bool _compute_non_overlapping_and_dense( + ArrayRef sizes, + ArrayRef strides) { + auto dim = sizes.size(); + if (dim == 1) { + return sizes[0] < 2 || strides[0] == 1; + } + SmallVector perm; + perm.resize(dim); + for (const auto i : c10::irange(dim)) { + perm[i] = i; + } + // Sort by strides, leaving 0 and 1 sized dims at the end of the array + std::sort(perm.begin(), perm.end(), [&](int64_t a, int64_t b) { + if (sizes[a] < 2) { + return false; + } else if (sizes[b] < 2) { + return true; + } + return strides[a] < strides[b]; + }); + T require_stride = 1; + for (const auto i : c10::irange(dim)) { + const auto& size_perm_i = sizes[perm[i]]; + if (size_perm_i < 2) { + return true; + } + if (strides[perm[i]] != require_stride) { + return false; + } + require_stride *= size_perm_i; + } + return true; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CopyBytes.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CopyBytes.h new file mode 100644 index 0000000000000000000000000000000000000000..bc2632794299da5a6c9c5d30be0b4591600bab2a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/CopyBytes.h @@ -0,0 +1,53 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace c10 { + +using CopyBytesFunction = void (*)( + size_t nbytes, + const void* src, + Device src_device, + void* dst, + Device dst_device); + +struct C10_API _CopyBytesFunctionRegisterer { + _CopyBytesFunctionRegisterer( + DeviceType from, + DeviceType to, + CopyBytesFunction func_sync, + CopyBytesFunction func_async = nullptr); +}; + +#define REGISTER_COPY_BYTES_FUNCTION(from, to, ...) \ + namespace { \ + static _CopyBytesFunctionRegisterer C10_ANONYMOUS_VARIABLE( \ + g_copy_function)(from, to, __VA_ARGS__); \ + } + +/* + * WARNING: Implementations for this function are currently registered from + * ATen and caffe2, not yet from c10. Don't use this if not either ATen + * or caffe2 is present as well. + * We can't move them yet, because the CUDA implementations aren't unified yet + * between ATen and caffe2. + * We're planning to move the implementations into c10/backend/xxx + * to make c10 self contained again. + */ +C10_API void CopyBytes( + size_t nbytes, + const void* src, + Device src_device, + void* dst, + Device dst_device, + bool async); +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DefaultDtype.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DefaultDtype.h new file mode 100644 index 0000000000000000000000000000000000000000..240c173ca22ae28ab20e243890b2f8a054156fa5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DefaultDtype.h @@ -0,0 +1,20 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace caffe2 { +class TypeMeta; +} // namespace caffe2 + +namespace c10 { +C10_API void set_default_dtype(caffe2::TypeMeta dtype); +C10_API const caffe2::TypeMeta get_default_dtype(); +C10_API ScalarType get_default_dtype_as_scalartype(); +C10_API const caffe2::TypeMeta get_default_complex_dtype(); +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DefaultTensorOptions.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DefaultTensorOptions.h new file mode 100644 index 0000000000000000000000000000000000000000..8d5e66ec405ddeb1494d987a034cf1b945663667 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DefaultTensorOptions.h @@ -0,0 +1,50 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace c10 { + +struct TensorOptions; + +/// Like TensorOptions, but all fields are guaranteed to be filled. +struct DefaultTensorOptions { + DefaultTensorOptions() = default; + + caffe2::TypeMeta dtype() const noexcept { + return dtype_; + } + Device device() const noexcept { + return device_; + } + Layout layout() const noexcept { + return layout_; + } + bool requires_grad() const noexcept { + return requires_grad_; + } + + // Defined in TensorOptions.h + inline DefaultTensorOptions& merge(const TensorOptions& options); + + private: + caffe2::TypeMeta dtype_ = caffe2::TypeMeta::Make(); // 64-bit + Device device_ = at::kCPU; // 32-bit + Layout layout_ = at::kStrided; // 8-bit + bool requires_grad_ = false; // 8-bit +}; + +inline const DefaultTensorOptions& getDefaultTensorOptions() { + static const auto options = DefaultTensorOptions(); + return options; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Device.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Device.h new file mode 100644 index 0000000000000000000000000000000000000000..d3380f434c6c8284476ac3bc662fd88e10289a86 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Device.h @@ -0,0 +1,221 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace c10 { + +/// An index representing a specific device; e.g., the 1 in GPU 1. +/// A DeviceIndex is not independently meaningful without knowing +/// the DeviceType it is associated; try to use Device rather than +/// DeviceIndex directly. +using DeviceIndex = int8_t; + +/// Represents a compute device on which a tensor is located. A device is +/// uniquely identified by a type, which specifies the type of machine it is +/// (e.g. CPU or CUDA GPU), and a device index or ordinal, which identifies the +/// specific compute device when there is more than one of a certain type. The +/// device index is optional, and in its defaulted state represents (abstractly) +/// "the current device". Further, there are two constraints on the value of the +/// device index, if one is explicitly stored: +/// 1. A negative index represents the current device, a non-negative index +/// represents a specific, concrete device, +/// 2. When the device type is CPU, the device index must be zero. +struct C10_API Device final { + using Type = DeviceType; + + /// Constructs a new `Device` from a `DeviceType` and an optional device + /// index. + /* implicit */ Device(DeviceType type, DeviceIndex index = -1) + : type_(type), index_(index) { + validate(); + } + + /// Constructs a `Device` from a string description, for convenience. + /// The string supplied must follow the following schema: + /// `(cpu|cuda)[:]` + /// where `cpu` or `cuda` specifies the device type, and + /// `:` optionally specifies a device index. + /* implicit */ Device(const std::string& device_string); + + /// Returns true if the type and index of this `Device` matches that of + /// `other`. + bool operator==(const Device& other) const noexcept { + return this->type_ == other.type_ && this->index_ == other.index_; + } + + /// Returns true if the type or index of this `Device` differs from that of + /// `other`. + bool operator!=(const Device& other) const noexcept { + return !(*this == other); + } + + /// Sets the device index. + void set_index(DeviceIndex index) { + index_ = index; + } + + /// Returns the type of device this is. + DeviceType type() const noexcept { + return type_; + } + + /// Returns the optional index. + DeviceIndex index() const noexcept { + return index_; + } + + /// Returns true if the device has a non-default index. + bool has_index() const noexcept { + return index_ != -1; + } + + /// Return true if the device is of CUDA type. + bool is_cuda() const noexcept { + return type_ == DeviceType::CUDA; + } + + /// Return true if the device is of PrivateUse1 type. + bool is_privateuseone() const noexcept { + return type_ == DeviceType::PrivateUse1; + } + + /// Return true if the device is of MPS type. + bool is_mps() const noexcept { + return type_ == DeviceType::MPS; + } + + /// Return true if the device is of HIP type. + bool is_hip() const noexcept { + return type_ == DeviceType::HIP; + } + + /// Return true if the device is of VE type. + bool is_ve() const noexcept { + return type_ == DeviceType::VE; + } + + /// Return true if the device is of XPU type. + bool is_xpu() const noexcept { + return type_ == DeviceType::XPU; + } + + /// Return true if the device is of IPU type. + bool is_ipu() const noexcept { + return type_ == DeviceType::IPU; + } + + /// Return true if the device is of XLA type. + bool is_xla() const noexcept { + return type_ == DeviceType::XLA; + } + + /// Return true if the device is of MTIA type. + bool is_mtia() const noexcept { + return type_ == DeviceType::MTIA; + } + + /// Return true if the device is of HPU type. + bool is_hpu() const noexcept { + return type_ == DeviceType::HPU; + } + + /// Return true if the device is of Lazy type. + bool is_lazy() const noexcept { + return type_ == DeviceType::Lazy; + } + + /// Return true if the device is of Vulkan type. + bool is_vulkan() const noexcept { + return type_ == DeviceType::Vulkan; + } + + /// Return true if the device is of Metal type. + bool is_metal() const noexcept { + return type_ == DeviceType::Metal; + } + + /// Return true if the device is of MAIA type. + bool is_maia() const noexcept { + return type_ == DeviceType::MAIA; + } + + /// Return true if the device is of META type. + bool is_meta() const noexcept { + return type_ == DeviceType::Meta; + } + + /// Return true if the device is of CPU type. + bool is_cpu() const noexcept { + return type_ == DeviceType::CPU; + } + + /// Return true if the device supports arbitrary strides. + bool supports_as_strided() const noexcept { + return type_ != DeviceType::IPU && type_ != DeviceType::XLA && + type_ != DeviceType::Lazy; + } + + /// Same string as returned from operator<<. + std::string str() const; + + private: + DeviceType type_; + DeviceIndex index_ = -1; + void validate() { + // Removing these checks in release builds noticeably improves + // performance in micro-benchmarks. + // This is safe to do, because backends that use the DeviceIndex + // have a later check when we actually try to switch to that device. + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + index_ >= -1, + "Device index must be -1 or non-negative, got ", + static_cast(index_)); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + !is_cpu() || index_ <= 0, + "CPU device index must be -1 or zero, got ", + static_cast(index_)); + } +}; + +C10_API std::ostream& operator<<(std::ostream& stream, const Device& device); + +} // namespace c10 + +namespace std { +template <> +struct hash { + size_t operator()(c10::Device d) const noexcept { + // Are you here because this static assert failed? Make sure you ensure + // that the bitmasking code below is updated accordingly! + static_assert(sizeof(c10::DeviceType) == 1, "DeviceType is not 8-bit"); + static_assert(sizeof(c10::DeviceIndex) == 1, "DeviceIndex is not 8-bit"); + // Note [Hazard when concatenating signed integers] + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // We must first convert to a same-sized unsigned type, before promoting to + // the result type, to prevent sign extension when any of the values is -1. + // If sign extension occurs, you'll clobber all of the values in the MSB + // half of the resulting integer. + // + // Technically, by C/C++ integer promotion rules, we only need one of the + // uint32_t casts to the result type, but we put in both for explicitness's + // sake. + uint32_t bits = static_cast(static_cast(d.type())) + << 16 | + static_cast(static_cast(d.index())); + return std::hash{}(bits); + } +}; +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceArray.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceArray.h new file mode 100644 index 0000000000000000000000000000000000000000..b2b179b4d2d82385aefe1f1b79cb2069120500d7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceArray.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include +#include +#include +#include +#include + +namespace c10 { + +template +class DeviceArray { + public: + DeviceArray(c10::Allocator& allocator, size_t size) + : data_ptr_(allocator.allocate(size * sizeof(T))) { + static_assert(std::is_trivial_v, "T must be a trivial type"); + TORCH_INTERNAL_ASSERT( + 0 == (reinterpret_cast(data_ptr_.get()) % alignof(T)), + "c10::DeviceArray: Allocated memory is not aligned for this data type"); + } + + T* get() { + return static_cast(data_ptr_.get()); + } + + private: + c10::DataPtr data_ptr_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceCapability.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceCapability.h new file mode 100644 index 0000000000000000000000000000000000000000..85477281261bed35e2652ddc471c9bae4042707a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceCapability.h @@ -0,0 +1,81 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10 { + +constexpr size_t NUMBER_OF_DEVICE_CAPABILITIES = NumScalarTypes; + +// Generate bitfields for each scalar type +#define DEFINE_SCALAR_TYPE(_1, n) unsigned int has_##n : 1; + +// Generate enum indices for each scalar type +#define DEFINE_SCALAR_ENUM(_1, name) kIndex_##name, + +enum ScalarTypeIndex { + AT_FORALL_SCALAR_TYPES_WITH_COMPLEX_AND_QINTS(DEFINE_SCALAR_ENUM) +}; + +/** + * @brief DeviceCapability represents the the common capabilities that all + * devices should support. + * + * This struct provides a compact way to represent the common capabilities that + * all devices should support. Includes the following capabilities: + * - Supported data types + * + * Purpose + * - Enable device-specific optimizations based on supported capabilities + * + * Contract + * + * Supported data types: + * - Each bitfield represents support for one device capability + * - Bit value 1 means the capability is supported, 0 means not supported + * - The struct is initialized with all capabilities enabled by default + * + * @note Adding New Capabilities + * + * 1. Define the new capability in the `DeviceCapability` struct + * 2. Update the support of the new capability in each accelerator + * implementation + * 3. Add the new capability to the returned PyObject Dictionary + */ +struct C10_API DeviceCapability { + union { + struct { + AT_FORALL_SCALAR_TYPES_WITH_COMPLEX_AND_QINTS(DEFINE_SCALAR_TYPE) + } supported_scalar_types; + uint64_t capability_bits; // Allow direct bit manipulation + } capability_data; + + // Default constructor with all capabilities enabled. + DeviceCapability() { + capability_data.capability_bits = + ((1ULL << NUMBER_OF_DEVICE_CAPABILITIES) - 1); + } + + // Iterate supported ScalarTypes without allocating a vector + template + void forEachSupportedScalarType(F&& visitor) const { +#define VISIT_SCALAR_TYPE(_1, n) \ + if (capability_data.supported_scalar_types.has_##n) { \ + visitor(ScalarType::n); \ + } + + AT_FORALL_SCALAR_TYPES_WITH_COMPLEX_AND_QINTS(VISIT_SCALAR_TYPE) + +#undef VISIT_SCALAR_TYPE + } +}; + +#undef DEFINE_SCALAR_ENUM +#undef DEFINE_SCALAR_TYPE +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceGuard.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceGuard.h new file mode 100644 index 0000000000000000000000000000000000000000..389ac29d10029d915279857f4fb4e2ffeb880307 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceGuard.h @@ -0,0 +1,207 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace c10 { + +/// RAII guard that sets a certain default device in its constructor, and +/// changes it back to the device that was originally active upon destruction. +/// +/// The device is always reset to the one that was active at the time of +/// construction of the guard. Even if you `set_device` after construction, the +/// destructor will still reset the device to the one that was active at +/// construction time. +/// +/// This device guard does NOT have an uninitialized state; it is guaranteed +/// to reset a device on exit. If you are in a situation where you *might* +/// want to setup a guard (i.e., are looking for the moral equivalent +/// of std::optional), see OptionalDeviceGuard. +class DeviceGuard { + public: + /// No default constructor; see Note [Omitted default constructor from RAII] + explicit DeviceGuard() = delete; + + /// Set the current device to the passed Device. + explicit DeviceGuard(Device device) : guard_(device) {} + + /// This constructor is for testing only. + explicit DeviceGuard( + Device device, + const impl::DeviceGuardImplInterface* impl) + : guard_(device, impl) {} + + ~DeviceGuard() = default; + + /// Copy is disallowed + DeviceGuard(const DeviceGuard&) = delete; + DeviceGuard& operator=(const DeviceGuard&) = delete; + + /// Move is disallowed, as DeviceGuard does not have an uninitialized state, + /// which is required for moves on types with nontrivial destructors. + DeviceGuard(DeviceGuard&& other) = delete; + DeviceGuard& operator=(DeviceGuard&& other) = delete; + + /// Sets the device to the given one. The specified device must be consistent + /// with the device type originally specified during guard construction. + /// + /// TODO: The consistency check here is inconsistent with StreamGuard's + /// behavior with set_stream, where a stream on a different device than + /// the original one isn't an error; we just reset the stream and then + /// switch devices. + void reset_device(at::Device device) { + guard_.reset_device(device); + } + + /// This method is for testing only. + void reset_device( + at::Device device, + const impl::DeviceGuardImplInterface* impl) { + guard_.reset_device(device, impl); + } + + /// Sets the device index to the given one. The device type is inferred + /// from the original device type the guard was constructed with. + void set_index(DeviceIndex index) { + guard_.set_index(index); + } + + /// Returns the device that was set at the time the guard was constructed. + Device original_device() const { + return guard_.original_device(); + } + + /// Returns the most recent device that was set using this device guard, + /// either from construction, or via set_device. + Device current_device() const { + return guard_.current_device(); + } + + private: + impl::InlineDeviceGuard guard_; +}; + +/** + * A OptionalDeviceGuard is an RAII class that sets a device to some value on + * initialization, and resets the device to its original value on destruction. + * Morally, a OptionalDeviceGuard is equivalent to std::optional, + * but with extra constructors and methods as appropriate. + * + * Besides its obvious use (optionally applying a DeviceGuard), + * OptionalDeviceGuard is often also used for the following idiom: + * + * OptionalDeviceGuard g; + * for (const auto& t : tensors) { + * g.set_device(t.device()); + * do_something_with(t); + * } + * + * This usage is marginally more efficient than constructing a DeviceGuard every + * iteration of the for loop, as it avoids an unnecessary device reset. + * + * Unlike DeviceGuard, a OptionalDeviceGuard may be uninitialized. This occurs + * when you use the nullary constructor, or pass a nullopt to the constructor. + * Uninitialized OptionalDeviceGuards do *nothing*; they do not know what the + * original device was and they do not reset on destruction. This is why + * original_device() and current_device() return std::optional rather + * than Device (as they do in DeviceGuard), and also is why we didn't just + * provide OptionalDeviceGuard by default and hide DeviceGuard from users. + * + * The semantics of an OptionalDeviceGuard are exactly explained by thinking + * of it as an std::optional. In particular, an initialized + * OptionalDeviceGuard doesn't restore device to its value at construction; it + * restores device to its value *at initialization*. So if you have the + * program: + * + * setDevice(1); + * OptionalDeviceGuard g; + * setDevice(2); + * g.reset_device(Device(DeviceType::CUDA, 3)); // initializes! + * + * On destruction, g will reset device to 2, rather than 1. + * + * An uninitialized OptionalDeviceGuard is distinct from a (initialized) + * DeviceGuard whose original_device_ and current_device_ match, since the + * DeviceGuard will still reset the device to original_device_. + */ +class OptionalDeviceGuard { + public: + /// Create an uninitialized guard. Set the guard later using reset_device. + explicit OptionalDeviceGuard() = default; + + /// Initialize the guard, setting the current device to the passed Device. + explicit OptionalDeviceGuard(Device device) : guard_(device) {} + + /// Initialize the guard if a Device is passed; otherwise leave the + /// guard uninitialized. + explicit OptionalDeviceGuard(std::optional device) : guard_(device) {} + + /// Constructor for testing only. + explicit OptionalDeviceGuard( + Device device, + const impl::DeviceGuardImplInterface* impl) + : guard_(device, impl) {} + + ~OptionalDeviceGuard() = default; + /// Copy is disallowed + OptionalDeviceGuard(const OptionalDeviceGuard&) = delete; + OptionalDeviceGuard& operator=(const OptionalDeviceGuard&) = delete; + + /// Move is disallowed + /// See Note [Explicit initialization of optional fields] + /// and // Note [Move construction for RAII guards is tricky] + /// for rationale. + OptionalDeviceGuard(OptionalDeviceGuard&& other) = delete; + OptionalDeviceGuard& operator=(OptionalDeviceGuard&& other) = delete; + + /// Sets the device to the given one. The specified device must be consistent + /// with the device type originally specified during guard construction. + void reset_device(at::Device device) { + guard_.reset_device(device); + } + + /// For testing only + void reset_device( + at::Device device, + const impl::DeviceGuardImplInterface* impl) { + guard_.reset_device(device, impl); + } + + /// Returns the device that was set at the time the guard was constructed. + std::optional original_device() const { + return guard_.original_device(); + } + + /// Returns the most recent device that was set using this device guard, + /// either from construction, or via reset_device. + std::optional current_device() const { + return guard_.current_device(); + } + + private: + impl::InlineOptionalDeviceGuard guard_; +}; + +// Note [Whither the DeviceGuard boilerplate] +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Design note: in principle, we could avoid these wrappers using: +// +// using DeviceGuard = impl::InlineDeviceGuard; +// using OptionalDeviceGuard = +// impl::InlineOptionalDeviceGuard; +// +// But the error messages are worse, and our users can't just look at the +// header file to find out what's going on. Furthermore, for specializations +// like CUDAStreamGuard, it can be profitable to replace some interfaces with +// refined types (e.g., return CUDAStream instead of Stream). So, we eat +// the boilerplate and write out the API explicitly. + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceType.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceType.h new file mode 100644 index 0000000000000000000000000000000000000000..3847b5e2650e4100d19dc0031747769f709b92f7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DeviceType.h @@ -0,0 +1,35 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +// If you modified DeviceType in caffe2/proto/caffe2.proto, please also sync +// your changes into torch/headeronly/core/DeviceType.h. +#include + +#include +#include + +namespace c10 { + +C10_API std::string DeviceTypeName(DeviceType d, bool lower_case = false); + +C10_API bool isValidDeviceType(DeviceType d); + +C10_API std::ostream& operator<<(std::ostream& stream, DeviceType type); + +C10_API void register_privateuse1_backend(const std::string& backend_name); +C10_API std::string get_privateuse1_backend(bool lower_case = true); + +C10_API bool is_privateuse1_backend_registered(); + +} // namespace c10 + +namespace torch { +// NOLINTNEXTLINE(misc-unused-using-decls) +using c10::DeviceType; +} // namespace torch + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DispatchKey.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DispatchKey.h new file mode 100644 index 0000000000000000000000000000000000000000..5095585b27919a6190f05c040d4aebc7fa8172ee --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DispatchKey.h @@ -0,0 +1,750 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +// Semantically, each value of BackendComponent identifies a "backend" for our +// dispatch. Some functionalities that we may dispatch to are allowed to +// register different handlers for each backend. The BackendComponent is then +// used to figure out which backend implementation to dispatch to. + +// In implementation terms, the backend component identifies a specific "bit" in +// a DispatchKeySet. The bits in the DispatchKeySet are split between the bottom +// ~12 "BackendComponent" bits, while the remaining upper bits are assigned to +// functionalities. When we encounter a functionality bit that is known to be +// customizable per-backend, then we also look at the lower BackendComponent +// bits and take the highest bit to determine which backend's implementation to +// use. + +// WARNING! If you add a new backend component to the end of this list, +// make sure you register it before Meta. +// Meta must be at the end so that meta key in tls triggers meta kernels. +// (But you shouldn't: private use keys should have higher precedence than all +// built-in keys) + +// If you add a new (non-privateuse) backend here, +// make sure to add an Autograd fallthrough kernel +// in aten/src/ATen/core/VariableFallbackKernel.cpp + +#define C10_FORALL_BACKEND_COMPONENTS(_, extra) \ + _(CPU, extra) \ + _(CUDA, extra) \ + _(HIP, extra) \ + _(XLA, extra) \ + _(MPS, extra) \ + _(IPU, extra) \ + _(XPU, extra) \ + _(HPU, extra) \ + _(VE, extra) \ + _(Lazy, extra) \ + _(MTIA, extra) \ + _(MAIA, extra) \ + _(PrivateUse1, extra) \ + _(PrivateUse2, extra) \ + _(PrivateUse3, extra) \ + _(Meta, extra) + +// WARNING! If we add a new per-backend functionality key that has higher +// priority than Autograd, then make sure you update EndOfRuntimeBackendKeys + +#define C10_FORALL_FUNCTIONALITY_KEYS(_) \ + _(Dense, ) \ + _(Quantized, Quantized) \ + _(Sparse, Sparse) \ + _(SparseCsr, SparseCsr) \ + _(NestedTensor, NestedTensor) \ + _(AutogradFunctionality, Autograd) + +enum class BackendComponent : uint8_t { + + // A "backend" is colloquially used to refer to handlers for dispatch + // which actually implement the numerics of an operation in question. + // + // Due to the nature of the enum, these backends are specified in + // an ordered way, but for most backends this order is not semantically + // meaningful (e.g., it's valid to reorder these backends without changing + // semantics). The only situation when backend ordering is meaningful + // is when the backend participates in multiple dispatch with another + // backend; e.g., CPU and CUDA (cuda must have higher priority). + + // These keys don't correspond to individual kernels. + // Instead, they represent the backends that are allowed to override specific + // pieces of functionality: + // - dense kernels (e.g. DispatchKey::CPU) + // - sparse kernels (e.g. DispatchKey::SparseCPU) + // - quantized kernels (e.g. DispatchKey::QuantizedCPU) + // - autograd kernels (e.g. DispatchKey::AutogradCPU) + // We reserve space in the runtime operator table for this full cross product + // of + // [backends in this enum] x [keys below that are explicitly marked as having + // per-backend functionality] + // + // A meta tensor is a tensor without any data associated with it. (They + // have also colloquially been referred to as tensors on the "null" device). + // A meta tensor can be used to dry run operators without actually doing any + // computation, e.g., add on two meta tensors would give you another meta + // tensor with the output shape and dtype, but wouldn't actually add anything. + + InvalidBit = 0, +#define DEFINE_BACKEND_COMPONENT(n, _) n##Bit, + C10_FORALL_BACKEND_COMPONENTS(DEFINE_BACKEND_COMPONENT, unused) +#undef DEFINE_BACKEND_COMPONENT + + // Define an alias to represent end of backend dispatch keys. + // If you add new backend keys after PrivateUse3, please also update it here. + EndOfBackendKeys = MetaBit, +}; + +// Semantically, a dispatch key identifies a possible "level" in our +// dispatch, for which a handler may be registered. Each handler corresponds +// to a type of functionality. +// +// In implementation terms, the dispatch key identifies a specific "bit" in a +// DispatchKeySet. Higher bit indexes get handled by dispatching first (because +// we "count leading zeros" when we extract the highest priority dispatch +// key.) +// +// Note [DispatchKey Classification] +// This enum actually contains several types of keys, which are explained +// in more detail further down: +// (1) non-customizable backends (e.g. FPGA) +// (2) non-customizable functionalities (e.g. Functionalize) +// (3) functionalized that are customizable per backend (e.g. Dense, Sparse, +// AutogradFunctionality) (4) per-backend instances of customizable +// functionalities (e.g. CPU, SparseCPU, AutogradCPU) (5) alias keys (e.g. +// CompositeImplicitAutograd) +// +// Of the categories above, it's important to note: +// (a) which keys are assigned individual bits in a DispatchKeySet +// (b) which keys are assigned individual slots in the runtime operator table +// ("Runtime keys") +// +// (1), (2) and (3) all get their own dedicated bits in the DispatchKeySet. +// (1), (2) and (4) all get their own dedicated slots in the runtime operator +// table. + +// See Note [DispatchKeySet Internal Representation] for more details. +// +// NOTE: Keep the list in sync with `DispatchKey` in torchgen/model.py +enum class DispatchKey : uint16_t { + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~ UNDEFINED ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // + // This is not a "real" functionality, but it exists to give us a "nullopt" + // element we can return for cases when a DispatchKeySet contains no elements. + // You can think a more semantically accurate definition of DispatchKey is: + // + // using DispatchKey = std::optional + // + // and Undefined == nullopt. We didn't actually represent + // it this way because std::optional would take two + // words, when DispatchKey fits in eight bits. + + Undefined = 0, + + // Define an alias for Undefined to represent CatchAll (long term + // this will get eliminated, but for now it's convenient) + CatchAll = Undefined, + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~ Functionality Keys ~~~~~~~~~~~~~~~~~~~~~~ // + // Every value in the enum (up to EndOfFunctionalityKeys) + // corresponds to an individual "functionality" that can be dispatched to. + // This is represented in the DispatchKeySet by assigning each of these enum + // values + // to each of the remaining (64 - len(BackendComponent)) bits. + // + // Most of these functionalities have a single handler assigned to them, + // making them "runtime keys". + // That map to a single slot in the runtime operator table. + // + // A few functionalities are allowed to be customizable per backend. + // See [Note: Per-Backend Functionality Dispatch Keys] for details. + + // See [Note: Per-Backend Functionality Dispatch Keys] + Dense, + + // Below are non-extensible backends. + // These are backends that currently don't have their own overrides for + // Autograd/Sparse/Quantized kernels, + // and we therefore don't waste space in the runtime operator table allocating + // space for them. + // If any of these backends ever need to customize, e.g., Autograd, then we'll + // need to add a DispatchKey::*Bit for them. + + // TODO: put this in BackendComponents + FPGA, // Xilinx support lives out of tree at + // https://gitlab.com/pytorch-complex/vitis_kernels + + Vulkan, // TODO: put this in BackendComponents + Metal, // TODO: put this in BackendComponents + + // See [Note: Per-Backend Functionality Dispatch Keys] + Quantized, + + // This backend is to support custom RNGs; it lets you go + // to a different kernel if you pass in a generator that is not a + // traditional CPUGeneratorImpl/CUDAGeneratorImpl. To make use of this + // key: + // 1) set it as a second parameter of at::Generator constructor call in + // the user-defined PRNG class. + // 2) use it as a dispatch key while registering custom kernels + // (templatized kernels specialized for user-defined PRNG class) + // intended for out of tree use; tested by aten/src/ATen/test/rng_test.cpp + CustomRNGKeyId, + + // TODO: Make Mkldnn a functionality key, so we can give it Meta + // support + // Here are backends which specify more specialized operators + // based on the layout of the tensor. Note that the sparse backends + // are one case where ordering matters: sparse multi-dispatches with + // the corresponding dense tensors, and must be handled before them. + MkldnnCPU, // registered at build/aten/src/ATen/RegisterMkldnnCPU.cpp + // NB: not to be confused with MKLDNN, which is Caffe2 only + + // See [Note: Per-Backend Functionality Dispatch Keys] + Sparse, + + SparseCsr, + + NestedTensor, + + // In some situations, it is not immediately obvious what the correct + // backend for function is, because the function in question doesn't + // have any "tensor" arguments. In this case, a BackendSelect function + // can be registered to implement the custom determination of the + // correct backend. + BackendSelect, + + Python, + + // Out-of-core key for Fake Tensor in torchdistx. + // See https://pytorch.org/torchdistx/latest/fake_tensor.html + // TODO: delete this in favor of Python-implemented fake tensor + Fake, + // See Note [Out-of-tree vmap+grad prototype]. The purpose of this key + // is to insert code after the "autograd subsystem" runs, so this key should + // be directly after ADInplaceOrView and all of the autograd keys. + FuncTorchDynamicLayerBackMode, + + // Alias and mutation removal. + // If some backends want to opt into only alias removal or only mutation + // removal, + // we can consider adding separate keys dedicated to those individual passes. + // See Note [Functionalization Pass In Core] for details. + Functionalize, + + // The named dispatch key is set for any tensors with named dimensions. + // Although we have a dispatch key for named tensors, for historical reasons, + // this dispatch key doesn't do any of the substantive functionality for named + // tensor (though, hypothetically, it could!) At the moment, it's just + // responsible for letting us give good error messages when operations + // don't support named tensors. + // + // NB: If you ever consider moving named tensor functionality into + // this dispatch key, note that it might be necessary add another dispatch + // key that triggers before composite operators, in case a composite operator + // has named dimension propagation that doesn't match that of its + // constituent parts. + // TODO: delete this once torchdim lands in functorch + Named, + + // The Conjugate dispatch key is set for any tensors that need to perform + // conjugation + // This is implemented at a dispatch level right before any backends run + Conjugate, + + // The Negative dispatch key is set for any tensors that need to perform + // negation + // This is implemented at a dispatch level right before any backends run + Negative, + + ZeroTensor, // registered at build/aten/src/ATen/RegisterZeroTensor.cpp + + // Note [ADInplaceOrView key] + // ADInplaceOrView key is used by inplace or view ops to register a kernel + // that does additional setup for future autograd computation. + // + // 1. For inplace ops this kernel does version bump + // 2. For view ops this kernel does `as_view` setup where we properly setup + // DifferentiableViewMeta on the view tensors. + // + // For other ops it's fallthrough kernel since there's no extra + // work to do. + // + // Note [Dream: skip VariableType kernel when requires_grad=false] + // + // In an ideal world where we can skip VariableType kernel for inputs + // with requires_grad=false, instead of a fallthrough kernel, we'll + // register a kernel shown below to all functional ops as well: + // torch::Tensor my_functional_op(...) { + // { + // // Note for every op in VariableType, you need to go through + // // `AutoDispatchBelowADInplaceOrView` guard exactly once to add the + // // key to TLS excluded set. If you don't go through it at all, + // // inplace/view ops called through `at::` inside your backend + // // kernel will dispatch to ADInplaceOrView kernels and do a lot + // // of extra work. + // at::AutoDispatchBelowADInplaceOrView guard; + // at::redispatch::my_functional_op(...); + // } + // } + // But this work is currently blocked since it adds an extra dispatch + // for all ops and it's non-trivial overhead at model level(a few percents). + // Thus our current approach takes advantage of the fact every kernel go + // through VariableType kernel first and pulls the + // `at::AutoDispatchBelowADInplaceOrView` guard of functional ops + // up to the `VariableType` kernel. Thus we only add the extra dispatch + // to view/inplace ops to minimize its perf impact to real models. + ADInplaceOrView, + // Note [Alias Dispatch Key : Autograd] + // All backends are oblivious to autograd; autograd is handled as a + // layer which happens on top of all backends. It inspects the autograd + // metadata of all inputs, determines what autograd metadata should be + // constructed by the output, and otherwise defers to the backend to + // actually do the numeric computation. Autograd contains + // the bulk of this logic. + + // Autograd is now an alias dispatch key which by default maps to all + // backend-specific autograd keys. + // Backend-specific allow backends to override the default kernel registered + // to Autograd key as needed. + // For example, XLA wants to define autograd for einsum directly. + // Registering a custom autograd implementation at the XLA key won't work + // because we process Autograd before XLA. This key has higher priority and + // gets processed first. You generally should NOT redispatch after handling + // autograd here (since that would result in execution of the Autograd + // operator, which you're trying to skip). In AutogradXLA implementations, + // you are responsible for handling autograd yourself, or deferring to other + // operators which support autograd. + + // Currently we only have backend-specific autograd keys for CPU/CUDA/XLA and + // reserved user-defined backends. All other in-tree backends share the + // AutogradOther key. We can add specific autograd key for those backends + // upon request. + AutogradOther, + + // See [Note: Per-Backend Functionality Dispatch Keys] + AutogradFunctionality, + + // NestedTensor is an example of something that isn't a "real backend" + // (because it mostly consists of redispatching kernels) + // but it would like to override autograd functionality in C++. + // We can handle cases like this by adding an extra functionality key + // exclusively for handling autograd for NestedTensor. + // lives out of tree at + // https://github.com/pytorch/nestedtensor + AutogradNestedTensor, + + Tracer, + + // TODO: make Autocast a functionality key + // Autocasting precedes VariableTypeId, to ensure casts are autograd-exposed + // and inputs are saved for backward in the post-autocast type. + AutocastCPU, + AutocastMTIA, + AutocastMAIA, + AutocastXPU, + AutocastIPU, + AutocastHPU, + AutocastXLA, + // AutocastXLA is only being used for TPUs. XLA GPUs continue to use + // AutocastCUDA. + AutocastMPS, + AutocastCUDA, + AutocastPrivateUse1, + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ WRAPPERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // + // There are a number of alternative modes which may want to handle before + // autograd; for example, error checking, tracing, profiling or vmap. They + // go here. + + FuncTorchBatched, // See Note [Out-of-tree vmap+grad prototype] + + // Dispatch key for BatchedTensorImpl wrapping a nested tensor. + BatchedNestedTensor, + + FuncTorchVmapMode, // See Note [Out-of-tree vmap+grad prototype] + + // This is the dispatch key for BatchedTensorImpl, which is used to implement + // batching rules for vmap. + Batched, + + // When we are inside a vmap, all tensors dispatch on this key. + // See Note: [DispatchKey::VmapMode usage] for more details. + VmapMode, + + FuncTorchGradWrapper, // See Note [Out-of-tree vmap+grad prototype] + + // Out-of-core key for Deferred Module Initialization in torchdistx. + // See https://pytorch.org/torchdistx/latest/deferred_init.html + DeferredInit, + + // Used by Python key logic to know the set of tls on entry to the dispatcher + // This kernel assumes it is the top-most non-functorch-related DispatchKey. + // If you add a key above, make sure to update the fallback implementation for + // this. + PythonTLSSnapshot, + + // This key should be at the very top of the dispatcher + FuncTorchDynamicLayerFrontMode, // See Note [Out-of-tree vmap+grad prototype] + + // TESTING: This is intended to be a generic testing tensor type id. + // Don't use it for anything real; its only acceptable use is within a single + // process test. Use it by creating a TensorImpl with this DispatchKey, and + // then registering operators to operate on this type id. See + // aten/src/ATen/core/dispatch/backend_fallback_test.cpp for a usage example. + TESTING_ONLY_GenericWrapper, + + // TESTING: This is intended to be a generic testing tensor type id. + // Don't use it for anything real; its only acceptable use is within a ingle + // process test. Use it by toggling the mode on and off via + // TESTING_ONLY_tls_generic_mode_set_enabled and then registering operators + // to operate on this type id. See + // aten/src/ATen/core/dispatch/backend_fallback_test.cpp + // for a usage example + TESTING_ONLY_GenericMode, + + // This key is used for pre-dispatch tracing in make_fx. + // It has lower priority than the PythonDispatcher key + // because we use the PythonDispatcher to intercept the key from python, + // and avoid having to implement it in C++. + PreDispatch, + + // This is a bypass that allows you to skip running the C++ dispatcher + // entirely + PythonDispatcher, + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FIN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // + EndOfFunctionalityKeys, // End of functionality keys. + +// ~~~~~~~~~~~~~~ "Dense" Per-Backend Dispatch keys ~~~~~~~~~~~~~~~~~~~~ // +// Here are backends which you think of as traditionally specifying +// how to implement operations on some device. + +#define DEFINE_PER_BACKEND_KEYS_FOR_BACKEND(n, prefix) prefix##n, + +#define DEFINE_PER_BACKEND_KEYS(fullname, prefix) \ + StartOf##fullname##Backends, \ + C10_FORALL_BACKEND_COMPONENTS( \ + DEFINE_PER_BACKEND_KEYS_FOR_BACKEND, prefix) \ + EndOf##fullname##Backends = prefix##Meta, + + C10_FORALL_FUNCTIONALITY_KEYS(DEFINE_PER_BACKEND_KEYS) + +#undef DEFINE_PER_BACKEND_KEYS +#undef DEFINE_PER_BACKEND_KEYS_FOR_BACKEND + + EndOfRuntimeBackendKeys = EndOfAutogradFunctionalityBackends, + + // ~~~~~~~~~~~~~~~~~~~~~~ Alias Dispatch Keys ~~~~~~~~~~~~~~~~~~~~~~~~~~ // + // Note [Alias Dispatch Keys] + // Alias dispatch keys are synthetic dispatch keys which map to multiple + // runtime dispatch keys. Alisa keys have precedence, but they are always + // lower precedence than runtime keys. You can register a kernel to an + // alias key, the kernel might be populated to the mapped runtime keys + // during dispatch table computation. + // If a runtime dispatch key has multiple kernels from alias keys, which + // kernel wins is done based on the precedence of alias keys (but runtime + // keys always have precedence over alias keys). + // Alias keys won't be directly called during runtime. + + // See Note [Alias Dispatch Key : Autograd] + Autograd, + CompositeImplicitAutograd, // registered at + // build/aten/src/ATen/RegisterCompositeImplicitAutograd.cpp + + // Note: The alias keyset for FuncTorchBatchedDecomposition is disjoint from + // all + // other alias keysets + // and so precedence order doesn't matter + FuncTorchBatchedDecomposition, // registered at + // build/aten/src/ATen/RegisterFuncTorchBatchedDecomposition.cpp + // Note: The alias keyset for CompositeImplicitAutogradNestedTensor is + // disjoint from all other alias keysets + CompositeImplicitAutogradNestedTensor, // registered at + // build/aten/src/ATen/RegisterCompositeImplicitAutogradNestedTensor.cpp + CompositeExplicitAutograd, // registered at + // build/aten/src/ATen/RegisterCompositeExplicitAutograd.cpp + // See Note [CompositeExplicitAutogradNonFunctional Key] + CompositeExplicitAutogradNonFunctional, // registered at + // build/aten/src/ATen/RegisterCompositeExplicitAutograd.cpp + + // Define an alias key to represent end of alias dispatch keys. + // If you add new alias keys after Autograd, please also update it here. + StartOfAliasKeys = Autograd, + EndOfAliasKeys = CompositeExplicitAutogradNonFunctional, // + + // ~~~~~~~~~~~~~~~~~~~~~~~~~ BC ALIASES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // + // The aliases exist for backwards compatibility reasons, they shouldn't + // be used + CPUTensorId = CPU, + CUDATensorId = CUDA, + DefaultBackend = CompositeExplicitAutograd, + PrivateUse1_PreAutograd = AutogradPrivateUse1, + PrivateUse2_PreAutograd = AutogradPrivateUse2, + PrivateUse3_PreAutograd = AutogradPrivateUse3, + Autocast = AutocastCUDA, +}; + +// Note [Private use DispatchKey] +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Private use tensor IDs are preallocated tensor type IDs for use in user +// applications. Similar to private use fields in HTTP, they can be used +// by end users for experimental or private applications, without needing +// to "standardize" the tensor ID (which would be done by submitting a PR +// to PyTorch to add your type ID). +// +// Private use tensor IDs are appropriate to use if you want to experiment +// with adding a new tensor type (without having to patch PyTorch first) or +// have a private, non-distributed application that needs to make use of a +// new tensor type. Private use tensor IDs are NOT appropriate to use for +// libraries intended to be distributed to further users: please contact +// the PyTorch developers to get a type ID registered in this case. +// +// We provide two classes of private user tensor id: regular DispatchKeys +// and Autograd DispatchKeys. DispatchKeys serve the role of ordinary "backend" +// DispatchKeys; if you were adding support for a new type of accelerator, you +// would use a backend DispatchKey, and ideally automatically reuse +// AutogradOther definitions already defined in PyTorch. AutogradPrivateUse +// DispatchKeys serve as "wrapper" DispatchKeys: they are only necessary for +// tensors that compose multiple internal tensors, and for cases when the +// built-in autograd formulas for operators are not appropriate. + +static_assert( + (static_cast(BackendComponent::EndOfBackendKeys) + + static_cast(DispatchKey::EndOfFunctionalityKeys)) <= 64, + "The BackendComponent and DispatchKey enums (below EndOfFunctionalityKeys)" + " both map to backend and functionality bits" + " into a 64-bit bitmask; you must have less than 64 total entries between them"); + +// Check if a DispatchKey is an alias mapping to other runtime keys. +constexpr bool isAliasDispatchKey(DispatchKey k) { + return k >= DispatchKey::StartOfAliasKeys && k <= DispatchKey::EndOfAliasKeys; +} + +// [Note: Per-Backend Functionality Dispatch Keys] +// Check if a DispatchKey is a per-backend functionality key +// Any functionalities that can be customized per-backend should be added here. +// These keys correspond to functionalities that can be customized individually +// per backend. While they only take up one bit in the `DispatchKeySet` bitset, +// they map to (# backends) slots in the operator table. +// Each of these keys also has a separate set of "runtime keys" in the dispatch +// key enum, per backend, which *do* map to the individual operator table slots. +// For example, the "Sparse" key maps to an individual bit in the +// DispatchKeySet, while `SparseCPU`, `SparseCUDA`, etc all map to individual +// slots in the runtime operator table. + +constexpr bool isPerBackendFunctionalityKey(DispatchKey k) { + if (k == DispatchKey::Dense || k == DispatchKey::Quantized || + k == DispatchKey::Sparse || k == DispatchKey::SparseCsr || + k == DispatchKey::AutogradFunctionality || + k == DispatchKey::NestedTensor) { + return true; + } else { + return false; + } +} + +// Note that this includes Undefined in the total count. +// BUT EndOfFunctionalityKeys is its own (placeholder) key. +// e.g. Undefined=0, Dense=1, Sparse=2, EndOfFunctionalityKeys=3. +// In the above example, there are 3 total functionality keys. +constexpr uint8_t num_functionality_keys = + static_cast(DispatchKey::EndOfFunctionalityKeys); + +constexpr uint8_t num_backends = + static_cast(BackendComponent::EndOfBackendKeys); + +// Note [No More Than 16 Backends] +// Search for this note to find places in the code where the "no more than 16 +// backends" invariant is baked in. +static_assert( + static_cast(BackendComponent::EndOfBackendKeys) <= 16, + "BackendComponent currently only supports <= 16 backends. If we really need to extend this, \ +there are a few places where this invariant is baked in"); + +constexpr uint8_t numPerBackendFunctionalityKeys() { + uint8_t count = 0; + for (uint8_t k = 0; k <= num_functionality_keys; ++k) { + if (isPerBackendFunctionalityKey(static_cast(k))) + ++count; + } + return count; +} + +#if defined(C10_MOBILE_TRIM_DISPATCH_KEYS) +// See [Note: Trimmed Mobile Dispatch Keys] +constexpr uint16_t num_runtime_entries = 8; +#else +constexpr uint16_t num_runtime_entries = num_functionality_keys + + (numPerBackendFunctionalityKeys() * (num_backends - 1)); +#endif + +// See Note [No More Than 16 Backends] +constexpr uint16_t full_backend_mask = + (static_cast(1) << num_backends) - 1; + +C10_API const char* toString(DispatchKey /*t*/); +C10_API const char* toString(BackendComponent /*t*/); +C10_API std::ostream& operator<<(std::ostream& /*str*/, DispatchKey /*rhs*/); +C10_API std::ostream& operator<<( + std::ostream& /*str*/, + BackendComponent /*rhs*/); + +C10_API DispatchKey getAutogradKeyFromBackend(BackendComponent k); + +// Parses a string into a dispatch key. +// If the string cannot be correctly parsed, throws an exception. +C10_API c10::DispatchKey parseDispatchKey(const std::string& k); + +// These are some convenience identifiers for dispatch keys which are +// shorter to type than their long counterparts. Note that some of these +// dispatch keys directly correspond to DeviceType; and most APIs that +// accept DispatchKey also accept DeviceType; e.g., +// torch::dispatch(torch::kCPU, ...) is also valid. +constexpr DispatchKey kAutograd = DispatchKey::Autograd; + +// See Note [The Ordering of Per-Backend Dispatch Keys Matters!] +// This function relies on the invariant that the dispatch keys between +// StartOfDenseBackends and EndOfRuntimeBackendKeys are ordered by backend +// in the same order as `BackendComponent`. +constexpr BackendComponent toBackendComponent(DispatchKey k) { + if (k >= DispatchKey::StartOfDenseBackends && + k <= DispatchKey::EndOfDenseBackends) { + return static_cast( + static_cast(k) - + static_cast(DispatchKey::StartOfDenseBackends)); + } else if ( + k >= DispatchKey::StartOfQuantizedBackends && + k <= DispatchKey::EndOfQuantizedBackends) { + return static_cast( + static_cast(k) - + static_cast(DispatchKey::StartOfQuantizedBackends)); + } else if ( + k >= DispatchKey::StartOfSparseBackends && + k <= DispatchKey::EndOfSparseBackends) { + return static_cast( + static_cast(k) - + static_cast(DispatchKey::StartOfSparseBackends)); + } else if ( + k >= DispatchKey::StartOfSparseCsrBackends && + k <= DispatchKey::EndOfSparseCsrBackends) { + return static_cast( + static_cast(k) - + static_cast(DispatchKey::StartOfSparseCsrBackends)); + } else if ( + k >= DispatchKey::StartOfNestedTensorBackends && + k <= DispatchKey::EndOfNestedTensorBackends) { + return static_cast( + static_cast(k) - + static_cast(DispatchKey::StartOfNestedTensorBackends)); + } else if ( + k >= DispatchKey::StartOfAutogradFunctionalityBackends && + k <= DispatchKey::EndOfAutogradFunctionalityBackends) { + return static_cast( + static_cast(k) - + static_cast( + DispatchKey::StartOfAutogradFunctionalityBackends)); + } else { + return BackendComponent::InvalidBit; + } +} + +constexpr DispatchKey toFunctionalityKey(DispatchKey k) { + if (k <= DispatchKey::EndOfFunctionalityKeys) { + return k; + } else if (k <= DispatchKey::EndOfDenseBackends) { + return DispatchKey::Dense; + } else if (k <= DispatchKey::EndOfQuantizedBackends) { + return DispatchKey::Quantized; + } else if (k <= DispatchKey::EndOfSparseBackends) { + return DispatchKey::Sparse; + } else if (k <= DispatchKey::EndOfSparseCsrBackends) { + return DispatchKey::SparseCsr; + } else if (k <= DispatchKey::EndOfNestedTensorBackends) { + return DispatchKey::NestedTensor; + } else if (k <= DispatchKey::EndOfAutogradFunctionalityBackends) { + return DispatchKey::AutogradFunctionality; + } else { + return DispatchKey::Undefined; + } +} + +BackendComponent toBackendComponent(DeviceType device_type); + +// Given (DispatchKey::Dense, BackendComponent::CUDABit), returns +// DispatchKey::CUDA. +// See Note [The Ordering of Per-Backend Dispatch Keys Matters!] +// This function relies on the invariant that the dispatch keys between +// StartOfDenseBackends and EndOfRuntimeBackendKeys are ordered by backend +// in the same order as `BackendComponent`. +constexpr DispatchKey toRuntimePerBackendFunctionalityKey( + DispatchKey functionality_k, + BackendComponent backend_k) { + if (functionality_k == DispatchKey::Dense) { + return static_cast( + static_cast(DispatchKey::StartOfDenseBackends) + + static_cast(backend_k)); + } + if (functionality_k == DispatchKey::Sparse) { + return static_cast( + static_cast(DispatchKey::StartOfSparseBackends) + + static_cast(backend_k)); + } + if (functionality_k == DispatchKey::SparseCsr) { + return static_cast( + static_cast(DispatchKey::StartOfSparseCsrBackends) + + static_cast(backend_k)); + } + if (functionality_k == DispatchKey::Quantized) { + return static_cast( + static_cast(DispatchKey::StartOfQuantizedBackends) + + static_cast(backend_k)); + } + if (functionality_k == DispatchKey::NestedTensor) { + return static_cast( + static_cast(DispatchKey::StartOfNestedTensorBackends) + + static_cast(backend_k)); + } + if (functionality_k == DispatchKey::AutogradFunctionality) { + return static_cast( + static_cast( + DispatchKey::StartOfAutogradFunctionalityBackends) + + static_cast(backend_k)); + } + return DispatchKey::Undefined; +} + +} // namespace c10 + +namespace torch { +// Expose the constant, but not the TYPE (DispatchKey is an implementation +// detail!) +// NOLINTNEXTLINE(misc-unused-using-decls) +using c10::kAutograd; +} // namespace torch + +// NB: You really shouldn't use this instance; this enum is guaranteed +// to be pretty small so a regular array should be acceptable. +namespace std { +template <> +struct hash { + typedef size_t result_type; + typedef c10::DispatchKey argument_type; + + size_t operator()(c10::DispatchKey x) const noexcept { + return static_cast(x); + } +}; +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DispatchKeySet.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DispatchKeySet.h new file mode 100644 index 0000000000000000000000000000000000000000..d1fecb157b4479d50f2f709d040765c9a00cd6fe --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DispatchKeySet.h @@ -0,0 +1,975 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-enum") + +namespace c10 { + +struct FunctionalityOffsetAndMask { + // empty constructor shouldn't be used; only needed to initialize + // the array before populating it. + FunctionalityOffsetAndMask() = default; + FunctionalityOffsetAndMask(uint16_t offset, uint16_t mask) + : offset(offset), mask(mask) {} + // This needs to big enough to cover the size of the operator table. + uint16_t offset{}; + // See Note [No More Than 16 Backends] + // This mask needs to be big enough to mask all of the backend bits. + // We probably don't ever want to have more than 16 backend bits, so uint16_t + // should be enough. + uint16_t mask{}; +}; +static_assert( + c10::num_runtime_entries < 65536, + "The dispatcher currently only supports up to 2^16 runtime entries"); + +C10_API std::array +initializeFunctionalityOffsetsAndMasks(); + +C10_ALWAYS_INLINE static const std:: + array& + offsetsAndMasks() { + static auto offsets_and_masks_ = initializeFunctionalityOffsetsAndMasks(); + return offsets_and_masks_; +} + +// A representation of a set of DispatchKeys. A DispatchKeySet contains both +// "functionality" bits and "backend bits", and every tensor holds its own +// DispatchKeySet. The Dispatcher implements multiple dispatch by grabbing the +// keyset on every input tensor, or’ing them together, and dispatching to a +// specific piece of functionality. The functionality bits are *ordered*. When +// multiple functionality bits are set, we use the highest priority +// functionality. Similarly, multiple backend bits can theoretically be set if +// you call an operator with multiple tensors from difference devices (e.g. CPU +// and CUDA), although support for mixed device dispatch is limited (the only +// kernels that gracefully handle mixed device inputs for now are cuda kernels +// that take in a scalar cpu tensor). + +// A representation of a set of DispatchKeys. A tensor may have multiple +// tensor type ids, e.g., a Variable tensor can also be a CPU tensor; the +// DispatchKeySet specifies what type ids apply. The internal representation is +// as a 64-bit bit set (this means only 64 tensor type ids are supported). +// +// As mentioned above, DispatchKeys are ordered; thus, we can ask questions like +// "what is the highest priority DispatchKey in the set"? (The set itself is +// not ordered; two sets with the same ids will always have the ids ordered in +// the same way.) +// +// Note [DispatchKeySet Internal Representation] +// Internally, dispatch keys are packed into 64-bit DispatchKeySet objects +// that get passed around at runtime. +// However, there isn't necessarily a 1-to-1 mapping between bits in the keyset +// and individual dispatch keys. +// +// First: why do we have this distinction, and why not map every dispatch key +// directly to a bit? This is mostly because we have several types of +// functionalities that different backends would like to customize. For example, +// we have: +// - "Dense": CPU, CUDA, XLA, ... (~12 keys) +// - "Sparse": SparseCPU, SparseCUDA, ... +// - "SparseCsr": SparseCsrCPU, SparseCsrCUDA, ... +// - "Quantized": QuantizedCPU, QuantizedCUDA, QuantizedXLA, ... +// - "Autograd": AutogradCPU, AutogradCUDA, Autograd XLA, ... +// The problem is that total number of keys grows quadratically with [# +// backends] x [# functionalities], making it very difficult to map each key +// directly to a bit in a bitset without dramatically increasing the size of the +// bitset over time. +// +// The two enums (BackendComponent and DispatchKey) can be divided roughly into +// 5 categories. +// +// (1) "Building block" keys +// (a) backends: Everything in the BackendComponent enum (e.g. CPUBit, +// CUDABit) (b) functionalities: (per-backend) functionality-bit DispatchKeys +// (e.g. AutogradFunctionality, SparseCsr, Sparse, Dense) +// (2) "Runtime" keys +// (a) "non-customizable backends" (e.g. FPGA) +// (b) "non-customizable functionalities" (e.g. Functionalize) +// (c) "per-backend instances of customizable functionalities" (e.g. CPU, +// SparseCPU, AutogradCPU) +// (3) "Alias" DispatchKeys (see Note [Alias Dispatch Keys]) +// +// (1) Building block keys always correspond to individual bits in a +// DispatchKeySet. They can also be combined in a DispatchKeySet to form actual +// runtime keys. e.g. +// auto dense_cpu_ks = DispatchKeySet({DispatchKey::CPUBit, +// DispatchKey::Dense}); +// // The keyset has the runtime dense-cpu key. +// dense_cpu_ks.has(DispatchKey::CPU); +// // And it contains the building block keys too. +// dense_cpu_ks.has(DispatchKey::CPUBit); +// dense_cpu_ks.has(DispatchKey::Dense); +// +// Not every backend and not every functionality counts as a "building block +// key". This is mostly to give us more levers to pull in the design space. +// Backend keys and functionality keys that count as "building blocks" will +// contribute to a full cross product of functionality that can be overridden. +// +// For example, right now we have at least 12 "backend" building +// blocks (CPU, CUDA, XLA, ...) and at least 5 "functionality" +// building blocks (Dense, Sparse, SparseCsr, Quantized, +// AutogradFunctionality, ...). These keys together allow every +// dispatcher operator to be customized in up to 12*4 different +// ways. Each of those requires a slot in the operator table of every +// dispatcher operator. Not every piece of functionality necessarily +// needs to be customizable per-backend, and not every backend +// necessarily needs to be able to customize every type of +// functionality. +// +// +// (2) Every runtime key corresponds directly to a slot in an operator's runtime +// dispatch table, and you can directly register kernels to a runtime dispatch +// key. +// +// For per-backend functionalities like "Dense" or "AutogradFunctionality", +// you can think of the corresponding runtime dispatch keys as "instances" of +// that functionality, per backend. E.g. "CPU", "CUDA", "XLA", etc. are all +// runtime instances of the "Dense" building block key. + +// (2a) and (2b) are represented identically in the DispatchKeySet logic: +// - backend-agnostic functionalities (e.g. FuncTorchBatched) are NOT +// customizable per backend. +// In order to do so, we'd need to promote it to a per-backend functionality +// "building block" key. +// - non-customizable backends (e.g. FPGA) can NOT customize existing +// functionality like Sparse, Autograd, etc. +// In order to do so, we'd need to promote it to a backend "building block" +// key. +// +// In both cases, these keys directly correspond to runtime slots in the +// operator table. +// +// +// (3) "Alias" keys +// See Note [Alias Dispatch Keys] +// +// Final note: for anyone making future changes to the Dispatcher + +// DispatchKeySet internals, there's a closed PR with a basic +// python-implementation of the Dispatcher that might be useful in quickly +// testing out and validating changes. See it at +// https://github.com/pytorch/pytorch/pull/68743 + +// An undefined tensor is one with an empty tensor type set. +class DispatchKeySet final { + public: + enum Full { FULL }; + enum FullAfter { FULL_AFTER }; + enum Raw { RAW }; + + // NB: default constructor representation as zero is MANDATORY as + // use of DispatchKeySet in TLS requires this. + constexpr DispatchKeySet() = default; + + constexpr DispatchKeySet(Full /*unused*/) + : repr_((1ULL << (num_backends + num_functionality_keys - 1)) - 1) {} + + constexpr DispatchKeySet(FullAfter /*unused*/, DispatchKey t) + // LSB after t are OK, but not t itself. + // "functionalities" have a notion of ordering (e.g. Autograd > Sparse > + // Quantized > Dense). But backends don't really have an ordering. + // Therefore, we're enforcing that FullAfter can only be used on + // "functionality" keys. + : repr_( + (1ULL + << (num_backends + static_cast(toFunctionalityKey(t)) - + 1)) - + 1) { + *this = add(DispatchKey::PythonDispatcher); + } + + // Public version of DispatchKeySet(uint64_t) API; external users + // must be explicit when they do this! + constexpr DispatchKeySet(Raw /*unused*/, uint64_t x) : repr_(x) {} + + constexpr explicit DispatchKeySet(BackendComponent k) { + if (k == BackendComponent::InvalidBit) { + repr_ = 0; + } else { + repr_ = 1ULL << (static_cast(k) - 1); + } + } + + constexpr explicit DispatchKeySet(DispatchKey k) { + // NOLINTNEXTLINE(bugprone-branch-clone) + if (k == DispatchKey::Undefined) { + // Case 1: handle Undefined specifically + repr_ = 0; + } else if (k <= DispatchKey::EndOfFunctionalityKeys) { + // Case 2: handle "functionality-only" keys + // These keys have a functionality bit set, but no backend bits + // These can technically be either: + // - valid runtime keys (e.g. DispatchKey::AutogradOther, + // DispatchKey::FuncTorchBatched, etc) + // - "building block" keys that aren't actual runtime keys (e.g. + // DispatchKey::Dense or Sparse) + uint64_t functionality_val = 1ULL + << (num_backends + static_cast(k) - 1); + repr_ = functionality_val; + } else if (k <= DispatchKey::EndOfRuntimeBackendKeys) { + // Case 3: "runtime" keys that have a functionality bit AND a backend bit. + // First compute which bit to flip for the functionality. + auto functionality_k = toFunctionalityKey(k); + // The - 1 is because Undefined is technically a "functionality" that + // doesn't show up in the bitset. So e.g. Dense is technically the second + // functionality, but the lowest functionality bit. + uint64_t functionality_val = 1ULL + << (num_backends + static_cast(functionality_k) - 1); + + // then compute which bit to flip for the backend + // Case 4a: handle the runtime instances of "per-backend functionality" + // keys For example, given DispatchKey::CPU, we should set: + // - the Dense functionality bit + // - the CPUBit backend bit + // first compute which bit to flip for the backend + auto backend_k = toBackendComponent(k); + uint64_t backend_val = backend_k == BackendComponent::InvalidBit + ? 0 + : 1ULL << (static_cast(backend_k) - 1); + repr_ = functionality_val + backend_val; + } else { + // At this point, we should have covered every case except for alias keys. + // Technically it would be possible to add alias dispatch keys to a + // DispatchKeySet, but the semantics are a little confusing and this + // currently isn't needed anywhere. + repr_ = 0; + } + } + + constexpr uint64_t keys_to_repr(std::initializer_list ks) { + uint64_t repr = 0; + for (auto k : ks) { + repr |= DispatchKeySet(k).repr_; + } + return repr; + } + + constexpr uint64_t backend_bits_to_repr( + std::initializer_list ks) { + uint64_t repr = 0; + for (auto k : ks) { + repr |= DispatchKeySet(k).repr_; + } + return repr; + } + + explicit constexpr DispatchKeySet(std::initializer_list ks) + : repr_(keys_to_repr(ks)) {} + + explicit constexpr DispatchKeySet(std::initializer_list ks) + // Note: for some reason, putting this logic directly in the constructor + // appears to fail to compile on CUDA 10.1. + // See an example internal failure at + // https://www.internalfb.com/intern/skycastle/run/76561193669136035/artifact/actionlog.76561193742069401.stderr + : repr_(backend_bits_to_repr(ks)) {} + + // Test if a DispatchKey is in the set + inline bool has(DispatchKey t) const { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(t != DispatchKey::Undefined); + return has_all(DispatchKeySet(t)); + } + constexpr bool has_backend(BackendComponent t) const { + return has_all(DispatchKeySet(t)); + } + + // Test if a DispatchKey is in the set + // Given a DispatchKeySet of functionality keys and (potentially) backend + // keys, tests if all of them are in the current set. + constexpr bool has_all(DispatchKeySet ks) const { + return static_cast((repr_ & ks.repr_) == ks.repr_); + } + + // Given a DispatchKeySet of functionality keys and (potentially) backend + // keys, tests if any of them are in the current set. This could technically + // be pretty easily implemented using has(). It is strictly a perf + // optimization though. There are many places in the code base where we want + // to test for multiple functionality keys together. HOWEVER, runtime + // per-backend functionality keys aren't allowed to be used with this + // function, because you can end up with weird results. e.g. + // DispatchKeySet(DispatchKey::AutogradCPU).has_any(DispatchKeySet(DispatchKey::CPU)) + // would return true. + inline bool has_any(DispatchKeySet ks) const { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + // Either there are no backend bits in the input keyset + ((ks.repr_ & full_backend_mask) == 0) || + // or there are no per-backend-functionality bits + // See [Note: Per-Backend Functionality Dispatch Keys] + ((ks & + DispatchKeySet({ + DispatchKey::Dense, + DispatchKey::Quantized, + DispatchKey::Sparse, + DispatchKey::SparseCsr, + DispatchKey::AutogradFunctionality, + }) + .repr_) == 0)); + return static_cast((repr_ & ks.repr_) != 0); + } + // Test if DispatchKeySet is a superset of ks. + bool isSupersetOf(DispatchKeySet ks) const { + return (repr_ & ks.repr_) == ks.repr_; + } + // Perform set union + constexpr DispatchKeySet operator|(DispatchKeySet other) const { + return DispatchKeySet(repr_ | other.repr_); + } + // Perform set intersection + constexpr DispatchKeySet operator&(DispatchKeySet other) const { + return DispatchKeySet(repr_ & other.repr_); + } + // Compute the set difference self - other, + // but ONLY for the functionality keys. + // Any backend bits set on self will remain unchanged. + // See Note [Removing keys from DispatchKeySet Only Affects Functionality + // Keys] + constexpr DispatchKeySet operator-(DispatchKeySet other) const { + return DispatchKeySet(repr_ & (full_backend_mask | ~other.repr_)); + } + + // Compute self ^ other + constexpr DispatchKeySet operator^(DispatchKeySet other) const { + return DispatchKeySet(repr_ ^ other.repr_); + } + bool operator==(DispatchKeySet other) const { + return repr_ == other.repr_; + } + bool operator!=(DispatchKeySet other) const { + return repr_ != other.repr_; + } + // Add a DispatchKey to the DispatchKey set. Does NOT mutate, + // returns the extended DispatchKeySet! + [[nodiscard]] constexpr DispatchKeySet add(DispatchKey t) const { + return *this | DispatchKeySet(t); + } + [[nodiscard]] constexpr DispatchKeySet add(DispatchKeySet ks) const { + return *this | ks; + } + + // Remove a DispatchKey from the DispatchKey set. + // This is generally not an operation you should be doing + // (it's used to implement the printing overload, operator<<) + // + // Note [Removing keys from DispatchKeySet Only Affects Functionality Keys] + // Only functionality bits are allowed to be removed from a keyset. + // For now, we're only allowing removal of "functionality bits" from the + // keyset, which is specifically needed by the fallthrough key calculation + // logic. Why is removing backend bits problematic? Consider this example: + // + // DispatchKeySet([DispatchKey.CPU, DispatchKey.AutogradCUDA, + // DispatchKey.CUDA]).remove(DispatchKey.AutogradCUDA) + // DispatchKeySet([DispatchKey.CPU, + // DispatchKey.AutogradCUDA]).remove(DispatchKey.AutogradCUDA) + // + // What do we want to happen? + // Technically, we'd like it to be true that after removal, + // the first keyset still has the CUDA dispatch key while the second doesn't. + // Unfortunately there's no way to represent that, because the two keysets are + // represented the same way internally: functionality bits: Autograd, Dense + // backend bits: CPU, CUDA + // + // Instead, remove(DispatchKey.AutogradCPU) will only remove the "Autograd" + // bit from the bitset. + [[nodiscard]] constexpr DispatchKeySet remove(DispatchKey t) const { + return DispatchKeySet( + repr_ & ~(DispatchKeySet(t).repr_ & ~full_backend_mask)); + } + // You're allowed to remove a backend bit from a DispatchKeySet, + // but you have to be explicit about it (remove_backend() instead of + // remove()). + constexpr DispatchKeySet remove_backend(BackendComponent b) const { + return DispatchKeySet(repr_ & ~(DispatchKeySet(b).repr_)); + } + // Is the set empty? (AKA undefined tensor) + bool empty() const { + return repr_ == 0; + } + uint64_t raw_repr() const { + return repr_; + } + + static DispatchKeySet from_raw_repr(uint64_t x) { + return DispatchKeySet(RAW, x); + } + + DispatchKey highestFunctionalityKey() const { + auto functionality_idx = indexOfHighestBit(); + // This means that none of the functionality bits were set. + if (functionality_idx < num_backends) + return DispatchKey::Undefined; + // The first num_backend bits in the keyset don't correspond to real + // dispatch keys. + return static_cast(functionality_idx - num_backends); + } + + // This is similar like toBackendComponent(DispatchKey), but less restrictive. + // toBackendComponent() errors out if the key that it was passed has no + // backend bits, which is useful for error checking. We need a version of that + // here that can also handle "fake" backends like FPGA, because they need to + // map to the AutogradOther key. For those backends, we return + // BackendComponent::InvalidBit. + BackendComponent highestBackendKey() const { + // mask to mask out functionality bits + auto backend_idx = + DispatchKeySet(repr_ & full_backend_mask).indexOfHighestBit(); + // all zeros across the backend bits means that no backend bits are set. + if (backend_idx == 0) + return BackendComponent::InvalidBit; + return static_cast(backend_idx); + } + + // returns the DispatchKey of highest priority in the set. + DispatchKey highestPriorityTypeId() const { + auto functionality_k = highestFunctionalityKey(); + if (isPerBackendFunctionalityKey(functionality_k)) { + return toRuntimePerBackendFunctionalityKey( + functionality_k, highestBackendKey()); + } + return functionality_k; + } + + // Returns the index of the most-significant bit in the keyset. + // This is used to as part of the calculation into the operator table to get: + // - the highest "functionality" bit in the keyset. + // - the highest "backend" bit in the keyset. + uint8_t indexOfHighestBit() const { + return 64 - llvm::countLeadingZeros(repr_); + } + +#if defined(C10_MOBILE_TRIM_DISPATCH_KEYS) + // [Note: Trimmed Mobile Dispatch Keys] + /** + * The method below maps the dispatch key in the enum DispatchKey to an + * integer index in the dispatchTable_ array in OperatorEntry. The array + * is trimmed for mobile to reduce peak memory usage since it's + * unnecessary to reserve additional space for dispatch keys that will + * never be used on mobile. + */ + int getDispatchTableIndexForDispatchKeySet() const { + auto dk = highestPriorityTypeId(); + switch (dk) { + case DispatchKey::Undefined: + return 0; + case DispatchKey::CPU: + return 1; + case DispatchKey::QuantizedCPU: + return 2; + case DispatchKey::SparseCPU: + return 3; + case DispatchKey::BackendSelect: + return 4; + case DispatchKey::ADInplaceOrView: + return 5; + case DispatchKey::AutogradOther: + return 6; + case DispatchKey::AutogradCPU: + return 7; + default: + return -1; + } + } +#else + // returns the index in the operator table of highest priority key in the the + // keyset Note that we could in theory implement this using + // highestPriorityTypeId(), but this code is very hotpath and we can do it + // faster without it. + int getDispatchTableIndexForDispatchKeySet() const { + auto functionality_idx = + DispatchKeySet(repr_ >> num_backends).indexOfHighestBit(); + auto offset_and_mask = offsetsAndMasks()[functionality_idx]; + // Mask the functionality bits out first, then right-shift by 1. + // right-shifting by 1 because everything is zero-indexed. + // E.g. 000001 (CPU) should give us an offset of 0, 000010 (CUDA) should + // give us an offset of 1, etc. + auto backend_idx = + DispatchKeySet((repr_ & offset_and_mask.mask) >> 1).indexOfHighestBit(); + return offset_and_mask.offset + backend_idx; + } +#endif + + // returns the "index" of the highest priority backend in the keyset. + // This is pretty similar to getBackendKey(), but: + // - It's hotpath code (part of the runtime bitset calculation) + // - I's returns an integer index, not an enum value + // - Everything is shifted to the right by 1. + // BackendComponent::InvalidBit is technically the lowest enum value, + // but it isn't included in the runtime table. So CPUBit = 1, CUDABit = 2, + // etc. + uint64_t getBackendIndex() const { + return DispatchKeySet((repr_ & full_backend_mask) >> 1).indexOfHighestBit(); + } + + private: + constexpr DispatchKeySet(uint64_t repr) : repr_(repr) {} + uint64_t repr_ = 0; + + public: + // STL iterator for DispatchKeySet. Iterates through all runtime DispatchKeys + // in the set. The iterator is only invalidated by the destruction of the + // underlying DispatchKeySet as the iterator stores a pointer to the raw + // representation of the DispatchKeySet. Note: When we encounter a per-backend + // functionality (e.g. Dense or Sparse), we will iterate through EVERY backend + // in the keyset, for that functionality. For example, if the next + // functionality key to iterate over is Autograd, and the backend bits in the + // keyset correspond to [BackendComponent::CPUBit, BackendComponent::CUDABit], + // then the next two keys we return will be DispatchKey::AutogradCPU, + // DispatchKey::AutogradCUDA (CPU first because it has lower precedence than + // CUDA in DispatchKey.h). + class iterator { + public: + using self_type = iterator; + using iterator_category = std::input_iterator_tag; + using value_type = DispatchKey; + using difference_type = ptrdiff_t; + using reference = value_type&; + using pointer = value_type*; + // final mask value should mask out the entire keyset + static constexpr uint8_t end_iter_mask_val = + num_backends + num_functionality_keys; + // final key value should be the last DispatchKey + static constexpr uint8_t end_iter_key_val = num_functionality_keys; + + // current_dispatchkey_idx_ will iterate through all functionality bits. + // current_backendcomponent_idx_ will iterate through all backend bits. + explicit iterator( + const uint64_t* data_ptr, + uint8_t next_functionality = num_backends, + uint8_t next_backend = 0) + : data_ptr_(data_ptr), + next_functionality_(next_functionality), + next_backend_(next_backend) { + // Go to the first key in the set + TORCH_INTERNAL_ASSERT( + next_functionality_ >= num_backends, + "num_backends=", + static_cast(num_backends), + "next_functionality_=", + static_cast(next_functionality_)); + ++(*this); + } + + C10_API self_type& operator++(); + + self_type operator++(int) { + self_type previous_iterator = *this; + ++(*this); + return previous_iterator; + } + + bool operator==(const self_type& rhs) const { + return next_functionality_ == rhs.next_functionality_ && + current_dispatchkey_idx_ == rhs.current_dispatchkey_idx_ && + next_backend_ == rhs.next_backend_ && + current_backendcomponent_idx_ == rhs.current_backendcomponent_idx_; + } + bool operator!=(const self_type& rhs) const { + return next_functionality_ != rhs.next_functionality_ || + current_dispatchkey_idx_ != rhs.current_dispatchkey_idx_ || + next_backend_ != rhs.next_backend_ || + current_backendcomponent_idx_ != rhs.current_backendcomponent_idx_; + } + DispatchKey operator*() const { + auto functionality_key = + static_cast(current_dispatchkey_idx_); + if (isPerBackendFunctionalityKey(functionality_key)) { + auto next_key = toRuntimePerBackendFunctionalityKey( + functionality_key, + static_cast(current_backendcomponent_idx_)); + // We expect all of the Dense, Sparse, Quantized, and Autograd keys to + // be ordered the same way with respect to their backends + TORCH_INTERNAL_ASSERT( + toBackendComponent(next_key) == + static_cast(current_backendcomponent_idx_), + "Tried to map functionality key ", + toString(functionality_key), + " and backend bit ", + toString( + static_cast(current_backendcomponent_idx_)), + " to a runtime key, but ended up with ", + toString(next_key), + ". This can happen if the order of the backend dispatch keys in DispatchKey.h isn't consistent.", + " Please double check that enum for inconsistencies."); + return next_key; + } else { + return functionality_key; + } + } + + private: + const uint64_t* data_ptr_; + uint8_t next_functionality_; + uint8_t next_backend_; + // These are in an invalid state at construction time, and set by the + // first increment call + uint8_t current_dispatchkey_idx_{end_iter_key_val}; + uint8_t current_backendcomponent_idx_{end_iter_key_val}; + }; + + public: + // Returns iterator to the first key in the set. If no keys are in the + // set, then will return the end iterator. + iterator begin() const { + return iterator(&repr_); + } + + // We do not need to iterate beyond EndOfFunctionalityKeys so we will treat + // this as the end iterator. + iterator end() const { + return iterator(&repr_, iterator::end_iter_mask_val); + } +}; + +C10_API std::string toString(DispatchKeySet /*ts*/); +C10_API std::ostream& operator<<(std::ostream& /*os*/, DispatchKeySet /*ts*/); + +inline int getDispatchTableIndexForDispatchKey(DispatchKey k) { + return DispatchKeySet(k).getDispatchTableIndexForDispatchKeySet(); +} + +// Alias key DispatchKey::Autograd maps to +// (autograd_dispatch_keyset x full_backend_mask) +// NB: keys in this set also get associated with CompositeImplicitAutograd +// +// Note [autograd_dispatch_keyset Does Not Include Backend Bits] +// We don't want to include any backend bits (BackendComponent::CPUBit, etc) +// directly in autograd_dispatch_keyset. +// Why? keysets like autograd_dispatch_keyset are commonly used to remove +// autograd keys from a DispatchKeySet throughout the code base. However, you +// are only allowed to remove functionality bits from a keyset, not backend +// bits. See Note [Removing keys from DispatchKeySet Only Affects Functionality +// Keys] for details. To be consistent and avoid confusion, we're explicitly +// setting up autograd_dispatch_keyset to not have any backend bits. +constexpr DispatchKeySet autograd_dispatch_keyset = DispatchKeySet({ + DispatchKey::AutogradFunctionality, + DispatchKey::AutogradOther, + DispatchKey::AutogradNestedTensor, +}); + +constexpr DispatchKeySet autocast_dispatch_keyset = DispatchKeySet({ + DispatchKey::AutocastCPU, + DispatchKey::AutocastMPS, + DispatchKey::AutocastCUDA, + DispatchKey::AutocastXPU, + DispatchKey::AutocastIPU, + DispatchKey::AutocastHPU, + DispatchKey::AutocastXLA, + DispatchKey::AutocastPrivateUse1, + DispatchKey::AutocastMTIA, + DispatchKey::AutocastMAIA, +}); + +// See Note [TLS Initialization] +constexpr DispatchKeySet default_included_set = DispatchKeySet({ + DispatchKey::BackendSelect, + DispatchKey::ADInplaceOrView, +}); + +constexpr DispatchKeySet default_excluded_set = DispatchKeySet({ + DispatchKey::AutocastCPU, + DispatchKey::AutocastMPS, + DispatchKey::AutocastCUDA, + DispatchKey::AutocastXPU, + DispatchKey::AutocastIPU, + DispatchKey::AutocastHPU, + DispatchKey::AutocastXLA, + DispatchKey::AutocastPrivateUse1, + DispatchKey::AutocastMTIA, + DispatchKey::AutocastMAIA, +}); + +constexpr DispatchKeySet autograd_dispatch_keyset_with_ADInplaceOrView = + autograd_dispatch_keyset | DispatchKeySet(DispatchKey::ADInplaceOrView); + +constexpr DispatchKeySet python_ks = DispatchKeySet({ + DispatchKey::Python, + DispatchKey::PythonTLSSnapshot, +}); + +constexpr DispatchKeySet sparse_ks = DispatchKeySet(DispatchKey::Sparse); + +constexpr DispatchKeySet sparse_csr_ks = DispatchKeySet(DispatchKey::SparseCsr); + +constexpr DispatchKeySet mkldnn_ks = DispatchKeySet(DispatchKey::MkldnnCPU); + +// backend dispatch keys that map to DispatchKey::AutogradOther +// NB: keys in this set also get associated with CompositeImplicitAutograd +constexpr DispatchKeySet autogradother_backends = + DispatchKeySet( + // HIP and VE aren't in this list: they now have their own backend bits + // which means that they can now have their own Autograd keys. + // Technically, HIP will now redispatch to its own custom AutogradHIP + // slot in the runtime table. + {DispatchKey::FPGA, + DispatchKey::Vulkan, + DispatchKey::Metal, + DispatchKey::CustomRNGKeyId, + DispatchKey::MkldnnCPU, + // Sparse and Quantized backends also live here. + DispatchKey::Sparse, + DispatchKey::SparseCsr, + DispatchKey::Quantized}) + // Including the backend bits because this keyset is used during op + // registration, which requires looping over all runtime autogradother + // backend keys. + | DispatchKeySet(DispatchKeySet::RAW, full_backend_mask); + +// The set of dispatch keys that come after autograd +// n.b. this relies on the fact that AutogradOther is currently the lowest +// Autograd key +constexpr DispatchKeySet after_autograd_keyset = + DispatchKeySet(DispatchKeySet::FULL_AFTER, c10::DispatchKey::AutogradOther); + +// The set of dispatch keys that come after ADInplaceOrView +constexpr DispatchKeySet after_ADInplaceOrView_keyset = DispatchKeySet( + DispatchKeySet::FULL_AFTER, + c10::DispatchKey::ADInplaceOrView); + +// The set of dispatch keys that come after Functionalize +constexpr DispatchKeySet after_func_keyset = + DispatchKeySet(DispatchKeySet::FULL_AFTER, c10::DispatchKey::Functionalize) + .remove( + // NOTE: we also need to remove ADInplaceOrView from the keyset when + // redispatching after the func kernels. This is because we're not + // calling the same op; we originally called an inplace op, and now + // we aren't. The original key calculation figured out which keys + // were Fallthrough based on the inplace op. That means that it did + // not include the ADInPlaceOrView kernel as a fallthrough key. + // However, we WANT the ADInPlaceOrView kernel to be ignored now + // that we're calling an out-of-place op. Re-invoking + // Dispatcher::call would re-run the Fallthrough key calculation and + // get us that, But at::redispatch is more performant. We can get + // away with it by explicitly removing the key here. + c10::DispatchKey::ADInplaceOrView); + +constexpr DispatchKeySet backend_bitset_mask = + DispatchKeySet(DispatchKeySet::RAW, (1ULL << num_backends) - 1); + +constexpr auto inplace_or_view_ks = + DispatchKeySet(DispatchKey::ADInplaceOrView); +constexpr auto autograd_cpu_ks = DispatchKeySet(DispatchKey::AutogradCPU); +constexpr auto autograd_ipu_ks = DispatchKeySet(DispatchKey::AutogradIPU); +constexpr auto autograd_mtia_ks = DispatchKeySet(DispatchKey::AutogradMTIA); +constexpr auto autograd_maia_ks = DispatchKeySet(DispatchKey::AutogradMAIA); +constexpr auto autograd_xpu_ks = DispatchKeySet(DispatchKey::AutogradXPU); +constexpr auto autograd_cuda_ks = DispatchKeySet(DispatchKey::AutogradCUDA); +constexpr auto autograd_xla_ks = DispatchKeySet(DispatchKey::AutogradXLA); +constexpr auto autograd_lazy_ks = DispatchKeySet(DispatchKey::AutogradLazy); +constexpr auto autograd_meta_ks = DispatchKeySet(DispatchKey::AutogradMeta); +constexpr auto autograd_mps_ks = DispatchKeySet(DispatchKey::AutogradMPS); +constexpr auto autograd_hpu_ks = DispatchKeySet(DispatchKey::AutogradHPU); +constexpr auto autograd_privateuse1_ks = + DispatchKeySet(DispatchKey::AutogradPrivateUse1); +constexpr auto autograd_privateuse2_ks = + DispatchKeySet(DispatchKey::AutogradPrivateUse2); +constexpr auto autograd_privateuse3_ks = + DispatchKeySet(DispatchKey::AutogradPrivateUse3); +constexpr auto autograd_other_ks = DispatchKeySet(DispatchKey::AutogradOther); +constexpr auto autograd_nested = + DispatchKeySet(DispatchKey::AutogradNestedTensor); +// keyset corresponding to functorch keys that have their own dedicated +// TensorImpl subclass. +constexpr auto functorch_transforms_ks = DispatchKeySet( + {DispatchKey::FuncTorchBatched, + DispatchKey::FuncTorchVmapMode, + DispatchKey::Batched, + DispatchKey::VmapMode, + DispatchKey::FuncTorchGradWrapper}); + +constexpr auto functorch_batched_ks = + DispatchKeySet({DispatchKey::FuncTorchBatched}); + +// This keyset has: +// (1) the functionality bits corresponding to backends (dense, sparse, +// quantized) (2) all of the backend bits set +constexpr DispatchKeySet backend_functionality_keys = + DispatchKeySet({ + DispatchKey::Dense, + DispatchKey::Quantized, + DispatchKey::Sparse, + DispatchKey::SparseCsr, + }) | + DispatchKeySet(DispatchKeySet::RAW, full_backend_mask); + +struct OpTableOffsetAndMask { + uint16_t offset; + uint16_t backend_mask; +}; + +static_assert( + num_backends <= 16, + "Right now we expect the number of backends not to exceed 16. In the (unlikely) event" + " that this changes, the size of OpTableOffsetAndMask::backend_mask needs to be increased too."); + +// true if t is a backend dispatch key +C10_API bool isBackendDispatchKey(DispatchKey t); + +// Resolve alias dispatch key to DispatchKeySet if applicable +C10_API DispatchKeySet getRuntimeDispatchKeySet(DispatchKey t); + +// Resolve alias dispatch key to DispatchKeySet if applicable, +// and check if k is a part of that set +C10_API bool runtimeDispatchKeySetHas(DispatchKey t, DispatchKey k); + +// Returns a DispatchKeySet of all backend keys mapped to Autograd dispatch key +// t, DispatchKeySet is empty if t is not alias of DispatchKey::Autograd. +C10_API DispatchKeySet getBackendKeySetFromAutograd(DispatchKey t); + +// Returns a DispatchKeySet of autograd related keys mapped to backend. +// for a given backend key, use the associated autograd key. +// for non-backend keys, use AutogradOther as a default. +// Note: it's convenient and fast to return a default here rather than (say) +// returning an std::optional, or throwing. But it makes callers +// responsible for either a) enforcing the invariant that only backend keys +// be passed as arguments, or b) interpreting our return value carefully. +inline DispatchKeySet getAutogradRelatedKeySetFromBackend(BackendComponent t) { + switch (t) { + case BackendComponent::CPUBit: + return inplace_or_view_ks | autograd_cpu_ks; + case BackendComponent::IPUBit: + return inplace_or_view_ks | autograd_ipu_ks; + case BackendComponent::MTIABit: + return inplace_or_view_ks | autograd_mtia_ks; + case BackendComponent::MAIABit: + return inplace_or_view_ks | autograd_maia_ks; + case BackendComponent::XPUBit: + return inplace_or_view_ks | autograd_xpu_ks; + case BackendComponent::CUDABit: + return inplace_or_view_ks | autograd_cuda_ks; + case BackendComponent::XLABit: + return inplace_or_view_ks | autograd_xla_ks; + case BackendComponent::LazyBit: + return inplace_or_view_ks | autograd_lazy_ks; + case BackendComponent::MetaBit: + return inplace_or_view_ks | autograd_meta_ks; + case BackendComponent::MPSBit: + return inplace_or_view_ks | autograd_mps_ks; + case BackendComponent::HPUBit: + return inplace_or_view_ks | autograd_hpu_ks; + case BackendComponent::PrivateUse1Bit: + return inplace_or_view_ks | autograd_privateuse1_ks; + case BackendComponent::PrivateUse2Bit: + return inplace_or_view_ks | autograd_privateuse2_ks; + case BackendComponent::PrivateUse3Bit: + return inplace_or_view_ks | autograd_privateuse3_ks; + default: + return inplace_or_view_ks | autograd_other_ks; + } +} + +// Returns a DispatchKeySet of autocast related keys mapped to backend. +inline DispatchKeySet getAutocastRelatedKeySetFromBackend(BackendComponent t) { + constexpr auto autocast_cpu_ks = DispatchKeySet(DispatchKey::AutocastCPU); + constexpr auto autocast_mtia_ks = DispatchKeySet(DispatchKey::AutocastMTIA); + constexpr auto autocast_maia_ks = DispatchKeySet(DispatchKey::AutocastMAIA); + constexpr auto autocast_xpu_ks = DispatchKeySet(DispatchKey::AutocastXPU); + constexpr auto autocast_ipu_ks = DispatchKeySet(DispatchKey::AutocastIPU); + constexpr auto autocast_hpu_ks = DispatchKeySet(DispatchKey::AutocastHPU); + constexpr auto autocast_cuda_ks = DispatchKeySet(DispatchKey::AutocastCUDA); + constexpr auto autocast_xla_ks = DispatchKeySet(DispatchKey::AutocastXLA); + constexpr auto autocast_privateuse1_ks = + DispatchKeySet(DispatchKey::AutocastPrivateUse1); + constexpr auto autocast_mps_ks = DispatchKeySet(DispatchKey::AutocastMPS); + switch (t) { + case BackendComponent::CPUBit: + return autocast_cpu_ks; + case BackendComponent::MTIABit: + return autocast_mtia_ks; + case BackendComponent::MAIABit: + return autocast_maia_ks; + case BackendComponent::XPUBit: + return autocast_xpu_ks; + case BackendComponent::IPUBit: + return autocast_ipu_ks; + case BackendComponent::HPUBit: + return autocast_hpu_ks; + case BackendComponent::CUDABit: + return autocast_cuda_ks; + case BackendComponent::XLABit: + return autocast_xla_ks; + case BackendComponent::PrivateUse1Bit: + return autocast_privateuse1_ks; + case BackendComponent::MPSBit: + return autocast_mps_ks; + default: + return DispatchKeySet(); + } +} + +// returns the "backend" DispatchKey of highest priority in the set. +// This is basically like highestBackendKey(), except that we have some +// "functionality" bits that correspond to backends (Sparse, Quantized) +inline DispatchKey highestPriorityBackendTypeId(DispatchKeySet ks) { + return (ks & backend_functionality_keys).highestPriorityTypeId(); +} + +// This API exists because we have a use case for checking +// getRuntimeDispatchKeySet(alias).has(DispatchKey::Undefined) +// in OperatorEntry.cpp but we disallow it in has() API. +C10_API bool isIncludedInAlias(DispatchKey k, DispatchKey alias); + +// Historically, every tensor only had a single DispatchKey, and it was always +// something like CPU, and there wasn't any of this business where TLS +// could cause the DispatchKey of a tensor to change. But we still have some +// legacy code that is still using DispatchKey for things like instanceof +// checks; if at all possible, refactor the code to stop using DispatchKey in +// those cases. +inline DispatchKey legacyExtractDispatchKey(DispatchKeySet s) { + // NB: If you add any extra keys that can be stored in TensorImpl on + // top of existing "backend" keys like CPU/CUDA, you need to add it + // here. At the moment, autograd keys and ADInplaceOrView key need this + // treatment; + return (s - autograd_dispatch_keyset_with_ADInplaceOrView - + autocast_dispatch_keyset - + DispatchKeySet( + {DispatchKey::Functionalize, + DispatchKey::PythonTLSSnapshot, + DispatchKey::FuncTorchGradWrapper, + DispatchKey::FuncTorchVmapMode, + DispatchKey::FuncTorchBatched, + DispatchKey::Python})) + .highestPriorityTypeId(); +} + +template +using is_not_DispatchKeySet = std::negation>; + +// Given a function type, constructs a function_traits type that drops the first +// parameter type if the first parameter is of type DispatchKeySet. NB: +// DispatchKeySet is currently explicitly hidden from JIT (mainly to avoid +// pushing unnecessary arguments on the stack - see Note [ Plumbing Keys Through +// the Dispatcher] for details). If at any point in the future we need to expose +// this type to JIT, revisit the usage of this type alias. +template +using remove_DispatchKeySet_arg_from_func = guts::make_function_traits_t< + typename guts::infer_function_traits_t::return_type, + typename std::conditional_t< + std::is_same_v< + DispatchKeySet, + typename guts::typelist::head_with_default_t< + void, + typename guts::infer_function_traits_t< + FuncType>::parameter_types>>, + guts::typelist::drop_if_nonempty_t< + typename guts::infer_function_traits_t::parameter_types, + 1>, + typename guts::infer_function_traits_t::parameter_types>>; +} // namespace c10 + +C10_DIAGNOSTIC_POP() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DynamicCast.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DynamicCast.h new file mode 100644 index 0000000000000000000000000000000000000000..d0f0f0b27c97bf7521a09fae5c6d7c04d9e0b46e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/DynamicCast.h @@ -0,0 +1,134 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +namespace c10 { + +// Dynamic type casting utils: +// - fetch_and_cast +// - cast_and_store +// +// fetch_and_cast fetch a value with dynamic type specified by a ScalarType +// from a void pointer and cast it to a static type. +// +// cast_and_store casts a static typed value into dynamic type specified +// by a ScalarType, and store it into a void pointer. +// +// NOTE: +// +// Dynamic casting allows us to support type promotion without blowing up +// the combination space: For example, without dynamic cast, in order to +// implement `add_` with type promotion, we would need something like +// +// AT_DISPATCH_ALL_TYPES(output.dtype(), +// AT_DISPATCH_ALL_TYPES(input1.dtype(), +// AT_DISPATCH_ALL_TYPES(input2.dtype(), +// [](arg0_t a, arg1_t b) -> out_t { return a + b; } +// ) +// ) +// ) +// +// If we support N dtypes, the above code would generate the a+b kernel for +// all the N * N * N different supported types, the compilation time and +// binary size would become horrible. +// +// Dynamic casting might sounds like a bad idea in terms of performance. +// Especially if you ever do it in a loop, you are going to do a billion tests. +// But in practice it is not as bad as it might look: +// +// - on CPU, this is a branch that always has the same outcome, therefore +// hopefully the branch predictor could do the job pretty well +// - on GPU, these branches will not diverge, so we could still have the same +// warp executing the same line of code +// - Most kernels, like `add`, are bandwidth bound, adding a few clock cycles to +// check an integer does not hurt the performance much because the ALUs would +// wait for load instructions anyway. +// +// For the discussion and benchmark, refer to: +// - https://github.com/pytorch/pytorch/pull/28343 +// - https://github.com/pytorch/pytorch/pull/28344 +// - https://github.com/pytorch/pytorch/pull/28345 +// + +#ifdef C10_HOST_DEVICE +#define ERROR_UNSUPPORTED_CAST CUDA_KERNEL_ASSERT(false); +#else +#define ERROR_UNSUPPORTED_CAST TORCH_CHECK(false, "Unexpected scalar type"); +#endif + +// Fetch a value with dynamic type src_type from ptr, and cast it to static type +// dest_t. +#define FETCH_AND_CAST_CASE(type, scalartype) \ + case ScalarType::scalartype: \ + return c10::convert(c10::load(ptr)); + +template +C10_HOST_DEVICE inline dest_t fetch_and_cast( + const ScalarType src_type, + const void* ptr) { + C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-enum") + switch (src_type) { + AT_FORALL_SCALAR_TYPES_WITH_COMPLEX(FETCH_AND_CAST_CASE) + FETCH_AND_CAST_CASE(uint16_t, UInt16) + FETCH_AND_CAST_CASE(uint32_t, UInt32) + FETCH_AND_CAST_CASE(uint64_t, UInt64) + default: + ERROR_UNSUPPORTED_CAST + } + C10_DIAGNOSTIC_POP() + return dest_t(0); // just to avoid compiler warning +} + +// Cast a value with static type src_t into dynamic dest_type, and store it to +// ptr. +#define CAST_AND_STORE_CASE(type, scalartype) \ + case ScalarType::scalartype: \ + *(type*)ptr = c10::convert(value); \ + return; +template +C10_HOST_DEVICE inline void cast_and_store( + const ScalarType dest_type, + void* ptr, + src_t value) { + C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-enum") + switch (dest_type) { + AT_FORALL_SCALAR_TYPES_WITH_COMPLEX(CAST_AND_STORE_CASE) + CAST_AND_STORE_CASE(uint16_t, UInt16) + CAST_AND_STORE_CASE(uint32_t, UInt32) + CAST_AND_STORE_CASE(uint64_t, UInt64) + default:; + } + C10_DIAGNOSTIC_POP() + ERROR_UNSUPPORTED_CAST +} + +#define DEFINE_UNCASTABLE(T, scalartype_) \ + template <> \ + C10_HOST_DEVICE inline T fetch_and_cast( \ + const ScalarType src_type, const void* ptr) { \ + CUDA_KERNEL_ASSERT(ScalarType::scalartype_ == src_type); \ + return c10::load(ptr); \ + } \ + template <> \ + C10_HOST_DEVICE inline void cast_and_store( \ + const ScalarType dest_type, void* ptr, T value) { \ + CUDA_KERNEL_ASSERT(ScalarType::scalartype_ == dest_type); \ + *(T*)ptr = value; \ + } + +AT_FORALL_QINT_TYPES(DEFINE_UNCASTABLE) + +#undef FETCH_AND_CAST_CASE +#undef CAST_AND_STORE_CASE +#undef DEFINE_UNCASTABLE +#undef ERROR_UNSUPPORTED_CAST + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Event.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Event.h new file mode 100644 index 0000000000000000000000000000000000000000..aed1a213bfb4724b5019909adafc237297262f9e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Event.h @@ -0,0 +1,142 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace c10 { + +/** + * A backend-generic movable, not copyable, not thread-safe event. + * + * The design of this event follows that of CUDA and HIP events. These events + * are recorded and waited on by streams and can be rerecorded to, + * each rerecording essentially creating a new version of the event. + * For example, if (in CPU time), stream X is asked to record E, + * stream Y waits on E, and stream X is asked to record E again, then Y will + * wait for X to finish the first call to record and not the second, because + * it's waiting on the first version of event E, not the second. + * Querying an event only returns the status of its most recent version. + * + * Backend-generic events are implemented by this class and + * impl::InlineEvent. In addition to these events there are also + * some backend-specific events, like ATen's CUDAEvent. Each of these + * classes has its own use. + * + * impl::InlineEvent<...> or a backend-specific event should be + * preferred when the backend is known at compile time and known to + * be compiled. Backend-specific events may have additional functionality. + * + * This Event should be used if a particular backend may not be available, + * or the backend required is not known at compile time. + * + * These generic events are built on top of DeviceGuardImpls, analogous + * to DeviceGuard and InlineDeviceGuard. The name "DeviceGuardImpls," + * is no longer entirely accurate, as these classes implement the + * backend-specific logic for a generic backend interface. + * + * See DeviceGuardImplInterface.h for a list of all supported flags. + */ + +struct Event final { + // Constructors + Event() = delete; + Event( + const DeviceType _device_type, + const EventFlag _flag = EventFlag::PYTORCH_DEFAULT) + : impl_{_device_type, _flag} {} + + // Copy constructor and copy assignment operator (deleted) + Event(const Event&) = delete; + Event& operator=(const Event&) = delete; + + // Move constructor and move assignment operator + Event(Event&&) noexcept = default; + Event& operator=(Event&&) noexcept = default; + + // Destructor + ~Event() = default; + + // Getters + Device device() const noexcept { + return Device(device_type(), device_index()); + } + DeviceType device_type() const noexcept { + return impl_.device_type(); + } + DeviceIndex device_index() const noexcept { + return impl_.device_index(); + } + EventFlag flag() const noexcept { + return impl_.flag(); + } + bool was_marked_for_recording() const noexcept { + return impl_.was_marked_for_recording(); + } + + /** + * Calls record() if and only if record() has never been called for this + * event. Note: because Event is not thread-safe recordOnce() may call + * record() multiple times if called from multiple threads. + */ + void recordOnce(const Stream& stream) { + impl_.recordOnce(stream); + } + + /** + * Increments the event's version and enqueues a job with this version + * in the stream's work queue. When the stream process that job + * it notifies all streams waiting on / blocked by that version of the + * event to continue and marks that version as recorded. + * */ + void record(const Stream& stream) { + impl_.record(stream); + } + + /** + * Does nothing if the event has not been scheduled to be recorded. + * If the event was previously enqueued to be recorded, a command + * to wait for the version of the event that exists at the time of this call + * is inserted in the stream's work queue. + * When the stream reaches this command it will stop processing + * additional commands until that version of the event is marked as recorded. + */ + void block(const Stream& stream) const { + impl_.block(stream); + } + + /** + * Returns true if (and only if) + * (1) the event has never been scheduled to be recorded + * (2) the current version is marked as recorded. + * Returns false otherwise. + */ + bool query() const { + return impl_.query(); + } + + double elapsedTime(const Event& event) const { + return impl_.elapsedTime(event.impl_); + } + + void* eventId() const { + return impl_.eventId(); + } + + void synchronize() const { + impl_.synchronize(); + } + + private: + impl::InlineEvent impl_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/GeneratorImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/GeneratorImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..7d7aac9243ffbbfc4f79471ebceee04ced485219 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/GeneratorImpl.h @@ -0,0 +1,116 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include + +/** + * Note [Generator] + * ~~~~~~~~~~~~~~~~ + * A Pseudo Random Number Generator (PRNG) is an engine that uses an algorithm + * to generate a seemingly random sequence of numbers, that may be later be used + * in creating a random distribution. Such an engine almost always maintains a + * state and requires a seed to start off the creation of random numbers. Often + * times, users have found it beneficial to be able to explicitly create, + * retain, and destroy PRNG states and also be able to have control over the + * seed value. + * + * A Generator in ATen gives users the ability to read, write and modify a PRNG + * engine. For instance, it does so by letting users seed a PRNG engine, fork + * the state of the engine, etc. + * + * By default, there is one generator per device, and a device's generator is + * lazily created. A user can use the torch.Generator() api to create their own + * generator. Currently torch.Generator() can only create a CPUGeneratorImpl. + */ + +/** + * Note [Acquire lock when using random generators] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Generator and its derived classes are NOT thread-safe. Please note that most + * of the places where we have inserted locking for generators are historically + * based, and we haven't actually checked that everything is truly thread safe + * (and it probably isn't). Please use the public mutex_ when using any methods + * from these classes, except for the read-only methods. You can learn about the + * usage by looking into the unittests (aten/src/ATen/cpu_generator_test.cpp) + * and other places where we have used lock_guard. + * + * TODO: Look into changing the threading semantics of Generators in ATen (e.g., + * making them non-thread safe and instead making the generator state + * splittable, to accommodate forks into other threads). + */ + +namespace c10 { + +// The default seed is selected to be a large number +// with good distribution of 0s and 1s in bit representation +constexpr uint64_t default_rng_seed_val = 67280421310721; + +struct C10_API GeneratorImpl : public c10::intrusive_ptr_target { + // Constructors + GeneratorImpl(Device device_in, DispatchKeySet key_set); + + // Delete all copy and move assignment in favor of clone() + // method + GeneratorImpl(const GeneratorImpl& other) = delete; + GeneratorImpl(GeneratorImpl&& other) = delete; + GeneratorImpl& operator=(const GeneratorImpl& other) = delete; + GeneratorImpl& operator=(GeneratorImpl&& other) = delete; + + ~GeneratorImpl() override = default; + c10::intrusive_ptr clone() const; + + // Common methods for all generators + virtual void set_current_seed(uint64_t seed) = 0; + virtual void set_offset(uint64_t offset) = 0; + virtual uint64_t get_offset() const = 0; + virtual uint64_t current_seed() const = 0; + virtual uint64_t seed() = 0; + virtual void set_state(const c10::TensorImpl& new_state) = 0; + virtual c10::intrusive_ptr get_state() const = 0; + virtual void graphsafe_set_state( + const c10::intrusive_ptr& new_state); + virtual c10::intrusive_ptr graphsafe_get_state() const; + Device device() const; + + // See Note [Acquire lock when using random generators] + std::mutex mutex_; + + DispatchKeySet key_set() const { + return key_set_; + } + + inline void set_pyobj(PyObject* pyobj) noexcept { + pyobj_ = pyobj; + } + + inline PyObject* pyobj() const noexcept { + return pyobj_; + } + + protected: + Device device_; + DispatchKeySet key_set_; + PyObject* pyobj_ = nullptr; + + virtual GeneratorImpl* clone_impl() const = 0; +}; + +namespace detail { + +C10_API uint64_t getNonDeterministicRandom(bool is_cuda = false); + +} // namespace detail + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/GradMode.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/GradMode.h new file mode 100644 index 0000000000000000000000000000000000000000..391b293f9f005af1035dbf9e43be91bf5b353bed --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/GradMode.h @@ -0,0 +1,57 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10 { + +struct C10_API GradMode { + static bool is_enabled(); + static void set_enabled(bool enabled); +}; + +// A RAII, thread local (!) guard that enables or disables grad mode upon +// construction, and sets it back to the original value upon destruction. +struct C10_API AutoGradMode { + AutoGradMode(bool enabled) : prev_mode(GradMode::is_enabled()) { + GradMode::set_enabled(enabled); + } + AutoGradMode(const AutoGradMode&) = delete; + AutoGradMode(AutoGradMode&&) = delete; + AutoGradMode& operator=(const AutoGradMode&) = delete; + AutoGradMode& operator=(AutoGradMode&&) = delete; + ~AutoGradMode() { + GradMode::set_enabled(prev_mode); + } + bool prev_mode; +}; + +// A RAII, thread local (!) guard that stops future operations from building +// gradients. +struct C10_API NoGradGuard : public AutoGradMode { + NoGradGuard() : AutoGradMode(/*enabled=*/false) {} +}; + +// A RAII, thread local (!) guard that enables or disables forward grad mode +// upon construction, and sets it back to the original value upon destruction. +struct C10_API AutoFwGradMode { + AutoFwGradMode(bool enabled) + : prev_mode(AutogradState::get_tls_state().get_fw_grad_mode()) { + AutogradState::get_tls_state().set_fw_grad_mode(enabled); + } + AutoFwGradMode(const AutoFwGradMode&) = delete; + AutoFwGradMode(AutoFwGradMode&&) = delete; + AutoFwGradMode& operator=(const AutoFwGradMode&) = delete; + AutoFwGradMode& operator=(AutoFwGradMode&&) = delete; + ~AutoFwGradMode() { + AutogradState::get_tls_state().set_fw_grad_mode(prev_mode); + } + bool prev_mode; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/InferenceMode.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/InferenceMode.h new file mode 100644 index 0000000000000000000000000000000000000000..8da25b5427e61d250268a352f11757a4e1d7ab24 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/InferenceMode.h @@ -0,0 +1,96 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace c10 { + +// A RAII, thread local (!) guard that enables or disables inference mode upon +// construction, and sets it back to the original value upon destruction. +struct C10_API InferenceMode { + // Note [Expected TLS state in InferenceMode]: + // InferenceMode: ADInplaceOrView not in + // raw_local_dispatch_key_set.included(), + // Autograd in raw_local_dispatch_key_set.excluded() + // GradMode is disabled. + // NormalMode: ADInplaceOrView in raw_local_dispatch_key_set.included(), + // Autograd not in raw_local_dispatch_key_set.excluded() + // GradMode is enabled by default unless toggled manually + // through other APIs, e.g. NoGradGuard. + // + // Invariant: + // - ADInplaceOrView is never in the excluded set + // - Autograd is never in the included set + // - Setting InferenceMode will set GradMode accordingly, but not vice versa. + // + // 1. Why do we put ADInplaceOrView in included set outside InferenceMode? + // + // Inplace update to inference tensor outside InferenceMode is not + // allowed. See Note [Inplace update inference tensor] for more details. + // Without going through ADInplaceOrView kernel, we cannot throw error + // for `inference_tensor.add_(1)` case. + // + // 2. Why not put ADInplaceOrView in the excluded set inside InferenceMode? + // + // For example: + // torch::Tensor a = torch::ones({1, 2, 3}).set_requires_grad(true); + // torch::Tensor k = a + 2; + // { + // c10::InferenceMode guard(true); + // k.add_(2); + // } + // `k.add_(2)` still need to go through ADInplaceOrView kernel so that it's + // prepared for future autograd. + // + // 3. Why does setting InferenceMode also set GradMode? + // + // This is required since InferenceMode is a faster and more restrictive + // version of NoGradGuard. All runtime checks using GradMode::is_enabled() + // are applicable to InferenceMode as well, e.g. + // `tensorTypeInCurrentExecutionContext` in interpreter.cpp. + InferenceMode(bool enabled = true) + : prev_mode(AutogradState::get_tls_state()), + prev_keyset(c10::impl::tls_local_dispatch_key_set()) { + // Enabling inference mode means disabling grad modes + // And disabling inference mode means enabling grad modes + AutogradState::set_tls_state(AutogradState( + /* grad_mode */ !enabled, + /* inference_mode */ enabled, + /* fw_grad_mode */ !enabled, + /* multithreading_enabled*/ !enabled)); + DispatchKeySet included = enabled + ? prev_keyset.included_.remove(c10::DispatchKey::ADInplaceOrView) + : prev_keyset.included_.add(c10::DispatchKey::ADInplaceOrView); + DispatchKeySet excluded = enabled + ? (prev_keyset.excluded_ | c10::autograd_dispatch_keyset) + : (prev_keyset.excluded_ - c10::autograd_dispatch_keyset); + c10::impl::PODLocalDispatchKeySet cur_keyset{}; + cur_keyset.set_included(included); + cur_keyset.set_excluded(excluded); + c10::impl::_force_tls_local_dispatch_key_set(cur_keyset); + } + + InferenceMode(const InferenceMode&) = delete; + InferenceMode(InferenceMode&&) = delete; + InferenceMode& operator=(const InferenceMode&) = delete; + InferenceMode& operator=(InferenceMode&&) = delete; + + ~InferenceMode() { + AutogradState::set_tls_state(prev_mode); + c10::impl::_force_tls_local_dispatch_key_set(prev_keyset); + } + static bool is_enabled(); + + private: + AutogradState prev_mode; + c10::impl::LocalDispatchKeySet prev_keyset; +}; +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Layout.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Layout.h new file mode 100644 index 0000000000000000000000000000000000000000..194e1863cb18cf2759f2c4e3e1ace298efd76150 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Layout.h @@ -0,0 +1,67 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include + +namespace c10 { + +inline Layout layout_from_backend(Backend backend) { + C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-enum") + switch (backend) { + case Backend::SparseCPU: + case Backend::SparseCUDA: + case Backend::SparseMPS: + case Backend::SparseHIP: + case Backend::SparseVE: + case Backend::SparseXPU: + case Backend::SparsePrivateUse1: + return Layout::Sparse; + case Backend::MkldnnCPU: + return Layout::Mkldnn; + case Backend::SparseCsrCPU: + case Backend::SparseCsrCUDA: + case Backend::SparseCsrMPS: + case Backend::SparseCsrHIP: + case Backend::SparseCsrVE: + case Backend::SparseCsrXPU: + TORCH_CHECK( + false, + "Cannot map Backend SparseCsr(CPU|CUDA|HIP|VE|XPU|MPS) to a unique layout."); + default: + return Layout::Strided; + } + C10_DIAGNOSTIC_POP() +} + +inline std::ostream& operator<<(std::ostream& stream, at::Layout layout) { + switch (layout) { + case at::kStrided: + return stream << "Strided"; + case at::kSparse: + return stream << "Sparse"; + case at::kSparseCsr: + return stream << "SparseCsr"; + case at::kSparseCsc: + return stream << "SparseCsc"; + case at::kSparseBsr: + return stream << "SparseBsr"; + case at::kSparseBsc: + return stream << "SparseBsc"; + case at::kMkldnn: + return stream << "Mkldnn"; + case at::kJagged: + return stream << "Jagged"; + case Layout::NumOptions: + default: + TORCH_CHECK(false, "Unknown layout"); + } +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/MemoryFormat.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/MemoryFormat.h new file mode 100644 index 0000000000000000000000000000000000000000..63cdb757952b073d957fc91c33357136c1287679 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/MemoryFormat.h @@ -0,0 +1,268 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include + +#include +#include + +namespace c10 { + +// If you are seeing this, it means that this call site was not checked if +// the memory format could be preserved, and it was switched to old default +// behaviour of contiguous +#define LEGACY_CONTIGUOUS_MEMORY_FORMAT c10::get_contiguous_memory_format() + +inline std::ostream& operator<<( + std::ostream& stream, + at::MemoryFormat memory_format) { + switch (memory_format) { + case MemoryFormat::Preserve: + return stream << "Preserve"; + case MemoryFormat::Contiguous: + return stream << "Contiguous"; + case MemoryFormat::ChannelsLast: + return stream << "ChannelsLast"; + case MemoryFormat::ChannelsLast3d: + return stream << "ChannelsLast3d"; + case MemoryFormat::NumOptions: + default: + TORCH_CHECK(false, "Unknown memory format ", memory_format); + } +} + +// Note: Hardcoded the channel last stride indices here to get better +// performance +template +inline std::vector get_channels_last_strides_2d(ArrayRef sizes) { + std::vector strides(sizes.size()); + switch (sizes.size()) { + case 4: + strides[1] = 1; + strides[3] = sizes[1]; + strides[2] = strides[3] * sizes[3]; + strides[0] = strides[2] * sizes[2]; + return strides; + case 3: + strides[0] = 1; + strides[2] = sizes[0]; + strides[1] = strides[2] * sizes[2]; + return strides; + default: + TORCH_INTERNAL_ASSERT( + false, "ChannelsLast2d doesn't support size ", sizes.size()); + } +} + +inline std::vector get_channels_last_strides_2d(IntArrayRef sizes) { + return get_channels_last_strides_2d(sizes); +} + +template +std::vector get_channels_last_strides_3d(ArrayRef sizes) { + std::vector strides(sizes.size()); + switch (sizes.size()) { + case 5: + strides[1] = 1; + strides[4] = sizes[1]; + strides[3] = strides[4] * sizes[4]; + strides[2] = strides[3] * sizes[3]; + strides[0] = strides[2] * sizes[2]; + return strides; + case 4: + strides[0] = 1; + strides[3] = sizes[0]; + strides[2] = strides[3] * sizes[3]; + strides[1] = strides[2] * sizes[2]; + return strides; + default: + TORCH_INTERNAL_ASSERT( + false, "ChannelsLast3d doesn't support size ", sizes.size()); + } +} + +inline std::vector get_channels_last_strides_3d(IntArrayRef sizes) { + return get_channels_last_strides_3d(sizes); +} + +// NOTE: +// Below are Helper functions for is_channels_last_strides_xd. +// 1. Please do not combine these helper functions, each helper function handles +// exactly one case of sizes + memory_format, by doing this, the strides indices +// will be a constant array and we can access it using constant index number, +// the compiler will fully unroll the loop on strides indices to gain a better +// performance. +// 2. No error check in helper function, caller ensures the correctness of the +// input +// 3. All helper functions have similar comments, only 1st helper function is +// commented here. +template +inline bool is_channels_last_strides_2d_s4( + const ArrayRef sizes, + const ArrayRef strides) { + T min = 0; + // special case for trivial C dimension. default to NCHW + if (strides[1] == 0) { + return false; + } + // loop strides indices + for (auto& d : {1, 3, 2, 0}) { + if (sizes[d] == 0) { + return false; + } + if (strides[d] < min) { + return false; + } + // Fallback to NCHW as default layout for ambiguous cases + // This is the flaw of implicit memory_format from strides. + // N111 tensor with identical strides for size 1 dimension; + // Two cases could lead us here: + // a. N111 contiguous Tensor ([N,1,1,1]@[1,1,1,1]) + // b. N11W contiguous Tensor sliced on the W-dimension. + // ([N,1,1,1]@[W,W,W,W]) + if (d == 0 && min == strides[1]) { + return false; + } + // This is necessary to: + // 1. distinguish the memory_format of N1H1; + // [H, 1, 1, 1] channels_last stride + // [H, H, 1, 1] contiguous stride + // 2. permutation of 1C1W: + // [1, C, 1, H]@[HC, H, H, 1] transpose(1, 3) + // [1, H, 1, C]@[HC, 1, H, H] shouldn't be identified as channels_last + min = strides[d]; + if (sizes[d] > 1) { + min *= sizes[d]; + } + } + return true; +} + +template +inline bool is_channels_last_strides_3d_s5( + const ArrayRef sizes, + const ArrayRef strides) { + T min = 0; + if (strides[1] == 0) { + return false; + } + for (auto& d : {1, 4, 3, 2, 0}) { + if (sizes[d] == 0) { + return false; + } + if (strides[d] < min) { + return false; + } + if (d == 0 && min == strides[1]) { + return false; + } + min = strides[d]; + if (sizes[d] > 1) { + min *= sizes[d]; + } + } + return true; +} + +// Note [Ambiguous is_channels_last_strides_xd] +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// The flaw of carrying memory_format implicitly through strides is very hard +// to WAR properly. issue #24090 +// Without the history of permutation, we can't infer the memory_format of a +// tensor from the snapshot of its size & stride +// e.g. +// +// 1. We can NOT specify the memory_format of N111 tensor through strides in a +// meaningful way; +// +// 2. Two path that ended up with identical size/stride +// N11W contiguous tensor sliced at w-dimension becomes [N,1,1,1]@[W,W,W,W] +// NC11 channels_last tensor sliced at c-dimension becomes [N,1,1,1]@[C,C,C,C] +// So if we see a tensor [N,1,1,1]@[X,X,X,X], there's no way for us to infer +// the memory_format of the original tensor. +// +// Due to the limitations, our temporary WAR `is_channels_last_strides` does the +// best effort to infer whether the original memory_format of a tensor is +// at::MemoryFormat::ChannelsLast. The two objectives of this function (ordered +// by their importance): +// 1. Ensure that normal shape manipulation does not accidentally change the +// MemoryFormat of an existing tensor. +// 2. Allows user to mark MemoryFormat::ChannelsLast to tensors; +// +// The function does so via checking strides of the tensor, including strides of +// size-1 dimensions. Although conventionally PyTorch implies no restriction on +// trivial stride (stride for size-1 dimension). +// +// Note that this approach is a compromise. We did not solve the problem +// completely. Many cases we will not be able to infer the correct memory +// format. +// The implementation of `is_channels_last_strides` is to serve the objectives: +// MemoryFormat::ChannelsLast has to be explicitly opted-in (no accidental +// conversion); Best effort to maintain the ChannelsLast flag. +// +// Due to the fact that this is not a bulletproof solution, through testing +// (aten/src/ATen/test/memory_format_test.cpp) +// a. we ensure that the common tasks are supported; +// a. we identify corner cases where the implementation compromises on. +// +// By the time accumulated permutation is enabled to replace implicit +// memory_format through strides, we should be updating our tests and fix the +// issues in our tests. +// +// We use Channels Last 2d as an example above. +// This is a general problem for all the is_channels_last_strides_xd +// implementation. Please check the helper functions +// (is_channels_last_strides_*d_s*) for more details. + +template +inline bool is_channels_last_strides_2d( + const ArrayRef sizes, + const ArrayRef strides) { + switch (sizes.size()) { + case 4: + return is_channels_last_strides_2d_s4(sizes, strides); + // NOLINTNEXTLINE(bugprone-branch-clone) + case 3: + // TODO dim == 3 case will be enabled once it is fully tested + return false; + default: + return false; + } +} + +template +inline bool is_channels_last_strides_3d( + const ArrayRef sizes, + const ArrayRef strides) { + switch (sizes.size()) { + case 5: + return is_channels_last_strides_3d_s5(sizes, strides); + // NOLINTNEXTLINE(bugprone-branch-clone) + case 4: + // TODO dim == 4 case will be enabled once it is fully tested + return false; + default: + return false; + } +} + +inline bool is_channels_last_strides_2d( + const IntArrayRef sizes, + const IntArrayRef strides) { + return is_channels_last_strides_2d(sizes, strides); +} + +inline bool is_channels_last_strides_3d( + const IntArrayRef sizes, + const IntArrayRef strides) { + return is_channels_last_strides_3d(sizes, strides); +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/OptionalRef.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/OptionalRef.h new file mode 100644 index 0000000000000000000000000000000000000000..f1199e1945a65866cfd17c5301e20454721dc117 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/OptionalRef.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +namespace c10 { + +template +class OptionalRef { + public: + OptionalRef() : data_(nullptr) {} + OptionalRef(const T* data) : data_(data) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(data_); + } + OptionalRef(const T& data) : data_(&data) {} + + bool has_value() const { + return data_ != nullptr; + } + + const T& get() const { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(data_); + return *data_; + } + + operator bool() const { + return has_value(); + } + + private: + const T* data_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/PyHandleCache.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/PyHandleCache.h new file mode 100644 index 0000000000000000000000000000000000000000..1c39510078bc70aa95e205176fd8bebeeb332065 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/PyHandleCache.h @@ -0,0 +1,81 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +#include + +namespace c10 { + +// A PyHandleCache represents a cached pointer from a C++ object to +// a Python object that represents that object analogously in Python. +// Upon a cache hit, the relevant object can be retrieved after a test +// and then a memory load. Two conditions must hold to be able to use this +// class: +// +// - This must truly be a cache; e.g., the caller must be able to produce +// the object some other way if the cache hit misses. +// +// - This must truly be a handle; e.g., the Python object referenced by +// this class must have static lifetime. This means we don't have to +// maintain strong ownership or deallocate the object when the C++ object +// dies. Static lifetime is a good idea in conjunction with the cache, +// since if you are producing a fresh object on miss you won't be +// maintaining object identity. If you need bidirectional ownership, +// you will want to factor out the pattern in TensorImpl with +// resurrection. +// +// This cache is expected to not improve perf under torchdeploy, as one +// interpreter will fill up the cache, and all the interpreters will be +// unable to use the slot. A potential improvement is to have multiple +// slots (one per interpreter), which will work in deployment scenarios +// where there a stable, fixed number of interpreters. You can also store +// the relevant state in the Python library, rather than in the non-Python +// library (although in many cases, this is not convenient, as there may +// not be a way to conveniently index based on the object.) +class PyHandleCache { + public: + PyHandleCache() : pyinterpreter_(nullptr) {} + + // Attempt to fetch the pointer from the cache, if the PyInterpreter + // matches. If it doesn't exist, or the cache entry is not valid, + // use slow_accessor to get the real pointer value and return that + // (possibly writing it to the cache, if the cache entry is + // available.) + template + PyObject* ptr_or(impl::PyInterpreter* self_interpreter, F slow_accessor) + const { + // Note [Memory ordering on Python interpreter tag] + impl::PyInterpreter* interpreter = + pyinterpreter_.load(std::memory_order_acquire); + if (C10_LIKELY(interpreter == self_interpreter)) { + return data_; + } else if (interpreter == nullptr) { + auto* r = slow_accessor(); + impl::PyInterpreter* expected = nullptr; + // attempt to claim this cache entry with the specified interpreter tag + if (pyinterpreter_.compare_exchange_strong( + expected, self_interpreter, std::memory_order_acq_rel)) { + data_ = r; + } + // This shouldn't be possible, as you should be GIL protected + TORCH_INTERNAL_ASSERT(expected != self_interpreter); + return r; + } else { + return slow_accessor(); + } + } + + private: + mutable std::atomic pyinterpreter_; + mutable PyObject* data_{nullptr}; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/QEngine.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/QEngine.h new file mode 100644 index 0000000000000000000000000000000000000000..b0bb6a245643a3e093c02ae80756403b931245ba --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/QEngine.h @@ -0,0 +1,51 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10 { + +/** + * QEngine is an enum that is used to select the engine to run quantized ops. + * Keep this enum in sync with get_qengine_id() in + * torch/backends/quantized/__init__.py + */ +enum class QEngine : uint8_t { + NoQEngine = 0, + FBGEMM = 1, + QNNPACK = 2, + ONEDNN = 3, + X86 = 4, +}; + +constexpr auto kNoQEngine = QEngine::NoQEngine; +constexpr auto kFBGEMM = QEngine::FBGEMM; +constexpr auto kQNNPACK = QEngine::QNNPACK; +constexpr auto kONEDNN = QEngine::ONEDNN; +constexpr auto kX86 = QEngine::X86; + +inline std::string toString(QEngine qengine) { + switch (qengine) { + case kNoQEngine: + return "NoQEngine"; + case kFBGEMM: + return "FBGEMM"; + case kQNNPACK: + return "QNNPACK"; + case kONEDNN: + return "ONEDNN"; + case kX86: + return "X86"; + default: + TORCH_CHECK( + false, "Unrecognized Quantized Engine: ", static_cast(qengine)); + } +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/QScheme.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/QScheme.h new file mode 100644 index 0000000000000000000000000000000000000000..f557affb1de8ff54fc961159d3cc67e2f11ef3b7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/QScheme.h @@ -0,0 +1,60 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-enum") + +namespace c10 { + +/** + * QScheme is an enum that specifies the type of quantization. This has a one + * to one correspondence with Quantizer + * Please refer to ATen/quantized/Quantizer.h to see the Quantizers classes. + * Keep this file in sync with torch/nn/_qscheme.py + */ +enum class QScheme : uint8_t { + PER_TENSOR_AFFINE = 0, + PER_CHANNEL_AFFINE = 1, + PER_TENSOR_SYMMETRIC = 2, + PER_CHANNEL_SYMMETRIC = 3, + PER_CHANNEL_AFFINE_FLOAT_QPARAMS = 4, + COMPILE_TIME_NUM_QSCHEMES = 5, +}; + +constexpr auto kPerTensorAffine = QScheme::PER_TENSOR_AFFINE; +constexpr auto kPerChannelAffine = QScheme::PER_CHANNEL_AFFINE; +constexpr auto kPerTensorSymmetric = QScheme::PER_TENSOR_SYMMETRIC; +constexpr auto kPerChannelSymmetric = QScheme::PER_CHANNEL_SYMMETRIC; +constexpr auto kPerChannelAffineFloatQParams = + QScheme::PER_CHANNEL_AFFINE_FLOAT_QPARAMS; +constexpr int COMPILE_TIME_NUM_QSCHEMES = + static_cast(QScheme::COMPILE_TIME_NUM_QSCHEMES); + +inline std::string toString(QScheme qscheme) { + switch (qscheme) { + case kPerTensorAffine: + return "per_tensor_affine"; + case kPerChannelAffine: + return "per_channel_affine"; + case kPerTensorSymmetric: + return "per_tensor_symmetric"; + case kPerChannelSymmetric: + return "per_channel_symmetric"; + case kPerChannelAffineFloatQParams: + return "per_channel_affine_float_qparams"; + default: + TORCH_CHECK(false, "Unrecognized qscheme: ", static_cast(qscheme)); + } +} + +} // namespace c10 + +C10_DIAGNOSTIC_POP() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/RefcountedDeleter.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/RefcountedDeleter.h new file mode 100644 index 0000000000000000000000000000000000000000..8b1e9ca7071a032e6a383dc539b8010af535471b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/RefcountedDeleter.h @@ -0,0 +1,57 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +#include +#include + +namespace c10 { + +// A RefcountedDeleterContext object is used as the `ctx` argument for DataPtr +// to implement a shared DataPtr. Normally, a DataPtr is unique, but we use +// this custom context and the `refcounted_deleter` function below to make the +// DataPtr act like a non-unique DataPtr. This context object holds onto an +// inner context and deleter function which handle the actual deletion of the +// data when the refcount reaches 0. +// +// This shared DataPtr feature is only used when storages are shared between +// multiple Python interpreters in MultiPy. // codespell:ignore multipy +// Before storages had PyObject preservation, interpreters could just share the +// same StorageImpl instance. But now a StorageImpl can only be associated with +// one interpreter in order to properly manage a zombie PyObject. So we share +// storages across Python interpreters by creating a different StorageImpl +// instance for each one, but they all point to the same data. +struct C10_API RefcountedDeleterContext { + RefcountedDeleterContext(void* other_ctx, c10::DeleterFnPtr other_deleter) + : other_ctx(other_ctx, other_deleter), refcount(1) {} + + std::unique_ptr other_ctx; + std::atomic_int refcount; +}; + +// `refcounted_deleter` is used as the `ctx_deleter` for DataPtr to implement +// a shared DataPtr. +// +// Warning: This should only be called on a pointer to +// a RefcountedDeleterContext that was allocated on the heap with `new`, +// because when the refcount reaches 0, the context is deleted with `delete` +C10_API void refcounted_deleter(void* ctx_); + +// If the storage's DataPtr does not use `refcounted_deleter`, replace it with +// a DataPtr that does, so it can be shared between multiple StorageImpls +C10_API void maybeApplyRefcountedDeleter(const c10::Storage& storage); + +// Create a new StorageImpl that points to the same data. If the original +// StorageImpl's DataPtr does not use `refcounted_deleter`, it will be replaced +// with one that does +C10_API c10::Storage newStorageImplFromRefcountedDataPtr( + const c10::Storage& storage); + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SafePyObject.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SafePyObject.h new file mode 100644 index 0000000000000000000000000000000000000000..bf8eee0e004b5e49c39d9718736df1099769ef24 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SafePyObject.h @@ -0,0 +1,125 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +namespace c10 { + +// This is an safe owning holder for a PyObject, akin to pybind11's +// py::object, with two major differences: +// +// - It is in c10/core; i.e., you can use this type in contexts where +// you do not have a libpython dependency +// +// - It is multi-interpreter safe (ala torchdeploy); when you fetch +// the underlying PyObject* you are required to specify what the current +// interpreter context is and we will check that you match it. +// +// It is INVALID to store a reference to a Tensor object in this way; +// you should just use TensorImpl directly in that case! +struct C10_API SafePyObject { + // Steals a reference to data + SafePyObject(PyObject* data, c10::impl::PyInterpreter* pyinterpreter) + : data_(data), pyinterpreter_(pyinterpreter) {} + SafePyObject(SafePyObject&& other) noexcept + : data_(std::exchange(other.data_, nullptr)), + pyinterpreter_(other.pyinterpreter_) {} + // For now it's not used, so we just disallow it. + SafePyObject& operator=(SafePyObject&&) = delete; + + SafePyObject(SafePyObject const& other) + : data_(other.data_), pyinterpreter_(other.pyinterpreter_) { + if (data_ != nullptr) { + (*pyinterpreter_)->incref(data_); + } + } + + SafePyObject& operator=(SafePyObject const& other) { + if (this == &other) { + return *this; // Handle self-assignment + } + if (other.data_ != nullptr) { + (*other.pyinterpreter_)->incref(other.data_); + } + if (data_ != nullptr) { + (*pyinterpreter_)->decref(data_); + } + data_ = other.data_; + pyinterpreter_ = other.pyinterpreter_; + return *this; + } + + ~SafePyObject() { + if (data_ != nullptr) { + (*pyinterpreter_)->decref(data_); + } + } + + c10::impl::PyInterpreter& pyinterpreter() const { + return *pyinterpreter_; + } + PyObject* ptr(const c10::impl::PyInterpreter* /*interpreter*/) const; + + // stop tracking the current object, and return it + PyObject* release() { + auto rv = data_; + data_ = nullptr; + return rv; + } + + private: + PyObject* data_; + c10::impl::PyInterpreter* pyinterpreter_; +}; + +// A newtype wrapper around SafePyObject for type safety when a python object +// represents a specific type. Note that `T` is only used as a tag and isn't +// actually used for any true purpose. +template +struct SafePyObjectT : private SafePyObject { + SafePyObjectT(PyObject* data, c10::impl::PyInterpreter* pyinterpreter) + : SafePyObject(data, pyinterpreter) {} + ~SafePyObjectT() = default; + SafePyObjectT(SafePyObjectT&& other) noexcept : SafePyObject(other) {} + SafePyObjectT(SafePyObjectT const&) = delete; + SafePyObjectT& operator=(SafePyObjectT const&) = delete; + SafePyObjectT& operator=(SafePyObjectT&&) = delete; + + using SafePyObject::ptr; + using SafePyObject::pyinterpreter; + using SafePyObject::release; +}; + +// Like SafePyObject, but non-owning. Good for references to global PyObjects +// that will be leaked on interpreter exit. You get a copy constructor/assign +// this way. +struct C10_API SafePyHandle { + SafePyHandle() : data_(nullptr), pyinterpreter_(nullptr) {} + SafePyHandle(PyObject* data, c10::impl::PyInterpreter* pyinterpreter) + : data_(data), pyinterpreter_(pyinterpreter) {} + + c10::impl::PyInterpreter& pyinterpreter() const { + return *pyinterpreter_; + } + PyObject* ptr(const c10::impl::PyInterpreter* /*interpreter*/) const; + void reset() { + data_ = nullptr; + pyinterpreter_ = nullptr; + } + operator bool() { + return data_; + } + + private: + PyObject* data_; + c10::impl::PyInterpreter* pyinterpreter_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Scalar.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Scalar.h new file mode 100644 index 0000000000000000000000000000000000000000..863a993ed08a614ca4526fee426ebd46f5633be0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Scalar.h @@ -0,0 +1,471 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +/** + * Scalar represents a 0-dimensional tensor which contains a single element. + * Unlike a tensor, numeric literals (in C++) are implicitly convertible to + * Scalar (which is why, for example, we provide both add(Tensor) and + * add(Scalar) overloads for many operations). It may also be used in + * circumstances where you statically know a tensor is 0-dim and single size, + * but don't know its type. + */ +class C10_API Scalar { + public: + Scalar() : Scalar(int64_t(0)) {} + + void destroy() { + if (Tag::HAS_si == tag || Tag::HAS_sd == tag || Tag::HAS_sb == tag) { + raw::intrusive_ptr::decref(v.p); + v.p = nullptr; + } + } + + ~Scalar() { + destroy(); + } + +#define DEFINE_IMPLICIT_CTOR(type, name) \ + Scalar(type vv) : Scalar(vv, true) {} + + AT_FORALL_SCALAR_TYPES_AND3(Half, BFloat16, ComplexHalf, DEFINE_IMPLICIT_CTOR) + AT_FORALL_COMPLEX_TYPES(DEFINE_IMPLICIT_CTOR) + AT_FORALL_FLOAT8_TYPES(DEFINE_IMPLICIT_CTOR) + + // Helper constructors to allow Scalar creation from long and long long types + // As std::is_same_v is false(except Android), one needs to + // provide a constructor from either long or long long in addition to one from + // int64_t +#if defined(__APPLE__) || defined(__MACOSX) + static_assert( + std::is_same_v, + "int64_t is the same as long long on MacOS"); + Scalar(long vv) : Scalar(vv, true) {} +#endif +#if defined(_MSC_VER) + static_assert( + std::is_same_v, + "int64_t is the same as long long on Windows"); + Scalar(long vv) : Scalar(vv, true) {} +#endif +#if defined(__linux__) && !defined(__ANDROID__) + static_assert( + sizeof(void*) != 8 || std::is_same_v, + "int64_t is the same as long on 64 bit Linux"); +#if LONG_MAX != INT_MAX + Scalar(long long vv) : Scalar(vv, true) {} +#endif /* not 32-bit system */ +#endif + + Scalar(uint16_t vv) : Scalar(vv, true) {} + Scalar(uint32_t vv) : Scalar(vv, true) {} + Scalar(uint64_t vv) { + if (vv > static_cast(INT64_MAX)) { + tag = Tag::HAS_u; + v.u = vv; + } else { + tag = Tag::HAS_i; + // NB: no need to use convert, we've already tested convertibility + v.i = static_cast(vv); + } + } + +#undef DEFINE_IMPLICIT_CTOR + + // Value* is both implicitly convertible to SymbolicVariable and bool which + // causes ambiguity error. Specialized constructor for bool resolves this + // problem. + template < + typename T, + typename std::enable_if_t, bool>* = nullptr> + Scalar(T vv) : tag(Tag::HAS_b) { + v.i = convert(vv); + } + + template < + typename T, + typename std::enable_if_t, bool>* = + nullptr> + Scalar(T vv) : tag(Tag::HAS_sb) { + v.i = convert(vv); + } + +#define DEFINE_ACCESSOR(type, name) \ + type to##name() const { \ + if (Tag::HAS_d == tag) { \ + return checked_convert(v.d, #type); \ + } else if (Tag::HAS_z == tag) { \ + return checked_convert>(v.z, #type); \ + } else if (Tag::HAS_sd == tag) { \ + return checked_convert( \ + toSymFloat().guard_float(__FILE__, __LINE__), #type); \ + } \ + if (Tag::HAS_b == tag) { \ + return checked_convert(v.i, #type); \ + } else if (Tag::HAS_i == tag) { \ + return checked_convert(v.i, #type); \ + } else if (Tag::HAS_u == tag) { \ + return checked_convert(v.u, #type); \ + } else if (Tag::HAS_si == tag) { \ + return checked_convert( \ + toSymInt().guard_int(__FILE__, __LINE__), #type); \ + } else if (Tag::HAS_sb == tag) { \ + return checked_convert( \ + toSymBool().guard_bool(__FILE__, __LINE__), #type); \ + } \ + TORCH_CHECK(false) \ + } + + // TODO: Support ComplexHalf accessor + AT_FORALL_SCALAR_TYPES_WITH_COMPLEX(DEFINE_ACCESSOR) + DEFINE_ACCESSOR(uint16_t, UInt16) + DEFINE_ACCESSOR(uint32_t, UInt32) + DEFINE_ACCESSOR(uint64_t, UInt64) + +#undef DEFINE_ACCESSOR + + SymInt toSymInt() const { + if (Tag::HAS_si == tag) { + return c10::SymInt(intrusive_ptr::reclaim_copy( + static_cast(v.p))); + } else { + return toLong(); + } + } + + SymFloat toSymFloat() const { + if (Tag::HAS_sd == tag) { + return c10::SymFloat(intrusive_ptr::reclaim_copy( + static_cast(v.p))); + } else { + return toDouble(); + } + } + + SymBool toSymBool() const { + if (Tag::HAS_sb == tag) { + return c10::SymBool(intrusive_ptr::reclaim_copy( + static_cast(v.p))); + } else { + return toBool(); + } + } + + // also support scalar.to(); + // Deleted for unsupported types, but specialized below for supported types + template + T to() const = delete; + + // audit uses of data_ptr + const void* data_ptr() const { + TORCH_INTERNAL_ASSERT(!isSymbolic()); + return static_cast(&v); + } + + bool isFloatingPoint() const { + return Tag::HAS_d == tag || Tag::HAS_sd == tag; + } + + [[deprecated( + "isIntegral is deprecated. Please use the overload with 'includeBool' parameter instead.")]] bool + isIntegral() const { + return Tag::HAS_i == tag || Tag::HAS_si == tag || Tag::HAS_u == tag; + } + + bool isIntegral(bool includeBool) const { + return Tag::HAS_i == tag || Tag::HAS_si == tag || Tag::HAS_u == tag || + (includeBool && isBoolean()); + } + + // See Note [Meaning of HAS_u] + bool isUnsigned() const { + return Tag::HAS_u == tag || (Tag::HAS_i == tag && v.i >= 0); + } + + bool isComplex() const { + return Tag::HAS_z == tag; + } + bool isBoolean() const { + return Tag::HAS_b == tag || Tag::HAS_sb == tag; + } + + // you probably don't actually want these; they're mostly for testing + bool isSymInt() const { + return Tag::HAS_si == tag; + } + bool isSymFloat() const { + return Tag::HAS_sd == tag; + } + bool isSymBool() const { + return Tag::HAS_sb == tag; + } + + bool isSymbolic() const { + return Tag::HAS_si == tag || Tag::HAS_sd == tag || Tag::HAS_sb == tag; + } + + C10_ALWAYS_INLINE Scalar& operator=(Scalar&& other) noexcept { + if (&other == this) { + return *this; + } + + destroy(); + moveFrom(std::move(other)); + return *this; + } + + C10_ALWAYS_INLINE Scalar& operator=(const Scalar& other) { + if (&other == this) { + return *this; + } + + *this = Scalar(other); + return *this; + } + + Scalar operator-() const; + Scalar conj() const; + Scalar log() const; + + template < + typename T, + typename std::enable_if_t::value, int> = 0> + bool equal(T num) const { + if (isComplex()) { + TORCH_INTERNAL_ASSERT(!isSymbolic()); + auto val = v.z; + return (val.real() == num) && (val.imag() == T()); + } else if (isFloatingPoint()) { + return toDouble() == num; + } else if (tag == Tag::HAS_i) { + if (overflows(v.i, /* strict_unsigned */ true)) { + return false; + } else { + return static_cast(v.i) == num; + } + } else if (tag == Tag::HAS_u) { + if (overflows(v.u, /* strict_unsigned */ true)) { + return false; + } else { + return static_cast(v.u) == num; + } + } else if (tag == Tag::HAS_si) { + TORCH_INTERNAL_ASSERT(false, "NYI SymInt equality"); + } else if (isBoolean()) { + // boolean scalar does not equal to a non boolean value + TORCH_INTERNAL_ASSERT(!isSymbolic()); + return false; + } else { + TORCH_INTERNAL_ASSERT(false); + } + } + + template < + typename T, + typename std::enable_if_t::value, int> = 0> + bool equal(T num) const { + if (isComplex()) { + TORCH_INTERNAL_ASSERT(!isSymbolic()); + return v.z == num; + } else if (isFloatingPoint()) { + return (toDouble() == num.real()) && (num.imag() == T()); + } else if (tag == Tag::HAS_i) { + if (overflows(v.i, /* strict_unsigned */ true)) { + return false; + } else { + return static_cast(v.i) == num.real() && num.imag() == T(); + } + } else if (tag == Tag::HAS_u) { + if (overflows(v.u, /* strict_unsigned */ true)) { + return false; + } else { + return static_cast(v.u) == num.real() && num.imag() == T(); + } + } else if (tag == Tag::HAS_si) { + TORCH_INTERNAL_ASSERT(false, "NYI SymInt equality"); + } else if (isBoolean()) { + // boolean scalar does not equal to a non boolean value + TORCH_INTERNAL_ASSERT(!isSymbolic()); + return false; + } else { + TORCH_INTERNAL_ASSERT(false); + } + } + + bool equal(bool num) const { + if (isBoolean()) { + TORCH_INTERNAL_ASSERT(!isSymbolic()); + return static_cast(v.i) == num; + } else { + return false; + } + } + + ScalarType type() const { + if (isComplex()) { + return ScalarType::ComplexDouble; + } else if (isFloatingPoint()) { + return ScalarType::Double; + } else if (isIntegral(/*includeBool=*/false)) { + // Represent all integers as long, UNLESS it is unsigned and therefore + // unrepresentable as long + if (Tag::HAS_u == tag) { + return ScalarType::UInt64; + } + return ScalarType::Long; + } else if (isBoolean()) { + return ScalarType::Bool; + } else { + TORCH_CHECK(false, "Unknown scalar type."); + } + } + + Scalar(Scalar&& rhs) noexcept : tag(rhs.tag) { + moveFrom(std::move(rhs)); + } + + Scalar(const Scalar& rhs) : tag(rhs.tag), v(rhs.v) { + if (isSymbolic()) { + c10::raw::intrusive_ptr::incref(v.p); + } + } + + Scalar(c10::SymInt si) { + if (auto m = si.maybe_as_int()) { + tag = Tag::HAS_i; + v.i = *m; + } else { + tag = Tag::HAS_si; + v.p = std::move(si).release(); + } + } + + Scalar(c10::SymFloat sd) { + if (sd.is_symbolic()) { + tag = Tag::HAS_sd; + v.p = std::move(sd).release(); + } else { + tag = Tag::HAS_d; + v.d = sd.as_float_unchecked(); + } + } + + Scalar(c10::SymBool sb) { + if (auto m = sb.maybe_as_bool()) { + tag = Tag::HAS_b; + v.i = *m; + } else { + tag = Tag::HAS_sb; + v.p = std::move(sb).release(); + } + } + + // We can't set v in the initializer list using the + // syntax v{ .member = ... } because it doesn't work on MSVC + private: + enum class Tag { HAS_d, HAS_i, HAS_u, HAS_z, HAS_b, HAS_sd, HAS_si, HAS_sb }; + + // Note [Meaning of HAS_u] + // ~~~~~~~~~~~~~~~~~~~~~~~ + // HAS_u is a bit special. On its face, it just means that we + // are holding an unsigned integer. However, we generally don't + // distinguish between different bit sizes in Scalar (e.g., we represent + // float as double), instead, it represents a mathematical notion + // of some quantity (integral versus floating point). So actually, + // HAS_u is used solely to represent unsigned integers that could + // not be represented as a signed integer. That means only uint64_t + // potentially can get this tag; smaller types like uint8_t fits into a + // regular int and so for BC reasons we keep as an int. + + // NB: assumes that self has already been cleared + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + C10_ALWAYS_INLINE void moveFrom(Scalar&& rhs) noexcept { + v = rhs.v; + tag = rhs.tag; + if (rhs.tag == Tag::HAS_si || rhs.tag == Tag::HAS_sd || + rhs.tag == Tag::HAS_sb) { + // Move out of scalar + rhs.tag = Tag::HAS_i; + rhs.v.i = 0; + } + } + + Tag tag; + + union v_t { + double d{}; + int64_t i; + // See Note [Meaning of HAS_u] + uint64_t u; + c10::complex z; + c10::intrusive_ptr_target* p; + // NOLINTNEXTLINE(modernize-use-equals-default) + v_t() {} // default constructor + } v; + + template < + typename T, + typename std::enable_if_t< + std::is_integral_v && !std::is_same_v, + bool>* = nullptr> + Scalar(T vv, bool /*unused*/) : tag(Tag::HAS_i) { + v.i = convert(vv); + } + + template < + typename T, + typename std::enable_if_t< + !std::is_integral_v && !c10::is_complex::value, + bool>* = nullptr> + Scalar(T vv, bool /*unused*/) : tag(Tag::HAS_d) { + v.d = convert(vv); + } + + template < + typename T, + typename std::enable_if_t::value, bool>* = nullptr> + Scalar(T vv, bool /*unused*/) : tag(Tag::HAS_z) { + v.z = convert(vv); + } +}; + +using OptionalScalarRef = c10::OptionalRef; + +// define the scalar.to() specializations +#define DEFINE_TO(T, name) \ + template <> \ + inline T Scalar::to() const { \ + return to##name(); \ + } +AT_FORALL_SCALAR_TYPES_WITH_COMPLEX(DEFINE_TO) +DEFINE_TO(uint16_t, UInt16) +DEFINE_TO(uint32_t, UInt32) +DEFINE_TO(uint64_t, UInt64) +#undef DEFINE_TO + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/ScalarType.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/ScalarType.h new file mode 100644 index 0000000000000000000000000000000000000000..4ba32310148bfcafbf2f4a6643c69156b128b31c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/ScalarType.h @@ -0,0 +1,310 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-enum") +C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-default") + +namespace c10 { + +// See [dtype Macros note] in torch/headeronly/core/ScalarType.h +// regarding macros. + +#define DEFINE_CONSTANT(_, name) \ + constexpr ScalarType k##name = ScalarType::name; + +// NOLINTNEXTLINE(clang-diagnostic-unused-const-variable) +AT_FORALL_SCALAR_TYPES_WITH_COMPLEX_AND_QINTS(DEFINE_CONSTANT) +#undef DEFINE_CONSTANT + +inline size_t elementSize(ScalarType t) { +#define CASE_ELEMENTSIZE_CASE(ctype, name) \ + case ScalarType::name: \ + return sizeof(ctype); + + switch (t) { + AT_FORALL_SCALAR_TYPES_WITH_COMPLEX_AND_QINTS(CASE_ELEMENTSIZE_CASE) + default: + TORCH_CHECK(false, "Unknown ScalarType"); + } +#undef CASE_ELEMENTSIZE_CASE +} + +inline ScalarType opaqueScalarType(ScalarType t) { + auto esize = elementSize(t); + ScalarType result; + switch (esize) { + case 1: + result = kByte; + break; + case 2: + result = kUInt16; + break; + case 4: + result = kUInt32; + break; + case 8: + result = kUInt64; + break; + case 16: + result = kComplexDouble; + break; + default: + TORCH_CHECK(false, "Unknown ScalarType"); + } + return result; +} + +inline bool isIntegralType(ScalarType t, bool includeBool) { + bool isIntegral = + (t == ScalarType::Byte || t == ScalarType::Char || t == ScalarType::Int || + t == ScalarType::Long || t == ScalarType::Short || + t == ScalarType::UInt16 || t == ScalarType::UInt32 || + t == ScalarType::UInt64); + + return isIntegral || (includeBool && t == ScalarType::Bool); +} + +[[deprecated( + "isIntegralType is deprecated. Please use the overload with 'includeBool' parameter instead.")]] inline bool +isIntegralType(ScalarType t) { + return isIntegralType(t, /*includeBool=*/false); +} + +inline bool isFloat8Type(ScalarType t) { + return t == ScalarType::Float8_e5m2 || t == ScalarType::Float8_e5m2fnuz || + t == ScalarType::Float8_e4m3fn || t == ScalarType::Float8_e4m3fnuz || + t == ScalarType::Float8_e8m0fnu; +} + +inline bool isReducedFloatingType(ScalarType t) { + return t == ScalarType::Half || t == ScalarType::BFloat16 || + isFloat8Type(t) || t == ScalarType::Float4_e2m1fn_x2; +} + +inline bool isFloatingType(ScalarType t) { + return t == ScalarType::Double || t == ScalarType::Float || + isReducedFloatingType(t); +} + +inline bool isComplexType(ScalarType t) { + return ( + t == ScalarType::ComplexHalf || t == ScalarType::ComplexFloat || + t == ScalarType::ComplexDouble); +} + +inline bool isBitsType(ScalarType t) { + return t == ScalarType::Bits1x8 || t == ScalarType::Bits2x4 || + t == ScalarType::Bits4x2 || t == ScalarType::Bits8 || + t == ScalarType::Bits16; +} + +inline bool isBarebonesUnsignedType(ScalarType t) { + return t == ScalarType::UInt1 || t == ScalarType::UInt2 || + t == ScalarType::UInt3 || t == ScalarType::UInt4 || + t == ScalarType::UInt5 || t == ScalarType::UInt6 || + t == ScalarType::UInt7 || t == ScalarType::UInt16 || + t == ScalarType::UInt32 || t == ScalarType::UInt64; +} + +inline ScalarType toQIntType(ScalarType t) { + switch (t) { + case ScalarType::Byte: + return ScalarType::QUInt8; + case ScalarType::Char: + return ScalarType::QInt8; + case ScalarType::Int: + return ScalarType::QInt32; + default: + return t; + } +} + +inline bool isSignedType(ScalarType t) { +#define CASE_ISSIGNED(name) \ + case ScalarType::name: \ + return std::numeric_limits< \ + ::c10::impl::ScalarTypeToCPPTypeT>::is_signed; + + // TODO(#146647): If we expect to have numeric_limits for everything, + // let's just have a big macro for the whole thing. + // If we're hardcoding it, let's just use the macro and a "true"/"false" + // below? + switch (t) { + case ScalarType::QInt8: + case ScalarType::QUInt8: + case ScalarType::QInt32: + case ScalarType::QUInt4x2: + case ScalarType::QUInt2x4: + TORCH_CHECK(false, "isSignedType not supported for quantized types"); + case ScalarType::Bits1x8: + case ScalarType::Bits2x4: + case ScalarType::Bits4x2: + case ScalarType::Bits8: + case ScalarType::Bits16: + TORCH_CHECK(false, "Bits types are undefined"); + CASE_ISSIGNED(UInt16); + CASE_ISSIGNED(UInt32); + CASE_ISSIGNED(UInt64); + CASE_ISSIGNED(BFloat16); + CASE_ISSIGNED(Float8_e5m2); + CASE_ISSIGNED(Float8_e5m2fnuz); + CASE_ISSIGNED(Float8_e4m3fn); + CASE_ISSIGNED(Float8_e4m3fnuz); + CASE_ISSIGNED(Float8_e8m0fnu); + CASE_ISSIGNED(Byte); + CASE_ISSIGNED(Char); + CASE_ISSIGNED(Short); + CASE_ISSIGNED(Int); + CASE_ISSIGNED(Long); + CASE_ISSIGNED(Half); + CASE_ISSIGNED(Float); + CASE_ISSIGNED(Double); + CASE_ISSIGNED(ComplexHalf); + CASE_ISSIGNED(ComplexFloat); + CASE_ISSIGNED(ComplexDouble); + CASE_ISSIGNED(Bool); + case ScalarType::Int1: + case ScalarType::Int2: + case ScalarType::Int3: + case ScalarType::Int4: + case ScalarType::Int5: + case ScalarType::Int6: + case ScalarType::Int7: + case ScalarType::Float4_e2m1fn_x2: + return true; + case ScalarType::UInt1: + case ScalarType::UInt2: + case ScalarType::UInt3: + case ScalarType::UInt4: + case ScalarType::UInt5: + case ScalarType::UInt6: + case ScalarType::UInt7: + return false; + case ScalarType::Undefined: + case ScalarType::NumOptions: + break; + // Do not add default here, but rather define behavior of every new entry + // here. `-Wswitch-enum` would raise a warning in those cases. + // TODO: get PyTorch to adopt exhaustive switches by default with a way to + // opt specific switches to being non-exhaustive. + // Exhaustive: + // `-Wswitch-enum`, `-Wswitch-default`, `-Wno-covered-switch-default` + // Non-Exhaustive: + // `-Wno-switch-enum`, `-Wswitch-default`, `-Wcovered-switch-default` + } + TORCH_CHECK(false, "Unknown ScalarType ", t); +#undef CASE_ISSIGNED +} + +inline bool isUnderlying(ScalarType type, ScalarType qtype) { + return type == toUnderlying(qtype); +} + +inline ScalarType toRealValueType(ScalarType t) { + switch (t) { + case ScalarType::ComplexHalf: + return ScalarType::Half; + case ScalarType::ComplexFloat: + return ScalarType::Float; + case ScalarType::ComplexDouble: + return ScalarType::Double; + default: + return t; + } +} + +inline ScalarType toComplexType(ScalarType t) { + switch (t) { + case ScalarType::BFloat16: + // BFloat16 has range equivalent to Float, + // so we map it to ComplexFloat. + return ScalarType::ComplexFloat; + case ScalarType::Half: + return ScalarType::ComplexHalf; + case ScalarType::Float: + return ScalarType::ComplexFloat; + case ScalarType::Double: + return ScalarType::ComplexDouble; + case ScalarType::ComplexHalf: + return ScalarType::ComplexHalf; + case ScalarType::ComplexFloat: + return ScalarType::ComplexFloat; + case ScalarType::ComplexDouble: + return ScalarType::ComplexDouble; + default: + TORCH_CHECK(false, "Unknown Complex ScalarType for ", t); + } +} + +// see tensor_attributes.rst for detailed explanation and examples +// of casting rules. +inline bool canCast(const ScalarType from, const ScalarType to) { + // We disallow complex -> non complex, e.g., float_tensor *= complex is + // disallowed. + if (isComplexType(from) && !isComplexType(to)) { + return false; + } + // We disallow float -> integral, e.g., int_tensor *= float is disallowed. + if (isFloatingType(from) && isIntegralType(to, false)) { + return false; + } + + // Treat bool as a distinct "category," to be consistent with type promotion + // rules (e.g. `bool_tensor + 5 -> int64_tensor`). If `5` was in the same + // category as `bool_tensor`, we would not promote. Differing categories + // implies `bool_tensor += 5` is disallowed. + // + // NB: numpy distinguishes "unsigned" as a category to get the desired + // `bool_tensor + 5 -> int64_tensor` behavior. We don't, because: + // * We don't want the performance hit of checking the runtime sign of + // Scalars. + // * `uint8_tensor + 5 -> int64_tensor` would be undesirable. + if (from != ScalarType::Bool && to == ScalarType::Bool) { + return false; + } + return true; +} + +C10_API ScalarType promoteTypes(ScalarType a, ScalarType b); + +// Returns a pair of strings representing the names for each dtype. +// The returned pair is (name, legacy_name_if_applicable) +C10_API std::pair getDtypeNames( + c10::ScalarType scalarType); + +// Returns a map of string name to dtype. +C10_API const std::unordered_map& getStringToDtypeMap(); + +} // namespace c10 + +C10_DIAGNOSTIC_POP() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/ScalarTypeToTypeMeta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/ScalarTypeToTypeMeta.h new file mode 100644 index 0000000000000000000000000000000000000000..d952b0dd2089207bef2bd3b53d348d6cb667e046 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/ScalarTypeToTypeMeta.h @@ -0,0 +1,62 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +// these just expose TypeMeta/ScalarType bridge functions in c10 +// TODO move to typeid.h (or codemod away) when TypeMeta et al +// are moved from caffe2 to c10 (see note at top of typeid.h) + +namespace c10 { + +/** + * convert ScalarType enum values to TypeMeta handles + */ +inline caffe2::TypeMeta scalarTypeToTypeMeta(ScalarType scalar_type) { + return caffe2::TypeMeta::fromScalarType(scalar_type); +} + +/** + * convert TypeMeta handles to ScalarType enum values + */ +inline ScalarType typeMetaToScalarType(caffe2::TypeMeta dtype) { + return dtype.toScalarType(); +} + +/** + * typeMetaToScalarType(), lifted to optional + */ +inline std::optional optTypeMetaToScalarType( + std::optional type_meta) { + if (!type_meta.has_value()) { + return std::nullopt; + } + return type_meta->toScalarType(); +} + +/** + * convenience: equality across TypeMeta/ScalarType conversion + */ +inline bool operator==(ScalarType t, caffe2::TypeMeta m) { + return m.isScalarType(t); +} + +inline bool operator==(caffe2::TypeMeta m, ScalarType t) { + return t == m; +} + +inline bool operator!=(ScalarType t, caffe2::TypeMeta m) { + return !(t == m); +} + +inline bool operator!=(caffe2::TypeMeta m, ScalarType t) { + return !(t == m); +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Storage.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Storage.h new file mode 100644 index 0000000000000000000000000000000000000000..ec425358953511dcc2e2314ee5495b7c87a995a7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Storage.h @@ -0,0 +1,297 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +struct Storage; + +C10_API bool isSharedStorageAlias( + const Storage& storage0, + const Storage& storage1); + +struct C10_API Storage { + public: + struct use_byte_size_t {}; + struct unsafe_borrow_t { + explicit unsafe_borrow_t() = default; + }; + + Storage() = default; + Storage(c10::intrusive_ptr ptr) + : storage_impl_(std::move(ptr)) {} + + // Allocates memory buffer using given allocator and creates a storage with it + Storage( + use_byte_size_t /*use_byte_size*/, + const SymInt& size_bytes, + Allocator* allocator = nullptr, + bool resizable = false) + : storage_impl_(c10::make_intrusive( + StorageImpl::use_byte_size_t(), + size_bytes, + allocator, + resizable)) {} + + // Creates storage with pre-allocated memory buffer. Allocator is given for + // potential future reallocations, however it can be nullptr if the storage + // is non-resizable + Storage( + use_byte_size_t /*use_byte_size*/, + size_t size_bytes, + at::DataPtr data_ptr, + at::Allocator* allocator = nullptr, + bool resizable = false) + : storage_impl_(c10::make_intrusive( + StorageImpl::use_byte_size_t(), + size_bytes, + std::move(data_ptr), + allocator, + resizable)) {} + + // Creates storage with pre-allocated memory buffer. Allocator is given for + // potential future reallocations, however it can be nullptr if the storage + // is non-resizable + Storage( + use_byte_size_t /*use_byte_size*/, + SymInt size_bytes, + at::DataPtr data_ptr, + at::Allocator* allocator = nullptr, + bool resizable = false) + : storage_impl_(c10::make_intrusive( + StorageImpl::use_byte_size_t(), + std::move(size_bytes), + std::move(data_ptr), + allocator, + resizable)) {} + + protected: + explicit Storage(unsafe_borrow_t /*unused*/, const Storage& rhs) + : storage_impl_(c10::intrusive_ptr::reclaim( + rhs.storage_impl_.get())) {} + + friend MaybeOwnedTraits; + + public: + // Legacy constructor for partially initialized (dtype or memory) storages + // that can be temporarily created with Caffe2 APIs. See the note on top of + // TensorImpl.h for details. + static Storage create_legacy(at::Device device) { + auto allocator = GetAllocator(device.type()); + return Storage(c10::make_intrusive( + StorageImpl::use_byte_size_t(), + 0, + allocator->allocate(0), // materialize a non-default Device. + allocator, + true)); + } + + // Mimic create_legacy, but without requiring a newly-created StorageImpl. + void reset_legacy() { + TORCH_CHECK(resizable() && allocator()); + set_nbytes(0); + set_data_ptr_noswap(allocator()->allocate(0)); + } + + // TODO: remove later + void set_nbytes(size_t size_bytes) const { + storage_impl_->set_nbytes(size_bytes); + } + + void set_nbytes(c10::SymInt size_bytes) const { + storage_impl_->set_nbytes(std::move(size_bytes)); + } + + bool resizable() const { + return storage_impl_->resizable(); + } + + size_t nbytes() const { + return storage_impl_->nbytes(); + } + + SymInt sym_nbytes() const { + return storage_impl_->sym_nbytes(); + } + // get() use here is to get const-correctness + + const void* data() const { + return storage_impl_->data(); + } + + void* mutable_data() const { + return storage_impl_->mutable_data(); + } + + at::DataPtr& mutable_data_ptr() const { + return storage_impl_->mutable_data_ptr(); + } + + const at::DataPtr& data_ptr() const { + return storage_impl_->data_ptr(); + } + + // Returns the previous data_ptr + at::DataPtr set_data_ptr(at::DataPtr&& data_ptr) const { + return storage_impl_->set_data_ptr(std::move(data_ptr)); + } + + void set_data_ptr_noswap(at::DataPtr&& data_ptr) const { + storage_impl_->set_data_ptr_noswap(std::move(data_ptr)); + } + + void swap_data_ptr(Storage& other) const { + storage_impl_->swap_data_ptr(*other.storage_impl_); + } + + DeviceType device_type() const { + return storage_impl_->device_type(); + } + + at::Allocator* allocator() const { + return storage_impl_->allocator(); + } + + at::Device device() const { + return storage_impl_->device(); + } + + StorageImpl* unsafeReleaseStorageImpl() { + return storage_impl_.release(); + } + + StorageImpl* unsafeGetStorageImpl() const noexcept { + return storage_impl_.get(); + } + + c10::weak_intrusive_ptr getWeakStorageImpl() const { + return c10::weak_intrusive_ptr(storage_impl_); + } + + operator bool() const { + return storage_impl_; + } + + size_t use_count() const { + return storage_impl_.use_count(); + } + + inline bool unique() const { + return storage_impl_.unique(); + } + + bool is_alias_of(const Storage& other) const { + return ( + storage_impl_ == other.storage_impl_ || + isSharedStorageAlias(*this, other)); + } + + void UniqueStorageShareExternalPointer( + void* src, + size_t capacity, + DeleterFnPtr d = nullptr) { + if (!storage_impl_.unique()) { + TORCH_CHECK( + false, + "UniqueStorageShareExternalPointer can only be called when use_count == 1"); + } + storage_impl_->UniqueStorageShareExternalPointer(src, capacity, d); + } + + void UniqueStorageShareExternalPointer( + at::DataPtr&& data_ptr, + size_t capacity) { + if (!storage_impl_.unique()) { + TORCH_CHECK( + false, + "UniqueStorageShareExternalPointer can only be called when use_count == 1"); + } + storage_impl_->UniqueStorageShareExternalPointer( + std::move(data_ptr), capacity); + } + + protected: + c10::intrusive_ptr storage_impl_; +}; + +template <> +struct MaybeOwnedTraits { + using owned_type = c10::Storage; + using borrow_type = c10::Storage; + + static borrow_type createBorrow(const owned_type& from) { + return borrow_type(borrow_type::unsafe_borrow_t{}, from); + } + + static void assignBorrow(borrow_type& lhs, const borrow_type& rhs) { + lhs.unsafeReleaseStorageImpl(); + lhs = borrow_type(borrow_type::unsafe_borrow_t{}, rhs); + } + + static void destroyBorrow(borrow_type& toDestroy) { + toDestroy.unsafeReleaseStorageImpl(); // "leak" it, but it was already +0. + } + + static const owned_type& referenceFromBorrow(const borrow_type& borrow) { + return borrow; + } + + static const owned_type* pointerFromBorrow(const borrow_type& borrow) { + return &borrow; + } + + static bool debugBorrowIsValid(const borrow_type& /*borrow*/) { + return true; + } +}; + +template <> +struct ExclusivelyOwnedTraits { + using repr_type = c10::Storage; + using pointer_type = c10::Storage*; + using const_pointer_type = const c10::Storage*; + + static repr_type nullRepr() { + return c10::Storage(); + } + + template + static repr_type createInPlace(Args&&... args) { + return c10::Storage(std::forward(args)...); + } + + static repr_type moveToRepr(c10::Storage&& x) { + return std::move(x); + } + + static c10::Storage take(c10::Storage& x) { + return std::move(x); + } + + static pointer_type getImpl(repr_type& x) { + return &x; + } + + static const_pointer_type getImpl(const repr_type& x) { + return &x; + } +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/StorageImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/StorageImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..c7e8cb855ac9df728ff71361d2131fc8147aefea --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/StorageImpl.h @@ -0,0 +1,424 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +[[noreturn]] C10_API void throwNullDataPtrError(); +C10_API void warnDeprecatedDataPtr(); + +// Used in StorageImpl to store extra metadata. +// Currently used only for storing a custom error message +// used when throwing an exception when data_ptr is accessed. +struct C10_API StorageExtraMeta { + std::optional custom_data_ptr_error_msg_ = std::nullopt; +}; + +// A storage represents the underlying backing data buffer for a +// tensor. This concept was inherited from the original Torch7 +// codebase; we'd kind of like to get rid of the concept +// (see https://github.com/pytorch/pytorch/issues/14797) but +// it's hard work and no one has gotten around to doing it. +// +// NB: storage is supposed to uniquely own a data pointer; e.g., +// two non-null data pointers alias if and only if they are from +// the same storage. Technically you can violate this invariant +// (e.g., you can create a non-owning StorageImpl with at::from_blob) +// but a lot of things won't work correctly, including: +// +// - An ordinary deleter on such a storage is wrong, because normal deleters +// assume unique ownership, but if you have two storages at the same data, +// that implies there is some sort of shared ownership. So your deleter would +// have to actually be internally doing some sort of refcount thing +// - Deepcopy in Python side relies on storage equality and not data pointer +// equality; so if there are two separate storages pointing to the same data, +// the data will actually get duplicated in that case (one data ptr before, +// two data ptrs after) +// - Version counts won't work correctly, because we do all VC tracking at the +// level of storages (unless you explicitly disconnect the VC with detach); +// mutation because data pointers are the same are totally untracked +struct C10_API StorageImpl : public c10::intrusive_ptr_target { + public: + struct use_byte_size_t {}; + + StorageImpl( + use_byte_size_t /*use_byte_size*/, + SymInt size_bytes, + at::DataPtr data_ptr, + at::Allocator* allocator, + bool resizable) + : data_ptr_(std::move(data_ptr)), + size_bytes_(std::move(size_bytes)), + size_bytes_is_heap_allocated_(size_bytes_.is_heap_allocated()), + resizable_(resizable), + received_cuda_(false), + allocator_(allocator) { + if (resizable) { + TORCH_INTERNAL_ASSERT( + allocator_, "For resizable storage, allocator must be provided"); + } + refresh_has_data_ptr_check(); + } + + StorageImpl( + use_byte_size_t /*use_byte_size*/, + const SymInt& size_bytes, + at::Allocator* allocator, + bool resizable) + : StorageImpl( + use_byte_size_t(), + size_bytes, + size_bytes.is_heap_allocated() + ? allocator->allocate(0) + : allocator->allocate(size_bytes.as_int_unchecked()), + allocator, + resizable) {} + + StorageImpl& operator=(StorageImpl&& other) = delete; + StorageImpl& operator=(const StorageImpl&) = delete; + StorageImpl() = delete; + StorageImpl(StorageImpl&& other) = delete; + StorageImpl(const StorageImpl&) = delete; + ~StorageImpl() override = default; + + void reset() { + data_ptr_.clear(); + size_bytes_ = 0; + size_bytes_is_heap_allocated_ = false; + } + + // Destructor doesn't call release_resources because it's + // unnecessary; don't forget to change that if needed! + void release_resources() override { + data_ptr_.clear(); + } + + void incref_pyobject() const noexcept final; + + void decref_pyobject() const noexcept final; + + bool try_incref_pyobject() const noexcept final; + + size_t nbytes() const { + // OK to do this instead of maybe_as_int as nbytes is guaranteed positive + TORCH_CHECK(!size_bytes_is_heap_allocated_); + return size_bytes_.as_int_unchecked(); + } + + SymInt sym_nbytes() const { + return size_bytes_; + } + + // TODO: remove later + void set_nbytes(size_t size_bytes) { + size_bytes_ = static_cast(size_bytes); + size_bytes_is_heap_allocated_ = false; + } + + void unsafe_set_nbytes(size_t size_bytes) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(!size_bytes_is_heap_allocated_); + size_bytes_.unsafe_set_data(size_bytes); + } + + void set_nbytes(c10::SymInt size_bytes) { + size_bytes_ = std::move(size_bytes); + } + + bool resizable() const { + return resizable_; + } + + const at::DataPtr& data_ptr() const { + if (C10_UNLIKELY(throw_on_immutable_data_ptr_)) { + throw_data_ptr_access_error(); + } + return data_ptr_; + } + + at::DataPtr& mutable_data_ptr() { + if (C10_UNLIKELY(has_mutable_data_ptr_check_)) { + if (throw_on_immutable_data_ptr_) { + throw_data_ptr_access_error(); + } + if (throw_on_mutable_data_ptr_) { + throwNullDataPtrError(); + } + if (warn_deprecated_on_mutable_data_ptr_) { + warnDeprecatedDataPtr(); + } + maybe_materialize_cow(); + } + return data_ptr_; + } + + // Returns the data_ptr. Bypasses all checks. + at::DataPtr& _mutable_data_ptr_no_checks() { + return data_ptr_; + } + + // Returns the previous data_ptr + at::DataPtr set_data_ptr(at::DataPtr&& data_ptr) { + // We need to materialize the old COW DataPtr because it is + // being returned as mutable. + maybe_materialize_cow(); + return set_data_ptr_no_materialize_cow(std::move(data_ptr)); + } + + void set_data_ptr_noswap(at::DataPtr&& data_ptr) { + data_ptr_ = std::move(data_ptr); + refresh_has_data_ptr_check(); + } + + void swap_data_ptr(StorageImpl& other) { + maybe_materialize_cow(); + other.maybe_materialize_cow(); + std::swap(data_ptr_, other.data_ptr_); + std::swap(size_bytes_, other.size_bytes_); + std::swap( + size_bytes_is_heap_allocated_, other.size_bytes_is_heap_allocated_); + std::swap(resizable_, other.resizable_); + std::swap(allocator_, other.allocator_); + std::swap(throw_on_immutable_data_ptr_, other.throw_on_immutable_data_ptr_); + std::swap(throw_on_mutable_data_ptr_, other.throw_on_mutable_data_ptr_); + std::swap( + warn_deprecated_on_mutable_data_ptr_, + other.warn_deprecated_on_mutable_data_ptr_); + refresh_has_data_ptr_check(); + other.refresh_has_data_ptr_check(); + } + + const void* data() const { + if (C10_UNLIKELY(throw_on_immutable_data_ptr_)) { + throw_data_ptr_access_error(); + } + return data_ptr_.get(); + } + + void* mutable_data() { + if (C10_UNLIKELY(has_mutable_data_ptr_check_)) { + if (throw_on_immutable_data_ptr_) { + throw_data_ptr_access_error(); + } + if (throw_on_mutable_data_ptr_) { + throwNullDataPtrError(); + } + if (warn_deprecated_on_mutable_data_ptr_) { + warnDeprecatedDataPtr(); + } + maybe_materialize_cow(); + } + return data_ptr_.mutable_get(); + } + + at::DeviceType device_type() const { + return data_ptr_.device().type(); + } + + at::Allocator* allocator() { + return allocator_; + } + + const at::Allocator* allocator() const { + return allocator_; + } + + // You generally shouldn't use this method, but it is occasionally + // useful if you want to override how a tensor will be reallocated, + // after it was already allocated (and its initial allocator was + // set) + void set_allocator(at::Allocator* allocator) { + allocator_ = allocator; + } + + Device device() const { + return data_ptr_.device(); + } + + void set_resizable(bool resizable) { + if (resizable) { + // We need an allocator to be resizable + AT_ASSERT(allocator_); + } + resizable_ = resizable; + } + + /** + * Can only be called when use_count is 1 + */ + void UniqueStorageShareExternalPointer( + void* src, + size_t size_bytes, + DeleterFnPtr d = nullptr) { + UniqueStorageShareExternalPointer( + at::DataPtr(src, src, d, data_ptr_.device()), size_bytes); + } + + /** + * Can only be called when use_count is 1 + */ + void UniqueStorageShareExternalPointer( + at::DataPtr&& data_ptr, + size_t size_bytes) { + data_ptr_ = std::move(data_ptr); + size_bytes_ = static_cast(size_bytes); + size_bytes_is_heap_allocated_ = false; + allocator_ = nullptr; + resizable_ = false; + } + + // This method can be used only after storage construction and cannot be used + // to modify storage status + void set_received_cuda(bool received_cuda) { + received_cuda_ = received_cuda; + } + + bool received_cuda() { + return received_cuda_; + } + + impl::PyObjectSlot* pyobj_slot() { + return &pyobj_slot_; + } + + const impl::PyObjectSlot* pyobj_slot() const { + return &pyobj_slot_; + } + + StorageExtraMeta& get_extra_meta() { + if (!extra_meta_) { + extra_meta_ = std::make_unique(); + } + return *extra_meta_; + } + + [[noreturn]] void throw_data_ptr_access_error() const; + + void release_data_and_set_meta_custom_data_ptr_error_msg_( + std::optional s) { + throw_on_immutable_data_ptr_ = true; + get_extra_meta().custom_data_ptr_error_msg_ = std::move(s); + refresh_has_data_ptr_check(); + } + + void clear_data_ptr_access_error_msg_() { + throw_on_immutable_data_ptr_ = false; + if (extra_meta_) { + extra_meta_->custom_data_ptr_error_msg_ = std::nullopt; + } + refresh_has_data_ptr_check(); + } + + void set_throw_on_mutable_data_ptr() { + throw_on_mutable_data_ptr_ = true; + refresh_has_data_ptr_check(); + } + + void set_warn_deprecated_on_mutable_data_ptr() { + warn_deprecated_on_mutable_data_ptr_ = true; + refresh_has_data_ptr_check(); + } + + protected: + // materialize_cow_storage needs to call set_data_ptr_no_materlize_cow + friend void c10::impl::cow::materialize_cow_storage(StorageImpl& storage); + + // Returns the previous data_ptr. If the old data_ptr was COW, + // this avoids materializing it + at::DataPtr set_data_ptr_no_materialize_cow(at::DataPtr&& data_ptr) { + at::DataPtr old_data_ptr(std::move(data_ptr_)); + data_ptr_ = std::move(data_ptr); + refresh_has_data_ptr_check(); + return old_data_ptr; + } + + private: + void refresh_has_data_ptr_check() { + has_mutable_data_ptr_check_ = is_cow() || throw_on_mutable_data_ptr_ || + warn_deprecated_on_mutable_data_ptr_ || throw_on_immutable_data_ptr_; + } + + inline bool is_cow() const { + return c10::impl::cow::is_cow_data_ptr(data_ptr_); + } + + // Triggers a copy if this is a copy-on-write tensor. + void maybe_materialize_cow() { + if (is_cow()) { + impl::cow::materialize_cow_storage(*this); + } + } + + DataPtr data_ptr_; + SymInt size_bytes_; + bool size_bytes_is_heap_allocated_; + bool resizable_; + // Identifies that Storage was received from another process and doesn't have + // local to process cuda memory allocation + bool received_cuda_; + // All special checks in data/data_ptr calls are guarded behind this single + // boolean. This is for performance: .data/.data_ptr calls are commonly in the + // hot-path. + bool has_mutable_data_ptr_check_ = false; + // If we should throw when mutable_data_ptr() or mutable_data() is called. + bool throw_on_mutable_data_ptr_ = false; + // If we should throw when data_ptr() or data() is called. + bool throw_on_immutable_data_ptr_ = false; + // If we warn when mutable_data_ptr() or mutable_data() is called. + bool warn_deprecated_on_mutable_data_ptr_ = false; + Allocator* allocator_; + impl::PyObjectSlot pyobj_slot_; + std::unique_ptr extra_meta_ = nullptr; +}; + +// Declare StorageImpl create function pointer types. +using StorageImplCreateHelper = intrusive_ptr (*)( + StorageImpl::use_byte_size_t, + SymInt size_bytes, + DataPtr data_ptr, + Allocator* allocator, + bool resizable); + +C10_API void SetStorageImplCreate(DeviceType t, StorageImplCreateHelper fptr); + +C10_API StorageImplCreateHelper GetStorageImplCreate(DeviceType t); + +C10_API c10::intrusive_ptr make_storage_impl( + c10::StorageImpl::use_byte_size_t use_byte_size, + c10::SymInt size_bytes, + c10::DataPtr data_ptr, + c10::Allocator* allocator, + bool resizable, + std::optional device_opt); + +namespace detail { + +#ifndef C10_MOBILE +template +struct TargetTraits< + T, + std::enable_if_t< + std::is_base_of_v>>> { + static constexpr bool can_have_pyobject = true; +}; +#endif + +} // namespace detail + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Stream.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Stream.h new file mode 100644 index 0000000000000000000000000000000000000000..c209a5ebfe404774fd1a0a88f64faf6648e443f7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/Stream.h @@ -0,0 +1,191 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +/// An index representing a specific stream. A StreamId is not independently +/// meaningful without knowing the Device it is associated with; try to +/// use Stream rather than StreamId directly. +/// +/// StreamIds are opaque; they are assigned by some DeviceType-specific +/// numbering system which is not visible to the user. HOWEVER, we +/// guarantee that StreamId 0 is always a valid stream, and corresponds +/// to some sort of "default" stream. +using StreamId = int64_t; + +struct C10_API StreamData3 { + StreamId stream_id; + DeviceIndex device_index; + DeviceType device_type; +}; + +// NB: I decided not to call the above StreamIndex to avoid confusion with +// DeviceIndex. This way, you access device index with index(), and stream id +// with id() + +/** + * A stream is a software mechanism used to synchronize launched kernels + * without requiring explicit synchronizations between kernels. The basic + * model is that every kernel launch is associated with a stream: every + * kernel on the same stream is implicitly synchronized so that if I launch + * kernels A and B on the same stream, A is guaranteed to finish before B + * launches. If I want B to run concurrently with A, I must schedule + * it on a different stream. + * + * The Stream class is a backend agnostic value class representing a stream + * which I may schedule a kernel on. Every stream is associated with a device, + * which is recorded in stream, which is used to avoid confusion about which + * device a stream refers to. + * + * Streams are explicitly thread-safe, in the sense that it is OK to pass + * a Stream from one thread to another, and kernels queued from two different + * threads will still get serialized appropriately. (Of course, the + * time when the kernels get queued is undetermined unless you synchronize + * host side ;) + * + * Stream does NOT have a default constructor. Streams are for expert + * users; if you want to use Streams, we're going to assume you know + * how to deal with C++ template error messages if you try to + * resize() a vector of Streams. + * + * Known instances of streams in backends: + * + * - cudaStream_t (CUDA) + * - hipStream_t (HIP) + * - cl_command_queue (OpenCL) (NB: Caffe2's existing OpenCL integration + * does NOT support command queues.) + * + * Because this class is device agnostic, it cannot provide backend-specific + * functionality (e.g., get the cudaStream_t of a CUDA stream.) There are + * wrapper classes which provide this functionality, e.g., CUDAStream. + */ +class C10_API Stream final { + private: + Device device_; + StreamId id_; + + public: + enum Unsafe { UNSAFE }; + enum Default { DEFAULT }; + + /// Unsafely construct a stream from a Device and a StreamId. In + /// general, only specific implementations of streams for a + /// backend should manufacture Stream directly in this way; other users + /// should use the provided APIs to get a stream. In particular, + /// we don't require backends to give any guarantees about non-zero + /// StreamIds; they are welcome to allocate in whatever way they like. + explicit Stream(Unsafe /*unused*/, Device device, StreamId id) + : device_(device), id_(id) {} + + /// Construct the default stream of a Device. The default stream is + /// NOT the same as the current stream; default stream is a fixed stream + /// that never changes, whereas the current stream may be changed by + /// StreamGuard. + explicit Stream(Default /*unused*/, Device device) + : device_(device), id_(0) {} + + bool operator==(const Stream& other) const noexcept { + return this->device_ == other.device_ && this->id_ == other.id_; + } + bool operator!=(const Stream& other) const noexcept { + return !(*this == other); + } + + Device device() const noexcept { + return device_; + } + DeviceType device_type() const noexcept { + return device_.type(); + } + DeviceIndex device_index() const noexcept { + return device_.index(); + } + StreamId id() const noexcept { + return id_; + } + + // Returns an opaque, backend-specific handle to the underlying stream. + // The handle is non-owning and its concrete type is backend-defined + // (e.g., a CUDA stream or a SYCL queue). + void* native_handle() const; + + // Enqueues a wait instruction in the stream's work queue. + // This instruction is a no-op unless the event is marked + // for recording. In that case the stream stops processing + // until the event is recorded. + template + void wait(const T& event) const { + event.block(*this); + } + + // Return whether all asynchronous work previously enqueued on this stream + // has completed running on the device. + bool query() const; + + // Wait (by blocking the calling thread) until all asynchronous work enqueued + // on this stream has completed running on the device. + void synchronize() const; + + // Return the stream is currently recording work for graph capture. True while + // the stream is in capture mode, false otherwise. + bool is_capturing() const; + + // The purpose of this function is to more conveniently permit binding + // of Stream to and from Python. Without packing, I have to setup a whole + // class with two fields (device and stream id); with packing I can just + // store a single uint64_t. + // + // The particular way we pack streams into a uint64_t is considered an + // implementation detail and should not be relied upon. + uint64_t hash() const noexcept { + // Concat these together into a 64-bit integer + uint64_t bits = static_cast(device_type()) << 56 | + static_cast(device_index()) << 48 | + // Remove the sign extension part of the 64-bit address because + // the id might be used to hold a pointer. + (static_cast(id()) & ((1ull << 48) - 1)); + return bits; + } + + struct StreamData3 pack3() const { + return {id(), device_index(), device_type()}; + } + + static Stream unpack3( + StreamId stream_id, + DeviceIndex device_index, + DeviceType device_type) { + TORCH_CHECK(isValidDeviceType(device_type)); + return Stream(UNSAFE, Device(device_type, device_index), stream_id); + } + + // I decided NOT to provide setters on this class, because really, + // why would you change the device of a stream? Just construct + // it correctly from the beginning dude. +}; + +C10_API std::ostream& operator<<(std::ostream& stream, const Stream& s); + +} // namespace c10 + +namespace std { +template <> +struct hash { + size_t operator()(c10::Stream s) const noexcept { + return std::hash{}(s.hash()); + } +}; +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/StreamGuard.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/StreamGuard.h new file mode 100644 index 0000000000000000000000000000000000000000..003816d62f6ce12223cc5106eee6ae37a26e04e9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/StreamGuard.h @@ -0,0 +1,178 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace c10 { + +/** + * A StreamGuard is an RAII class that changes the current device + * to the device corresponding to some stream, and changes the + * default stream on that device to be this stream. + * + * Use of StreamGuard is HIGHLY discouraged in operator definitions. In + * a single operator, you probably don't know enough about the global + * state of the world to profitably decide how to set streams. Let + * the caller handle this appropriately, and just use the current stream + * in your operator code. + * + * This StreamGuard does NOT have an uninitialized state; it is guaranteed + * to reset the stream and device on exit. If you are in a situation + * where you *might* want to setup a stream guard, see OptionalStreamGuard. + */ +struct StreamGuard { + /// No default constructor, see Note [Omitted default constructor from RAII] + explicit StreamGuard() = delete; + ~StreamGuard() = default; + + /// Set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream. + explicit StreamGuard(Stream stream) : guard_(stream) {} + + /// Copy is disallowed + StreamGuard(const StreamGuard&) = delete; + StreamGuard& operator=(const StreamGuard&) = delete; + + /// Move is disallowed, as StreamGuard does not have an uninitialized state, + /// which is required for moves on types with nontrivial destructors. + StreamGuard(StreamGuard&& other) = delete; + StreamGuard& operator=(StreamGuard&& other) = delete; + + /// Resets the currently set stream to the original stream and + /// the currently set device to the original device. Then, + /// set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream. + /// + /// NOTE: this implementation may skip some stream/device setting if + /// it can prove that it is unnecessary. + /// + /// WARNING: reset_stream does NOT preserve previously set streams on + /// different devices. If you need to set streams on multiple devices + /// on , use MultiStreamGuard instead. + void reset_stream(Stream stream) { + guard_.reset_stream(stream); + } + + /// Returns the stream that was set at the time the guard was constructed. + Stream original_stream() const { + return guard_.original_stream(); + } + + /// Returns the most recent stream that was set using this device guard, + /// either from construction, or via set_stream. + Stream current_stream() const { + return guard_.current_stream(); + } + + /// Returns the most recent device that was set using this device guard, + /// either from construction, or via set_device/reset_device/set_index. + Device current_device() const { + return guard_.current_device(); + } + + /// Returns the device that was set at the most recent reset_stream(), + /// or otherwise the device at construction time. + Device original_device() const { + return guard_.original_device(); + } + + private: + c10::impl::InlineStreamGuard guard_; +}; + +/** + * An OptionalStreamGuard is an RAII class that sets a device to some value on + * initialization, and resets the device to its original value on destruction. + * See OptionalDeviceGuard for more guidance on how to use this class. + */ +struct OptionalStreamGuard { + /// Create an uninitialized guard. + explicit OptionalStreamGuard() = default; + + /// Set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream. + explicit OptionalStreamGuard(Stream stream) : guard_(stream) {} + + /// Set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream, + /// if the passed stream is not nullopt. + explicit OptionalStreamGuard(std::optional stream_opt) + : guard_(stream_opt) {} + + /// Copy is disallowed + OptionalStreamGuard(const OptionalStreamGuard&) = delete; + OptionalStreamGuard& operator=(const OptionalStreamGuard&) = delete; + + // See Note [Move construction for RAII guards is tricky] + OptionalStreamGuard(OptionalStreamGuard&& other) = delete; + + // See Note [Move assignment for RAII guards is tricky] + OptionalStreamGuard& operator=(OptionalStreamGuard&& other) = delete; + ~OptionalStreamGuard() = default; + + /// Resets the currently set stream to the original stream and + /// the currently set device to the original device. Then, + /// set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream. + /// Initializes the guard if it was not previously initialized. + void reset_stream(Stream stream) { + guard_.reset_stream(stream); + } + + /// Returns the stream that was set at the time the guard was most recently + /// initialized, or nullopt if the guard is uninitialized. + std::optional original_stream() const { + return guard_.original_stream(); + } + + /// Returns the most recent stream that was set using this stream guard, + /// either from construction, or via reset_stream, if the guard is + /// initialized, or nullopt if the guard is uninitialized. + std::optional current_stream() const { + return guard_.current_stream(); + } + + /// Restore the original device and stream, resetting this guard to + /// uninitialized state. + void reset() { + guard_.reset(); + } + + private: + c10::impl::InlineOptionalStreamGuard guard_; +}; + +/** + * A MultiStreamGuard is an RAII class that sets the current streams of a set of + * devices all at once, and resets them to their original values on destruction. + */ +struct MultiStreamGuard { + /// Set the current streams to the passed streams on each of their respective + /// devices. + explicit MultiStreamGuard(ArrayRef streams) : guard_(streams) {} + + /// Copy is disallowed + MultiStreamGuard(const MultiStreamGuard&) = delete; + MultiStreamGuard& operator=(const MultiStreamGuard&) = delete; + + // See Note [Move construction for RAII guards is tricky] + MultiStreamGuard(MultiStreamGuard&& other) = delete; + + // See Note [Move assignment for RAII guards is tricky] + MultiStreamGuard& operator=(MultiStreamGuard&& other) = delete; + ~MultiStreamGuard() = default; + + private: + c10::impl::InlineMultiStreamGuard guard_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymBool.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymBool.h new file mode 100644 index 0000000000000000000000000000000000000000..d12fa75fb41446f3f9967a73aed8a25fc1a60f4b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymBool.h @@ -0,0 +1,184 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +class SymInt; + +class C10_API SymBool { + public: + /*implicit*/ SymBool(bool b) : data_(b) {} + SymBool(SymNode ptr) : data_(false), ptr_(std::move(ptr)) { + TORCH_CHECK(ptr_->is_bool()); + } + SymBool() : data_(false) {} + + SymNodeImpl* toSymNodeImplUnowned() const { + return ptr_.get(); + } + + SymNodeImpl* release() && { + return std::move(ptr_).release(); + } + + // Only valid if is_heap_allocated() + SymNode toSymNodeImpl() const; + + // Guaranteed to return a SymNode, wrapping using base if necessary + SymNode wrap_node(const SymNode& base) const; + + bool expect_bool() const { + std::optional c = maybe_as_bool(); + TORCH_CHECK(c.has_value()); + return *c; + } + + SymBool sym_and(const SymBool& /*sci*/) const; + SymBool sym_or(const SymBool& /*sci*/) const; + SymBool sym_not() const; + + SymBool operator&(const SymBool& other) const { + return sym_and(other); + } + SymBool operator|(const SymBool& other) const { + return sym_or(other); + } + SymBool operator||(const SymBool& other) const { + return sym_or(other); + } + SymBool operator~() const { + return sym_not(); + } + + // Insert a guard for the bool to be its concrete value, and then return + // that value. Note that C++ comparison operations default to returning + // bool, so it's not so common to have to call this + bool guard_bool(const char* file, int64_t line) const; + bool expect_true(const char* file, int64_t line) const; + bool guard_size_oblivious(const char* file, int64_t line) const; + bool statically_known_true(const char* file, int64_t line) const; + bool guard_or_false(const char* file, int64_t line) const; + bool guard_or_true(const char* file, int64_t line) const; + + bool has_hint() const; + + bool as_bool_unchecked() const { + return data_; + } + + std::optional maybe_as_bool() const { + if (!is_heap_allocated()) { + return data_; + } + return toSymNodeImplUnowned()->constant_bool(); + } + + // Convert SymBool to SymInt (0 or 1) + // This is the C++ equivalent of Python's cast_symbool_to_symint_guardless + SymInt toSymInt() const; + + bool is_heap_allocated() const { + return ptr_; + } + + private: + // TODO: optimize to union + bool data_; + SymNode ptr_; +}; + +C10_API std::ostream& operator<<(std::ostream& os, const SymBool& s); + +#define TORCH_SYM_CHECK(cond, ...) \ + TORCH_CHECK((cond).expect_true(__FILE__, __LINE__), __VA_ARGS__) +#define TORCH_SYM_INTERNAL_ASSERT(cond, ...) \ + TORCH_INTERNAL_ASSERT((cond).expect_true(__FILE__, __LINE__), __VA_ARGS__) +#define TORCH_MAYBE_SYM_CHECK(cond, ...) \ + if constexpr (std::is_same_v, SymBool>) { \ + TORCH_CHECK((cond).expect_true(__FILE__, __LINE__), __VA_ARGS__) \ + } else { \ + TORCH_CHECK((cond), __VA_ARGS__) \ + } + +inline bool guard_size_oblivious( + bool b, + const char* file [[maybe_unused]], + int64_t line [[maybe_unused]]) { + return b; +} + +inline bool guard_size_oblivious( + const c10::SymBool& b, + const char* file, + int64_t line) { + return b.guard_size_oblivious(file, line); +} + +inline bool guard_or_false( + bool b, + const char* file [[maybe_unused]], + int64_t line [[maybe_unused]]) { + return b; +} + +inline bool guard_or_false( + const c10::SymBool& b, + const char* file, + int64_t line) { + return b.guard_or_false(file, line); +} + +inline bool statically_known_true( + bool b, + const char* file [[maybe_unused]], + int64_t line [[maybe_unused]]) { + return b; +} + +inline bool statically_known_true( + const c10::SymBool& b, + const char* file, + int64_t line) { + return b.statically_known_true(file, line); +} + +inline bool guard_or_true( + bool b, + const char* file [[maybe_unused]], + int64_t line [[maybe_unused]]) { + return b; +} + +inline bool guard_or_true( + const c10::SymBool& b, + const char* file, + int64_t line) { + return b.guard_or_true(file, line); +} + +#define TORCH_GUARD_SIZE_OBLIVIOUS(cond) \ + c10::guard_size_oblivious((cond), __FILE__, __LINE__) + +#define TORCH_STATICALLY_KNOWN_TRUE(cond) \ + c10::statically_known_true((cond), __FILE__, __LINE__) + +#define TORCH_GUARD_OR_FALSE(cond) \ + c10::guard_or_false((cond), __FILE__, __LINE__) + +#define TORCH_GUARD_OR_TRUE(cond) c10::guard_or_true((cond), __FILE__, __LINE__) + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymFloat.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymFloat.h new file mode 100644 index 0000000000000000000000000000000000000000..332726ba4c5dade5accef6a3dac6076366c04d95 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymFloat.h @@ -0,0 +1,123 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace c10 { + +// NB: this is actually double precision; we're using the Python naming here +class C10_API SymFloat { + public: + /*implicit*/ SymFloat(double d) : data_(d) {} + SymFloat(SymNode ptr) + : data_(std::numeric_limits::quiet_NaN()), ptr_(std::move(ptr)) { + TORCH_CHECK(ptr_->is_float()); + } + SymFloat() : data_(0.0) {} + + SymNodeImpl* toSymNodeImplUnowned() const { + return ptr_.get(); + } + + SymNodeImpl* release() && { + return std::move(ptr_).release(); + } + + // Only valid if is_symbolic() + SymNode toSymNodeImpl() const; + + // Guaranteed to return a SymNode, wrapping using base if necessary + SymNode wrap_node(const SymNode& base) const; + + double expect_float() const { + TORCH_CHECK(!is_symbolic()); + return data_; + } + + SymFloat operator+(const SymFloat& /*sci*/) const; + SymFloat operator-(const SymFloat& /*sci*/) const; + SymFloat operator*(const SymFloat& /*sci*/) const; + SymFloat operator/(const SymFloat& /*sci*/) const; + + SymBool sym_eq(const SymFloat& /*sci*/) const; + SymBool sym_ne(const SymFloat& /*sci*/) const; + SymBool sym_lt(const SymFloat& /*sci*/) const; + SymBool sym_le(const SymFloat& /*sci*/) const; + SymBool sym_gt(const SymFloat& /*sci*/) const; + SymBool sym_ge(const SymFloat& /*sci*/) const; + + bool operator==(const SymFloat& o) const { + return sym_eq(o).guard_bool(__FILE__, __LINE__); + } + bool operator!=(const SymFloat& o) const { + return sym_ne(o).guard_bool(__FILE__, __LINE__); + } + bool operator<(const SymFloat& o) const { + return sym_lt(o).guard_bool(__FILE__, __LINE__); + } + bool operator<=(const SymFloat& o) const { + return sym_le(o).guard_bool(__FILE__, __LINE__); + } + bool operator>(const SymFloat& o) const { + return sym_gt(o).guard_bool(__FILE__, __LINE__); + } + bool operator>=(const SymFloat& o) const { + return sym_ge(o).guard_bool(__FILE__, __LINE__); + } + + SymFloat min(const SymFloat& sci) const; + SymFloat max(const SymFloat& sci) const; + + // Need guidance on where to put this code + SymFloat sqrt() const; + + // Insert a guard for the float to be its concrete value, and then return + // that value. This operation always works, even if the float is symbolic, + // so long as we know what the underlying value is. Don't blindly put this + // everywhere; you can cause overspecialization of PyTorch programs with + // this method. + // + // It should be called as guard_float(__FILE__, __LINE__). The file and line + // number can be used to diagnose overspecialization. + double guard_float(const char* file, int64_t line) const; + + bool has_hint() const; + + // N.B. It's important to keep this definition in the header + // as we expect if checks to be folded for mobile builds + // where `is_symbolic` is always false + C10_ALWAYS_INLINE bool is_symbolic() const { + return ptr_; + } + + // UNSAFELY coerce this SymFloat into a double. You MUST have + // established that this is a non-symbolic by some other means, + // typically by having tested is_symbolic(). You will get garbage + // from this function if is_symbolic() + double as_float_unchecked() const { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(!is_symbolic()); + return data_; + } + + private: + // TODO: optimize to union + double data_; + SymNode ptr_; +}; + +C10_API std::ostream& operator<<(std::ostream& os, const SymFloat& s); +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymInt.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymInt.h new file mode 100644 index 0000000000000000000000000000000000000000..706470cd3872b24b04ec8d2e3e7702ae7552aced --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymInt.h @@ -0,0 +1,582 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +class SymFloat; + +// SymInt represents either a regular int64_t, or a symbolic integer +// (represented in a type erased way as SymNode). The intention is for SymInt +// to represent symbolic sizes that arise when doing shape computation in +// operator kernels. This allows for tracing through programs without baking in +// concrete sizes into kernel calls. +// +// SymInt has an API equivalent to int64_t. In particular, it is a value type. +// Internally, SymInt is represented in a clever packed way, so that it only +// occupies one word of space; but morally, it is a union between an int64_t +// and an intrusive pointer to SymNodeImpl. +// +// Invariant: the referenced SymNodeImpl is guaranteed to be a SymNode where +// is_int() returns true + +class C10_API SymInt { + public: + enum Unchecked { + UNCHECKED, + }; + + /*implicit*/ SymInt(int64_t d) : data_(d) { + if (is_heap_allocated()) { + // Large negative number, heap allocate it + promote_to_negative(); + } + } + SymInt() : data_(0) {} + SymInt(SymNode n); + + // unchecked c-tor accepting raw `data_` + // One appropriate use for this is when you are constructing a symint + // in a situation where you know it is non-negative (or, if it is negative, + // the negative value is -1; i.e., not user controlled) + SymInt(Unchecked /*unused*/, int64_t d) : data_(d) {} + + SymInt(const SymInt& s) : data_(s.data_) { + if (s.is_heap_allocated()) { + c10::raw::intrusive_ptr::incref(s.toSymNodeImplUnowned()); + } + } + SymInt(SymInt&& s) noexcept : data_(s.data_) { + s.data_ = 0; + } + + SymInt& operator=(const SymInt& s) { + if (this != &s) { + release_(); + data_ = s.data_; + if (s.is_heap_allocated()) { + c10::raw::intrusive_ptr::incref(s.toSymNodeImplUnowned()); + } + } + return *this; + } + SymInt& operator=(SymInt&& s) noexcept { + if (this != &s) { + release_(); // release the current SymNode if any + data_ = s.data_; + if (s.is_heap_allocated()) + s.data_ = 0; + }; + return *this; + } + + SymNodeImpl* toSymNodeImplUnowned() const { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(is_heap_allocated()); + uint64_t unextended_bits = static_cast(data_) & ~MASK; + uint64_t sign_bit_mask = 1ULL << (62 - 1); + // https://stackoverflow.com/questions/42534749/signed-extension-from-24-bit-to-32-bit-in-c + uint64_t extended_bits = (unextended_bits ^ sign_bit_mask) - sign_bit_mask; + return static_cast( + // NOLINTNEXTLINE(performance-no-int-to-ptr, bugprone*) + reinterpret_cast(static_cast(extended_bits))); + } + + void release_() { + if (is_heap_allocated()) { + SymNode::reclaim(toSymNodeImplUnowned()); // steal + } + } + + SymNodeImpl* release() && { +#ifndef C10_MOBILE + TORCH_INTERNAL_ASSERT(is_heap_allocated()); + auto* r = toSymNodeImplUnowned(); + data_ = 0; // transfer ownership + return r; +#else + TORCH_INTERNAL_ASSERT(false); +#endif + } + + // Only valid if is_heap_allocated() + SymNode toSymNode() const; + + // Guaranteed to return a SymNode, wrapping using base if necessary + SymNode wrap_node(const SymNode& base) const; + + ~SymInt() { + release_(); + } + + // Require the int to be non-symbolic, and if it is symbolic raise an + // error. This is safe to use for C++ code that doesn't work for symbolic + // shapes, and you don't have time to fix it immediately, as if we + // try to trigger the path in C++ you'll appropriately get an error + int64_t expect_int() const { + if (auto r = maybe_as_int()) { + return *r; + } + TORCH_CHECK_ALWAYS_SHOW_CPP_STACKTRACE( + false, "when unpacking SymInt, expected int but got ", *this); + } + + // Test if we have a hint for this int (e.g., guard_int would work). + // Most of the time this is true; it is only false when you have + // an unbacked SymInt. + bool has_hint() const; + + // Insert a guard for the int to be its concrete value, and then return + // that value. This operation always works, even if the int is symbolic, + // so long as we know what the underlying value is (e.g., this won't work + // if you call it on the size of nonzero output). Don't blindly put this + // everywhere; you can cause overspecialization of PyTorch programs with + // this method. + // + // It should be called as guard_int(__FILE__, __LINE__). The file and line + // number can be used to diagnose overspecialization. + int64_t guard_int(const char* file, int64_t line) const; + + // Distinguish actual symbolic values from constants stored on the heap + bool is_symbolic() const { + return is_heap_allocated() && + !toSymNodeImplUnowned()->constant_int().has_value(); + } + + // N.B. It's important to keep this definition in the header + // as we expect if checks to be folded for mobile builds + // where `is_heap_allocated` is always false and optimize dead code paths + C10_ALWAYS_INLINE bool is_heap_allocated() const { +#ifdef C10_MOBILE + return false; +#else + return !check_range(data_); +#endif + } + + SymInt operator+(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymInt(*ma + *mb); + } + } + return operator_add_slow_path(sci); + } + + SymInt operator-(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymInt(*ma - *mb); + } + } + return operator_sub_slow_path(sci); + } + + SymInt operator*(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymInt(*ma * *mb); + } + } + return operator_mul_slow_path(sci); + } + + SymInt operator/(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymInt(*ma / *mb); + } + } + return operator_div_slow_path(sci); + } + + SymInt operator%(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymInt(*ma % *mb); + } + } + return operator_mod_slow_path(sci); + } + + void operator*=(const SymInt& sci) { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + *this = SymInt(*ma * *mb); + return; + } + } + operator_imul_slow_path(sci); + } + + void operator+=(const SymInt& sci) { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + *this = SymInt(*ma + *mb); + return; + } + } + operator_iadd_slow_path(sci); + } + + void operator/=(const SymInt& sci) { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + *this = SymInt(*ma / *mb); + return; + } + } + operator_idiv_slow_path(sci); + } + + SymInt clone() const; + + SymBool sym_eq(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymBool(*ma == *mb); + } + } + return sym_eq_slow_path(sci); + } + + SymBool sym_ne(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymBool(*ma != *mb); + } + } + return sym_ne_slow_path(sci); + } + + SymBool sym_lt(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymBool(*ma < *mb); + } + } + return sym_lt_slow_path(sci); + } + + SymBool sym_le(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymBool(*ma <= *mb); + } + } + return sym_le_slow_path(sci); + } + + SymBool sym_gt(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymBool(*ma > *mb); + } + } + return sym_gt_slow_path(sci); + } + + SymBool sym_ge(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymBool(*ma >= *mb); + } + } + return sym_ge_slow_path(sci); + } + + bool operator==(const SymInt& o) const { + return sym_eq(o).guard_bool(__FILE__, __LINE__); + } + bool operator!=(const SymInt& o) const { + return sym_ne(o).guard_bool(__FILE__, __LINE__); + } + bool operator<(const SymInt& o) const { + return sym_lt(o).guard_bool(__FILE__, __LINE__); + } + bool operator<=(const SymInt& o) const { + return sym_le(o).guard_bool(__FILE__, __LINE__); + } + bool operator>(const SymInt& o) const { + return sym_gt(o).guard_bool(__FILE__, __LINE__); + } + bool operator>=(const SymInt& o) const { + return sym_ge(o).guard_bool(__FILE__, __LINE__); + } + + SymInt min(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymInt(std::min(*ma, *mb)); + } + } + return min_slow_path(sci); + } + + SymInt max(const SymInt& sci) const { + if (auto ma = maybe_as_int()) { + if (auto mb = sci.maybe_as_int()) { + return SymInt(std::max(*ma, *mb)); + } + } + return max_slow_path(sci); + } + + // If both are symbolic, this checks if + // they share the same node. + // If both are not symbolic this just checks normal equality. + bool is_same(const SymInt& other) const; + + operator SymFloat() const; + + void unsafe_set_data(size_t nbytes) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(!is_heap_allocated()); + data_ = static_cast(nbytes); + } + + // Don't use this. Prefer maybe_as_int instead + int64_t as_int_unchecked() const { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(!is_heap_allocated()); + return data_; + } + + std::optional maybe_as_int() const { + if (!is_heap_allocated()) { + return data_; + } + return maybe_as_int_slow_path(); + } + + // Return whether the integer is directly coercible to a SymInt + // without requiring heap allocation. You don't need to use this + // to check if you can pass an integer to SymInt; this is guaranteed + // to work (it just might heap allocate!) + static bool check_range(int64_t i) { + return i > MAX_UNREPRESENTABLE_INT; + } + + // Return the min representable integer as a SymInt without + // heap allocation. For quantities that count bytes (or larger), + // this is still much larger than you need, so you may consider + // using this as a more efficient version of MIN_INT + static constexpr int64_t min_representable_int() { + return MAX_UNREPRESENTABLE_INT + 1; + } + + private: + void promote_to_negative(); + SymInt operator_add_slow_path(const SymInt& sci) const; + SymInt operator_sub_slow_path(const SymInt& sci) const; + SymInt operator_mul_slow_path(const SymInt& sci) const; + SymInt operator_div_slow_path(const SymInt& sci) const; + SymInt operator_mod_slow_path(const SymInt& sci) const; + void operator_imul_slow_path(const SymInt& sci); + void operator_iadd_slow_path(const SymInt& sci); + void operator_idiv_slow_path(const SymInt& sci); + SymBool sym_eq_slow_path(const SymInt& sci) const; + SymBool sym_ne_slow_path(const SymInt& sci) const; + SymBool sym_lt_slow_path(const SymInt& sci) const; + SymBool sym_le_slow_path(const SymInt& sci) const; + SymBool sym_gt_slow_path(const SymInt& sci) const; + SymBool sym_ge_slow_path(const SymInt& sci) const; + + SymInt min_slow_path(const SymInt& sci) const; + SymInt max_slow_path(const SymInt& sci) const; + + std::optional maybe_as_int_slow_path() const; + + // Constraints on the internal representation: + // + // - Should represent positive and small negative ints + // - No conversion necessary for operations on ints + // - Must represent valid 64-bit pointers + // - Is symbolic test should be FAST (two arithmetic instructions is too + // much). + // This code being a hotpath is based on Strobelight profiles of + // is_heap_allocated(). FB only: https://fburl.com/strobelight/5l50ncxd + // (you will need to change the time window). + // + // So, the scheme is to reserve large negative numbers (assuming + // two's complement): + // + // - 0b0.... means we are a positive int + // - 0b11... means we are a small negative int + // - 0b10... means we are are a pointer. This means that + // [-2^63, -2^62-1] are not representable as ints. + // We don't actually need all of this space as on x86_64 + // as the top 16bits aren't used for anything + static constexpr uint64_t MASK = 1ULL << 63 | 1ULL << 62 | 1ULL << 61; + static constexpr uint64_t IS_SYM = 1ULL << 63 | 1ULL << 61; + // We must manually translate the bit pattern test into a greater + // than test because compiler doesn't figure it out: + // https://godbolt.org/z/356aferaW + static constexpr int64_t MAX_UNREPRESENTABLE_INT = + -1LL & static_cast(~(1ULL << 62)); + int64_t data_; +}; + +/// Sum of a list of SymInt; accumulates into the c10::SymInt expression +template < + typename C, + typename std::enable_if_t< + std::is_same_v, + int> = 0> +inline c10::SymInt multiply_integers(const C& container) { + return std::accumulate( + container.begin(), + container.end(), + c10::SymInt(1), + [](const c10::SymInt& a, const c10::SymInt& b) { return a * b; }); +} + +template < + typename Iter, + typename = std::enable_if_t::value_type, + c10::SymInt>>> +inline c10::SymInt multiply_integers(Iter begin, Iter end) { + return std::accumulate( + begin, + end, + c10::SymInt(1), + [](const c10::SymInt& a, const c10::SymInt& b) { return a * b; }); +} + +#define DECLARE_SYMINT_OP_INTONLY(scalar_t, RetTy) \ + C10_API RetTy operator%(const SymInt& a, scalar_t b); \ + C10_API RetTy operator%(scalar_t a, const SymInt& b); + +#define DECLARE_SYMINT_OP(scalar_t, RetTy) \ + C10_API RetTy operator+(const SymInt& a, scalar_t b); \ + C10_API RetTy operator-(const SymInt& a, scalar_t b); \ + C10_API RetTy operator*(const SymInt& a, scalar_t b); \ + C10_API RetTy operator/(const SymInt& a, scalar_t b); \ + C10_API RetTy operator+(scalar_t a, const SymInt& b); \ + C10_API RetTy operator-(scalar_t a, const SymInt& b); \ + C10_API RetTy operator*(scalar_t a, const SymInt& b); \ + C10_API RetTy operator/(scalar_t a, const SymInt& b); \ + C10_API bool operator==(const SymInt& a, scalar_t b); \ + C10_API bool operator!=(const SymInt& a, scalar_t b); \ + C10_API bool operator<(const SymInt& a, scalar_t b); \ + C10_API bool operator<=(const SymInt& a, scalar_t b); \ + C10_API bool operator>(const SymInt& a, scalar_t b); \ + C10_API bool operator>=(const SymInt& a, scalar_t b); \ + C10_API bool operator==(scalar_t a, const SymInt& b); \ + C10_API bool operator!=(scalar_t a, const SymInt& b); \ + C10_API bool operator<(scalar_t a, const SymInt& b); \ + C10_API bool operator<=(scalar_t a, const SymInt& b); \ + C10_API bool operator>(scalar_t a, const SymInt& b); \ + C10_API bool operator>=(scalar_t a, const SymInt& b); + +DECLARE_SYMINT_OP_INTONLY(int64_t, SymInt) +DECLARE_SYMINT_OP_INTONLY(int32_t, SymInt) +DECLARE_SYMINT_OP_INTONLY(uint64_t, SymInt) +DECLARE_SYMINT_OP_INTONLY(uint32_t, SymInt) +DECLARE_SYMINT_OP(int64_t, SymInt) +DECLARE_SYMINT_OP(int32_t, SymInt) // make sure constants work +DECLARE_SYMINT_OP(uint64_t, SymInt) +DECLARE_SYMINT_OP(uint32_t, SymInt) +DECLARE_SYMINT_OP(double, SymFloat) +DECLARE_SYMINT_OP(float, SymFloat) // just for completeness + +// On OSX size_t is different than uint64_t so we have to +// define it separately +#if defined(__APPLE__) +DECLARE_SYMINT_OP_INTONLY(size_t, SymInt) +DECLARE_SYMINT_OP(size_t, SymInt) +#endif + +#undef DECLARE_SYMINT_OP + +C10_API std::ostream& operator<<(std::ostream& os, const SymInt& s); +C10_API SymInt operator-(const SymInt& s); + +inline bool sym_eq(int64_t a, int64_t b) { + return a == b; +} + +inline SymBool sym_eq(const SymInt& a, const SymInt& b) { + return a.sym_eq(b); +} + +inline bool sym_ne(int64_t a, int64_t b) { + return a != b; +} + +inline SymBool sym_ne(const SymInt& a, const SymInt& b) { + return a.sym_ne(b); +} + +inline bool sym_lt(int64_t a, int64_t b) { + return a < b; +} + +inline SymBool sym_lt(const SymInt& a, const SymInt& b) { + return a.sym_lt(b); +} + +inline bool sym_le(int64_t a, int64_t b) { + return a <= b; +} + +inline SymBool sym_le(const SymInt& a, const SymInt& b) { + return a.sym_le(b); +} + +inline bool sym_gt(int64_t a, int64_t b) { + return a > b; +} + +inline SymBool sym_gt(const SymInt& a, const SymInt& b) { + return a.sym_gt(b); +} + +inline bool sym_ge(int64_t a, int64_t b) { + return a >= b; +} + +inline SymBool sym_ge(const SymInt& a, const SymInt& b) { + return a.sym_ge(b); +} + +} // namespace c10 + +#include + +namespace std { + +template <> +class numeric_limits { + public: + static constexpr bool is_specialized = true; + + static constexpr int64_t max() noexcept { + return std::numeric_limits::max(); + } + + static constexpr int64_t min() noexcept { + return std::numeric_limits::min(); + } + + static constexpr bool is_signed = true; + static constexpr bool is_integer = true; +}; + +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymIntArrayRef.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymIntArrayRef.h new file mode 100644 index 0000000000000000000000000000000000000000..b63753b186937f0e6869ee557ca1528bb2d7e340 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymIntArrayRef.h @@ -0,0 +1,113 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { +using SymIntArrayRef = ArrayRef; + +inline at::IntArrayRef asIntArrayRefUnchecked(c10::SymIntArrayRef ar) { + return IntArrayRef(reinterpret_cast(ar.data()), ar.size()); +} + +// TODO: a SymIntArrayRef containing a heap allocated large negative integer +// can actually technically be converted to an IntArrayRef... but not with +// the non-owning API we have here. We can't reinterpet cast; we have to +// allocate another buffer and write the integers into it. If you need it, +// we can do it. But I don't think you need it. + +inline std::optional asIntArrayRefSlowOpt( + c10::SymIntArrayRef ar) { + for (const c10::SymInt& sci : ar) { + if (sci.is_heap_allocated()) { + return std::nullopt; + } + } + + return {asIntArrayRefUnchecked(ar)}; +} + +inline at::IntArrayRef asIntArrayRefSlow( + c10::SymIntArrayRef ar, + const char* file, + int64_t line) { + for (const c10::SymInt& sci : ar) { + TORCH_CHECK( + !sci.is_heap_allocated(), + file, + ":", + line, + ": SymIntArrayRef expected to contain only concrete integers"); + } + return asIntArrayRefUnchecked(ar); +} + +// Even slower than asIntArrayRefSlow, as it forces an allocation for a +// destination int, BUT it is able to force specialization (it never errors) +inline c10::DimVector asIntArrayRefSlowAlloc( + c10::SymIntArrayRef ar, + const char* file, + int64_t line) { + c10::DimVector res(ar.size(), 0); + for (const auto i : c10::irange(ar.size())) { + res[i] = ar[i].guard_int(file, line); + } + return res; +} + +#define C10_AS_INTARRAYREF_SLOW(a) c10::asIntArrayRefSlow(a, __FILE__, __LINE__) +#define C10_AS_INTARRAYREF_SLOW_ALLOC(a) \ + c10::asIntArrayRefSlowAlloc(a, __FILE__, __LINE__) + +// Prefer using a more semantic constructor, like +// fromIntArrayRefKnownNonNegative +inline SymIntArrayRef fromIntArrayRefUnchecked(IntArrayRef array_ref) { + return SymIntArrayRef( + reinterpret_cast(array_ref.data()), array_ref.size()); +} + +inline SymIntArrayRef fromIntArrayRefKnownNonNegative(IntArrayRef array_ref) { + return fromIntArrayRefUnchecked(array_ref); +} + +inline SymIntArrayRef fromIntArrayRefSlow(IntArrayRef array_ref) { + for (long i : array_ref) { + TORCH_CHECK( + SymInt::check_range(i), + "IntArrayRef contains an int that cannot be represented as a SymInt: ", + i); + } + return SymIntArrayRef( + reinterpret_cast(array_ref.data()), array_ref.size()); +} + +inline c10::SymBool sym_equals(SymIntArrayRef LHS, SymIntArrayRef RHS) { + if (LHS.size() != RHS.size()) { + return c10::SymBool(false); + } + + c10::SymBool result = sym_eq(LHS.size(), RHS.size()); + for (size_t i = 0; i < RHS.size(); ++i) { + c10::SymBool equals = sym_eq(LHS[i], RHS[i]); + std::optional equals_bool = equals.maybe_as_bool(); + + if (equals_bool.has_value() && !*equals_bool) { + // Early return if element comparison is known to be false + return equals; + } + result = result.sym_and(equals); + } + return result; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymNodeImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymNodeImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..a4257684ea150ac4f8f1bda39ab4c1212c1929ed --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymNodeImpl.h @@ -0,0 +1,261 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wunused-parameter") + +namespace c10 { + +class SymNodeImpl; +using SymNode = c10::intrusive_ptr; + +// When you add a method, you also need to edit +// torch/csrc/jit/python/init.cpp +// torch/csrc/utils/python_symnode.h +// c10/core/ConstantSymNodeImpl.h +class C10_API SymNodeImpl : public c10::intrusive_ptr_target { + public: + ~SymNodeImpl() override = default; + + template + c10::intrusive_ptr dyn_cast() const { + return c10::intrusive_ptr::reclaim_copy(dynamic_cast(this)); + } + + // these could be pure virtual when we implement LTC versions + virtual bool is_int() { + TORCH_CHECK(false, "NYI"); + } + virtual bool is_bool() { + TORCH_CHECK(false, "NYI"); + } + virtual bool is_float() { + TORCH_CHECK(false, "NYI"); + } + virtual bool is_nested_int() const { + return false; + } + virtual SymNode add(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode sub(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode mul(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + // NB: legacy, prefer float_truediv or int_truediv + virtual SymNode truediv(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode float_truediv(const SymNode& other) { + return truediv(other); + } + virtual SymNode int_truediv(const SymNode& other) { + return truediv(other); + } + // NB: legacy, prefer float_pow or pow_by_natural + virtual SymNode pow(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode float_pow(const SymNode& other) { + return pow(other); + } + virtual SymNode pow_by_natural(const SymNode& other) { + return pow(other); + } + // NB: legacy, prefer int_floordiv + virtual SymNode floordiv(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode int_floordiv(const SymNode& other) { + return floordiv(other); + } + virtual SymNode mod(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode eq(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode ne(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode gt(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode lt(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode le(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode ge(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode ceil() { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode floor() { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode neg() { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode sym_min(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode sym_max(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode sym_or(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode sym_and(const SymNode& other) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode sym_not() { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode sym_ite(const SymNode& then_val, const SymNode& else_val) { + TORCH_CHECK(false, "NYI"); + } + // NB: self is ignored here, only the arguments are used + virtual SymNode is_contiguous( + ArrayRef sizes, + ArrayRef strides) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode is_channels_last_contiguous_2d( + ArrayRef sizes, + ArrayRef strides) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode is_channels_last_contiguous_3d( + ArrayRef sizes, + ArrayRef strides) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode is_channels_last_strides_2d( + ArrayRef sizes, + ArrayRef strides) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode is_channels_last_strides_3d( + ArrayRef sizes, + ArrayRef strides) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode is_non_overlapping_and_dense( + ArrayRef sizes, + ArrayRef strides) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode clone() { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode sym_float() { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode wrap_int(int64_t num) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode wrap_float(double num) { + TORCH_CHECK(false, "NYI"); + } + virtual SymNode wrap_bool(bool num) { + TORCH_CHECK(false, "NYI"); + } + virtual int64_t guard_int(const char* file, int64_t line) { + TORCH_CHECK(false, "NYI"); + } + virtual bool guard_bool(const char* file, int64_t line) { + TORCH_CHECK(false, "NYI"); + } + virtual double guard_float(const char* file, int64_t line) { + TORCH_CHECK(false, "NYI"); + } + virtual bool guard_size_oblivious(const char* file, int64_t line) { + // No improvement for unbacked SymBools by default, replace this + // with a better implementation! + return guard_bool(file, line); + } + virtual bool guard_or_false(const char* file, int64_t line) { + // Note: PT2 primarily uses PythonSymNodeImpl for this functionality. + // XLA is currently the main consumer of this fallback path since it uses + // ahead-of-time compilation and cannot depend on Python runtime. + return guard_bool(file, line); + } + virtual bool statically_known_true(const char* file, int64_t line) { + // Note: PT2 primarily uses PythonSymNodeImpl for this functionality. + // XLA is currently the main consumer of this fallback path since it uses + // ahead-of-time compilation and cannot depend on Python runtime. + return guard_bool(file, line); + } + virtual bool guard_or_true(const char* file, int64_t line) { + // Note: PT2 primarily uses PythonSymNodeImpl for this functionality. + // XLA is currently the main consumer of this fallback path since it uses + // ahead-of-time compilation and cannot depend on Python runtime. + return guard_bool(file, line); + } + virtual bool expect_true(const char* file, int64_t line) { + // No improvement for unbacked SymBools by default, replace this + // with a better implementation! + return guard_bool(file, line); + } + virtual int64_t int_() { + TORCH_CHECK(false, "NYI"); + } + virtual bool bool_() { + TORCH_CHECK(false, "NYI"); + } + virtual bool has_hint() { + TORCH_CHECK(false, "NYI"); + } + virtual std::string str() { + TORCH_CHECK(false, "NYI"); + } + virtual std::string _graph_repr() { + return str(); + } + virtual std::optional nested_int() { + return std::nullopt; + } + virtual std::optional nested_int_coeff() { + return std::nullopt; + } + virtual std::optional constant_int() { + return std::nullopt; + } + virtual std::optional constant_bool() { + return std::nullopt; + } + virtual std::optional maybe_as_int() { + return std::nullopt; + } + virtual bool is_constant() { + return false; + } + virtual bool is_symbolic() { + return true; + } + std::ostream& operator<<(std::ostream& os) { + os << str(); + return os; + } +}; + +} // namespace c10 +C10_DIAGNOSTIC_POP() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymbolicShapeMeta.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymbolicShapeMeta.h new file mode 100644 index 0000000000000000000000000000000000000000..fa048561a771fd8070ba1e3940740b474d48f762 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/SymbolicShapeMeta.h @@ -0,0 +1,234 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace c10 { + +class C10_API SymbolicShapeMeta { + public: + // Basic metadata from which other quantities are derived + SymDimVector sizes_ = {0}; + SymDimVector strides_ = {1}; + SymInt storage_offset_ = 0; + + bool strides_valid_ = true; // e.g. for sparse where there are no strides + + SymbolicShapeMeta() = default; + ~SymbolicShapeMeta() = default; + SymbolicShapeMeta(const SymbolicShapeMeta& other); + SymbolicShapeMeta(SymbolicShapeMeta&& other) = delete; + SymbolicShapeMeta& operator=(const SymbolicShapeMeta& other) = delete; + SymbolicShapeMeta& operator=(SymbolicShapeMeta&& other) = delete; + + void refresh_numel() { + // Non-const, don't need to hold mutables_ lock + available_.fetch_and(~numel_avail); + numel_ = 1; + } + + void refresh_contiguous() { + // Non-const, don't need to hold mutables_ lock + available_.fetch_and(numel_avail); + is_contiguous_ = false; + is_channels_last_contiguous_ = false; + is_channels_last_3d_contiguous_ = false; + is_channels_last_ = false; + is_channels_last_3d_ = false; + is_non_overlapping_and_dense_ = false; + } + + int64_t dim() const { + return static_cast(sizes_.size()); + } + + // Accessors for derived quantities, computed lazily on first access + + bool has_numel() const { + return available_.load() & numel_avail; + } + bool has_is_contiguous() const { + return available_.load() & is_contiguous_avail; + } + bool has_is_channels_last_contiguous() const { + return available_.load() & is_channels_last_contiguous_avail; + } + bool has_is_channels_last_3d_contiguous() const { + return available_.load() & is_channels_last_3d_contiguous_avail; + } + bool has_is_channels_last() const { + return available_.load() & is_channels_last_avail; + } + bool has_is_channels_last_3d() const { + return available_.load() & is_channels_last_3d_avail; + } + bool has_is_non_overlapping_and_dense() const { + return available_.load() & is_non_overlapping_and_dense_avail; + } + + // Accessors to cached derived properties + // DO NOT call with mutables_ lock held + const SymInt& numel() const { + if (C10_UNLIKELY(!has_numel())) { + init_numel(); + } + return numel_; + } + + const SymBool& is_contiguous(at::MemoryFormat memory_format) const { + if (memory_format == at::MemoryFormat::ChannelsLast) { + return this->is_channels_last_contiguous(); + } else if (memory_format == at::MemoryFormat::ChannelsLast3d) { + return this->is_channels_last_3d_contiguous(); + } + return this->is_contiguous(); + } + + const SymBool& is_contiguous() const { + if (C10_UNLIKELY(!has_is_contiguous())) { + init_is_contiguous(); + } + return is_contiguous_; + } + + const SymBool& is_channels_last_contiguous() const { + if (C10_UNLIKELY(!has_is_channels_last_contiguous())) { + init_is_channels_last_contiguous(); + } + return is_channels_last_contiguous_; + } + + const SymBool& is_channels_last_3d_contiguous() const { + if (C10_UNLIKELY(!has_is_channels_last_3d_contiguous())) { + init_is_channels_last_3d_contiguous(); + } + return is_channels_last_3d_contiguous_; + } + + const SymBool& is_channels_last() const { + if (C10_UNLIKELY(!has_is_channels_last())) { + init_is_channels_last(); + } + return is_channels_last_; + } + + const SymBool& is_channels_last_3d() const { + if (C10_UNLIKELY(!has_is_channels_last_3d())) { + init_is_channels_last_3d(); + } + return is_channels_last_3d_; + } + + const SymBool& is_non_overlapping_and_dense() const { + if (C10_UNLIKELY(!has_is_non_overlapping_and_dense())) { + init_is_non_overlapping_and_dense(); + } + return is_non_overlapping_and_dense_; + } + + // Assumptions so we can short-circuit computation + // NOTE: Don't need to lock mutables_ since these aren't const + void assume_contiguous(SymBool val = true) { + is_contiguous_ = std::move(val); + available_.fetch_or(is_contiguous_avail); + } + void assume_channels_last_contiguous(SymBool val = true) { + is_channels_last_contiguous_ = std::move(val); + available_.fetch_or(is_channels_last_contiguous_avail); + } + void assume_channels_last_3d_contiguous(SymBool val = true) { + is_channels_last_3d_contiguous_ = std::move(val); + available_.fetch_or(is_channels_last_3d_contiguous_avail); + } + void assume_channels_last(SymBool val = true) { + is_channels_last_ = std::move(val); + available_.fetch_or(is_channels_last_avail); + } + void assume_channels_last_3d(SymBool val = true) { + is_channels_last_3d_ = std::move(val); + available_.fetch_or(is_channels_last_3d_avail); + } + void assume_non_overlapping_and_dense(SymBool val = true) { + is_non_overlapping_and_dense_ = std::move(val); + available_.fetch_or(is_non_overlapping_and_dense_avail); + } + + private: + SymBool compute_contiguous() const; + SymBool compute_channels_last_contiguous_2d() const; + SymBool compute_channels_last_contiguous_3d() const; + SymBool compute_strides_like_channels_last_2d() const; + SymBool compute_strides_like_channels_last_3d() const; + SymBool compute_non_overlapping_and_dense() const; + + // These are little wrappers over the real compute_ functions that + // can make use of other contiguity fields to short circuit. + // They need to be implemented separately for SymBool, as SymBool does + // not short circuit. + // TODO: should the SymBool cases avoid the short circuit? Need to reason + // if its correct, and reason if the simpler expressions are better for + // analysis (maybe not!) + + SymBool compute_channels_last_contiguous_3d_dim5() const; + SymBool compute_channels_last_2d_dim5() const; + SymBool compute_channels_last_3d_dim5() const; + SymBool compute_is_non_overlapping_and_dense_dim4() const; + SymBool compute_is_non_overlapping_and_dense_dim5() const; + SymBool compute_is_non_overlapping_and_dense_anydim() const; + + void init_numel() const; + void init_is_contiguous() const; + void init_is_channels_last_contiguous() const; + void init_is_channels_last_3d_contiguous() const; + void init_is_channels_last() const; + void init_is_channels_last_3d() const; + void init_is_non_overlapping_and_dense() const; + + // NOTE: These only set if !has_foo() + void set_numel(SymInt val) const; + void set_is_contiguous(SymBool val) const; + void set_is_channels_last_contiguous(SymBool val) const; + void set_is_channels_last_3d_contiguous(SymBool val) const; + void set_is_channels_last(SymBool val) const; + void set_is_channels_last_3d(SymBool val) const; + void set_is_non_overlapping_and_dense(SymBool val) const; + + // Lazily initialized variables, with the corresponding available_ flag + // indicating whether the value has been initialized + mutable std::atomic available_{0}; + + enum avail { + numel_avail = 1 << 0, + is_contiguous_avail = 1 << 1, + is_channels_last_contiguous_avail = 1 << 2, + is_channels_last_3d_contiguous_avail = 1 << 3, + is_channels_last_avail = 1 << 4, + is_channels_last_3d_avail = 1 << 5, + is_non_overlapping_and_dense_avail = 1 << 6, + }; + + // Mutex to prevent races when initializing the variable from const accessors + mutable std::mutex mutables_; + mutable SymInt numel_ = 1; + mutable SymBool is_contiguous_{true}; + mutable SymBool is_channels_last_contiguous_{false}; + mutable SymBool is_channels_last_3d_contiguous_{false}; + mutable SymBool is_channels_last_{false}; + mutable SymBool is_channels_last_3d_{false}; + mutable SymBool is_non_overlapping_and_dense_{true}; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/TensorImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/TensorImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..4ea7a74ba20bf74f35c450e4208c935ca3fb7b90 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/TensorImpl.h @@ -0,0 +1,3339 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// A global boolean variable to control whether we free memory when a Tensor +// is shrunk to a smaller size. As a result, a Tensor is always going to +// keep the memory allocated for its maximum capacity reshaped to so far. +// +// This parameter is respected "upper-case" methods which call Resize() +// (e.g., CopyFrom, ResizeLike); it is NOT respected by Tensor::resize_ +// or ShrinkTo, both of which guarantee to never to free memory. +C10_DECLARE_bool(caffe2_keep_on_shrink); + +// Since we can have high variance in blob memory allocated across different +// inputs in the same run, we will shrink the blob only if the memory gain +// is larger than this flag in bytes. This only applies to functions which +// respect caffe2_keep_on_shrink. +C10_DECLARE_int64(caffe2_max_keep_on_shrink_memory); + +C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-default") + +namespace at { +class Tensor; +class TensorBase; +} // namespace at + +namespace c10 { + +/** + * A utility function to convert vector to vector. + */ +inline std::vector ToVectorint64_t(const ArrayRef& src) { + return std::vector(src.begin(), src.end()); +} + +/** + * Return product of all dimensions starting from k + */ +inline int64_t size_from_dim_(int k, IntArrayRef dims) { + int64_t r = 1; + for (const auto i : c10::irange(k, dims.size())) { + r *= dims[i]; + } + return r; +} + +// Product of all dims up to k (not including dims[k]) +inline int64_t size_to_dim_(int k, IntArrayRef dims) { + TORCH_CHECK(k >= 0 && static_cast(k) <= dims.size()); + int64_t r = 1; + for (const auto i : c10::irange(k)) { + r *= dims[i]; + } + return r; +} + +// Product of all dims between k and l (not including dims[k] and dims[l]) +inline int64_t size_between_dim_(int k, int l, IntArrayRef dims) { + TORCH_CHECK((unsigned)l < dims.size() && (unsigned)k < dims.size()); + int64_t r = 1; + if (k < l) { + for (int i = k + 1; i < l; ++i) { + r *= dims[i]; + } + } else { + for (int i = l + 1; i < k; ++i) { + r *= dims[i]; + } + } + return r; +} + +// Wrap around axis_index if it is negative, s.t., -1 is the last dim +inline int canonical_axis_index_(int axis_index, int ndims) { + TORCH_CHECK(axis_index >= -ndims); + TORCH_CHECK(axis_index < ndims); + if (axis_index < 0) { + return axis_index + ndims; + } + return axis_index; +} + +using PlacementDtor = void (*)(void*, size_t); + +/* + * A Context that will call extra placement deleter during + * deconstruction. + * + * Accept a already constructed DataPtr and store it as member + * during destruction, we'll call extra deleter on the underlying + * data pointer before the DataPtr is destructed. + * `data_ptr_` owns the memory. + */ +struct C10_API PlacementDeleteContext { + DataPtr data_ptr_; + PlacementDtor placement_dtor_; + size_t size_; + + PlacementDeleteContext( + DataPtr&& data_ptr, + PlacementDtor placement_dtor, + size_t size) + : data_ptr_(std::move(data_ptr)), + placement_dtor_(placement_dtor), + size_(size) {} + + PlacementDeleteContext(PlacementDeleteContext&&) noexcept = delete; + PlacementDeleteContext(const PlacementDeleteContext&) = delete; + PlacementDeleteContext& operator=(const PlacementDeleteContext&) = delete; + PlacementDeleteContext& operator=(PlacementDeleteContext&&) = delete; + static DataPtr makeDataPtr( + DataPtr&& data_ptr, + PlacementDtor placement_dtor, + size_t size, + Device device); + ~PlacementDeleteContext() { + placement_dtor_(data_ptr_.get(), size_); + // original memory will be freed when data_ptr_ is destructed + } +}; + +struct C10_API AutogradMetaInterface { + virtual void set_requires_grad( + bool requires_grad, + at::TensorImpl* self_impl) = 0; + virtual bool requires_grad() const = 0; + virtual at::Tensor& mutable_grad() = 0; + virtual const at::Tensor& grad() const = 0; + virtual const at::Tensor& fw_grad(uint64_t level, const at::TensorBase& self) + const = 0; + virtual void set_fw_grad( + const at::TensorBase& new_grad, + const at::TensorBase& self, + uint64_t level, + bool is_inplace_op) = 0; + virtual ~AutogradMetaInterface(); +}; + +namespace impl { + +// Unfortunately, the definition of AutogradMeta lives in a separate +// compilation unit than TensorImpl (libtorch.so versus libc10.so) +// which means that we cannot construct an AutogradMeta from TensorImpl, +// not even from the cpp file. So we have to indirect it through a factory +// function which will be initialized when we load libtorch.so. + +struct C10_API AutogradMetaFactory { + virtual ~AutogradMetaFactory() = default; + virtual std::unique_ptr make() const = 0; + // This method is the dumbest method. But I don't have access + // to Tensor (not TensorImpl) which is undefined in this header. + virtual const at::Tensor& undefined_tensor() const = 0; +}; + +C10_API void SetAutogradMetaFactory(AutogradMetaFactory* factory); +C10_API AutogradMetaFactory* GetAutogradMetaFactory(); + +struct C10_API AutogradMetaFactoryRegisterer{ + explicit AutogradMetaFactoryRegisterer(AutogradMetaFactory * factory){ + SetAutogradMetaFactory(factory); +} // namespace impl +}; // namespace c10 + +} // namespace impl + +struct C10_API NamedTensorMetaInterface { + virtual ~NamedTensorMetaInterface() = default; + virtual std::unique_ptr clone() const { + TORCH_INTERNAL_ASSERT( + false, "Not implemented: NamedTensorMetaInterface::clone"); + } + virtual int64_t slow_dim() const { + TORCH_INTERNAL_ASSERT( + false, "Not implemented: NamedTensorMetaInterface::slow_dim"); + } +}; + +// For ease of copy pasting +#if 0 +is_contiguous +is_channels_last_contiguous +is_channels_last_3d_contiguous +is_channels_last +is_channels_last_3d +is_non_overlapping_and_dense +#endif + +/** + * This structure is intended to hold additional metadata of the specific device + * backend. + **/ +struct C10_API BackendMeta : intrusive_ptr_target { + ~BackendMeta() override = default; + virtual intrusive_ptr clone( + const intrusive_ptr& ptr) const { + return ptr; + } +}; + +struct C10_API ExtraMeta { + std::unique_ptr symbolic_shape_meta_ = nullptr; + std::unique_ptr named_tensor_meta_ = nullptr; + intrusive_ptr backend_meta_ = nullptr; + std::optional custom_data_ptr_error_msg_ = std::nullopt; + std::optional custom_storage_error_msg_ = std::nullopt; + + ExtraMeta() = default; + ~ExtraMeta() = default; + ExtraMeta(const ExtraMeta& other) { + if (other.symbolic_shape_meta_) { + symbolic_shape_meta_ = + std::make_unique(*other.symbolic_shape_meta_); + } + if (other.named_tensor_meta_) { + named_tensor_meta_ = other.named_tensor_meta_->clone(); + } + if (other.backend_meta_) { + backend_meta_ = other.backend_meta_->clone(other.backend_meta_); + } + if (other.custom_data_ptr_error_msg_) { + custom_data_ptr_error_msg_ = other.custom_data_ptr_error_msg_; + } + if (other.custom_storage_error_msg_) { + custom_storage_error_msg_ = other.custom_storage_error_msg_; + } + } + ExtraMeta& operator=(const ExtraMeta& other) = delete; + ExtraMeta(ExtraMeta&& other) = delete; + ExtraMeta& operator=(ExtraMeta&& other) = delete; + + ExtraMeta( + std::unique_ptr symbolic_shape_meta, + std::unique_ptr named_tensor_meta, + intrusive_ptr backend_meta, + std::optional custom_data_ptr_error_msg = std::nullopt, + std::optional custom_storage_access_error_msg = std::nullopt) + : symbolic_shape_meta_(std::move(symbolic_shape_meta)), + named_tensor_meta_(std::move(named_tensor_meta)), + backend_meta_(std::move(backend_meta)), + custom_data_ptr_error_msg_(std::move(custom_data_ptr_error_msg)), + custom_storage_error_msg_(std::move(custom_storage_access_error_msg)) {} + + std::unique_ptr clone() const { + return std::make_unique(*this); + } +}; + +// NOTE [ Version Counter Sharing ] +// +// Every Tensor has a version counter. Version counters are incremented whenever +// the data or size of a tensor changes through in-place Variable operations. +// Version counters are used to detect modifications to saved variables which +// would result in incorrect gradient calculations. Version counters may be +// shared between Variables: +// +// 1. A view shares the version counter of the base Variable, +// 2. `x.detach()` shares the version counter of `x`, +// 3. Unpacked saved variables share the version counter of the source. +// +// Version counters are not shared in these scenarios: +// +// 1. When we replace a `Variable`'s underlying `Tensor` by calling +// `set_data(...)`, +// 2. `x.data` does not share the version counter of `x`. (See discussion at +// https://github.com/pytorch/pytorch/issues/5396) +// +// Question: Why do we put the version counter in TensorImpl instead of +// AutogradMeta? +// +// Answer: After the Variable/Tensor merge, a tensor will not have AutogradMeta +// when its `requires_grad_` is false, but when we use this tensor in the +// forward pass of a function that requires saving this tensor for backward, we +// need to keep track of this tensor's version to make sure it's always valid in +// the autograd graph. +// +// To achieve this goal, we put the version counter in TensorImpl instead of +// AutogradMeta, and have it always be available. This allows us to have the +// optimization of not carrying AutogradMeta when a tensor doesn't require +// gradient. +// +// A hypothetical alternative way to achieve this goal is to initialize +// AutogradMeta and create the version counter for the non-requires-grad tensor +// only when it's saved for backward. However, since saving a tensor for +// backward happens in the forward pass, and our invariant is that forward pass +// needs to be thread-safe, lazy-initializing AutogradMeta when saving a tensor +// can introduce race conditions when we are running the forward pass in +// multi-thread scenarios, thus making the forward pass not thread-safe anymore, +// which breaks the invariant. +struct C10_API VariableVersion { + private: + struct VersionCounter : intrusive_ptr_target { + VersionCounter(uint32_t version) : version_(version) {} + std::atomic version_; + }; + c10::intrusive_ptr version_counter_; + + public: + // Note [Disabled VariableVersion] + // VariableVersion struct has an intrusive_ptr pointing VersionCounter struct + // with an atomic variable. Thus `VariableVersion(/*version=*/0)` is not as + // cheap as we expected. In some cases constructing a VariableVersion with + // version 0 is not necessary so we add a cheap constructor which + // doesn't allocate the intrusive_ptr. + // Example use cases are: + // - Inference tensors don't track version counter, so they'll just always + // have disabled VariableVersion. + // - In SavedVariable class we override version_counter_ inside its + // constructor + // so that we can use the cheap constructor there. + enum Disabled { DISABLED }; + // It's okay to return true even for inference tensor which + // doesn't have version counter enabled. + // We want to be permissive here since in many cases (e.g. make_variable) + // we can std::move a TensorImpl if there's no other uses which saves us + // an additional TensorImpl allocation. + bool unique() const { + return version_counter_ ? 1 == version_counter_.use_count() : true; + } + // NOTE: As of C++11 and 14, default-constructing a std::atomic variable + // leaves it in a persistently undefined state. See + // https://cplusplus.github.io/LWG/issue2334. + VariableVersion(uint32_t version) + : version_counter_(c10::make_intrusive(version)) {} + VariableVersion(Disabled /*unused*/ = DISABLED) {} + + bool enabled() const { + return version_counter_; + } + + // Note [Inplace update inference tensor] + // 1. Inplace update to inference tensor is forbidden in normal mode. + // For example: + // inference_tensor.copy_(normal_tensor_requires_grad) + // This inplace makes inference_tensor have requires_grad=True and + // have a grad_fn. This is bad because views of `inference_tensor` + // created in InferenceMode won't be able to know the grad_fn since + // their ViewMeta were not recorded. To match NoGradMode behavior + // that "inplace update to a view created in NoGradMode raise an error", + // we just ban inplace update to inference tensor since we can't tell + // if an inference tensor is a view created in InferenceMode. + // + // Note that views of normal tensor created in InferenceMode has proper + // ViewMeta so that they're aware of the grad_fn correctly. + // + // 2. Inplace update to inference tensor in inference tensor doesn't bump + // version counter. + // * It either doesn't call bump() by skipping ADInplaceOrView kernel, + // - e.g. inference_tensor.add_(1) + // * or bump() is a no-op for inference tensor. + // - e.g. inference_tensor.add_(normal_tensor) + void bump() { + // TODO: Replace the link to the documentation once it's available. + TORCH_CHECK( + version_counter_ || InferenceMode::is_enabled(), + "Inplace update to inference tensor outside InferenceMode is not allowed." + "You can make a clone to get a normal tensor before doing inplace update." + "See https://github.com/pytorch/rfcs/pull/17 for more details."); + if (version_counter_) { + ++version_counter_->version_; + } + } + + void set_version(int64_t i) { + TORCH_CHECK( + version_counter_, + "Tried to call torch.autograd._unsafe_set_version() on a tensor " + "that does not have a version counter. Was it created in inference mode?"); + TORCH_CHECK(i >= 0, "Cannot set a version_counter to a value below 0: ", i); + version_counter_->version_ = i; + } + + // Inference tensor doesn't have version counter so it shouldn't be + // accessed. + uint32_t current_version() const { + TORCH_CHECK( + version_counter_, "Inference tensors do not track version counter."); + return version_counter_->version_; + } +}; + +// Forward declaration of TensorImpl needed for forward declaration of +// C10_TensorImpl_Size_Check_Dummy_Class +struct C10_API TensorImpl; + +/** + * NOTE: Some TensorImpl methods are small and not overridden in the + * PyTorch codebase itself, but may theoretically need to be + * overridden by third-party TensorImpl subclasses. This macro allows + * users that need maximum performance and don't need these extension + * points to disable them with a build-time flag. (In particular, + * XLA's XLATensorImpl currently overrides these methods, so we can't + * enable this flag by default.) + */ +#ifdef C10_DISABLE_TENSORIMPL_EXTENSIBILITY +#define TENSORIMPL_MAYBE_VIRTUAL +#else +#define TENSORIMPL_MAYBE_VIRTUAL virtual +#endif + +/** + * The low-level representation of a tensor, which contains a pointer + * to a storage (which contains the actual data) and metadata (e.g., sizes and + * strides) describing this particular view of the data as a tensor. + * + * Some basic characteristics about our in-memory representation of + * tensors: + * + * - It contains a pointer to a storage struct (Storage/StorageImpl) + * which contains the pointer to the actual data and records the + * data type and device of the view. This allows multiple tensors + * to alias the same underlying data, which allows to efficiently + * implement differing *views* on a tensor. + * + * - The tensor struct itself records view-specific metadata about + * the tensor, e.g., sizes, strides and offset into storage. + * Each view of a storage can have a different size or offset. + * + * - This class is intrusively refcounted. It is refcounted so that + * we can support prompt deallocation of large tensors; it is + * intrusively refcounted so that we can still perform reference + * counted operations on raw pointers, which is often more convenient + * when passing tensors across language boundaries. + * + * - For backwards-compatibility reasons, a tensor may be in an + * uninitialized state. A tensor may be uninitialized in the following + * two ways: + * + * - A tensor may be DTYPE UNINITIALIZED. A tensor of this + * form has an uninitialized dtype. This situation most + * frequently arises when a user writes Tensor x(CPU). The dtype + * is subsequently initialized when mutable_data() is + * invoked for the first time. + * + * - A tensor may be STORAGE UNINITIALIZED. A tensor of this form + * has non-zero size, but has a storage with a null data pointer. + * This situation most frequently arises when a user calls + * Resize() or FreeMemory(). This is because Caffe2 historically + * does lazy allocation: allocation of data doesn't occur until + * mutable_data() is invoked. A tensor with zero size is + * always storage initialized, because no allocation is necessary + * in this case. + * + * All combinations of these two uninitialized states are possible. + * Consider the following transcript in idiomatic Caffe2 API: + * + * Tensor x(CPU); // x is storage-initialized, dtype-UNINITIALIZED + * x.Resize(4); // x is storage-UNINITIALIZED, dtype-UNINITIALIZED + * x.mutable_data(); // x is storage-initialized, dtype-initialized + * x.FreeMemory(); // x is storage-UNINITIALIZED, dtype-initialized. + * + * All other fields on tensor are always initialized. In particular, + * size is always valid. (Historically, a tensor declared as Tensor x(CPU) + * also had uninitialized size, encoded as numel == -1, but we have now + * decided to default to zero size, resulting in numel == 0). + * + * Uninitialized storages MUST be uniquely owned, to keep our model + * simple. Thus, we will reject operations which could cause an + * uninitialized storage to become shared (or a shared storage to + * become uninitialized, e.g., from FreeMemory). + * + * In practice, tensors which are storage-UNINITIALIZED and + * dtype-UNINITIALIZED are *extremely* ephemeral: essentially, + * after you do a Resize(), you basically always call mutable_data() + * immediately afterwards. Most functions are not designed to + * work if given a storage-UNINITIALIZED, dtype-UNINITIALIZED tensor. + * + * We intend to eliminate all uninitialized states, so that every + * tensor is fully initialized in all fields. Please do not write new code + * that depends on these uninitialized states. + */ +struct C10_API TensorImpl : public c10::intrusive_ptr_target { + TensorImpl() = delete; + ~TensorImpl() override; + // Note [Enum ImplType] + // This enum is temporary. In the followup refactor we should + // think about how to specialize TensorImpl creation for view + // tensors. Currently we only special case its key_set_ but + // there's also potential to share version_counter_ directly + // without creating first and then override in as_view. + enum ImplType { VIEW }; + + /** + * Construct a 1-dim 0-size tensor backed by the given storage. + */ + TensorImpl( + Storage&& storage, + DispatchKeySet /*key_set*/, + const caffe2::TypeMeta data_type); + + // See Note [Enum ImplType] + TensorImpl( + ImplType /*unused*/, + Storage&& storage, + DispatchKeySet /*key_set*/, + const caffe2::TypeMeta data_type); + + /** + * Construct a 1-dim 0 size tensor that doesn't have a storage. + */ + TensorImpl( + DispatchKeySet /*key_set*/, + const caffe2::TypeMeta data_type, + std::optional device_opt); + + // Legacy constructors so I don't have to go update call sites. + // TODO: When Variable is added, delete these constructors + TensorImpl( + Storage&& storage, + DispatchKey dispatch_key, + const caffe2::TypeMeta data_type) + : TensorImpl( + std::move(storage), + DispatchKeySet(dispatch_key), + data_type) {} + TensorImpl( + DispatchKey dispatch_key, + const caffe2::TypeMeta data_type, + std::optional device_opt) + : TensorImpl(DispatchKeySet(dispatch_key), data_type, device_opt) {} + + private: + // This constructor is private, because the data_type is redundant with + // storage. Still, we pass it in separately because it's easier to write + // the initializer list if we're not worried about storage being moved out + // from under us. + TensorImpl( + Storage&& storage, + DispatchKeySet /*key_set*/, + const caffe2::TypeMeta data_type, + std::optional /*device_opt*/); + + public: + TensorImpl(const TensorImpl&) = delete; + TensorImpl& operator=(const TensorImpl&) = delete; + TensorImpl(TensorImpl&&) = delete; + TensorImpl& operator=(TensorImpl&&) = delete; + + /** + * Release (decref) storage, and any other external allocations. This + * override is for `intrusive_ptr_target` and is used to implement weak + * tensors. + */ + void release_resources() override; + + public: + /** + * Return the DispatchKeySet corresponding to this Tensor, specifying + * all of the DispatchKeys that this Tensor identifies as. This is the + * information used to dispatch operations on this tensor. + */ + DispatchKeySet key_set() const { + return key_set_; + } + + private: + [[noreturn]] void throw_cannot_call_with_symbolic(const char* meth) const; + + // NOTE: The general recipe for customizable methods is that the fastpath + // function (e.g., sizes()) does an unlikely policy test, and if doesn't + // trigger, it does the fast path implementation with no checks and going + // directly to on-TensorImpl fields. In particular, you never need to + // check ExtraMeta if the policy doesn't trigger, as non-trivial ExtraMeta + // implies the policy will always match. + // + // The default implementations of methods are "safe": they do extra tests + // to make sure the internal state is consistent no matter if you are + // doing symbolic shapes or not. If you don't want the tests, directly + // override the custom method (e.g., custom_sizes()) to do your preferred + // behavior. + + public: + /** + * Return a reference to the sizes of this tensor. This reference remains + * valid as long as the tensor is live and not resized. + */ + IntArrayRef sizes() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomSizes))) { + return sizes_custom(); + } + return sizes_and_strides_.sizes_arrayref(); + } + + SymIntArrayRef sym_sizes() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomSizes))) { + return sym_sizes_custom(); + } + // Sizes guaranteed to be non-negative, so unchecked cast is OK + return c10::fromIntArrayRefKnownNonNegative( + sizes_and_strides_.sizes_arrayref()); + } + + IntArrayRef sizes_default() const { + if (C10_UNLIKELY(has_symbolic_sizes_strides_)) { + throw_cannot_call_with_symbolic("sizes"); + } + return sizes_and_strides_.sizes_arrayref(); + } + + SymIntArrayRef sym_sizes_default() const { + if (has_symbolic_sizes_strides_) { + return symbolic_shape_meta().sizes_; + } else { + // Sizes guaranteed to be non-negative, so unchecked cast is OK + return c10::fromIntArrayRefKnownNonNegative(sizes_default()); + } + } + + template + ArrayRef generic_sizes() { + static_assert( + std::is_same_v || std::is_same_v, + "Only supports int64_t and c10::SymInt."); + + if constexpr (std::is_same_v) { + return sizes(); + } else { + return sym_sizes(); + } + } + + template + ArrayRef generic_strides() { + static_assert( + std::is_same_v || std::is_same_v, + "Only supports int64_t and c10::SymInt."); + + if constexpr (std::is_same_v) { + return strides(); + } else { + return sym_strides(); + } + } + + template + T generic_storage_offset() { + static_assert( + std::is_same_v || std::is_same_v, + "Only supports int64_t and c10::SymInt."); + + if constexpr (std::is_same_v) { + return storage_offset(); + } else { + return sym_storage_offset(); + } + } + + /** + * The number of elements in a tensor. + * + * WARNING: Previously, if you were using the Caffe2 API, you could + * test numel() == -1 to see if a tensor was uninitialized. This + * is no longer true; numel always accurately reports the product + * of sizes of a tensor. + */ + int64_t numel() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomSizes))) { + return numel_custom(); + } + return numel_; + } + + c10::SymInt sym_numel() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomSizes))) { + return sym_numel_custom(); + } + return c10::SymInt(SymInt::UNCHECKED, numel_); + } + + int64_t numel_default() const { + if (C10_UNLIKELY(has_symbolic_sizes_strides_)) { + throw_cannot_call_with_symbolic("numel"); + } + return numel_; + } + + c10::SymInt sym_numel_default() const { + if (has_symbolic_sizes_strides_) { + return symbolic_shape_meta().numel(); + } else { + return c10::SymInt(SymInt::UNCHECKED, numel_); + } + } + + /** + * Return the number of dimensions of this tensor. Note that 0-dimension + * represents a Tensor that is a Scalar, e.g., one that has a single element. + */ + int64_t dim() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomSizes))) { + return dim_custom(); + } + return static_cast(sizes_and_strides_.size()); + } + + int64_t dim_default() const { + if (has_symbolic_sizes_strides_) { + return static_cast(symbolic_shape_meta().sizes_.size()); + } else { + return static_cast(sizes_and_strides_.size()); + } + } + + /** + * Return the offset in number of elements into the storage that this + * tensor points to. Most tensors have storage_offset() == 0, but, + * for example, an index into a tensor will have a non-zero storage_offset(). + * + * WARNING: This is NOT computed in bytes. + */ + int64_t storage_offset() const { + // TODO: maybe this should be toggled by strides + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomSizes))) { + return storage_offset_custom(); + } + return storage_offset_; + } + + c10::SymInt sym_storage_offset() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomSizes))) { + return sym_storage_offset_custom(); + } + return c10::SymInt(SymInt::UNCHECKED, storage_offset_); + } + + int64_t storage_offset_default() const { + if (C10_UNLIKELY(has_symbolic_sizes_strides_)) { + throw_cannot_call_with_symbolic("storage_offset"); + } + return storage_offset_; + } + + c10::SymInt sym_storage_offset_default() const { + if (has_symbolic_sizes_strides_) { + return symbolic_shape_meta().storage_offset_; + } else { + return c10::SymInt(SymInt::UNCHECKED, storage_offset_); + } + } + + /** + * Return a reference to the strides of this tensor. This reference remains + * valid as long as the tensor is live and not restrided. + */ + IntArrayRef strides() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomStrides))) { + return strides_custom(); + } + return sizes_and_strides_.strides_arrayref(); + } + + c10::SymIntArrayRef sym_strides() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomStrides))) { + return sym_strides_custom(); + } + return c10::fromIntArrayRefKnownNonNegative(strides_default()); + } + + IntArrayRef strides_default() const { + if (C10_UNLIKELY(has_symbolic_sizes_strides_)) { + throw_cannot_call_with_symbolic("strides"); + } + return sizes_and_strides_.strides_arrayref(); + } + + c10::SymIntArrayRef sym_strides_default() const { + if (has_symbolic_sizes_strides_) { + return symbolic_shape_meta().strides_; + } else { + return c10::fromIntArrayRefKnownNonNegative(strides_default()); + } + } + + c10::SymBool sym_is_contiguous( + at::MemoryFormat memory_format = at::MemoryFormat::Contiguous) const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomStrides))) { + return sym_is_contiguous_custom(memory_format); + } + return sym_is_contiguous_default(memory_format); + } + + template + T is_contiguous_default_impl(at::MemoryFormat memory_format) const { + if (!has_symbolic_sizes_strides_) { + if (memory_format == at::MemoryFormat::ChannelsLast) { + return is_channels_last_contiguous_; + } else if (memory_format == at::MemoryFormat::ChannelsLast3d) { + return is_channels_last_3d_contiguous_; + } + return is_contiguous_; + } + + // Handle dynamic shapes. + const auto& symbolic = symbolic_shape_meta().is_contiguous(memory_format); + + if constexpr (std::is_same_v) { + return symbolic.guard_bool(__FILE__, __LINE__); + } else { + return symbolic; + } + } + + bool is_contiguous_default(at::MemoryFormat memory_format) const { + return is_contiguous_default_impl(memory_format); + } + + c10::SymBool sym_is_contiguous_default(at::MemoryFormat memory_format) const { + return is_contiguous_default_impl(memory_format); + } + + /** + * Whether or not a tensor is laid out in contiguous memory. + * + * Tensors with non-trivial strides are not contiguous. See + * compute_contiguous() for the exact definition of whether or not + * a tensor is contiguous or not. + */ + bool is_contiguous( + at::MemoryFormat memory_format = at::MemoryFormat::Contiguous) const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomStrides))) { + return is_contiguous_custom(memory_format); + } + return is_contiguous_default(memory_format); + } + + bool is_strides_like_default(at::MemoryFormat memory_format) const { + if (has_symbolic_sizes_strides_) { + if (memory_format == at::MemoryFormat::ChannelsLast) { + return symbolic_shape_meta().is_channels_last().guard_bool( + __FILE__, __LINE__); + } else if (memory_format == at::MemoryFormat::ChannelsLast3d) { + return symbolic_shape_meta().is_channels_last_3d().guard_bool( + __FILE__, __LINE__); + } else { + return false; + } + } + + if (memory_format == at::MemoryFormat::ChannelsLast) { + return is_channels_last_; + } else if (memory_format == at::MemoryFormat::ChannelsLast3d) { + return is_channels_last_3d_; + } else { + return false; + } + } + + SymBool sym_is_non_overlapping_and_dense_default() const { + if (has_symbolic_sizes_strides_) { + return symbolic_shape_meta().is_non_overlapping_and_dense(); + } else { + return is_non_overlapping_and_dense_; + } + } + + bool is_non_overlapping_and_dense_default() const { + if (has_symbolic_sizes_strides_) { + return sym_is_non_overlapping_and_dense_default().guard_bool( + __FILE__, __LINE__); + } else { + return is_non_overlapping_and_dense_; + } + } + + // NB: these dim accessor functions don't have _default(), as you can use + // sizes_default/strides_default + /** + * Return the size of a tensor at some dimension, wrapping the dimension if + * necessary. + * + * NOTE: if you know wrapping is unnecessary, do sizes()[d] instead; it will + * be faster + */ + int64_t size(int64_t d) const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomSizes))) { + return size_custom(d); + } + d = maybe_wrap_dim(d, dim(), /*wrap_scalar=*/false); + return sizes_and_strides_.size_at_unchecked(d); + } + + c10::SymInt sym_size(int64_t d) const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomSizes))) { + return sym_size_custom(d); + } + d = maybe_wrap_dim(d, dim(), /*wrap_scalar=*/false); + const auto sizes = this->sym_sizes(); + return sizes[d]; + } + + /** + * Return the stride of a tensor at some dimension, wrapping the dimension + * if necessary. + * + * NOTE: if you know wrapping is unnecessary, do sizes()[d] instead; it will + * be faster + */ + int64_t stride(int64_t d) const { + d = maybe_wrap_dim(d, dim(), false); + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomStrides))) { + // TODO: provide stride_custom, symmetrically with size_custom. + // There is presently no user for it; only NestedTensor is using + // size_custom overrideability + return strides_custom()[d]; // unchecked (maybe_wrap_dim enforces bounds) + } + // Intentionally don't call default, which also handles symbolic + return sizes_and_strides_.stride_at_unchecked(d); + } + + enum class SizesStridesPolicy : uint8_t { + // Default behavior, e.g., dense tensor. + // + // Can override: nothing + Default = 0, + // Customizable strides behavior, e.g., sparse tensor, + // mkldnn tensor. + // + // Can override: strides(), is_contiguous() + CustomStrides = 1, + // Customizable sizes behavior, e.g., nested tensor + // + // Can override: strides(), is_contiguous(), sizes(), dim(), numel() + CustomSizes = 2 + }; + + protected: + inline bool matches_policy(SizesStridesPolicy policy) const { + return sizes_strides_policy_ >= static_cast(policy); + } + + inline bool matches_custom(SizesStridesPolicy policy) const { + return custom_sizes_strides_ >= static_cast(policy); + } + + inline bool matches_python_custom(SizesStridesPolicy policy) const { + auto r = python_custom_sizes_strides_ >= static_cast(policy); + if (r) { + TORCH_INTERNAL_ASSERT(is_python_dispatch()) + } + return r; + } + + /** + * Customization points for the functions above. sizes_strides_policy_ + * must be set to enable these. + * + * NB: dim is overridable separately from sizes because it is possible + * for a tensor to have rank, but not well defined sizes. + */ + // sizes_strides_policy_ >= CustomStrides + + virtual bool is_strides_like_custom(at::MemoryFormat memory_format) const; + + virtual c10::SymBool sym_is_non_overlapping_and_dense_custom() const; + + bool is_non_overlapping_and_dense_custom() const { + return sym_is_non_overlapping_and_dense_custom().guard_bool( + __FILE__, __LINE__); + } + + virtual c10::SymBool sym_is_contiguous_custom( + at::MemoryFormat memory_format) const; + + bool is_contiguous_custom(at::MemoryFormat memory_format) const { + return sym_is_contiguous_custom(memory_format) + .guard_bool(__FILE__, __LINE__); + } + + // sizes_strides_policy_ >= CustomSizes + // Currently this method only exists to be overwritten by subclasses such as + // NestedTensorImpl. + virtual int64_t size_custom(int64_t d) const { + // TODO: We could add support to Python dispatch here. + // TODO: We could call into aten::size.int instead of + // sizes_custom()[d] and enable use of the dispatcher. + d = maybe_wrap_dim(d, dim(), /*wrap_scalar=*/false); + return sizes_custom()[d]; // unchecked (maybe_wrap_dim enforces bounds) + } + + virtual c10::SymInt sym_size_custom(int64_t d) const { + // TODO: We could add support to Python dispatch here. + // TODO: We could call into aten::size.int instead of + // sym_sizes_custom()[d] and enable use of the dispatcher. + d = maybe_wrap_dim(d, dim(), /*wrap_scalar=*/false); + return sym_sizes_custom()[d]; // unchecked (maybe_wrap_dim enforces bounds) + } + + virtual IntArrayRef sizes_custom() const; + virtual IntArrayRef strides_custom() const; + virtual int64_t numel_custom() const; + virtual int64_t storage_offset_custom() const; + virtual int64_t dim_custom() const; + virtual Device device_custom() const; + virtual Layout layout_custom() const; + + virtual c10::SymIntArrayRef sym_sizes_custom() const; + virtual c10::SymIntArrayRef sym_strides_custom() const; + virtual c10::SymInt sym_numel_custom() const; + virtual c10::SymInt sym_storage_offset_custom() const; + + public: +/** + * True if this tensor has storage. See storage() for details. + */ +#ifdef DEBUG + // Allow subclasses to check that their storage_ is never getting set in debug + // builds. + virtual +#else + TENSORIMPL_MAYBE_VIRTUAL +#endif + bool + has_storage() const +// NOTE: we devirtualize this because it arguably shouldn't be an +// error just to ask subclasses if they have storage. +// This used to throw for most subclasses, but OpaqueTensorImpl +// wanted it to successfully return false, so we went ahead and made +// it a non-error. +#ifdef C10_DISABLE_TENSORIMPL_EXTENSIBILITY + { + return storage_; + } +#else + ; +#endif + + /** + * Return the underlying storage of a Tensor. Multiple tensors may share + * a single storage. A Storage is an impoverished, Tensor-like class + * which supports far less operations than Tensor. + * + * Avoid using this method if possible; try to use only Tensor APIs to perform + * operations. + */ + TENSORIMPL_MAYBE_VIRTUAL const Storage& storage() const { + if (C10_UNLIKELY(storage_access_should_throw_)) { + throw_storage_access_error(); + } + return storage_; + } + + /** + * Return the underlying storage, unsafely assuming this is a basic strided + * tensor. In cases where `storage` access would throw, this returns a + * default-constructed Storage. + */ + inline const Storage& unsafe_storage() const { + return storage_; + } + + bool unique_version() const { + return version_counter_.unique(); + } + + protected: + virtual Layout layout_impl() const { + TORCH_CHECK( + false, "layout_impl is only implemented for TensorImpl subclasses."); + } + + public: + // Whether a tensor is sparse COO or not. + bool is_sparse() const { + // NB: This method is not virtual and avoid dispatches for performance + // reasons. + return key_set_.has_all(c10::sparse_ks); + } + + // Whether a tensor is sparse CSR or not. + bool is_sparse_csr() const { + return layout() == kSparseCsr; + } + + // Whether a tensor is sparse CSR/CSC/BSR/BSC or not. + bool is_sparse_compressed() const { + return key_set_.has_all(c10::sparse_csr_ks); + } + + bool is_quantized() const { + // NB: This method is not virtual and avoid dispatches for performance + // reasons. + constexpr auto quantized_ks = DispatchKeySet(DispatchKey::Quantized); + return key_set_.has_all(quantized_ks); + } + + bool is_meta() const { + // NB: This method is not virtual and avoid dispatches for performance + // reasons. + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_meta(); + } + return device_opt_.has_value() && device_opt_->type() == kMeta; + } + + bool is_cpu() const { + // NB: This method is not virtual and avoid dispatches for performance + // reasons. + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_cpu(); + } + // Note: we cannot rely on dispatch keys to determine the device type + // of a tensor, because "wrapper" tensors (like FunctionalTensorWrapper) + // don't include backend dispatch keys. + return device_opt_.has_value() && device_opt_->type() == kCPU; + } + + bool is_cuda() const { + // NB: This method is not virtual and avoid dispatches for performance + // reasons. + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_cuda(); + } + return device_opt_.has_value() && device_opt_->type() == kCUDA; + } + + bool is_xpu() const { + // NB: This method is not virtual and avoid dispatches for performance + // reasons. + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_xpu(); + } + return device_opt_.has_value() && device_opt_->type() == kXPU; + } + + bool is_ipu() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_ipu(); + } + return device_opt_.has_value() && device_opt_->type() == kIPU; + } + + bool is_xla() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_xla(); + } + return device_opt_.has_value() && device_opt_->type() == kXLA; + } + + bool is_mtia() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_mtia(); + } + return device_opt_.has_value() && device_opt_->type() == kMTIA; + } + + bool is_hpu() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_hpu(); + } + return device_opt_.has_value() && device_opt_->type() == kHPU; + } + + bool is_lazy() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_lazy(); + } + return device_opt_.has_value() && device_opt_->type() == kLazy; + } + + bool is_hip() const { + // NB: This method is not virtual and avoid dispatches for performance + // reasons. + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_hip(); + } + return device_opt_.has_value() && device_opt_->type() == kHIP; + } + + bool is_ve() const { + // NB: This method is not virtual and avoid dispatches for performance + // reasons. + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_ve(); + } + return device_opt_.has_value() && device_opt_->type() == kVE; + } + + bool is_privateuseone() const { + // NB: This method is not virtual and avoid dispatches for performance + // reasons. + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_privateuseone(); + } + return device_opt_.has_value() && device_opt_->type() == kPrivateUse1; + } + + bool is_mkldnn() const { + return key_set_.has_all(c10::mkldnn_ks); + } + + bool is_vulkan() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_vulkan(); + } + return device_opt_.has_value() && device_opt_->type() == kVulkan; + } + + bool is_metal() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_metal(); + } + return device_opt_.has_value() && device_opt_->type() == kMetal; + } + + bool is_mps() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_mps(); + } + return device_opt_.has_value() && device_opt_->type() == kMPS; + } + + bool is_maia() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().is_maia(); + } + return device_opt_.has_value() && device_opt_->type() == kMAIA; + } + + bool is_nested() const { + return key_set_.has(DispatchKey::NestedTensor); + } + + // TODO: remove this once we don't automatically enabled Autograd dispatch + // keys + // in TensorImpl constructor. + // DON'T USE THIS API!! It's only created for testing purpose in + // file aten/src/ATen/core/boxing/impl/test_helpers.h + void remove_autograd_key() { + key_set_ = key_set_ - autograd_dispatch_keyset; + } + + // Inference tensor doesn't have autograd or ADInplaceOrView key. + // Invariant: + // Inference tensor has version_counter_.enabled() == false + bool is_inference() { + bool no_ADInplaceOrView = !key_set_.has_any(c10::inplace_or_view_ks); + bool no_Autograd = !key_set_.has_any(c10::autograd_dispatch_keyset); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + no_ADInplaceOrView == no_Autograd, + "ADInplaceOrView and Autograd keys must be on/off at the same time."); + return no_ADInplaceOrView && no_Autograd; + } + + DeviceIndex get_device() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom().index(); + } + return device_default().index(); + } + + Device device() const { + if (C10_UNLIKELY(device_policy_)) { + return device_custom(); + } + return device_default(); + } + + protected: + c10::Device device_default() const { + TORCH_CHECK(device_opt_.has_value(), "tensor does not have a device"); + // See NOTE [std::optional operator usage in CUDA] + return *device_opt_; + } + + public: + Layout layout() const { + if (C10_UNLIKELY(layout_policy_)) { + return layout_custom(); + } + + // NB: This method is not virtual and avoid dispatches for perf. + // strided is also the most common layout type, so we check for + // strided case first. + // This keyset must also be kept in sync with the logic in + // is_sparse() / is_sparse_csr() / is_mkldnn() + constexpr auto sparse_and_sparsecsr_and_mkldnn_ks = + c10::sparse_ks | c10::sparse_csr_ks | c10::mkldnn_ks; + if (!key_set_.has_any(sparse_and_sparsecsr_and_mkldnn_ks)) { + return kStrided; + } else if (is_sparse()) { + return kSparse; + } else if (is_sparse_compressed()) { + // Typically, the tensor dispatch keys define the tensor layout + // uniquely. This allows using non-virtual layout method for + // better performance. However, when tensor's layout depends, + // say, on tensor attributes, one must use this execution path + // where the corresponding tensor impl class overwrites virtual + // layout_impl() method. + // + // TODO: implement layout() as native function/method so that + // __torch_dispatch__ users will be able to redefine the + // layout() method. + return layout_impl(); + } else { + TORCH_INTERNAL_ASSERT( + is_mkldnn(), "There is an error in the layout calculation logic."); + return kMkldnn; + } + } + + /** + * True if a tensor was auto-wrapped from a C++ or Python number. + * For example, when you write 't + 2', 2 is auto-wrapped into a Tensor + * with `is_wrapped_number_` set to true. + * + * Wrapped numbers do not participate in the result type computation for + * mixed-type operations if there are any Tensors that are not wrapped + * numbers. This is useful, because we want 't + 2' to work with + * any type of tensor, not just LongTensor (which is what integers + * in Python represent). + * + * Otherwise, they behave like their non-wrapped equivalents. + * See [Result type computation] in TensorIterator.h. + * + * Why did we opt for wrapped numbers, as opposed to just having + * an extra function add(Tensor, Scalar)? This helps greatly reduce + * the amount of code we have to write for add, when actually + * a Tensor-Scalar addition is really just a Tensor-Tensor + * addition when the RHS is 0-dim (except for promotion behavior.) + */ + bool is_wrapped_number() const { + return is_wrapped_number_; + } + + /** + * Set whether or not a tensor was auto-wrapped from a C++ or Python + * number. You probably don't want to call this, unless you are + * writing binding code. + */ + void set_wrapped_number(bool value) { + TORCH_INTERNAL_ASSERT(dim() == 0); + is_wrapped_number_ = value; + } + + /** + * Returns true if Tensor supports as_strided and as_strided_backward. + * This is used in autograd to perform inplace update on view Tensors. + * See Note [View + Inplace update for base tensor] and + * [View + Inplace update for view tensor] for details. + * Note this method only returns true for XLA backend, where it + * simulates strided Tensor to support most view ops, but it cannot + * fully support general `as_strided` case. + * It can be expanded as needed in the future, e.g sparse Tensor. + */ + inline bool support_as_strided() const { + if (is_nested()) { + return false; + } + if (key_set_.has(DispatchKey::Functionalize)) { + return false; + } + return device().supports_as_strided(); + } + + // ~~~~~ Autograd API ~~~~~ + // Some methods below are defined in TensorImpl.cpp because Tensor is an + // incomplete type. + + /** + * Set whether or not a tensor requires gradient. + */ + void set_requires_grad(bool requires_grad); + + /** + * True if a tensor requires gradient. Tensors which require gradient + * have history tracked for any operations performed on them, so that + * we can automatically differentiate back to them. A tensor that + * requires gradient and has no history is a "leaf" tensor, which we + * accumulate gradients into. + */ + bool requires_grad() const; + + /** + * Return a mutable reference to the gradient. This is conventionally + * used as `t.grad() = x` to set a gradient to a completely new tensor. + */ + at::Tensor& mutable_grad(); + + /** + * Return the accumulated gradient of a tensor. This gradient is written + * into when performing backwards, when this tensor is a leaf tensor. + */ + const at::Tensor& grad() const; + + /** + * Whether or not the imaginary part of the tensor should be negated + */ + inline bool is_conj() const { + constexpr auto conjugate_ks = DispatchKeySet(DispatchKey::Conjugate); + return key_set_.has_all(conjugate_ks); + } + + /** + * Set whether or not to take the conjugate of the tensor (flip the imaginary + * bit). + */ + void _set_conj(bool value) { + if (value) { + key_set_ = key_set_.add(DispatchKey::Conjugate); + TORCH_INTERNAL_ASSERT(isComplexType(typeMetaToScalarType(dtype()))); + } else { + key_set_ = key_set_.remove(DispatchKey::Conjugate); + } + } + + /** + * XXX: do not use, private api! + * Update the backend component related keys to the backend component + * corresponding to this device. + */ + void _change_backend_component_keys(c10::Device device); + + /** + * Whether or not the tensor is a zerotensor + */ + inline bool _is_zerotensor() const { + constexpr auto zerotensor_ks = DispatchKeySet(DispatchKey::ZeroTensor); + return key_set_.has_all(zerotensor_ks); + } + + /** + Set whether or not the tensor is a zero tensor + */ + void _set_zero(bool value) { + if (value) { + TORCH_INTERNAL_ASSERT( + false, + "Please call `torch._efficientzerotensor` if you want to create a tensor with no storage."); + } else { + key_set_ = key_set_.remove(DispatchKey::ZeroTensor); + } + } + + /** + * Whether or not the tensor should be negated + */ + inline bool is_neg() const { + constexpr auto negative_ks = DispatchKeySet(DispatchKey::Negative); + return key_set_.has_all(negative_ks); + } + + /** + * Set whether or not to take the conjugate of the tensor (flip the imaginary + * bit). + */ + void _set_neg(bool value) { + if (value) { + key_set_ = key_set_.add(DispatchKey::Negative); + } else { + key_set_ = key_set_.remove(DispatchKey::Negative); + } + } + + /** + * Return the accumulated gradient of a tensor. This gradient is computed + * using forward mode AD. + * + * This is an internal API that should never be used by end users. + * + * The API is as follows: + * - "level" allows to specify the level of forward AD nesting for which the + * gradient should be returned. Note that since levels are not fully + * supported yet, this argument should be 0. See documentation for + * torch::autograd::enter_dual_level for more details about forward AD + * nesting. + * - "self" should represent the Tensor whose forward grad is accessed. It + * is required when dealing with view. + */ + const at::Tensor& _fw_grad(uint64_t level, const at::TensorBase& self) const; + + /** + * Sets the forward gradient for this Tensor. + * The given Tensor might not be used directly and its content will be copied. + * + * This is an internal API that should never be used by end users. + * + * The API is as follows: + * - "new_grad" is a Tensor containing the new value of the gradient that + * should be set + * - "self" should represent the Tensor whose forward grad is accessed. It + * is required when dealing with view. + * - "level" allows to specify the level of forward AD nesting for which the + * gradient should be set. Note that since levels are not fully supported + * yet, this argument should be 0. See documentation for + * torch::autograd::enter_dual_level for more details about forward AD + * nesting. + * - "is_inplace_op" is a boolean flag that tells if this gradient was + * generated by an inplace operation or an out of place one. This allows + * better error checking. + */ + void _set_fw_grad( + const at::TensorBase& new_grad, + const at::TensorBase& self, + uint64_t level, + bool is_inplace_op); + + /** + * Return a typed data pointer to the actual data which this tensor refers to. + * This checks that the requested type (from the template parameter) matches + * the internal type of the tensor. + * + * It is invalid to call data() on a dtype-uninitialized tensor, even if + * the size is 0. + * + * WARNING: If a tensor is not contiguous, you MUST use strides when + * performing index calculations to determine the location of elements in + * the tensor. We recommend using 'TensorAccessor' to handle this computation + * for you; this class is available from 'Tensor'. + */ + template + const T* data_dtype_initialized() const { + return data_dtype_initialized_impl( + [this] { return static_cast(storage_.data()); }); + } + + /** + * Return a mutable typed data pointer to the actual data which this + * tensor refers to. This checks that the requested type (from the + * template parameter) matches the internal type of the tensor. + * + * It is invalid to call data() on a dtype-uninitialized tensor, even if + * the size is 0. + * + * WARNING: If a tensor is not contiguous, you MUST use strides when + * performing index calculations to determine the location of elements in + * the tensor. We recommend using 'TensorAccessor' to handle this computation + * for you; this class is available from 'Tensor'. + */ + template + T* mutable_data_dtype_initialized() { + return data_dtype_initialized_impl( + [this] { return static_cast(storage_.mutable_data()); }); + } + + private: + // Shared implementation of data_dtype_initialized() and + // mutable_data_dtype_initialized(). + template + T* data_dtype_initialized_impl(const Func& get_data) const { + TORCH_CHECK( + data_type_.Match>(), + "Tensor type mismatch, caller expects elements to be ", + caffe2::TypeMeta::TypeName>(), + ", while tensor contains ", + data_type_.name(), + ". "); + return data_ptr_impl_impl(get_data); + } + + public: + /** + * More efficient helper for Tensor::data_ptr(). Like data(), but + * does not do a type check. Unlike the untemplated data(), does + * check has_storage() and storage_initialized(). + */ + template + inline const T* data_ptr_impl() const { + return data_ptr_impl_impl( + [this] { return static_cast(storage_.data()); }); + } + + /** + * More efficient helper for Tensor::data_ptr(). Like data(), but + * does not do a type check. Unlike the untemplated data(), does + * check has_storage() and storage_initialized(). + */ + template + inline T* mutable_data_ptr_impl() { + return data_ptr_impl_impl( + [this] { return static_cast(storage_.mutable_data()); }); + } + + private: + // Shared implementation of mutable_data_ptr_impl() and the future + // mutable_data_ptr_impl(). + template + __ubsan_ignore_pointer_overflow__ T* data_ptr_impl_impl( + const Func& get_data) const { + if (C10_UNLIKELY(!has_storage())) { + throw_data_ptr_access_error(); + } + TORCH_CHECK( + storage_initialized(), + "The tensor has a non-zero number of elements, but its data is not allocated yet.\n" + "If you're using torch.compile/export/fx, it is likely that we are erroneously " + "tracing into a custom kernel. To fix this, please wrap the custom kernel into " + "an opaque custom op. Please see the following for details: " + "https://pytorch.org/tutorials/advanced/custom_ops_landing_page.html\n" + "If you're using Caffe2, Caffe2 uses a lazy allocation, so you will need to call " + "mutable_data() or raw_mutable_data() to actually allocate memory."); + // Caller does the type check. + // Note: storage_offset_ can be non-null even for zero-elements tensors + // (for example if created as `torch.empty(5)[10:]`) that triggers + // applying non-zero offset to null pointer in UBSan + return get_data() + storage_offset_; + } + + public: + /** + * Return a const void* data pointer to the actual data which this + * tensor refers to. + * + * It is invalid to call data() on a dtype-uninitialized tensor, even if the + * size is 0. + * + * WARNING: The data pointed to by this tensor may not contiguous; do NOT + * assume that itemsize() * numel() is sufficient to compute the bytes that + * can be validly read from this tensor. + */ + inline const void* data() const { + return data_impl( + [this] { return static_cast(storage_.data()); }); + } + + /** + * Return a void* data pointer to the actual data which this tensor refers to. + * + * It is invalid to call mutable_data() on a dtype-uninitialized + * tensor, even if the size is 0. + * + * WARNING: The data pointed to by this tensor may not contiguous; do NOT + * assume that itemsize() * numel() is sufficient to compute the bytes that + * can be validly read from this tensor. + */ + inline void* mutable_data() { + return data_impl( + [this] { return static_cast(storage_.mutable_data()); }); + } + + private: + /// Shared implementation of data() and mutable_data(). + /// + /// get_data must return a byte-addressed pointer, e.g. char*, + /// std::byte const*, etc. + template + Void* data_impl(const Func& get_data) const { + if (C10_UNLIKELY(!has_storage())) { + throw_data_ptr_access_error(); + } + TORCH_CHECK( + dtype_initialized(), + "Cannot access data pointer of Tensor that doesn't have initialized dtype " + "(e.g., caffe2::Tensor x(CPU), prior to calling mutable_data() on x)"); + auto* data = get_data(); + static_assert( + sizeof(*data) == 1, "get_data must return a byte-addressed pointer."); + // Computing an offset into an empty tensor would be UB, since an empty + // tensor's storage will be nullptr, and adding a nonzero offset to nullptr + // is UB. So we skip the offset computation in this case. + if (is_empty()) { + return nullptr; + } + return data + data_type_.itemsize() * storage_offset_; + } + + public: + /** + * Returns the TypeMeta of a tensor, which describes what data type + * it is (e.g., int, float, ...) + */ + const caffe2::TypeMeta dtype() const { + return data_type_; + } + + /** + * Return the size of a single element of this tensor in bytes. + */ + size_t itemsize() const { + TORCH_CHECK( + dtype_initialized(), + "Cannot report itemsize of Tensor that doesn't have initialized dtype " + "(e.g., caffe2::Tensor x(CPU), prior to calling mutable_data() on x)"); + return data_type_.itemsize(); + } + + void set_backend_meta(intrusive_ptr backend_meta) { + get_extra_meta().backend_meta_ = std::move(backend_meta); + } + + c10::BackendMeta* get_backend_meta() { + if (!extra_meta_) { + return nullptr; + } + return extra_meta_->backend_meta_.get(); + } + + intrusive_ptr get_backend_meta_intrusive_ptr() const { + if (!extra_meta_) { + return nullptr; + } + return extra_meta_->backend_meta_; + } + + void release_storage_and_set_meta_custom_data_ptr_error_msg_( + std::optional s) { + storage_ = {}; + set_storage_access_should_throw(); + get_extra_meta().custom_data_ptr_error_msg_ = s; + get_extra_meta().custom_storage_error_msg_ = std::move(s); + } + + protected: + /** + * Returns the human-readable name of the actual type of this object (e.g., + * TensorImpl, BatchedTensorImpl, etc.). Used for error messages. + */ + virtual const char* tensorimpl_type_name() const { + return "TensorImpl"; + } + + private: + [[noreturn]] void throw_storage_access_error() const; + [[noreturn]] void throw_data_ptr_access_error() const; + + ExtraMeta& get_extra_meta() { + if (!extra_meta_) { + extra_meta_ = std::make_unique(); + } + return *extra_meta_; + } + + c10::SymbolicShapeMeta& symbolic_shape_meta() { + TORCH_INTERNAL_ASSERT(extra_meta_ && extra_meta_->symbolic_shape_meta_); + return *extra_meta_->symbolic_shape_meta_; + } + + const c10::SymbolicShapeMeta& symbolic_shape_meta() const { + TORCH_INTERNAL_ASSERT(extra_meta_ && extra_meta_->symbolic_shape_meta_); + return *extra_meta_->symbolic_shape_meta_; + } + + public: + /** + * True if a tensor has no elements (e.g., numel() == 0). + */ + inline bool is_empty() const { + return numel() == 0; + } + + // if we are going to use sym sizes, we should be setting sym strides at the + // same time, otherwise it's very easy to misuse this API + void set_sizes_and_strides( + c10::SymIntArrayRef sizes, + c10::SymIntArrayRef strides, + std::optional storage_offset = std::nullopt); + // This is renamed to avoid breaking overload BC + void generic_set_sizes_contiguous(c10::SymIntArrayRef sizes); + void generic_set_sizes_contiguous(c10::IntArrayRef sizes) { + set_sizes_contiguous(sizes); + } + + /** + * Change the size at some dimension. This DOES NOT update strides; + * thus, most changes to size will not preserve contiguity. You probably + * also want to call set_stride() when you call this. + * + * TODO: This should be jettisoned in favor of `set_sizes_and_strides`, + * which is harder to misuse. + */ + virtual void set_size(int64_t dim, int64_t new_size) { + TORCH_CHECK( + allow_tensor_metadata_change(), + "set_size ", + err_msg_tensor_metadata_change_not_allowed); + TORCH_CHECK( + !matches_policy(SizesStridesPolicy::CustomSizes), + "set_size() called on tensor with dynamic shapes or customized size behavior") + sizes_and_strides_.size_at(dim) = new_size; + refresh_numel(); + refresh_contiguous(); + } + + /** + * Change the stride at some dimension. + * + * TODO: This should be jettisoned in favor of `set_sizes_and_strides`, + * which is harder to misuse. + */ + virtual void set_stride(int64_t dim, int64_t new_stride) { + TORCH_CHECK( + allow_tensor_metadata_change(), + "set_stride ", + err_msg_tensor_metadata_change_not_allowed); + TORCH_CHECK( + !has_symbolic_sizes_strides_, + "set_stride() called on tensor with symbolic shape") + sizes_and_strides_.stride_at_unchecked(dim) = new_stride; + refresh_contiguous(); + } + + /** + * Set the offset into the storage of this tensor. + * + * WARNING: This does NOT check if the tensor is in bounds for the new + * location at the storage; the caller is responsible for checking this + * (and resizing if necessary.) + */ + virtual void set_storage_offset(int64_t storage_offset) { + TORCH_CHECK( + allow_tensor_metadata_change(), + "set_storage_offset ", + err_msg_tensor_metadata_change_not_allowed); + // TODO: this should probably consult policy + TORCH_CHECK( + !has_symbolic_sizes_strides_, + "set_storage_offset() called on tensor with symbolic shape") + storage_offset_ = storage_offset; + } + + /** + * Like set_sizes_and_strides but assumes contiguous strides. + * + * WARNING: This function does not check if the requested + * sizes/strides are in bounds for the storage that is allocated; + * this is the responsibility of the caller + */ + void set_sizes_contiguous(IntArrayRef new_size) { + TORCH_CHECK( + allow_tensor_metadata_change(), + "set_sizes_contiguous ", + err_msg_tensor_metadata_change_not_allowed); + TORCH_CHECK( + !matches_policy(SizesStridesPolicy::CustomStrides), + "tried to directly modify sizes for customized tensor"); + sizes_and_strides_.set_sizes(new_size); + + refresh_numel(); + empty_tensor_restride( + MemoryFormat::Contiguous); // calls refresh_contiguous() + } + + C10_ALWAYS_INLINE const impl::SizesAndStrides& sizes_and_strides() { + return sizes_and_strides_; + } + + /** + * Set the sizes and strides of a tensor. + * + * WARNING: This function does not check if the requested + * sizes/strides are in bounds for the storage that is allocated; + * this is the responsibility of the caller + */ + void set_sizes_and_strides( + IntArrayRef new_size, + IntArrayRef new_stride, + std::optional storage_offset = std::nullopt) { + TORCH_CHECK( + allow_tensor_metadata_change(), + "set_sizes_and_strides ", + err_msg_tensor_metadata_change_not_allowed); + TORCH_CHECK( + !has_symbolic_sizes_strides_, + "set_sizes_and_strides() called on tensor with symbolic shape") + TORCH_CHECK( + new_size.size() == new_stride.size(), + "dimensionality of sizes (", + new_size.size(), + ") must match dimensionality of strides (", + new_stride.size(), + ")"); + const auto new_dim = new_size.size(); + bool overflowed = false; + sizes_and_strides_.set_sizes(new_size); + + if (new_dim > 0) { + for (size_t dim = new_dim - 1;; dim--) { + if (new_stride[dim] >= 0) { + sizes_and_strides_.stride_at_unchecked(dim) = new_stride[dim]; + } else { + // XXX: This behavior is surprising and may need to be removed to + // support negative strides. Some pytorch functions rely on it: + // for example, torch.cat (run TestTorch.test_cat_empty). + if (dim == new_dim - 1) { + sizes_and_strides_.stride_at_unchecked(dim) = 1; + } else { + // Keep stride monotonically increasing to match NumPy. + overflowed |= c10::mul_overflows( + sizes_and_strides_.stride_at_unchecked(dim + 1), + std::max( + sizes_and_strides_.size_at_unchecked(dim + 1), 1), + std::addressof(sizes_and_strides_.stride_at_unchecked(dim))); + } + } + if (dim == 0) + break; + } + TORCH_CHECK(!overflowed, "Stride calculation overflowed"); + } + + refresh_numel(); + refresh_contiguous(); + + if (storage_offset.has_value()) { + storage_offset_ = *storage_offset; + } + } + + /** + * Set whether a tensor allows changes to its metadata (e.g. sizes / strides / + * storage / storage_offset). See NOTE [ Metadata Change for a Detached Tensor + * ] for details. + */ + void set_allow_tensor_metadata_change(bool value [[maybe_unused]]) { + // TODO: at some point, we should kill this field completely. + allow_tensor_metadata_change_ = true; + } + + /** + * True if a tensor allows changes to its metadata (e.g. sizes / strides / + * storage / storage_offset). See NOTE [ Metadata Change for a Detached Tensor + * ] for details. + */ + bool allow_tensor_metadata_change() const { + return allow_tensor_metadata_change_; + } + + /** + * Set the pointer to autograd metadata. + */ + void set_autograd_meta( + std::unique_ptr autograd_meta); + + /** + * Return the pointer to autograd metadata. May return nullptr if the + * tensor does not track gradients. + */ + c10::AutogradMetaInterface* autograd_meta() const; + + /** + * Set the pointer to named tensor metadata. + */ + void set_named_tensor_meta( + std::unique_ptr named_tensor_meta) { + TORCH_WARN_ONCE( + "Named tensors and all their associated APIs are an experimental feature ", + "and subject to change. Please do not use them for anything important ", + "until they are released as stable."); +#ifdef DEBUG + if (named_tensor_meta) { + TORCH_INTERNAL_ASSERT(named_tensor_meta->slow_dim() == dim()); + } +#endif + if (named_tensor_meta) { + get_extra_meta().named_tensor_meta_ = std::move(named_tensor_meta); + key_set_ = key_set_.add(DispatchKey::Named); + } else { + if (extra_meta_) { + extra_meta_->named_tensor_meta_ = nullptr; + } + key_set_ = key_set_.remove(DispatchKey::Named); + } + } + + void set_python_dispatch(bool k) { + if (k) { + key_set_ = key_set_.add(c10::python_ks); + } else { + key_set_ = key_set_ - c10::python_ks; + } + } + + bool is_python_dispatch() const { + return key_set_.has_all(c10::python_ks); + } + + /** + * Return the pointer to named tensor metadata. + */ + const c10::NamedTensorMetaInterface* named_tensor_meta() const { + if (!extra_meta_) { + return nullptr; + } + return extra_meta_->named_tensor_meta_.get(); + } + + c10::NamedTensorMetaInterface* named_tensor_meta() { + if (!extra_meta_) { + return nullptr; + } + return extra_meta_->named_tensor_meta_.get(); + } + + bool has_named_tensor_meta() const { + if (!extra_meta_) { + return false; + } + return extra_meta_->named_tensor_meta_ != nullptr; + } + + // NOTE [ TensorImpl Shallow-Copying ] + // + // TensorImpl shallow-copying is used when we want to have two Variables share + // the same tensor metadata (e.g. sizes / strides / storage pointer / + // storage_offset), but each with a different autograd history. Example call + // sites: + // + // 1. `var_detached = var.detach()` uses `shallow_copy_and_detach()` to create + // `var_detached` that shares the same tensor metadata with `var`, but with a + // completely new autograd history. + // 2. `var.set_data(tensor)` uses `shallow_copy_from()` to copy tensor + // metadata from `tensor` into `var`, while keeping `var`'s original + // AutogradMeta. + // + // Functions that shallow-copy a TensorImpl (such as + // `shallow_copy_and_detach()` / `shallow_copy_from()` / + // `copy_tensor_metadata()`) copy the tensor metadata fields (e.g. sizes / + // strides / storage pointer / storage_offset) by value. However, the + // following fields are not copied: + // + // 1. the AutogradMeta pointer, because it is unique for each Variable. + // 2. the version counter, because the destination TensorImpl's version + // counter is either set to the passed-in `version_counter` (in + // `shallow_copy_and_detach()` and `copy_tensor_metadata()`), or it is kept + // intact (in `shallow_copy_from()`). See NOTE [ Version Counter Sharing ] for + // details. + // + // In `shallow_copy_and_detach()` and `copy_tensor_metadata()`, the passed-in + // `allow_tensor_metadata_change` determines whether the TensorImpl + // shallow-copy allows changes to its metadata (e.g. sizes / strides / storage + // / storage_offset). See NOTE [ Metadata Change for a Detached Tensor ] for + // details. + // + // In `shallow_copy_from()`, we don't check the destination TensorImpl's + // `allow_tensor_metadata_change_`, because `shallow_copy_from()` is used for + // implementing functions such as `var.set_data(tensor)`, which changes + // `var`'s tensor metadata and expects its `allow_tensor_metadata_change_` to + // be ignored. + + /** + * One TensorImpl can be copied to another TensorImpl if + * - They have the same DispatchKeySet. + * - Or both have DispatchKey::Dense and a supported dense backend + * (CPU, CUDA, MPS, HIP, XPU, HPU, MTIA) + * - Or both have DispatchKey::Sparse and a supported sparse backend + * (CPU, CUDA, MPS, HIP, XPU) + * - Or both have DispatchKey::SparseCsr + * For PrivateUse1 backend, user can implement their own + * `_has_compatible_shallow_copy_type` operator. + * See OpenRegMinimal.cpp for an example of overriding this operator. + */ + inline bool has_compatible_shallow_copy_type(DispatchKeySet from) { + auto is_dense = [](DispatchKeySet ts) { + constexpr auto dense_backends = DispatchKeySet( + {BackendComponent::CPUBit, + BackendComponent::CUDABit, + BackendComponent::MPSBit, + BackendComponent::HIPBit, + BackendComponent::XPUBit, + BackendComponent::HPUBit, + BackendComponent::MTIABit}); + constexpr auto dense_k = DispatchKeySet(DispatchKey::Dense); + return ts.has_any(dense_k) && ts.has_any(dense_backends); + }; + auto is_sparse = [](DispatchKeySet ts) { + constexpr auto sparse_backends = DispatchKeySet( + {BackendComponent::CPUBit, + BackendComponent::CUDABit, + BackendComponent::MPSBit, + BackendComponent::HIPBit, + BackendComponent::XPUBit}); + constexpr auto sparse_k = DispatchKeySet(DispatchKey::Sparse); + return ts.has_any(sparse_k) && ts.has_any(sparse_backends); + }; + auto is_sparse_compressed = [](DispatchKeySet ts) { + constexpr auto sparse_compressed_k = + DispatchKeySet(DispatchKey::SparseCsr); + return ts.has_any(sparse_compressed_k); + }; + return (key_set_ == from) || (is_dense(key_set_) && is_dense(from)) || + (is_sparse(key_set_) && is_sparse(from)) || + (is_sparse_compressed(key_set_) && is_sparse_compressed(from)); + ; + } + + private: + template + c10::intrusive_ptr shallow_copy_and_detach_core( + VariableVersion&& version_counter, + bool allow_tensor_metadata_change) const; + + public: + /** + * Return a TensorImpl that is a shallow-copy of this TensorImpl. + * + * For usage of `version_counter` and `allow_tensor_metadata_change`, + * see NOTE [ TensorImpl Shallow-Copying ]. + */ + virtual c10::intrusive_ptr shallow_copy_and_detach( + const c10::VariableVersion& version_counter, + bool allow_tensor_metadata_change) const; + + /** + * Return a TensorImpl that is a shallow-copy of this TensorImpl. + * + * For usage of `version_counter` and `allow_tensor_metadata_change`, + * see NOTE [ TensorImpl Shallow-Copying ]. + */ + virtual c10::intrusive_ptr shallow_copy_and_detach( + c10::VariableVersion&& version_counter, + bool allow_tensor_metadata_change) const; + + /** + * Shallow-copies data from another TensorImpl into this TensorImpl. + * + * For why this function doesn't check this TensorImpl's + * `allow_tensor_metadata_change_`, see NOTE [ TensorImpl Shallow-Copying ]. + */ + virtual void shallow_copy_from(const c10::intrusive_ptr& impl) { + copy_tensor_metadata( + /*src_impl=*/impl.get(), + /*dest_impl=*/this, + /*version_counter=*/version_counter(), + /*allow_tensor_metadata_change=*/allow_tensor_metadata_change()); + } + + // Inference tensor doesn't have version counter, + // set_version_counter is no-op for them. + void set_version_counter(const c10::VariableVersion& version_counter) { + TORCH_CHECK( + !(is_inference() && version_counter.enabled()), + "Cannot set version_counter for inference tensor"); + version_counter_ = version_counter; + } + + void set_version_counter(c10::VariableVersion&& version_counter) { + TORCH_CHECK( + !(is_inference() && version_counter.enabled()), + "Cannot set version_counter for inference tensor"); + version_counter_ = std::move(version_counter); + } + + const c10::VariableVersion& version_counter() const noexcept { + return version_counter_; + } + + void bump_version() { + version_counter_.bump(); + } + + impl::PyObjectSlot* pyobj_slot() { + return &pyobj_slot_; + } + + const impl::PyObjectSlot* pyobj_slot() const { + return &pyobj_slot_; + } + + void incref_pyobject() const noexcept final; + + void decref_pyobject() const noexcept final; + + bool try_incref_pyobject() const noexcept final; + + private: + // See NOTE [std::optional operator usage in CUDA] + // We probably don't want to expose this publicly until + // the note is addressed. + std::optional device_opt() const { + return device_opt_; + } + + public: + /** + * The device type of a Tensor, e.g., DeviceType::CPU or DeviceType::CUDA. + */ + DeviceType device_type() const { + // TODO: A useful internal assert would be to show that device_opt_ is null + // only if you are an undefined tensor + TORCH_CHECK( + device_opt_.has_value(), + "device_type cannot be run on undefined Tensor"); + // See NOTE [std::optional operator usage in CUDA] + return (*device_opt_).type(); + } + + /** + * @brief Extends the outer-most dimension of this tensor by num elements, + * preserving the existing data. + * + * The underlying data may be reallocated in order to accommodate the new + * elements, in which case this tensors' capacity is grown at a factor of + * growthPct. This ensures that Extend runs on an amortized O(1) time + * complexity. + * + * This op is auto-asynchronous if the underlying device (CUDA) supports it. + */ + void Extend(int64_t num, float growthPct); + + /** + * @brief Reserve space for the underlying tensor. + * + * This must be called after Resize(), since we only specify the first + * dimension This does not copy over the old data to the newly allocated space + */ + void ReserveSpace(int64_t outer_dim); + + /** + * @brief Resizes a tensor. + * + * Resize takes in a vector of ints specifying the dimensions of the tensor. + * You can pass in an empty vector to specify that it is a scalar (i.e. + * containing one single item). + * + * The underlying storage may be deleted after calling Resize: if the new + * shape leads to a different number of items in the tensor, the old memory + * is deleted and new memory will be allocated next time you call + * mutable_data(). However, if the shape is different but the total number of + * items is the same, the underlying storage is kept. + * + * This method respects caffe2_keep_on_shrink. Consult the internal logic + * of this method to see exactly under what circumstances this flag matters. + */ + template + void Resize(Ts... dim_source) { + bool size_changed = SetDims(dim_source...); + if (size_changed) { + HandleResize(); + } + } + + template + void Resize(const std::vector& dim_source) { + Resize(ArrayRef(dim_source)); + } + + /** + * Resizes the tensor without touching underlying storage. + * This requires the total size of the tensor to remains constant. + */ + void Reshape(const std::vector& dims); + + /** + * Release whatever memory the tensor was holding but keep size and type + * information. Subsequent call to mutable_data will trigger new memory + * allocation. + */ + void FreeMemory(); + + /** + * @brief Shares the data with another tensor. + * + * To share data between two tensors, the sizes of the two tensors must be + * equal already. The reason we do not implicitly do a Resize to make the two + * tensors have the same shape is that we want to allow tensors of different + * shapes but the same number of items to still be able to share data. This + * allows one to e.g. have a n-dimensional Tensor and a flattened version + * sharing the same underlying storage. + * + * The source tensor should already have its data allocated. + */ + // To be deprecated + void ShareData(const TensorImpl& src); + + void ShareExternalPointer( + DataPtr&& data_ptr, + const caffe2::TypeMeta data_type, + size_t size_bytes); + + /** + * Returns a mutable raw pointer of the underlying storage. Since we will need + * to know the type of the data for allocation, a TypeMeta object is passed in + * to specify the necessary information. This is conceptually equivalent of + * calling mutable_data() where the TypeMeta parameter meta is derived from + * the type T. This function differs from mutable_data() in the sense that + * the type T can be specified during runtime via the TypeMeta object. + * + * If the existing data does not match the desired type, it will be deleted + * and a new storage will be created. + */ + inline void* raw_mutable_data(const caffe2::TypeMeta& meta) { + // For 0-size tensors it's fine to return any pointer (including nullptr) + if (data_type_ == meta && storage_initialized()) { + return static_cast( + static_cast(storage_.mutable_data()) + + storage_offset_ * meta.itemsize()); + } else { + bool had_special_dtor = data_type_.placementDelete() != nullptr; + storage_offset_ = 0; + data_type_ = meta; + // NB: device is not changed + + // We can reuse the existing buffer if the current data does not have + // a special destructor and the new data doesn't have a special + // constructor. + if (numel_ == 0 || + (meta.placementNew() == nullptr && !had_special_dtor && + (storage_.nbytes() >= (numel_ * data_type_.itemsize())))) { + TORCH_INTERNAL_ASSERT( + storage_offset_ == 0); // because we just reallocated + return storage_.mutable_data(); + } + Allocator* allocator = storage_.allocator(); + // Storage might have nullptr allocator in rare cases, for example, if + // an external memory segment has been wrapped with Tensor and we don't + // know how to reallocate it. However, in order to preserve legacy C2 + // behavior, we allow reallocating the memory using default allocator. + if (allocator == nullptr) { + allocator = GetAllocator(storage_.device_type()); + } + if (meta.placementNew()) { + // For types that need placement new, we will call it, as well as + // making sure that when the data is freed, it calls the right + // destruction procedure. + auto size = numel_; + auto dtor = data_type_.placementDelete(); + auto data_ptr = allocator->allocate(numel_ * data_type_.itemsize()); + storage_.set_data_ptr_noswap(PlacementDeleteContext::makeDataPtr( + std::move(data_ptr), dtor, size, storage_.device())); + data_type_.placementNew()(storage_.mutable_data(), numel_); + } else { + // For fundamental type, new and delete is easier. + storage_.set_data_ptr_noswap( + allocator->allocate(numel_ * data_type_.itemsize())); + } + storage_.set_nbytes(numel_ * data_type_.itemsize()); + TORCH_INTERNAL_ASSERT( + storage_offset_ == 0); // because we just reallocated + device_opt_ = storage_.device(); + return storage_.mutable_data(); + } + } + + /** + * Returns a typed pointer of the underlying storage. + * + * For fundamental types, we reuse possible existing storage if there + * is sufficient capacity. + */ + template + inline T* mutable_data() { + if (storage_initialized() && data_type_.Match()) { + return static_cast(storage_.mutable_data()) + storage_offset_; + } + // Check it here statically - otherwise TypeMeta would throw the runtime + // error in attempt to invoke TypeMeta::ctor() + static_assert( + std::is_default_constructible_v, + "Tensor can't hold non-default-constructable types"); + return static_cast(raw_mutable_data(caffe2::TypeMeta::Make())); + } + + /** + * True if a tensor is storage initialized. A tensor may become + * storage UNINITIALIZED after a Resize() or FreeMemory() + */ + bool storage_initialized() const { + TORCH_CHECK( + has_storage(), + "cannot call storage_initialized on tensor that does not have storage"); + return storage_.data() || numel_ == 0; + } + + /** + * True if a tensor is dtype initialized. A tensor allocated with + * Caffe2-style constructors is dtype uninitialized until the + * first time mutable_data() is called. + */ + bool dtype_initialized() const noexcept { + return data_type_ != caffe2::TypeMeta(); + } + + void set_storage_keep_dtype(at::Storage storage) { + TORCH_CHECK( + allow_tensor_metadata_change(), + "set_storage ", + err_msg_tensor_metadata_change_not_allowed); + storage_ = std::move(storage); + device_opt_ = storage_.device(); + } + + void set_storage_and_dtype( + at::Storage storage, + const caffe2::TypeMeta data_type) { + set_storage_keep_dtype(std::move(storage)); + data_type_ = data_type; + } + + void empty_tensor_restride_symint(MemoryFormat memory_format); + + /** + * Set the strides of the tensor to match memory_format + * + * WARNING: This function doesn't rearrange data and assumes tensor is a + * memory contiguous + */ + void empty_tensor_restride(MemoryFormat memory_format) { + if (has_symbolic_sizes_strides_) { + empty_tensor_restride_symint(memory_format); + return; + } +#ifdef DEBUG + TORCH_INTERNAL_ASSERT( + compute_numel() == numel_, + "If you are seeing this error, that means empty_tensor_restride was " + "called before setting correct numel"); +#endif + switch (memory_format) { + case MemoryFormat::Contiguous: { + // dim_ is a virtual call, don't repeat it + const auto dim_ = dim(); + sizes_and_strides_.resize(dim_); + if (dim_ > 0) { + bool overflowed = false; + const auto last_idx = dim_ - 1; + sizes_and_strides_.stride_at_unchecked(last_idx) = 1; + for (auto i = last_idx - 1; i >= 0; --i) { + overflowed |= c10::mul_overflows( + sizes_and_strides_.stride_at_unchecked(i + 1), + std::max( + sizes_and_strides_.size_at_unchecked(i + 1), 1), + std::addressof(sizes_and_strides_.stride_at_unchecked(i))); + } + TORCH_CHECK(!overflowed, "Stride calculation overflowed"); + } + break; + } + case MemoryFormat::ChannelsLast: { + TORCH_CHECK( + dim() == 4, "required rank 4 tensor to use channels_last format"); + set_sizes_and_strides(sizes(), get_channels_last_strides_2d(sizes())); + break; + } + case MemoryFormat::ChannelsLast3d: { + TORCH_CHECK( + dim() == 5, + "required rank 5 tensor to use channels_last_3d format"); + set_sizes_and_strides(sizes(), get_channels_last_strides_3d(sizes())); + break; + } + case MemoryFormat::Preserve: + TORCH_CHECK(false, "unsupported memory format ", memory_format); + // Cleaning warning messages, no need to break as TORCH_CHECK(false) + // terminates flow. + // break; + case MemoryFormat::NumOptions: + TORCH_INTERNAL_ASSERT(false, "invalid memory format ", memory_format); + } + // recompute contiguous flag, as currently NHWC/NCHW flags are not mutually + // exclusive see #24090 + refresh_contiguous(); + } + + bool is_strides_like(at::MemoryFormat memory_format) const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomStrides))) { + return is_strides_like_custom(memory_format); + } + return is_strides_like_default(memory_format); + } + + bool is_strides_like_channels_last() const { + return is_strides_like(at::MemoryFormat::ChannelsLast); + } + + bool is_strides_like_channels_last_3d() const { + return is_strides_like(at::MemoryFormat::ChannelsLast3d); + } + + bool is_non_overlapping_and_dense_or_false() const { + return sym_is_non_overlapping_and_dense().guard_or_false( + __FILE__, __LINE__); + } + + bool is_non_overlapping_and_dense() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomStrides))) { + return is_non_overlapping_and_dense_custom(); + } + return is_non_overlapping_and_dense_default(); + } + + SymBool sym_is_non_overlapping_and_dense() const { + if (C10_UNLIKELY(matches_policy(SizesStridesPolicy::CustomStrides))) { + return sym_is_non_overlapping_and_dense_custom(); + } + return sym_is_non_overlapping_and_dense_default(); + } + + // if this returns true, then it is guaranteed that this tensor has symbolic + // sizes/strides + bool has_symbolic_sizes_strides() const { + return has_symbolic_sizes_strides_; + } + + private: + void HandleResize(); + + // The Caffe2 Resize() method supports being called both as Resize({2,2}) as + // well as variadic with Resize(2, 2). These overloads provide all of the + // supported calling configurations, while being overloads (and not templates) + // so that implicit conversions still work. + // + // SetDims on ArrayRef is internally implemented as a template, so we can + // handle both ArrayRefs of different types (there are some uses of + // Resize in Caffe2 which pass in int, not int64_t.) + + template < + typename T, + typename = typename std::enable_if_t>> + bool SetDimsTemplate(ArrayRef src) { + TORCH_CHECK( + !has_symbolic_sizes_strides_, + "SetDims() called on tensor with symbolic shape") + + auto old_numel = numel_; + sizes_and_strides_.resize(src.size()); + int64_t new_numel = 1; + for (const auto i : c10::irange(src.size())) { + new_numel *= src[i]; + sizes_and_strides_.size_at_unchecked(i) = src[i]; + } + numel_ = new_numel; + empty_tensor_restride(MemoryFormat::Contiguous); + return numel_ != old_numel; + } + + bool SetDims(ArrayRef s) { + return SetDimsTemplate(s); + } + + bool SetDims(ArrayRef s) { + return SetDimsTemplate(s); + } + + bool SetDims(ArrayRef s) { + return SetDimsTemplate(s); + } + + bool SetDims() { + return SetDims(IntArrayRef{}); + } + + bool SetDims(const int64_t d0) { + return SetDims(IntArrayRef{d0}); + } + + bool SetDims(const int64_t d0, const int64_t d1) { + return SetDims(IntArrayRef{d0, d1}); + } + + bool SetDims(const int64_t d0, const int64_t d1, const int64_t d2) { + return SetDims(IntArrayRef{d0, d1, d2}); + } + + bool SetDims( + const int64_t d0, + const int64_t d1, + const int64_t d2, + const int64_t d3) { + return SetDims(IntArrayRef{d0, d1, d2, d3}); + } + + /** + * Compute the number of elements based on the sizes of a tensor. + */ + // NB: This is ONLY called when sizes_and_strides_ is used directly; if + // we are virtualizing, then numel calls are virtualized as well, and this + // should never get called + int64_t compute_numel() const { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(!has_symbolic_sizes_strides_); +#if C10_HAS_BUILTIN_OVERFLOW() && !defined(C10_MOBILE) + // Use overflow checks if supported by the compiler + return safe_compute_numel(); +#else + return c10::multiply_integers(sizes_and_strides_.sizes_arrayref()); +#endif + } + + /** + * Compute the number of elements based on the sizes of a + * tensor. Catches integer overflow that may occur when a tensor + * using a sparse layout has multiple dimensions with large sizes. + */ + int64_t safe_compute_numel() const { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(!has_symbolic_sizes_strides_); + uint64_t n = 1; + bool overflows = + c10::safe_multiplies_u64(sizes_and_strides_.sizes_arrayref(), &n); + constexpr auto numel_max = std::min( + static_cast(std::numeric_limits::max()), + static_cast(std::numeric_limits::max())); + + overflows |= (n > numel_max); + TORCH_CHECK(!overflows, "numel: integer multiplication overflow"); + return static_cast(n); + } + + /** + * Compute whether or not a tensor is contiguous based on the sizes and + * strides of a tensor. + */ + bool compute_contiguous() const; + + bool compute_channels_last_contiguous_2d() const; + + bool compute_channels_last_contiguous_3d() const; + + bool compute_strides_like_channels_last_2d() const; + + bool compute_strides_like_channels_last_3d() const; + + bool compute_non_overlapping_and_dense() const; + + protected: + /** + * Recompute the cached numel of a tensor. Call this if you modify + * sizes. + * + * For tensors with sparse layouts, use safe_refresh_numel() instead + * because it will catch integer overflow that may occur for tensors + * with sparse layouts and large dimensions. + * + * NB: We may uselessly recompute cached numel even in situations where + * it is completely never used (e.g., if CustomSizes for Python). However, + * we still must keep it up to date in case the Python overload + * returns None (in which case we will consult the field here). This also + * implies that sizes/strides will never be complete garbage; in the + * very worst case scenario, it will reflect a 1-dim zero size tensor. + */ + void refresh_numel() { + if (has_symbolic_sizes_strides_) { + symbolic_shape_meta().refresh_numel(); + } else { + numel_ = compute_numel(); + } + } + + /** + * Recompute the cached numel of a tensor. Call this if you modify + * sizes. Use only for tensors with sparse layouts because only + * sparse tensor are likely to have sizes that may lead to integer + * overflow when computing numel. + */ + void safe_refresh_numel() { + if (has_symbolic_sizes_strides_) { + // NB: sym numel is done with symbolic integers, which handle overflow + // checking + symbolic_shape_meta().refresh_numel(); + } else { + numel_ = safe_compute_numel(); + } + } + + private: + void _set_is_contiguous(bool b) { + is_contiguous_ = b; + } + + void _set_is_channels_last_contiguous(bool b) { + is_channels_last_contiguous_ = b; + } + + void _set_is_channels_last_3d_contiguous(bool b) { + is_channels_last_3d_contiguous_ = b; + } + + void _set_is_channels_last(bool b) { + is_channels_last_ = b; + } + + void _set_is_channels_last_3d(bool b) { + is_channels_last_3d_ = b; + } + + void _set_is_non_overlapping_and_dense(bool b) { + is_non_overlapping_and_dense_ = b; + } + + // These are little wrappers over the real compute_ functions that + // can make use of other contiguity fields to short circuit. + + bool compute_is_non_overlapping_and_dense_dim4() { + return is_contiguous_ || is_channels_last_contiguous_ || + compute_non_overlapping_and_dense(); + } + + bool compute_channels_last_contiguous_3d_dim5() { + return !is_channels_last_contiguous_ && + compute_channels_last_contiguous_3d(); + } + + bool compute_channels_last_2d_dim5() { + return !is_channels_last_3d_contiguous_ && + compute_strides_like_channels_last_2d(); + } + + bool compute_channels_last_3d_dim5() { + return !is_channels_last_ && compute_strides_like_channels_last_3d(); + } + + bool compute_is_non_overlapping_and_dense_dim5() { + return is_contiguous_ || is_channels_last_contiguous_ || + is_channels_last_3d_contiguous_ || compute_non_overlapping_and_dense(); + } + + bool compute_is_non_overlapping_and_dense_anydim() { + return is_contiguous_ || compute_non_overlapping_and_dense(); + } + + void _refresh_contiguous() { + // Note: + // Dim 0, 1, 2 will never be a channels last 2d/3d format + // Dim 3+ is possibly be a channels last 2d format (Dim 4 only at this + // point) Dim 4+ is possibly be a channels last 3d format (Dim 5 only at + // this point) + switch (dim()) { + case 4: { + _set_is_contiguous(compute_contiguous()); + _set_is_channels_last_contiguous(compute_channels_last_contiguous_2d()); + _set_is_channels_last_3d_contiguous(false); + _set_is_channels_last(compute_strides_like_channels_last_2d()); + _set_is_channels_last_3d(false); + _set_is_non_overlapping_and_dense( + compute_is_non_overlapping_and_dense_dim4()); + break; + } + case 5: { + _set_is_contiguous(compute_contiguous()); + _set_is_channels_last_contiguous(compute_channels_last_contiguous_2d()); + _set_is_channels_last_3d_contiguous( + compute_channels_last_contiguous_3d_dim5()); + _set_is_channels_last(compute_channels_last_2d_dim5()); + _set_is_channels_last_3d(compute_channels_last_3d_dim5()); + _set_is_non_overlapping_and_dense( + compute_is_non_overlapping_and_dense_dim5()); + break; + } + default: + // is_channels_last_ and is_channels_last_3d_ are suggested + // memory_format. Being channels_last_contiguous doesn't necessarily + // mean the tensor is strided like channels_last: for strides on channel + // dimension could suggest desired memory_layout, but it doesn't affect + // memory storage + _set_is_contiguous(compute_contiguous()); + _set_is_channels_last_contiguous(false); + _set_is_channels_last_3d_contiguous(false); + _set_is_channels_last(false); + _set_is_channels_last_3d(false); + _set_is_non_overlapping_and_dense( + compute_is_non_overlapping_and_dense_anydim()); + break; + } + } + + protected: + /** + * Recompute the cached contiguity of a tensor. Call this if you modify sizes + * or strides. + */ + void refresh_contiguous() { + if (has_symbolic_sizes_strides_) { + symbolic_shape_meta().refresh_contiguous(); + } else { + _refresh_contiguous(); + } + } + + /** + * Copy the tensor metadata fields (e.g. sizes / strides / storage pointer / + * storage_offset) from one TensorImpl to another TensorImpl. + * + * For usage of `version_counter` and `allow_tensor_metadata_change`, see NOTE + * [ TensorImpl Shallow-Copying ]. + */ + static void copy_tensor_metadata( + const TensorImpl* src_impl, + TensorImpl* dest_impl, + const c10::VariableVersion& version_counter, + bool allow_tensor_metadata_change); + + /** + * Copy the tensor metadata fields (e.g. sizes / strides / storage pointer / + * storage_offset) from one TensorImpl to another TensorImpl. + * + * For usage of `version_counter` and `allow_tensor_metadata_change`, see NOTE + * [ TensorImpl Shallow-Copying ]. + */ + static void copy_tensor_metadata( + const TensorImpl* src_impl, + TensorImpl* dest_impl, + c10::VariableVersion&& version_counter, + bool allow_tensor_metadata_change); + + private: + static void copy_tensor_metadata_except_version_counter( + const TensorImpl* src_impl, + TensorImpl* dest_impl, + bool allow_tensor_metadata_change); + + protected: + // Error message to show when the user tries to change tensor metadata on + // Tensor created from .data or .detach(). + // + // See NOTE [ Metadata Change for a Detached Tensor ] for details. + static const char* const err_msg_tensor_metadata_change_not_allowed; + + static void copy_generic_tensor_metadata( + const TensorImpl* src_impl, + TensorImpl* dest_impl); + + public: + void set_storage_access_should_throw() { + storage_access_should_throw_ = true; + } + + public: + void set_custom_sizes_strides(SizesStridesPolicy policy) { + custom_sizes_strides_ = static_cast(policy); + refresh_sizes_strides_policy(); + } + + void set_python_custom_sizes_strides(SizesStridesPolicy policy) { + python_custom_sizes_strides_ = static_cast(policy); + refresh_sizes_strides_policy(); + } + + void set_custom_device(bool custom_device) { + custom_device_ = custom_device; + refresh_device_policy(); + } + + void set_custom_layout(bool custom_layout) { + custom_layout_ = custom_layout; + refresh_layout_policy(); + } + + void set_python_custom_device(bool custom_device) { + python_custom_device_ = custom_device; + refresh_device_policy(); + } + + void set_python_custom_layout(bool custom_layout) { + python_custom_layout_ = custom_layout; + refresh_layout_policy(); + } + + protected: + void refresh_sizes_strides_policy() { + if (has_symbolic_sizes_strides_) { + sizes_strides_policy_ = + static_cast(SizesStridesPolicy::CustomSizes); + } else { + sizes_strides_policy_ = + std::max(custom_sizes_strides_, python_custom_sizes_strides_); + } + } + + void refresh_device_policy() { + device_policy_ = custom_device_ || python_custom_device_; + } + + void refresh_layout_policy() { + layout_policy_ = custom_layout_ || python_custom_layout_; + } + + protected: + Storage storage_; + + private: + // This pointer points to an AutogradMeta struct that stores autograd-specific + // fields (such as grad_ / grad_fn_ / grad_accumulator_). This pointer always + // has unique ownership (meaning only one TensorImpl can own it at a time). + // + // autograd_meta_ can be nullptr, as an optimization. When this occurs, it is + // equivalent to having an autograd_meta_ pointing to a default constructed + // AutogradMeta; intuitively, tensors which don't require grad will have this + // field set to null. + // + // This means accessors on autograd_meta_ have to be careful to test if they + // got a nullptr, and handle default behavior appropriately in that case. + // + // Note that we don't enforce the invariant that if the AutogradMeta is + // default constructed, it is nullptr (to do this, we'd have to continuously + // check if an AutogradMeta became, by mutation, equal to the default + // constructed form. (This might be useful, but it seems rare enough that + // a requires_grad=True variable will turn back into the requires_grad=False + // version.) So there are three representable states: + // + // 1. autograd_meta_ == nullptr + // 2. autograd_meta_ is default constructed (semantically, same as (1)) + // 3. autograd_meta_ has nontrivial information content + // + std::unique_ptr autograd_meta_ = nullptr; + + protected: + std::unique_ptr extra_meta_ = nullptr; + + c10::VariableVersion version_counter_; + + impl::PyObjectSlot pyobj_slot_; + + c10::impl::SizesAndStrides sizes_and_strides_; + + int64_t storage_offset_ = 0; + // If sizes and strides are empty, the numel is 1!! However, most of the + // time, we will immediately set sizes to {0} and reset numel to 0. + // (Can't do that in the default initializers, because there's no way to + // spell "allocate a one-element array" for strides_). + int64_t numel_ = 1; + + // INVARIANT: When storage is non-null, this type meta must + // agree with the type meta in storage + caffe2::TypeMeta data_type_; + + // NOTE [std::optional operator usage in CUDA] + // Our optional definition doesn't compile in .cu file if `value()` or + // `operator->` are used. Instead, we always use `operator*`. + // See https://github.com/pytorch/pytorch/issues/18496 for more info. + // If this is too burdensome to maintain, we can just + // manually implement this with an additional bool. + + // INVARIANT: When storage is non-null, this Device must + // agree with the type meta in storage. + // + // INVARIANT: device_opt_ is only nullopt for undefined tensors + // (which do not have a device.) + std::optional device_opt_; + + // default member initializers for bit-fields only available with -std=c++2a + // or -std=gnu++2a + inline void init_bitfields() { + is_contiguous_ = true; + is_channels_last_ = false; + is_channels_last_contiguous_ = false; + is_channels_last_3d_ = false; + is_channels_last_3d_contiguous_ = false; + is_non_overlapping_and_dense_ = true; + is_wrapped_number_ = false; + allow_tensor_metadata_change_ = true; + reserved_ = false; + sizes_strides_policy_ = static_cast(SizesStridesPolicy::Default); + custom_sizes_strides_ = static_cast(SizesStridesPolicy::Default); + python_custom_sizes_strides_ = + static_cast(SizesStridesPolicy::Default); + python_custom_device_ = false; + python_custom_layout_ = false; + custom_device_ = false; + custom_layout_ = false; + device_policy_ = false; + layout_policy_ = false; + storage_access_should_throw_ = false; + has_symbolic_sizes_strides_ = false; + } + + // Tensor is contiguous + bool is_contiguous_ : 1; + + // Tensor is a subclass that does not permit storage access. + bool storage_access_should_throw_ : 1; + + // Tensor is stored in the channels last 2d memory format, when dimensions + // order is (N)CHW and C-strides < W-strides < H-strides (< N-strides) + // (If size of any dimension is equal to 1, this dimension strides value + // is not taken into account). + bool is_channels_last_ : 1; + + // Channels last contiguous tensor is channel last tensor which occupies + // contiguous memory block. + bool is_channels_last_contiguous_ : 1; + + // Tensor is stored in the channels last 3d memory format, when dimensions + // order is (N)CDHW and C-strides < W-strides < H-strides < D - strides (< + // N-strides) (If size of any dimension is equal to 1, this dimension strides + // value is not taken into account). + bool is_channels_last_3d_ : 1; + + // Channels last 3d contiguous tensor is channel last 3d tensor which occupies + // contiguous memory block. + bool is_channels_last_3d_contiguous_ : 1; + + // Dense tensor is the tensor that store values in a contiguous block of + // memory. Non-overlapping tensor is the tensor in which elements occupy + // individual non-repetitive memory. + bool is_non_overlapping_and_dense_ : 1; + + bool is_wrapped_number_ : 1; + + // NOTE [ Metadata Change for a Detached Tensor ] + // + // Normally, a user is allowed to change the tensor metadata + // (e.g. sizes / strides / storage / storage_offset) of a tensor. + // However, if the tensor is created by `t1_detached = t1.data` in Python + // or `t1_detached = t1.detach()` in Python/C++, those changes to the + // tensor metadata of `t1_detached` will not be propagated back to the + // original tensor `t1`. In order to make such changes explicitly illegal, + // we created the `allow_tensor_metadata_change_` flag, to prevent users + // from changing metadata of the detached tensor and expecting the original + // tensor to also be updated. + // + // NOTE: For a full list of tensor metadata fields, please see + // `copy_tensor_metadata()` in TensorImpl and its subclasses to find + // which fields are copied by value. + bool allow_tensor_metadata_change_ : 1; + + // we decide to keep reserved_ and it will + // live in Tensor after the split + // The logic is that if Extend() or ReserveSpace() were ever called, + // then subsequent Resize()s will not free up Storage. + bool reserved_ : 1; + + // Call _custom() virtual methods for + // strides()/is_contiguous()/sizes()/dim()/numel() + // This is a combination of sizes_strides_custom_dispatch_ + // and has_symbolic_sizes_strides_ + uint8_t sizes_strides_policy_ : 2; + + // Whether or not sizes_and_strides_ contains a symbolic value. + bool has_symbolic_sizes_strides_ : 1; + + // Call _custom() virtual method for + // strides()/is_contiguous()/sizes()/dim()/numel() + uint8_t custom_sizes_strides_ : 2; + + // Combo of custom_ and python_custom_ + bool device_policy_ : 1; + bool layout_policy_ : 1; + + // Call _custom() virtual method for device() + bool custom_device_ : 1; + + // Call _custom() virtual method for layout() + bool custom_layout_ : 1; + + // Call into Python for + // strides()/is_contiguous()/sizes()/dim()/numel() + uint8_t python_custom_sizes_strides_ : 2; + + // Call into Python for device() + bool python_custom_device_ : 1; + + // Call into Python for layout() + bool python_custom_layout_ : 1; + + // The set of DispatchKeys which describe this tensor. NB: this + // does NOT include Autograd (historically, it did, but + // not anymore!) + // + // INVARIANT: extra_meta_->named_tensor_meta_ != nullptr <==> + // key_set_.has(DispatchKey::Named) + DispatchKeySet key_set_; + + private: + // C10_TensorImpl_Size_Check_Dummy_Class needs to be friends with + // TensorImpl so it can inspect the size of private fields + template < + size_t cplusplus, + size_t clang_ver_major, + size_t gcc_ver, + size_t gcc_ver_minor, + size_t nvcc, + size_t cuda_version, + size_t cuda_version_major, + size_t ptr_size> + friend class C10_TensorImpl_Size_Check_Dummy_Class; +}; + +namespace detail { + +#ifndef C10_MOBILE +template +struct TargetTraits< + T, + std::enable_if_t>>> { + static constexpr bool can_have_pyobject = true; +}; +#endif + +} // namespace detail + +// Note [TensorImpl size constraints] +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Changed the size of TensorImpl? If the size went down, good for +// you! Adjust the documentation below and the expected size. +// Did it go up? Read on... +// +// Struct size matters. In some production systems at Facebook, we have +// 400M live tensors during a training run. Do the math: every 64-bit +// word you add to Tensor is an extra 3.2 gigabytes in RAM. +// +// If you are a Facebook employee, you can check if the run in question +// has tipped you over the point using the command here: +// https://fburl.com/q5enpv98 +// +// For reference, we OOMed at 160 bytes (20 words) per TensorImpl. +// This is not counting overhead from strides out-of-line allocation and +// StorageImpl space and this is from before we inlined sizes and strides +// directly into TensorImpl as SmallVectors. +// +// Our memory usage on 32-bit systems is suboptimal, but we're not checking +// for it at the moment (to help avoid rage inducing cycles when the +// 32-bit number is wrong). +// +// Current breakdown: +// +// vtable pointer +// strong refcount TODO: pack these into one word +// weak refcount +// storage pointer +// autograd metadata pointer +// named tensor metadata pointer +// version counter pointer +// PyObjectSlot +// SizesAndStrides size/pointer +// SizesAndStrides sizes (pre-allocated 0) +// SizesAndStrides sizes (pre-allocated 1) +// SizesAndStrides sizes (pre-allocated 2) +// SizesAndStrides sizes (pre-allocated 3) +// SizesAndStrides sizes (pre-allocated 4) +// SizesAndStrides strides (pre-allocated 0) +// SizesAndStrides strides (pre-allocated 1) +// SizesAndStrides strides (pre-allocated 2) +// SizesAndStrides strides (pre-allocated 3) +// SizesAndStrides strides (pre-allocated 4) +// storage offset +// numel +// data type, device, is_contiguous, storage_access_should_throw_, bitfields +// DispatchKeySet +// + +// Various preprocessor macros we use to check that the +// TensorImpl size hasn't changed unexpectedly. We undef +// these later. +#ifndef __NVCC__ +#define C10_NVCC 0 +#else +#define C10_NVCC __NVCC__ +#endif + +#ifndef __CUDA_VER_MAJOR__ +#define C10_CUDA_VERSION_MAJOR 0 +#else +#define C10_CUDA_VERSION_MAJOR __CUDA_VER_MAJOR__ +#endif + +#ifndef CUDA_VERSION +#define C10_CUDA_VERSION 0 +#else +#define C10_CUDA_VERSION CUDA_VERSION +#endif + +#ifndef __clang_major__ +#define C10_CLANG_MAJOR_VERSION 0 +#else +#define C10_CLANG_MAJOR_VERSION __clang_major__ +#endif + +#ifndef __GNUC__ +#define C10_GCC_VERSION 0 +#else +#define C10_GCC_VERSION __GNUC__ +#endif + +#ifndef __GNUC_MINOR__ +#define C10_GCC_VERSION_MINOR 0 +#else +#define C10_GCC_VERSION_MINOR __GNUC_MINOR__ +#endif + +// We use a templatized class to both contain the logic of checking the sizes +// as well as to provide compile-time information that might be useful in +// figuring out why sizes may have changed. +// All the compile time information is given by the template fields that are +// always printed by the compiler when the static_assert fails. +template < + size_t cplusplus = __cplusplus, + size_t clang_ver_major = C10_CLANG_MAJOR_VERSION, + size_t gcc_ver = C10_GCC_VERSION, + size_t gcc_ver_minor = C10_GCC_VERSION_MINOR, + size_t nvcc = C10_NVCC, + size_t cuda_version = C10_CUDA_VERSION, + size_t cuda_version_major = C10_CUDA_VERSION_MAJOR, + size_t ptr_size = sizeof(void*)> +class C10_TensorImpl_Size_Check_Dummy_Class : private TensorImpl { + // Names of (non-bitfield) fields in TensorImpl; used to provide + // compile-time info about fields whose size changes unexpectedly. + enum class FieldNameEnum { + storage_, + autograd_meta_, + extra_meta_, + version_counter_, + pyobj_slot_, + sizes_and_strides_, + storage_offset_, + numel_, + data_type_, + device_opt_, + key_set_, + TOTAL_SIZE + }; + + // Provides compile-time equality check that reveals what numbers + // were used and on which quantity + template + constexpr static bool are_equal() { + static_assert( + Actual == Expected, + "Actual and Expected sizes of a field did not match!"); + return true; + } + + // Provides compile-time <= check that reveals what numbers + // were used and on which quantity + template + constexpr static bool is_le() { + static_assert( + Actual <= Expected, + "Actual and Expected sizes of a field did not match!"); + return true; + } + + public: + // Compile-time check that TensorImpl field sizes are as expected + // + // Observed total sizes and associated versions + // If you find a flag that predicts when unique_ptr has 16 bytes + // on 64-bit systems or when sizes_and_strides_ is 84 vs 88 bytes + // on 32-bit systems you get a cookie! + // Length | LLVM | GCC | C++ | CUDA + // 192 | ? | 11.2 | 201703 | 11040 + // 208 | ? | 11.2 | 201703 | 11040 + // 208 | ? | 11.2 | 201402 | 11040 + // 192 | ? | 11.2 | 201402 | 11040 + // 160 | 12 | 4.2 | 201703 | 0 + // + // To keep things clean, we split on systems here. + +#if UINTPTR_MAX == 0xFFFFFFFF + // This is a 32-bit system + static constexpr bool check_sizes() { + constexpr size_t tsize = 20 * sizeof(int64_t); + + // clang-format off + are_equal(); + are_equal(); + are_equal(); + are_equal(); + are_equal(); + is_le(); + are_equal(); + are_equal(); + are_equal(); + are_equal(); + are_equal(); + is_le(); + // clang-format on + + return true; + } +#else + // This is a 64-bit system + static constexpr bool check_sizes() { + constexpr size_t tsize = 26 * sizeof(int64_t); + + // clang-format off + are_equal(); + // On some systems involving NVCC the size of unique_ptr is 16 bytes. We haven't + // figured out how to detect those via macro preprocessors yet, so we use <= + // comparisons for the relevant fields. + is_le(); + is_le(); + are_equal(); + are_equal(); + are_equal(); + are_equal(); + are_equal(); + are_equal(); + are_equal(); + are_equal(); + is_le(); + // clang-format on + + return true; + } +#endif +}; + +// We use a class to encapsulate size-checking logic with +// templates to capture sizes and flags. We call this within +// a static assert to prove there is no run-time behaviour. +// Since the methods we call return either true or fail their +// own static_asserts, we should never see the error messages +// below. We have to provide it though for c++ <17. +static_assert( + C10_TensorImpl_Size_Check_Dummy_Class<>::check_sizes(), + "You should not see this message."); + +// Clean up after ourselves +#undef C10_NVCC +#undef C10_CUDA_VERSION_MAJOR +#undef C10_CUDA_VERSION +#undef C10_CLANG_MAJOR_VERSION +#undef C10_GCC_VERSION +#undef C10_GCC_VERSION_MINOR + +} // namespace c10 + +C10_DIAGNOSTIC_POP() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/TensorOptions.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/TensorOptions.h new file mode 100644 index 0000000000000000000000000000000000000000..7add8edc4361ab3c38675d8565ad13b4d1ed48b3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/TensorOptions.h @@ -0,0 +1,791 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wswitch-enum") + +namespace c10 { + +inline ScalarType dtype_or_default(std::optional dtype) { + return dtype.value_or(get_default_dtype_as_scalartype()); +} + +inline caffe2::TypeMeta dtype_or_default( + std::optional dtype) { + return dtype.value_or(get_default_dtype()); +} + +inline Layout layout_or_default(std::optional layout) { + return layout.value_or(kStrided); +} + +inline Device device_or_default(std::optional device) { + return device.value_or(Device(kCPU)); +} + +inline bool pinned_memory_or_default(std::optional pinned_memory) { + return pinned_memory.value_or(false); +} + +/// A class to encapsulate construction axes of an Tensor. TensorOptions was +/// designed to support the Python style API for specifying construction options +/// on factory functions, e.g., +/// +/// torch.zeros(2, 3, dtype=torch.int32) +/// +/// Because C++ doesn't natively support keyword arguments, there must be +/// another way of specifying keyword-like arguments. TensorOptions is a +/// builder class which can be used to construct this "dictionary" of keyword +/// arguments: functions which support TensorOptions conventionally take this +/// argument optionally as their last argument. +/// +/// WARNING: In PyTorch, there are `torch::` variants of factory functions, +/// e.g., torch::zeros for at::zeros. These return Variables (while the +/// stock ATen functions return plain Tensors). If you mix these functions +/// up, you WILL BE SAD. +/// +/// Rather than use the constructor of this class directly, you should prefer to +/// use the constructor functions, and then chain setter methods on top of them. +/// +/// at::device(at::kCUDA).dtype(kInt) +/// at::dtype(at::kInt) +/// +/// Additionally, anywhere a TensorOptions is expected, you can directly +/// pass at::kCUDA / at::kInt, and it will implicitly convert to a +/// TensorOptions. +/// +/// Here are some recommended ways to create a 2x2 tensor of zeros +/// with certain properties. These all *implicitly* make use of +/// TensorOptions, even if they don't mention the class explicitly: +/// +/// at::zeros({2,2}, at::kCUDA); +/// at::zeros({2,2}, at::kLong); +/// at::zeros({2,2}, at::device(at::kCUDA).dtype(at::kLong())); +/// at::zeros({2,2}, at::device({at::kCUDA, 1})); // place on device 1 +/// at::zeros({2,2}, at::requires_grad()); +/// + +/// NOTE [ TensorOptions Constructors ] +/// +/// TensorOptions is like a dictionary with entries from the set: +/// {requires_grad, device, dtype, layout}, where each entry may be +/// unspecified (i.e., is optional). It is used to specify the properties of +/// tensors in many places both in C++ internal and API, e.g., tensor factory +/// methods like `at::empty({10}, options)`, tensor conversions like +/// `tensor.to(...)`, etc. +/// +/// To provide a simple API that is consistent with Python, where one can do +/// `torch.empty(sizes, X)` with `X` being a `torch.device`, `torch.dtype`, or a +/// `torch.layout`, we want TensorOptions to be implicitly convertible from +/// `ScalarType dtype`, `Layout layout` and `Device device`. Therefore, we have +/// three implicit constructors from each of these three types. +/// +/// This is sufficient for `ScalarType` and `Layout` as they are simple Enum +/// classes. However, `Device` is an ordinary class with implicit constructors +/// `Device(DeviceType, DeviceIndex = -1)` and `Device(std::string)` to be +/// consistent with Python API, where strings are treated as equivalent with a +/// `torch.device` object (e.g., "cuda:1" can be passed to everywhere a +/// `torch.device("cuda:1")` is accepted). To support the syntax +/// `at::empty({10}, {kCUDA, 1})` and `tensor.to(kCUDA)`, we need to make sure +/// that `TensorOptions` is implicitly constructible with any arguments that a +/// `Device` can constructed from. So we have, +/// +/// /* implicit */ TensorOptions(T&& device) : TensorOptions() { +/// this->set_device(device); +/// } +/// +/// template ::value>> +/// /* implicit */ TensorOptions(Args&&... args) +/// : TensorOptions(Device(std::forward(args)...)) {} +/// +/// +/// But this will be problematic. Consider this: `TensorOptions({kCUDA, 1})`. +/// Compiler will complain about ambiguity between the copy constructor and the +/// `Device` constructor because `{kCUDA, 1}` can be converted to both a +/// `TensorOption` and a `Device`. +/// +/// To get around this, we templatize the `Device` constructor. Since overload +/// resolution is done before template resolution, our problem is solved. + +DispatchKey computeDispatchKey( + std::optional dtype, + std::optional layout, + std::optional device); + +struct C10_API TensorOptions { + TensorOptions() + : requires_grad_(false), + pinned_memory_(false), + has_device_(false), + has_dtype_(false), + has_layout_(false), + has_requires_grad_(false), + has_pinned_memory_(false), + has_memory_format_(false) {} + + /// Constructs a `TensorOptions` object with the given layout. + /* implicit */ TensorOptions(Layout layout) : TensorOptions() { + this->set_layout(layout); + } + + /// Constructs a `TensorOptions` object with the given device. + /// See NOTE [ TensorOptions Constructors ] on why this is templatized. + template < + typename T, + typename = std::enable_if_t, Device>>> + /* implicit */ TensorOptions(T&& device) : TensorOptions() { + this->set_device(std::forward(device)); + } + + /// Constructs a `TensorOptions` object from arguments allowed in `Device` + /// constructors. + /// + /// See NOTE [ TensorOptions Constructors ]. + /// + /// NB: Ideally we only allow implicit constructors here. But there is no easy + /// way to detect them. So we have this one that allows explicit + /// constructors too. + template < + typename... Args, + typename = std::enable_if_t>> + /* implicit */ TensorOptions(Args&&... args) + : TensorOptions(Device(std::forward(args)...)) {} + + /// Constructs a `TensorOptions` object with the given dtype. + /* implicit */ TensorOptions(caffe2::TypeMeta dtype) : TensorOptions() { + this->set_dtype(dtype); + } + + /// legacy constructor to support ScalarType + /* implicit */ TensorOptions(ScalarType dtype) : TensorOptions() { + this->set_dtype(dtype); + } + + /// Constructs a `TensorOptions` object with the given memory format. + /* implicit */ TensorOptions(MemoryFormat memory_format) : TensorOptions() { + set_memory_format(memory_format); + } + + /// Return a copy of `TensorOptions` with `device` set to the given one, or + /// cleared if `device` is `nullopt`. + [[nodiscard]] TensorOptions device( + std::optional device) const noexcept { + TensorOptions r = *this; + r.set_device(device); + return r; + } + + /// Return a copy of `TensorOptions` with `device` set to the given one. + /// (This overload ensures that variadic template std::optional constructor + /// for Device work correctly.) + template + [[nodiscard]] TensorOptions device(Args&&... args) const noexcept { + return device( + std::optional(std::in_place, std::forward(args)...)); + } + + /// Return a copy of `TensorOptions`, but with device set to CUDA, and the + /// device index set to the given one. + /// + /// TODO: This function encourages bad behavior (assuming CUDA is + /// the only device that matters). Get rid of it / rename it. + [[nodiscard]] TensorOptions device_index( + c10::DeviceIndex device_index) const noexcept { + return device(Device::Type::CUDA, device_index); + } + + /// Return a copy of `TensorOptions` with `dtype` set to the given one. + [[nodiscard]] TensorOptions dtype( + std::optional dtype) const noexcept { + TensorOptions r = *this; + r.set_dtype(dtype); + return r; + } + + // legacy function to support ScalarType + [[nodiscard]] TensorOptions dtype( + std::optional dtype) const noexcept { + TensorOptions r = *this; + r.set_dtype(dtype); + return r; + } + + // Since dtype is taken... + template + TensorOptions& dtype() { + dtype_ = caffe2::TypeMeta::Make(); + has_dtype_ = true; + return *this; + } + + /// Sets the layout of the `TensorOptions`. + [[nodiscard]] TensorOptions layout( + std::optional layout) const noexcept { + TensorOptions r = *this; + r.set_layout(layout); + return r; + } + + /// Sets the `requires_grad` property of the `TensorOptions`. + [[nodiscard]] TensorOptions requires_grad( + std::optional requires_grad) const noexcept { + TensorOptions r = *this; + r.set_requires_grad(requires_grad); + return r; + } + + /// Sets the `pinned_memory` property on the `TensorOptions`. + [[nodiscard]] TensorOptions pinned_memory( + std::optional pinned_memory) const noexcept { + TensorOptions r = *this; + r.set_pinned_memory(pinned_memory); + return r; + } + + /// Sets the `memory_format` property on `TensorOptions`. + [[nodiscard]] TensorOptions memory_format( + std::optional memory_format) const noexcept { + TensorOptions r = *this; + r.set_memory_format(memory_format); + return r; + } + + /// Returns the device of the `TensorOptions`. + Device device() const noexcept { + return device_or_default(device_opt()); + } + + /// Returns whether the device is specified. + bool has_device() const noexcept { + return has_device_; + } + + /// Returns the device of the `TensorOptions`, or `std::nullopt` if + /// device is not specified. + std::optional device_opt() const noexcept { + return has_device_ ? std::make_optional(device_) : std::nullopt; + } + + /// Returns the device index of the `TensorOptions`. + c10::DeviceIndex device_index() const noexcept { + return device().index(); + } + + /// Returns the dtype of the `TensorOptions`. + caffe2::TypeMeta dtype() const noexcept { + return dtype_or_default(dtype_opt()); + } + + /// Returns whether the dtype is specified. + bool has_dtype() const noexcept { + return has_dtype_; + } + + /// Returns the dtype of the `TensorOptions`, or `std::nullopt` if + /// device is not specified. + std::optional dtype_opt() const noexcept { + return has_dtype_ ? std::make_optional(dtype_) : std::nullopt; + } + + /// Returns the layout of the `TensorOptions`. + Layout layout() const noexcept { + return layout_or_default(layout_opt()); + } + + /// Returns whether the layout is specified. + bool has_layout() const noexcept { + return has_layout_; + } + + /// Returns the layout of the `TensorOptions`, or `std::nullopt` if + /// layout is not specified. + std::optional layout_opt() const noexcept { + return has_layout_ ? std::make_optional(layout_) : std::nullopt; + } + + /// Returns the `requires_grad` property of the `TensorOptions`. + bool requires_grad() const noexcept { + return has_requires_grad_ ? requires_grad_ : false; + } + + /// Returns whether the `requires_grad` is specified. + bool has_requires_grad() const noexcept { + return has_requires_grad_; + } + + /// Returns the `requires_grad` property of the `TensorOptions`, or + /// `std::nullopt` if `requires_grad` is not specified. + std::optional requires_grad_opt() const noexcept { + return has_requires_grad_ ? std::make_optional(requires_grad_) + : std::nullopt; + } + + /// Returns the `pinned_memory` property of the `TensorOptions`. + bool pinned_memory() const noexcept { + return pinned_memory_or_default(pinned_memory_opt()); + } + + /// Returns whether the `pinned_memory` is specified. + bool has_pinned_memory() const noexcept { + return has_pinned_memory_; + } + + /// Returns if the layout is sparse + bool is_sparse() const { + return layout_ == c10::Layout::Sparse; + } + + /// Returns if the layout is sparse CSR, deprecated, use + /// is_sparse_compressed() instead + bool is_sparse_csr() const { + return layout_ == c10::Layout::SparseCsr; + } + + bool is_sparse_compressed() const { + return layout_ == c10::Layout::SparseCsr || + layout_ == c10::Layout::SparseCsc || + layout_ == c10::Layout::SparseBsr || layout_ == c10::Layout::SparseBsc; + } + + // For compatibility with legacy tensor.type() comparisons + bool type_equal(const TensorOptions& other) const { + return computeDispatchKey() == other.computeDispatchKey() && + typeMetaToScalarType(dtype_) == typeMetaToScalarType(other.dtype()); + } + + /// Returns the `pinned_memory` property of the `TensorOptions`, or + /// `std::nullopt` if `pinned_memory` is not specified. + std::optional pinned_memory_opt() const noexcept { + return has_pinned_memory_ ? std::make_optional(pinned_memory_) + : std::nullopt; + } + + /// Returns whether the `memory_layout` is specified + bool has_memory_format() const noexcept { + return has_memory_format_; + } + + // NB: memory_format() getter is PURPOSELY not defined, as the default + // behavior of memory_format varies from function to function. + + /// Returns the `memory_layout` property of `TensorOptions, or + /// `std::nullopt` if `memory_format` is not specified. + std::optional memory_format_opt() const noexcept { + return has_memory_format_ ? std::make_optional(memory_format_) + : std::nullopt; + } + + // Resolves the ATen backend specified by the current construction axes. + // TODO: Deprecate this + Backend backend() const { + return at::dispatchKeyToBackend(computeDispatchKey()); + } + + /// Return the right-biased merge of two TensorOptions. This has the + /// effect of overwriting settings from self with specified options + /// of options. + /// + /// NB: This merging operation does NOT respect device merges. + /// For example, if you device({kCUDA, 1}).merge_in(kCUDA) + /// you will get kCUDA in the end! Functions like Tensor.new_empty + /// ensure the right device is selected anyway by way of a + /// device guard. + /// + TensorOptions merge_in(TensorOptions options) const noexcept { + TensorOptions merged = *this; + if (options.has_device()) + merged.set_device(options.device_opt()); + if (options.has_dtype()) + merged.set_dtype(options.dtype_opt()); + if (options.has_layout()) + merged.set_layout(options.layout_opt()); + // NB: requires grad is right biased; not a logical AND/OR! + if (options.has_requires_grad()) + merged.set_requires_grad(options.requires_grad_opt()); + if (options.has_pinned_memory()) + merged.set_pinned_memory(options.pinned_memory_opt()); + if (options.has_memory_format()) + merged.set_memory_format(options.memory_format_opt()); + return merged; + } + + // TODO remove after TensorOptions rationalization + TensorOptions merge_memory_format( + std::optional optional_memory_format) const noexcept { + TensorOptions merged = *this; + if (optional_memory_format.has_value()) { + merged.set_memory_format(optional_memory_format); + } + return merged; + } + + // INVARIANT: computeDispatchKey returns only the subset of dispatch keys for + // which dispatchKeyToBackend is injective, if it is defined at all (for + // the most part, this just means that this function never returns an + // Autograd key) + DispatchKey computeDispatchKey() const { + return c10::computeDispatchKey( + optTypeMetaToScalarType(dtype_opt()), layout_opt(), device_opt()); + } + + private: + // These methods are currently private because I'm not sure if it's wise + // to actually publish them. They are methods because I need them in + // the constructor and the functional API implementation. + // + // If you really, really need it, you can make these public, but check if you + // couldn't just do what you need with the functional API. Similarly, these + // methods are not chainable, because if you wanted chaining, you probably + // want to use the functional API instead. (It's probably OK to make + // these chainable, because these functions are all explicitly annotated + // with a ref-qualifier, the trailing &, that makes them illegal to call + // on temporaries.) + + /// Mutably set the device of `TensorOptions`. + void set_device(std::optional device) & noexcept { + if (device) { + device_ = *device; + has_device_ = true; + } else { + has_device_ = false; + } + } + + /// Mutably set the dtype of `TensorOptions`. + void set_dtype(std::optional dtype) & noexcept { + if (dtype) { + dtype_ = *dtype; + has_dtype_ = true; + } else { + has_dtype_ = false; + } + } + + // legacy function to support ScalarType + void set_dtype(std::optional dtype) & noexcept { + if (dtype) { + dtype_ = scalarTypeToTypeMeta(*dtype); + has_dtype_ = true; + } else { + has_dtype_ = false; + } + } + + /// Mutably set the layout of `TensorOptions`. + void set_layout(std::optional layout) & noexcept { + if (layout) { + layout_ = *layout; + has_layout_ = true; + } else { + has_layout_ = false; + } + } + + /// Mutably set the `requires_grad` property of `TensorOptions`. + void set_requires_grad(std::optional requires_grad) & noexcept { + if (requires_grad) { + requires_grad_ = *requires_grad; + has_requires_grad_ = true; + } else { + has_requires_grad_ = false; + } + } + + /// Mutably set the `pinned_memory` property of `TensorOptions`. + void set_pinned_memory(std::optional pinned_memory) & noexcept { + if (pinned_memory) { + pinned_memory_ = *pinned_memory; + has_pinned_memory_ = true; + } else { + has_pinned_memory_ = false; + } + } + + /// Mutably set the `memory_Format` property of `TensorOptions`. + void set_memory_format(std::optional memory_format) & noexcept { + if (memory_format) { + memory_format_ = *memory_format; + has_memory_format_ = true; + } else { + has_memory_format_ = false; + } + } + + // WARNING: If you edit TensorOptions to add more options, you + // may need to adjust the implementation of Tensor::options. + // The criteria for whether or not Tensor::options must be adjusted + // is whether or not the new option you added should preserved + // by functions such as empty_like(); if it should be preserved, + // you must adjust options(). + // + // TODO: MemoryFormat is not implemented in this way + + // NB: We didn't use std::optional here, because then we can't pack + // the has_***_ boolean fields. + + Device device_ = at::kCPU; // 16-bit + caffe2::TypeMeta dtype_ = caffe2::TypeMeta::Make(); // 16-bit + Layout layout_ = at::kStrided; // 8-bit + MemoryFormat memory_format_ = MemoryFormat::Contiguous; // 8-bit + + // Bitmask required here to get this to fit inside 32 bits (or even 64 bits, + // for that matter) + + bool requires_grad_ : 1; + bool pinned_memory_ : 1; + + bool has_device_ : 1; + bool has_dtype_ : 1; + bool has_layout_ : 1; + bool has_requires_grad_ : 1; + bool has_pinned_memory_ : 1; + bool has_memory_format_ : 1; +}; + +// We should aspire to fit in one machine-size word; but a size greater than two +// words is too much. (We are doing terribly on 32-bit archs, where we require +// three machine size words to store tensor options. Eek!) +static_assert( + sizeof(TensorOptions) <= sizeof(int64_t) * 2, + "TensorOptions must fit in 128-bits"); + +/// Convenience function that returns a `TensorOptions` object with the `dtype` +/// set to the given one. +inline TensorOptions dtype(caffe2::TypeMeta dtype) { + return TensorOptions().dtype(dtype); +} + +// legacy function to support ScalarType +inline TensorOptions dtype(ScalarType dtype) { + return TensorOptions().dtype(scalarTypeToTypeMeta(dtype)); +} + +/// Convenience function that returns a `TensorOptions` object with the `layout` +/// set to the given one. +inline TensorOptions layout(Layout layout) { + return TensorOptions().layout(layout); +} + +/// Convenience function that returns a `TensorOptions` object with the `device` +/// set to the given one. +inline TensorOptions device(Device device) { + return TensorOptions().device(device); +} + +/// Convenience function that returns a `TensorOptions` object with the +/// `device` set to CUDA and the `device_index` set to the given one. +inline TensorOptions device_index(c10::DeviceIndex device_index) { + return TensorOptions().device_index(device_index); +} + +/// Convenience function that returns a `TensorOptions` object with the +/// `requires_grad` set to the given one. +inline TensorOptions requires_grad(bool requires_grad = true) { + return TensorOptions().requires_grad(requires_grad); +} + +/// Convenience function that returns a `TensorOptions` object with the +/// `memory_format` set to the given one. +inline TensorOptions memory_format(MemoryFormat memory_format) { + return TensorOptions().memory_format(memory_format); +} + +C10_API std::ostream& operator<<( + std::ostream& stream, + const TensorOptions& options); + +template +inline TensorOptions dtype() { + return dtype(caffe2::TypeMeta::Make()); +} + +inline std::string toString(const TensorOptions& options) { + std::ostringstream stream; + stream << options; + return stream.str(); +} + +// This is intended to be a centralized location by which we can determine +// what an appropriate DispatchKey for a tensor is. +inline DispatchKey computeDispatchKey( + std::optional dtype, + std::optional layout, + std::optional device) { + const auto layout_ = layout_or_default(layout); + const auto device_ = device_or_default(device); + switch (layout_) { + case Layout::Jagged: + case Layout::Strided: { + const auto dtype_ = dtype_or_default(dtype); + switch (device_.type()) { +#define DO_CASE(device, _) \ + case c10::DeviceType::device: { \ + if (isQIntType(dtype_)) { \ + return DispatchKey::Quantized##device; \ + } \ + return DispatchKey::device; \ + } + C10_FORALL_BACKEND_DEVICE_TYPES(DO_CASE, unused) +#undef DO_CASE + case c10::DeviceType::FPGA: + return DispatchKey::FPGA; + case c10::DeviceType::MAIA: + return DispatchKey::MAIA; + case c10::DeviceType::Vulkan: + return DispatchKey::Vulkan; + case c10::DeviceType::Metal: + return DispatchKey::Metal; + case c10::DeviceType::MKLDNN: + case c10::DeviceType::OPENGL: + case c10::DeviceType::OPENCL: + case c10::DeviceType::IDEEP: + TORCH_INTERNAL_ASSERT( + 0, + "This is a grandfathered Caffe2 device type ", + device_.type(), + ", it shouldn't ever convert to a DispatchKey. File a bug describing what you were doing if you think this is in error."); + default: + TORCH_CHECK_NOT_IMPLEMENTED( + false, + "Unsupported device type for dense layout: ", + device_.type()); + } + } + case Layout::Sparse: + switch (device_.type()) { +#define DO_CASE(device, _) \ + case c10::DeviceType::device: { \ + return DispatchKey::Sparse##device; \ + } + C10_FORALL_BACKEND_DEVICE_TYPES(DO_CASE, unused) +#undef DO_CASE + default: + TORCH_CHECK_NOT_IMPLEMENTED( + false, + "Unsupported device type for sparse layout: ", + device_.type()); + } + case Layout::Mkldnn: + switch (device_.type()) { + case c10::DeviceType::CPU: + return DispatchKey::MkldnnCPU; + default: + TORCH_CHECK_NOT_IMPLEMENTED( + false, + "Unsupported device type for mkldnn layout: ", + device_.type()); + } + case Layout::SparseCsr: + case Layout::SparseCsc: + case Layout::SparseBsr: + case Layout::SparseBsc: + switch (device_.type()) { +#define DO_CASE(device, _) \ + case c10::DeviceType::device: { \ + return DispatchKey::SparseCsr##device; \ + } + C10_FORALL_BACKEND_DEVICE_TYPES(DO_CASE, unused) +#undef DO_CASE + default: + TORCH_CHECK_NOT_IMPLEMENTED( + false, + "Unsupported device type for ", + layout_, + " layout: ", + device_.type()); + } + default: + TORCH_CHECK(false, "Unsupported layout: ", layout_); + } +} + +inline Layout dispatchKeyToLayout(DispatchKey dispatch_key) { + switch (dispatch_key) { +#define DO_CASE(bc, _) case DispatchKey::Sparse##bc: + C10_FORALL_BACKEND_COMPONENTS(DO_CASE, unused) +#undef DO_CASE + return Layout::Sparse; +#define DO_CASE(bc, _) case DispatchKey::SparseCsr##bc: + C10_FORALL_BACKEND_COMPONENTS(DO_CASE, unused) +#undef DO_CASE + TORCH_CHECK( + false, "Cannot map DispatchKey ", dispatch_key, " to a unique layout."); + case DispatchKey::MkldnnCPU: + return Layout::Mkldnn; + default: + return Layout::Strided; + } +} + +inline c10::DeviceType dispatchKeyToDeviceType(DispatchKey dispatch_key) { + switch (dispatch_key) { + // stuff that's real +#define DO_CASE(suffix, prefix) \ + case DispatchKey::prefix##suffix: \ + return c10::DeviceType::suffix; +#define DO_CASES(_, prefix) C10_FORALL_BACKEND_DEVICE_TYPES(DO_CASE, prefix) + C10_FORALL_FUNCTIONALITY_KEYS(DO_CASES) +#undef DO_CASES +#undef DO_CASE + + case DispatchKey::MkldnnCPU: + return c10::DeviceType::CPU; + case DispatchKey::Vulkan: + return c10::DeviceType::Vulkan; + + case DispatchKey::MAIA: + return c10::DeviceType::MAIA; + default: + TORCH_CHECK( + false, + "DispatchKey ", + dispatch_key, + " doesn't correspond to a device"); + } +} + +inline TensorOptions dispatchKeyToTensorOptions(DispatchKey dispatch_key) { + return TensorOptions() + .layout(dispatchKeyToLayout(dispatch_key)) + .device(dispatchKeyToDeviceType(dispatch_key)); +} + +namespace detail { +inline bool backend_supports_empty_operator(const TensorOptions& options) { + // Quantized backends don't support at::empty(). + // They have separate operators like at::empty_quantized() that take in + // extra information about how to quantize the tensor. + return !isQIntType(typeMetaToScalarType(options.dtype())); +} + +} // namespace detail + +} // namespace c10 + +C10_DIAGNOSTIC_POP() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/UndefinedTensorImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/UndefinedTensorImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..3a8381e887f90556b66f8b654bb5376e16afe074 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/UndefinedTensorImpl.h @@ -0,0 +1,54 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace c10 { + +struct C10_API UndefinedTensorImpl final : public TensorImpl { + public: + // Without this, we get: + // error: identifier "at::UndefinedTensorImpl::_singleton" is undefined in + // device code + // (ostensibly because the constexpr tricks MSVC into trying to compile this + // function for device as well). +#ifdef _WIN32 + static inline TensorImpl* singleton() { + return &getInstance(); + } +#else + static constexpr inline TensorImpl* singleton() { + return &_singleton; + } +#endif + +#ifdef DEBUG + bool has_storage() const override; +#endif + void set_storage_offset(int64_t offset) override; + + protected: + c10::SymBool sym_is_contiguous_custom(MemoryFormat format) const override; + IntArrayRef strides_custom() const override; + SymIntArrayRef sym_strides_custom() const override; + + private: + UndefinedTensorImpl(); +#ifdef _WIN32 + static UndefinedTensorImpl& getInstance(); +#else + static UndefinedTensorImpl _singleton; +#endif + const char* tensorimpl_type_name() const override; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/WrapDimMinimal.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/WrapDimMinimal.h new file mode 100644 index 0000000000000000000000000000000000000000..02570ae84ffdb64c1b2c8b20deb52178c606f57d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/WrapDimMinimal.h @@ -0,0 +1,53 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace c10 { + +namespace detail { +// This template can only be specialized at int64_t and c10::SymInt; +// you'll get linker errors otherwise +template +C10_API T maybe_wrap_dim_slow(T dim, T dim_post_expr, bool wrap_scalar); +} // namespace detail + +template +T _maybe_wrap_dim(T dim, T dim_post_expr, bool wrap_scalar = true) { + // Inline the fast paths + if (C10_LIKELY(dim_post_expr * -1 <= dim && dim < dim_post_expr)) { + // For SymInts, we want an explicit control flow to trigger a guard, so we + // may as well branch too. + if (dim < 0) { + return dim + dim_post_expr; + } + return dim; + } + // Check edge-cases out-of-line (wrapping scalars and out-of-bounds errors) + return c10::detail::maybe_wrap_dim_slow( + std::move(dim), std::move(dim_post_expr), wrap_scalar); +} + +inline int64_t maybe_wrap_dim( + int64_t dim, + int64_t dim_post_expr, + bool wrap_scalar = true) { + return _maybe_wrap_dim(dim, dim_post_expr, wrap_scalar); +} + +inline c10::SymInt maybe_wrap_dim( + c10::SymInt dim, + c10::SymInt dim_post_expr, + bool wrap_scalar = true) { + return _maybe_wrap_dim(std::move(dim), std::move(dim_post_expr), wrap_scalar); +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/alignment.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/alignment.h new file mode 100644 index 0000000000000000000000000000000000000000..4ef01f7bfa99c473ebb6612a83f0cdde53eeec6b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/alignment.h @@ -0,0 +1,35 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10 { + +#ifdef C10_MOBILE +// Use 16-byte alignment on mobile +// - ARM NEON AArch32 and AArch64 +// - x86[-64] < AVX +constexpr size_t gAlignment = 16; +#else +// Use 64-byte alignment should be enough for computation up to AVX512. +constexpr size_t gAlignment = 64; +#endif + +constexpr size_t gPagesize = 4096; +// since the default thp pagesize is 2MB, enable thp only +// for buffers of size 2MB or larger to avoid memory bloating +constexpr size_t gAlloc_threshold_thp = static_cast(2) * 1024 * 1024; + +// Cache line size used to avoid false sharing between threads. Falls back to 64 +// bytes if C++17 feature is unavailable. +#ifdef __cpp_lib_hardware_interference_size +using std::hardware_destructive_interference_size; +#else +constexpr std::size_t hardware_destructive_interference_size = 64; +#endif +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/COW.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/COW.h new file mode 100644 index 0000000000000000000000000000000000000000..1ef394e6e3536530af4a6427f16f0a383c39c5be --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/COW.h @@ -0,0 +1,37 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10 { +struct StorageImpl; +class DataPtr; +} // namespace c10 + +namespace c10::impl::cow { + +// Creates a Copy-on-write (COW) clone of the given storage. This will also +// convert the given storage into a COW storage if it is not COW already. +// +// Converting the storage into a COW storage will not be successful if the +// storage's DataPtr has some context (`DataPtr::get_context()`) which is not +// equal to the data pointer (`DataPtr::get()`). In this case, a nullptr is +// returned. +C10_API c10::intrusive_ptr lazy_clone_storage( + StorageImpl& storage); + +// Check if a storage has a simple DataPtr with no abnormal context +C10_API bool has_simple_data_ptr(const c10::StorageImpl& storage); + +// Check if a DataPtr is COW +C10_API bool is_cow_data_ptr(const c10::DataPtr& data_ptr); + +// Eagerly copies a COW storage's data, turning it into a non-COW storage. +C10_API void materialize_cow_storage(StorageImpl& storage); + +} // namespace c10::impl::cow + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/COWDeleter.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/COWDeleter.h new file mode 100644 index 0000000000000000000000000000000000000000..90a618003c995ce6fe949b8f0ea5110a8a47b74a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/COWDeleter.h @@ -0,0 +1,71 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +namespace c10::impl::cow { + +// A COWDeleterContext object is used as the `ctx` argument for DataPtr +// to implement a Copy-on-write (COW) DataPtr. +class C10_API COWDeleterContext { + public: + // Creates an instance, holding the pair of data and original + // deleter. + // + // Note that the deleter will only be called in our destructor if + // the last reference to this goes away without getting + // materialized. + explicit COWDeleterContext(std::unique_ptr data); + + // Increments the current refcount. + void increment_refcount(); + + // See README.md in this directory to understand the locking + // strategy. + + // Represents a reference to the context. + // + // This is returned by decrement_refcount to allow the caller to + // copy the data under the shared lock. + using NotLastReference = std::shared_lock; + + // Represents the last reference to the context. + // + // This will be returned by decrement_refcount when it is the last + // reference remaining and after any pending copies have completed. + using LastReference = std::unique_ptr; + + // Decrements the refcount, returning a handle indicating what to + // do with it. + std::variant decrement_refcount(); + + private: + // The destructor is hidden, this should only ever be used within + // UniqueVoidPtr using cow::delete_context as the deleter. + ~COWDeleterContext(); + + std::shared_mutex mutex_; + std::unique_ptr data_; + std::atomic refcount_ = 1; +}; + +// `cow_deleter` is used as the `ctx_deleter` for DataPtr to implement a COW +// DataPtr. +// +// Warning: This should only be called on a pointer to a COWDeleterContext that +// was allocated on the heap with `new`, because when the refcount reaches 0, +// the context is deleted with `delete`. +C10_API void cow_deleter(void* ctx); + +} // namespace c10::impl::cow + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/DeviceGuardImplInterface.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/DeviceGuardImplInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..a62ce82f650e7fa85b0a4dbaf55e6f80ce609e54 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/DeviceGuardImplInterface.h @@ -0,0 +1,435 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +// Just for C10_ANONYMOUS_VARIABLE +#include +#include + +#include +#include + +namespace c10 { + +// Forward declaration +class DataPtr; + +/** + * Note [Flags defining the behavior of events] + * + * PYTORCH_DEFAULT and BACKEND_DEFAULT are valid for all backends. The + * BACKEND_DEFAULT is what a particular backend would select if no + * flags were given. PYTORCH_DEFAULT is the PyTorch's framework default + * choice for events on that backend, which may not be the same. + * + * The mapping of PYTORCH_DEFAULT and BACKEND_DEFAULT is done by each + * backend implementation. + */ +enum class EventFlag { + // Disable timing + PYTORCH_DEFAULT, + // Enable timing + BACKEND_DEFAULT, + // FOR TESTING ONLY + INVALID +}; + +namespace impl { + +/** + * DeviceGuardImplInterface represents the virtual interface which provides + * functionality to provide an RAII class for device and stream switching, + * via DeviceGuard. Every distinct device type, e.g., CUDA and HIP, is + * expected to implement and register an implementation of this interface. + * All classes which inherit from DeviceGuardImplInterface should be declared + * 'final'. + * + * This class exists because we provide a unified interface for performing + * device guards via DeviceGuard, but we cannot assume that we have actually + * compiled against the, e.g., CUDA library, which actually implements + * this guard functionality. In this case, a dynamic dispatch is required + * to cross the library boundary. + * + * If possible, you should directly use implementations of this interface; + * those uses will be devirtualized. + */ +struct C10_API DeviceGuardImplInterface { + DeviceGuardImplInterface() = default; + DeviceGuardImplInterface(const DeviceGuardImplInterface&) = default; + DeviceGuardImplInterface& operator=(const DeviceGuardImplInterface&) = + default; + DeviceGuardImplInterface(DeviceGuardImplInterface&&) noexcept = default; + DeviceGuardImplInterface& operator=(DeviceGuardImplInterface&&) noexcept = + default; + + /** + * Return the type of device managed by this guard implementation. + */ + virtual DeviceType type() const = 0; + + /** + * Set the current device to Device, and return the previous Device. + */ + virtual Device exchangeDevice(Device) const = 0; + // NB: Implementations of exchangeDevice can be a bit boilerplatey. You might + // consider replacing exchangeDevice with a non-virtual function with a baked + // in implementation; however, note that this will triple the number of + // virtual calls (when you implement exchangeDevice in a final subclass, + // the compiler gets to devirtualize everything; it won't do that if you don't + // define it in the subclass!) A common way to solve this problem is to use + // some sort of CRTP; however, we can template DeviceGuardImplInterface since + // we really *do* need it to be virtual. A little boilerplate seems easiest + // to explain. (Another way around this problem is to provide inline + // functions that provide the default implementations, but this seems a little + // hard to explain. In any case, we're only going to have on order of ten + // implementations of this anyway.) + + /** + * Get the current device. + */ + virtual Device getDevice() const = 0; + + /** + * Set the current device to Device. + */ + virtual void setDevice(Device) const = 0; + + /** + * Set the current device to Device, without checking for errors + * (so, e.g., this can be called from a destructor). + */ + virtual void uncheckedSetDevice(Device) const noexcept = 0; + + /** + * Get the current stream for a given device. + */ + virtual Stream getStream(Device) const = 0; + + /** + * Get the default stream for a given device. + */ + virtual Stream getDefaultStream(Device /*unused*/) const { + TORCH_CHECK(false, "Backend doesn't support acquiring a default stream.") + } + + /** + * Get a stream from the global pool for a given device. + */ + virtual Stream getStreamFromGlobalPool( + Device /*unused*/, + bool isHighPriority = false) const { + (void)isHighPriority; // Suppress unused variable warning + TORCH_CHECK(false, "Backend doesn't support acquiring a stream from pool.") + } + + /** + * Return a new stream for a given device and priority. The stream will be + * copied and shared around, device backend should be able to correctly handle + * the lifetime of the stream. + */ + virtual Stream getNewStream(Device /*unused*/, int priority = 0) const { + (void)priority; + TORCH_CHECK(false, "Backend doesn't support create a new Stream.") + } + + /** + * Set a stream to be the thread local current stream for its device. + * Return the previous stream for that device. You are NOT required + * to set the current device to match the device of this stream. + */ + virtual Stream exchangeStream(Stream) const = 0; + + /** + * Returns a backend-specific, opaque native handle associated with the given + * stream. + * + * The returned pointer is owned and managed by PyTorch. Callers must not + * modify or free it. + */ + virtual void* getStreamNativeHandle(const Stream) const { + TORCH_CHECK(false, "Backend doesn't support getting stream native handle.") + } + + /** + * Destroys the given event. + */ + virtual void destroyEvent(void* /*event*/, const DeviceIndex /*device_index*/) + const noexcept {} + + /** + * Increments the event's version and enqueues a job with this version + * in the stream's work queue. When the stream process that job + * it notifies all streams waiting on / blocked by that version of the + * event to continue and marks that version as recorded. + * */ + virtual void record( + void** /*event*/, + const Stream& /*stream*/, + const DeviceIndex /*device_index*/, + const c10::EventFlag /*flag*/) const { + TORCH_CHECK(false, "Backend doesn't support events."); + } + + /** + * Does nothing if the event has not been scheduled to be recorded. + * If the event was previously enqueued to be recorded, a command + * to wait for the version of the event that exists at the time of this call + * is inserted in the stream's work queue. + * When the stream reaches this command it will stop processing + * additional commands until that version of the event is marked as recorded. + */ + virtual void block(void* /*event*/, const Stream& /*stream*/) const { + TORCH_CHECK(false, "Backend doesn't support events."); + } + + /** + * Returns true if (and only if) + * (1) the event has never been scheduled to be recorded + * (2) the current version is marked as recorded. + * Returns false otherwise. + */ + virtual bool queryEvent(void* /*event*/) const { + TORCH_CHECK(false, "Backend doesn't support events."); + } + + /** + * Get the number of devices. WARNING: This is REQUIRED to not raise + * an exception. If there is some sort of problem, e.g., driver error, + * you should report that there are zero available devices. + */ + virtual DeviceIndex deviceCount() const noexcept = 0; + + /** + * Get the following capabilities of the current device: + * (1) Data type support + * Returns DeviceCapability object. + */ + virtual DeviceCapability getDeviceCapability(Device /*unused*/) const { + TORCH_CHECK(false, "Backend doesn't support getting device capabilities."); + } + + /** + * Return true if all the work previously enqueued on the stream for + * asynchronous execution has completed running on the device. + */ + virtual bool queryStream(const Stream& /*stream*/) const { + TORCH_CHECK(false, "Backend doesn't support querying streams."); + } + + /** + * Wait (by blocking the calling thread) until all the work previously + * enqueued on the stream has completed running on the device. + */ + virtual void synchronizeStream(const Stream& /*stream*/) const { + TORCH_CHECK(false, "Backend doesn't support synchronizing streams."); + } + + /** + * Return true if this stream is currently recording work for graph capture. + */ + virtual bool isStreamCapturing(const Stream& /*stream*/) const { + TORCH_CHECK(false, "Backend doesn't support stream capture query."); + } + + /** + * Wait (by blocking the calling thread) until all the work previously + * recorded on the event has completed running on the device. + */ + virtual void synchronizeEvent(void* /*event*/) const { + TORCH_CHECK(false, "Backend doesn't support synchronizing events."); + } + + /** + * Wait (by blocking the calling thread) until all the work previously + * enqueued on the device has been completed. + */ + virtual void synchronizeDevice(const DeviceIndex /*device_index*/) const { + TORCH_CHECK( + false, "Backend doesn't support synchronizing all streams on device."); + } + + /** + * Ensure the caching allocator (if any) is aware that the given DataPtr is + * being used on the given stream, and that it should thus avoid recycling the + * DataPtr until all work on that stream is done. + */ + virtual void recordDataPtrOnStream( + const c10::DataPtr& /*unused*/, + const Stream& /*unused*/) const {} + + /** + * Fetch the elapsed time between two recorded events. + */ + virtual double elapsedTime( + void* /*event1*/, + void* /*event2*/, + const DeviceIndex /*device_index*/) const { + TORCH_CHECK(false, "Backend doesn't support elapsedTime."); + } + + /** + * Intended use of this class is to leak the DeviceGuardImpl at program end. + * So you better not call the destructor, buster! + */ + virtual ~DeviceGuardImplInterface() = default; +}; + +// A no-op device guard impl that doesn't do anything interesting. Useful +// for devices that don't actually have a concept of device index. Prominent +// examples are CPU and Meta. +template +struct NoOpDeviceGuardImpl : public DeviceGuardImplInterface { + NoOpDeviceGuardImpl() = default; + DeviceType type() const override { + return D; + } + Device exchangeDevice(Device /*unused*/) const override { + return Device(D, -1); // no-op + } + Device getDevice() const override { + return Device(D, -1); + } + void setDevice(Device /*unused*/) const override { + // no-op + } + void uncheckedSetDevice(Device /*unused*/) const noexcept override { + // no-op + } + Stream getStream(Device /*unused*/) const noexcept override { + // no-op + return Stream(Stream::DEFAULT, Device(D, -1)); + } + + Stream getNewStream(Device /*unused*/, int priority = 0) const override { + // no-op + (void)priority; + return Stream(Stream::DEFAULT, Device(D, -1)); + } + + // NB: These do NOT set the current device + Stream exchangeStream(Stream /*unused*/) const noexcept override { + // no-op + return Stream(Stream::DEFAULT, Device(D, -1)); + } + DeviceIndex deviceCount() const noexcept override { + return 1; + } + + DeviceCapability getDeviceCapability(Device /*unused*/) const override { + DeviceCapability cap; + if constexpr (D == DeviceType::Meta) { + cap.capability_data.capability_bits = 0; + // Meta only supports basic types for shape inference + // Byte, Char, Short, Int, Long, Float, Double, + // Bool, ComplexFloat, ComplexDouble + cap.capability_data.capability_bits = (1ULL << kIndex_Byte) | + (1ULL << kIndex_Char) | (1ULL << kIndex_Short) | + (1ULL << kIndex_Int) | (1ULL << kIndex_Long) | + (1ULL << kIndex_Float) | (1ULL << kIndex_Double) | + (1ULL << kIndex_ComplexFloat) | (1ULL << kIndex_ComplexDouble) | + (1ULL << kIndex_Bool); + } + return cap; + } + + // Event-related functions + void record( + void** /*event*/, + const Stream& /*stream*/, + const DeviceIndex /*device_index*/, + const EventFlag /*flag*/) const override { + TORCH_CHECK(false, D, " backend doesn't support events."); + } + void block(void* /*event*/, const Stream& /*stream*/) const override { + TORCH_CHECK(false, D, " backend doesn't support events.") + } + bool queryEvent(void* /*event*/) const override { + TORCH_CHECK(false, D, " backend doesn't support events.") + } + void destroyEvent(void* /*event*/, const DeviceIndex /*device_index*/) + const noexcept override {} + + // Stream-related functions + bool queryStream(const Stream& /*stream*/) const override { + return true; + } + void synchronizeStream(const Stream& /*stream*/) const override { + // Don't wait for anything. + } +}; + +// The registry is NON-owning. Each stored pointer is std::atomic so +// that under all interleavings of registry calls the structure is +// race-free. This doesn't cost us anything on reads in X86. (An +// unsynchronized implementation probably is OK too, but I didn't want +// to prove that we never read from device_guard_impl_registry at the +// same time some registration is occurring. Shiver.) +// +// I'd like this registry to be valid even at program destruction time +// (in case someone uses a DeviceGuard in a destructor to do some cleanup +// in the CUDA API.) Since there are no direct accesses of the underlying +// owning objects which I can use to enforce initialization order (unlike +// in a Meyer singleton), it implies that you must *leak* objects when +// putting them in the registry. This is done by deleting the destructor +// on DeviceGuardImplInterface. +extern C10_API std::array< + std::atomic, + static_cast(DeviceType::COMPILE_TIME_MAX_DEVICE_TYPES)> + device_guard_impl_registry; + +// I can't conveniently use c10/util/Registry.h for the following reason: +// c10/util/Registry.h gives me a slow way of Create'ing a object of some +// interface from the registry, but no way of quickly accessing an already +// created object. I'll be banging on getDeviceGuardImpl every time we do a +// DeviceGuard, so I really don't want to be doing an unordered_map lookup. +// Better if the registration mechanism directly drops its implementation +// into device_guard_impl_registry. + +class C10_API DeviceGuardImplRegistrar { + public: + DeviceGuardImplRegistrar( + DeviceType /*type*/, + const DeviceGuardImplInterface* /*impl*/); +}; + +#define C10_REGISTER_GUARD_IMPL(DevType, DeviceGuardImpl) \ + static ::c10::impl::DeviceGuardImplRegistrar C10_ANONYMOUS_VARIABLE( \ + g_##DeviceType)(::c10::DeviceType::DevType, new DeviceGuardImpl()); + +inline const DeviceGuardImplInterface* getDeviceGuardImpl(DeviceType type) { + // Two adjacent int16_t fields DeviceType and DeviceIndex has field access + // miscompiled on NVCC. To workaround this issue, we apply a mask to the + // DeviceType. First check if the DeviceType is 16-bit. + // FB employees can see + // https://fb.workplace.com/groups/llvm.gcc/permalink/4053565044692080/ + // for more details + static_assert(sizeof(DeviceType) == 1, "DeviceType is not 8-bit"); + auto p = device_guard_impl_registry[static_cast(type) & 0xFF].load(); + + // This seems to be the first place where you make use of a device + // when you pass devices to factory functions. Give a nicer error + // message in this case. + TORCH_CHECK(p, "PyTorch is not linked with support for ", type, " devices"); + return p; +} + +void C10_API +registerDeviceGuard(DeviceType type, const DeviceGuardImplInterface* impl); + +inline bool hasDeviceGuardImpl(DeviceType type) { + return device_guard_impl_registry[static_cast(type)].load(); +} + +void C10_API ensureCUDADeviceGuardSet(); + +} // namespace impl +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/FakeGuardImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/FakeGuardImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..902a4d3febafc5d9ea5c5695c428d25be7c171c2 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/FakeGuardImpl.h @@ -0,0 +1,107 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include + +namespace c10::impl { + +// FakeGuardImpl is hardcoded to have eight devices. Not for +// any good reason, just to simplify code. +constexpr DeviceIndex kFakeGuardImplMaxDevices = 8; + +/** + * A fake implementation of DeviceGuardImplInterface suitable for testing. + * The current device is modeled as a mutable field in the guard implementation + * class. See DeviceGuard_test.cpp for an example use. + */ +template +struct FakeGuardImpl final : public DeviceGuardImplInterface { + static constexpr DeviceType static_type = T; + // Runtime device type is not used + FakeGuardImpl(DeviceType /*unused*/) {} + FakeGuardImpl() = default; + DeviceType type() const override { + return T; + } + Device exchangeDevice(Device d) const override { + AT_ASSERT(d.type() == type()); + AT_ASSERT(d.index() < kFakeGuardImplMaxDevices); + Device old_device = getDevice(); + if (old_device.index() != d.index()) { + current_device_ = d.index(); + } + return old_device; + } + Device getDevice() const override { + return Device(type(), current_device_); + } + void setDevice(Device d) const override { + AT_ASSERT(d.type() == type()); + AT_ASSERT(d.index() >= 0); + AT_ASSERT(d.index() < kFakeGuardImplMaxDevices); + current_device_ = d.index(); + } + void uncheckedSetDevice(Device d) const noexcept override { + current_device_ = d.index(); + } + Stream getStream(Device d) const noexcept override { + return Stream(Stream::UNSAFE, d, current_streams_[d.index()]); + } + Stream exchangeStream(Stream s) const noexcept override { + auto old_id = current_streams_[s.device_index()]; + current_streams_[s.device_index()] = s.id(); + return Stream(Stream::UNSAFE, s.device(), old_id); + } + DeviceIndex deviceCount() const noexcept override { + return kFakeGuardImplMaxDevices; + } + + // Event-related functions + void record( + void** /*event*/, + const Stream& /*stream*/, + const DeviceIndex /*device_index*/, + const EventFlag /*flag*/) const override {} + void block(void* /*event*/, const Stream& /*stream*/) const override {} + bool queryEvent(void* /*event*/) const override { + return true; + } + void destroyEvent(void* /*event*/, const DeviceIndex /*device_index*/) + const noexcept override {} + + // Convenience methods for testing + static DeviceIndex getDeviceIndex() { + return current_device_; + } + static void setDeviceIndex(DeviceIndex i) { + AT_ASSERT(i >= 0); + AT_ASSERT(i < kFakeGuardImplMaxDevices); + current_device_ = i; + } + static StreamId getCurrentStreamIdFor(DeviceIndex i) { + return current_streams_.at(i); + } + static void resetStreams() { + current_streams_.fill(0); + } + + private: + thread_local static DeviceIndex current_device_; + thread_local static std::array + current_streams_; +}; + +template +thread_local DeviceIndex FakeGuardImpl::current_device_ = 0; + +template +thread_local std::array + FakeGuardImpl::current_streams_ = {0, 0, 0, 0, 0, 0, 0, 0}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/GPUTrace.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/GPUTrace.h new file mode 100644 index 0000000000000000000000000000000000000000..57761cff9bc254158816d43451ed5bc01f60411f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/GPUTrace.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace c10::impl { + +struct C10_API GPUTrace { + // On the x86 architecture the atomic operations are lock-less. + static std::atomic gpuTraceState; + + // When PyTorch migrates to C++20, this should be changed to an atomic flag. + // Currently, the access to this variable is not synchronized, on the basis + // that it will only be flipped once and by the first interpreter that + // accesses it. + static bool haveState; + + // This function will only register the first interpreter that tries to invoke + // it. For all of the next ones it will be a no-op. + static void set_trace(const PyInterpreter* /*trace*/); + + static const PyInterpreter* get_trace() { + if (!haveState) + return nullptr; + return gpuTraceState.load(std::memory_order_acquire); + } +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/HermeticPyObjectTLS.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/HermeticPyObjectTLS.h new file mode 100644 index 0000000000000000000000000000000000000000..032b90a20bd297b742711ada1d9d5ed1501a5e7e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/HermeticPyObjectTLS.h @@ -0,0 +1,67 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10::impl { + +// This TLS controls whether or not we permanently associate PyObject +// with Tensor the first time it is allocated. When hermetic PyObject +// TLS is enabled (state is true), we DO NOT save PyObjects to Tensor, +// meaning you get a distinct PyObject whenever you execute the code in +// question. +struct C10_API HermeticPyObjectTLS { + static void set_state(bool state); + static bool get_state() { + // Hypothetical fastpath if torchdeploy/multipy // codespell:ignore multipy + // isn't used. Per + // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2055r0.pdf + // this qualifies relaxed access because it is a single-location data + // structure (only the boolean here). + // + // Forgetting about data races for a moment, is there a logical race? + // + // - Boolean only ever transitions from false to true. So the + // critical situation is when one interpreter is already running + // when a second interpreter switches haveState from false to true. + // + // - The first interpreter is indifferent whether or not it sees + // hasState true/false; obviously false works (this is what the + // interpreter was previously using; more directly, the interpreter + // calls into itself as the handler, so being hermetic is not + // required), and true simply means serviced python operator calls will + // be hermetic; in these cases it is expected to be functionally + // equivalent. + // + // - The second interpreter MUST see hasState true (as its requests will + // be forwarded to the first interpreter), but it is assumed that there + // is a synchronization between the interpreter initialization, and + // when we actually perform operations, so it is guaranteed to see + // hasState true. + // + // QED. + // + // This fastpath is currently disabled so that we can more easily test that + // hermetic mode works correctly even on stock build of PyTorch. + if (false && !haveState_.load(std::memory_order_relaxed)) + return false; + return get_tls_state(); + } + // Call this from the multipy/torchdeploy // codespell:ignore multipy + // top level + static void init_state(); + + private: + // This only flipped once from false to true during + // torchdeploy/multipy initialization, // codespell:ignore multipy + // and never again. + static std::atomic haveState_; + static bool get_tls_state(); +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/InlineDeviceGuard.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/InlineDeviceGuard.h new file mode 100644 index 0000000000000000000000000000000000000000..34d6dff97654888cd12d52ce1f44441f30247e44 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/InlineDeviceGuard.h @@ -0,0 +1,438 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// This file provides implementations of InlineDeviceGuard and +// InlineOptionalDeviceGuard. + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10::impl { + +/** + * A DeviceGuard is an RAII class that sets a device to some value + * on construction, and resets the device to its original value on + * destruction. + * + * InlineDeviceGuard is a helper class for implementing DeviceGuards. + * It is templated over a DeviceGuardImpl (anything that implements + * DeviceGuardImplInterface). There are two primary ways to instantiate + * InlineDeviceGuard: + * + * - With a concrete implementation of DeviceGuardImpl, e.g., CUDAGuardImpl. + * This is the best way to use InlineDeviceGuard, as all calls are + * devirtualized, giving you code as efficient as straight line + * calls to cudaGetDevice/cudaSetDevice. + * + * - With VirtualGuardImpl, which does a virtual dispatch to a DeviceGuardImpl + * retrieved from a DeviceType registry. We have explicitly instantiated + * InlineDeviceGuard this way as c10::DeviceGuard. + * + * If you are in a hurry, you can use InlineDeviceGuard directly: + * + * using CUDAGuard = impl::InlineDeviceGuard; + * + * However, you can provide a better user experience if you explicitly write a + * wrapper class that itself contains the template instantiation: + * + * class CUDAGuard { + * public: + * // ... the API ... + * private: + * impl::InlineDeviceGuard guard_; + * } + * + * The wrapper class provides a good place to write documentation, and helps + * avoid weird template instantiation errors when a user incorrectly uses the + * class. + * + * If you need to test this class, consider instantiating it with FakeGuardImpl. + */ +template +class InlineDeviceGuard { + public: + // Note [Omitted default constructor from RAII] + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // In principle, we could add a default constructor to + // DeviceGuard which reads the current device and promises to + // restore to that device on exit. However, most cases where you + // would have written this, you probably meant to actually just + // use DeviceGuard (since you don't actually need the + // restore to happen if you don't ever actually set the device). + // We remove the constructor here to encourage you to think about + // what you actually want to happen. + explicit InlineDeviceGuard() = delete; + + /// Set the current device to the passed Device. + explicit InlineDeviceGuard(Device device) + : impl_(device.type()), + original_device_( + device.index() == -1 ? impl_.getDevice() + : impl_.exchangeDevice(device)), + current_device_(device.index() == -1 ? original_device_ : device) {} + + /// Set the current device index to the passed DeviceIndex. (The + /// device type is inferred from the template parameter T). + template < + typename U = T, + typename = + typename std::enable_if_t>> + explicit InlineDeviceGuard(DeviceIndex device_index) + : InlineDeviceGuard(Device(U::static_type, device_index)) {} + + /// Construct an InlineDeviceGuard using VirtualGuardImpl with an explicit + /// DeviceGuardImplInterface pointer. + template < + typename U = T, + typename = typename std::enable_if_t>> + explicit InlineDeviceGuard( + Device device, + const DeviceGuardImplInterface* impl) + : impl_( + VirtualGuardImpl(impl ? impl : getDeviceGuardImpl(device.type()))), + original_device_( + device.index() == -1 ? impl_.getDevice() + : impl_.exchangeDevice(device)), + current_device_(device.index() == -1 ? original_device_ : device) {} + + /// Copy is disallowed + InlineDeviceGuard(const InlineDeviceGuard&) = delete; + InlineDeviceGuard& operator=(const InlineDeviceGuard&) = delete; + + /// Move is disallowed, as DeviceGuard does not have an uninitialized state, + /// which is required for moves on types with nontrivial destructors. + InlineDeviceGuard(InlineDeviceGuard&& other) = delete; + InlineDeviceGuard& operator=(InlineDeviceGuard&& other) = delete; + + ~InlineDeviceGuard() { + impl_.uncheckedSetDevice(original_device_); + } + + /// Sets the device to the given one. + template < + typename U = T, + typename std::enable_if_t, int> = 0> + void set_device(at::Device device) { + AT_ASSERT( + (U::static_type == DeviceType::HIP && device.is_cuda()) || + device.type() == U::static_type); + auto index = device.index(); + if (index == -1) + return; + impl_.setDevice(device); + current_device_ = device; + } + + /// Resets the currently set device to its original device, and then sets the + /// current device to the passed device. This is effectively equivalent to + /// set_device when a guard supports only a single device type. + template + typename std::enable_if_t> reset_device( + at::Device device) { + set_device(device); + } + + /// Resets the currently set device to its original device, and then sets the + /// current device to the passed device (for a possibly different device + /// type). + /// + /// This method is named reset_device to highlight the fact that previous + /// device settings from this guard are NOT preserved, even if the device + /// has a different device type. For example: + /// + /// // CUDA device is 0 + /// DeviceGuard g(Device(kCUDA, 1)); + /// g.reset_device(Device(kHIP, 2)); + /// // CUDA device is 0 (!!) + /// + /// NOTE: this implementation may skip some device setting if it can prove + /// that it is unnecessary. + /// + /// Optional argument is for testing only. + template + typename std::enable_if_t> reset_device( + at::Device device, + const impl::DeviceGuardImplInterface* impl = nullptr) { + auto index = device.index(); + if (index == -1) + return; + if (device.type() == original_device_.type()) { + AT_ASSERT(impl == nullptr || impl->type() == device.type()); + impl_.setDevice(device); + current_device_ = device; + } else { + // Destruct and reconstruct the DeviceGuard in place + impl_.setDevice(original_device_); + impl_ = !impl ? VirtualGuardImpl(device.type()) : VirtualGuardImpl(impl); + original_device_ = impl_.exchangeDevice(device); + current_device_ = device; + } + } + + /// Sets the device index to the given one. The device type is inferred + /// from the original device type. + void set_index(DeviceIndex index) { + reset_device(Device(original_device_.type(), index)); + } + + /// Returns the device that was set at the time the most recent + /// reset_device(), or otherwise the device at construction time. + Device original_device() const { + return original_device_; + } + + /// Returns the most recent device that was set using this device guard, + /// either from construction, or via set_device/reset_device/set_index. + Device current_device() const { + return current_device_; + } + + protected: + T impl_; + + private: + Device original_device_; + Device current_device_; +}; + +/** + * A OptionalDeviceGuard is an RAII class that sets a device to some value on + * initialization, and resets the device to its original value on destruction. + * + * InlineOptionalDeviceGuard is a helper class for implementing + * OptionalDeviceGuards. See guidance in InlineDeviceGuard on how to + * use this. See OptionalDeviceGuard for user-oriented usage notes. + */ +template +class InlineOptionalDeviceGuard { + public: + // Note [Explicit initialization of optional fields] + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Explicit initialization of optional fields + // required to workaround an nvcc bug; see + // https://github.com/pytorch/pytorch/issues/12117 + + /// Creates an uninitialized OptionalDeviceGuard. + explicit InlineOptionalDeviceGuard() + : guard_() // See Note [Explicit initialization of optional fields] + {} + ~InlineOptionalDeviceGuard() = default; + + /// Set the current device to the passed Device, if it is not nullopt. + explicit InlineOptionalDeviceGuard(std::optional device_opt) + : guard_() { // See Note [Explicit initialization of optional fields] + if (device_opt.has_value()) { + guard_.emplace(device_opt.value()); + } + } + + /// Set the current device to the passed DeviceIndex, if it is not nullopt. + template < + typename U = T, + typename = + typename std::enable_if_t>> + explicit InlineOptionalDeviceGuard( + std::optional device_index_opt) + : guard_() { // See Note [Explicit initialization of optional fields] + if (device_index_opt.has_value()) { + guard_.emplace(device_index_opt.value()); + } + } + + /// All constructors of DeviceGuard are valid for OptionalDeviceGuard + /// and result in initialized OptionalDeviceGuard. + template + explicit InlineOptionalDeviceGuard(Args&&... args) + : guard_(std::in_place, std::forward(args)...) {} + + // TODO: Consider reading Tensor and TensorList constructors here, when + // Tensor moves to c10. (These are only valid on OptionalDeviceGuard, + // because a Tensor may be undefined, in which case we need an uninitialized + // tensor guard.) + + // Note [Move construction for RAII guards is tricky] + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // In principle, move construction is useful for terminating + // the lifetime of a `OptionalDeviceGuard` early; for example: + // + // // current device is d0 + // OptionalDeviceGuard g1(d1); + // // current device is d1 + // { + // OptionalDeviceGuard g2(std::move(g1)); + // } + // // current device is d0!! + // + // However, it's difficult to implement the move constructor + // in a way that works in all situations. For example, consider + // the following example: + // + // OptionalDeviceGuard g1(d1); + // { + // OptionalDeviceGuard g2(d2); + // { + // OptionalDeviceGuard g3(std::move(g1)); // !!! + // } + // } + // + // What should the current device be while g3 in scope... and what + // should it be after it goes out of scope? What about g2? + // There don't seem to be satisfactory answers for these questions. + // + // It's in principle possible to raise an error when this occurs + // by doing some extra thread-local bookkeeping. But why bother? + // Just don't provide the constructor. + InlineOptionalDeviceGuard(const InlineOptionalDeviceGuard& other) = delete; + InlineOptionalDeviceGuard(InlineOptionalDeviceGuard&& other) = delete; + + // Note [Move assignment for RAII guards is tricky] + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Move assignment is deleted, because you need to know which guard was + // defined "first", as that guard's original_device_ wins--with the current + // representation, we have no way of telling which is the case. (Move + // construction does not have this problem, as one guard is always + // uninitialized.) + // + // We can make this clear by way of a pair of examples: + // + // Example 1: + // + // // initial device is n0 + // { + // CUDAGuard g1(n1); + // { + // CUDAGuard g2(n2); + // // current device should be n2 + // g1 = std::move(g2); + // // current device should still be n2 + // } + // // current device should still be n2 + // } + // // current device should be n0 + // + // Example 2 (flip the order of the two guards): + // + // // initial device is n0 + // { + // CUDAGuard g2(n2); + // { + // CUDAGuard g1(n1); + // // current device should be n1 + // g1 = std::move(g2); + // // current device should be n2 + // } + // // current device should be n0 (since g2 has been vacated) + // } + // + // In both examples, we need g1 to restore to n0 after move assignment. + // However, in example 1, this is determined by the restore value of g1 + // (prior to the move). In example 2, however, it is determined by the the + // restore value of g2(!!). We don't know which one should win, without having + // a way of telling which guard was allocated first. + // + // We could solve this with an extra thread-local variable. But no one is + // actually using move-assignment. So just get rid of it. + InlineOptionalDeviceGuard& operator=(const InlineOptionalDeviceGuard& other) = + delete; + InlineOptionalDeviceGuard& operator=(InlineOptionalDeviceGuard&& other) = + delete; + + /// Sets the device to the given one. Initializes OptionalDeviceGuard if it + /// is not already initialized. + template < + typename U = T, + typename = + typename std::enable_if_t>> + void set_device(at::Device device) { + if (!guard_.has_value()) { + guard_.emplace(device); + } else { + guard_->set_device(device); + } + } + + /// Resets the currently set device to its original device, and then sets the + /// current device to the passed device (for a possibly different device + /// type). Initializes OptionalDeviceGuard if it is not already initialized. + /// + /// See notes on why this is called reset_device on InlineDeviceGuard. + /// + /// Optional argument is for testing only. + template < + typename U = T, + typename = typename std::enable_if_t>> + void reset_device( + at::Device device, + const DeviceGuardImplInterface* impl = nullptr) { + if (!guard_.has_value()) { + guard_.emplace(device, impl); + } else { + guard_->reset_device(device, impl); + } + } + + /// Resets the currently set device to its original device, and then sets the + /// current device to the passed device. Initializes the guard if it is + /// not already initialized. This is effectively equivalent to set_device + /// when a guard supports only a single device type. + template < + typename U = T, + typename = + typename std::enable_if_t>> + void reset_device(at::Device device) { + if (!guard_.has_value()) { + guard_.emplace(device); + } else { + guard_->reset_device(device); + } + } + + /// Sets the device index to the given one. The device type is statically + /// known. + template < + typename U = T, + typename = + typename std::enable_if_t>> + void set_index(DeviceIndex index) { + if (!guard_.has_value()) { + guard_.emplace(index); + } else { + guard_->set_index(index); + } + } + + /// Returns the device that was set immediately prior to initialization of + /// the, guard, or nullopt if the guard is uninitialized. + std::optional original_device() const { + return guard_.has_value() ? std::make_optional(guard_->original_device()) + : std::nullopt; + } + + /// Returns the most recent device that was set using this device guard, + /// either from construction, or via set_device, if the guard is initialized, + /// or nullopt if the guard is uninitialized. + std::optional current_device() const { + return guard_.has_value() ? std::make_optional(guard_->current_device()) + : std::nullopt; + } + + /// Restore the original device, resetting this guard to uninitialized state. + void reset() { + guard_.reset(); + } + + private: + std::optional> guard_; +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/InlineEvent.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/InlineEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..15d4083daab7439295a132ca3b157eae1ba6745d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/InlineEvent.h @@ -0,0 +1,152 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +namespace c10::impl { + +template +struct InlineEvent final { + InlineEvent() = delete; + InlineEvent( + const DeviceType _device_type, + const EventFlag _flag = EventFlag::PYTORCH_DEFAULT) + : backend_{_device_type}, device_type_{_device_type}, flag_{_flag} {} + + // Copy constructor and copy assignment operator (deleted) + InlineEvent(const InlineEvent&) = delete; + InlineEvent& operator=(const InlineEvent&) = delete; + + // Move constructor and move assignment operator + InlineEvent(InlineEvent&& other) noexcept + : event_(other.event_), + backend_(std::move(other.backend_)), + device_type_(other.device_type_), + device_index_(other.device_index_), + flag_(other.flag_), + was_marked_for_recording_(other.was_marked_for_recording_) { + other.event_ = nullptr; + } + InlineEvent& operator=(InlineEvent&& other) noexcept { + swap(other); + return *this; + } + + void swap(InlineEvent& other) noexcept { + std::swap(event_, other.event_); + std::swap(backend_, other.backend_); + std::swap(device_type_, other.device_type_); + std::swap(device_index_, other.device_index_); + std::swap(flag_, other.flag_); + std::swap(was_marked_for_recording_, other.was_marked_for_recording_); + } + + ~InlineEvent() noexcept { + if (event_) + backend_.destroyEvent(event_, device_index_); + } + + DeviceType device_type() const noexcept { + return device_type_; + } + DeviceIndex device_index() const noexcept { + return device_index_; + } + EventFlag flag() const noexcept { + return flag_; + } + bool was_marked_for_recording() const noexcept { + return was_marked_for_recording_; + } + + void recordOnce(const Stream& stream) { + if (!was_marked_for_recording_) + record(stream); + } + + void record(const Stream& stream) { + TORCH_CHECK( + stream.device_type() == device_type_, + "Event device type ", + DeviceTypeName(device_type_), + " does not match recording stream's device type ", + DeviceTypeName(stream.device_type()), + "."); + + backend_.record(&event_, stream, device_index_, flag_); + was_marked_for_recording_ = true; + device_index_ = stream.device_index(); + } + + void block(const Stream& stream) const { + if (!was_marked_for_recording_) + return; + + TORCH_CHECK( + stream.device_type() == device_type_, + "Event device type ", + DeviceTypeName(device_type_), + " does not match blocking stream's device type ", + DeviceTypeName(stream.device_type()), + "."); + + backend_.block(event_, stream); + } + + bool query() const { + if (!was_marked_for_recording_) + return true; + return backend_.queryEvent(event_); + } + + void* eventId() const { + return event_; + } + + double elapsedTime(const InlineEvent& other) const { + TORCH_CHECK( + other.device_type() == device_type_, + "Event device type ", + DeviceTypeName(device_type_), + " does not match other's device type ", + DeviceTypeName(other.device_type()), + "."); + TORCH_CHECK_VALUE( + (flag_ == EventFlag::BACKEND_DEFAULT) && + (other.flag_ == EventFlag::BACKEND_DEFAULT), + "Both events must be created with argument 'enable_timing=True'."); + TORCH_CHECK_VALUE( + was_marked_for_recording() && other.was_marked_for_recording(), + "Both events must be recorded before calculating elapsed time."); + // elapsedTime in MPS can wait event to be completed if event is not ready, + // which is a little different from CUDA + TORCH_CHECK( + (query() && other.query()) || device_type_ == DeviceType::MPS, + "Both events must be completed before calculating elapsed time."); + + return backend_.elapsedTime(event_, other.event_, device_index_); + } + + void synchronize() const { + if (!was_marked_for_recording_) + return; + backend_.synchronizeEvent(event_); + } + + private: + void* event_ = nullptr; + T backend_; + DeviceType device_type_; + DeviceIndex device_index_ = -1; + EventFlag flag_ = EventFlag::PYTORCH_DEFAULT; + bool was_marked_for_recording_ = false; +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/InlineStreamGuard.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/InlineStreamGuard.h new file mode 100644 index 0000000000000000000000000000000000000000..7ce87a9a8eb55a30e8e6fb0ab6e5a38bc065dab9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/InlineStreamGuard.h @@ -0,0 +1,265 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10::impl { + +/** + * A StreamGuard is an RAII class that changes the current device + * to the device corresponding to some stream, and changes the + * default stream on that device to be this stream. + * + * InlineStreamGuard is a helper class for implementing StreamGuards. + * See InlineDeviceGuard for guidance on how to use this class. + */ +template +class InlineStreamGuard : private InlineDeviceGuard { + public: + /// No default constructor, see Note [Omitted default constructor from RAII] + explicit InlineStreamGuard() = delete; + + /// Set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream. + explicit InlineStreamGuard(Stream stream) + : InlineDeviceGuard(stream.device()), + original_stream_of_original_device_( + this->impl_.getStream(original_device())), + original_stream_of_current_device_(this->impl_.exchangeStream(stream)), + current_stream_(stream) {} + + /// This constructor exists purely for testing + template < + typename U = T, + typename = typename std::enable_if_t>> + explicit InlineStreamGuard( + Stream stream, + const DeviceGuardImplInterface* impl) + : InlineDeviceGuard( + stream.device(), + impl ? impl : getDeviceGuardImpl(stream.device_type())), + original_stream_of_original_device_( + this->impl_.getStream(original_device())), + original_stream_of_current_device_(this->impl_.exchangeStream(stream)), + current_stream_(stream) {} + + /// Copy is disallowed + InlineStreamGuard(const InlineStreamGuard&) = delete; + InlineStreamGuard& operator=(const InlineStreamGuard&) = delete; + + /// Move is disallowed, as StreamGuard does not have an uninitialized state, + /// which is required for moves on types with nontrivial destructors. + InlineStreamGuard(InlineStreamGuard&& other) = delete; + InlineStreamGuard& operator=(InlineStreamGuard&& other) = delete; + + ~InlineStreamGuard() { + this->impl_.exchangeStream(original_stream_of_current_device_); + } + + /// Resets the currently set stream to the original stream and + /// the currently set device to the original device. Then, + /// set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream. + /// + /// NOTE: this implementation may skip some stream/device setting if + /// it can prove that it is unnecessary. + /// + /// WARNING: reset_stream does NOT preserve previously set streams on + /// different devices. If you need to set streams on multiple devices + /// use MultiStreamGuard instead. + void reset_stream(Stream stream) { + // TODO: make a version that takes an impl argument. Unfortunately, + // that will require SFINAE because impl is only valid for the + // VirtualGuardImpl specialization. + if (stream.device() == this->current_device()) { + this->impl_.exchangeStream(stream); + current_stream_ = stream; + } else { + // Destruct and reconstruct the StreamGuard in-place + this->impl_.exchangeStream(original_stream_of_current_device_); + this->reset_device(stream.device()); + original_stream_of_current_device_ = this->impl_.exchangeStream(stream); + current_stream_ = stream; + } + } + + // It's not clear if set_device should also reset the current stream + // if the device is unchanged; therefore, we don't provide it. + // The situation is somewhat clearer with reset_device, but it's still + // a pretty weird thing to do, so haven't added this either. + + /// Returns the stream of the original device prior to this guard. Subtly, + /// the stream returned here is the original stream of the *original* + /// device; i.e., it's the stream that your computation *would* have + /// been put on, if it hadn't been for this meddling stream guard. + /// This is usually what you want. + Stream original_stream() const { + return original_stream_of_original_device_; + } + + /// Returns the most recent stream that was set using this device guard, + /// either from construction, or via set_stream. + Stream current_stream() const { + return current_stream_; + } + + /// Returns the most recent device that was set using this device guard, + /// either from construction, or via set_device/reset_device/set_index. + Device current_device() const { + return InlineDeviceGuard::current_device(); + } + + /// Returns the device that was set at the most recent reset_stream(), + /// or otherwise the device at construction time. + Device original_device() const { + return InlineDeviceGuard::original_device(); + } + + private: + Stream + original_stream_of_original_device_; // what the user probably cares about + Stream original_stream_of_current_device_; // what we need to restore + Stream current_stream_; +}; + +/** + * An OptionalStreamGuard is an RAII class that sets a device to some value on + * initialization, and resets the device to its original value on destruction. + * See InlineOptionalDeviceGuard for more guidance on how to use this class. + */ +template +class InlineOptionalStreamGuard { + public: + /// Creates an uninitialized stream guard. + explicit InlineOptionalStreamGuard() + : guard_() // See Note [Explicit initialization of optional fields] + {} + ~InlineOptionalStreamGuard() = default; + + /// Set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream, + /// if the passed stream is not nullopt. + explicit InlineOptionalStreamGuard(std::optional stream_opt) + : guard_() { + if (stream_opt.has_value()) { + guard_.emplace(stream_opt.value()); + } + } + + /// All constructors of StreamGuard are valid for OptionalStreamGuard + template + explicit InlineOptionalStreamGuard(Args&&... args) + : guard_(std::in_place, std::forward(args)...) {} + + InlineOptionalStreamGuard(const InlineOptionalStreamGuard& other) = delete; + InlineOptionalStreamGuard& operator=(const InlineOptionalStreamGuard& other) = + delete; + // See Note [Move construction for RAII guards is tricky] + InlineOptionalStreamGuard(InlineOptionalStreamGuard&& other) = delete; + + // See Note [Move assignment for RAII guards is tricky] + InlineOptionalStreamGuard& operator=(InlineOptionalStreamGuard&& other) = + delete; + + /// Resets the currently set stream to the original stream and + /// the currently set device to the original device. Then, + /// set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream. + /// Initializes the OptionalStreamGuard if it was not previously initialized. + void reset_stream(Stream stream) { + if (guard_.has_value()) { + guard_->reset_stream(stream); + } else { + guard_.emplace(stream); + } + } + + /// Returns the stream that was set at the time the guard was most recently + /// initialized, or nullopt if the guard is uninitialized. + std::optional original_stream() const { + return guard_.has_value() ? std::make_optional(guard_->original_stream()) + : std::nullopt; + } + + /// Returns the most recent stream that was set using this stream guard, + /// either from construction, or via reset_stream, if the guard is + /// initialized, or nullopt if the guard is uninitialized. + std::optional current_stream() const { + return guard_.has_value() ? std::make_optional(guard_->current_stream()) + : std::nullopt; + } + + /// Restore the original device and stream, resetting this guard to + /// uninitialized state. + void reset() { + guard_.reset(); + } + + private: + std::optional> guard_; +}; + +template +class InlineMultiStreamGuard { + public: + /// Calls `set_stream` on each of the streams in the list. + /// This may be useful if you need to set different streams + /// for different devices. + explicit InlineMultiStreamGuard(ArrayRef streams) { + if (!streams.empty()) { + impl_.emplace(getDeviceTypeOfStreams(streams)); + original_streams_.reserve(streams.size()); + for (const Stream& s : streams) { + original_streams_.emplace_back(this->impl_->exchangeStream(s)); + } + } + } + + /// Copy is disallowed + InlineMultiStreamGuard(const InlineMultiStreamGuard&) = delete; + InlineMultiStreamGuard& operator=(const InlineMultiStreamGuard&) = delete; + + /// Move is disallowed, as StreamGuard does not have an uninitialized state, + /// which is required for moves on types with nontrivial destructors. + InlineMultiStreamGuard(InlineMultiStreamGuard&& other) = delete; + InlineMultiStreamGuard& operator=(InlineMultiStreamGuard&& other) = delete; + + ~InlineMultiStreamGuard() noexcept { + if (this->impl_.has_value()) { + for (const Stream& s : original_streams_) { + this->impl_->exchangeStream(s); + } + } + } + + protected: + std::optional impl_; + + private: + /// The original streams that were active on all devices. + std::vector original_streams_; + + static DeviceType getDeviceTypeOfStreams(ArrayRef streams) { + TORCH_INTERNAL_ASSERT(!streams.empty()); + DeviceType type = streams[0].device_type(); + for (const auto idx : c10::irange(1, streams.size())) { + TORCH_CHECK_VALUE( + streams[idx].device_type() == type, + "Streams have a mix of device types: stream 0 is on ", + streams[0].device(), + " while stream ", + idx, + " is on device ", + streams[idx].device()); + } + return type; + } +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/LocalDispatchKeySet.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/LocalDispatchKeySet.h new file mode 100644 index 0000000000000000000000000000000000000000..3b288627047eada813c500f50158f1d3950a84e4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/LocalDispatchKeySet.h @@ -0,0 +1,174 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +// TLS management for DispatchKeySet (the "local" DispatchKeySet(s)) +// +// This manages two thread-local DispatchKeySets: +// +// - The included type set, which adds a tensor type for consideration +// in dispatch. (For example, you might add Profiling to +// the included type set to turn on profiling on all tensor operations.) +// +// - The excluded type set, which disqualifies a tensor type from dispatch. +// (For example, after redispatching on variable, we disqualify +// Autograd so we don't attempt to handle variable again.) +// (Exclusion wins over inclusion.) +// +// NB: Originally, I implemented the excluded type set as storing the inverted +// set, but TLS is defined to be zero-initialized, so this doesn't actually work +// (if it's inverted, you want the set to be -1 initialized). + +namespace c10::impl { + +// POD version of LocalDispatchKeySet. Declared here just so that +// we can put it in the guards. +// This struct encapsulates special handling for TLS initialization +// in set_included()/included() API so that they reflect the truth. +// If you want to create PODLocalDispatchKeySet with non-zero state, +// use set_included() instead of default constructor. +struct C10_API PODLocalDispatchKeySet { + uint64_t included_; + uint64_t excluded_; + + // See Note [TLS Initialization] + DispatchKeySet included() const { + return DispatchKeySet(DispatchKeySet::RAW, included_) ^ + c10::default_included_set; + } + DispatchKeySet excluded() const { + return DispatchKeySet(DispatchKeySet::RAW, excluded_) ^ + c10::default_excluded_set; + } + + void set_included(DispatchKeySet x) { + included_ = (x ^ c10::default_included_set).raw_repr(); + } + void set_excluded(DispatchKeySet x) { + excluded_ = (x ^ c10::default_excluded_set).raw_repr(); + } +}; +static_assert( + std::is_trivial_v, + "PODLocalDispatchKeySet must be a POD type."); + +struct C10_API LocalDispatchKeySet { + /* implicit */ LocalDispatchKeySet(PODLocalDispatchKeySet x) + : included_(x.included()), excluded_(x.excluded()) {} + DispatchKeySet included_; + DispatchKeySet excluded_; +}; + +// thread_local variables cannot be C10_API on Windows. +// Inlining this seems to break AutoDispatchBelowAutograd on Android. +#if defined(_MSC_VER) || defined(C10_ANDROID) || defined(C10_IPHONE) +C10_API LocalDispatchKeySet tls_local_dispatch_key_set(); +#else // defined(_MSC_VER) || defined(C10_ANDROID) || defined(C10_IPHONE) +extern C10_API thread_local PODLocalDispatchKeySet raw_local_dispatch_key_set; + +inline C10_API LocalDispatchKeySet tls_local_dispatch_key_set() { + // Don't let people fiddle with the thread_local directly just + // because they include this header. + return raw_local_dispatch_key_set; +} +#endif // defined(_MSC_VER) || defined(C10_ANDROID) || defined(C10_IPHONE) + +// Internal, use ThreadLocalStateGuard +C10_API void _force_tls_local_dispatch_key_set(LocalDispatchKeySet key_set); + +// RAII API for manipulating the thread-local dispatch state. + +class C10_API IncludeDispatchKeyGuard { + public: + IncludeDispatchKeyGuard(DispatchKeySet /*include*/); + IncludeDispatchKeyGuard(DispatchKey k) + : IncludeDispatchKeyGuard(DispatchKeySet(k)) {} + IncludeDispatchKeyGuard(const IncludeDispatchKeyGuard&) = delete; + IncludeDispatchKeyGuard operator=(const IncludeDispatchKeyGuard&) = delete; + IncludeDispatchKeyGuard(IncludeDispatchKeyGuard&&) = delete; + IncludeDispatchKeyGuard operator=(IncludeDispatchKeyGuard&&) = delete; + ~IncludeDispatchKeyGuard(); + + private: + // A little micro-optimization to save us from tls_get_addr call + // on destruction + PODLocalDispatchKeySet* tls_; + DispatchKeySet saved_state_; +}; + +class C10_API ExcludeDispatchKeyGuard { + public: + ExcludeDispatchKeyGuard(DispatchKeySet /*exclude*/); + ExcludeDispatchKeyGuard(DispatchKey k) + : ExcludeDispatchKeyGuard(DispatchKeySet(k)) {} + ExcludeDispatchKeyGuard(const ExcludeDispatchKeyGuard&) = delete; + ExcludeDispatchKeyGuard operator=(const ExcludeDispatchKeyGuard&) = delete; + ExcludeDispatchKeyGuard(ExcludeDispatchKeyGuard&&) = delete; + ExcludeDispatchKeyGuard operator=(ExcludeDispatchKeyGuard&&) = delete; + ~ExcludeDispatchKeyGuard(); + + private: + // A little micro-optimization to save us from tls_get_addr call + // on destruction + PODLocalDispatchKeySet* tls_; + DispatchKeySet saved_state_; +}; + +struct C10_API ForceDispatchKeyGuard { + public: + ForceDispatchKeyGuard() + : saved_keyset_(c10::impl::tls_local_dispatch_key_set()) {} + ForceDispatchKeyGuard(c10::impl::LocalDispatchKeySet key_set) + : ForceDispatchKeyGuard() { + c10::impl::_force_tls_local_dispatch_key_set(key_set); + } + ForceDispatchKeyGuard( + c10::DispatchKeySet include, + c10::DispatchKeySet exclude) + : ForceDispatchKeyGuard() { + auto updated_set = saved_keyset_; + updated_set.included_ = include; + updated_set.excluded_ = exclude; + c10::impl::_force_tls_local_dispatch_key_set(updated_set); + } + + ForceDispatchKeyGuard(ForceDispatchKeyGuard&&) noexcept = delete; + ForceDispatchKeyGuard(const ForceDispatchKeyGuard&) = delete; + ForceDispatchKeyGuard& operator=(const ForceDispatchKeyGuard&) = delete; + ForceDispatchKeyGuard& operator=(ForceDispatchKeyGuard&&) = delete; + ~ForceDispatchKeyGuard() { + c10::impl::_force_tls_local_dispatch_key_set(saved_keyset_); + } + + private: + c10::impl::LocalDispatchKeySet saved_keyset_; +}; + +// Non-RAII API for manipulating the thread-local dispatch state. +// Please prefer the RAII API. The non-RAII API may be useful when +// the included/excluded state of a given DispatchKey must span +// many calls from the Python to the C++, so you cannot conveniently +// use an RAII guard. +// +// Example use case: a Python context manager that includes a certain +// DispatchKey, to ensure ops running under the context manager dispatch +// through that DispatchKey's registered overrides. +// +// The non-RAII API is less efficient than the RAII guards because both the +// getter and setter will do a tls_getaddr lookup (the RAII struct only needs +// one!) + +C10_API bool tls_is_dispatch_key_excluded(DispatchKey x); +C10_API void tls_set_dispatch_key_excluded(DispatchKey x, bool desired_state); +C10_API bool tls_is_dispatch_key_included(DispatchKey x); +C10_API void tls_set_dispatch_key_included(DispatchKey x, bool desired_state); +C10_API bool tls_is_dispatch_keyset_excluded(DispatchKeySet ks); +C10_API bool tls_is_dispatch_keyset_included(DispatchKeySet ks); + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PyInterpreter.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PyInterpreter.h new file mode 100644 index 0000000000000000000000000000000000000000..ce74e9b9050b3db0db196ff4ef9f3cad198c9beb --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PyInterpreter.h @@ -0,0 +1,257 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Forward declarations + +namespace c10 { +struct IValue; +class OperatorHandle; +struct TensorImpl; +namespace impl { +struct PyObjectSlot; +} // namespace impl +} // namespace c10 + +namespace torch::jit { +using Stack = std::vector; +} + +// Actual implementation + +namespace c10::impl { + +struct C10_API PyInterpreter; + +// Note [Python interpreter tag] +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Traditionally, PyTorch is layered such that our Python library +// (libtorch_python) references our pure C++ library (libtorch) as the +// natural order of things. However, sometimes this natural order is +// subverted: C++ objects refer to Python objects (for example, we +// store a PyObject* pointer on TensorImpl so that converting from a +// C++ Tensor to a Python Tensor is just a memory dereference). +// +// These unusual orderings must be treated with care. To start, you need to +// virtualize the destructor so that the PyObject can be decref'ed on +// destruction (because the C++ object itself doesn't know anything about +// Python--remember, layering!). This process itself is fraught, since +// acquiring the GIL could lead to deadlocks if someone is blocking on you +// while holding the GIL. Furthermore, if the C++ objects outlive the +// interpreter (which can happen if you stash them in a static global +// variable defined in libtorch), you may attempt to decref the object when +// the Python interpreter has already been shutdown. +// +// BUT WAIT, IT GETS WORSE. With torchdeploy, there may be multiple Python +// interpreters in a single process. If a C++ object is accessible from +// multiple interpreters, we must take care not to accidentally pass a +// PyObject from one interpreter with another interpreter. +// +// To prevent these mixups, we introduce a PyInterpreter "tag" (object with +// a vtable), which specifies a specific Python interpreter. +// +// - Any given object can be associated with AT MOST one Python interpreter. +// We represent the interpreter tag as a memory address to an instance of +// a virtual class that is allocated once per interpreter (this is so that +// we can request the interpreter to perform operations for us, if +// necessary). +// +// - It can be recorded with a PyObject (PyInterpreterObject) so that +// we know what interpreter the object is associated with, and we can +// raise an error if you try to use the PyObject from the wrong +// interpreter context. +// +// - It contains a vtable that can be used to perform various Python +// operations from ordinary C++ code that ordinarily wouldn't be accessible +// from libtorch. +// +// A simple use case is when a C++ object must be associated with a PyObject. +// However, for TensorImpl, we lazily allocate a PyObject the first time the +// object passes into Python. The invariants for this situation are more +// subtle: +// +// - A given TensorImpl's interpreter tag can only go from uninitialized to +// tagged; once tagged, this is a quiescent state (once tagged to an +// interpreter, ALWAYS tagged to that interpreter) +// +// - A thread may mutate the PyObject field of a TensorImpl if and only if it +// holds the GIL for the interpreter tagged on the TensorImpl. (If the +// TensorImpl is not tagged, it must first atomically claim its tag before it +// can validly write) +// +// WARNING: This class has to be written very carefully, because it may be +// possible for a Tensor to have a reference an interpreter corresponding to +// a shared library that has ALREADY BEEN UNLOADED. This makes blindly calling +// virtual methods very dangerous, because the vtable may be garbage at that +// point (on a good day, you might get "pure virtual method called"). +// +// The idea to solve this problem is we always leak PyInterpreters (so they +// always stay live even after dlclose), and make sure we can disarm their +// virtual methods by indirecting through a separate PyInterpreterVTable +// object. This can be replaced with a no-op vtable from libc10.so, which +// is guaranteed to stick around until the bitter end. +// +// NB: The downside with representing PyInterpreter tags as full objects is that +// it takes an extra word on TensorImpl. If tags were instead just integer +// indices, on 64-bit architectures we could pack the tag and PyObject together +// into a single atomic word. On 32-bit architectures we could simply say that +// only one Python interpreter is supported (erroring if a nontrivial +// interpreter tag is attempted to be set). +// +// The difficulty with this scheme is we need to maintain an out-of-line table +// to get at the PyInterpreters so that we can do virtual method calls on them, +// and registration/deregistration to this table must be done in a thread safe +// manner. This can be easily done if the number of possible PyInterpreters is +// small enough (e.g., 8-bit integer) by simply preallocating an array of +// sufficient size to hold all possible interpreters. Surely 128 threads is +// more than enough for anyone! +// +// I didn't decide to do this technique at the moment, because the extra word +// added by the PyInterpreter tag takes us to 24 words, which means that we +// still fit inside three eight word cache lines. If you need to penny pinch +// another word consider doing this! + +struct C10_API PyInterpreterVTable { + virtual ~PyInterpreterVTable() = default; + + // Report the name of this interpreter + virtual std::string name() const = 0; + + // Run Py_INCREF on a PyObject. + virtual void incref(PyObject* pyobj) const = 0; + // Run Py_DECREF on a PyObject. We DO NOT assume the GIL is held on call. + virtual void decref(PyObject* pyobj) const = 0; + // Run PyUnstable_TryIncRef on a PyObject if it's not NULL. + virtual bool try_incref(const c10::impl::PyObjectSlot& pyobj_slot) const = 0; + // Run Py_REFCNT on a PyObject. + virtual size_t refcnt(PyObject* pyobj) const = 0; + + // Perform a detach by deferring to the __torch_dispatch__ implementation of + // detach, which will also arrange for the PyObject to get copied in this + // situation + virtual c10::intrusive_ptr detach( + const TensorImpl* self) const = 0; + + // Invoke the Python boxed fallback dispatch to go back into Python + virtual void dispatch(const c10::OperatorHandle& op, torch::jit::Stack* stack) + const = 0; + + virtual void reportErrorCallback(PyObject* callback, DispatchKey key) + const = 0; + + // This is only invoked in the multipy/torchdeploy // codespell:ignore multipy + // situation from pythonOpRegistrationTrampoline; this lets us get to the + // Python interpreter to actually find the appropriate Python op registration + // entry to call. + virtual void python_op_registration_trampoline( + const c10::OperatorHandle& op, + c10::DispatchKey, + c10::DispatchKeySet keyset, + torch::jit::Stack* stack, + bool with_keyset, + bool with_op) const = 0; + + virtual void throw_abstract_impl_not_imported_error( + std::string opname, + const char* pymodule, + const char* context) const = 0; + + // Invoke the Python dispatcher to handle this call + virtual void python_dispatcher( + const c10::OperatorHandle& op, + c10::DispatchKeySet, + torch::jit::Stack* stack) const = 0; + + virtual bool is_contiguous(const TensorImpl* self, at::MemoryFormat) + const = 0; + virtual c10::SymBool sym_is_contiguous( + const TensorImpl* self, + at::MemoryFormat) const = 0; + virtual bool is_strides_like(const TensorImpl* self, at::MemoryFormat) + const = 0; + virtual bool is_non_overlapping_and_dense(const TensorImpl* self) const = 0; + virtual c10::Device device(const TensorImpl* self) const = 0; + virtual int64_t dim(const TensorImpl* self) const = 0; + virtual c10::IntArrayRef strides(const TensorImpl* self) const = 0; + virtual c10::IntArrayRef sizes(const TensorImpl* self) const = 0; + virtual c10::SymIntArrayRef sym_sizes(const TensorImpl* self) const = 0; + virtual c10::Layout layout(const TensorImpl* self) const = 0; + virtual int64_t numel(const TensorImpl* self) const = 0; + virtual c10::SymInt sym_numel(const TensorImpl* self) const = 0; + virtual c10::SymIntArrayRef sym_strides(const TensorImpl* self) const = 0; + virtual c10::SymInt sym_storage_offset(const TensorImpl* self) const = 0; + + virtual void trace_gpu_event_creation( + c10::DeviceType device_type, + uintptr_t event) const = 0; + virtual void trace_gpu_event_deletion( + c10::DeviceType device_type, + uintptr_t event) const = 0; + virtual void trace_gpu_event_record( + c10::DeviceType device_type, + uintptr_t event, + uintptr_t stream) const = 0; + virtual void trace_gpu_event_wait( + c10::DeviceType device_type, + uintptr_t event, + uintptr_t stream) const = 0; + virtual void trace_gpu_memory_allocation( + c10::DeviceType device_type, + uintptr_t ptr) const = 0; + virtual void trace_gpu_memory_deallocation( + c10::DeviceType device_type, + uintptr_t ptr) const = 0; + virtual void trace_gpu_stream_creation( + c10::DeviceType device_type, + uintptr_t stream) const = 0; + virtual void trace_gpu_device_synchronization( + c10::DeviceType device_type) const = 0; + virtual void trace_gpu_stream_synchronization( + c10::DeviceType device_type, + uintptr_t stream) const = 0; + virtual void trace_gpu_event_synchronization( + c10::DeviceType device_type, + uintptr_t event) const = 0; + + virtual void reset_backward_hooks(const TensorImpl* self) const = 0; +}; + +struct C10_API PyInterpreter { + const PyInterpreterVTable* vtable_; + + PyInterpreter(const PyInterpreterVTable* vtable) : vtable_(vtable) {} + + const PyInterpreterVTable& operator*() const noexcept { + return *vtable_; + } + const PyInterpreterVTable* operator->() const noexcept { + return vtable_; + } + + // Disarm this PyInterpreter, making all of its methods noops. + // The vtable pointer is not an atomic at the moment, which means + // a disarm() invocation that is concurrent with active destructors + // is not thread safe and will trigger TSAN. My hope is that this + // situations doesn't ever actually happen; tensor destruction should + // quiesce when a dlclose happens, and any long lived tensors whose + // destructors would be disarmed here only begin the destruction process + // on process shutdown (long after the dlclose has occurred). + void disarm() noexcept; +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PyInterpreterHooks.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PyInterpreterHooks.h new file mode 100644 index 0000000000000000000000000000000000000000..acd2003569302cffcce5a907bd7fd506ac984a7b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PyInterpreterHooks.h @@ -0,0 +1,45 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +namespace c10::impl { + +// Minimal interface for PyInterpreter hooks +struct C10_API PyInterpreterHooksInterface { + virtual ~PyInterpreterHooksInterface() = default; + + // Get the PyInterpreter instance + // Stub implementation throws error when Python is not available + virtual PyInterpreter* getPyInterpreter() const { + TORCH_CHECK( + false, + "PyTorch was compiled without Python support. " + "Cannot access Python interpreter from C++."); + } +}; + +struct C10_API PyInterpreterHooksArgs{}; + +C10_DECLARE_REGISTRY( + PyInterpreterHooksRegistry, + PyInterpreterHooksInterface, + PyInterpreterHooksArgs); + +#define REGISTER_PYTHON_HOOKS(clsname) \ + C10_REGISTER_CLASS(PyInterpreterHooksRegistry, clsname, clsname) + +// Get the global PyInterpreter hooks instance +C10_API const PyInterpreterHooksInterface& getPyInterpreterHooks(); + +// Helper function to get the global interpreter +C10_API PyInterpreter* getGlobalPyInterpreter(); + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PyObjectSlot.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PyObjectSlot.h new file mode 100644 index 0000000000000000000000000000000000000000..8ba0688f66e597d4398d4a7d0407b2683ceb30aa --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PyObjectSlot.h @@ -0,0 +1,70 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace torch::utils { +class PyObjectPreservation; +} + +namespace c10::impl { + +struct C10_API PyObjectSlot { + public: + PyObjectSlot() : pyobj_interpreter_(nullptr), pyobj_(nullptr) {} + + // Query the PyObject interpreter. This may return null if there is no + // interpreter. + PyInterpreter* pyobj_interpreter() const { + return pyobj_interpreter_.load(std::memory_order_acquire); + } + + PyInterpreter& load_pyobj_interpreter() const { + auto interpreter = pyobj_interpreter_.load(std::memory_order_acquire); + TORCH_INTERNAL_ASSERT( + interpreter, "cannot access PyObject for Tensor - no interpreter set"); + return *interpreter; + } + + PyObject* load_pyobj() const { + return pyobj_.load(std::memory_order_acquire); + } + + void store_pyobj(PyObject* obj) { + pyobj_.store(obj, std::memory_order_release); + } + + bool has_unique_reference() const { + PyObject* pyobj = load_pyobj(); + return pyobj != nullptr && load_pyobj_interpreter()->refcnt(pyobj) == 1; + } + + void clear() { + pyobj_.store(nullptr, std::memory_order_relaxed); + pyobj_interpreter_.store(nullptr, std::memory_order_relaxed); + } + + private: + // This is now always the global interpreter if the PyObject is set. + // Maybe we can remove this field some day... + std::atomic pyobj_interpreter_; + + // The PyObject representing this Tensor or nullptr. Ownership is managed + // by intrusive_ptr. By the time the PyObjectSlot is destroyed, this + // reference is already dead. + std::atomic pyobj_; + + friend class torch::utils::PyObjectPreservation; +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PythonDispatcherTLS.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PythonDispatcherTLS.h new file mode 100644 index 0000000000000000000000000000000000000000..cffb7fc31e3d18b4544027b261b98c686f81274a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/PythonDispatcherTLS.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10::impl { + +struct C10_API PythonDispatcherTLS { + static void set_state(PyInterpreter* state); + static PyInterpreter* get_state(); + static void reset_state(); +}; + +struct C10_API DisablePythonDispatcher { + DisablePythonDispatcher() : old_(PythonDispatcherTLS::get_state()) { + PythonDispatcherTLS::set_state({}); + } + + DisablePythonDispatcher(DisablePythonDispatcher&& other) = delete; + DisablePythonDispatcher(const DisablePythonDispatcher&) = delete; + DisablePythonDispatcher& operator=(const DisablePythonDispatcher&) = delete; + DisablePythonDispatcher& operator=(DisablePythonDispatcher&&) = delete; + ~DisablePythonDispatcher() { + PythonDispatcherTLS::set_state(old_); + } + PyInterpreter* old_; +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/SizesAndStrides.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/SizesAndStrides.h new file mode 100644 index 0000000000000000000000000000000000000000..da3a9a0c4abacf6165ca946e62257771cf2790ce --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/SizesAndStrides.h @@ -0,0 +1,336 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include +#include +#include + +#define C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE 5 + +namespace c10::impl { + +// Packed container for TensorImpl sizes and strides. +// This design improves on the previous approach of using a pair of +// c10::SmallVector by specializing for the operations we +// actually use and enforcing that the number of sizes is the same as +// the number of strides. The memory layout is as follows: +// +// 1 size_t for the size +// 5 eightbytes of inline sizes and 5 eightbytes of inline strides, OR pointer +// to out-of-line array +class C10_API SizesAndStrides { + public: + // TODO: different iterator types for sizes & strides to prevent + // mixing the two accidentally. + using sizes_iterator = int64_t*; + using sizes_const_iterator = const int64_t*; + using strides_iterator = int64_t*; + using strides_const_iterator = const int64_t*; + + SizesAndStrides() { + size_at_unchecked(0) = 0; + stride_at_unchecked(0) = 1; + } + + ~SizesAndStrides() { + if (C10_UNLIKELY(!isInline())) { + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + free(outOfLineStorage_); + } + } + + SizesAndStrides(const SizesAndStrides& rhs) : size_(rhs.size_) { + if (C10_LIKELY(rhs.isInline())) { + copyDataInline(rhs); + } else { + allocateOutOfLineStorage(size_); + copyDataOutline(rhs); + } + } + + bool operator==(const SizesAndStrides& other) const { + if (size_ != other.size_) { + return false; + } + return !( + isInline() + ? std::memcmp( + inlineStorage_, other.inlineStorage_, sizeof(inlineStorage_)) + : std::memcmp( + outOfLineStorage_, + other.outOfLineStorage_, + storageBytes(size_))); + } + + bool operator!=(const SizesAndStrides& other) const { + return !(*this == other); + } + + SizesAndStrides& operator=(const SizesAndStrides& rhs) { + if (this == &rhs) { + return *this; + } + if (C10_LIKELY(rhs.isInline())) { + if (C10_UNLIKELY(!isInline())) { + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + free(outOfLineStorage_); + } + copyDataInline(rhs); + } else { + if (isInline()) { + allocateOutOfLineStorage(rhs.size_); + } else { + resizeOutOfLineStorage(rhs.size_); + } + copyDataOutline(rhs); + } + size_ = rhs.size_; + return *this; + } + + // Move from rhs. rhs.size() == 0 afterwards. + SizesAndStrides(SizesAndStrides&& rhs) noexcept : size_(rhs.size_) { + if (C10_LIKELY(isInline())) { + memcpy(inlineStorage_, rhs.inlineStorage_, sizeof(inlineStorage_)); + } else { + outOfLineStorage_ = rhs.outOfLineStorage_; + rhs.outOfLineStorage_ = nullptr; + } + + rhs.size_ = 0; + } + + // Move from rhs. rhs.size() == 0 afterwards. + SizesAndStrides& operator=(SizesAndStrides&& rhs) noexcept { + if (this == &rhs) { + return *this; + } + if (C10_LIKELY(rhs.isInline())) { + if (C10_UNLIKELY(!isInline())) { + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + free(outOfLineStorage_); + } + copyDataInline(rhs); + } else { + // They're outline. We're going to steal their vector. + if (!isInline()) { + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + free(outOfLineStorage_); + } + outOfLineStorage_ = rhs.outOfLineStorage_; + rhs.outOfLineStorage_ = nullptr; + } + size_ = rhs.size_; + rhs.size_ = 0; + + return *this; + } + + size_t size() const noexcept { + return size_; + } + + const int64_t* sizes_data() const noexcept { + if (C10_LIKELY(isInline())) { + return &inlineStorage_[0]; + } else { + return &outOfLineStorage_[0]; + } + } + + int64_t* sizes_data() noexcept { + if (C10_LIKELY(isInline())) { + return &inlineStorage_[0]; + } else { + return &outOfLineStorage_[0]; + } + } + + sizes_const_iterator sizes_begin() const noexcept { + return sizes_data(); + } + + sizes_iterator sizes_begin() noexcept { + return sizes_data(); + } + + sizes_const_iterator sizes_end() const noexcept { + return sizes_begin() + size(); + } + + sizes_iterator sizes_end() noexcept { + return sizes_begin() + size(); + } + + IntArrayRef sizes_arrayref() const noexcept { + return IntArrayRef{sizes_data(), size()}; + } + + void set_sizes(IntArrayRef newSizes) { + resize(newSizes.size()); + std::copy(newSizes.begin(), newSizes.end(), sizes_begin()); + } + + void set_strides(IntArrayRef strides) { + TORCH_INTERNAL_ASSERT(strides.size() == size()); + std::copy(strides.begin(), strides.end(), strides_begin()); + } + + const int64_t* strides_data() const noexcept { + if (C10_LIKELY(isInline())) { + return &inlineStorage_[C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE]; + } else { + return &outOfLineStorage_[size()]; + } + } + + int64_t* strides_data() noexcept { + if (C10_LIKELY(isInline())) { + return &inlineStorage_[C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE]; + } else { + return &outOfLineStorage_[size()]; + } + } + + strides_const_iterator strides_begin() const noexcept { + if (C10_LIKELY(isInline())) { + return &inlineStorage_[C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE]; + } else { + return &outOfLineStorage_[size()]; + } + } + + strides_iterator strides_begin() noexcept { + if (C10_LIKELY(isInline())) { + return &inlineStorage_[C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE]; + } else { + return &outOfLineStorage_[size()]; + } + } + + strides_const_iterator strides_end() const noexcept { + return strides_begin() + size(); + } + + strides_iterator strides_end() noexcept { + return strides_begin() + size(); + } + + IntArrayRef strides_arrayref() const noexcept { + return IntArrayRef{strides_data(), size()}; + } + + // Size accessors. + int64_t size_at(size_t idx) const noexcept { + assert(idx < size()); + return sizes_data()[idx]; + } + + int64_t& size_at(size_t idx) noexcept { + assert(idx < size()); + return sizes_data()[idx]; + } + + int64_t size_at_unchecked(size_t idx) const noexcept { + return sizes_data()[idx]; + } + + int64_t& size_at_unchecked(size_t idx) noexcept { + return sizes_data()[idx]; + } + + // Size accessors. + int64_t stride_at(size_t idx) const noexcept { + assert(idx < size()); + return strides_data()[idx]; + } + + int64_t& stride_at(size_t idx) noexcept { + assert(idx < size()); + return strides_data()[idx]; + } + + int64_t stride_at_unchecked(size_t idx) const noexcept { + return strides_data()[idx]; + } + + int64_t& stride_at_unchecked(size_t idx) noexcept { + return strides_data()[idx]; + } + + void resize(size_t newSize) { + const auto oldSize = size(); + if (newSize == oldSize) { + return; + } + if (C10_LIKELY( + newSize <= C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE && isInline())) { + if (oldSize < newSize) { + const auto bytesToZero = + (newSize - oldSize) * sizeof(inlineStorage_[0]); + memset(&inlineStorage_[oldSize], 0, bytesToZero); + memset( + &inlineStorage_[C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE + oldSize], + 0, + bytesToZero); + } + size_ = newSize; + } else { + resizeSlowPath(newSize, oldSize); + } + } + + void resizeSlowPath(size_t newSize, size_t oldSize); + + private: + bool isInline() const noexcept { + return size_ <= C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE; + } + + void copyDataInline(const SizesAndStrides& rhs) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(rhs.isInline()); + memcpy(inlineStorage_, rhs.inlineStorage_, sizeof(inlineStorage_)); + } + + static size_t storageBytes(size_t size) noexcept { + return size * 2 * sizeof(int64_t); + } + + void allocateOutOfLineStorage(size_t size) { + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + outOfLineStorage_ = static_cast(malloc(storageBytes(size))); + TORCH_CHECK( + outOfLineStorage_, + "Could not allocate memory for Tensor SizesAndStrides!"); + } + + void resizeOutOfLineStorage(size_t newSize) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(!isInline()); + outOfLineStorage_ = static_cast( + // NOLINTNEXTLINE(cppcoreguidelines-no-malloc) + realloc(outOfLineStorage_, storageBytes(newSize))); + TORCH_CHECK( + outOfLineStorage_, + "Could not allocate memory for Tensor SizesAndStrides!"); + } + + void copyDataOutline(const SizesAndStrides& rhs) noexcept { + memcpy(outOfLineStorage_, rhs.outOfLineStorage_, storageBytes(rhs.size_)); + } + + size_t size_{1}; + union { + int64_t* outOfLineStorage_; + // NOLINTNEXTLINE(*c-array*) + int64_t inlineStorage_[C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE * 2]{}; + }; +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/TorchDispatchModeTLS.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/TorchDispatchModeTLS.h new file mode 100644 index 0000000000000000000000000000000000000000..002bf4283806448b0cf9470116758b21fa5499e6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/TorchDispatchModeTLS.h @@ -0,0 +1,72 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10::impl { + +enum class TorchDispatchModeKey : int8_t { + FAKE, + PROXY, + FUNCTIONAL, + NUM_MODE_KEYS +}; + +using PyObject_TorchDispatchMode = SafePyObjectT; + +struct C10_API TorchDispatchModeTLS { + // This API is NOT invariant safe. + // It must not take in an infra mode that uses TorchDispatchModeKey + // If you're pushing an infra mode onto the stack, we expect + // you to use set_mode + static void push_non_infra_mode_onto_stack( + std::shared_ptr mode); + // Pops the top mode of the stack, + // giving precedence to user modes before attempting to pop + // any infra modes + static const std::shared_ptr pop_stack(); + // Returns the highest-priority infra mode on the stack, + // along with its mode key. + static const std:: + tuple, TorchDispatchModeKey> + pop_highest_infra_mode(); + + static const std::shared_ptr& get_stack_at( + int64_t idx); + static int64_t stack_len(); + + static const std::optional> + get_mode(TorchDispatchModeKey mode_key); + static const std::optional> + unset_mode(TorchDispatchModeKey mode_key); + static void set_mode( + const std::shared_ptr& mode, + TorchDispatchModeKey mode_key); + + static const TorchDispatchModeTLS& get_state(); + static void set_state(TorchDispatchModeTLS state); + + static bool any_modes_set(bool skip_infra_modes = false); + + private: + std::vector> stack_; + // Users are allowed to push multiple ProxyTorchDispatchMode objects onto the + // stack + // However, we only allow a single FakeTensorMode onto the stack at a time + // (Pushing additional FakeTensorModes onto the stack is a no-op) + std::array< + std::optional>, + static_cast(TorchDispatchModeKey::NUM_MODE_KEYS)> + infra_modes_; +}; + +C10_API bool dispatch_mode_enabled(); + +C10_API std::string to_string(TorchDispatchModeKey mode_key); + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/VirtualGuardImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/VirtualGuardImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..c5bbeeb3cec5d5f48773dba3314ceaab8184c0f7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/VirtualGuardImpl.h @@ -0,0 +1,123 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace c10::impl { + +/** + * An implementation of DeviceGuardImplInterface which delegates + * to virtual dispatch on the DeviceGuardImpl registry. + */ +class VirtualGuardImpl final : public DeviceGuardImplInterface { + public: + VirtualGuardImpl(DeviceType device_type) + : impl_(getDeviceGuardImpl(device_type)) {} + // This constructor exists purely for testing + VirtualGuardImpl(const DeviceGuardImplInterface* impl) : impl_(impl) {} + + // Copying and moving is OK! + VirtualGuardImpl(const VirtualGuardImpl&) = default; + VirtualGuardImpl& operator=(const VirtualGuardImpl&) = default; + VirtualGuardImpl(VirtualGuardImpl&&) noexcept = default; + VirtualGuardImpl& operator=(VirtualGuardImpl&&) noexcept = default; + ~VirtualGuardImpl() override = default; + + DeviceType type() const override { + return impl_->type(); + } + Device exchangeDevice(Device d) const override { + return impl_->exchangeDevice(d); + } + Device getDevice() const override { + return impl_->getDevice(); + } + void setDevice(Device d) const override { + impl_->setDevice(d); + } + void uncheckedSetDevice(Device d) const noexcept override { + impl_->uncheckedSetDevice(d); + } + Stream getStream(Device d) const override { + return impl_->getStream(d); + } + Stream getNewStream(Device d, int priority = 0) const override { + return impl_->getNewStream(d, priority); + } + Stream getDefaultStream(Device d) const override { + return impl_->getDefaultStream(d); + } + Stream getStreamFromGlobalPool(Device d, bool isHighPriority = false) + const override { + return impl_->getStreamFromGlobalPool(d, isHighPriority); + } + Stream exchangeStream(Stream s) const override { + return impl_->exchangeStream(s); + } + void* getStreamNativeHandle(const Stream s) const override { + return impl_->getStreamNativeHandle(s); + } + DeviceIndex deviceCount() const noexcept override { + return impl_->deviceCount(); + } + + DeviceCapability getDeviceCapability(Device d) const override { + return impl_->getDeviceCapability(d); + } + + // Event functions + void record( + void** event, + const Stream& stream, + const DeviceIndex device_index, + const EventFlag flag) const override { + impl_->record(event, stream, device_index, flag); + } + void block(void* event, const Stream& stream) const override { + impl_->block(event, stream); + } + bool queryEvent(void* event) const override { + return impl_->queryEvent(event); + } + void destroyEvent(void* event, const DeviceIndex device_index) + const noexcept override { + impl_->destroyEvent(event, device_index); + } + + bool queryStream(const Stream& stream) const override { + return impl_->queryStream(stream); + } + void synchronizeStream(const Stream& stream) const override { + impl_->synchronizeStream(stream); + } + bool isStreamCapturing(const Stream& stream) const override { + return impl_->isStreamCapturing(stream); + } + + void recordDataPtrOnStream(const c10::DataPtr& data_ptr, const Stream& stream) + const override { + impl_->recordDataPtrOnStream(data_ptr, stream); + } + + double elapsedTime(void* event1, void* event2, const DeviceIndex device_index) + const override { + return impl_->elapsedTime(event1, event2, device_index); + } + + void synchronizeEvent(void* event) const override { + impl_->synchronizeEvent(event); + } + + void synchronizeDevice(const DeviceIndex device_index) const override { + impl_->synchronizeDevice(device_index); + } + + private: + const DeviceGuardImplInterface* impl_ = nullptr; +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/alloc_cpu.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/alloc_cpu.h new file mode 100644 index 0000000000000000000000000000000000000000..ef28ed469f010d3aedeb5d68ad5405c2ffdaa055 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/impl/alloc_cpu.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include + +namespace c10 { + +C10_API void* alloc_cpu(size_t nbytes); +C10_API void free_cpu(void* data); + +#if defined(__linux__) && !defined(__ANDROID__) +C10_API size_t c10_compute_alignment(size_t nbytes); +#endif + +#ifdef USE_MIMALLOC_ON_MKL +namespace mi_malloc_wrapper { +C10_API void* c10_mi_malloc(size_t size); +C10_API void* c10_mi_calloc(size_t count, size_t size); +C10_API void* c10_mi_realloc(void* p, size_t newsize); +C10_API void* c10_mi_malloc_aligned(size_t size, size_t alignment); +C10_API void c10_mi_free(void* p); +} // namespace mi_malloc_wrapper +#endif + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/thread_pool.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/thread_pool.h new file mode 100644 index 0000000000000000000000000000000000000000..85b9a73d6bfa7bdf5a815c6e659f0c4af6bd8ef8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/core/thread_pool.h @@ -0,0 +1,125 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace c10 { + +class C10_API TaskThreadPoolBase { + public: + virtual void run(std::function func) = 0; + + virtual size_t size() const = 0; + + /** + * The number of available (i.e. idle) threads in this thread pool. + */ + virtual size_t numAvailable() const = 0; + + /** + * Check if the current thread is from the thread pool. + */ + virtual bool inThreadPool() const = 0; + + virtual ~TaskThreadPoolBase() noexcept = default; + + static size_t defaultNumThreads(); +}; + +class C10_API ThreadPool : public c10::TaskThreadPoolBase { + protected: + struct task_element_t { + bool run_with_id; + // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) + const std::function no_id; + // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) + const std::function with_id; + + explicit task_element_t(std::function f) + : run_with_id(false), no_id(std::move(f)), with_id(nullptr) {} + explicit task_element_t(std::function f) + : run_with_id(true), no_id(nullptr), with_id(std::move(f)) {} + }; + + std::queue tasks_; + std::vector threads_; + mutable std::mutex mutex_; + std::condition_variable condition_; + std::condition_variable completed_; + std::atomic_bool running_; + bool complete_; + std::size_t available_; + std::size_t total_; + int numa_node_id_; + + public: + ThreadPool() = delete; + + explicit ThreadPool( + int pool_size, + int numa_node_id = -1, + const std::function& init_thread = nullptr); + + ~ThreadPool() override; + + size_t size() const override; + + size_t numAvailable() const override; + + bool inThreadPool() const override; + + void run(std::function func) override; + + template + void runTaskWithID(Task task) { + std::unique_lock lock(mutex_); + + // Set task and signal condition variable so that a worker thread will + // wake up and use the task. + tasks_.emplace(static_cast>(task)); + complete_ = false; + condition_.notify_one(); + } + + /// @brief Wait for queue to be empty + void waitWorkComplete(); + + private: + // @brief Entry point for pool threads. + void main_loop(std::size_t index); +}; + +class C10_API TaskThreadPool : public c10::ThreadPool { + public: + explicit TaskThreadPool(int pool_size, int numa_node_id = -1) + : ThreadPool(pool_size, numa_node_id, [numa_node_id]() { + setThreadName("CaffeTaskThread"); + NUMABind(numa_node_id); + }) {} +}; + +C10_DECLARE_SHARED_REGISTRY( + ThreadPoolRegistry, + TaskThreadPoolBase, + int, + int, + bool); + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAAlgorithm.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAAlgorithm.h new file mode 100644 index 0000000000000000000000000000000000000000..62995e142a3e84bf83e2e7143cdc6bc8eb67f91f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAAlgorithm.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifdef THRUST_DEVICE_LOWER_BOUND_WORKS +#include +#include +#include +#include +#endif +namespace c10::cuda { +#ifdef THRUST_DEVICE_LOWER_BOUND_WORKS +template +__forceinline__ __device__ Iter +lower_bound(Iter start, Iter end, Scalar value) { + return thrust::lower_bound(thrust::device, start, end, value); +} +#else +// thrust::lower_bound is broken on device, see +// https://github.com/NVIDIA/thrust/issues/1734 Implementation inspired by +// https://github.com/pytorch/pytorch/blob/805120ab572efef66425c9f595d9c6c464383336/aten/src/ATen/native/cuda/Bucketization.cu#L28 +template +__device__ Iter lower_bound(Iter start, Iter end, Scalar value) { + while (start < end) { + auto mid = start + ((end - start) >> 1); + if (*mid < value) { + start = mid + 1; + } else { + end = mid; + } + } + return end; +} +#endif // THRUST_DEVICE_LOWER_BOUND_WORKS +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAAllocatorConfig.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAAllocatorConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..b70157b1615ea2c2fd20524adb30ac04938a4bce --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAAllocatorConfig.h @@ -0,0 +1,235 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace c10::cuda::CUDACachingAllocator { + +enum class Expandable_Segments_Handle_Type : int { + UNSPECIFIED = 0, + POSIX_FD = 1, + FABRIC_HANDLE = 2, +}; + +// Environment config parser +class C10_CUDA_API CUDAAllocatorConfig { + public: + C10_DEPRECATED_MESSAGE( + "c10::cuda::CUDACachingAllocator::CUDAAllocatorConfig::max_split_size() is deprecated. Please use c10::CachingAllocator::AcceleratorAllocatorConfig::max_split_size() instead.") + static size_t max_split_size() { + return c10::CachingAllocator::AcceleratorAllocatorConfig::max_split_size(); + } + + C10_DEPRECATED_MESSAGE( + "c10::cuda::CUDACachingAllocator::CUDAAllocatorConfig::garbage_collection_threshold() is deprecated. Please use c10::CachingAllocator::AcceleratorAllocatorConfig::garbage_collection_threshold() instead.") + static double garbage_collection_threshold() { + return c10::CachingAllocator::AcceleratorAllocatorConfig:: + garbage_collection_threshold(); + } + + static bool expandable_segments() { + bool enabled = c10::CachingAllocator::AcceleratorAllocatorConfig:: + use_expandable_segments(); +#if !defined(PYTORCH_C10_DRIVER_API_SUPPORTED) && \ + (!defined(USE_ROCM) || (ROCM_VERSION < 70000)) + if (enabled) { + TORCH_WARN_ONCE("expandable_segments not supported on this platform") + } + return false; +#else + return enabled; +#endif + } + + static Expandable_Segments_Handle_Type expandable_segments_handle_type() { + return instance().m_expandable_segments_handle_type; + } + + static void set_expandable_segments_handle_type( + Expandable_Segments_Handle_Type handle_type) { + instance().m_expandable_segments_handle_type = handle_type; + } + + static bool release_lock_on_cudamalloc() { + return instance().m_release_lock_on_cudamalloc; + } + + static bool graph_capture_record_stream_reuse() { + return instance().m_graph_capture_record_stream_reuse; + } + + static double per_process_memory_fraction() { + return instance().m_per_process_memory_fraction; + } + + // When enabled, throws OOM error before calling cudaMalloc if the allocation + // would likely fail due to insufficient memory. This provides early failure + // with clear error messages instead of letting cudaMalloc fail. + static bool throw_on_cudamalloc_oom() { + return instance().m_throw_on_cudamalloc_oom; + } + + /** Pinned memory allocator settings */ + static bool pinned_use_cuda_host_register() { + return instance().m_pinned_use_cuda_host_register; + } + + static size_t pinned_num_register_threads() { + return instance().m_pinned_num_register_threads; + } + + C10_DEPRECATED_MESSAGE( + "c10::cuda::CUDACachingAllocator::CUDAAllocatorConfig::pinned_use_background_threads() is deprecated. Please use c10::CachingAllocator::AcceleratorAllocatorConfig::pinned_use_background_threads() instead.") + static bool pinned_use_background_threads() { + return c10::CachingAllocator::AcceleratorAllocatorConfig:: + pinned_use_background_threads(); + } + + static size_t pinned_reserve_segment_size_mb() { + return instance().m_pinned_reserve_segment_size_mb; + } + + static size_t pinned_max_register_threads() { + // Based on the benchmark results, we see better allocation performance + // with 8 threads. However on future systems, we may need more threads + // and limiting this to 128 threads. + return 128; + } + + static bool pinned_free_catch_all() { + return instance().m_pinned_free_catch_all; + } + + C10_DEPRECATED_MESSAGE( + "c10::cuda::CUDACachingAllocator::CUDAAllocatorConfig::roundup_power2_divisions() is deprecated. Please use c10::CachingAllocator::AcceleratorAllocatorConfig::roundup_power2_divisions() instead.") + static size_t roundup_power2_divisions(size_t size) { + return c10::CachingAllocator::AcceleratorAllocatorConfig:: + roundup_power2_divisions(size); + } + + C10_DEPRECATED_MESSAGE( + "c10::cuda::CUDACachingAllocator::CUDAAllocatorConfig::roundup_power2_divisions() is deprecated. Please use c10::CachingAllocator::AcceleratorAllocatorConfig::roundup_power2_divisions() instead.") + static std::vector roundup_power2_divisions() { + return c10::CachingAllocator::AcceleratorAllocatorConfig:: + roundup_power2_divisions(); + } + + static size_t max_non_split_rounding_size() { + return c10::CachingAllocator::AcceleratorAllocatorConfig:: + max_non_split_rounding_size(); + } + + C10_DEPRECATED_MESSAGE( + "c10::cuda::CUDACachingAllocator::CUDAAllocatorConfig::last_allocator_settings() is deprecated. Please use c10::CachingAllocator::AcceleratorAllocatorConfig::last_allocator_settings() instead.") + static std::string last_allocator_settings() { + return c10::CachingAllocator::getAllocatorSettings(); + } + + static CUDAAllocatorConfig& instance() { + static CUDAAllocatorConfig* s_instance = ([]() { + auto inst = new CUDAAllocatorConfig(); + auto env = c10::utils::get_env("PYTORCH_CUDA_ALLOC_CONF"); +#ifdef USE_ROCM + // convenience for ROCm users, allow alternative HIP token + if (!env.has_value()) { + env = c10::utils::get_env("PYTORCH_HIP_ALLOC_CONF"); + } +#endif + // Note: keep the parsing order and logic stable to avoid potential + // performance regressions in internal tests. + if (!env.has_value()) { + env = c10::utils::get_env("PYTORCH_ALLOC_CONF"); + } + if (env.has_value()) { + inst->parseArgs(env.value()); + } + return inst; + })(); + return *s_instance; + } + + // Use `Construct On First Use Idiom` to avoid `Static Initialization Order` + // issue. + static const std::unordered_set& getKeys() { + static std::unordered_set keys{ + "backend", + // keep BC for Rocm: `cuda` -> `cud` `a`, to avoid hipify issues + // NOLINTBEGIN(bugprone-suspicious-missing-comma,-warnings-as-errors) + "release_lock_on_cud" + "amalloc", + "pinned_use_cud" + "a_host_register", + // NOLINTEND(bugprone-suspicious-missing-comma,-warnings-as-errors) + "release_lock_on_hipmalloc", + "pinned_use_hip_host_register", + "graph_capture_record_stream_reuse", + "pinned_reserve_segment_size_mb", + "pinned_num_register_threads", + "per_process_memory_fraction", + "pinned_free_catch_all", + "throw_on_cudamalloc_oom"}; + return keys; + } + + void parseArgs(const std::string& env); + + private: + CUDAAllocatorConfig() = default; + + size_t parseAllocatorConfig( + const c10::CachingAllocator::ConfigTokenizer& tokenizer, + size_t i, + bool& used_cudaMallocAsync); + size_t parsePinnedUseCudaHostRegister( + const c10::CachingAllocator::ConfigTokenizer& tokenizer, + size_t i); + size_t parsePinnedNumRegisterThreads( + const c10::CachingAllocator::ConfigTokenizer& tokenizer, + size_t i); + size_t parsePinnedReserveSegmentSize( + const c10::CachingAllocator::ConfigTokenizer& tokenizer, + size_t i); + size_t parseGraphCaptureRecordStreamReuse( + const c10::CachingAllocator::ConfigTokenizer& tokenizer, + size_t i); + double parsePerProcessMemoryFraction( + const c10::CachingAllocator::ConfigTokenizer& tokenizer, + size_t i); + size_t parsePinnedFreeCatchAll( + const c10::CachingAllocator::ConfigTokenizer& tokenizer, + size_t i); + size_t parseThrowOnCudaMallocOom( + const c10::CachingAllocator::ConfigTokenizer& tokenizer, + size_t i); + + std::atomic m_pinned_num_register_threads{1}; + std::atomic m_pinned_reserve_segment_size_mb{0}; + std::atomic m_expandable_segments_handle_type +#if CUDA_VERSION >= 12030 + {Expandable_Segments_Handle_Type::UNSPECIFIED}; +#else + {Expandable_Segments_Handle_Type::POSIX_FD}; +#endif + std::atomic m_release_lock_on_cudamalloc{false}; + std::atomic m_pinned_use_cuda_host_register{false}; + std::atomic m_graph_capture_record_stream_reuse{false}; + std::atomic m_per_process_memory_fraction{1.0}; + std::atomic m_pinned_free_catch_all{false}; + // When true, throw OOM error before calling cudaMalloc if allocation would + // fail + std::atomic m_throw_on_cudamalloc_oom{false}; +}; + +// Keep this for backwards compatibility +using c10::CachingAllocator::setAllocatorSettings; + +} // namespace c10::cuda::CUDACachingAllocator + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDACachingAllocator.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDACachingAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..91ed4491738259471849f57e25ea86cacc9631ed --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDACachingAllocator.h @@ -0,0 +1,517 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +// Caching allocator will execute every registered callback if it unable to find +// block inside of already allocated area. +class C10_CUDA_API FreeMemoryCallback { + public: + virtual ~FreeMemoryCallback() = default; + virtual bool Execute() = 0; +}; + +C10_DECLARE_REGISTRY(FreeCudaMemoryCallbacksRegistry, FreeMemoryCallback); +#define REGISTER_FREE_MEMORY_CALLBACK(name, ...) \ + C10_REGISTER_CLASS(FreeCudaMemoryCallbacksRegistry, name, __VA_ARGS__) +} // namespace c10 + // +// TODO: Turn this into an honest to goodness class. I briefly attempted to do +// this, but it was a bit irritating to figure out how to also correctly +// apply pimpl pattern so I didn't have to leak any internal implementation +// details in the header (CUDACachingAllocator could be made a pimpl, but +// you also need to appropriately define a class which is a subclass +// of Allocator. Not impossible, but required a bit more surgery than +// I wanted to do at the time.) +// +// Why is this using a namespace rather than old-style THCCachingAllocator_ +// prefix? Mostly because it made the HIPify rules easier to write; _ is +// not counted as a word boundary, so you would otherwise have to list each +// of these functions. + +namespace c10::cuda::CUDACachingAllocator { + +// Preserved only for BC reasons +// NOLINTNEXTLINE(misc-unused-using-decls) +using c10::CachingDeviceAllocator::AllocatorTraceTracker; +using c10::CachingDeviceAllocator::BlockInfo; +using c10::CachingDeviceAllocator::CreateContextFn; +using c10::CachingDeviceAllocator::DeviceStats; +using c10::CachingDeviceAllocator::RecordContext; +using c10::CachingDeviceAllocator::SegmentInfo; +using c10::CachingDeviceAllocator::TraceEntry; + +struct AllocatorState { + virtual ~AllocatorState() = default; +}; + +struct AllocatorConfigInfo { + double garbage_collection_threshold; + size_t max_split_size; + size_t pinned_num_register_threads; + bool expandable_segments; + bool release_lock_on_malloc; + bool pinned_use_host_register; + bool graph_capture_record_stream_reuse; + std::string last_allocator_settings; + std::vector roundup_power2_divisions; +}; + +struct SnapshotInfo { + std::vector segments; + std::vector> device_traces; + std::vector external_annotations; + AllocatorConfigInfo config_metadata; +}; + +// returns the pointers freed in the pool +// and the pointers allocated. Note: a pointer +// may appear in both freed and allocated +struct CheckpointDelta { + std::vector ptrs_freed; + std::vector dataptrs_allocd; +}; + +using OutOfMemoryObserver = std::function; + +// Observer called when an allocation is preemptively rejected due to +// throw_on_cudamalloc_oom policy. Parameters: +// - device: GPU device index +// - alloc_size: size of the rejected allocation request +// - total_allocated: total memory allocated before the request +// - device_total: total GPU memory +using OomRejectionObserver = std::function; + +struct ShareableHandle { + ptrdiff_t offset; + std::string handle; +}; + +struct StreamSegmentSize { + StreamSegmentSize(cudaStream_t s, bool small_, size_t sz) + : stream(s), is_small_pool(small_), total_size(sz) {} + cudaStream_t stream; + bool is_small_pool; + size_t total_size; +}; + +class CUDAAllocator : public DeviceAllocator { + public: + virtual void* raw_alloc(size_t nbytes) = 0; + virtual void* raw_alloc_with_stream(size_t nbytes, cudaStream_t stream) = 0; + virtual void raw_delete(void* ptr) = 0; + virtual void init(int device_count) = 0; + virtual double getMemoryFraction(c10::DeviceIndex device) = 0; + virtual void setMemoryFraction(double fraction, c10::DeviceIndex device) = 0; + virtual std::vector getExpandableSegmentSizes( + c10::DeviceIndex device) = 0; + virtual void enable(bool value) = 0; + virtual bool isEnabled() const = 0; + virtual void cacheInfo(c10::DeviceIndex device, size_t* largestBlock) = 0; + virtual void* getBaseAllocation(void* ptr, size_t* size) = 0; + // Keep for BC only + virtual void recordStream(const DataPtr& ptr, CUDAStream stream) = 0; + void recordStream(const DataPtr& ptr, c10::Stream stream) override { + CUDAStream cuda_stream = CUDAStream(stream); + recordStream(ptr, cuda_stream); + } + virtual SnapshotInfo snapshot( + MempoolId_t mempool_id = {0, 0}, + bool include_traces = true) = 0; + virtual void beginAllocateToPool( + c10::DeviceIndex device, + MempoolId_t mempool_id, + std::function filter) = 0; + virtual void endAllocateToPool( + c10::DeviceIndex device, + MempoolId_t mempool_id) = 0; + virtual void releasePool(c10::DeviceIndex device, MempoolId_t mempool_id) = 0; + virtual int getPoolUseCount( + c10::DeviceIndex /*device*/, + MempoolId_t /*mempool_id*/) { + TORCH_CHECK( + false, + name(), + " does not yet support getPoolUseCount. " + "If you need it, please file an issue describing your use case."); + } + virtual void createOrIncrefPool( + c10::DeviceIndex /*device*/, + MempoolId_t /*mempool_id*/, + std::shared_ptr allocator = nullptr) { + TORCH_CHECK( + false, + name(), + " does not yet support createOrIncrefPool. " + "If you need it, please file an issue describing your use case."); + } + virtual void setUseOnOOM( + c10::DeviceIndex device, + MempoolId_t mempool_id, + bool use_on_oom) { + TORCH_CHECK( + false, + name(), + " does not yet support setUseOnOOM. " + "If you need it, please file an issue describing your use case."); + } + virtual void setNoSplit(c10::DeviceIndex device, MempoolId_t mempool_id) { + TORCH_CHECK( + false, + name(), + " does not yet support setNoSplit. " + "If you need it, please file an issue describing your use case."); + } + + // returns true if the allocated blocks are equal to expected live allocations + virtual bool checkPoolLiveAllocations( + c10::DeviceIndex /*device*/, + MempoolId_t /*mempool_id*/, + const std::unordered_set& /*expected_live_allocations*/) { + TORCH_CHECK( + false, + name(), + " does not yet support checkPoolLiveAllocations. " + "If you need it, please file an issue describing your use case."); + } + virtual ShareableHandle shareIpcHandle(void* ptr) = 0; + virtual std::shared_ptr getIpcDevPtr(std::string handle) = 0; + virtual bool isHistoryEnabled() { + TORCH_CHECK( + false, + name(), + " does not yet support recordHistory. " + "If you need it, please file an issue describing your use case."); + } + virtual std::shared_ptr getContextForPointer( + const void* ptr) { + return nullptr; + } + virtual void recordHistory( + bool enabled, + CreateContextFn context_recorder, + size_t alloc_trace_max_entries, + RecordContext when, + bool clearHistory, + const std::vector& skip_actions) = 0; + virtual void recordAnnotation( + const std::vector>& /*md*/) {} + virtual void pushCompileContext(std::string& md) {} + virtual void popCompileContext() {} + virtual void setUserMetadata(const std::string& metadata) {} + virtual std::string getUserMetadata() { + return ""; + } + virtual void attachOutOfMemoryObserver(OutOfMemoryObserver observer) = 0; + virtual void attachOomRejectionObserver(OomRejectionObserver observer) = 0; + + // Attached AllocatorTraceTracker callbacks will be called while the + // per-device allocator lock is held. Any additional locks taken from within + // the callback must be proven to always have the lock order that never + // triggers a deadlock. In particular, Python's GIL may be held when + // calling the allocator so it is unsafe to try to acquire the GIL in this + // callback. + virtual void attachAllocatorTraceTracker(AllocatorTraceTracker tracker) = 0; + + virtual void enablePeerAccess( + c10::DeviceIndex dev, + c10::DeviceIndex dev_to_access) = 0; + + // memory not allocated from cudaMalloc cannot be copied + // across devices using cudaMemcpyAsync if peer to peer access is disabled. + // instead it requires cudaMemcpyAsyncPeer + // with P2P Enabled, all combinations work + // with P2P Disabled: + // cudaMalloc cudaMallocAsync/cuMemMap + // cudaMemcpyAsyncPeer works works + // cudaMemcpyAsync works error + + // This function performs chooses to use the Peer version of + // memcpy if required based on where the allocated put dst/src. + virtual cudaError_t memcpyAsync( + void* dst, + int dstDevice, + const void* src, + int srcDevice, + size_t count, + cudaStream_t stream, + bool p2p_enabled) = 0; + virtual std::shared_ptr getCheckpointState( + c10::DeviceIndex device, + MempoolId_t id) = 0; + virtual CheckpointDelta setCheckpointPoolState( + c10::DeviceIndex device, + std::shared_ptr pps) = 0; + virtual std::string name() = 0; + std::pair getMemoryInfo(c10::DeviceIndex device) override { + c10::DeviceGuard device_guard({at::kCUDA, device}); + size_t free = 0; + size_t total = 0; + C10_CUDA_CHECK(cudaMemGetInfo(&free, &total)); + return {free, total}; + } +}; + +// Allocator object, statically initialized +// See BackendInitializer in CUDACachingAllocator.cpp. +// Atomic loads on x86 are just normal loads, +// (atomic stores are different), so reading this value +// is no different than loading a pointer. +C10_CUDA_API extern std::atomic allocator; + +inline CUDAAllocator* get() { + return allocator.load(); +} + +// Called directly by clients. +inline void* raw_alloc(size_t nbytes) { + return get()->raw_alloc(nbytes); +} + +inline void* raw_alloc_with_stream(size_t nbytes, cudaStream_t stream) { + return get()->raw_alloc_with_stream(nbytes, stream); +} + +inline void raw_delete(void* ptr) { + get()->raw_delete(ptr); +} + +inline void init(int device_count) { + get()->init(device_count); +} + +inline double getMemoryFraction(c10::DeviceIndex device) { + return get()->getMemoryFraction(device); +} + +inline void setMemoryFraction(double fraction, c10::DeviceIndex device) { + get()->setMemoryFraction(fraction, device); +} + +inline std::vector getExpandableSegmentSizes( + c10::DeviceIndex device) { + return get()->getExpandableSegmentSizes(device); +} + +inline void emptyCache(MempoolId_t mempool_id = {0, 0}) { + get()->emptyCache(mempool_id); +} + +inline void enable(bool value) { + get()->enable(value); +} + +inline bool isEnabled() { + return get()->isEnabled(); +} + +inline void cacheInfo(c10::DeviceIndex device, size_t* largestBlock) { + get()->cacheInfo(device, largestBlock); +} + +inline void* getBaseAllocation(void* ptr, size_t* size) { + return get()->getBaseAllocation(ptr, size); +} + +inline void recordStream(const DataPtr& dataPtr, CUDAStream stream) { + get()->recordStream(dataPtr, stream); +} + +inline c10::CachingDeviceAllocator::DeviceStats getDeviceStats( + c10::DeviceIndex device) { + return get()->getDeviceStats(device); +} + +inline void resetAccumulatedStats(c10::DeviceIndex device) { + get()->resetAccumulatedStats(device); +} + +inline void resetPeakStats(c10::DeviceIndex device) { + get()->resetPeakStats(device); +} + +inline SnapshotInfo snapshot( + MempoolId_t mempool_id = {0, 0}, + bool include_traces = true) { + return get()->snapshot(mempool_id, include_traces); +} + +inline std::shared_ptr getCheckpointState( + c10::DeviceIndex device, + MempoolId_t id) { + return get()->getCheckpointState(device, id); +} + +inline CheckpointDelta setCheckpointPoolState( + c10::DeviceIndex device, + std::shared_ptr pps) { + return get()->setCheckpointPoolState(device, std::move(pps)); +} + +// CUDAGraph interactions +inline void beginAllocateToPool( + c10::DeviceIndex device, + MempoolId_t mempool_id, + std::function filter) { + get()->beginAllocateToPool(device, mempool_id, std::move(filter)); +} + +inline void endAllocateToPool(c10::DeviceIndex device, MempoolId_t mempool_id) { + get()->endAllocateToPool(device, mempool_id); +} + +inline void recordHistory( + bool enabled, + CreateContextFn context_recorder, + size_t alloc_trace_max_entries, + RecordContext when, + bool clearHistory, + const std::vector& skip_actions) { + get()->recordHistory( + enabled, + context_recorder, + alloc_trace_max_entries, + when, + clearHistory, + skip_actions); +} + +inline void recordAnnotation( + const std::vector>& md) { + get()->recordAnnotation(md); +} + +inline void pushCompileContext(std::string& md) { + get()->pushCompileContext(md); +} + +inline void popCompileContext() { + get()->popCompileContext(); +} + +inline bool isHistoryEnabled() { + return get()->isHistoryEnabled(); +} + +inline std::shared_ptr getContextForPointer(const void* ptr) { + return get()->getContextForPointer(ptr); +} + +inline bool checkPoolLiveAllocations( + c10::DeviceIndex device, + MempoolId_t mempool_id, + const std::unordered_set& expected_live_allocations) { + return get()->checkPoolLiveAllocations( + device, mempool_id, expected_live_allocations); +} + +inline void attachOutOfMemoryObserver(OutOfMemoryObserver observer) { + get()->attachOutOfMemoryObserver(std::move(observer)); +} + +inline void attachOomRejectionObserver(OomRejectionObserver observer) { + get()->attachOomRejectionObserver(std::move(observer)); +} + +inline void attachAllocatorTraceTracker(AllocatorTraceTracker tracker) { + get()->attachAllocatorTraceTracker(std::move(tracker)); +} + +inline void releasePool(c10::DeviceIndex device, MempoolId_t mempool_id) { + get()->releasePool(device, mempool_id); +} +inline void createOrIncrefPool( + c10::DeviceIndex device, + MempoolId_t mempool_id, + std::shared_ptr allocator_ptr = nullptr) { + get()->createOrIncrefPool(device, mempool_id, std::move(allocator_ptr)); +} +inline void setUseOnOOM( + c10::DeviceIndex device, + MempoolId_t mempool_id, + bool use_on_oom) { + get()->setUseOnOOM(device, mempool_id, use_on_oom); +} +inline void setNoSplit(c10::DeviceIndex device, MempoolId_t mempool_id) { + get()->setNoSplit(device, mempool_id); +} +inline int getPoolUseCount(c10::DeviceIndex device, MempoolId_t mempool_id) { + return get()->getPoolUseCount(device, mempool_id); +} + +// Not part of CUDA_ALLOCATOR_BACKEND_INTERFACE +inline std::shared_ptr getIpcDevPtr(std::string handle) { + return get()->getIpcDevPtr(std::move(handle)); +} + +inline ShareableHandle shareIpcHandle(void* ptr) { + return get()->shareIpcHandle(ptr); +} + +inline std::string name() { + return get()->name(); +} + +inline cudaError_t memcpyAsync( + void* dst, + int dstDevice, + const void* src, + int srcDevice, + size_t count, + cudaStream_t stream, + bool p2p_enabled) { + return get()->memcpyAsync( + dst, dstDevice, src, srcDevice, count, stream, p2p_enabled); +} + +inline void enablePeerAccess( + c10::DeviceIndex dev, + c10::DeviceIndex dev_to_access) { + get()->enablePeerAccess(dev, dev_to_access); +} + +inline void setUserMetadata(const std::string& metadata) { + get()->setUserMetadata(metadata); +} + +inline std::string getUserMetadata() { + return get()->getUserMetadata(); +} + +} // namespace c10::cuda::CUDACachingAllocator + +namespace c10::cuda { +// Keep BC only +using c10::CaptureId_t; +using c10::MempoolId_t; +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDADeviceAssertion.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDADeviceAssertion.h new file mode 100644 index 0000000000000000000000000000000000000000..294734601cb78d68aff50da939b3452c948adb80 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDADeviceAssertion.h @@ -0,0 +1,103 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10::cuda { + +#ifdef TORCH_USE_CUDA_DSA +C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wunused-function") +// Copy string from `src` to `dst` +static __device__ void dstrcpy(char* dst, const char* src) { + int i = 0; + // Copy string from source to destination, ensuring that it + // isn't longer than `C10_CUDA_DSA_MAX_STR_LEN-1` + while (*src != '\0' && i++ < C10_CUDA_DSA_MAX_STR_LEN - 1) { + *dst++ = *src++; + } + *dst = '\0'; +} + +static __device__ void dsa_add_new_assertion_failure( + DeviceAssertionsData* assertions_data, + const char* assertion_msg, + const char* filename, + const char* function_name, + const int line_number, + const uint32_t caller, + const dim3 block_id, + const dim3 thread_id) { + // `assertions_data` may be nullptr if device-side assertion checking + // is disabled at run-time. If it is disabled at compile time this + // function will never be called + if (!assertions_data) { + return; + } + + // Atomically increment so other threads can fail at the same time + // Note that incrementing this means that the CPU can observe that + // a failure has happened and can begin to respond before we've + // written information about that failure out to the buffer. + const auto nid = atomicAdd(&(assertions_data->assertion_count), 1); + + if (nid >= C10_CUDA_DSA_ASSERTION_COUNT) { + // At this point we're ran out of assertion buffer space. + // We could print a message about this, but that'd get + // spammy if a lot of threads did it, so we just silently + // ignore any other assertion failures. In most cases the + // failures will all probably be analogous anyway. + return; + } + + // Write information about the assertion failure to memory. + // Note that this occurs only after the `assertion_count` + // increment broadcasts that there's been a problem. + auto& self = assertions_data->assertions[nid]; + dstrcpy(self.assertion_msg, assertion_msg); + dstrcpy(self.filename, filename); + dstrcpy(self.function_name, function_name); + self.line_number = line_number; + self.caller = caller; + self.block_id[0] = block_id.x; + self.block_id[1] = block_id.y; + self.block_id[2] = block_id.z; + self.thread_id[0] = thread_id.x; + self.thread_id[1] = thread_id.y; + self.thread_id[2] = thread_id.z; +} +C10_CLANG_DIAGNOSTIC_POP() + +// Emulates a kernel assertion. The assertion won't stop the kernel's progress, +// so you should assume everything the kernel produces is garbage if there's an +// assertion failure. +// NOTE: This assumes that `assertions_data` and `assertion_caller_id` are +// arguments of the kernel and therefore accessible. +#define CUDA_KERNEL_ASSERT2(condition) \ + do { \ + if (C10_UNLIKELY(!(condition))) { \ + /* Has an atomic element so threads can fail at the same time */ \ + c10::cuda::dsa_add_new_assertion_failure( \ + assertions_data, \ + C10_STRINGIZE(condition), \ + __FILE__, \ + __FUNCTION__, \ + __LINE__, \ + assertion_caller_id, \ + blockIdx, \ + threadIdx); \ + /* Now that the kernel has failed we early exit the kernel, but */ \ + /* otherwise keep going and rely on the host to check UVM and */ \ + /* determine we've had a problem */ \ + return; \ + } \ + } while (false) +#else +#define CUDA_KERNEL_ASSERT2(condition) assert(condition) +#endif + +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDADeviceAssertionHost.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDADeviceAssertionHost.h new file mode 100644 index 0000000000000000000000000000000000000000..ad371c3003a6899d39bf3a9c172b4bacec66e7d0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDADeviceAssertionHost.h @@ -0,0 +1,169 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#if defined(USE_CUDA) || defined(USE_ROCM) +#define TORCH_USE_CUDA_DSA +#endif + +/// Number of assertion failure messages we can store. If this is too small +/// threads will fail silently. +constexpr int C10_CUDA_DSA_ASSERTION_COUNT = 10; +constexpr int C10_CUDA_DSA_MAX_STR_LEN = 512; + +namespace c10::cuda { + +/// Holds information about any device-side assertions that fail. +/// Held in managed memory and access by both the CPU and the GPU. +struct DeviceAssertionData { + /// Stringification of the assertion + // NOLINTNEXTLINE(*-c-arrays) + char assertion_msg[C10_CUDA_DSA_MAX_STR_LEN]{}; + /// File the assertion was in + // NOLINTNEXTLINE(*-c-arrays) + char filename[C10_CUDA_DSA_MAX_STR_LEN]{}; + /// Name of the function the assertion was in + // NOLINTNEXTLINE(*-c-arrays) + char function_name[C10_CUDA_DSA_MAX_STR_LEN]{}; + /// Line number the assertion was at + int line_number{}; + /// Number uniquely identifying the kernel launch that triggered the assertion + uint32_t caller{}; + /// block_id of the thread that failed the assertion + // NOLINTNEXTLINE(*-c-arrays) + int32_t block_id[3]{}; + /// third_id of the thread that failed the assertion + // NOLINTNEXTLINE(*-c-arrays) + int32_t thread_id[3]{}; +}; + +/// Used to hold assertions generated by the device +/// Held in managed memory and access by both the CPU and the GPU. +struct DeviceAssertionsData { + /// Total number of assertions found; a subset of these will be recorded + /// in `assertions` + int32_t assertion_count{}; + /// An array of assertions that will be written to in a race-free manner + // NOLINTNEXTLINE(*-c-arrays) + DeviceAssertionData assertions[C10_CUDA_DSA_ASSERTION_COUNT]{}; +}; + +/// Use to hold info about kernel launches so that we can run kernels +/// asynchronously and still associate launches with device-side +/// assertion failures +struct CUDAKernelLaunchInfo { + /// Filename of the code where the kernel was launched from + const char* launch_filename; + /// Function from which the kernel was launched + const char* launch_function; + /// Line number of where the code was launched from + uint32_t launch_linenum; + /// Backtrace of where the kernel was launched from, only populated if + /// CUDAKernelLaunchRegistry::gather_launch_stacktrace is True + std::string launch_stacktrace; + /// Kernel that was launched + const char* kernel_name; + /// Device the kernel was launched on + int device; + /// Stream the kernel was launched on + int32_t stream; + /// A number that uniquely identifies the kernel launch + uint64_t generation_number; +}; + +/// Circular buffer used to hold information about kernel launches +/// this is later used to reconstruct how a device-side kernel assertion failure +/// occurred CUDAKernelLaunchRegistry is used as a singleton +class C10_CUDA_API CUDAKernelLaunchRegistry { + private: + /// Assume that this is the max number of kernel launches that might ever be + /// enqueued across all streams on a single device + static constexpr int max_kernel_launches = 1024; + /// How many kernel launch infos we've inserted. Used to ensure that circular + /// queue doesn't provide false information by always increasing, but also to + /// mark where we are inserting into the queue +#ifdef TORCH_USE_CUDA_DSA + uint64_t generation_number = 0; +#endif + /// Shared mutex between writer and accessor to ensure multi-threaded safety. + mutable std::mutex read_write_mutex; + /// Used to ensure prevent race conditions in GPU memory allocation + mutable std::mutex gpu_alloc_mutex; + /// Pointer to managed memory keeping track of device-side assertions. There + /// is one entry for each possible device the process might work with. Unused + /// entries are nullptrs. We could also use an unordered_set here, but this + /// vector design will be faster and the wasted memory is small since we + /// expect the number of GPUs per node will always be small + std::vector< + std::unique_ptr> + uvm_assertions; + /// A single circular buffer holds information about every kernel launch the + /// process makes across all devices. + std::vector kernel_launches; + bool check_env_for_enable_launch_stacktracing() const; + bool check_env_for_dsa_enabled() const; + + public: + CUDAKernelLaunchRegistry(); + /// Register a new kernel launch and obtain a generation number back to be + /// passed to the kernel + uint32_t insert( + const char* launch_filename, + const char* launch_function, + const uint32_t launch_linenum, + const char* kernel_name, + const int32_t stream_id); + /// Get copies of the kernel launch registry and each device's assertion + /// failure buffer so they can be inspected without raising race conditions + std:: + pair, std::vector> + snapshot() const; + /// Get a pointer to the current device's assertion failure buffer. If no such + /// buffer exists then one is created. This means that the first kernel launch + /// made on each device will be slightly slower because memory allocations are + /// required + DeviceAssertionsData* get_uvm_assertions_ptr_for_current_device(); + /// Gets the global singleton of the registry + static CUDAKernelLaunchRegistry& get_singleton_ref(); + /// If not all devices support DSA, we disable it + const bool do_all_devices_support_managed_memory = false; + /// Whether or not to gather stack traces when launching kernels + bool gather_launch_stacktrace = false; + /// Whether or not host-side DSA is enabled or disabled at run-time + /// Note: Device-side code cannot be enabled/disabled at run-time + bool enabled_at_runtime = false; + /// Whether or not a device has indicated a failure + bool has_failed() const; +#ifdef TORCH_USE_CUDA_DSA + const bool enabled_at_compile_time = true; +#else + const bool enabled_at_compile_time = false; +#endif +}; + +C10_CUDA_API std::string c10_retrieve_device_side_assertion_info(); + +} // namespace c10::cuda + +// Each kernel launched with TORCH_DSA_KERNEL_LAUNCH +// requires the same input arguments. We introduce the following macro to +// standardize these. +#define TORCH_DSA_KERNEL_ARGS \ + [[maybe_unused]] c10::cuda::DeviceAssertionsData *const assertions_data, \ + [[maybe_unused]] uint32_t assertion_caller_id + +// This macro can be used to pass the DSA arguments onward to another +// function +#define TORCH_DSA_KERNEL_ARGS_PASS assertions_data, assertion_caller_id + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAEvent.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..5bbdd354d1016acce31c97c68fa1d15411e71f1f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAEvent.h @@ -0,0 +1,374 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +/* + * `cudaEventExternal` is a torch-specific flag that is used to + * indicate that the CUDAEvent will be used only for synchronization + * with work outside of the cuda graph, rather than creation of + * cross-stream dependencies within a cuda graph. Resources: + * https://docs.nvidia.com/cuda/archive/12.9.0/cuda-c-programming-guide/index.html#cross-stream-dependencies-and-events + * https://docs.nvidia.com/cuda/archive/12.9.0/cuda-runtime-api/group__CUDART__TYPES.html#group__CUDART__TYPES_1g3457b81d1d32c6a00f6132fbc2693d47 + * https://docs.nvidia.com/cuda/archive/12.9.0/cuda-runtime-api/group__CUDART__TYPES.html#group__CUDART__TYPES_1g0c23426b7252eaa9cef695859991304e + */ +#define cudaEventExternal 0x08 + +namespace c10::cuda { + +/* + * CUDAEvents are movable not copyable wrappers around CUDA's events. + * + * CUDAEvents are constructed lazily when first recorded unless it is + * reconstructed from a cudaIpcEventHandle_t. The event has a device, and this + * device is acquired from the first recording stream. However, if reconstructed + * from a handle, the device should be explicitly specified; or if ipc_handle() + * is called before the event is ever recorded, it will use the current device. + * Later streams that record the event must match this device. + */ +struct CUDAEvent { + // Constructors + // Default value for `flags` is specified below - it's cudaEventDisableTiming + CUDAEvent() noexcept = default; + CUDAEvent(unsigned int flags) noexcept : flags_{flags} {} + + CUDAEvent(DeviceIndex device_index, const cudaIpcEventHandle_t* handle) + : device_index_(device_index) { + CUDAGuard guard(device_index_); + + C10_CUDA_CHECK(cudaIpcOpenEventHandle(&event_, *handle)); + is_created_ = true; + } + + // Note: event destruction done on creating device to avoid creating a + // CUDA context on other devices. + ~CUDAEvent() { + if (is_created_) { + CUDAGuard guard(device_index_); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_deletion( + c10::kCUDA, reinterpret_cast(event_)); + } + C10_CUDA_CHECK_WARN(cudaEventDestroy(event_)); + } + } + + CUDAEvent(const CUDAEvent&) = delete; + CUDAEvent& operator=(const CUDAEvent&) = delete; + + CUDAEvent(CUDAEvent&& other) noexcept { + moveHelper(std::move(other)); + } + CUDAEvent& operator=(CUDAEvent&& other) noexcept { + if (this != &other) { + moveHelper(std::move(other)); + } + return *this; + } + + operator cudaEvent_t() const { + return event(); + } + + // Less than operator (to allow use in sets) + friend bool operator<(const CUDAEvent& left, const CUDAEvent& right) { + return left.event_ < right.event_; + } + + std::optional device() const { + if (is_created_) { + return c10::Device(c10::kCUDA, device_index_); + } else { + return {}; + } + } + + bool isCreated() const { + return is_created_; + } + DeviceIndex device_index() const { + return device_index_; + } + cudaEvent_t event() const { + return event_; + } + + // Note: cudaEventQuery can be safely called from any device + bool query() const { + if (!is_created_) { + return true; + } + + cudaError_t err = cudaEventQuery(event_); + if (err == cudaSuccess) { + return true; + } else if (err != cudaErrorNotReady) { + C10_CUDA_CHECK(err); + } else { + // ignore and clear the error if not ready + (void)cudaGetLastError(); + } + + return false; + } + + void record() { + record(getCurrentCUDAStream()); + } + + void recordOnce(const CUDAStream& stream) { + if (!was_recorded_) + record(stream); + } + + // Note: cudaEventRecord must be called on the same device as the event. + void record(const CUDAStream& stream) { + if (!is_created_) { + createEvent(stream.device_index()); + } + + TORCH_CHECK( + device_index_ == stream.device_index(), + "Event device ", + device_index_, + " does not match recording stream's device ", + stream.device_index(), + "."); + CUDAGuard guard(device_index_); + +#ifndef USE_ROCM + // it is an error to use cudaEventRecordExternal when not doing stream + // capture + unsigned int flags = (c10::cuda::currentStreamCaptureStatusMayInitCtx() != + c10::cuda::CaptureStatus::None && + external_) + ? cudaEventRecordExternal + : cudaEventRecordDefault; + C10_CUDA_CHECK(cudaEventRecordWithFlags(event_, stream, flags)); +#else + C10_CUDA_CHECK(cudaEventRecord(event_, stream)); +#endif + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_record( + c10::kCUDA, + reinterpret_cast(event_), + reinterpret_cast(stream.stream())); + } + was_recorded_ = true; + } + + // Note: cudaStreamWaitEvent must be called on the same device as the stream. + // The event has no actual GPU resources associated with it. + void block(const CUDAStream& stream) { + if (is_created_) { + CUDAGuard guard(stream.device_index()); +#ifndef USE_ROCM + // it is an error to use cudaEventWaitExternal when not doing stream + // capture + unsigned int flags = (c10::cuda::currentStreamCaptureStatusMayInitCtx() != + c10::cuda::CaptureStatus::None && + external_) + ? cudaEventWaitExternal + : cudaEventWaitDefault; + C10_CUDA_CHECK(cudaStreamWaitEvent(stream, event_, flags)); +#else + C10_CUDA_CHECK(cudaStreamWaitEvent(stream, event_)); +#endif + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_wait( + c10::kCUDA, + reinterpret_cast(event_), + reinterpret_cast(stream.stream())); + } + } + } + + // Note: cudaEventElapsedTime can be safely called from any device + float elapsed_time(const CUDAEvent& other) const { + TORCH_CHECK_VALUE( + !(flags_ & cudaEventDisableTiming) && + !(other.flags_ & cudaEventDisableTiming), + "Both events must be created with argument 'enable_timing=True'."); + TORCH_CHECK_VALUE( + is_created_ && other.isCreated(), + "Both events must be recorded before calculating elapsed time."); + TORCH_CHECK( + query() && other.query(), + "Both events must be completed before calculating elapsed time."); + + float time_ms = 0; + // We do not strictly have to set the device index to the same as our event, + // but if we don't and the current device is not initialized, it will + // create a new cuda context, which will consume a lot of memory. + CUDAGuard guard(device_index_); + // raise cudaErrorNotReady if either event is recorded but not yet completed + C10_CUDA_CHECK(cudaEventElapsedTime(&time_ms, event_, other.event_)); + return time_ms; + } + + // Note: cudaEventSynchronize can be safely called from any device + void synchronize() const { + if (is_created_) { + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_synchronization( + c10::kCUDA, reinterpret_cast(event_)); + } + C10_CUDA_CHECK(cudaEventSynchronize(event_)); + } + } + + // Note: cudaIpcGetEventHandle must be called on the same device as the event + void ipc_handle(cudaIpcEventHandle_t* handle) { + if (!is_created_) { + // this CUDAEvent object was initially constructed from flags but event_ + // is not created yet. + createEvent(getCurrentCUDAStream().device_index()); + } + CUDAGuard guard(device_index_); + C10_CUDA_CHECK(cudaIpcGetEventHandle(handle, event_)); + } + + void create(DeviceIndex device_index) { + if (!is_created_) { + createEvent(device_index); + } + } + + private: + unsigned int flags_ = cudaEventDisableTiming; + bool is_created_ = false; + bool was_recorded_ = false; + bool external_ = false; + DeviceIndex device_index_ = -1; + cudaEvent_t event_{}; + + void createEvent(DeviceIndex device_index) { + external_ = (flags_ & cudaEventExternal) != 0; +#ifdef USE_ROCM + TORCH_CHECK(!external_, "External events are disallowed in rocm"); +#endif + flags_ &= ~cudaEventExternal; + device_index_ = device_index; + CUDAGuard guard(device_index_); + C10_CUDA_CHECK(cudaEventCreateWithFlags(&event_, flags_)); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_creation( + c10::kCUDA, reinterpret_cast(event_)); + } + is_created_ = true; + } + + void moveHelper(CUDAEvent&& other) { + // Transfer ownership of all state from other to this + flags_ = other.flags_; + is_created_ = other.is_created_; + was_recorded_ = other.was_recorded_; + external_ = other.external_; + device_index_ = other.device_index_; + event_ = other.event_; + + // Reset other to a valid empty state to prevent double-free + // The moved-from object must not attempt to destroy the event + other.is_created_ = false; + other.event_ = cudaEvent_t{}; + } +}; + +// CUDAEventPool - A thread-safe pool of CUDA events to avoid the overhead of +// repeatedly calling cudaEventCreate(). Concurrent cudaEventCreate() calls +// can incur significant cost on some device/driver combinations. +// +// This pool maintains per-device lists of pre-created CUDA events. +// Borrowed events are returned to the pool via a custom unique_ptr deleter. + +class CUDAEventPool { + public: + using Event = std::unique_ptr< + c10::cuda::CUDAEvent, + std::function>; + + CUDAEventPool(size_t init_num_events = 0) + : pools_(c10::cuda::device_count()) { + if (init_num_events > 0) { + reserve_events_on_pools(init_num_events); + } + } + + // Acquire an event associated with a given device. If device is invalid, fall + // back to a regular CUDAEvent and no pooling. + Event get(const DeviceIndex device) { + if (device < 0 || device >= (DeviceIndex)pools_.size()) { + auto deleter = [](CUDAEvent* event) { delete event; }; + return Event(std::make_unique().release(), deleter); + } + + auto& pool = pools_[device]; + + // Create a destructor that returns the event to the appropriate device pool + auto destructor = [&pool](CUDAEvent* event) noexcept { + if (event != nullptr) { + std::lock_guard lock(pool.mutex_); + pool.event_pool_.emplace_back(event); + } + }; + + { + std::lock_guard lock(pool.mutex_); + if (!pool.event_pool_.empty()) { + auto event = std::move(pool.event_pool_.back()); + pool.event_pool_.pop_back(); + return Event(event.release(), destructor); + } + } + + // Pool is empty then create a new Event + return Event(std::make_unique().release(), destructor); + } + + void empty_cache() { + for (auto& pool : pools_) { + std::lock_guard lock(pool.mutex_); + pool.event_pool_.clear(); + } + } + + private: + // Pre-initialize each device pool with N events. This prevents + // cudaEventCreate() from invoking during steady-state execution. + void reserve_events_on_pools(size_t num_events) { + for (const auto device : c10::irange(pools_.size())) { + std::vector temp_events; + temp_events.reserve(num_events); + pools_[device].event_pool_.reserve(num_events); + for ([[maybe_unused]] const auto _ : c10::irange(num_events)) { + auto event = get(device); + event->create(device); + temp_events.emplace_back(std::move(event)); + } + // Events will be returned to pool when temp_events is destroyed. + } + } + + struct alignas(c10::hardware_destructive_interference_size) PerDevicePool { + alignas(c10::hardware_destructive_interference_size) std::mutex mutex_; + std::vector> event_pool_; + }; + + std::vector pools_; +}; + +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAException.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAException.h new file mode 100644 index 0000000000000000000000000000000000000000..5a8c805a23224c4c4375c3e6f14cab712bd231ad --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAException.h @@ -0,0 +1,104 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +// Note [CHECK macro] +// ~~~~~~~~~~~~~~~~~~ +// This is a macro so that AT_ERROR can get accurate __LINE__ +// and __FILE__ information. We could split this into a short +// macro and a function implementation if we pass along __LINE__ +// and __FILE__, but no one has found this worth doing. + +// Used to denote errors from CUDA framework. +// This needs to be declared here instead util/Exception.h for proper conversion +// during hipify. +namespace c10 { +class C10_CUDA_API CUDAError : public c10::Error { + using Error::Error; +}; +} // namespace c10 + +#define C10_CUDA_CHECK(EXPR) \ + do { \ + const cudaError_t __err = EXPR; \ + c10::cuda::c10_cuda_check_implementation( \ + static_cast(__err), \ + __FILE__, \ + __func__, /* Line number data type not well-defined between \ + compilers, so we perform an explicit cast */ \ + static_cast(__LINE__), \ + true); \ + } while (0) +// backwards compat due to hipify v2 changes, for extension projects +#define C10_HIP_CHECK C10_CUDA_CHECK + +#define C10_CUDA_CHECK_WARN(EXPR) \ + do { \ + const cudaError_t __err = EXPR; \ + if (C10_UNLIKELY(__err != cudaSuccess)) { \ + [[maybe_unused]] auto error_unused = cudaGetLastError(); \ + TORCH_WARN("CUDA warning: ", cudaGetErrorString(__err)); \ + } \ + } while (0) + +// Indicates that a CUDA error is handled in a non-standard way +#define C10_CUDA_ERROR_HANDLED(EXPR) EXPR + +// Intentionally ignore a CUDA error +#define C10_CUDA_IGNORE_ERROR(EXPR) \ + do { \ + const cudaError_t __err = EXPR; \ + if (C10_UNLIKELY(__err != cudaSuccess)) { \ + [[maybe_unused]] cudaError_t error_unused = cudaGetLastError(); \ + } \ + } while (0) + +// Clear the last CUDA error +#define C10_CUDA_CLEAR_ERROR() \ + do { \ + [[maybe_unused]] cudaError_t error_unused = cudaGetLastError(); \ + } while (0) + +// This should be used directly after every kernel launch to ensure +// the launch happened correctly and provide an early, close-to-source +// diagnostic if it didn't. +#define C10_CUDA_KERNEL_LAUNCH_CHECK() C10_CUDA_CHECK(cudaGetLastError()) + +/// Launches a CUDA kernel appending to it all the information need to handle +/// device-side assertion failures. Checks that the launch was successful. +#define TORCH_DSA_KERNEL_LAUNCH( \ + kernel, blocks, threads, shared_mem, stream, ...) \ + do { \ + auto& launch_registry = \ + c10::cuda::CUDAKernelLaunchRegistry::get_singleton_ref(); \ + kernel<<>>( \ + __VA_ARGS__, \ + launch_registry.get_uvm_assertions_ptr_for_current_device(), \ + launch_registry.insert( \ + __FILE__, __FUNCTION__, __LINE__, #kernel, stream.id())); \ + C10_CUDA_KERNEL_LAUNCH_CHECK(); \ + } while (0) + +namespace c10::cuda { + +/// In the event of a CUDA failure, formats a nice error message about that +/// failure and also checks for device-side assertion failures +C10_CUDA_API void c10_cuda_check_implementation( + const int32_t err, + const char* filename, + const char* function_name, + const uint32_t line_number, + const bool include_device_assertions); + +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAFunctions.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAFunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..be4dc8b14bc534739ceb2070ca37fb5b55f30bbe --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAFunctions.h @@ -0,0 +1,154 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// This header provides C++ wrappers around commonly used CUDA API functions. +// The benefit of using C++ here is that we can raise an exception in the +// event of an error, rather than explicitly pass around error codes. This +// leads to more natural APIs. +// +// The naming convention used here matches the naming convention of torch.cuda + +#include +#include +#include +#include +#include +namespace c10::cuda { + +// NB: In the past, we were inconsistent about whether or not this reported +// an error if there were driver problems are not. Based on experience +// interacting with users, it seems that people basically ~never want this +// function to fail; it should just return zero if things are not working. +// Oblige them. +// It still might log a warning for user first time it's invoked +C10_CUDA_API DeviceIndex device_count() noexcept; + +// Version of device_count that throws is no devices are detected +C10_CUDA_API DeviceIndex device_count_ensure_non_zero(); + +C10_CUDA_API DeviceIndex current_device(); + +C10_CUDA_API void set_device(DeviceIndex device, const bool force = false); + +C10_CUDA_API void device_synchronize(); + +C10_CUDA_API void warn_or_error_on_sync(); + +// Raw CUDA device management functions +C10_CUDA_API cudaError_t GetDeviceCount(int* dev_count); + +C10_CUDA_API cudaError_t GetDevice(DeviceIndex* device); + +C10_CUDA_API cudaError_t +SetDevice(DeviceIndex device, const bool force = false); + +C10_CUDA_API cudaError_t MaybeSetDevice(DeviceIndex device); + +C10_CUDA_API DeviceIndex ExchangeDevice(DeviceIndex device); + +C10_CUDA_API DeviceIndex MaybeExchangeDevice(DeviceIndex device); + +C10_CUDA_API void SetTargetDevice(); + +enum class SyncDebugMode { L_DISABLED = 0, L_WARN, L_ERROR }; + +// this is a holder for c10 global state (similar to at GlobalContext) +// currently it's used to store cuda synchronization warning state, +// but can be expanded to hold other related global state, e.g. to +// record stream usage +class WarningState { + public: + void set_sync_debug_mode(SyncDebugMode l) { + sync_debug_mode = l; + } + + SyncDebugMode get_sync_debug_mode() { + return sync_debug_mode; + } + + private: + SyncDebugMode sync_debug_mode = SyncDebugMode::L_DISABLED; +}; + +C10_CUDA_API __inline__ WarningState& warning_state() { + static WarningState warning_state_; + return warning_state_; +} +// the subsequent functions are defined in the header because for performance +// reasons we want them to be inline +C10_CUDA_API void __inline__ memcpy_and_sync( + void* dst, + const void* src, + int64_t nbytes, + cudaMemcpyKind kind, + cudaStream_t stream) { + if (C10_UNLIKELY( + warning_state().get_sync_debug_mode() != SyncDebugMode::L_DISABLED)) { + warn_or_error_on_sync(); + } + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_stream_synchronization( + c10::kCUDA, reinterpret_cast(stream)); + } +#if defined(USE_ROCM) && USE_ROCM + // As of ROCm 6.4.1, HIP runtime does not raise an error during capture of + // hipMemcpyWithStream which is a synchronous call. Thus, we add a check + // here explicitly. + hipStreamCaptureStatus captureStatus; + C10_CUDA_CHECK(hipStreamGetCaptureInfo(stream, &captureStatus, nullptr)); + if (C10_LIKELY(captureStatus == hipStreamCaptureStatusNone)) { + C10_CUDA_CHECK(hipMemcpyWithStream(dst, src, nbytes, kind, stream)); + } else { + C10_CUDA_CHECK(hipErrorStreamCaptureUnsupported); + } +#else + C10_CUDA_CHECK(cudaMemcpyAsync(dst, src, nbytes, kind, stream)); + C10_CUDA_CHECK(cudaStreamSynchronize(stream)); +#endif +} + +C10_CUDA_API void __inline__ stream_synchronize(cudaStream_t stream) { + if (C10_UNLIKELY( + warning_state().get_sync_debug_mode() != SyncDebugMode::L_DISABLED)) { + warn_or_error_on_sync(); + } + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_stream_synchronization( + c10::kCUDA, reinterpret_cast(stream)); + } + C10_CUDA_CHECK(cudaStreamSynchronize(stream)); +} + +C10_CUDA_API bool hasPrimaryContext(DeviceIndex device_index); +C10_CUDA_API std::optional getDeviceIndexWithPrimaryContext(); + +} // namespace c10::cuda + +#ifdef USE_ROCM +// for backward-compat between hipify v1 and v2 for external projects +namespace c10::hip { +using c10::cuda::current_device; +using c10::cuda::device_count; +using c10::cuda::device_count_ensure_non_zero; +using c10::cuda::device_synchronize; +using c10::cuda::ExchangeDevice; +using c10::cuda::GetDevice; +using c10::cuda::GetDeviceCount; +using c10::cuda::getDeviceIndexWithPrimaryContext; +using c10::cuda::hasPrimaryContext; +using c10::cuda::MaybeExchangeDevice; +using c10::cuda::MaybeSetDevice; +using c10::cuda::memcpy_and_sync; +using c10::cuda::set_device; +using c10::cuda::SetDevice; +using c10::cuda::SetTargetDevice; +using c10::cuda::stream_synchronize; +using c10::cuda::warn_or_error_on_sync; +} // namespace c10::hip +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAGraphsC10Utils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAGraphsC10Utils.h new file mode 100644 index 0000000000000000000000000000000000000000..6992addcbd323279f46e399d4dc088557756697d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAGraphsC10Utils.h @@ -0,0 +1,114 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include +#include + +// CUDA Graphs utils used by c10 and aten. +// aten/cuda/CUDAGraphsUtils.cuh adds utils used by aten only. + +namespace c10::cuda { + +// RAII guard for "cudaStreamCaptureMode", a thread-local value +// that controls the error-checking strictness of a capture. +struct C10_CUDA_API CUDAStreamCaptureModeGuard { + CUDAStreamCaptureModeGuard(cudaStreamCaptureMode desired) + : strictness_(desired) { + C10_CUDA_CHECK(cudaThreadExchangeStreamCaptureMode(&strictness_)); + } + CUDAStreamCaptureModeGuard(const CUDAStreamCaptureModeGuard&) = delete; + CUDAStreamCaptureModeGuard(CUDAStreamCaptureModeGuard&&) = delete; + CUDAStreamCaptureModeGuard& operator=(const CUDAStreamCaptureModeGuard&) = + delete; + CUDAStreamCaptureModeGuard& operator=(CUDAStreamCaptureModeGuard&&) = delete; + ~CUDAStreamCaptureModeGuard() { + C10_CUDA_CHECK_WARN(cudaThreadExchangeStreamCaptureMode(&strictness_)); + } + + private: + cudaStreamCaptureMode strictness_; +}; + +// Protects against enum cudaStreamCaptureStatus implementation changes. +// Some compilers seem not to like static_assert without the messages. +static_assert( + int(cudaStreamCaptureStatus::cudaStreamCaptureStatusNone) == 0, + "unexpected int(cudaStreamCaptureStatusNone) value"); +static_assert( + int(cudaStreamCaptureStatus::cudaStreamCaptureStatusActive) == 1, + "unexpected int(cudaStreamCaptureStatusActive) value"); +static_assert( + int(cudaStreamCaptureStatus::cudaStreamCaptureStatusInvalidated) == 2, + "unexpected int(cudaStreamCaptureStatusInvalidated) value"); + +enum class CaptureStatus : int { + None = int(cudaStreamCaptureStatus::cudaStreamCaptureStatusNone), + Active = int(cudaStreamCaptureStatus::cudaStreamCaptureStatusActive), + Invalidated = int(cudaStreamCaptureStatus::cudaStreamCaptureStatusInvalidated) +}; + +inline std::ostream& operator<<(std::ostream& os, CaptureStatus status) { + switch (status) { + case CaptureStatus::None: + os << "cudaStreamCaptureStatusNone"; + break; + case CaptureStatus::Active: + os << "cudaStreamCaptureStatusActive"; + break; + case CaptureStatus::Invalidated: + os << "cudaStreamCaptureStatusInvalidated"; + break; + default: + TORCH_INTERNAL_ASSERT( + false, "Unknown CUDA graph CaptureStatus", int(status)); + } + return os; +} + +// Use this version where you're sure a CUDA context exists already. +inline CaptureStatus currentStreamCaptureStatusMayInitCtx() { + cudaStreamCaptureStatus status{cudaStreamCaptureStatusNone}; + C10_CUDA_CHECK( + cudaStreamIsCapturing(c10::cuda::getCurrentCUDAStream(), &status)); + return CaptureStatus(status); +} + +inline CaptureStatus captureStatusMayInitCtx(cudaStream_t stream) { + cudaStreamCaptureStatus status{cudaStreamCaptureStatusNone}; + C10_CUDA_CHECK(cudaStreamIsCapturing(stream, &status)); + return CaptureStatus(status); +} + +inline bool isStreamCapturingMayInitCtx(cudaStream_t stream) { + return captureStatusMayInitCtx(stream) == CaptureStatus::Active; +} + +inline std::optional currentStreamCaptureIdMayInitCtx() { + cudaStreamCaptureStatus status{}; + CaptureId_t capture_id = 0; + C10_CUDA_CHECK(cudaStreamGetCaptureInfo( + c10::cuda::getCurrentCUDAStream(), &status, &capture_id)); + if (status == cudaStreamCaptureStatus::cudaStreamCaptureStatusActive) { + return capture_id; + } + return std::nullopt; +} + +inline std::optional captureIdMayInitCtx(cudaStream_t stream) { + cudaStreamCaptureStatus status{}; + CaptureId_t capture_id = 0; + C10_CUDA_CHECK(cudaStreamGetCaptureInfo(stream, &status, &capture_id)); + if (status == cudaStreamCaptureStatus::cudaStreamCaptureStatusActive) { + return capture_id; + } + return std::nullopt; +} + +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAGuard.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAGuard.h new file mode 100644 index 0000000000000000000000000000000000000000..6cf6ce4be26c07d3869fb4c7d7242fc220128fe8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAGuard.h @@ -0,0 +1,311 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace c10::cuda { + +// This code is kind of boilerplatey. See Note [Whither the DeviceGuard +// boilerplate] + +/// A variant of DeviceGuard that is specialized for CUDA. It accepts +/// integer indices (interpreting them as CUDA devices) and is a little +/// more efficient than DeviceGuard (it compiles to straight line +/// cudaSetDevice/cudaGetDevice calls); however, it can only be used +/// from code that links against CUDA directly. +struct CUDAGuard { + /// No default constructor; see Note [Omitted default constructor from RAII] + explicit CUDAGuard() = delete; + + /// Set the current CUDA device to the passed device index. + explicit CUDAGuard(DeviceIndex device_index) : guard_(device_index) {} + + /// Sets the current CUDA device to the passed device. Errors if the passed + /// device is not a CUDA device. + explicit CUDAGuard(Device device) : guard_(device) {} + + // Copy is not allowed + CUDAGuard(const CUDAGuard&) = delete; + CUDAGuard& operator=(const CUDAGuard&) = delete; + + // Move is not allowed (there is no uninitialized state) + CUDAGuard(CUDAGuard&& other) = delete; + CUDAGuard& operator=(CUDAGuard&& other) = delete; + ~CUDAGuard() = default; + + /// Sets the CUDA device to the given device. Errors if the given device + /// is not a CUDA device. + void set_device(Device device) { + guard_.set_device(device); + } + + /// Sets the CUDA device to the given device. Errors if the given device + /// is not a CUDA device. (This method is provided for uniformity with + /// DeviceGuard). + void reset_device(Device device) { + guard_.reset_device(device); + } + + /// Sets the CUDA device to the given device index. + void set_index(DeviceIndex device_index) { + guard_.set_index(device_index); + } + + /// Returns the device that was set upon construction of the guard + Device original_device() const { + return guard_.original_device(); + } + + /// Returns the last device that was set via `set_device`, if any, otherwise + /// the device passed during construction. + Device current_device() const { + return guard_.current_device(); + } + + private: + /// The guard for the current device. + c10::impl::InlineDeviceGuard guard_; +}; + +/// A variant of OptionalDeviceGuard that is specialized for CUDA. See +/// CUDAGuard for when you can use this. +struct OptionalCUDAGuard { + /// Create an uninitialized OptionalCUDAGuard. + explicit OptionalCUDAGuard() = default; + + /// Set the current CUDA device to the passed Device, if it is not nullopt. + explicit OptionalCUDAGuard(std::optional device_opt) + : guard_(device_opt) {} + + /// Set the current CUDA device to the passed device index, if it is not + /// nullopt + explicit OptionalCUDAGuard(std::optional device_index_opt) + : guard_(device_index_opt) {} + + // Copy is not allowed + OptionalCUDAGuard(const OptionalCUDAGuard&) = delete; + OptionalCUDAGuard& operator=(const OptionalCUDAGuard&) = delete; + + // See Note [Move construction for RAII guards is tricky] + OptionalCUDAGuard(OptionalCUDAGuard&& other) = delete; + + // See Note [Move assignment for RAII guards is tricky] + OptionalCUDAGuard& operator=(OptionalCUDAGuard&& other) = delete; + ~OptionalCUDAGuard() = default; + + /// Sets the CUDA device to the given device, initializing the guard if it + /// is not already initialized. Errors if the given device is not a CUDA + /// device. + void set_device(Device device) { + guard_.set_device(device); + } + + /// Sets the CUDA device to the given device, initializing the guard if it is + /// not already initialized. Errors if the given device is not a CUDA device. + /// (This method is provided for uniformity with OptionalDeviceGuard). + void reset_device(Device device) { + guard_.reset_device(device); + } + + /// Sets the CUDA device to the given device index, initializing the guard if + /// it is not already initialized. + void set_index(DeviceIndex device_index) { + guard_.set_index(device_index); + } + + /// Returns the device that was set immediately prior to initialization of the + /// guard, or nullopt if the guard is uninitialized. + std::optional original_device() const { + return guard_.original_device(); + } + + /// Returns the most recent device that was set using this device guard, + /// either from construction, or via set_device, if the guard is initialized, + /// or nullopt if the guard is uninitialized. + std::optional current_device() const { + return guard_.current_device(); + } + + /// Restore the original CUDA device, resetting this guard to uninitialized + /// state. + void reset() { + guard_.reset(); + } + + private: + c10::impl::InlineOptionalDeviceGuard guard_; +}; + +/// A variant of StreamGuard that is specialized for CUDA. See CUDAGuard +/// for when you can use this. +struct CUDAStreamGuard { + /// No default constructor, see Note [Omitted default constructor from RAII] + explicit CUDAStreamGuard() = delete; + + /// Set the current CUDA device to the device associated with the passed + /// stream, and set the current CUDA stream on that device to the passed + /// stream. Errors if the Stream is not a CUDA stream. + explicit CUDAStreamGuard(Stream stream) : guard_(stream) {} + ~CUDAStreamGuard() = default; + + /// Copy is disallowed + CUDAStreamGuard(const CUDAStreamGuard&) = delete; + CUDAStreamGuard& operator=(const CUDAStreamGuard&) = delete; + + /// Move is disallowed, as CUDAStreamGuard does not have an uninitialized + /// state, which is required for moves on types with nontrivial destructors. + CUDAStreamGuard(CUDAStreamGuard&& other) = delete; + CUDAStreamGuard& operator=(CUDAStreamGuard&& other) = delete; + + /// Resets the currently set stream to the original stream and + /// the currently set device to the original device. Then, + /// set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream. + /// Errors if the stream passed is not a CUDA stream. + /// + /// NOTE: this implementation may skip some stream/device setting if + /// it can prove that it is unnecessary. + /// + /// WARNING: reset_stream does NOT preserve previously set streams on + /// different devices. If you need to set streams on multiple devices + /// on CUDA, use CUDAMultiStreamGuard instead. + void reset_stream(Stream stream) { + guard_.reset_stream(stream); + } + + /// Returns the CUDA stream that was set at the time the guard was + /// constructed. + CUDAStream original_stream() const { + return CUDAStream(CUDAStream::UNCHECKED, guard_.original_stream()); + } + + /// Returns the most recent CUDA stream that was set using this device guard, + /// either from construction, or via set_stream. + CUDAStream current_stream() const { + return CUDAStream(CUDAStream::UNCHECKED, guard_.current_stream()); + } + + /// Returns the most recent CUDA device that was set using this device guard, + /// either from construction, or via set_device/reset_device/set_index. + Device current_device() const { + return guard_.current_device(); + } + + /// Returns the CUDA device that was set at the most recent reset_stream(), + /// or otherwise the device at construction time. + Device original_device() const { + return guard_.original_device(); + } + + private: + c10::impl::InlineStreamGuard guard_; +}; + +/// A variant of OptionalStreamGuard that is specialized for CUDA. See +/// CUDAGuard for when you can use this. +struct OptionalCUDAStreamGuard { + /// Create an uninitialized guard. + explicit OptionalCUDAStreamGuard() = default; + + /// Set the current CUDA device to the device associated with the passed + /// stream, and set the current CUDA stream on that device to the passed + /// stream. Errors if the Stream is not a CUDA stream. + explicit OptionalCUDAStreamGuard(Stream stream) : guard_(stream) {} + + /// Set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream, + /// if the passed stream is not nullopt. + explicit OptionalCUDAStreamGuard(std::optional stream_opt) + : guard_(stream_opt) {} + + /// Copy is disallowed + OptionalCUDAStreamGuard(const OptionalCUDAStreamGuard&) = delete; + OptionalCUDAStreamGuard& operator=(const OptionalCUDAStreamGuard&) = delete; + + // See Note [Move construction for RAII guards is tricky] + OptionalCUDAStreamGuard(OptionalCUDAStreamGuard&& other) = delete; + + // See Note [Move assignment for RAII guards is tricky] + OptionalCUDAStreamGuard& operator=(OptionalCUDAStreamGuard&& other) = delete; + ~OptionalCUDAStreamGuard() = default; + + /// Resets the currently set CUDA stream to the original stream and + /// the currently set device to the original device. Then, + /// set the current device to the device associated with the passed stream, + /// and set the current stream on that device to the passed stream. + /// Initializes the guard if it was not previously initialized. + void reset_stream(Stream stream) { + guard_.reset_stream(stream); + } + + /// Returns the CUDA stream that was set at the time the guard was most + /// recently initialized, or nullopt if the guard is uninitialized. + std::optional original_stream() const { + auto r = guard_.original_stream(); + if (r.has_value()) { + return CUDAStream(CUDAStream::UNCHECKED, r.value()); + } else { + return std::nullopt; + } + } + + /// Returns the most recent CUDA stream that was set using this stream guard, + /// either from construction, or via reset_stream, if the guard is + /// initialized, or nullopt if the guard is uninitialized. + std::optional current_stream() const { + auto r = guard_.current_stream(); + if (r.has_value()) { + return CUDAStream(CUDAStream::UNCHECKED, r.value()); + } else { + return std::nullopt; + } + } + + /// Restore the original CUDA device and stream, resetting this guard to + /// uninitialized state. + void reset() { + guard_.reset(); + } + + private: + c10::impl::InlineOptionalStreamGuard guard_; +}; + +/// A variant of MultiStreamGuard that is specialized for CUDA. +struct CUDAMultiStreamGuard { + explicit CUDAMultiStreamGuard(ArrayRef streams) + : guard_(unwrapStreams(streams)) {} + + /// Copy is disallowed + CUDAMultiStreamGuard(const CUDAMultiStreamGuard&) = delete; + CUDAMultiStreamGuard& operator=(const CUDAMultiStreamGuard&) = delete; + + // See Note [Move construction for RAII guards is tricky] + CUDAMultiStreamGuard(CUDAMultiStreamGuard&& other) = delete; + + // See Note [Move assignment for RAII guards is tricky] + CUDAMultiStreamGuard& operator=(CUDAMultiStreamGuard&& other) = delete; + ~CUDAMultiStreamGuard() = default; + + private: + c10::impl::InlineMultiStreamGuard guard_; + + static std::vector unwrapStreams(ArrayRef cudaStreams) { + std::vector streams; + streams.reserve(cudaStreams.size()); + for (const CUDAStream& cudaStream : cudaStreams) { + streams.push_back(cudaStream); + } + return streams; + } +}; + +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAMacros.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAMacros.h new file mode 100644 index 0000000000000000000000000000000000000000..93b371ce6ee854d074f6d47d0481c2a193e07d69 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAMacros.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#ifndef C10_USING_CUSTOM_GENERATED_MACROS + +// We have not yet modified the AMD HIP build to generate this file so +// we add an extra option to specifically ignore it. +#ifndef C10_CUDA_NO_CMAKE_CONFIGURE_FILE +#include +#endif // C10_CUDA_NO_CMAKE_CONFIGURE_FILE + +#endif + +// See c10/macros/Export.h for a detailed explanation of what the function +// of these macros are. We need one set of macros for every separate library +// we build. + +#ifdef _WIN32 +#if defined(C10_CUDA_BUILD_SHARED_LIBS) +#define C10_CUDA_EXPORT __declspec(dllexport) +#define C10_CUDA_IMPORT __declspec(dllimport) +#else +#define C10_CUDA_EXPORT +#define C10_CUDA_IMPORT +#endif +#else // _WIN32 +#if defined(__GNUC__) +#define C10_CUDA_EXPORT __attribute__((__visibility__("default"))) +#else // defined(__GNUC__) +#define C10_CUDA_EXPORT +#endif // defined(__GNUC__) +#define C10_CUDA_IMPORT C10_CUDA_EXPORT +#endif // _WIN32 + +// This one is being used by libc10_cuda.so +#ifdef C10_CUDA_BUILD_MAIN_LIB +#define C10_CUDA_API C10_CUDA_EXPORT +#else +#define C10_CUDA_API C10_CUDA_IMPORT +#endif + +/** + * The maximum number of GPUs that we recognizes. Increasing this beyond the + * initial limit of 16 broke Caffe2 testing, hence the ifdef guards. + * This value cannot be more than 128 because our DeviceIndex is a uint8_t. +o */ +#ifdef FBCODE_CAFFE2 +// fbcode depends on this value being 16 +#define C10_COMPILE_TIME_MAX_GPUS 16 +#else +#define C10_COMPILE_TIME_MAX_GPUS 120 +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAMathCompat.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAMathCompat.h new file mode 100644 index 0000000000000000000000000000000000000000..ec08cde0c1b71c9a0c8dd586e4fa7f6760e230f8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAMathCompat.h @@ -0,0 +1,157 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +/* This file defines math functions compatible across different gpu + * platforms (currently CUDA and HIP). + */ +#if defined(__CUDACC__) || defined(__HIPCC__) + +#include +#include + +#ifdef __HIPCC__ +#define __MATH_FUNCTIONS_DECL__ inline C10_DEVICE +#else /* __HIPCC__ */ +#ifdef __CUDACC_RTC__ +#define __MATH_FUNCTIONS_DECL__ C10_HOST_DEVICE +#else /* __CUDACC_RTC__ */ +#define __MATH_FUNCTIONS_DECL__ inline C10_HOST_DEVICE +#endif /* __CUDACC_RTC__ */ +#endif /* __HIPCC__ */ + +namespace c10::cuda::compat { + +__MATH_FUNCTIONS_DECL__ float abs(float x) { + return ::fabsf(x); +} +__MATH_FUNCTIONS_DECL__ double abs(double x) { + return ::fabs(x); +} + +__MATH_FUNCTIONS_DECL__ float exp(float x) { + return ::expf(x); +} +__MATH_FUNCTIONS_DECL__ double exp(double x) { + return ::exp(x); +} + +__MATH_FUNCTIONS_DECL__ float ceil(float x) { + return ::ceilf(x); +} +__MATH_FUNCTIONS_DECL__ double ceil(double x) { + return ::ceil(x); +} + +__MATH_FUNCTIONS_DECL__ float copysign(float x, float y) { +#if defined(__CUDA_ARCH__) || defined(__HIPCC__) + return ::copysignf(x, y); +#else + // std::copysign gets ICE/Segfaults with gcc 7.5/8 on arm64 + // (e.g. Jetson), see PyTorch PR #51834 + // This host function needs to be here for the compiler but is never used + TORCH_INTERNAL_ASSERT( + false, "CUDAMathCompat copysign should not run on the CPU"); +#endif +} +__MATH_FUNCTIONS_DECL__ double copysign(double x, double y) { +#if defined(__CUDA_ARCH__) || defined(__HIPCC__) + return ::copysign(x, y); +#else + // see above + TORCH_INTERNAL_ASSERT( + false, "CUDAMathCompat copysign should not run on the CPU"); +#endif +} + +__MATH_FUNCTIONS_DECL__ float floor(float x) { + return ::floorf(x); +} +__MATH_FUNCTIONS_DECL__ double floor(double x) { + return ::floor(x); +} + +__MATH_FUNCTIONS_DECL__ float log(float x) { + return ::logf(x); +} +__MATH_FUNCTIONS_DECL__ double log(double x) { + return ::log(x); +} + +__MATH_FUNCTIONS_DECL__ float log1p(float x) { + return ::log1pf(x); +} + +__MATH_FUNCTIONS_DECL__ double log1p(double x) { + return ::log1p(x); +} + +__MATH_FUNCTIONS_DECL__ float max(float x, float y) { + return ::fmaxf(x, y); +} +__MATH_FUNCTIONS_DECL__ double max(double x, double y) { + return ::fmax(x, y); +} + +__MATH_FUNCTIONS_DECL__ float min(float x, float y) { + return ::fminf(x, y); +} +__MATH_FUNCTIONS_DECL__ double min(double x, double y) { + return ::fmin(x, y); +} + +__MATH_FUNCTIONS_DECL__ float pow(float x, float y) { + return ::powf(x, y); +} +__MATH_FUNCTIONS_DECL__ double pow(double x, double y) { + return ::pow(x, y); +} + +__MATH_FUNCTIONS_DECL__ void sincos(float x, float* sptr, float* cptr) { + return ::sincosf(x, sptr, cptr); +} +__MATH_FUNCTIONS_DECL__ void sincos(double x, double* sptr, double* cptr) { + return ::sincos(x, sptr, cptr); +} + +__MATH_FUNCTIONS_DECL__ float sqrt(float x) { + return ::sqrtf(x); +} +__MATH_FUNCTIONS_DECL__ double sqrt(double x) { + return ::sqrt(x); +} + +__MATH_FUNCTIONS_DECL__ float rsqrt(float x) { + return ::rsqrtf(x); +} +__MATH_FUNCTIONS_DECL__ double rsqrt(double x) { + return ::rsqrt(x); +} + +__MATH_FUNCTIONS_DECL__ float tan(float x) { + return ::tanf(x); +} +__MATH_FUNCTIONS_DECL__ double tan(double x) { + return ::tan(x); +} + +__MATH_FUNCTIONS_DECL__ float tanh(float x) { + return ::tanhf(x); +} +__MATH_FUNCTIONS_DECL__ double tanh(double x) { + return ::tanh(x); +} + +__MATH_FUNCTIONS_DECL__ float normcdf(float x) { + return ::normcdff(x); +} +__MATH_FUNCTIONS_DECL__ double normcdf(double x) { + return ::normcdf(x); +} + +} // namespace c10::cuda::compat + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAMiscFunctions.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAMiscFunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..c44105fa61281b2d06f02524b789d7c7554374f9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAMiscFunctions.h @@ -0,0 +1,20 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// this file is to avoid circular dependency between CUDAFunctions.h and +// CUDAExceptions.h + +#include +#include + +#include +#include + +namespace c10::cuda { +C10_CUDA_API std::string get_cuda_error_help(cudaError_t /*error*/) noexcept; +C10_CUDA_API const char* get_cuda_check_suffix() noexcept; +C10_CUDA_API std::mutex* getFreeMutex(); +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAStream.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAStream.h new file mode 100644 index 0000000000000000000000000000000000000000..14fd4a66e5d8d5f9115702e32042ce1af3d58980 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/CUDAStream.h @@ -0,0 +1,303 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include +#include +#include +#include + +/* + * Stream pool note. + * + * A CUDAStream is an abstraction of an actual cuStream on the GPU. CUDAStreams + * are backed by cuStreams, but they use several pools to minimize the costs + * associated with creating, retaining, and destroying cuStreams. + * + * There are three pools per device, and a device's pools are lazily created. + * + * The first pool contains only the default stream. When the default stream + * is requested it's returned. + * + * The second pool is the "low priority" or "default priority" streams. In + * HIP builds there is no distinction between streams in this pool and streams + * in the third pool (below). There are 32 of these streams per device, and + * when a stream is requested one of these streams is returned round-robin. + * That is, the first stream requested is at index 0, the second at index 1... + * to index 31, then index 0 again. + * + * This means that if 33 low priority streams are requested, the first and + * last streams requested are actually the same stream (under the covers) + * and kernels enqueued on them cannot run concurrently. + * + * The third pool is the "high priority" streams. The third pool acts like + * the second pool except the streams are created with a higher priority. + * + * These pools suggest that stream users should prefer many short-lived streams, + * as the cost of acquiring and releasing streams is effectively zero. If + * many longer-lived streams are required in performance critical scenarios + * then the functionality here may need to be extended to allow, for example, + * "reserving" a subset of the pool so that other streams do not accidentally + * overlap the performance critical streams. + * + * Note: although the notion of "current stream for device" is thread local + * (every OS thread has a separate current stream, as one might expect), + * the stream pool is global across all threads; stream 0 is always stream 0 + * no matter which thread you use it on. Multiple threads can synchronize + * on the same stream. Although the CUDA documentation is not very clear + * on the matter, streams are thread safe; e.g., it is safe to enqueue + * a kernel on the same stream from two different threads. + */ + +namespace c10::cuda { + +static constexpr int max_compile_time_stream_priorities = 4; + +// Value object representing a CUDA stream. This is just a wrapper +// around c10::Stream, but it comes with a little extra CUDA-specific +// functionality (conversion to cudaStream_t), and a guarantee that +// the wrapped c10::Stream really is a CUDA stream. +class C10_CUDA_API CUDAStream { + public: + enum Unchecked { UNCHECKED }; + + /// Construct a CUDAStream from a Stream. This construction is checked, + /// and will raise an error if the Stream is not, in fact, a CUDA stream. + explicit CUDAStream(Stream stream) : stream_(stream) { + TORCH_CHECK(stream_.device_type() == DeviceType::CUDA); + } + + /// Construct a CUDAStream from a Stream with no error checking. + /// This constructor uses the "named" constructor idiom, and can + /// be invoked as: CUDAStream(CUDAStream::UNCHECKED, stream) + explicit CUDAStream(Unchecked /*unused*/, Stream stream) : stream_(stream) {} + + bool operator==(const CUDAStream& other) const noexcept { + return unwrap() == other.unwrap(); + } + + bool operator!=(const CUDAStream& other) const noexcept { + return unwrap() != other.unwrap(); + } + + /// Implicit conversion to cudaStream_t. + operator cudaStream_t() const { + return stream(); + } + + /// Implicit conversion to Stream (a.k.a., forget that the stream is a + /// CUDA stream). + operator Stream() const { + return unwrap(); + } + + /// Used to avoid baking in device type explicitly to Python-side API. + DeviceType device_type() const { + return DeviceType::CUDA; + } + + /// Get the CUDA device index that this stream is associated with. + DeviceIndex device_index() const { + return stream_.device_index(); + } + + /// Get the full Device that this stream is associated with. The Device + /// is guaranteed to be a CUDA device. + Device device() const { + return Device(DeviceType::CUDA, device_index()); + } + + /// Return the stream ID corresponding to this particular stream. + StreamId id() const { + return stream_.id(); + } + + bool query() const; + + void synchronize() const; + + bool is_capturing() const { + DeviceGuard guard{stream_.device()}; + cudaStreamCaptureStatus status{cudaStreamCaptureStatusNone}; + C10_CUDA_CHECK(cudaStreamIsCapturing(stream(), &status)); + return status != cudaStreamCaptureStatusNone; + } + + int priority() const { + DeviceGuard guard{stream_.device()}; + int priority = 0; + C10_CUDA_CHECK(cudaStreamGetPriority(stream(), &priority)); + return priority; + } + + /// Explicit conversion to cudaStream_t. + cudaStream_t stream() const; + + /// Explicit conversion to Stream. + Stream unwrap() const { + return stream_; + } + + /// Reversibly pack a CUDAStream into a struct representation. + /// Previously the stream's data was packed into a single int64_t, + /// as it was assumed the fields would not require more than + /// 64 bits of storage in total. + /// See https://github.com/pytorch/pytorch/issues/75854 + /// for more information regarding newer platforms that may violate + /// this assumption. + /// + /// The CUDAStream can be unpacked using unpack(). + struct c10::StreamData3 pack3() const { + return stream_.pack3(); + } + + // Unpack a CUDAStream from the 3 fields generated by pack(). + static CUDAStream unpack3( + StreamId stream_id, + DeviceIndex device_index, + DeviceType device_type) { + return CUDAStream(Stream::unpack3(stream_id, device_index, device_type)); + } + + static std::tuple priority_range() { + // Note: this returns the range of priority **supported by PyTorch**, not + // the range of priority **supported by CUDA**. The former is a subset of + // the latter. + int least_priority = 0, greatest_priority = 0; + C10_CUDA_CHECK( + cudaDeviceGetStreamPriorityRange(&least_priority, &greatest_priority)); +#ifdef USE_ROCM + // See Note [HIP stream priorities] + TORCH_INTERNAL_ASSERT( + least_priority == 1, "Unexpected HIP stream priority range"); + least_priority = 0; +#else + TORCH_INTERNAL_ASSERT( + least_priority == 0, "Unexpected CUDA stream priority range"); +#endif + TORCH_INTERNAL_ASSERT( + greatest_priority <= -1, "Unexpected CUDA stream priority range"); + greatest_priority = std::max( + -c10::cuda::max_compile_time_stream_priorities + 1, greatest_priority); + return std::make_tuple(least_priority, greatest_priority); + } + + // Deleted for now; use CUDAEvent::block instead + // void synchronize_with(const CUDAEvent& event) const; + + private: + Stream stream_; +}; + +/** + * Get a new stream from the CUDA stream pool. You can think of this + * as "creating" a new stream, but no such creation actually happens; + * instead, streams are preallocated from the pool and returned in a + * round-robin fashion. + * + * You can request a stream from the high priority pool by setting + * isHighPriority to true, or a stream for a specific device by setting device + * (defaulting to the current CUDA stream.) + */ +C10_API CUDAStream +getStreamFromPool(const bool isHighPriority = false, DeviceIndex device = -1); +// no default priority to disambiguate overloads +C10_API CUDAStream +getStreamFromPool(const int priority, DeviceIndex device = -1); + +/** + * Get a CUDAStream from a externally allocated one. + * + * This is mainly for interoperability with different libraries where we + * want to operate on a non-torch allocated stream for data exchange or similar + * purposes + */ +C10_API CUDAStream +getStreamFromExternal(cudaStream_t ext_stream, DeviceIndex device_index); + +/** + * Get the default CUDA stream, for the passed CUDA device, or for the + * current device if no device index is passed. The default stream is + * where most computation occurs when you aren't explicitly using + * streams. + */ +C10_API CUDAStream getDefaultCUDAStream(DeviceIndex device_index = -1); + +/** + * Get the current CUDA stream, for the passed CUDA device, or for the + * current device if no device index is passed. The current CUDA stream + * will usually be the default CUDA stream for the device, but it may + * be different if someone called 'setCurrentCUDAStream' or used 'StreamGuard' + * or 'CUDAStreamGuard'. + */ +C10_API CUDAStream getCurrentCUDAStream(DeviceIndex device_index = -1); + +/** + * Set the current stream on the device of the passed in stream to be + * the passed in stream. Yes, you read that right: this function + * has *nothing* to do with the current device: it toggles the current + * stream of the device of the passed stream. + * + * Confused? Avoid using this function; prefer using 'CUDAStreamGuard' instead + * (which will switch both your current device and current stream in the way you + * expect, and reset it back to its original state afterwards). + */ +C10_API void setCurrentCUDAStream(CUDAStream stream); + +C10_API std::ostream& operator<<(std::ostream& stream, const CUDAStream& s); + +} // namespace c10::cuda + +// hipify v2 backward compat in external projects +#ifdef USE_ROCM +namespace c10::hip { +using c10::cuda::getStreamFromExternal; +using c10::cuda::getStreamFromPool; +// must use inline wrappers instead of reference aliases due to default args +inline c10::cuda::CUDAStream getDefaultHIPStream( + DeviceIndex device_index = -1) { + return c10::cuda::getDefaultCUDAStream(device_index); +} +inline c10::cuda::CUDAStream getCurrentHIPStream( + DeviceIndex device_index = -1) { + return c10::cuda::getCurrentCUDAStream(device_index); +} +inline auto& setCurrentHIPStream = c10::cuda::setCurrentCUDAStream; +inline c10::cuda::CUDAStream getStreamFromPoolMasqueradingAsCUDA( + const bool isHighPriority = false, + DeviceIndex device = -1) { + return c10::cuda::getStreamFromPool(isHighPriority, device); +} +inline c10::cuda::CUDAStream getStreamFromPoolMasqueradingAsCUDA( + const int priority, + DeviceIndex device = -1) { + return c10::cuda::getStreamFromPool(priority, device); +} +inline auto& getStreamFromExternalMasqueradingAsCUDA = + c10::cuda::getStreamFromExternal; +inline c10::cuda::CUDAStream getDefaultHIPStreamMasqueradingAsCUDA( + DeviceIndex device_index = -1) { + return c10::cuda::getDefaultCUDAStream(device_index); +} +inline c10::cuda::CUDAStream getCurrentHIPStreamMasqueradingAsCUDA( + DeviceIndex device_index = -1) { + return c10::cuda::getCurrentCUDAStream(device_index); +} +inline auto& setCurrentHIPStreamMasqueradingAsCUDA = + c10::cuda::setCurrentCUDAStream; +} // namespace c10::hip +#endif + +namespace std { +template <> +struct hash { + size_t operator()(c10::cuda::CUDAStream s) const noexcept { + return std::hash{}(s.unwrap()); + } +}; +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/PeerToPeerAccess.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/PeerToPeerAccess.h new file mode 100644 index 0000000000000000000000000000000000000000..373d89a334c078d48fc15b22e5eda2dee65cdd55 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/PeerToPeerAccess.h @@ -0,0 +1,54 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +#include +#include + +namespace c10::cuda { + +namespace detail { + +/// Initialize the peer-to-peer and fabric access caches. +/// Must be called before any calls to get_p2p_access or get_fabric_access. +/// @param num_devices The number of CUDA devices in the system. +C10_CUDA_API void init_p2p_access_cache(int64_t num_devices); + +} // namespace detail + +/// Query if peer-to-peer access is available between two devices. +/// @param source_dev The source device index. +/// @param dest_dev The destination device index. +/// @return true if P2P access is available, false otherwise. +C10_CUDA_API bool get_p2p_access( + c10::DeviceIndex source_dev, + c10::DeviceIndex dest_dev); + +/// Query if GPU fabric (high-speed interconnect like NVLink/NVSwitch) is +/// available for a device. This checks both hardware support and the ability +/// to allocate/export/import memory with fabric handles. +/// @param device The device index to check. +/// @return true if fabric access is available, false otherwise. +C10_CUDA_API bool get_fabric_access(c10::DeviceIndex device); + +constexpr int kCliqueIdNotQueried = -2; +constexpr int kCliqueIdUnsupported = -1; + +/// Query the NVLink fabric clique ID for a device. +/// Returns the clique ID (>= 0) if fabric is supported, or kCliqueIdUnsupported +/// if unsupported. +C10_CUDA_API int get_fabric_clique_id(c10::DeviceIndex device); + +/// Returns a formatted string with NVML fabric info (clique_id, cluster_uuid, +/// state, status, health_mask) for the given device. Intended for error +/// diagnostics — only call on failure paths. +C10_CUDA_API std::string get_nvml_fabric_info(c10::DeviceIndex device); + +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/driver_api.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/driver_api.h new file mode 100644 index 0000000000000000000000000000000000000000..b3635f5ff41ac10c32c5000a1f71d30d8a336d38 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/driver_api.h @@ -0,0 +1,151 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#define NVML_NO_UNVERSIONED_FUNC_DEFS +#include + +#include + +#define C10_CUDA_DRIVER_CHECK(EXPR) \ + do { \ + CUresult __err = EXPR; \ + if (__err != CUDA_SUCCESS) { \ + const char* err_str; \ + CUresult get_error_str_err [[maybe_unused]] = \ + c10::cuda::DriverAPI::get()->cuGetErrorString_(__err, &err_str); \ + if (get_error_str_err != CUDA_SUCCESS) { \ + TORCH_CHECK(false, "CUDA driver error: unknown error"); \ + } else { \ + TORCH_CHECK(false, "CUDA driver error: ", err_str); \ + } \ + } \ + } while (0) + +// clang-format off +#define C10_CUDA_DRIVER_CHECK_MSG(EXPR, ...) \ + do { \ + CUresult __err = EXPR; \ + if (__err != CUDA_SUCCESS) { \ + const char* err_str; \ + CUresult get_error_str_err [[maybe_unused]] = \ + c10::cuda::DriverAPI::get()->cuGetErrorString_(__err, &err_str); \ + if (get_error_str_err != CUDA_SUCCESS) { \ + TORCH_CHECK(false, "CUDA driver error: unknown error", __VA_ARGS__);\ + } else { \ + TORCH_CHECK(false, "CUDA driver error: ", err_str, __VA_ARGS__); \ + } \ + } \ + } while (0) +// clang-format on + +#define C10_CUDA_DRIVER_CHECK_GOTO(EXPR, NEXT) \ + do { \ + CUresult __err = EXPR; \ + if (__err != CUDA_SUCCESS) { \ + const char* err_str; \ + CUresult get_error_str_err [[maybe_unused]] = \ + c10::cuda::DriverAPI::get()->cuGetErrorString_(__err, &err_str); \ + if (get_error_str_err != CUDA_SUCCESS) { \ + TORCH_WARN("CUDA driver error: unknown error"); \ + } else { \ + TORCH_WARN("CUDA driver error: ", err_str); \ + } \ + goto NEXT; \ + } \ + } while (0) + +// The integer in the second column specifies the requested CUDA Driver API +// version. The dynamic loader will accept a driver with a newer version, but it +// ensures that the requested symbol exists in *at least* the specified version +// or earlier. + +// Keep these requested versions as low as possible to maximize compatibility +// across different driver versions. + +// Why do we pin to an older version instead of using the latest? +// If a user installs a newer driver, blindly resolving the symbol may bind to a +// newer version of the function with different behavior, potentially breaking +// PyTorch. + +#define C10_LIBCUDA_DRIVER_API_REQUIRED(_) \ + _(cuDeviceGet, 12000) \ + _(cuDeviceGetAttribute, 12000) \ + _(cuMemGetAddressRange, 12000) \ + _(cuMemAddressReserve, 12000) \ + _(cuMemRelease, 12000) \ + _(cuMemMap, 12000) \ + _(cuMemAddressFree, 12000) \ + _(cuMemSetAccess, 12000) \ + _(cuMemUnmap, 12000) \ + _(cuMemCreate, 12000) \ + _(cuMemGetAllocationGranularity, 12000) \ + _(cuMemExportToShareableHandle, 12000) \ + _(cuMemImportFromShareableHandle, 12000) \ + _(cuMemRetainAllocationHandle, 12000) \ + _(cuMemGetAllocationPropertiesFromHandle, 12000) \ + _(cuMemsetD32Async, 12000) \ + _(cuStreamWriteValue32, 12000) \ + _(cuGetErrorString, 12000) + +#if defined(CUDA_VERSION) && (CUDA_VERSION >= 12080) +#define C10_LIBCUDA_DRIVER_API_OPTIONAL(_) \ + _(cuCtxFromGreenCtx, 12080) \ + _(cuCtxGetCurrent, 12080) \ + _(cuCtxPopCurrent, 12080) \ + _(cuCtxPushCurrent, 12080) \ + _(cuCtxSetCurrent, 12080) \ + _(cuGreenCtxCreate, 12080) \ + _(cuGreenCtxDestroy, 12080) \ + _(cuGreenCtxStreamCreate, 12080) \ + _(cuDevSmResourceSplitByCount, 12080) \ + _(cuDeviceGetDevResource, 12080) \ + _(cuDevResourceGenerateDesc, 12080) \ + _(cuMulticastAddDevice, 12030) \ + _(cuMulticastBindMem, 12030) \ + _(cuMulticastCreate, 12030) \ + _(cuMulticastUnbind, 12030) +#elif defined(CUDA_VERSION) && (CUDA_VERSION >= 12030) +#define C10_LIBCUDA_DRIVER_API_OPTIONAL(_) \ + _(cuMulticastAddDevice, 12030) \ + _(cuMulticastBindMem, 12030) \ + _(cuMulticastCreate, 12030) \ + _(cuMulticastUnbind, 12030) +#else +#define C10_LIBCUDA_DRIVER_API_OPTIONAL(_) +#endif + +#define C10_NVML_DRIVER_API(_) \ + _(nvmlInit_v2) \ + _(nvmlDeviceGetHandleByPciBusId_v2) \ + _(nvmlDeviceGetNvLinkRemoteDeviceType) \ + _(nvmlDeviceGetNvLinkRemotePciInfo_v2) \ + _(nvmlDeviceGetComputeRunningProcesses) \ + _(nvmlSystemGetCudaDriverVersion_v2) + +#if defined(CUDA_VERSION) && (CUDA_VERSION >= 12040) +#define C10_NVML_DRIVER_API_OPTIONAL(_) _(nvmlDeviceGetGpuFabricInfoV) +#else +#define C10_NVML_DRIVER_API_OPTIONAL(_) +#endif + +namespace c10::cuda { + +struct DriverAPI { +#define CREATE_MEMBER_VERSIONED(name, version) decltype(&name) name##_; +#define CREATE_MEMBER(name) decltype(&name) name##_; + C10_LIBCUDA_DRIVER_API_REQUIRED(CREATE_MEMBER_VERSIONED) + C10_LIBCUDA_DRIVER_API_OPTIONAL(CREATE_MEMBER_VERSIONED) + C10_NVML_DRIVER_API(CREATE_MEMBER) + C10_NVML_DRIVER_API_OPTIONAL(CREATE_MEMBER) +#undef CREATE_MEMBER_VERSIONED +#undef CREATE_MEMBER + + static DriverAPI* get(); + static void* get_nvml_handle(); +}; + +} // namespace c10::cuda + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/impl/CUDAGuardImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/impl/CUDAGuardImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..f8f7be9d9b5475987b3f77ae7e13e7fa5911a07d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/impl/CUDAGuardImpl.h @@ -0,0 +1,279 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace c10::cuda::impl { + +struct CUDAGuardImpl final : public c10::impl::DeviceGuardImplInterface { + static constexpr DeviceType static_type = DeviceType::CUDA; + + CUDAGuardImpl() = default; + explicit CUDAGuardImpl(DeviceType t) { + TORCH_CHECK( + t == DeviceType::CUDA, + "CUDAGuardImpl initialized with non-CUDA DeviceType: ", + t); + } + DeviceType type() const override { + return DeviceType::CUDA; + } + Device exchangeDevice(Device d) const override { + TORCH_CHECK(d.is_cuda(), "Expected a CUDA device, but got ", d); + auto old_device_index = c10::cuda::ExchangeDevice(d.index()); + return Device(DeviceType::CUDA, old_device_index); + } + Device getDevice() const override { + DeviceIndex device = 0; + C10_CUDA_CHECK(c10::cuda::GetDevice(&device)); + return Device(DeviceType::CUDA, device); + } + std::optional uncheckedGetDevice() const noexcept { + DeviceIndex device{-1}; + const auto err = C10_CUDA_ERROR_HANDLED(c10::cuda::GetDevice(&device)); + C10_CUDA_CHECK_WARN(err); + if (err != cudaSuccess) { + return std::nullopt; + } + return Device(DeviceType::CUDA, device); + } + void setDevice(Device d) const override { + TORCH_CHECK(d.is_cuda(), "Expected a CUDA device, but got ", d); + C10_CUDA_CHECK(c10::cuda::SetDevice(d.index())); + } + void uncheckedSetDevice(Device d) const noexcept override { + C10_CUDA_CHECK_WARN(c10::cuda::MaybeSetDevice(d.index())); + } + Stream getStream(Device d) const override { + return getCurrentCUDAStream(d.index()).unwrap(); + } + Stream getDefaultStream(Device d) const override { + return getDefaultCUDAStream(d.index()); + } + Stream getNewStream(Device d, int priority = 0) const override { + return getStreamFromPool(priority, d.index()); + } + Stream getStreamFromGlobalPool(Device d, bool isHighPriority = false) + const override { + return getStreamFromPool(isHighPriority, d.index()); + } + // NB: These do NOT set the current device + Stream exchangeStream(Stream s) const override { + CUDAStream cs(s); + auto old_stream = getCurrentCUDAStream(s.device().index()); + setCurrentCUDAStream(cs); + return old_stream.unwrap(); + } + void* getStreamNativeHandle(const Stream s) const override { + CUDAStream stream{s}; + return reinterpret_cast(stream.stream()); + } + DeviceIndex deviceCount() const noexcept override { + return device_count(); + } + + // Event-related functions + void createEvent(cudaEvent_t* cuda_event, const EventFlag flag) const { + // Maps PyTorch's Event::Flag to CUDA flag + auto cuda_flag = cudaEventDefault; + switch (flag) { + case EventFlag::PYTORCH_DEFAULT: + cuda_flag = cudaEventDisableTiming; + break; + case EventFlag::BACKEND_DEFAULT: + cuda_flag = cudaEventDefault; + break; + default: + TORCH_CHECK(false, "CUDA event received unknown flag"); + } + + C10_CUDA_CHECK(cudaEventCreateWithFlags(cuda_event, cuda_flag)); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_creation( + c10::kCUDA, reinterpret_cast(cuda_event)); + } + } + + void destroyEvent(void* event, const DeviceIndex device_index) + const noexcept override { + if (!event) + return; + auto cuda_event = static_cast(event); + DeviceIndex orig_device{-1}; + C10_CUDA_CHECK_WARN(c10::cuda::GetDevice(&orig_device)); + C10_CUDA_CHECK_WARN(c10::cuda::SetDevice(device_index)); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_deletion( + c10::kCUDA, reinterpret_cast(cuda_event)); + } + C10_CUDA_CHECK_WARN(cudaEventDestroy(cuda_event)); + C10_CUDA_CHECK_WARN(c10::cuda::SetDevice(orig_device)); + } + + void record( + void** event, + const Stream& stream, + const DeviceIndex device_index, + const EventFlag flag) const override { + TORCH_CHECK( + device_index == -1 || device_index == stream.device_index(), + "Event device index ", + device_index, + " does not match recording stream's device index ", + stream.device_index(), + "."); + + cudaEvent_t cuda_event = static_cast(*event); + CUDAStream cuda_stream{stream}; + + // Moves to stream's device to record + const auto orig_device = getDevice(); + setDevice(stream.device()); + + // Creates the event (lazily) + if (!cuda_event) + createEvent(&cuda_event, flag); + C10_CUDA_CHECK(cudaEventRecord(cuda_event, cuda_stream)); + // Makes the void* point to the (possibly just allocated) CUDA event + *event = cuda_event; + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_record( + c10::kCUDA, + reinterpret_cast(cuda_event), + reinterpret_cast(cuda_stream.stream())); + } + + // Resets device + setDevice(orig_device); + } + + void block(void* event, const Stream& stream) const override { + if (!event) + return; + cudaEvent_t cuda_event = static_cast(event); + CUDAStream cuda_stream{stream}; + const auto orig_device = getDevice(); + setDevice(stream.device()); + C10_CUDA_CHECK(cudaStreamWaitEvent( + cuda_stream, + cuda_event, + /*flags (must be zero)=*/0)); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_wait( + c10::kCUDA, + reinterpret_cast(cuda_event), + reinterpret_cast(cuda_stream.stream())); + } + setDevice(orig_device); + } + + // May be called from any device + bool queryEvent(void* event) const override { + if (!event) + return true; + cudaEvent_t cuda_event = static_cast(event); + // Note: cudaEventQuery can be safely called from any device + const cudaError_t err = C10_CUDA_ERROR_HANDLED(cudaEventQuery(cuda_event)); + if (err != cudaErrorNotReady) { + C10_CUDA_CHECK(err); + } else { + // ignore and clear the error if not ready + (void)cudaGetLastError(); + } + return (err == cudaSuccess); + } + + // Stream-related functions + bool queryStream(const Stream& stream) const override { + CUDAStream cuda_stream{stream}; + return cuda_stream.query(); + } + + void synchronizeStream(const Stream& stream) const override { + CUDAStream cuda_stream{stream}; + cuda_stream.synchronize(); + } + + bool isStreamCapturing(const Stream& stream) const override { + CUDAStream cuda_stream{stream}; + return cuda_stream.is_capturing(); + } + + void synchronizeEvent(void* event) const override { + if (!event) + return; + cudaEvent_t cuda_event = static_cast(event); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_synchronization( + c10::kCUDA, reinterpret_cast(cuda_event)); + } + // Note: cudaEventSynchronize can be safely called from any device + C10_CUDA_CHECK(cudaEventSynchronize(cuda_event)); + } + + // Note: synchronizeDevice can be safely called from any device + void synchronizeDevice(const c10::DeviceIndex device_index) const override { + DeviceIndex orig_device{-1}; + C10_CUDA_CHECK(c10::cuda::GetDevice(&orig_device)); + C10_CUDA_CHECK(c10::cuda::SetDevice(device_index)); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_device_synchronization(c10::kCUDA); + } + C10_CUDA_CHECK(cudaDeviceSynchronize()); + C10_CUDA_CHECK(c10::cuda::SetDevice(orig_device)); + } + + void recordDataPtrOnStream(const c10::DataPtr& data_ptr, const Stream& stream) + const override { + CUDAStream cuda_stream{stream}; + CUDACachingAllocator::recordStream(data_ptr, cuda_stream); + } + + double elapsedTime(void* event1, void* event2, const DeviceIndex device_index) + const override { + TORCH_CHECK( + event1 && event2, + "Both events must be recorded before calculating elapsed time."); + // Even though cudaEventElapsedTime can be safely called from any device, if + // the current device is not initialized, it will create a new cuda context, + // which will consume a lot of memory. + DeviceIndex orig_device{-1}; + C10_CUDA_CHECK(c10::cuda::GetDevice(&orig_device)); + C10_CUDA_CHECK(c10::cuda::SetDevice(device_index)); + cudaEvent_t cuda_event1 = static_cast(event1); + cudaEvent_t cuda_event2 = static_cast(event2); + float time_ms = 0; + // raise cudaErrorNotReady if either event is recorded but not yet completed + C10_CUDA_CHECK(cudaEventElapsedTime(&time_ms, cuda_event1, cuda_event2)); + C10_CUDA_CHECK(c10::cuda::SetDevice(orig_device)); + return static_cast(time_ms); + } +}; + +} // namespace c10::cuda::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/impl/CUDATest.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/impl/CUDATest.h new file mode 100644 index 0000000000000000000000000000000000000000..3edcfe6d88a72a94120bf95d82a6bbc0a0798500 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/impl/CUDATest.h @@ -0,0 +1,14 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace c10::cuda::impl { + +C10_CUDA_API int c10_cuda_test(); + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/impl/cuda_cmake_macros.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/impl/cuda_cmake_macros.h new file mode 100644 index 0000000000000000000000000000000000000000..a2fb43f54676972b1df12b2be146786465a1b403 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/cuda/impl/cuda_cmake_macros.h @@ -0,0 +1,11 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// Automatically generated header file for the C10 CUDA library. Do not +// include this file directly. Instead, include c10/cuda/CUDAMacros.h + +#define C10_CUDA_BUILD_SHARED_LIBS + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/macros/Export.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/macros/Export.h new file mode 100644 index 0000000000000000000000000000000000000000..dfc4378c482c621ce05179900c719510e59ee8d0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/macros/Export.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/macros/Macros.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/macros/Macros.h new file mode 100644 index 0000000000000000000000000000000000000000..02fdbd4df99eaed11dfdc5dc190378156ea30177 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/macros/Macros.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/macros/cmake_macros.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/macros/cmake_macros.h new file mode 100644 index 0000000000000000000000000000000000000000..5d89f61f37a9db44fc7bbe5df20ce372e37dff4c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/macros/cmake_macros.h @@ -0,0 +1,10 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// This file exists for backwards compatibility and has been moved to +// torch/headeronly/macros/cmake_macros.h.in. No end user library should be +// including this file directly anyway (cuz they should be including +// Macros.h instead). +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/atomic.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/atomic.h new file mode 100644 index 0000000000000000000000000000000000000000..ea450c15caaed4be24cdc636ead2b79c26e09a6f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/atomic.h @@ -0,0 +1,289 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +namespace c10 { +namespace metal { + +// Atomic operations helper +template +struct AtomicType {}; +template +using AtomicType_t = typename AtomicType::type; + +template +static inline void atomic_binary_op_helper( + device ::metal::atomic* data, + long offset, + T value, + T (*op)(T, T)) { + auto ptr = data + offset; + auto old = ::metal::atomic_load_explicit(ptr, ::metal::memory_order_relaxed); + T val; + do { + val = op(old, value); + } while (!::metal::atomic_compare_exchange_weak_explicit( + ptr, + &old, + val, + ::metal::memory_order_relaxed, + ::metal::memory_order_relaxed)); +} + +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, float value) { + ::metal::atomic_fetch_add_explicit( + data + offset, value, ::metal::memory_order_relaxed); + } + static inline void atomic_binary_op( + device type* data, + long offset, + float value, + float (*op)(float, float)) { + atomic_binary_op_helper(data, offset, value, op); + } +}; + +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, int value) { + ::metal::atomic_fetch_add_explicit( + data + offset, value, ::metal::memory_order_relaxed); + } + static inline void atomic_binary_op( + device type* data, + long offset, + int value, + int (*op)(int, int)) { + atomic_binary_op_helper(data, offset, value, op); + } +}; + +// As of Metal3.2 atomic operations are not supported on half-precision floats, +// so they must be simulated Using atomic compare and exchange over 32-bit +// atomic type +template +static inline void atomic_add_helper( + device ::metal::atomic* data, + long offset, + T value) { + // atomic requires 4-byte alignment; fix up misaligned pointers + auto addr = reinterpret_cast(data); + auto misalign = (addr % alignof(::metal::atomic)) / sizeof(T); + data = reinterpret_cast*>( + reinterpret_cast(data) - misalign * sizeof(T)); + offset += misalign; + + constexpr auto elem_per_enum = sizeof(uint) / sizeof(T); + auto ptr = data + (offset / elem_per_enum); + auto old = ::metal::atomic_load_explicit(ptr, ::metal::memory_order_relaxed); + union { + uint i; + T t[elem_per_enum]; + } val; + do { + val.i = old; + val.t[offset & (elem_per_enum - 1)] += value; + } while (!::metal::atomic_compare_exchange_weak_explicit( + ptr, + &old, + val.i, + ::metal::memory_order_relaxed, + ::metal::memory_order_relaxed)); +} + +template +static inline void atomic_binary_op_helper( + device ::metal::atomic* data, + long offset, + T value, + T (*Op)(T, T)) { + // atomic requires 4-byte alignment; fix up misaligned pointers + auto addr = reinterpret_cast(data); + auto misalign = (addr % alignof(::metal::atomic)) / sizeof(T); + data = reinterpret_cast*>( + reinterpret_cast(data) - misalign * sizeof(T)); + offset += misalign; + + constexpr auto elem_per_enum = sizeof(uint) / sizeof(T); + auto ptr = data + (offset / elem_per_enum); + auto old = ::metal::atomic_load_explicit(ptr, ::metal::memory_order_relaxed); + union { + uint i; + T t[elem_per_enum]; + } val; + do { + val.i = old; + val.t[offset & (elem_per_enum - 1)] = + Op(val.t[offset & (elem_per_enum - 1)], value); + } while (!::metal::atomic_compare_exchange_weak_explicit( + ptr, + &old, + val.i, + ::metal::memory_order_relaxed, + ::metal::memory_order_relaxed)); +} + +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, half value) { + atomic_add_helper(data, offset, value); + } + static inline void atomic_binary_op( + device type* data, + long offset, + half value, + half (*op)(half, half)) { + atomic_binary_op_helper(data, offset, value, op); + } +}; + +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, short value) { + atomic_add_helper(data, offset, value); + } + static inline void atomic_binary_op( + device type* data, + long offset, + short value, + short (*op)(short, short)) { + atomic_binary_op_helper(data, offset, value, op); + } +}; + +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, char value) { + atomic_add_helper(data, offset, value); + } + static inline void atomic_binary_op( + device type* data, + long offset, + char value, + char (*op)(char, char)) { + atomic_binary_op_helper(data, offset, value, op); + } +}; + +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, char value) { + atomic_add_helper(data, offset, value); + } + static inline void atomic_binary_op( + device type* data, + long offset, + uchar value, + uchar (*op)(uchar, uchar)) { + atomic_binary_op_helper(data, offset, value, op); + } +}; + +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, bfloat value) { + atomic_add_helper(data, offset, value); + } + static inline void atomic_binary_op( + device type* data, + long offset, + bfloat value, + bfloat (*op)(bfloat, bfloat)) { + atomic_binary_op_helper(data, offset, value, op); + } +}; + +// Metal supports atomic_store_explicit for bools, but +// sizeof(::metal::atomic_bool) is 4 Therefore it could not be used to +// atomically modify unaligned memory, so fall back to compare and exchange +// trick As accumulation over booleans are just or operation, do nothing if +// value is false +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, bool value) { + if (!value) { + return; + } + auto ptr = data + (offset >> 2); + auto old = + ::metal::atomic_load_explicit(ptr, ::metal::memory_order_relaxed); + union { + uint i; + bool t[4]; + } val; + do { + val.i = old; + val.t[offset & 3] = true; + } while (!::metal::atomic_compare_exchange_weak_explicit( + ptr, + &old, + val.i, + ::metal::memory_order_relaxed, + ::metal::memory_order_relaxed)); + } +}; + +// ComplexHalf atomic op +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, half2 value) { + auto ptr = data + offset; + auto old = + ::metal::atomic_load_explicit(ptr, ::metal::memory_order_relaxed); + while (!::metal::atomic_compare_exchange_weak_explicit( + ptr, + &old, + as_type(as_type(old) + value), + ::metal::memory_order_relaxed, + ::metal::memory_order_relaxed)) + ; + } +}; + +// There are no atomic 64-bit add in Metal yet, but templates below implements a +// consistent add I.e. if multiple threads are modify the same 64-bit value, +// results stored at the address will eventually be equal to its original value +// plus sum of all operands +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, long value) { + const auto value_bits = as_type(value); + const uint low = static_cast(value_bits); + uint high = static_cast(value_bits >> 32); + auto ptr = data + (offset << 1); + auto old_low = + atomic_fetch_add_explicit(ptr, low, ::metal::memory_order_relaxed); + high += (old_low + low < old_low) ? 1 : 0; + atomic_fetch_add_explicit(ptr + 1, high, ::metal::memory_order_relaxed); + } +}; + +// ComplexFloat atomic op, which again is not really atomic, but eventually +// consistent +template <> +struct AtomicType { + using type = ::metal::atomic; + static inline void atomic_add(device type* data, long offset, float2 value) { + auto ptr = data + (offset << 1); + atomic_fetch_add_explicit(ptr + 0, value.x, ::metal::memory_order_relaxed); + atomic_fetch_add_explicit(ptr + 1, value.y, ::metal::memory_order_relaxed); + } +}; + +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/common.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/common.h new file mode 100644 index 0000000000000000000000000000000000000000..fe0a0ebed4212c56a537e3a45fcd81336dbf6194 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/common.h @@ -0,0 +1,53 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +// Set of global constants that could be shareable between CPU and Metal code + +#ifdef __METAL__ +#include +#define C10_METAL_CONSTEXPR constant constexpr +#else +#include +#define C10_METAL_CONSTEXPR constexpr +#endif + +#define C10_METAL_ALL_TYPES_FUNCTOR(_) \ + _(Byte, 0) \ + _(Char, 1) \ + _(Short, 2) \ + _(Int, 3) \ + _(Long, 4) \ + _(Half, 5) \ + _(Float, 6) \ + _(ComplexHalf, 8) \ + _(ComplexFloat, 9) \ + _(Bool, 11) \ + _(BFloat16, 15) \ + _(UInt16, 27) \ + _(UInt32, 28) \ + _(UInt64, 29) + +namespace c10 { +namespace metal { +C10_METAL_CONSTEXPR unsigned max_ndim = 16; +C10_METAL_CONSTEXPR unsigned simdgroup_size = 32; + +#ifdef __METAL__ +template +using array = ::metal::array; +#else +template +using array = std::array; +#endif + +enum class ScalarType { +#define _DEFINE_ENUM_VAL_(_v, _n) _v = _n, + C10_METAL_ALL_TYPES_FUNCTOR(_DEFINE_ENUM_VAL_) +#undef _DEFINE_ENUM_VAL_ +}; + +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/error.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/error.h new file mode 100644 index 0000000000000000000000000000000000000000..25786e69bb6d9c37d69ce603aed53c8cb04a4a10 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/error.h @@ -0,0 +1,116 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include + +namespace c10 { +namespace metal { +C10_METAL_CONSTEXPR unsigned error_message_count = 30; +struct ErrorMessage { + char file[128]; + char func[128]; + char message[250]; + unsigned int line; +}; + +struct ErrorMessages { +#ifdef __METAL__ + ::metal::atomic count; +#else + unsigned int count; +#endif + ErrorMessage msg[error_message_count]; +}; + +#ifdef __METAL__ +namespace detail { +static uint strncpy(device char* dst, constant const char* src, unsigned len) { + uint i = 0; + while (src[i] != 0 && i < len - 1) { + dst[i] = src[i]; + i++; + } + dst[i] = 0; + return i; +} + +inline uint print_arg( + device char* ptr, + unsigned len, + constant const char* arg) { + return strncpy(ptr, arg, len); +} + +// Returns number length as string in base10 +static inline uint base10_length(long num) { + uint rc = 1; + if (num < 0) { + num = -num; + rc += 1; + } + while (num > 9) { + num /= 10; + rc++; + } + return rc; +} + +// Converts signed integer to string +inline uint print_arg(device char* ptr, unsigned len, long arg) { + const auto arg_len = base10_length(arg); + if (arg_len >= len) + return 0; + if (arg < 0) { + ptr[0] = '-'; + arg = -arg; + } + uint idx = 1; + do { + ptr[arg_len - idx] = '0' + (arg % 10); + arg /= 10; + idx++; + } while (arg > 0); + ptr[arg_len] = 0; + return arg_len; +} + +template +inline void print_args(device char* ptr, unsigned len, T arg) { + print_arg(ptr, len, arg); +} + +template +inline void print_args(device char* ptr, unsigned len, T arg, Args... args) { + const auto rc = print_arg(ptr, len, arg); + print_args(ptr + rc, len - rc, args...); +} + +} // namespace detail + +template +static void report_error( + device ErrorMessages* msgs, + constant const char* file, + int line, + constant const char* func, + Args... args) { + const auto idx = + atomic_fetch_add_explicit(&msgs->count, 1, ::metal::memory_order_relaxed); + if (idx >= error_message_count) { + return; + } + device auto* msg = &msgs->msg[idx]; + detail::strncpy(msg->file, file, 128); + detail::strncpy(msg->func, func, 128); + detail::print_args(msg->message, 250, args...); + msg->line = line; +} + +#define TORCH_REPORT_ERROR(buf, ...) \ + ::c10::metal::report_error(buf, __FILE__, __LINE__, __func__, __VA_ARGS__) +#endif +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/expm1f.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/expm1f.h new file mode 100644 index 0000000000000000000000000000000000000000..18061b711232ddc8053f6672b23814fee5023926 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/expm1f.h @@ -0,0 +1,102 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Copy-and-pasted from: +// https://github.com/ml-explore/mlx/blob/99c33d011d63174f50cea37c3eede002958be6d3/mlx/backend/metal/kernels/expm1f.h + +#pragma once + +#include + +// Original license copied below: +// Copyright (c) 2015-2023 Norbert Juffa +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +namespace c10 { +namespace metal { + +/* Compute exponential base e minus 1. Maximum ulp error = 0.997458 + + i = rint(a/log(2)), f = a-i*log(2). Then expm1(a) = 2**i * (expm1(f)+1) - 1. + Compute r = expm1(f). Then expm1(a)= 2 * (0.5 * 2**i * r + 0.5 * 2**i - 0.5). + With t = 0.5*2**i, expm1(a) = 2*(r * t + t-0.5). However, for best accuracy, + when i == 1, expm1(a)= 2*(r + 0.5), and when i == 0, expm1(a) = r. + + NOTE: Scale factor b is only applied if i < 0 or i > 1 (should be power of 2) +*/ +inline float expm1f_scaled_unchecked(float a, float b) { + float f, j, r, s, t, u, v, x, y; + int i; + + // exp(a) = 2**i * exp(f); i = rintf (a / log(2)) + j = ::metal::fma(1.442695f, a, 12582912.f); // 0x1.715476p0, 0x1.8p23 + j = j - 12582912.0f; // 0x1.8p23 + i = (int)j; + f = ::metal::fma(j, -6.93145752e-1f, a); + + // approximate r = exp(f)-1 on interval [-log(2)/2, +log(2)/2] + s = f * f; + if (a == 0.0f) + s = a; // ensure -0 is passed through + // err = 0.997458 ulp1 = 11081805 + r = 1.97350979e-4f; // 0x1.9de000p-13 + r = ::metal::fma(r, f, 1.39309070e-3f); // 0x1.6d30bcp-10 + r = ::metal::fma(r, f, 8.33343994e-3f); // 0x1.1111f6p-7 + r = ::metal::fma(r, f, 4.16668020e-2f); // 0x1.55559ep-5 + r = ::metal::fma(r, f, 1.66666716e-1f); // 0x1.55555cp-3 + r = ::metal::fma(r, f, 4.99999970e-1f); // 0x1.fffffep-2 + u = (j == 1) ? (f + 0.5f) : f; + v = ::metal::fma(r, s, u); + s = 0.5f * b; + t = ::metal::ldexp(s, i); + y = t - s; + x = (t - y) - s; // double-float canonicalization of difference + r = ::metal::fma(v, t, x) + y; + r = r + r; + if (j == 0) + r = v; + if (j == 1) + r = v + v; + return r; +} + +/* Compute exponential base e minus 1. max ulp err = 0.99746 */ +inline float expm1f(float a) { + float r; + + r = expm1f_scaled_unchecked(a, 1.0f); + /* handle severe overflow and underflow */ + if (::metal::abs(a - 1.0f) > 88.0f) { + r = ::metal::pow(2, a); + r = ::metal::fma(r, r, -1.0f); + } + return r; +} + +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/igamma.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/igamma.h new file mode 100644 index 0000000000000000000000000000000000000000..4fb235e226ad27e7bb94b76a02172df86ce4c17f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/igamma.h @@ -0,0 +1,749 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +using namespace c10::metal; +using namespace metal; + +namespace c10 { +namespace metal { + +template +inline float log_gamma(const T); + +inline float expm1f(float a); + +template +float erfc(T x); + +} // namespace metal +} // namespace c10 + +namespace { + +template +inline float lgamma(const T a) { + return log_gamma(a); +} + +inline float expm1(float a) { + return expm1f(a); +} + +// NOTE: The following code was ported directly from the CUDA implementation in +// `aten/src/ATen/native/cuda/IGammaKernel.cu` + +/* + * This implementation of the regularized incomplete gamma functions and + * their helper functions are derived from the implementation of SciPy's + * gammainc, Cephes's igam and igamc, and Boost's Lanczos approximations. + * See NOTICE for the licenses. + */ +// regularized lower & upper incomplete gamma +template +scalar_t ratevl( + scalar_t x, + const scalar_t num[], + int64_t M, + const scalar_t denom[], + int64_t N) { + // evaluating rational function, i.e., the ratio of two polynomials + // the coefficients for numerator are given by `num` while coeffs for + // denumerator are given by `denom` + + using accscalar_t = opmath_t; + int64_t i, dir; + accscalar_t y, num_ans, denom_ans; + accscalar_t absx = ::fabs(x); + thread const accscalar_t* p; + + if (absx > 1) { + /* Evaluate as a polynomial in 1/x. */ + dir = -1; + p = num + M; + y = 1 / x; + } else { + dir = 1; + p = num; + y = x; + } + + /* Evaluate the numerator */ + num_ans = *p; + p += dir; + for (i = 1; i <= M; i++) { + num_ans = num_ans * y + *p; + p += dir; + } + /* Evaluate the denominator */ + if (absx > 1) { + p = denom + N; + } else { + p = denom; + } + + denom_ans = *p; + p += dir; + for (i = 1; i <= N; i++) { + denom_ans = denom_ans * y + *p; + p += dir; + } + if (absx > 1) { + i = N - M; + return ::pow(x, static_cast(i)) * num_ans / denom_ans; + } else { + return num_ans / denom_ans; + } +} + +template +scalar_t lanczos_sum_expg_scaled(scalar_t x) { + // lanczos approximation + using accscalar_t = opmath_t; + + const accscalar_t lanczos_sum_expg_scaled_num[13] = { + 0.006061842346248906525783753964555936883222, + 0.5098416655656676188125178644804694509993, + 19.51992788247617482847860966235652136208, + 449.9445569063168119446858607650988409623, + 6955.999602515376140356310115515198987526, + 75999.29304014542649875303443598909137092, + 601859.6171681098786670226533699352302507, + 3481712.15498064590882071018964774556468, + 14605578.08768506808414169982791359218571, + 43338889.32467613834773723740590533316085, + 86363131.28813859145546927288977868422342, + 103794043.1163445451906271053616070238554, + 56906521.91347156388090791033559122686859}; + const accscalar_t lanczos_sum_expg_scaled_denom[13] = { + 1., + 66., + 1925., + 32670., + 357423., + 2637558., + 13339535., + 45995730., + 105258076., + 150917976., + 120543840., + 39916800., + 0}; + return ratevl( + static_cast(x), + lanczos_sum_expg_scaled_num, + sizeof(lanczos_sum_expg_scaled_num) / + sizeof(lanczos_sum_expg_scaled_num[0]) - + 1, + lanczos_sum_expg_scaled_denom, + sizeof(lanczos_sum_expg_scaled_denom) / + sizeof(lanczos_sum_expg_scaled_denom[0]) - + 1); +} + +template +scalar_t _igam_helper_fac(scalar_t a, scalar_t x) { + // compute x^a * exp(-a) / gamma(a) + // corrected from (15) and (16) in [igam2] by replacing exp(x - a) with + // exp(a - x). + + using accscalar_t = opmath_t; + accscalar_t ax, fac, res, num, numfac; + const accscalar_t MAXLOG = 88.72283905206835; + const accscalar_t EXP1 = 2.718281828459045; + const accscalar_t lanczos_g = 6.024680040776729583740234375; + + if (::fabs(a - x) > 0.4 * ::fabs(a)) { + ax = a * ::log(x) - x - ::lgamma(a); + if (ax < -MAXLOG) { + return 0.0; + } + return ::exp(ax); + } + + fac = a + lanczos_g - 0.5; + res = ::sqrt(fac / EXP1) / lanczos_sum_expg_scaled(a); + + if ((a < 200) && (x < 200)) { + res *= ::exp(a - x) * ::pow(x / fac, a); + } else { + num = x - a - lanczos_g + 0.5; + numfac = num / fac; + res *= ::exp(a * (::log1p(numfac) - numfac) + x * (0.5 - lanczos_g) / fac); + } + return res; +} + +template +scalar_t _igam_helper_series(scalar_t a, scalar_t x) { + // Compute igam using DLMF 8.11.4. [igam1] + + using accscalar_t = opmath_t; + const accscalar_t MACHEP = 5.9604644775390625E-8; + const int MAXITER = 2000; + + int i; + accscalar_t ans, ax, c, r; + + ax = _igam_helper_fac(a, x); + if (ax == 0.0) { + return 0.0; + } + + /* power series */ + r = a; + c = 1.0; + ans = 1.0; + + for (i = 0; i < MAXITER; i++) { + r += 1.0; + c *= x / r; + ans += c; + if (c <= MACHEP * ans) { + break; + } + } + return (ans * ax / a); +} + +template +scalar_t _igamc_helper_series(scalar_t a, scalar_t x) { + // Compute igamc using DLMF 8.7.3 [igam1]. This is related to the series in + // _igam_helper_series but extra care is taken to avoid cancellation. + + using accscalar_t = opmath_t; + int n; + accscalar_t fac = 1; + accscalar_t sum = 0; + accscalar_t term, logx; + const int MAXITER = 2000; + const accscalar_t MACHEP = 5.9604644775390625E-8; + + for (n = 1; n < MAXITER; n++) { + fac *= -x / n; + term = fac / (a + n); + sum += term; + if (::fabs(term) <= MACHEP * ::fabs(sum)) { + break; + } + } + + logx = ::log(x); + term = -::expm1(a * logx - ::lgamma(1 + a)); + return term - ::exp(a * logx - ::lgamma(a)) * sum; +} + +template +scalar_t _igam_helper_asymptotic_series(scalar_t a, scalar_t x, bool igam) { + // Compute igam/igamc using DLMF 8.12.3/8.12.4 [igam1] + + using accscalar_t = opmath_t; + const accscalar_t d[25][25] = { + {-3.3333333333333333e-1, 8.3333333333333333e-2, + -1.4814814814814815e-2, 1.1574074074074074e-3, + 3.527336860670194e-4, -1.7875514403292181e-4, + 3.9192631785224378e-5, -2.1854485106799922e-6, + -1.85406221071516e-6, 8.296711340953086e-7, + -1.7665952736826079e-7, 6.7078535434014986e-9, + 1.0261809784240308e-8, -4.3820360184533532e-9, + 9.1476995822367902e-10, -2.551419399494625e-11, + -5.8307721325504251e-11, 2.4361948020667416e-11, + -5.0276692801141756e-12, 1.1004392031956135e-13, + 3.3717632624009854e-13, -1.3923887224181621e-13, + 2.8534893807047443e-14, -5.1391118342425726e-16, + -1.9752288294349443e-15}, + {-1.8518518518518519e-3, -3.4722222222222222e-3, 2.6455026455026455e-3, + -9.9022633744855967e-4, 2.0576131687242798e-4, -4.0187757201646091e-7, + -1.8098550334489978e-5, 7.6491609160811101e-6, -1.6120900894563446e-6, + 4.6471278028074343e-9, 1.378633446915721e-7, -5.752545603517705e-8, + 1.1951628599778147e-8, -1.7543241719747648e-11, -1.0091543710600413e-9, + 4.1627929918425826e-10, -8.5639070264929806e-11, 6.0672151016047586e-14, + 7.1624989648114854e-12, -2.9331866437714371e-12, 5.9966963656836887e-13, + -2.1671786527323314e-16, -4.9783399723692616e-14, 2.0291628823713425e-14, + -4.13125571381061e-15}, + {4.1335978835978836e-3, -2.6813271604938272e-3, 7.7160493827160494e-4, + 2.0093878600823045e-6, -1.0736653226365161e-4, 5.2923448829120125e-5, + -1.2760635188618728e-5, 3.4235787340961381e-8, 1.3721957309062933e-6, + -6.298992138380055e-7, 1.4280614206064242e-7, -2.0477098421990866e-10, + -1.4092529910867521e-8, 6.228974084922022e-9, -1.3670488396617113e-9, + 9.4283561590146782e-13, 1.2872252400089318e-10, -5.5645956134363321e-11, + 1.1975935546366981e-11, -4.1689782251838635e-15, -1.0940640427884594e-12, + 4.6622399463901357e-13, -9.905105763906906e-14, 1.8931876768373515e-17, + 8.8592218725911273e-15}, + {6.4943415637860082e-4, 2.2947209362139918e-4, -4.6918949439525571e-4, + 2.6772063206283885e-4, -7.5618016718839764e-5, -2.3965051138672967e-7, + 1.1082654115347302e-5, -5.6749528269915966e-6, 1.4230900732435884e-6, + -2.7861080291528142e-11, -1.6958404091930277e-7, 8.0994649053880824e-8, + -1.9111168485973654e-8, 2.3928620439808118e-12, 2.0620131815488798e-9, + -9.4604966618551322e-10, 2.1541049775774908e-10, -1.388823336813903e-14, + -2.1894761681963939e-11, 9.7909989511716851e-12, -2.1782191880180962e-12, + 6.2088195734079014e-17, 2.126978363279737e-13, -9.3446887915174333e-14, + 2.0453671226782849e-14}, + {-8.618882909167117e-4, 7.8403922172006663e-4, + -2.9907248030319018e-4, -1.4638452578843418e-6, + 6.6414982154651222e-5, -3.9683650471794347e-5, + 1.1375726970678419e-5, 2.5074972262375328e-10, + -1.6954149536558306e-6, 8.9075075322053097e-7, + -2.2929348340008049e-7, 2.956794137544049e-11, + 2.8865829742708784e-8, -1.4189739437803219e-8, + 3.4463580499464897e-9, -2.3024517174528067e-13, + -3.9409233028046405e-10, 1.8602338968504502e-10, + -4.356323005056618e-11, 1.2786001016296231e-15, + 4.6792750266579195e-12, -2.1492464706134829e-12, + 4.9088156148096522e-13, -6.3385914848915603e-18, + -5.0453320690800944e-14}, + {-3.3679855336635815e-4, -6.9728137583658578e-5, 2.7727532449593921e-4, + -1.9932570516188848e-4, 6.7977804779372078e-5, 1.419062920643967e-7, + -1.3594048189768693e-5, 8.0184702563342015e-6, -2.2914811765080952e-6, + -3.252473551298454e-10, 3.4652846491085265e-7, -1.8447187191171343e-7, + 4.8240967037894181e-8, -1.7989466721743515e-14, -6.3061945000135234e-9, + 3.1624176287745679e-9, -7.8409242536974293e-10, 5.1926791652540407e-15, + 9.3589442423067836e-11, -4.5134262161632782e-11, 1.0799129993116827e-11, + -3.661886712685252e-17, -1.210902069055155e-12, 5.6807435849905643e-13, + -1.3249659916340829e-13}, + {5.3130793646399222e-4, -5.9216643735369388e-4, 2.7087820967180448e-4, + 7.9023532326603279e-7, -8.1539693675619688e-5, 5.6116827531062497e-5, + -1.8329116582843376e-5, -3.0796134506033048e-9, 3.4651553688036091e-6, + -2.0291327396058604e-6, 5.7887928631490037e-7, 2.338630673826657e-13, + -8.8286007463304835e-8, 4.7435958880408128e-8, -1.2545415020710382e-8, + 8.6496488580102925e-14, 1.6846058979264063e-9, -8.5754928235775947e-10, + 2.1598224929232125e-10, -7.6132305204761539e-16, -2.6639822008536144e-11, + 1.3065700536611057e-11, -3.1799163902367977e-12, 4.7109761213674315e-18, + 3.6902800842763467e-13}, + {3.4436760689237767e-4, 5.1717909082605922e-5, + -3.3493161081142236e-4, 2.812695154763237e-4, + -1.0976582244684731e-4, -1.2741009095484485e-7, + 2.7744451511563644e-5, -1.8263488805711333e-5, + 5.7876949497350524e-6, 4.9387589339362704e-10, + -1.0595367014026043e-6, 6.1667143761104075e-7, + -1.7562973359060462e-7, -1.2974473287015439e-12, + 2.695423606288966e-8, -1.4578352908731271e-8, + 3.887645959386175e-9, -3.8810022510194121e-17, + -5.3279941738772867e-10, 2.7437977643314845e-10, + -6.9957960920705679e-11, 2.5899863874868481e-17, + 8.8566890996696381e-12, -4.403168815871311e-12, + 1.0865561947091654e-12}, + {-6.5262391859530942e-4, 8.3949872067208728e-4, -4.3829709854172101e-4, + -6.969091458420552e-7, 1.6644846642067548e-4, -1.2783517679769219e-4, + 4.6299532636913043e-5, 4.5579098679227077e-9, -1.0595271125805195e-5, + 6.7833429048651666e-6, -2.1075476666258804e-6, -1.7213731432817145e-11, + 3.7735877416110979e-7, -2.1867506700122867e-7, 6.2202288040189269e-8, + 6.5977038267330006e-16, -9.5903864974256858e-9, 5.2132144922808078e-9, + -1.3991589583935709e-9, 5.382058999060575e-16, 1.9484714275467745e-10, + -1.0127287556389682e-10, 2.6077347197254926e-11, -5.0904186999932993e-18, + -3.3721464474854592e-12}, + {-5.9676129019274625e-4, -7.2048954160200106e-5, + 6.7823088376673284e-4, -6.4014752602627585e-4, + 2.7750107634328704e-4, 1.8197008380465151e-7, + -8.4795071170685032e-5, 6.105192082501531e-5, + -2.1073920183404862e-5, -8.8585890141255994e-10, + 4.5284535953805377e-6, -2.8427815022504408e-6, + 8.7082341778646412e-7, 3.6886101871706965e-12, + -1.5344695190702061e-7, 8.862466778790695e-8, + -2.5184812301826817e-8, -1.0225912098215092e-14, + 3.8969470758154777e-9, -2.1267304792235635e-9, + 5.7370135528051385e-10, -1.887749850169741e-19, + -8.0931538694657866e-11, 4.2382723283449199e-11, + -1.1002224534207726e-11}, + {1.3324454494800656e-3, -1.9144384985654775e-3, 1.1089369134596637e-3, + 9.932404122642299e-7, -5.0874501293093199e-4, 4.2735056665392884e-4, + -1.6858853767910799e-4, -8.1301893922784998e-9, 4.5284402370562147e-5, + -3.127053674781734e-5, 1.044986828530338e-5, 4.8435226265680926e-11, + -2.1482565873456258e-6, 1.329369701097492e-6, -4.0295693092101029e-7, + -1.7567877666323291e-13, 7.0145043163668257e-8, -4.040787734999483e-8, + 1.1474026743371963e-8, 3.9642746853563325e-18, -1.7804938269892714e-9, + 9.7480262548731646e-10, -2.6405338676507616e-10, 5.794875163403742e-18, + 3.7647749553543836e-11}, + {1.579727660730835e-3, 1.6251626278391582e-4, -2.0633421035543276e-3, + 2.1389686185689098e-3, -1.0108559391263003e-3, -3.9912705529919201e-7, + 3.6235025084764691e-4, -2.8143901463712154e-4, 1.0449513336495887e-4, + 2.1211418491830297e-9, -2.5779417251947842e-5, 1.7281818956040463e-5, + -5.6413773872904282e-6, -1.1024320105776174e-11, 1.1223224418895175e-6, + -6.8693396379526735e-7, 2.0653236975414887e-7, 4.6714772409838506e-14, + -3.5609886164949055e-8, 2.0470855345905963e-8, -5.8091738633283358e-9, + -1.332821287582869e-16, 9.0354604391335133e-10, -4.9598782517330834e-10, + 1.3481607129399749e-10}, + {-4.0725121195140166e-3, 6.4033628338080698e-3, -4.0410161081676618e-3, + -2.183732802866233e-6, 2.1740441801254639e-3, -1.9700440518418892e-3, + 8.3595469747962458e-4, 1.9445447567109655e-8, -2.5779387120421696e-4, + 1.9009987368139304e-4, -6.7696499937438965e-5, -1.4440629666426572e-10, + 1.5712512518742269e-5, -1.0304008744776893e-5, 3.304517767401387e-6, + 7.9829760242325709e-13, -6.4097794149313004e-7, 3.8894624761300056e-7, + -1.1618347644948869e-7, -2.816808630596451e-15, 1.9878012911297093e-8, + -1.1407719956357511e-8, 3.2355857064185555e-9, 4.1759468293455945e-20, + -5.0423112718105824e-10}, + {-5.9475779383993003e-3, -5.4016476789260452e-4, 8.7910413550767898e-3, + -9.8576315587856125e-3, 5.0134695031021538e-3, 1.2807521786221875e-6, + -2.0626019342754683e-3, 1.7109128573523058e-3, -6.7695312714133799e-4, + -6.9011545676562133e-9, 1.8855128143995902e-4, -1.3395215663491969e-4, + 4.6263183033528039e-5, 4.0034230613321351e-11, -1.0255652921494033e-5, + 6.612086372797651e-6, -2.0913022027253008e-6, -2.0951775649603837e-13, + 3.9756029041993247e-7, -2.3956211978815887e-7, 7.1182883382145864e-8, + 8.925574873053455e-16, -1.2101547235064676e-8, 6.9350618248334386e-9, + -1.9661464453856102e-9}, + {1.7402027787522711e-2, -2.9527880945699121e-2, 2.0045875571402799e-2, + 7.0289515966903407e-6, -1.2375421071343148e-2, 1.1976293444235254e-2, + -5.4156038466518525e-3, -6.3290893396418616e-8, 1.8855118129005065e-3, + -1.473473274825001e-3, 5.5515810097708387e-4, 5.2406834412550662e-10, + -1.4357913535784836e-4, 9.9181293224943297e-5, -3.3460834749478311e-5, + -3.5755837291098993e-12, 7.1560851960630076e-6, -4.5516802628155526e-6, + 1.4236576649271475e-6, 1.8803149082089664e-14, -2.6623403898929211e-7, + 1.5950642189595716e-7, -4.7187514673841102e-8, -6.5107872958755177e-17, + 7.9795091026746235e-9}, + {3.0249124160905891e-2, 2.4817436002649977e-3, -4.9939134373457022e-2, + 5.9915643009307869e-2, -3.2483207601623391e-2, -5.7212968652103441e-6, + 1.5085251778569354e-2, -1.3261324005088445e-2, 5.5515262632426148e-3, + 3.0263182257030016e-8, -1.7229548406756723e-3, 1.2893570099929637e-3, + -4.6845138348319876e-4, -1.830259937893045e-10, 1.1449739014822654e-4, + -7.7378565221244477e-5, 2.5625836246985201e-5, 1.0766165333192814e-12, + -5.3246809282422621e-6, 3.349634863064464e-6, -1.0381253128684018e-6, + -5.608909920621128e-15, 1.9150821930676591e-7, -1.1418365800203486e-7, + 3.3654425209171788e-8}, + {-9.9051020880159045e-2, 1.7954011706123486e-1, -1.2989606383463778e-1, + -3.1478872752284357e-5, 9.0510635276848131e-2, -9.2828824411184397e-2, + 4.4412112839877808e-2, 2.7779236316835888e-7, -1.7229543805449697e-2, + 1.4182925050891573e-2, -5.6214161633747336e-3, -2.39598509186381e-9, + 1.6029634366079908e-3, -1.1606784674435773e-3, 4.1001337768153873e-4, + 1.8365800754090661e-11, -9.5844256563655903e-5, 6.3643062337764708e-5, + -2.076250624489065e-5, -1.1806020912804483e-13, 4.2131808239120649e-6, + -2.6262241337012467e-6, 8.0770620494930662e-7, 6.0125912123632725e-16, + -1.4729737374018841e-7}, + {-1.9994542198219728e-1, -1.5056113040026424e-2, 3.6470239469348489e-1, + -4.6435192311733545e-1, 2.6640934719197893e-1, 3.4038266027147191e-5, + -1.3784338709329624e-1, 1.276467178337056e-1, -5.6213828755200985e-2, + -1.753150885483011e-7, 1.9235592956768113e-2, -1.5088821281095315e-2, + 5.7401854451350123e-3, 1.0622382710310225e-9, -1.5335082692563998e-3, + 1.0819320643228214e-3, -3.7372510193945659e-4, -6.6170909729031985e-12, + 8.4263617380909628e-5, -5.5150706827483479e-5, 1.7769536448348069e-5, + 3.8827923210205533e-14, -3.53513697488768e-6, 2.1865832130045269e-6, + -6.6812849447625594e-7}, + {7.2438608504029431e-1, -1.3918010932653375, 1.0654143352413968, + 1.876173868950258e-4, -8.2705501176152696e-1, 8.9352433347828414e-1, + -4.4971003995291339e-1, -1.6107401567546652e-6, 1.9235590165271091e-1, + -1.6597702160042609e-1, 6.8882222681814333e-2, 1.3910091724608687e-8, + -2.146911561508663e-2, 1.6228980898865892e-2, -5.9796016172584256e-3, + -1.1287469112826745e-10, 1.5167451119784857e-3, -1.0478634293553899e-3, + 3.5539072889126421e-4, 8.1704322111801517e-13, -7.7773013442452395e-5, + 5.0291413897007722e-5, -1.6035083867000518e-5, 1.2469354315487605e-14, + 3.1369106244517615e-6}, + {1.6668949727276811, 1.165462765994632e-1, -3.3288393225018906, + 4.4692325482864037, -2.6977693045875807, -2.600667859891061e-4, + 1.5389017615694539, -1.4937962361134612, 6.8881964633233148e-1, + 1.3077482004552385e-6, -2.5762963325596288e-1, 2.1097676102125449e-1, + -8.3714408359219882e-2, -7.7920428881354753e-9, 2.4267923064833599e-2, + -1.7813678334552311e-2, 6.3970330388900056e-3, 4.9430807090480523e-11, + -1.5554602758465635e-3, 1.0561196919903214e-3, -3.5277184460472902e-4, + 9.3002334645022459e-14, 7.5285855026557172e-5, -4.8186515569156351e-5, + 1.5227271505597605e-5}, + {-6.6188298861372935, 1.3397985455142589e+1, -1.0789350606845146e+1, + -1.4352254537875018e-3, 9.2333694596189809, -1.0456552819547769e+1, + 5.5105526029033471, 1.2024439690716742e-5, -2.5762961164755816, + 2.3207442745387179, -1.0045728797216284, -1.0207833290021914e-7, + 3.3975092171169466e-1, -2.6720517450757468e-1, 1.0235252851562706e-1, + 8.4329730484871625e-10, -2.7998284958442595e-2, 2.0066274144976813e-2, + -7.0554368915086242e-3, 1.9402238183698188e-12, 1.6562888105449611e-3, + -1.1082898580743683e-3, 3.654545161310169e-4, -5.1290032026971794e-11, + -7.6340103696869031e-5}, + {-1.7112706061976095e+1, -1.1208044642899116, 3.7131966511885444e+1, + -5.2298271025348962e+1, 3.3058589696624618e+1, 2.4791298976200222e-3, + -2.061089403411526e+1, 2.088672775145582e+1, -1.0045703956517752e+1, + -1.2238783449063012e-5, 4.0770134274221141, -3.473667358470195, + 1.4329352617312006, 7.1359914411879712e-8, -4.4797257159115612e-1, + 3.4112666080644461e-1, -1.2699786326594923e-1, -2.8953677269081528e-10, + 3.3125776278259863e-2, -2.3274087021036101e-2, 8.0399993503648882e-3, + -1.177805216235265e-9, -1.8321624891071668e-3, 1.2108282933588665e-3, + -3.9479941246822517e-4}, + {7.389033153567425e+1, -1.5680141270402273e+2, 1.322177542759164e+2, + 1.3692876877324546e-2, -1.2366496885920151e+2, 1.4620689391062729e+2, + -8.0365587724865346e+1, -1.1259851148881298e-4, 4.0770132196179938e+1, + -3.8210340013273034e+1, 1.719522294277362e+1, 9.3519707955168356e-7, + -6.2716159907747034, 5.1168999071852637, -2.0319658112299095, + -4.9507215582761543e-9, 5.9626397294332597e-1, -4.4220765337238094e-1, + 1.6079998700166273e-1, -2.4733786203223402e-8, -4.0307574759979762e-2, + 2.7849050747097869e-2, -9.4751858992054221e-3, 6.419922235909132e-6, + 2.1250180774699461e-3}, + {2.1216837098382522e+2, 1.3107863022633868e+1, -4.9698285932871748e+2, + 7.3121595266969204e+2, -4.8213821720890847e+2, -2.8817248692894889e-2, + 3.2616720302947102e+2, -3.4389340280087117e+2, 1.7195193870816232e+2, + 1.4038077378096158e-4, -7.52594195897599e+1, 6.651969984520934e+1, + -2.8447519748152462e+1, -7.613702615875391e-7, 9.5402237105304373, + -7.5175301113311376, 2.8943997568871961, -4.6612194999538201e-7, + -8.0615149598794088e-1, 5.8483006570631029e-1, -2.0845408972964956e-1, + 1.4765818959305817e-4, 5.1000433863753019e-2, -3.3066252141883665e-2, + 1.5109265210467774e-2}, + {-9.8959643098322368e+2, 2.1925555360905233e+3, -1.9283586782723356e+3, + -1.5925738122215253e-1, 1.9569985945919857e+3, -2.4072514765081556e+3, + 1.3756149959336496e+3, 1.2920735237496668e-3, -7.525941715948055e+2, + 7.3171668742208716e+2, -3.4137023466220065e+2, -9.9857390260608043e-6, + 1.3356313181291573e+2, -1.1276295161252794e+2, 4.6310396098204458e+1, + -7.9237387133614756e-6, -1.4510726927018646e+1, 1.1111771248100563e+1, + -4.1690817945270892, 3.1008219800117808e-3, 1.1220095449981468, + -7.6052379926149916e-1, 3.6262236505085254e-1, 2.216867741940747e-1, + 4.8683443692930507e-1}}; + + int k, n, sgn; + int maxpow = 0; + const accscalar_t MACHEP = 5.9604644775390625E-8; + accscalar_t lambda = x / a; + accscalar_t sigma = (x - a) / a; + accscalar_t eta, res, ck, ckterm, term, absterm; + accscalar_t absoldterm = INFINITY; + accscalar_t etapow[25] = {1}; + accscalar_t sum = 0; + accscalar_t afac = 1; + + if (igam) { + sgn = -1; + } else { + sgn = 1; + } + + if (lambda > 1) { + eta = ::sqrt(-2 * (::log1p(sigma) - sigma)); + } else if (lambda < 1) { + eta = -::sqrt(-2 * (::log1p(sigma) - sigma)); + } else { + eta = 0; + } + res = 0.5 * ::erfc(sgn * eta * ::sqrt(a / 2)); + + for (k = 0; k < 25; k++) { + ck = d[k][0]; + for (n = 1; n < 25; n++) { + if (n > maxpow) { + etapow[n] = eta * etapow[n - 1]; + maxpow += 1; + } + ckterm = d[k][n] * etapow[n]; + ck += ckterm; + if (::fabs(ckterm) < MACHEP * ::fabs(ck)) { + break; + } + } + term = ck * afac; + absterm = ::fabs(term); + if (absterm > absoldterm) { + break; + } + sum += term; + if (absterm < MACHEP * ::fabs(sum)) { + break; + } + absoldterm = absterm; + afac /= a; + } + res += sgn * ::exp(-0.5 * a * eta * eta) * sum / ::sqrt(2 * 3.1415926535 * a); + + return res; +} + +template +scalar_t _igamc_helper_continued_fraction(scalar_t a, scalar_t x) { + // Compute igamc using DLMF 8.9.2. [igam1] + + using accscalar_t = opmath_t; + int i; + accscalar_t ans, ax, c, yc, r, t, y, z; + accscalar_t pk, pkm1, pkm2, qk, qkm1, qkm2; + const int MAXITER = 2000; + const accscalar_t MACHEP = 5.9604644775390625E-8; + const accscalar_t BIG = 16777216.; + const accscalar_t BIGINV = 5.9604644775390625E-8; + + ax = _igam_helper_fac(a, x); + if (ax == 0.0) { + return 0.0; + } + + /* continued fraction */ + y = 1.0 - a; + z = x + y + 1.0; + c = 0.0; + pkm2 = 1.0; + qkm2 = x; + pkm1 = x + 1.0; + qkm1 = z * x; + ans = pkm1 / qkm1; + + for (i = 0; i < MAXITER; i++) { + c += 1.0; + y += 1.0; + z += 2.0; + yc = y * c; + pk = pkm1 * z - pkm2 * yc; + qk = qkm1 * z - qkm2 * yc; + if (qk != 0) { + r = pk / qk; + t = ::fabs((ans - r) / r); + ans = r; + } else { + t = 1.0; + } + pkm2 = pkm1; + pkm1 = pk; + qkm2 = qkm1; + qkm1 = qk; + if (::fabs(pk) > BIG) { + pkm2 *= BIGINV; + pkm1 *= BIGINV; + qkm2 *= BIGINV; + qkm1 *= BIGINV; + } + if (t <= MACHEP) { + break; + } + } + return ans * ax; +} + +template +scalar_t calc_igammac(scalar_t a, scalar_t x) { + /* the calculation of the regularized upper incomplete gamma function + * is done differently based on the values of a and x: + * - if x and/or a is at the boundary of defined region, then assign the + * result at the boundary + * - if a is large and a ~ x, then using Uniform Asymptotic Expansions for + * Large Parameter (see DLMF 8.12.4 [igam1]) + * - if x > 1.1 and x < a, using the subtraction from the regularized lower + * incomplete gamma + * - otherwise, calculate the series from [igam2] eq (5) + */ + + using accscalar_t = opmath_t; + accscalar_t absxma_a; + + const accscalar_t SMALL = 20.0; + const accscalar_t LARGE = 200.0; + const accscalar_t SMALLRATIO = 0.3; + const accscalar_t LARGERATIO = 4.5; + + if ((x < 0) || (a < 0)) { + // out of defined-region of the function + return NAN; + } else if (a == 0) { + if (x > 0) { + return 0.0; + } else { + return NAN; + } + } else if (x == 0) { + return 1.0; + } else if (isinf(a)) { + if (isinf(x)) { + return NAN; + } + return 1.0; + } else if (isinf(x)) { + return 0.0; + } + + absxma_a = ::fabs(x - a) / a; + if ((a > SMALL) && (a < LARGE) && (absxma_a < SMALLRATIO)) { + return _igam_helper_asymptotic_series(a, x, 0); + } else if ((a > LARGE) && (absxma_a < LARGERATIO / ::sqrt(a))) { + return _igam_helper_asymptotic_series(a, x, 0); + } + + if (x > 1.1) { + if (x < a) { + return 1.0 - _igam_helper_series(a, x); + } else { + return _igamc_helper_continued_fraction(a, x); + } + } else if (x <= 0.5) { + if (-0.4 / ::log(x) < a) { + return 1.0 - _igam_helper_series(a, x); + } else { + return _igamc_helper_series(a, x); + } + } else { + if (x * 1.1 < a) { + return 1.0 - _igam_helper_series(a, x); + } else { + return _igamc_helper_series(a, x); + } + } +} + +template +scalar_t calc_igamma(scalar_t a, scalar_t x) { + /* the calculation of the regularized lower incomplete gamma function + * is done differently based on the values of a and x: + * - if x and/or a is at the boundary of defined region, then assign the + * result at the boundary + * - if a is large and a ~ x, then using Uniform Asymptotic Expansions for + * Large Parameter (see DLMF 8.12.3 [igam1]) + * - if x > 1 and x > a, using the subtraction from the regularized upper + * incomplete gamma + * - otherwise, calculate the series from [igam2] eq (4) + */ + + using accscalar_t = opmath_t; + accscalar_t absxma_a; + const accscalar_t SMALL = 20.0; + const accscalar_t LARGE = 200.0; + const accscalar_t SMALLRATIO = 0.3; + const accscalar_t LARGERATIO = 4.5; + + // boundary values following SciPy + if ((x < 0) || (a < 0)) { + // out of defined-region of the function + return NAN; + } else if (a == 0) { + if (x > 0) { + return 1.0; + } else { + return NAN; + } + } else if (x == 0) { + return 0.0; // zero integration limit + } else if (isinf(a)) { + if (isinf(x)) { + return NAN; + } + return 0.0; + } else if (isinf(x)) { + return 1.0; + } + + /* Asymptotic regime where a ~ x. */ + absxma_a = ::fabs(x - a) / a; + if ((a > SMALL) && (a < LARGE) && (absxma_a < SMALLRATIO)) { + return _igam_helper_asymptotic_series(a, x, 1); + } else if ((a > LARGE) && (absxma_a < LARGERATIO / ::sqrt(a))) { + return _igam_helper_asymptotic_series(a, x, 1); + } + + if ((x > 1.0) && (x > a)) { + return 1.0 - calc_igammac(a, x); + } + + return _igam_helper_series(a, x); +} + +} // namespace + +// end of regularized lower & upper incomplete gamma + +namespace c10 { +namespace metal { + +template +inline T igamma(T a, T b) { + return calc_igamma(a, b); +} + +template +inline T igammac(T a, T b) { + return calc_igammac(a, b); +} + +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/indexing.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/indexing.h new file mode 100644 index 0000000000000000000000000000000000000000..bf18bfd5f5fb1f784b1f74163d8db0b1e485c6d0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/indexing.h @@ -0,0 +1,1085 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Metal indexing primitives +#pragma once +#include +#include +#include + +namespace c10 { +namespace metal { + +// Given coordinates and strides, calculates offset from the start of the +// tensors +template +inline T offset_from_coord( + thread T idx[max_ndim], + constant long* strides, + uint ndim) { + T rc = 0; + for (uint i = 0; i < ndim; ++i) { + rc += idx[i] * T(strides[i]); + } + return rc; +} + +// Given thread index calculates position in the ndim tensor +template +inline void pos_from_thread_index( + T idx, + thread T pos[max_ndim], + constant long* sizes, + uint ndim) { + for (uint i = 0; i < ndim; ++i) { + pos[i] = idx % T(sizes[i]); + idx /= T(sizes[i]); + } +} + +inline long offset_from_thread_index( + long idx, + constant long* sizes, + constant long* strides, + uint ndim) { + long pos[max_ndim]; + pos_from_thread_index(idx, pos, sizes, ndim); + return offset_from_coord(pos, strides, ndim); +} + +template +kernel void unary_dense( + device result_of* output [[buffer(0)]], + constant T* input [[buffer(1)]], + uint index [[thread_position_in_grid]]) { + F f; + output[index] = f(input[index]); +} + +template +kernel void unary_dense_vec4( + device result_of* output [[buffer(0)]], + constant T* input [[buffer(1)]], + constant uint& numel [[buffer(2)]], + uint index [[thread_position_in_grid]]) { + F f; + uint base = index * 4; + if (base + 4 <= numel) { + using ::metal::vec; + vec val = *(constant vec*)(input + base); + *(device vec, 4>*)(output + base) = { + f(val.x), f(val.y), f(val.z), f(val.w)}; + } else { + for (uint i = base; i < numel; i++) + output[i] = f(input[i]); + } +} + +template +kernel void unary_strided( + device result_of* output [[buffer(0)]], + constant T* input [[buffer(1)]], + constant long* sizes [[buffer(2)]], + constant long* input_strides [[buffer(3)]], + constant long* output_strides [[buffer(4)]], + constant uint& ndim [[buffer(5)]], + uint index [[thread_position_in_grid]]) { + F f; + int pos[max_ndim]; + pos_from_thread_index(int(index), pos, sizes, ndim); + const auto input_offs = offset_from_coord(pos, input_strides, ndim); + const auto output_offs = offset_from_coord(pos, output_strides, ndim); + output[output_offs] = f(input[input_offs]); +} + +#define REGISTER_UNARY_OP(NAME, DTYPE0, DTYPE1) \ + static_assert( \ + ::metal:: \ + is_same_v>, \ + "Output dtype mismatch for unary op " #NAME " and input " #DTYPE0); \ + template [[host_name(#NAME "_dense_" #DTYPE1 "_" #DTYPE0)]] kernel void :: \ + c10::metal::unary_dense( \ + device ::c10::metal::result_of * output, \ + constant DTYPE0 * input, \ + uint index); \ + template [[host_name(#NAME "_strided_" #DTYPE1 "_" #DTYPE0)]] kernel void :: \ + c10::metal::unary_strided( \ + device ::c10::metal::result_of * output, \ + constant DTYPE0 * input, \ + constant long* sizes, \ + constant long* input_strides, \ + constant long* output_strides, \ + constant uint& ndim, \ + uint index) + +#define REGISTER_UNARY_VEC4_OP(NAME, DTYPE0, DTYPE1) \ + static_assert( \ + ::metal:: \ + is_same_v>, \ + "Output dtype mismatch for unary op " #NAME " and input " #DTYPE0); \ + template [[host_name(#NAME "_dense_vec4_" #DTYPE1 "_" #DTYPE0)]] \ + kernel void ::c10::metal::unary_dense_vec4( \ + device ::c10::metal::result_of * output, \ + constant DTYPE0 * input, \ + constant uint & numel, \ + uint index) + +#define DEFINE_UNARY_FLOATING_FUNCTOR(NAME) \ + struct NAME##_functor { \ + template \ + inline ::metal::enable_if_t<::metal::is_floating_point_v, T> operator()( \ + const T x) { \ + return T(NAME(x)); \ + } \ + template \ + inline ::metal::enable_if_t<::metal::is_integral_v, float> operator()( \ + const T x) { \ + return NAME(static_cast(x)); \ + } \ + } + +template +kernel void unary_alpha_dense( + device result_of* output [[buffer(0)]], + constant T* input [[buffer(1)]], + constant T2& alpha [[buffer(2)]], + uint index [[thread_position_in_grid]]) { + F f; + output[index] = f(input[index], alpha); +} + +template +kernel void unary_alpha_strided( + device result_of* output [[buffer(0)]], + constant T* input [[buffer(1)]], + constant long* sizes [[buffer(2)]], + constant long* input_strides [[buffer(3)]], + constant long* output_strides [[buffer(4)]], + constant uint& ndim [[buffer(5)]], + constant T2& alpha [[buffer(6)]], + uint index [[thread_position_in_grid]]) { + F f; + int pos[max_ndim]; + pos_from_thread_index(int(index), pos, sizes, ndim); + const auto input_offs = offset_from_coord(pos, input_strides, ndim); + const auto output_offs = offset_from_coord(pos, output_strides, ndim); + output[output_offs] = f(input[input_offs], alpha); +} + +#define REGISTER_UNARY_ALPHA_OP(NAME, DTYPEI, DTYPEA, DTYPEO) \ + static_assert( \ + ::metal::is_same_v< \ + DTYPEO, \ + ::c10::metal::result_of>, \ + "Output dtype mismatch for unary op " #NAME " and input " #DTYPEI); \ + template [[host_name(#NAME "_dense_" #DTYPEO "_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + unary_alpha_dense( \ + device ::c10::metal::result_of * \ + output, \ + constant DTYPEI * input, \ + constant DTYPEA & alpha, \ + uint index); \ + template [[host_name(#NAME "_strided_" #DTYPEO "_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + unary_alpha_strided( \ + device ::c10::metal::result_of * \ + output, \ + constant DTYPEI * input, \ + constant long* sizes, \ + constant long* input_strides, \ + constant long* output_strides, \ + constant uint& ndim, \ + constant DTYPEA& alpha, \ + uint index) + +template +inline T val_at_offs(constant void* ptr, long offs) { + return *reinterpret_cast( + static_cast(ptr) + offs); +} + +// Value at offset with dynamic cast from provided type +template +inline T val_at_offs(device void* ptr, long offs) { + return *reinterpret_cast(static_cast(ptr) + offs); +} + +template +inline T val_at_offs(P ptr, long offs, ScalarType type) { + switch (type) { + case ScalarType::Bool: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::Byte: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::Char: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::Short: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::UInt16: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::Int: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::UInt32: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::Long: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::UInt64: + return cast_to(val_at_offs(ptr, offs)); + // Floats + case ScalarType::Float: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::Half: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::BFloat16: + return cast_to(val_at_offs(ptr, offs)); + // Complex + case ScalarType::ComplexHalf: + return cast_to(val_at_offs(ptr, offs)); + case ScalarType::ComplexFloat: + return cast_to(val_at_offs(ptr, offs)); + } +} + +template +inline device T& ref_at_offs(device void* ptr, long offs) { + return *reinterpret_cast(static_cast(ptr) + offs); +} + +// Binary elementwise ops kernels +// Right now there are 4 flavors available: +// - binary_dense where both input, other and output are dense and share the +// same type +// - binary_strided when all inputs are of the same types, but some elements are +// strided +// - binary_dense_cast - inputs are dense, but of different dtypes +// - binary_strided_cast - inputs or output are strided and of different dtypes +// - binary_dense_broadcast - one input is dense, another one is broadcastable +// Note about accuracy (for more info see +// https://github.com/pytorch/pytorch/issues/152736) Sometimes when kernel is +// invoked to produce `half` output, but one of the arguments is float arguments +// should be upcast to float, rather than downcast to half At the moment this is +// expressed with `om_t` optional argument (which stands for opmath_type) which +// is identical to output type but could be something else + +template +kernel void binary_strided( + device void* output [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* other [[buffer(2)]], + constant long* sizes [[buffer(3)]], + constant long* output_strides [[buffer(4)]], + constant long* input_strides [[buffer(5)]], + constant long* other_strides [[buffer(6)]], + constant uint3& ndim [[buffer(7)]], + uint index [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + int pos[max_ndim]; + pos_from_thread_index(int(index), pos, sizes, ndim.x); + const auto input_offs = offset_from_coord(pos, input_strides, ndim.x); + const auto other_offs = offset_from_coord(pos, other_strides, ndim.x); + const auto output_offs = offset_from_coord(pos, output_strides, ndim.x); + const auto a = val_at_offs(input, input_offs); + const auto b = val_at_offs(other, other_offs); + ref_at_offs(output, output_offs) = + static_cast(f(om_t(a), om_t(b))); +} + +template +kernel void binary_alpha_strided( + device void* output [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* other [[buffer(2)]], + constant T2& alpha [[buffer(3)]], + constant long* sizes [[buffer(4)]], + constant long* output_strides [[buffer(5)]], + constant long* input_strides [[buffer(6)]], + constant long* other_strides [[buffer(7)]], + constant uint3& ndim [[buffer(8)]], + uint index [[thread_position_in_grid]]) { + F f; + int pos[max_ndim]; + pos_from_thread_index(int(index), pos, sizes, ndim.x); + const auto input_offs = offset_from_coord(pos, input_strides, ndim.x); + const auto other_offs = offset_from_coord(pos, other_strides, ndim.x); + const auto output_offs = offset_from_coord(pos, output_strides, ndim.x); + const auto a = val_at_offs(input, input_offs); + const auto b = val_at_offs(other, other_offs); + ref_at_offs>(output, output_offs) = f(a, b, alpha); +} + +template > +kernel void binary_strided_cast( + device void* output [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* other [[buffer(2)]], + constant long* sizes [[buffer(3)]], + constant long* output_strides [[buffer(4)]], + constant long* input_strides [[buffer(5)]], + constant long* other_strides [[buffer(6)]], + constant uint4& ndim_types [[buffer(7)]], + uint index [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + int pos[max_ndim]; + pos_from_thread_index(int(index), pos, sizes, ndim_types.x); + const auto input_offs = offset_from_coord(pos, input_strides, ndim_types.x); + const auto other_offs = offset_from_coord(pos, other_strides, ndim_types.x); + const auto output_offs = offset_from_coord(pos, output_strides, ndim_types.x); + const auto a = val_at_offs( + input, input_offs, static_cast(ndim_types.y)); + const auto b = val_at_offs( + other, other_offs, static_cast(ndim_types.z)); + ref_at_offs(output, output_offs) = static_cast(f(a, b)); +} + +template +kernel void binary_alpha_strided_cast( + device void* output [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* other [[buffer(2)]], + constant T2& alpha [[buffer(3)]], + constant long* sizes [[buffer(4)]], + constant long* output_strides [[buffer(5)]], + constant long* input_strides [[buffer(6)]], + constant long* other_strides [[buffer(7)]], + constant uint4& ndim_types [[buffer(8)]], + uint index [[thread_position_in_grid]]) { + F f; + int pos[max_ndim]; + pos_from_thread_index(int(index), pos, sizes, ndim_types.x); + const auto input_offs = offset_from_coord(pos, input_strides, ndim_types.x); + const auto other_offs = offset_from_coord(pos, other_strides, ndim_types.x); + const auto output_offs = offset_from_coord(pos, output_strides, ndim_types.x); + const auto a = + val_at_offs(input, input_offs, static_cast(ndim_types.y)); + const auto b = + val_at_offs(other, other_offs, static_cast(ndim_types.z)); + ref_at_offs>(output, output_offs) = f(a, b, alpha); +} + +template > +kernel void binary_dense( + device result_of* out [[buffer(0)]], + constant T* input [[buffer(1)]], + constant T* other [[buffer(2)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + out[tid] = static_cast(f(om_t(input[tid]), om_t(other[tid]))); +} + +template +kernel void binary_alpha_dense( + device result_of* out [[buffer(0)]], + constant T* input [[buffer(1)]], + constant T* other [[buffer(2)]], + constant T2& alpha [[buffer(3)]], + uint tid [[thread_position_in_grid]]) { + F f; + out[tid] = f(input[tid], other[tid], alpha); +} + +template +kernel void binary_dense_cast( + device result_of* out [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* other [[buffer(2)]], + constant uint4& sizes_types [[buffer(3)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + const auto a = val_at_offs( + input, tid * sizes_types.x, static_cast(sizes_types.z)); + const auto b = val_at_offs( + other, tid * sizes_types.y, static_cast(sizes_types.w)); + out[tid] = static_cast(f(a, b)); +} + +template +kernel void binary_alpha_dense_cast( + device result_of* out [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* other [[buffer(2)]], + constant T2& alpha [[buffer(3)]], + constant uint4& sizes_types [[buffer(4)]], + uint tid [[thread_position_in_grid]]) { + F f; + const auto a = val_at_offs( + input, tid * sizes_types.x, static_cast(sizes_types.z)); + const auto b = val_at_offs( + other, tid * sizes_types.y, static_cast(sizes_types.w)); + out[tid] = f(a, b, alpha); +} + +template > +kernel void binary_dense_broadcast( + device result_of* out [[buffer(0)]], + constant T* input [[buffer(1)]], + constant T* broadcast [[buffer(2)]], + constant long& broadcast_numel [[buffer(3)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + out[tid] = static_cast( + f(om_t(input[tid]), om_t(broadcast[tid % broadcast_numel]))); +} + +template > +kernel void binary_dense_broadcast_rhs( + device result_of* out [[buffer(0)]], + constant T* broadcast [[buffer(1)]], + constant T* input [[buffer(2)]], + constant long& broadcast_numel [[buffer(3)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + out[tid] = static_cast( + f(om_t(broadcast[tid % broadcast_numel]), om_t(input[tid]))); +} + +template +kernel void binary_alpha_dense_broadcast( + device result_of* out [[buffer(0)]], + constant T* input [[buffer(1)]], + constant T* broadcast [[buffer(2)]], + constant long& broadcast_numel [[buffer(3)]], + constant T2& alpha [[buffer(4)]], + uint tid [[thread_position_in_grid]]) { + F f; + out[tid] = f(input[tid], broadcast[tid % broadcast_numel], alpha); +} + +template +kernel void binary_alpha_dense_broadcast_rhs( + device result_of* out [[buffer(0)]], + constant T* broadcast [[buffer(1)]], + constant T* input [[buffer(2)]], + constant long& broadcast_numel [[buffer(3)]], + constant T2& alpha [[buffer(4)]], + uint tid [[thread_position_in_grid]]) { + F f; + out[tid] = f(broadcast[tid % broadcast_numel], input[tid], alpha); +} + +template +kernel void binary_dense_broadcast_cast( + device result_of* out [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* broadcast [[buffer(2)]], + constant long& broadcast_numel [[buffer(3)]], + constant uint4& sizes_types [[buffer(4)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + const auto a = val_at_offs( + input, tid * sizes_types.x, static_cast(sizes_types.z)); + const auto b = val_at_offs( + broadcast, + (tid % broadcast_numel) * sizes_types.y, + static_cast(sizes_types.w)); + out[tid] = static_cast(f(a, b)); +} + +template +kernel void binary_dense_broadcast_rhs_cast( + device result_of* out [[buffer(0)]], + constant void* broadcast [[buffer(1)]], + constant void* input [[buffer(2)]], + constant long& broadcast_numel [[buffer(3)]], + constant uint4& sizes_types [[buffer(4)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + const auto a = val_at_offs( + broadcast, + (tid % broadcast_numel) * sizes_types.x, + static_cast(sizes_types.z)); + const auto b = val_at_offs( + input, tid * sizes_types.y, static_cast(sizes_types.w)); + out[tid] = static_cast(f(a, b)); +} + +template +kernel void binary_alpha_dense_broadcast_cast( + device result_of* out [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* broadcast [[buffer(2)]], + constant long& broadcast_numel [[buffer(3)]], + constant T2& alpha [[buffer(4)]], + constant uint4& sizes_types [[buffer(5)]], + uint tid [[thread_position_in_grid]]) { + F f; + const auto a = val_at_offs( + input, tid * sizes_types.x, static_cast(sizes_types.z)); + const auto b = val_at_offs( + broadcast, + (tid % broadcast_numel) * sizes_types.y, + static_cast(sizes_types.w)); + out[tid] = f(a, b, alpha); +} + +template +kernel void binary_alpha_dense_broadcast_rhs_cast( + device result_of* out [[buffer(0)]], + constant void* broadcast [[buffer(1)]], + constant void* input [[buffer(2)]], + constant long& broadcast_numel [[buffer(3)]], + constant T2& alpha [[buffer(4)]], + constant uint4& sizes_types [[buffer(5)]], + uint tid [[thread_position_in_grid]]) { + F f; + const auto a = val_at_offs( + broadcast, + (tid % broadcast_numel) * sizes_types.x, + static_cast(sizes_types.z)); + const auto b = val_at_offs( + input, tid * sizes_types.y, static_cast(sizes_types.w)); + out[tid] = f(a, b, alpha); +} + +template > +kernel void binary_dense_scalar( + device result_of* out [[buffer(0)]], + constant T* input [[buffer(1)]], + device T* scalar [[buffer(2)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + out[tid] = static_cast(f(om_t(input[tid]), om_t(scalar[0]))); +} + +template > +kernel void binary_dense_scalar_lhs( + device result_of* out [[buffer(0)]], + device T* scalar [[buffer(1)]], + constant T* input [[buffer(2)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + out[tid] = static_cast(f(om_t(scalar[0]), om_t(input[tid]))); +} + +template +kernel void binary_dense_scalar_cast( + device result_of* out [[buffer(0)]], + constant void* input [[buffer(1)]], + device void* scalar [[buffer(2)]], + constant uint4& sizes_types [[buffer(3)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + const auto a = val_at_offs( + input, tid * sizes_types.x, static_cast(sizes_types.z)); + const auto b = + val_at_offs(scalar, 0, static_cast(sizes_types.w)); + out[tid] = static_cast(f(a, b)); +} + +template +kernel void binary_dense_scalar_lhs_cast( + device result_of* out [[buffer(0)]], + device void* scalar [[buffer(1)]], + constant void* input [[buffer(2)]], + constant uint4& sizes_types [[buffer(3)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + const auto a = + val_at_offs(scalar, 0, static_cast(sizes_types.z)); + const auto b = val_at_offs( + input, tid * sizes_types.y, static_cast(sizes_types.w)); + out[tid] = static_cast(f(a, b)); +} + +template +kernel void binary_alpha_dense_scalar( + device result_of* out [[buffer(0)]], + constant T* input [[buffer(1)]], + device T* scalar [[buffer(2)]], + constant T2& alpha [[buffer(3)]], + uint tid [[thread_position_in_grid]]) { + F f; + out[tid] = f(input[tid], scalar[0], alpha); +} + +template +kernel void binary_alpha_dense_scalar_lhs( + device result_of* out [[buffer(0)]], + device T* scalar [[buffer(1)]], + constant T* input [[buffer(2)]], + constant T2& alpha [[buffer(3)]], + uint tid [[thread_position_in_grid]]) { + F f; + out[tid] = f(scalar[0], input[tid], alpha); +} + +template +kernel void binary_alpha_dense_scalar_cast( + device result_of* out [[buffer(0)]], + constant void* input [[buffer(1)]], + device void* scalar [[buffer(2)]], + constant T2& alpha [[buffer(3)]], + constant uint4& sizes_types [[buffer(4)]], + uint tid [[thread_position_in_grid]]) { + F f; + const auto a = val_at_offs( + input, tid * sizes_types.x, static_cast(sizes_types.z)); + const auto b = + val_at_offs(scalar, 0, static_cast(sizes_types.w)); + out[tid] = f(a, b, alpha); +} + +template +kernel void binary_alpha_dense_scalar_lhs_cast( + device result_of* out [[buffer(0)]], + device void* scalar [[buffer(1)]], + constant void* input [[buffer(2)]], + constant T2& alpha [[buffer(3)]], + constant uint4& sizes_types [[buffer(4)]], + uint tid [[thread_position_in_grid]]) { + F f; + const auto a = + val_at_offs(scalar, 0, static_cast(sizes_types.z)); + const auto b = val_at_offs( + input, tid * sizes_types.y, static_cast(sizes_types.w)); + out[tid] = f(a, b, alpha); +} + +#define REGISTER_BINARY_OP_(NAME, DTYPEI, DTYPEO, OMT) \ + static_assert( \ + ::metal::is_same_v< \ + DTYPEO, \ + ::c10::metal::result_of>, \ + "Output dtype mismatch for binary op " #NAME " and input " #DTYPEI); \ + template [[host_name(#NAME "_strided_" #DTYPEO "_" #DTYPEI)]] kernel void :: \ + c10::metal::binary_strided( \ + device void* out, \ + constant void* input, \ + constant void* other, \ + constant long* sizes, \ + constant long* output_strides, \ + constant long* input_strides, \ + constant long* other_strides, \ + constant uint3& ndim, \ + uint tid); \ + template [[host_name(#NAME "_strided_cast_" #DTYPEI)]] kernel void ::c10:: \ + metal::binary_strided_cast( \ + device void* out, \ + constant void* input, \ + constant void* other, \ + constant long* sizes, \ + constant long* output_strides, \ + constant long* input_strides, \ + constant long* other_strides, \ + constant uint4& ndim_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_" #DTYPEO "_" #DTYPEI)]] kernel void :: \ + c10::metal::binary_dense( \ + device ::c10::metal::result_of * \ + out_, \ + constant DTYPEI * input_, \ + constant DTYPEI * other_, \ + uint tid); \ + template [[host_name(#NAME "_dense_cast_" #DTYPEI)]] kernel void ::c10:: \ + metal::binary_dense_cast( \ + device ::c10::metal::result_of * \ + out_, \ + constant void* input, \ + constant void* other, \ + constant uint4& sizes_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_broadcast_" #DTYPEO "_" #DTYPEI)]] \ + kernel void ::c10::metal:: \ + binary_dense_broadcast( \ + device ::c10::metal::result_of * \ + out_, \ + constant DTYPEI * input_, \ + constant DTYPEI * broadcast_, \ + constant long& broadcast_numel, \ + uint tid); \ + template [[host_name(#NAME "_dense_broadcast_rhs_" #DTYPEO "_" #DTYPEI)]] \ + kernel void ::c10::metal:: \ + binary_dense_broadcast_rhs( \ + device ::c10::metal::result_of * \ + out_, \ + constant DTYPEI * broadcast_, \ + constant DTYPEI * input_, \ + constant long& broadcast_numel, \ + uint tid); \ + template [[host_name(#NAME "_dense_broadcast_cast_" #DTYPEI)]] \ + kernel void ::c10::metal:: \ + binary_dense_broadcast_cast( \ + device ::c10::metal::result_of * \ + out_, \ + constant void* input_, \ + constant void* broadcast_, \ + constant long& broadcast_numel, \ + constant uint4& sizes_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_broadcast_rhs_cast_" #DTYPEI)]] \ + kernel void ::c10::metal:: \ + binary_dense_broadcast_rhs_cast( \ + device ::c10::metal::result_of * \ + out_, \ + constant void* broadcast_, \ + constant void* input_, \ + constant long& broadcast_numel, \ + constant uint4& sizes_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_scalar_" #DTYPEO "_" #DTYPEI)]] \ + kernel void ::c10::metal::binary_dense_scalar( \ + device ::c10::metal::result_of * out_, \ + constant DTYPEI * input_, \ + device DTYPEI * scalar_, \ + uint tid); \ + template [[host_name(#NAME "_dense_scalar_lhs_" #DTYPEO "_" #DTYPEI)]] \ + kernel void ::c10::metal:: \ + binary_dense_scalar_lhs( \ + device ::c10::metal::result_of * \ + out_, \ + device DTYPEI * scalar_, \ + constant DTYPEI * input_, \ + uint tid); \ + template [[host_name(#NAME "_dense_scalar_cast_" #DTYPEI)]] \ + kernel void ::c10::metal:: \ + binary_dense_scalar_cast( \ + device ::c10::metal::result_of * \ + out_, \ + constant void* input_, \ + device void* scalar_, \ + constant uint4& sizes_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_scalar_lhs_cast_" #DTYPEI)]] \ + kernel void ::c10::metal:: \ + binary_dense_scalar_lhs_cast( \ + device ::c10::metal::result_of * \ + out_, \ + device void* scalar_, \ + constant void* input_, \ + constant uint4& sizes_types, \ + uint tid) + +// OpMath Binary Op promotes inputs to higher precision type before Functor call +#define REGISTER_OPMATH_BINARY_OP(NAME, DTYPEI, DTYPEO) \ + REGISTER_BINARY_OP_(NAME, DTYPEI, DTYPEO, ::c10::metal::opmath_t) + +#define REGISTER_BINARY_OP(NAME, DTYPEI, DTYPEO) \ + REGISTER_BINARY_OP_(NAME, DTYPEI, DTYPEO, DTYPEI) + +#define REGISTER_BINARY_ALPHA_OP(NAME, DTYPEI, DTYPEA, DTYPEO) \ + static_assert( \ + ::metal::is_same_v< \ + DTYPEO, \ + ::c10::metal::result_of>, \ + "Output dtype mismatch for binary op " #NAME " and input " #DTYPEI); \ + template [[host_name(#NAME "_strided_" #DTYPEO "_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_strided( \ + device void* out, \ + constant void* input, \ + constant void* other, \ + constant DTYPEA& alpha, \ + constant long* sizes, \ + constant long* output_strides, \ + constant long* input_strides, \ + constant long* other_strides, \ + constant uint3& ndim, \ + uint tid); \ + template [[host_name(#NAME "_strided_cast_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_strided_cast( \ + device void* out, \ + constant void* input, \ + constant void* other, \ + constant DTYPEA& alpha, \ + constant long* sizes, \ + constant long* output_strides, \ + constant long* input_strides, \ + constant long* other_strides, \ + constant uint4& ndim_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_" #DTYPEO "_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_dense( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant DTYPEI * input_, \ + constant DTYPEI * other_, \ + constant DTYPEA & alpha, \ + uint tid); \ + template \ + [[host_name(#NAME "_dense_cast_" #DTYPEI "_" #DTYPEA)]] kernel void :: \ + c10::metal::binary_alpha_dense_cast( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant void* input, \ + constant void* other, \ + constant DTYPEA& alpha, \ + constant uint4& sizes_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_broadcast_" #DTYPEO "_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_dense_broadcast( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant DTYPEI * input_, \ + constant DTYPEI * broadcast_, \ + constant long& broadcast_numel, \ + constant DTYPEA& alpha, \ + uint tid); \ + template [[host_name(#NAME "_dense_broadcast_rhs_" #DTYPEO "_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_dense_broadcast_rhs( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant DTYPEI * broadcast_, \ + constant DTYPEI * input_, \ + constant long& broadcast_numel, \ + constant DTYPEA& alpha, \ + uint tid); \ + template [[host_name(#NAME "_dense_broadcast_cast_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_dense_broadcast_cast( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant void* input_, \ + constant void* broadcast_, \ + constant long& broadcast_numel, \ + constant DTYPEA& alpha, \ + constant uint4& sizes_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_broadcast_rhs_cast_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_dense_broadcast_rhs_cast( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant void* broadcast_, \ + constant void* input_, \ + constant long& broadcast_numel, \ + constant DTYPEA& alpha, \ + constant uint4& sizes_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_scalar_" #DTYPEO "_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_dense_scalar( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant DTYPEI * input_, \ + device DTYPEI * scalar_, \ + constant DTYPEA & alpha, \ + uint tid); \ + template [[host_name(#NAME "_dense_scalar_lhs_" #DTYPEO "_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_dense_scalar_lhs( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + device DTYPEI * scalar_, \ + constant DTYPEI * input_, \ + constant DTYPEA & alpha, \ + uint tid); \ + template [[host_name(#NAME "_dense_scalar_cast_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_dense_scalar_cast( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant void* input_, \ + device void* scalar_, \ + constant DTYPEA& alpha, \ + constant uint4& sizes_types, \ + uint tid); \ + template [[host_name(#NAME "_dense_scalar_lhs_cast_" #DTYPEI \ + "_" #DTYPEA)]] kernel void ::c10::metal:: \ + binary_alpha_dense_scalar_lhs_cast( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + device void* scalar_, \ + constant void* input_, \ + constant DTYPEA& alpha, \ + constant uint4& sizes_types, \ + uint tid) + +// Ternary elementwise ops kernels +// Right now there are 4 flavors available: +// - ternary_dense where both input, other1, other2, and output are dense and +// share the same type +// - ternary_strided when all inputs are of the same types, but some elements +// are strided +// - ternary_dense_cast - inputs are dense, but of different dtypes +// - ternary_strided_cast - inputs or output are strided and of different dtypes +// Note about accuracy (for more info see +// https://github.com/pytorch/pytorch/issues/152736) Sometimes when kernel is +// invoked to produce `half` output, but one of the arguments is float arguments +// should be upcast to float, rather than downcast to half At the moment this is +// expressed with `om_t` optional argument (which stands for opmath_type) which +// is identical to output type but could be something else + +template +kernel void ternary_strided( + device void* output [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* other1 [[buffer(2)]], + constant void* other2 [[buffer(3)]], + constant long* sizes [[buffer(4)]], + constant long* output_strides [[buffer(5)]], + constant long* input_strides [[buffer(6)]], + constant long* other1_strides [[buffer(7)]], + constant long* other2_strides [[buffer(8)]], + constant uint& ndim [[buffer(9)]], + uint index [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + int pos[max_ndim]; + pos_from_thread_index(int(index), pos, sizes, ndim); + const auto input_offs = offset_from_coord(pos, input_strides, ndim); + const auto other1_offs = offset_from_coord(pos, other1_strides, ndim); + const auto other2_offs = offset_from_coord(pos, other2_strides, ndim); + const auto output_offs = offset_from_coord(pos, output_strides, ndim); + const auto a = val_at_offs(input, input_offs); + const auto b = val_at_offs(other1, other1_offs); + const auto c = val_at_offs(other2, other2_offs); + ref_at_offs(output, output_offs) = + static_cast(f(om_t(a), om_t(b), om_t(c))); +} + +template > +kernel void ternary_strided_cast( + device void* output [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* other1 [[buffer(2)]], + constant void* other2 [[buffer(3)]], + constant long* sizes [[buffer(4)]], + constant long* output_strides [[buffer(5)]], + constant long* input_strides [[buffer(6)]], + constant long* other1_strides [[buffer(7)]], + constant long* other2_strides [[buffer(8)]], + constant uint& ndim [[buffer(9)]], + constant uint4& types [[buffer(10)]], + uint index [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + int pos[max_ndim]; + pos_from_thread_index(int(index), pos, sizes, ndim); + const auto input_offs = offset_from_coord(pos, input_strides, ndim); + const auto other1_offs = offset_from_coord(pos, other1_strides, ndim); + const auto other2_offs = offset_from_coord(pos, other2_strides, ndim); + const auto output_offs = offset_from_coord(pos, output_strides, ndim); + const auto a = + val_at_offs(input, input_offs, static_cast(types.x)); + const auto b = + val_at_offs(other1, other1_offs, static_cast(types.y)); + const auto c = + val_at_offs(other2, other2_offs, static_cast(types.z)); + ref_at_offs(output, output_offs) = static_cast(f(a, b, c)); +} + +template > +kernel void ternary_dense( + device result_of* out [[buffer(0)]], + constant T* input [[buffer(1)]], + constant T* other1 [[buffer(2)]], + constant T* other2 [[buffer(3)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + out[tid] = static_cast( + f(om_t(input[tid]), om_t(other1[tid]), om_t(other2[tid]))); +} + +template +kernel void ternary_dense_cast( + device result_of* out [[buffer(0)]], + constant void* input [[buffer(1)]], + constant void* other1 [[buffer(2)]], + constant void* other2 [[buffer(3)]], + constant uint3& sizes [[buffer(4)]], + constant uint3& types [[buffer(5)]], + uint tid [[thread_position_in_grid]]) { + F f; + using res_t = result_of; + const auto a = + val_at_offs(input, tid * sizes.x, static_cast(types.x)); + const auto b = val_at_offs( + other1, tid * sizes.y, static_cast(types.y)); + const auto c = val_at_offs( + other2, tid * sizes.z, static_cast(types.z)); + out[tid] = static_cast(f(a, b, c)); +} + +#define REGISTER_TERNARY_OP_(NAME, DTYPEI, DTYPEO, OMT) \ + static_assert( \ + ::metal::is_same_v< \ + DTYPEO, \ + ::c10::metal::result_of>, \ + "Output dtype mismatch for ternary op " #NAME " and input " #DTYPEI); \ + template [[host_name(#NAME "_strided_" #DTYPEO "_" #DTYPEI)]] kernel void :: \ + c10::metal::ternary_strided( \ + device void* out, \ + constant void* input, \ + constant void* other1, \ + constant void* other2, \ + constant long* sizes, \ + constant long* output_strides, \ + constant long* input_strides, \ + constant long* other1_strides, \ + constant long* other2_strides, \ + constant uint& ndim, \ + uint tid); \ + template [[host_name(#NAME "_strided_cast_" #DTYPEI)]] kernel void ::c10:: \ + metal::ternary_strided_cast( \ + device void* out, \ + constant void* input, \ + constant void* other1, \ + constant void* other2, \ + constant long* sizes, \ + constant long* output_strides, \ + constant long* input_strides, \ + constant long* other1_strides, \ + constant long* other2_strides, \ + constant uint& ndim, \ + constant uint4& types, \ + uint tid); \ + template [[host_name(#NAME "_dense_" #DTYPEO "_" #DTYPEI)]] kernel void :: \ + c10::metal::ternary_dense( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant DTYPEI * input_, \ + constant DTYPEI * other1_, \ + constant DTYPEI * other2_, \ + uint tid); \ + template [[host_name(#NAME "_dense_cast_" #DTYPEI)]] kernel void ::c10:: \ + metal::ternary_dense_cast( \ + device ::c10::metal:: \ + result_of * \ + out_, \ + constant void* input, \ + constant void* other1, \ + constant void* other2, \ + constant uint3& sizes, \ + constant uint3& types, \ + uint tid) + +// OpMath ternary Op promotes inputs to higher precision type before Functor +// call +#define REGISTER_OPMATH_TERNARY_OP(NAME, DTYPEI, DTYPEO) \ + REGISTER_TERNARY_OP_(NAME, DTYPEI, DTYPEO, ::c10::metal::opmath_t) + +#define REGISTER_TERNARY_OP(NAME, DTYPEI, DTYPEO) \ + REGISTER_TERNARY_OP_(NAME, DTYPEI, DTYPEO, DTYPEI) + +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/random.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/random.h new file mode 100644 index 0000000000000000000000000000000000000000..b250b3c9e1a2a089d0a4161b0d1a290a268445de --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/random.h @@ -0,0 +1,83 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Philox Counter based RNG implementation for Metal +// Borrowed from aten/src/ATen/core/PhiloxRNGEngine.h +// Which in turn borrowed from +// http://www.thesalmons.org/john/random123/papers/random123sc11.pdf +#pragma once +#include + +namespace c10 { +namespace metal { + +namespace detail { + +constexpr float uint32_to_uniform_float(uint32_t value) { + // maximum value such that `MAX_INT * scale < 1.0` (with float rounding) + constexpr float scale = 4.6566127342e-10; + return static_cast(value & 0x7FFFFFFF) * scale; +} + +inline uint2 splitlong(ulong v) { + return uint2(v >> 32, v & 0xffffffff); +} + +} // namespace detail + +namespace philox4 { + +uint2 mulhilo(uint a, uint b) { + auto rc = static_cast(a) * b; + return detail::splitlong(rc); +} +uint4 single_round(uint4 ctr, uint2 key) { + constexpr uint kPhiloxSA = 0xD2511F53; + constexpr uint kPhiloxSB = 0xCD9E8D57; + auto rc0 = mulhilo(kPhiloxSA, ctr.x); + auto rc1 = mulhilo(kPhiloxSB, ctr.z); + return uint4(rc1.x ^ ctr.y ^ key.x, rc1.y, rc0.x ^ ctr.w ^ key.y, rc0.y); +} + +uint4 multiple_rounds(uint4 ctr, uint2 key, uint rounds) { + constexpr uint2 kPhilox10 = {0x9E3779B9, 0xBB67AE85}; + for (uint round = 0; round < rounds - 1; ++round) { + ctr = single_round(ctr, key); + key += kPhilox10; + } + return ctr; +} + +uint4 rand(long seed, long index) { + uint4 ctr = 0; + ctr.zw = detail::splitlong(index); + return multiple_rounds(ctr, detail::splitlong(seed), 10); +} + +} // namespace philox4 + +float randn(long seed, long index) { + auto value = philox4::rand(seed, index); + float u1 = 1.0 - detail::uint32_to_uniform_float(value.x); + float u2 = 1.0 - detail::uint32_to_uniform_float(value.y); + return ::metal::sqrt(-2.0 * ::metal::log(u1)) * + ::metal::cos(2.0 * M_PI_F * u2); +} + +float rand(long seed, long index) { + auto value = philox4::rand(seed, index); + return detail::uint32_to_uniform_float(value.x); +} + +long randint64(long seed, long index, long low, long high) { + auto range = high - low; + auto value = philox4::rand(seed, index); + // TODO: Implement better algorithm for large ranges + return low + + static_cast(detail::uint32_to_uniform_float(value.x) * range); +} + +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/reduction_utils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/reduction_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..f23c1af774ed88568bc1abacc668e98760bb6f98 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/reduction_utils.h @@ -0,0 +1,364 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10 { +namespace metal { +namespace detail { +template +struct simd_type { + using t = T; +}; + +// Helper that allows one to run simd ops over bfl16 by upcasting them to fp32 +template +using simd_type_t = typename simd_type::t; + +template <> +struct simd_type { + using t = float; +}; +} // namespace detail + +template +inline ::metal::enable_if_t, T> simd_sum(T val) { + return T(::metal::simd_sum(detail::simd_type_t(val))); +} + +template +inline ::metal::enable_if_t, T> simd_prod(T val) { + return T(::metal::simd_product(detail::simd_type_t(val))); +} + +// Extend simd_broadcast to 64-bit integral types using int2 trick +template < + typename T, + ::metal::enable_if_t<::metal::is_integral_v && sizeof(T) == 8, bool> = + true> +inline T simd_broadcast(T val, ushort lane_id) { + return as_type(::metal::simd_broadcast(as_type(val), lane_id)); +} + +template < + typename T, + ::metal::enable_if_t || sizeof(T) != 8, bool> = + true> +inline T simd_broadcast(T val, ushort lane_id) { + return ::metal::simd_broadcast(val, lane_id); +} + +// Floating simd_min/max with nan propagation +template < + typename T, + ::metal::enable_if_t<::metal::is_floating_point_v, bool> = true> +inline T simd_max(T val) { + if (::metal::simd_any(::metal::isnan(val))) { + return ::metal::numeric_limits::quiet_NaN(); + } + return T(::metal::simd_max(detail::simd_type_t(val))); +} + +template < + typename T, + ::metal::enable_if_t<::metal::is_floating_point_v, bool> = true> +inline T simd_min(T val) { + if (::metal::simd_any(::metal::isnan(val))) { + return ::metal::numeric_limits::quiet_NaN(); + } + return T(::metal::simd_min(detail::simd_type_t(val))); +} + +template < + typename T, + ::metal::enable_if_t<::metal::is_integral_v && sizeof(T) != 8, bool> = + true> +inline T simd_max(T val) { + return ::metal::simd_max(val); +} + +template < + typename T, + ::metal::enable_if_t<::metal::is_integral_v && sizeof(T) != 8, bool> = + true> +inline T simd_min(T val) { + return ::metal::simd_min(val); +} + +// Metal does not support SIMD reductions over 64-bit types, but it could be +// implement using simd_shuffle_down, that yields result in log2(simdgroup_size) +// iterations Use fill variant, as shuffle down returns garbage if inactive +// thread is referenced (on M1/M2, works fine on M4) and broadcast result to all +// threads in the end. Implementation heavily borrows from +// https://github.com/ml-explore/mlx/blob/86389bf9707f46101af45d90510e8e97c8a90b93/mlx/backend/metal/kernels/reduction/ops.h#L16 +template +inline ::metal::enable_if_t<::metal::is_same_v, T> simd_sum(T val) { + for (ushort i = simdgroup_size / 2; i > 0; i /= 2) { + val += as_type( + ::metal::simd_shuffle_and_fill_down(as_type(val), int2(0), i)); + } + return simd_broadcast(val, 0); +} + +template +inline ::metal::enable_if_t<::metal::is_same_v, T> simd_prod(T val) { + for (ushort i = simdgroup_size / 2; i > 0; i /= 2) { + val *= as_type( + ::metal::simd_shuffle_and_fill_down(as_type(val), int2(0), i)); + } + return simd_broadcast(val, 0); +} + +template +inline ::metal::enable_if_t<::metal::is_same_v, T> simd_max(T val) { + for (ushort i = simdgroup_size / 2; i > 0; i /= 2) { + val = ::metal::max( + val, + as_type(::metal::simd_shuffle_and_fill_down( + as_type(val), int2(0), i))); + } + return simd_broadcast(val, 0); +} + +template +inline ::metal::enable_if_t<::metal::is_same_v, T> simd_min(T val) { + for (ushort i = simdgroup_size / 2; i > 0; i /= 2) { + val = ::metal::min( + val, + as_type(::metal::simd_shuffle_and_fill_down( + as_type(val), int2(0), i))); + } + return simd_broadcast(val, 0); +} + +// argmin/argmax helpers using simd_ballot +template < + typename T, + ::metal::enable_if_t<::metal::is_integral_v, bool> = true> +inline ::c10::metal::pair simd_argmin(T val) { + const auto rc = simd_min(val); + const auto vote = ::metal::simd_ballot(val == rc); + return {rc, static_cast(::metal::ctz(static_cast(vote)))}; +} + +template < + typename T, + ::metal::enable_if_t<::metal::is_floating_point_v, bool> = true> +inline ::c10::metal::pair simd_argmin(T val) { + const auto rc = simd_min(val); + const auto vote = ::metal::simd_ballot(val == rc || ::metal::isnan(val)); + return {rc, static_cast(::metal::ctz(static_cast(vote)))}; +} + +template < + typename T, + ::metal::enable_if_t<::metal::is_integral_v, bool> = true> +inline ::c10::metal::pair simd_argmax(T val) { + const auto rc = simd_max(val); + const auto vote = ::metal::simd_ballot(val == rc); + return {rc, static_cast(::metal::ctz(static_cast(vote)))}; +} + +template < + typename T, + ::metal::enable_if_t<::metal::is_floating_point_v, bool> = true> +inline ::c10::metal::pair simd_argmax(T val) { + const auto rc = simd_max(val); + const auto vote = ::metal::simd_ballot(val == rc || ::metal::isnan(val)); + return {rc, static_cast(::metal::ctz(static_cast(vote)))}; +} + +template +inline c10::metal::pair simd_argmin(ARG_T val, IDX_T idx_val) { + auto rc = simd_argmin(val); + return {rc.first, simd_broadcast(idx_val, rc.second)}; +} + +template +inline c10::metal::pair simd_argmax(ARG_T val, IDX_T idx_val) { + auto rc = simd_argmax(val); + return {rc.first, simd_broadcast(idx_val, rc.second)}; +} + +// Below algorithms are written with hardcoded assumption that simdgroup is 32 +// and threadgroup_max is 1024, i.e. reduction can be done in two stages max +template +opmath_t threadgroup_sum( + threadgroup opmath_t* data, + T val, + unsigned idx, + unsigned size) { + auto rc = simd_sum(static_cast>(val)); + if (idx % simdgroup_size == 0) { + data[idx / simdgroup_size] = rc; + } + if (size > simdgroup_size) { + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + if (idx < ((size + simdgroup_size - 1) / simdgroup_size)) { + auto rc1 = simd_sum(data[idx]); + if (idx == 0) { + data[0] = rc1; + } + } + } + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + return data[0]; +} + +template +opmath_t threadgroup_prod( + threadgroup opmath_t* data, + T val, + unsigned idx, + unsigned size) { + auto rc = simd_prod(static_cast>(val)); + if (idx % simdgroup_size == 0) { + data[idx / simdgroup_size] = rc; + } + if (size > simdgroup_size) { + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + if (idx < ((size + simdgroup_size - 1) / simdgroup_size)) { + auto rc1 = simd_prod(data[idx]); + if (idx == 0) { + data[0] = rc1; + } + } + } + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + return data[0]; +} + +template +T threadgroup_max(threadgroup T* data, T val, unsigned idx, unsigned size) { + auto rc = simd_max(val); + if (idx % simdgroup_size == 0) { + data[idx / simdgroup_size] = rc; + } + if (size > simdgroup_size) { + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + if (idx < ((size + simdgroup_size - 1) / simdgroup_size)) { + auto rc1 = simd_max(data[idx]); + if (idx == 0) { + data[0] = rc1; + } + } + } + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + return data[0]; +} + +template +T threadgroup_min(threadgroup T* data, T val, unsigned idx, unsigned size) { + auto rc = simd_min(val); + if (idx % simdgroup_size == 0) { + data[idx / simdgroup_size] = rc; + } + if (size > simdgroup_size) { + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + if (idx < ((size + simdgroup_size - 1) / simdgroup_size)) { + auto rc1 = simd_min(data[idx]); + if (idx == 0) { + data[0] = rc1; + } + } + } + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + return data[0]; +} + +template +float3 threadgroup_welford_reduce(threadgroup T* data, unsigned size) { + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + float m = data[0]; + float m2 = 0; + for (unsigned idx = 1; idx < size; ++idx) { + float delta = data[idx] - m; + m += delta / (idx + 1); + m2 += delta * (data[idx] - m); + } + return float3(m, m2, size); +} + +// Each vec3type is tuple of mean, m2 and weight +template +float3 welford_combine(T a, T b) { + float delta = b.x - a.x; + float new_weight = a.z + b.z; + auto w2_over_w = new_weight != 0 ? b.z / new_weight : 0.0; + return float3( + a.x + delta * w2_over_w, + a.y + b.y + delta * delta * a.z * w2_over_w, + new_weight); +} + +template +float3 threadgroup_welford_combine(threadgroup T* data, unsigned size) { + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + float3 rc = data[0]; + for (unsigned idx = 1; idx < size; ++idx) { + rc = welford_combine(rc, data[idx]); + } + return rc; +} + +template +IDX_T threadgroup_argmax( + threadgroup ARG_T* arg_data, + threadgroup IDX_T* idx_data, + ARG_T val, + IDX_T idx_val, + unsigned idx, + unsigned size) { + auto rc = simd_argmax(val, idx_val); + if (size <= simdgroup_size) { + return rc.second; + } + if (idx % simdgroup_size == 0) { + arg_data[idx / simdgroup_size] = rc.first; + idx_data[idx / simdgroup_size] = rc.second; + } + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + if (idx < ((size + simdgroup_size - 1) / simdgroup_size)) { + auto rc1 = simd_argmax(arg_data[idx], idx_data[idx]); + if (idx == 0) { + idx_data[0] = rc1.second; + } + } + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + return idx_data[0]; +} + +template +IDX_T threadgroup_argmin( + threadgroup ARG_T* arg_data, + threadgroup IDX_T* idx_data, + ARG_T val, + IDX_T idx_val, + unsigned idx, + unsigned size) { + auto rc = simd_argmin(val, idx_val); + if (size <= simdgroup_size) { + return rc.second; + } + if (idx % simdgroup_size == 0) { + arg_data[idx / simdgroup_size] = rc.first; + idx_data[idx / simdgroup_size] = rc.second; + } + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + if (idx < ((size + simdgroup_size - 1) / simdgroup_size)) { + auto rc1 = simd_argmin(arg_data[idx], idx_data[idx]); + if (idx == 0) { + idx_data[0] = rc1.second; + } + } + ::metal::threadgroup_barrier(::metal::mem_flags::mem_threadgroup); + return idx_data[0]; +} + +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/special_math.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/special_math.h new file mode 100644 index 0000000000000000000000000000000000000000..5dab929f9be08cd7ead0c080532933f07975251c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/special_math.h @@ -0,0 +1,3086 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Implementation of special math functions for Metal +#pragma once +#include +#include +#include +#include + +namespace c10 { +namespace metal { + +/* + * Approximation to the error function. + * Based on code from: + * https://stackoverflow.com/questions/35148198/efficient-faithfully-rounded-implementation-of-error-function-erff#answer-35148199 + * Copy-n-pasted from + * https://github.com/ml-explore/mlx/blob/2e8cf0b4506c200a5c2d199ecbbf655fdf4c2ce2/mlx/backend/metal/kernels/erf.h#L11 + */ +template +inline float erf(T x) { + const auto a = static_cast(x); + const auto t = ::metal::abs(a); + const auto s = a * a; + if (t > 0.927734375f) { + // maximum error 0.99527 ulp + auto r = ::metal::fma( + -1.72853470e-5f, t, 3.83197126e-4f); // -0x1.220000p-16,0x1.91cfb2p-12 + const auto u = ::metal::fma( + -3.88396438e-3f, t, 2.42546219e-2f); // -0x1.fd1438p-9, 0x1.8d6342p-6 + r = ::metal::fma(r, s, u); + r = ::metal::fma(r, t, -1.06777877e-1f); // -0x1.b55cb8p-4 + r = ::metal::fma(r, t, -6.34846687e-1f); // -0x1.450aa0p-1 + r = ::metal::fma(r, t, -1.28717512e-1f); // -0x1.079d0cp-3 + r = ::metal::fma(r, t, -t); + // TODO, replace with expm1 when implemented + r = 1.0f - ::metal::exp(r); + r = ::metal::copysign(r, a); + return r; + } + + // maximum error 0.98929 ulp + auto r = -5.96761703e-4f; // -0x1.38e000p-11 + r = ::metal::fma(r, s, 4.99119423e-3f); // 0x1.471a58p-8 + r = ::metal::fma(r, s, -2.67681349e-2f); // -0x1.b691b2p-6 + r = ::metal::fma(r, s, 1.12819925e-1f); // 0x1.ce1c44p-4 + r = ::metal::fma(r, s, -3.76125336e-1f); // -0x1.812700p-2 + r = ::metal::fma(r, s, 1.28379166e-1f); // 0x1.06eba8p-3 + r = ::metal::fma(r, a, a); + return r; +} + +template +float erfc(T x) { + return 1.0 - erf(x); +} + +template +inline float erfinv(T y) { + /* coefficients in rational expansion */ + constexpr float a[4] = {0.886226899, -1.645349621, 0.914624893, -0.140543331}; + constexpr float b[4] = {-2.118377725, 1.442710462, -0.329097515, 0.012229801}; + constexpr float c[4] = {-1.970840454, -1.624906493, 3.429567803, 1.641345311}; + constexpr float d[2] = {3.543889200, 1.637067800}; + + float x, z, num, dem; /*working variables */ + + float y_abs = ::metal::abs(static_cast(y)); + if (y_abs >= 1.0f) { + return y_abs > 1.0f ? NAN + : ::metal::copysign(INFINITY, static_cast(y)); + } + if (y_abs <= 0.7f) { + z = y * y; + num = ((a[3] * z + a[2]) * z + a[1]) * z + a[0]; + dem = (((b[3] * z + b[2]) * z + b[1]) * z + b[0]) * z + 1.0f; + x = y * num / dem; + } else { + z = ::metal::sqrt(-1.0f * ::metal::log((1.0 - y_abs) / 2.0)); + num = ((c[3] * z + c[2]) * z + c[1]) * z + c[0]; + dem = (d[1] * z + d[0]) * z + 1.0f; + x = ::metal::copysign(num, static_cast(y)) / dem; + } + + return x; +} + +/* + * For licensing information and documentation, please refer to the cpu + * implementation located in "ATen/native/Math.h". + */ + +template +inline T chbevl(T x, const float array[], const int len) { + T b0, b1, b2; + + b0 = array[0]; + b1 = 0; + + for (int i = 1; i < len; ++i) { + b2 = b1; + b1 = b0; + b0 = x * b1 - b2 + array[i]; + } + + return T{0.5} * (b0 - b2); +} + +// Copied from +// https://github.com/pytorch/pytorch/blob/58b661cda2c002a8e1ac3bee494bfe1f7420437c/aten/src/ATen/native/cuda/Math.cuh#L502 + +template +inline T i0(T _x) { + auto x = ::metal::fabs(_x); + + if (x <= 8.0) { + /* Chebyshev coefficients for exp(-x) I0(x) + * in the interval [0,8]. + * + * lim(x->0){ exp(-x) I0(x) } = 1. + */ + constexpr float A[] = { + -4.41534164647933937950E-18, 3.33079451882223809783E-17, + -2.43127984654795469359E-16, 1.71539128555513303061E-15, + -1.16853328779934516808E-14, 7.67618549860493561688E-14, + -4.85644678311192946090E-13, 2.95505266312963983461E-12, + -1.72682629144155570723E-11, 9.67580903537323691224E-11, + -5.18979560163526290666E-10, 2.65982372468238665035E-9, + -1.30002500998624804212E-8, 6.04699502254191894932E-8, + -2.67079385394061173391E-7, 1.11738753912010371815E-6, + -4.41673835845875056359E-6, 1.64484480707288970893E-5, + -5.75419501008210370398E-5, 1.88502885095841655729E-4, + -5.76375574538582365885E-4, 1.63947561694133579842E-3, + -4.32430999505057594430E-3, 1.05464603945949983183E-2, + -2.37374148058994688156E-2, 4.93052842396707084878E-2, + -9.49010970480476444210E-2, 1.71620901522208775349E-1, + -3.04682672343198398683E-1, 6.76795274409476084995E-1}; + + auto y = (x / 2.0) - 2.0; + return static_cast(::metal::exp(x) * chbevl(y, A, 30)); + } + + // Handles x > 8 case + /* Chebyshev coefficients for exp(-x) sqrt(x) I0(x) + * in the inverted interval [8,infinity]. + * + * lim(x->inf){ exp(-x) sqrt(x) I0(x) } = 1/sqrt(2pi). + */ + constexpr float B[] = { + -7.23318048787475395456E-18, -4.83050448594418207126E-18, + 4.46562142029675999901E-17, 3.46122286769746109310E-17, + -2.82762398051658348494E-16, -3.42548561967721913462E-16, + 1.77256013305652638360E-15, 3.81168066935262242075E-15, + -9.55484669882830764870E-15, -4.15056934728722208663E-14, + 1.54008621752140982691E-14, 3.85277838274214270114E-13, + 7.18012445138366623367E-13, -1.79417853150680611778E-12, + -1.32158118404477131188E-11, -3.14991652796324136454E-11, + 1.18891471078464383424E-11, 4.94060238822496958910E-10, + 3.39623202570838634515E-9, 2.26666899049817806459E-8, + 2.04891858946906374183E-7, 2.89137052083475648297E-6, + 6.88975834691682398426E-5, 3.36911647825569408990E-3, + 8.04490411014108831608E-1}; + + return static_cast( + (::metal::exp(x) * chbevl(32.0 / x - 2.0, B, 25)) / ::metal::sqrt(x)); +} + +template +inline T i0e(T _x) { + auto x = ::metal::fabs(_x); + + if (x <= 8.0) { + constexpr float coefficients[] = { + -4.41534164647933937950E-18, 3.33079451882223809783E-17, + -2.43127984654795469359E-16, 1.71539128555513303061E-15, + -1.16853328779934516808E-14, 7.67618549860493561688E-14, + -4.85644678311192946090E-13, 2.95505266312963983461E-12, + -1.72682629144155570723E-11, 9.67580903537323691224E-11, + -5.18979560163526290666E-10, 2.65982372468238665035E-9, + -1.30002500998624804212E-8, 6.04699502254191894932E-8, + -2.67079385394061173391E-7, 1.11738753912010371815E-6, + -4.41673835845875056359E-6, 1.64484480707288970893E-5, + -5.75419501008210370398E-5, 1.88502885095841655729E-4, + -5.76375574538582365885E-4, 1.63947561694133579842E-3, + -4.32430999505057594430E-3, 1.05464603945949983183E-2, + -2.37374148058994688156E-2, 4.93052842396707084878E-2, + -9.49010970480476444210E-2, 1.71620901522208775349E-1, + -3.04682672343198398683E-1, 6.76795274409476084995E-1}; + + auto y = (x / 2.0) - 2.0; + return static_cast(chbevl(y, coefficients, int{30})); + } + + // x > 8 + constexpr float coefficients[] = { + -7.23318048787475395456E-18, -4.83050448594418207126E-18, + 4.46562142029675999901E-17, 3.46122286769746109310E-17, + -2.82762398051658348494E-16, -3.42548561967721913462E-16, + 1.77256013305652638360E-15, 3.81168066935262242075E-15, + -9.55484669882830764870E-15, -4.15056934728722208663E-14, + 1.54008621752140982691E-14, 3.85277838274214270114E-13, + 7.18012445138366623367E-13, -1.79417853150680611778E-12, + -1.32158118404477131188E-11, -3.14991652796324136454E-11, + 1.18891471078464383424E-11, 4.94060238822496958910E-10, + 3.39623202570838634515E-9, 2.26666899049817806459E-8, + 2.04891858946906374183E-7, 2.89137052083475648297E-6, + 6.88975834691682398426E-5, 3.36911647825569408990E-3, + 8.04490411014108831608E-1}; + + return static_cast( + chbevl(32.0 / x - 2.0, coefficients, 25) / ::metal::sqrt(x)); +} + +// Copied from +// https://github.com/pytorch/pytorch/blob/58b661cda2c002a8e1ac3bee494bfe1f7420437c/aten/src/ATen/native/cuda/Math.cuh#L576 + +template +inline T i1(T _x) { + const auto x = ::metal::fabs(_x); + + if (x <= 8.0) { + // Chebyshev coefficients for exp(-x) i1(x) in the internal [0, 8] + // lim(x->0){ exp(-x) i1(x) / x } = 1/2 + constexpr float coefficients[] = { + 2.77791411276104639959E-18, -2.11142121435816608115E-17, + 1.55363195773620046921E-16, -1.10559694773538630805E-15, + 7.60068429473540693410E-15, -5.04218550472791168711E-14, + 3.22379336594557470981E-13, -1.98397439776494371520E-12, + 1.17361862988909016308E-11, -6.66348972350202774223E-11, + 3.62559028155211703701E-10, -1.88724975172282928790E-9, + 9.38153738649577178388E-9, -4.44505912879632808065E-8, + 2.00329475355213526229E-7, -8.56872026469545474066E-7, + 3.47025130813767847674E-6, -1.32731636560394358279E-5, + 4.78156510755005422638E-5, -1.61760815825896745588E-4, + 5.12285956168575772895E-4, -1.51357245063125314899E-3, + 4.15642294431288815669E-3, -1.05640848946261981558E-2, + 2.47264490306265168283E-2, -5.29459812080949914269E-2, + 1.02643658689847095384E-1, -1.76416518357834055153E-1, + 2.52587186443633654823E-1}; + const auto y = x / 2.0 - 2.0; + const auto out = ::metal::exp(x) * x * chbevl(y, coefficients, 29); + return static_cast(_x < T(0.) ? -out : out); + } + + // Chebyshev coefficients for exp(-x) sqrt(x) i1(x) + // in the inverted interval [8, infinity] + // lim(x->inf){ exp(-x) sqrt(x) i1(x) } = 1/sqrt(2pi) + constexpr float coefficients[] = { + 7.51729631084210481353E-18, 4.41434832307170791151E-18, + -4.65030536848935832153E-17, -3.20952592199342395980E-17, + 2.96262899764595013876E-16, 3.30820231092092828324E-16, + -1.88035477551078244854E-15, -3.81440307243700780478E-15, + 1.04202769841288027642E-14, 4.27244001671195135429E-14, + -2.10154184277266431302E-14, -4.08355111109219731823E-13, + -7.19855177624590851209E-13, 2.03562854414708950722E-12, + 1.41258074366137813316E-11, 3.25260358301548823856E-11, + -1.89749581235054123450E-11, -5.58974346219658380687E-10, + -3.83538038596423702205E-9, -2.63146884688951950684E-8, + -2.51223623787020892529E-7, -3.88256480887769039346E-6, + -1.10588938762623716291E-4, -9.76109749136146840777E-3, + 7.78576235018280120474E-1}; + const auto out = (::metal::exp(x) * chbevl(32. / x - 2., coefficients, 25)) / + ::metal::sqrt(x); + return static_cast(_x < T(0.) ? -out : out); +} + +template +inline T i1e(T _x) { + const auto x = ::metal::fabs(_x); + if (x <= 8.0) { + // Chebyshev double coefficients for exp(-x) i1(x) in the interval [0,8]. + // Note: lim(x->0){ exp(-x) i1(x) / x } = 1/2. + constexpr float coefficients[] = { + 9.38153738649577178388E-9f, + -4.44505912879632808065E-8f, + 2.00329475355213526229E-7f, + -8.56872026469545474066E-7f, + 3.47025130813767847674E-6f, + -1.32731636560394358279E-5f, + 4.78156510755005422638E-5f, + -1.61760815825896745588E-4f, + 5.12285956168575772895E-4f, + -1.51357245063125314899E-3f, + 4.15642294431288815669E-3f, + -1.05640848946261981558E-2f, + 2.47264490306265168283E-2f, + -5.29459812080949914269E-2f, + 1.02643658689847095384E-1f, + -1.76416518357834055153E-1f, + 2.52587186443633654823E-1f}; + const auto y = x / 2.0 - 2.0; + const auto out = chbevl(y, coefficients, 17) * x; + return static_cast(_x < 0. ? -out : out); + } + + // Chebyshev coefficients for exp(-x) sqrt(x) i1(x) + // in the inverted interval (8, infinity]. + // Note: lim(x->inf){ exp(-x) sqrt(x) i1(x) } = 1/sqrt(2pi). + // TODO: what's an "inverted interval"? Open on the left + // and closed on the right? + constexpr float coefficients[] = { + -3.83538038596423702205E-9f, + -2.63146884688951950684E-8f, + -2.51223623787020892529E-7f, + -3.88256480887769039346E-6f, + -1.10588938762623716291E-4f, + -9.76109749136146840777E-3f, + 7.78576235018280120474E-1f}; + + const auto out = + chbevl(32. / x - 2., coefficients, 7) / ::metal::precise::sqrt(x); + return static_cast(_x < 0. ? -out : out); +} + +// gamma, lgamma +template +inline float log_gamma(const T); + +/* + * The gamma function approximations follow John D Cook's + * c++ implementation: https://www.johndcook.com/Gamma.cpp. + * (BSD License) + */ +template +inline float gamma(const T x) { + if (x < 0.001) { + constexpr float EULER_MASCHERONI = 0.577215664901532860606512090; + // For small x, 1/gamma(x) has power series x + gamma x^2 - ... + // So in this range, 1/gamma(x) = x + gamma x^2 with error on the order of + // x^3. The relative error over this interval is less than 6e-7. + + return 1.0 / (x * (1.0 + EULER_MASCHERONI * x)); + } + if (x >= 12.0) { + return ::metal::exp(log_gamma(x)); + } + // The algorithm directly approximates gamma over (1,2) and uses + // reduction identities to reduce other arguments to this interval. + // numerator coefficients for gamma approximation over the interval (1,2) + constexpr float GAMMA_NUMERATOR_COEF[8] = { + -1.71618513886549492533811E+0, + 2.47656508055759199108314E+1, + -3.79804256470945635097577E+2, + 6.29331155312818442661052E+2, + 8.66966202790413211295064E+2, + -3.14512729688483675254357E+4, + -3.61444134186911729807069E+4, + 6.64561438202405440627855E+4}; + + // denominator coefficients for gamma approximation over the interval (1,2) + constexpr float GAMMA_DENOMINATOR_COEF[8] = { + -3.08402300119738975254353E+1, + 3.15350626979604161529144E+2, + -1.01515636749021914166146E+3, + -3.10777167157231109440444E+3, + 2.25381184209801510330112E+4, + 4.75584627752788110767815E+3, + -1.34659959864969306392456E+5, + -1.15132259675553483497211E+5}; + + // Add or subtract integers as necessary to bring y into (1,2) + float y = 1.0 + ::metal::fract(x); + + float num = 0.0; + float den = 1.0; + + float z = y - 1; + for (int i = 0; i < 8; i++) { + num = (num + GAMMA_NUMERATOR_COEF[i]) * z; + den = den * z + GAMMA_DENOMINATOR_COEF[i]; + } + float result = num / den + 1.0; + + // Apply correction if argument was not initially in (1,2) + if (x < 1.0) { + // identity gamma(z) = gamma(z+1)/z + result /= (y - 1.0); + } else { + // identity gamma(z+n) = z*(z+1)* ... *(z+n-1)*gamma(z) + auto n = static_cast(::metal::floor(x)); + for (int i = 1; i < n; i++) { + result *= y++; + } + } + + return result; +} + +template +inline float log_gamma(const T x) { + constexpr float LOG_PI = 1.14472988584940017414342735135305; + constexpr float HALF_LOG_TWO_PI = 0.91893853320467274178032973640562; + constexpr float LGAMMA_EXPANSION_COEF[8] = { + 1.0 / 12.0, + -1.0 / 360.0, + 1.0 / 1260.0, + -1.0 / 1680.0, + 1.0 / 1188.0, + -691.0 / 360360.0, + 1.0 / 156.0, + -3617.0 / 122400.0}; + + float rc; + + const auto abs_x = ::metal::abs(static_cast(x)); + if (abs_x == 0) { + return INFINITY; + } + if (abs_x < 12.0) { + rc = ::metal::log(::metal::abs(gamma(abs_x))); + } else { + // Abramowitz and Stegun 6.1.41 + // Asymptotic series should be good to at least 11 or 12 figures + // For error analysis, see Whittiker and Watson + // A Course in Modern Analysis (1927), page 252 + + float z = 1.0 / (abs_x * abs_x); + float sum = LGAMMA_EXPANSION_COEF[7]; + + for (int i = 6; i >= 0; i--) { + sum *= z; + sum += LGAMMA_EXPANSION_COEF[i]; + } + float series = sum / abs_x; + + rc = (abs_x - 0.5) * ::metal::log(abs_x) - abs_x + HALF_LOG_TWO_PI + series; + } + + if (x >= 0) { + return rc; + } + + // Reflection formula + // Compute arg first to workaround Metal compiler bgg of sorts on M4 + // See https://github.com/pytorch/pytorch/pull/145740 for more details + auto log_arg = abs_x * ::metal::abs(::metal::sinpi(abs_x)); + return LOG_PI - rc - ::metal::log(log_arg); +} + +inline float zeta(float x, float q) { + constexpr float MACHEP = 1.11022302462515654042E-16; + constexpr float ZETA_EXPANSION[] = { + 12.0, + -720.0, + 30240.0, + -1209600.0, + 47900160.0, + -1.8924375803183791606e9, + 7.47242496e10, + -2.950130727918164224e12, + 1.1646782814350067249e14, + -4.5979787224074726105e15, + 1.8152105401943546773e17, + -7.1661652561756670113e18}; + if (x == 1.0f) { + return INFINITY; + } + + if (x < 1.0f) { + return NAN; + } + + if (q <= 0.0f) { + if (q == ::metal::trunc(q)) { + return INFINITY; + } + if (x != ::metal::trunc(x)) { + return NAN; + } + } + + float s = ::metal::pow(q, -x); + float a = q; + int i = 0; + float b = 0.0f; + while ((i < 9) || (a <= 9.0f)) { + i += 1; + a += 1.0f; + b = ::metal::pow(a, -x); + s += b; + if ((-MACHEP * s < b) && (b < MACHEP * s)) { + return s; + } + } + + float w = a; + s += b * w / (x - 1.0f); + s -= 0.5f * b; + a = 1.0f; + float t; + float k = 0.0f; + for (int i = 0; i < 12; i++) { + a *= x + k; + b /= w; + t = a * b / ZETA_EXPANSION[i]; + s += t; + t = ::metal::fabs(t / s); + if (t < MACHEP) { + return s; + } + k += 1.0f; + a *= x + k; + b /= w; + k += 1.0f; + } + return s; +} + +inline float calc_digamma_positive_domain(float x) { + constexpr float DIGAMMA_COEF[7] = { + 8.33333333333333333333E-2, + -2.10927960927960927961E-2, + 7.57575757575757575758E-3, + -4.16666666666666666667E-3, + 3.96825396825396825397E-3, + -8.33333333333333333333E-3, + 8.33333333333333333333E-2, + }; + + // Push x to be >= 10 + float result = 0; + while (x < 10) { + result -= 1 / x; + x += 1; + } + if (x == 10) { + constexpr float PSI_10 = 2.25175258906672110764; + return result + PSI_10; + } + + // Compute asymptotic digamma + float y = 0; + if (x < 1.0E+17) { + float z = 1.0 / (x * x); + for (int i = 0; i <= 6; i++) { + y += ::metal::pow(z, i) * DIGAMMA_COEF[i]; + } + y *= z; + } + return result + ::metal::log(x) - (0.5 / x) - y; +} + +/* + * The digamma kernel and helper function is derived from the pytorch cpu + * of this function, which is itself derived from the implementation + * of the digamma function in the Cephes Math Library. + * See note [3-Clause BSD License for the Cephes Math Library]. + */ +template +inline float digamma(T0 x) { + if (x < 0.0f) { + if (x == ::metal::trunc(x)) { + // As per C++ standard for gamma related functions and SciPy, + // If the argument is a negative integer, NaN is returned + return NAN; + } else { + // Extracts the fractional part of x as r, since tan(pi * r) is more + // numerically accurate than tan(pi * x). While these operations are + // mathematically equivalent since both x and r are in radians and tan() + // has a periodicity of pi, in practice the computation of pi * x is a + // source of error (when |x| > 1). + float r = ::metal::fract(x); + return calc_digamma_positive_domain(1.0f - x) - + M_PI_F / ::metal::tan(M_PI_F * r); + } + } else if (x == 0.0f) { + // As per C++ standard for gamma related functions and SciPy, + // If the argument is ±0, ±∞ is returned + return ::metal::copysign(INFINITY, static_cast(-x)); + } else { + return calc_digamma_positive_domain(x); + } +} + +template +inline float polygamma(const int64_t order, const T0 input) { + // Filter out n == 0. + if (order == 0) { + return digamma(input); + } + + float x = input; + float n = order; + float sgn = ((order % 2) ? 1 : -1); + return sgn * gamma(n + 1) * zeta(n + 1, x); +} + +template +float trigamma(T x) { + float sign = 1.0f; + float result = 0.0f; + + if (x < 0.0f) { + sign = -1.0f; + auto sin_pi_x = sin(M_PI_F * x); + result -= (M_PI_F * M_PI_F) / (sin_pi_x * sin_pi_x); + x = 1.0f - x; + } else if (x == 0.0) { + return INFINITY; + } else if (x < 1.0) { + result += 1.0 / (x * x); + x += 1.0f; + } + + for (int i = 0; i < 6; ++i) { + result += 1.0f / (x * x); + x += 1.0f; + } + + const float ixx = 1.0f / (x * x); + result += + (1.0f + 1.0f / (2.0f * x) + + ixx * ((1.0f / 6.0f) - ixx * ((1.0f / 30.0f) - ixx * (1.0f / 42.0f)))) / + x; + return sign * result; +} + +template +inline ::metal::enable_if_t, T> sinc(T a) { + if (a == static_cast(0)) { + return static_cast(1); + } + auto product = M_PI_F * static_cast(a); + return static_cast(::metal::precise::sin(product) / product); +} + +// Complex sinc2 implementation +template +inline ::metal::enable_if_t, T> sinc(T inp) { + auto a = static_cast(inp) * M_PI_F; + const float a2 = a.x * a.x + a.y * a.y; + if (a2 == 0) { + return 0; + } + float cosx; + float sinx = ::metal::sincos(a.x, cosx); + float sinhy = ::metal::sinh(a.y); + float coshy = ::metal::cosh(a.y); + auto re = sinx * coshy * a.x + cosx * sinhy * a.y; + auto im = cosx * sinhy * a.x - sinx * coshy * a.y; + return T(re, im) / a2; +} + +template +inline T spherical_bessel_j0(T x) { + if (::metal::isinf(x)) + return T(0.0); + T x2 = x * x; + T k1 = static_cast(-1.0); + T k2 = static_cast(1.0); + + if (::metal::fabs(static_cast(x)) < T(0.5)) { + return T(1.0) + + x2 * + (k1 / T(6.0) + + x2 * + (k2 / T(120.0) + + x2 * + (k1 / T(5040.0) + + x2 * + (k2 / T(362880.0) + + x2 * + (k1 / T(39916800.0) + + x2 * (k2 / T(6227020800.0))))))); + } + + return static_cast(::metal::sin(x) / x); +} + +template +inline ::metal::enable_if_t, T> logaddexp( + T a, + T b) { + float a0 = static_cast(a); + float b0 = static_cast(b); + if (::metal::isinf(a0) && a0 == b0) { + return static_cast(a0); + } else { + float m0 = ::metal::max(a0, b0); + return static_cast( + m0 + ::c10::metal::log1p(::metal::exp(-::metal::abs(a0 - b0)))); + } +} + +// The function is ported from mlx +template +inline ::metal::enable_if_t, T> logaddexp(T a, T b) { + if (::metal::isnan(a.x) || ::metal::isnan(a.y) || ::metal::isnan(b.x) || + ::metal::isnan(b.y)) { + return T(NAN, NAN); + } + + T maxval = a.x > b.x ? a : b; + T minval = a.x < b.x ? a : b; + constexpr auto inf = ::metal::numeric_limits::infinity().x; + + if (minval.x == -inf || maxval.x == inf) { + return maxval; + } + + float2 maxval_ = static_cast(maxval); + float2 minval_ = static_cast(minval); + float m = ::metal::exp(minval_.x - maxval_.x); + float2 dexp{ + m * ::metal::cos(minval_.y - maxval_.y), + m * ::metal::sin(minval_.y - maxval_.y), + }; + return static_cast(maxval_ + ::c10::metal::log1p(dexp)); +} + +template +inline T logaddexp2(T a, T b) { + constexpr auto log_2 = float(0.693147180559945309417232121458176); + constexpr auto inv_log_2 = float(1) / log_2; + float a0 = static_cast(a); + float b0 = static_cast(b); + if (::metal::isinf(a0) && a0 == b0) { + return static_cast(a0); + } else { + float m0 = ::metal::max(a0, b0); + return static_cast( + m0 + + ::c10::metal::log1p(::metal::pow(float(2), -::metal::abs(a0 - b0))) * + inv_log_2); + } +} + +template +inline float xlogy(T x, T y) { + if (::metal::isnan(y)) { + return NAN; + } + + if (x == 0) { + return x; + } + + return x * precise::log(float(y)); +} + +template +inline float xlog1py(T x, T y) { + if (::metal::isnan(y)) { + return NAN; + } + + if (x == 0) { + return x; + } + + return x * ::c10::metal::log1p(y); +} + +template +inline T entr(T a) { + if (a != a) { + return a; + } + + if (a > 0) { + return static_cast(-a * ::metal::log(a)); + } + + if (a == 0) { + return 0; + } + + return static_cast(-INFINITY); +} + +// Copy-n-paste from aten/src/ATen/native/cuda/Math.cuh lines 1463-1915 +template +inline float bessel_j0_forward(T x) { + constexpr float PP[] = { + +7.96936729297347051624e-04, + +8.28352392107440799803e-02, + +1.23953371646414299388e+00, + +5.44725003058768775090e+00, + +8.74716500199817011941e+00, + +5.30324038235394892183e+00, + +9.99999999999999997821e-01, + }; + + constexpr float PQ[] = { + +9.24408810558863637013e-04, + +8.56288474354474431428e-02, + +1.25352743901058953537e+00, + +5.47097740330417105182e+00, + +8.76190883237069594232e+00, + +5.30605288235394617618e+00, + +1.00000000000000000218e+00, + }; + + constexpr float QP[] = { + -1.13663838898469149931e-02, + -1.28252718670509318512e+00, + -1.95539544257735972385e+01, + -9.32060152123768231369e+01, + -1.77681167980488050595e+02, + -1.47077505154951170175e+02, + -5.14105326766599330220e+01, + -6.05014350600728481186e+00, + }; + + constexpr float QQ[] = { + +6.43178256118178023184e+01, + +8.56430025976980587198e+02, + +3.88240183605401609683e+03, + +7.24046774195652478189e+03, + +5.93072701187316984827e+03, + +2.06209331660327847417e+03, + +2.42005740240291393179e+02, + }; + + constexpr float RP[] = { + -4.79443220978201773821e+09, + +1.95617491946556577543e+12, + -2.49248344360967716204e+14, + +9.70862251047306323952e+15, + }; + + constexpr float RQ[] = { + +4.99563147152651017219e+02, + +1.73785401676374683123e+05, + +4.84409658339962045305e+07, + +1.11855537045356834862e+10, + +2.11277520115489217587e+12, + +3.10518229857422583814e+14, + +3.18121955943204943306e+16, + +1.71086294081043136091e+18, + }; + + if (x < T(0)) { + x = -x; + } + + if (x <= T(5.0)) { + if (x < T(0.00001)) { + return 1.0 - x * x / 4.0; + } + + float rp = 0.0; + + for (auto index = 0; index <= 3; index++) { + rp = rp * (x * x) + RP[index]; + } + + float rq = 0.0; + + for (auto index = 0; index <= 7; index++) { + rq = rq * (x * x) + RQ[index]; + } + + return (x * x - 5.78318596294678452118e+00) * + (x * x - T(3.04712623436620863991e+01)) * rp / rq; + } + + float pp = 0.0; + + for (auto index = 0; index <= 6; index++) { + pp = pp * (25.0 / (x * x)) + PP[index]; + } + + float pq = 0.0; + + for (auto index = 0; index <= 6; index++) { + pq = pq * (25.0 / (x * x)) + PQ[index]; + } + + float qp = 0.0; + + for (auto index = 0; index <= 7; index++) { + qp = qp * (25.0 / (x * x)) + QP[index]; + } + + float qq = 0.0; + + for (auto index = 0; index <= 6; index++) { + qq = qq * (25.0 / (x * x)) + QQ[index]; + } + + return (pp / pq * + ::metal::precise::cos( + x - T(0.785398163397448309615660845819875721)) - + 5.0 / x * (qp / qq) * + ::metal::precise::sin( + x - 0.785398163397448309615660845819875721)) * + 0.797884560802865355879892119868763737 / ::metal::precise::sqrt(x); +} // bessel_j0_forward(T x) + +template +inline float bessel_y0_forward(T x) { + constexpr float PP[] = { + +7.96936729297347051624e-04, + +8.28352392107440799803e-02, + +1.23953371646414299388e+00, + +5.44725003058768775090e+00, + +8.74716500199817011941e+00, + +5.30324038235394892183e+00, + +9.99999999999999997821e-01, + }; + + constexpr float PQ[] = { + +9.24408810558863637013e-04, + +8.56288474354474431428e-02, + +1.25352743901058953537e+00, + +5.47097740330417105182e+00, + +8.76190883237069594232e+00, + +5.30605288235394617618e+00, + +1.00000000000000000218e+00, + }; + + constexpr float QP[] = { + -1.13663838898469149931e-02, + -1.28252718670509318512e+00, + -1.95539544257735972385e+01, + -9.32060152123768231369e+01, + -1.77681167980488050595e+02, + -1.47077505154951170175e+02, + -5.14105326766599330220e+01, + -6.05014350600728481186e+00, + }; + + constexpr float QQ[] = { + +6.43178256118178023184e+01, + +8.56430025976980587198e+02, + +3.88240183605401609683e+03, + +7.24046774195652478189e+03, + +5.93072701187316984827e+03, + +2.06209331660327847417e+03, + +2.42005740240291393179e+02, + }; + + constexpr float YP[] = { + +1.55924367855235737965e+04, + -1.46639295903971606143e+07, + +5.43526477051876500413e+09, + -9.82136065717911466409e+11, + +8.75906394395366999549e+13, + -3.46628303384729719441e+15, + +4.42733268572569800351e+16, + -1.84950800436986690637e+16, + }; + + constexpr float YQ[] = { + +1.04128353664259848412e+03, + +6.26107330137134956842e+05, + +2.68919633393814121987e+08, + +8.64002487103935000337e+10, + +2.02979612750105546709e+13, + +3.17157752842975028269e+15, + +2.50596256172653059228e+17, + }; + + if (x <= T(5.0)) { + if (x == T(0.0)) { + return -INFINITY; + } + + if (x < T(0.0)) { + return NAN; + } + + float yp = 0.0; + + for (auto index = 0; index <= 7; index++) { + yp = yp * (x * x) + YP[index]; + } + + float yq = 0.0; + + for (auto index = 0; index <= 6; index++) { + yq = yq * (x * x) + YQ[index]; + } + + return yp / yq + + (0.636619772367581343075535053490057448 * ::metal::precise::log(x) * + bessel_j0_forward(x)); + } + + float pp = 0.0; + + for (auto index = 0; index <= 6; index++) { + pp = pp * (25.0 / (x * x)) + PP[index]; + } + + float pq = 0.0; + + for (auto index = 0; index <= 6; index++) { + pq = pq * (25.0 / (x * x)) + PQ[index]; + } + + float qp = 0.0; + + for (auto index = 0; index <= 7; index++) { + qp = qp * (25.0 / (x * x)) + QP[index]; + } + + float qq = 0.0; + + for (auto index = 0; index <= 6; index++) { + qq = qq * (25.0 / (x * x)) + QQ[index]; + } + + return (pp / pq * + ::metal::precise::sin( + x - 0.785398163397448309615660845819875721) + + 5.0 / x * (qp / qq) * + ::metal::precise::cos( + x - 0.785398163397448309615660845819875721)) * + 0.797884560802865355879892119868763737 / ::metal::precise::sqrt(x); +} // bessel_y0_forward(T x) + +template +inline float bessel_j1_forward(T x) { + constexpr float PP[] = { + +7.62125616208173112003e-04, + +7.31397056940917570436e-02, + +1.12719608129684925192e+00, + +5.11207951146807644818e+00, + +8.42404590141772420927e+00, + +5.21451598682361504063e+00, + +1.00000000000000000254e+00, + }; + + constexpr float PQ[] = { + +5.71323128072548699714e-04, + +6.88455908754495404082e-02, + +1.10514232634061696926e+00, + +5.07386386128601488557e+00, + +8.39985554327604159757e+00, + +5.20982848682361821619e+00, + +9.99999999999999997461e-01, + }; + + constexpr float QP[] = { + +5.10862594750176621635e-02, + +4.98213872951233449420e+00, + +7.58238284132545283818e+01, + +3.66779609360150777800e+02, + +7.10856304998926107277e+02, + +5.97489612400613639965e+02, + +2.11688757100572135698e+02, + +2.52070205858023719784e+01, + }; + + constexpr float QQ[] = { + +7.42373277035675149943e+01, + +1.05644886038262816351e+03, + +4.98641058337653607651e+03, + +9.56231892404756170795e+03, + +7.99704160447350683650e+03, + +2.82619278517639096600e+03, + +3.36093607810698293419e+02, + }; + + constexpr float RP[] = { + -8.99971225705559398224e+08, + +4.52228297998194034323e+11, + -7.27494245221818276015e+13, + +3.68295732863852883286e+15, + }; + + constexpr float RQ[] = { + +6.20836478118054335476e+02, + +2.56987256757748830383e+05, + +8.35146791431949253037e+07, + +2.21511595479792499675e+10, + +4.74914122079991414898e+12, + +7.84369607876235854894e+14, + +8.95222336184627338078e+16, + +5.32278620332680085395e+18, + }; + + if (x < T(0.0)) { + return -bessel_j1_forward(-x); + } + + if (x <= T(5.0)) { + float rp = 0.0; + + for (auto index = 0; index <= 3; index++) { + rp = rp * (x * x) + RP[index]; + } + + float rq = 0.0; + + for (auto index = 0; index <= 7; index++) { + rq = rq * (x * x) + RQ[index]; + } + + return rp / rq * x * (x * x - 1.46819706421238932572e+01) * + (x * x - 4.92184563216946036703e+01); + } + + float pp = 0.0; + + for (auto index = 0; index <= 6; index++) { + pp = pp * (5.0 / x * (5.0 / x)) + PP[index]; + } + + float pq = 0.0; + + for (auto index = 0; index <= 6; index++) { + pq = pq * (5.0 / x * (5.0 / x)) + PQ[index]; + } + + float qp = 0.0; + + for (auto index = 0; index <= 7; index++) { + qp = qp * (5.0 / x * (5.0 / x)) + QP[index]; + } + + float qq = 0.0; + + for (auto index = 0; index <= 6; index++) { + qq = qq * (5.0 / x * (5.0 / x)) + QQ[index]; + } + + return (pp / pq * + ::metal::precise::cos( + x - 2.356194490192344928846982537459627163) - + 5.0 / x * (qp / qq) * + ::metal::precise::sin( + x - 2.356194490192344928846982537459627163)) * + 0.797884560802865355879892119868763737 / ::metal::precise::sqrt(x); +} // bessel_j1_forward(T x) + +template +inline float bessel_y1_forward(T x) { + constexpr float PP[] = { + +7.62125616208173112003e-04, + +7.31397056940917570436e-02, + +1.12719608129684925192e+00, + +5.11207951146807644818e+00, + +8.42404590141772420927e+00, + +5.21451598682361504063e+00, + +1.00000000000000000254e+00, + }; + + constexpr float PQ[] = { + +5.71323128072548699714e-04, + +6.88455908754495404082e-02, + +1.10514232634061696926e+00, + +5.07386386128601488557e+00, + +8.39985554327604159757e+00, + +5.20982848682361821619e+00, + +9.99999999999999997461e-01, + }; + + constexpr float QP[] = { + +5.10862594750176621635e-02, + +4.98213872951233449420e+00, + +7.58238284132545283818e+01, + +3.66779609360150777800e+02, + +7.10856304998926107277e+02, + +5.97489612400613639965e+02, + +2.11688757100572135698e+02, + +2.52070205858023719784e+01, + }; + + constexpr float QQ[] = { + +7.42373277035675149943e+01, + +1.05644886038262816351e+03, + +4.98641058337653607651e+03, + +9.56231892404756170795e+03, + +7.99704160447350683650e+03, + +2.82619278517639096600e+03, + +3.36093607810698293419e+02, + }; + + constexpr float YP[] = { + +1.26320474790178026440e+09, + -6.47355876379160291031e+11, + +1.14509511541823727583e+14, + -8.12770255501325109621e+15, + +2.02439475713594898196e+17, + -7.78877196265950026825e+17, + }; + + constexpr float YQ[] = { + +5.94301592346128195359e+02, + +2.35564092943068577943e+05, + +7.34811944459721705660e+07, + +1.87601316108706159478e+10, + +3.88231277496238566008e+12, + +6.20557727146953693363e+14, + +6.87141087355300489866e+16, + +3.97270608116560655612e+18, + }; + + if (x <= T(5.0)) { + if (x == T(0.0)) { + return -INFINITY; + } + + if (x <= T(0.0)) { + return NAN; + } + + float yp = 0.0; + + for (auto index = 0; index <= 5; index++) { + yp = yp * (x * x) + YP[index]; + } + + float yq = 0.0; + + for (auto index = 0; index <= 7; index++) { + yq = yq * (x * x) + YQ[index]; + } + + return x * (yp / yq) + + (0.636619772367581343075535053490057448 * + (bessel_j1_forward(x) * ::metal::precise::log(x) - 1.0 / x)); + } + + float pp = 0.0; + + for (auto index = 0; index <= 6; index++) { + pp = pp * (5.0 / x * (5.0 / x)) + PP[index]; + } + + float pq = 0.0; + + for (auto index = 0; index <= 6; index++) { + pq = pq * (5.0 / x * (5.0 / x)) + PQ[index]; + } + + float qp = 0.0; + + for (auto index = 0; index <= 7; index++) { + qp = qp * (5.0 / x * (5.0 / x)) + QP[index]; + } + + float qq = 0.0; + + for (auto index = 0; index <= 6; index++) { + qq = qq * (5.0 / x * (5.0 / x)) + QQ[index]; + } + + return (pp / pq * + ::metal::precise::sin( + x - 2.356194490192344928846982537459627163) + + 5.0 / x * (qp / qq) * + ::metal::precise::cos( + x - 2.356194490192344928846982537459627163)) * + 0.797884560802865355879892119868763737 / ::metal::precise::sqrt(x); +} // bessel_y1_forward(T x) + +template +inline float modified_bessel_i0_forward(T x) { + constexpr float A[] = { + -4.41534164647933937950e-18, +3.33079451882223809783e-17, + -2.43127984654795469359e-16, +1.71539128555513303061e-15, + -1.16853328779934516808e-14, +7.67618549860493561688e-14, + -4.85644678311192946090e-13, +2.95505266312963983461e-12, + -1.72682629144155570723e-11, +9.67580903537323691224e-11, + -5.18979560163526290666e-10, +2.65982372468238665035e-09, + -1.30002500998624804212e-08, +6.04699502254191894932e-08, + -2.67079385394061173391e-07, +1.11738753912010371815e-06, + -4.41673835845875056359e-06, +1.64484480707288970893e-05, + -5.75419501008210370398e-05, +1.88502885095841655729e-04, + -5.76375574538582365885e-04, +1.63947561694133579842e-03, + -4.32430999505057594430e-03, +1.05464603945949983183e-02, + -2.37374148058994688156e-02, +4.93052842396707084878e-02, + -9.49010970480476444210e-02, +1.71620901522208775349e-01, + -3.04682672343198398683e-01, +6.76795274409476084995e-01, + }; + + constexpr float B[] = { + -7.23318048787475395456e-18, -4.83050448594418207126e-18, + +4.46562142029675999901e-17, +3.46122286769746109310e-17, + -2.82762398051658348494e-16, -3.42548561967721913462e-16, + +1.77256013305652638360e-15, +3.81168066935262242075e-15, + -9.55484669882830764870e-15, -4.15056934728722208663e-14, + +1.54008621752140982691e-14, +3.85277838274214270114e-13, + +7.18012445138366623367e-13, -1.79417853150680611778e-12, + -1.32158118404477131188e-11, -3.14991652796324136454e-11, + +1.18891471078464383424e-11, +4.94060238822496958910e-10, + +3.39623202570838634515e-09, +2.26666899049817806459e-08, + +2.04891858946906374183e-07, +2.89137052083475648297e-06, + +6.88975834691682398426e-05, +3.36911647825569408990e-03, + +8.04490411014108831608e-01, + }; + + float p; + float q = 0.0; + + if (::metal::fabs(x) <= 8.0) { + float a = A[0]; + + for (uint8_t index = 1; index < 30; index++) { + p = q; + q = a; + a = (.5 * ::metal::fabs(x) - 2.0) * q - p + A[index]; + } + + return ::metal::exp(::metal::fabs(x)) * (T(0.5) * (a - p)); + } + + float b = B[0]; + + for (uint8_t index = 1; index < 25; index++) { + p = q; + q = b; + b = (32.0 / ::metal::fabs(x) - 2.0) * q - p + B[index]; + } + + return ::metal::exp(::metal::fabs(x)) * (.5 * (b - p)) / + ::metal::precise::sqrt(::metal::fabs(x)); +} // modified_bessel_i0_forward(T x) + +template +inline float modified_bessel_i1_forward(T x) { + constexpr float A[] = { + +2.77791411276104639959e-18, -2.11142121435816608115e-17, + +1.55363195773620046921e-16, -1.10559694773538630805e-15, + +7.60068429473540693410e-15, -5.04218550472791168711e-14, + +3.22379336594557470981e-13, -1.98397439776494371520e-12, + +1.17361862988909016308e-11, -6.66348972350202774223e-11, + +3.62559028155211703701e-10, -1.88724975172282928790e-09, + +9.38153738649577178388e-09, -4.44505912879632808065e-08, + +2.00329475355213526229e-07, -8.56872026469545474066e-07, + +3.47025130813767847674e-06, -1.32731636560394358279e-05, + +4.78156510755005422638e-05, -1.61760815825896745588e-04, + +5.12285956168575772895e-04, -1.51357245063125314899e-03, + +4.15642294431288815669e-03, -1.05640848946261981558e-02, + +2.47264490306265168283e-02, -5.29459812080949914269e-02, + +1.02643658689847095384e-01, -1.76416518357834055153e-01, + +2.52587186443633654823e-01, + }; + + constexpr float B[] = { + +7.51729631084210481353e-18, +4.41434832307170791151e-18, + -4.65030536848935832153e-17, -3.20952592199342395980e-17, + +2.96262899764595013876e-16, +3.30820231092092828324e-16, + -1.88035477551078244854e-15, -3.81440307243700780478e-15, + +1.04202769841288027642e-14, +4.27244001671195135429e-14, + -2.10154184277266431302e-14, -4.08355111109219731823e-13, + -7.19855177624590851209e-13, +2.03562854414708950722e-12, + +1.41258074366137813316e-11, +3.25260358301548823856e-11, + -1.89749581235054123450e-11, -5.58974346219658380687e-10, + -3.83538038596423702205e-09, -2.63146884688951950684e-08, + -2.51223623787020892529e-07, -3.88256480887769039346e-06, + -1.10588938762623716291e-04, -9.76109749136146840777e-03, + +7.78576235018280120474e-01, + }; + + float p; + float q = 0.0; + + if (::metal::fabs(x) <= T(8.0)) { + float a = A[0]; + + for (uint8_t index = 1; index < 29; index++) { + p = q; + q = a; + a = (.5 * ::metal::fabs(x) - 2.0) * q - p + A[index]; + } + + return .5 * (a - p) * x * ::metal::precise::exp(::metal::fabs(x)); + } + + float b = B[0]; + + for (uint8_t index = 1; index < 25; index++) { + p = q; + q = b; + b = (32.0 / ::metal::fabs(x) - 2.0) * q - p + B[index]; + } + + if (x < 0.0) { + return -( + ::metal::precise::exp(::metal::fabs(x)) * (0.5 * (b - p)) / + ::metal::precise::sqrt(::metal::fabs(x))); + } + + return ::metal::precise::exp(::metal::fabs(x)) * (0.5 * (b - p)) / + ::metal::precise::sqrt(::metal::fabs(x)); +} // modified_bessel_i1_forward(T x) + +template +inline float modified_bessel_k0_forward(T x) { + constexpr float A[] = { + +1.37446543561352307156e-16, + +4.25981614279661018399e-14, + +1.03496952576338420167e-11, + +1.90451637722020886025e-09, + +2.53479107902614945675e-07, + +2.28621210311945178607e-05, + +1.26461541144692592338e-03, + +3.59799365153615016266e-02, + +3.44289899924628486886e-01, + -5.35327393233902768720e-01, + }; + + constexpr float B[] = { + +5.30043377268626276149e-18, -1.64758043015242134646e-17, + +5.21039150503902756861e-17, -1.67823109680541210385e-16, + +5.51205597852431940784e-16, -1.84859337734377901440e-15, + +6.34007647740507060557e-15, -2.22751332699166985548e-14, + +8.03289077536357521100e-14, -2.98009692317273043925e-13, + +1.14034058820847496303e-12, -4.51459788337394416547e-12, + +1.85594911495471785253e-11, -7.95748924447710747776e-11, + +3.57739728140030116597e-10, -1.69753450938905987466e-09, + +8.57403401741422608519e-09, -4.66048989768794782956e-08, + +2.76681363944501510342e-07, -1.83175552271911948767e-06, + +1.39498137188764993662e-05, -1.28495495816278026384e-04, + +1.56988388573005337491e-03, -3.14481013119645005427e-02, + +2.44030308206595545468e+00, + }; + + if (x == 0.0) { + return INFINITY; + } + + if (x < 0.0) { + return NAN; + } + + float p; + float q = 0.0; + + if (x <= 2.0) { + float a = A[0]; + + for (uint8_t index = 1; index < 10; index++) { + p = q; + q = a; + a = (x * x - 2.0) * q - p + A[index]; + } + + return 0.5 * (a - p) - + ::metal::log(0.5 * x) * modified_bessel_i0_forward(x); + } + + float b = B[0]; + + for (uint8_t index = 1; index < 25; index++) { + p = q; + q = b; + b = (8.0 / x - 2.0) * q - p + B[index]; + } + + return ::metal::exp(-x) * (0.5 * (b - p)) / ::metal::sqrt(x); +} // modified_bessel_k0_forward(T x) + +template +inline float modified_bessel_k1_forward(T x) { + constexpr float A[] = { + -7.02386347938628759343e-18, + -2.42744985051936593393e-15, + -6.66690169419932900609e-13, + -1.41148839263352776110e-10, + -2.21338763073472585583e-08, + -2.43340614156596823496e-06, + -1.73028895751305206302e-04, + -6.97572385963986435018e-03, + -1.22611180822657148235e-01, + -3.53155960776544875667e-01, + +1.52530022733894777053e+00, + }; + + constexpr float B[] = { + -5.75674448366501715755e-18, +1.79405087314755922667e-17, + -5.68946255844285935196e-17, +1.83809354436663880070e-16, + -6.05704724837331885336e-16, +2.03870316562433424052e-15, + -7.01983709041831346144e-15, +2.47715442448130437068e-14, + -8.97670518232499435011e-14, +3.34841966607842919884e-13, + -1.28917396095102890680e-12, +5.13963967348173025100e-12, + -2.12996783842756842877e-11, +9.21831518760500529508e-11, + -4.19035475934189648750e-10, +2.01504975519703286596e-09, + -1.03457624656780970260e-08, +5.74108412545004946722e-08, + -3.50196060308781257119e-07, +2.40648494783721712015e-06, + -1.93619797416608296024e-05, +1.95215518471351631108e-04, + -2.85781685962277938680e-03, +1.03923736576817238437e-01, + +2.72062619048444266945e+00, + }; + + if (x == 0.0) { + return INFINITY; + } + + if (x < 0.0) { + return NAN; + } + + float p; + float q = 0.0; + + if (x <= 2.0) { + float a = A[0]; + + for (uint8_t index = 1; index < 11; index++) { + p = q; + q = a; + a = (x * x - T(2.0)) * q - p + A[index]; + } + + return ::metal::precise::log(T(0.5) * x) * modified_bessel_i1_forward(x) + + 0.5 * (a - p) / x; + } + + float b = B[0]; + + for (uint8_t index = 1; index < 25; index++) { + p = q; + q = b; + b = (8.0 / x - 2.0) * q - p + B[index]; + } + + return ::metal::precise::exp(-x) * (0.5 * (b - p)) / + ::metal::precise::sqrt(x); +} + +template +inline float scaled_modified_bessel_k0_forward(T x) { + constexpr float A[] = { + +1.37446543561352307156e-16, + +4.25981614279661018399e-14, + +1.03496952576338420167e-11, + +1.90451637722020886025e-09, + +2.53479107902614945675e-07, + +2.28621210311945178607e-05, + +1.26461541144692592338e-03, + +3.59799365153615016266e-02, + +3.44289899924628486886e-01, + -5.35327393233902768720e-01, + }; + + constexpr float B[] = { + +5.30043377268626276149e-18, -1.64758043015242134646e-17, + +5.21039150503902756861e-17, -1.67823109680541210385e-16, + +5.51205597852431940784e-16, -1.84859337734377901440e-15, + +6.34007647740507060557e-15, -2.22751332699166985548e-14, + +8.03289077536357521100e-14, -2.98009692317273043925e-13, + +1.14034058820847496303e-12, -4.51459788337394416547e-12, + +1.85594911495471785253e-11, -7.95748924447710747776e-11, + +3.57739728140030116597e-10, -1.69753450938905987466e-09, + +8.57403401741422608519e-09, -4.66048989768794782956e-08, + +2.76681363944501510342e-07, -1.83175552271911948767e-06, + +1.39498137188764993662e-05, -1.28495495816278026384e-04, + +1.56988388573005337491e-03, -3.14481013119645005427e-02, + +2.44030308206595545468e+00, + }; + + if (x == 0.0) { + return INFINITY; + } + + if (x < 0.0) { + return NAN; + } + + float p; + float q = 0.0; + + if (x <= 2.0) { + float a = A[0]; + + for (uint8_t index = 1; index < 10; index++) { + p = q; + q = a; + a = (x * x - T(2.0)) * q - p + A[index]; + } + + return (0.5 * (a - p) - + ::metal::precise::log(0.5 * x) * modified_bessel_i0_forward(x)) * + ::metal::precise::exp(x); + } + + float b = B[0]; + + for (uint8_t index = 1; index < 25; index++) { + p = q; + q = b; + b = (8.0 / x - 2.0) * q - p + B[index]; + } + + return 0.5 * (b - p) / ::metal::precise::sqrt(x); +} + +template +inline float scaled_modified_bessel_k1_forward(T x) { + constexpr float A[] = { + -7.02386347938628759343e-18, + -2.42744985051936593393e-15, + -6.66690169419932900609e-13, + -1.41148839263352776110e-10, + -2.21338763073472585583e-08, + -2.43340614156596823496e-06, + -1.73028895751305206302e-04, + -6.97572385963986435018e-03, + -1.22611180822657148235e-01, + -3.53155960776544875667e-01, + +1.52530022733894777053e+00, + }; + + constexpr float B[] = { + -5.75674448366501715755e-18, +1.79405087314755922667e-17, + -5.68946255844285935196e-17, +1.83809354436663880070e-16, + -6.05704724837331885336e-16, +2.03870316562433424052e-15, + -7.01983709041831346144e-15, +2.47715442448130437068e-14, + -8.97670518232499435011e-14, +3.34841966607842919884e-13, + -1.28917396095102890680e-12, +5.13963967348173025100e-12, + -2.12996783842756842877e-11, +9.21831518760500529508e-11, + -4.19035475934189648750e-10, +2.01504975519703286596e-09, + -1.03457624656780970260e-08, +5.74108412545004946722e-08, + -3.50196060308781257119e-07, +2.40648494783721712015e-06, + -1.93619797416608296024e-05, +1.95215518471351631108e-04, + -2.85781685962277938680e-03, +1.03923736576817238437e-01, + +2.72062619048444266945e+00, + }; + + if (x == 0.0) { + return INFINITY; + } + + if (x < 0.0) { + return NAN; + } + + float p; + float q = 0.0; + + if (x <= 2.0) { + float a = A[0]; + + for (uint8_t index = 1; index < 11; index++) { + p = q; + q = a; + a = (x * x - 2.0) * q - p + A[index]; + } + + return (::metal::precise::log(0.5 * x) * modified_bessel_i1_forward(x) + + 0.5 * (a - p) / x) * + ::metal::precise::exp(x); + } + + float b = B[0]; + + for (uint8_t index = 1; index < 25; index++) { + p = q; + q = b; + b = (8.0 / x - 2.0) * q - p + B[index]; + } + + return (0.5 * (b - p) / ::metal::precise::sqrt(x)); +} + +template +float chebyshev_polynomial_t_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (::metal::fabs(x) == 1.0) { + if (x > 0.0 || n % 2 == 0) { + return 1.0; + } + + return -1.0; + } + + if ((n > 6) && (::metal::precise::fabs(x) < 1.0)) { + return ::metal::precise::cos(n * ::metal::precise::acos(x)); + } + + if (n == 0) { + return 1.0; + } + + if (n == 1) { + return x; + } + + float p = 1.0; + float q = x; + float r; + + for (int64_t k = 2; (k <= n) && !::metal::isnan(q); k++) { + r = (x + x) * q - p; + p = q; + q = r; + } + return r; +} + +template +float chebyshev_polynomial_u_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (::metal::fabs(x) == 1.0) { + if (x > 0.0 || n % 2 == 0) { + return n + 1; + } + + return -(n + 1); + } + + if ((n > 8) && (::metal::fabs(x) < 1.0)) { + const auto acos_x = ::metal::precise::acos(x); + if (::metal::precise::sin(acos_x) != 0.0) { + return ::metal::precise::sin((n + 1) * acos_x) / + ::metal::precise::sin(acos_x); + } + + return (n + 1) * ::metal::precise::cos((n + 1) * acos_x) / x; + } + + if (n == 0) { + return 1.0; + } + + auto q = 2.0 * x; + if (n == 1) { + return q; + } + + auto p = 1.0; + float r; + + for (int64_t k = 2; (k <= n) && !::metal::isnan(q); k++) { + r = 2 * x * q - p; + p = q; + q = r; + } + + return r; +} + +template +float chebyshev_polynomial_v_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (::metal::fabs(x) == 1.0) { + if (x > 0.0) { + return 1.0; + } + + if (n % 2 == 0) { + return n + n + 1; + } + + return -(n + n + 1); + } + + if ((n > 8) && (::metal::fabs(x) < 1.0)) { + const auto acos_x = ::metal::precise::acos(x); + if (::metal::precise::sin(.5 * acos_x) != 1.0) { + return ::metal::precise::cos((n + 0.5) * acos_x) / + ::metal::precise::cos(.5 * acos_x); + } + + if (n % 2 == 0) { + return n + n + 1; + } + + return -(n + n + 1); + } + + if (n == 0) { + return 1.0; + } + + auto q = 2.0 * x - 1.0; + if (n == 1) { + return q; + } + + auto p = 1.0; + float r; + + for (int64_t k = 2; (k <= n) && !::metal::isnan(q); k++) { + r = 2 * x * q - p; + p = q; + q = r; + } + + return r; +} // chebyshev_polynomial_v_forward(T x, int64_t n) + +template +float chebyshev_polynomial_w_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (::metal::fabs(x) == 1.0) { + if (x > 0.0) { + return n + n + 1; + } + + if (n % 2 == 0) { + return 1.0; + } + + return -1.0; + } + + if ((n > 8) && (::metal::fabs(x) < 1.0)) { + const auto acos_x = ::metal::precise::acos(x); + if (::metal::precise::cos(.5 * acos_x) != 1.0) { + return ::metal::precise::sin((n + 0.5) * acos_x) / + ::metal::precise::sin(.5 * acos_x); + } + + if (x > 0.0) { + return n + n + 1; + } + + if (n % 2 == 0) { + return 1.0; + } + + return -1.0; + } + + if (n == 0) { + return 1.0; + } + + auto q = 2.0 * x + 1.0; + if (n == 1) { + return q; + } + + auto p = 1.0; + float r; + + for (int64_t k = 2; (k <= n) && !::metal::isnan(q); k++) { + r = 2.0 * x * q - p; + p = q; + q = r; + } + + return r; +} // chebyshev_polynomial_w_forward(T x, int64_t n) + +template +float shifted_chebyshev_polynomial_t_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (x == T(1.0)) { + return 1.0; + } + + if (x == 0.0) { + if (n % 2 == 0) { + return 1.0; + } + + return -1.0; + } + + const float xpxm1 = x + x - 1.0; + if ((n > 6) && (::metal::abs(xpxm1) < 1.0)) { + return ::metal::precise::cos(n * ::metal::precise::acos(xpxm1)); + } + + if (n == 0) { + return 1.0; + } + + if (n == 1) { + return xpxm1; + } + + float p = 1.0; + float q = xpxm1; + float r; + + for (int64_t k = 2; (k <= n) && !::metal::isnan(q); k++) { + r = (xpxm1 + xpxm1) * q - p; + p = q; + q = r; + } + + return r; +} // shifted_chebyshev_polynomial_t_forward(T x, int64_t n) + +template +float shifted_chebyshev_polynomial_u_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (x == 1.0) { + return n + 1; + } + + if (x == 0.0) { + if (n % 2 == 0) { + return n + 1; + } + + return -(n + 1); + } + const float xpxm1 = x + x - 1.0; + if ((n > 6) && (::metal::abs(xpxm1) < 1.0)) { + const float acos_2xm1 = ::metal::precise::acos(xpxm1); + const float divisor = ::metal::precise::sin(acos_2xm1); + if (divisor != 0.0) { + return ::metal::precise::sin((n + 1) * acos_2xm1) / divisor; + } + + return (n + 1) * ::metal::precise::cos((n + 1) * acos_2xm1) / xpxm1; + } + + if (n == 0) { + return 1.0; + } + + if (n == 1) { + return xpxm1 + xpxm1; + } + + float p = 1.0; + float q = xpxm1 + xpxm1; + float r; + + for (int64_t k = 2; (k <= n) && !::metal::isnan(q); k++) { + r = (xpxm1 + xpxm1) * q - p; + p = q; + q = r; + } + + return r; +} // shifted_chebyshev_polynomial_u_forward(T x, int64_t n) + +template +float shifted_chebyshev_polynomial_v_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (x == 1.0) { + return 1.0; + } + + if (x == 0.0) { + if (n % 2 == 0) { + return (n + n + 1); + } + + return -(n + n + 1); + } + + const float xpxm1 = x + x - 1.0; + if ((n > 6) && (::metal::abs(xpxm1) < 1.0)) { + const float acos_2xm1 = ::metal::precise::acos(xpxm1); + if (::metal::precise::sin(acos_2xm1 / 2.0) != 1.0) { + return ::metal::precise::cos((n + 0.5) * acos_2xm1) / + ::metal::precise::cos(acos_2xm1 / 2.0); + } + + if (n % 2 == 0) { + return n + n + 1; + } + + return -(n + n + 1); + } + + if (n == 0) { + return T(1.0); + } + + if (n == 1) { + return xpxm1 + xpxm1 - 1.0; + } + + float p = 1.0; + float q = xpxm1 + xpxm1 - 1.0; + float r; + + for (int64_t k = 2; (k <= n) && !::metal::isnan(q); k++) { + r = (xpxm1 + xpxm1) * q - p; + p = q; + q = r; + } + + return r; +} // shifted_chebyshev_polynomial_v_forward(T x, int64_t n) + +template +float shifted_chebyshev_polynomial_w_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (x == 1.0) { + return n + n + 1; + } + + if (x == 0.0) { + if (n % 2 == 0) { + return 1.0; + } + + return -1.0; + } + + const float xpxm1 = x + x - 1.0; + if ((n > 4) && (::metal::abs(xpxm1) < 1.0)) { + const float acos_2xm1 = ::metal::precise::acos(xpxm1); + if (::metal::precise::cos(acos_2xm1 / 2.0) != 1.0) { + return ::metal::precise::sin((n + 0.5) * acos_2xm1) / + ::metal::precise::sin(acos_2xm1 / 2.0); + } + + if (n % 2 == 0) { + return 1.0; + } + + return -1.0; + } + + if (n == 0) { + return 1.0; + } + + if (n == 1) { + return xpxm1 + xpxm1 + 1.0; + } + + float p = 1.0; + float q = xpxm1 + xpxm1 + 1.0; + float r; + + for (int64_t k = 2; (k <= n) && !::metal::isnan(q); k++) { + r = (xpxm1 + xpxm1) * q - p; + p = q; + q = r; + } + + return r; +} // shifted_chebyshev_polynomial_w_forward(T x, int64_t n) + +template +// TODO: Add 512 if/when double will be supported in Metal +inline constexpr int getHermitianLimit() { + return 128; +} + +template +inline float hermite_polynomial_h_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (n == 0) { + return 1.0; + } + + if (n == 1) { + return x + x; + } + + if (n > getHermitianLimit()) { + return NAN; + } + + float p = 1.0; + float q = x + x; + float r = 0.0; + + for (int64_t k = 2; k < n + n; k += 2) { + r = (x + x) * q - k * p; + p = q; + q = r; + } + + return r; +} // hermite_polynomial_h_forward(T x, int64_t n) + +template +inline float hermite_polynomial_he_forward(T x, int64_t n) { + if (n < 0) { + return 0.0; + } + + if (n == 0) { + return 1.0; + } + + if (n == 1) { + return x; + } + + if (n > getHermitianLimit()) { + return NAN; + } + + float p = 1.0; + float q = x; + float r; + + for (int64_t k = 1; k < n; k++) { + r = x * q - k * p; + p = q; + q = r; + } + + return r; +} // hermite_polynomial_he_forward(T x, int64_t n) + +/* The next function is taken from http://ab-initio.mit.edu/faddeeva */ + +/* Copyright (c) 2012 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#define IMPL_ERFCX_Y100_CASE(X, A, B, C, D, E, F, G) \ + case X: { \ + const auto t = 2.0 * y100 - (2 * X + 1); \ + return A + (B + (C + (D + (E + (F + G * t) * t) * t) * t) * t) * t; \ + } + +template +inline T erfcx_y100(T y100) { + switch (static_cast(y100)) { + IMPL_ERFCX_Y100_CASE( + 0, + 0.70878032454106438663e-3, + 0.71234091047026302958e-3, + 0.35779077297597742384e-5, + 0.17403143962587937815e-7, + 0.81710660047307788845e-10, + 0.36885022360434957634e-12, + 0.15917038551111111111e-14) + IMPL_ERFCX_Y100_CASE( + 1, + 0.21479143208285144230e-2, + 0.72686402367379996033e-3, + 0.36843175430938995552e-5, + 0.18071841272149201685e-7, + 0.85496449296040325555e-10, + 0.38852037518534291510e-12, + 0.16868473576888888889e-14) + IMPL_ERFCX_Y100_CASE( + 2, + 0.36165255935630175090e-2, + 0.74182092323555510862e-3, + 0.37948319957528242260e-5, + 0.18771627021793087350e-7, + 0.89484715122415089123e-10, + 0.40935858517772440862e-12, + 0.17872061464888888889e-14) + IMPL_ERFCX_Y100_CASE( + 3, + 0.51154983860031979264e-2, + 0.75722840734791660540e-3, + 0.39096425726735703941e-5, + 0.19504168704300468210e-7, + 0.93687503063178993915e-10, + 0.43143925959079664747e-12, + 0.18939926435555555556e-14) + IMPL_ERFCX_Y100_CASE( + 4, + 0.66457513172673049824e-2, + 0.77310406054447454920e-3, + 0.40289510589399439385e-5, + 0.20271233238288381092e-7, + 0.98117631321709100264e-10, + 0.45484207406017752971e-12, + 0.20076352213333333333e-14) + IMPL_ERFCX_Y100_CASE( + 5, + 0.82082389970241207883e-2, + 0.78946629611881710721e-3, + 0.41529701552622656574e-5, + 0.21074693344544655714e-7, + 0.10278874108587317989e-9, + 0.47965201390613339638e-12, + 0.21285907413333333333e-14) + IMPL_ERFCX_Y100_CASE( + 6, + 0.98039537275352193165e-2, + 0.80633440108342840956e-3, + 0.42819241329736982942e-5, + 0.21916534346907168612e-7, + 0.10771535136565470914e-9, + 0.50595972623692822410e-12, + 0.22573462684444444444e-14) + IMPL_ERFCX_Y100_CASE( + 7, + 0.11433927298290302370e-1, + 0.82372858383196561209e-3, + 0.44160495311765438816e-5, + 0.22798861426211986056e-7, + 0.11291291745879239736e-9, + 0.53386189365816880454e-12, + 0.23944209546666666667e-14) + IMPL_ERFCX_Y100_CASE( + 8, + 0.13099232878814653979e-1, + 0.84167002467906968214e-3, + 0.45555958988457506002e-5, + 0.23723907357214175198e-7, + 0.11839789326602695603e-9, + 0.56346163067550237877e-12, + 0.25403679644444444444e-14) + IMPL_ERFCX_Y100_CASE( + 9, + 0.14800987015587535621e-1, + 0.86018092946345943214e-3, + 0.47008265848816866105e-5, + 0.24694040760197315333e-7, + 0.12418779768752299093e-9, + 0.59486890370320261949e-12, + 0.26957764568888888889e-14) + IMPL_ERFCX_Y100_CASE( + 10, + 0.16540351739394069380e-1, + 0.87928458641241463952e-3, + 0.48520195793001753903e-5, + 0.25711774900881709176e-7, + 0.13030128534230822419e-9, + 0.62820097586874779402e-12, + 0.28612737351111111111e-14) + IMPL_ERFCX_Y100_CASE( + 11, + 0.18318536789842392647e-1, + 0.89900542647891721692e-3, + 0.50094684089553365810e-5, + 0.26779777074218070482e-7, + 0.13675822186304615566e-9, + 0.66358287745352705725e-12, + 0.30375273884444444444e-14) + IMPL_ERFCX_Y100_CASE( + 12, + 0.20136801964214276775e-1, + 0.91936908737673676012e-3, + 0.51734830914104276820e-5, + 0.27900878609710432673e-7, + 0.14357976402809042257e-9, + 0.70114790311043728387e-12, + 0.32252476000000000000e-14) + IMPL_ERFCX_Y100_CASE( + 13, + 0.21996459598282740954e-1, + 0.94040248155366777784e-3, + 0.53443911508041164739e-5, + 0.29078085538049374673e-7, + 0.15078844500329731137e-9, + 0.74103813647499204269e-12, + 0.34251892320000000000e-14) + IMPL_ERFCX_Y100_CASE( + 14, + 0.23898877187226319502e-1, + 0.96213386835900177540e-3, + 0.55225386998049012752e-5, + 0.30314589961047687059e-7, + 0.15840826497296335264e-9, + 0.78340500472414454395e-12, + 0.36381553564444444445e-14) + IMPL_ERFCX_Y100_CASE( + 15, + 0.25845480155298518485e-1, + 0.98459293067820123389e-3, + 0.57082915920051843672e-5, + 0.31613782169164830118e-7, + 0.16646478745529630813e-9, + 0.82840985928785407942e-12, + 0.38649975768888888890e-14) + IMPL_ERFCX_Y100_CASE( + 16, + 0.27837754783474696598e-1, + 0.10078108563256892757e-2, + 0.59020366493792212221e-5, + 0.32979263553246520417e-7, + 0.17498524159268458073e-9, + 0.87622459124842525110e-12, + 0.41066206488888888890e-14) + IMPL_ERFCX_Y100_CASE( + 17, + 0.29877251304899307550e-1, + 0.10318204245057349310e-2, + 0.61041829697162055093e-5, + 0.34414860359542720579e-7, + 0.18399863072934089607e-9, + 0.92703227366365046533e-12, + 0.43639844053333333334e-14) + IMPL_ERFCX_Y100_CASE( + 18, + 0.31965587178596443475e-1, + 0.10566560976716574401e-2, + 0.63151633192414586770e-5, + 0.35924638339521924242e-7, + 0.19353584758781174038e-9, + 0.98102783859889264382e-12, + 0.46381060817777777779e-14) + IMPL_ERFCX_Y100_CASE( + 19, + 0.34104450552588334840e-1, + 0.10823541191350532574e-2, + 0.65354356159553934436e-5, + 0.37512918348533521149e-7, + 0.20362979635817883229e-9, + 0.10384187833037282363e-11, + 0.49300625262222222221e-14) + IMPL_ERFCX_Y100_CASE( + 20, + 0.36295603928292425716e-1, + 0.11089526167995268200e-2, + 0.67654845095518363577e-5, + 0.39184292949913591646e-7, + 0.21431552202133775150e-9, + 0.10994259106646731797e-11, + 0.52409949102222222221e-14) + IMPL_ERFCX_Y100_CASE( + 21, + 0.38540888038840509795e-1, + 0.11364917134175420009e-2, + 0.70058230641246312003e-5, + 0.40943644083718586939e-7, + 0.22563034723692881631e-9, + 0.11642841011361992885e-11, + 0.55721092871111111110e-14) + IMPL_ERFCX_Y100_CASE( + 22, + 0.40842225954785960651e-1, + 0.11650136437945673891e-2, + 0.72569945502343006619e-5, + 0.42796161861855042273e-7, + 0.23761401711005024162e-9, + 0.12332431172381557035e-11, + 0.59246802364444444445e-14) + IMPL_ERFCX_Y100_CASE( + 23, + 0.43201627431540222422e-1, + 0.11945628793917272199e-2, + 0.75195743532849206263e-5, + 0.44747364553960993492e-7, + 0.25030885216472953674e-9, + 0.13065684400300476484e-11, + 0.63000532853333333334e-14) + IMPL_ERFCX_Y100_CASE( + 24, + 0.45621193513810471438e-1, + 0.12251862608067529503e-2, + 0.77941720055551920319e-5, + 0.46803119830954460212e-7, + 0.26375990983978426273e-9, + 0.13845421370977119765e-11, + 0.66996477404444444445e-14) + IMPL_ERFCX_Y100_CASE( + 25, + 0.48103121413299865517e-1, + 0.12569331386432195113e-2, + 0.80814333496367673980e-5, + 0.48969667335682018324e-7, + 0.27801515481905748484e-9, + 0.14674637611609884208e-11, + 0.71249589351111111110e-14) + IMPL_ERFCX_Y100_CASE( + 26, + 0.50649709676983338501e-1, + 0.12898555233099055810e-2, + 0.83820428414568799654e-5, + 0.51253642652551838659e-7, + 0.29312563849675507232e-9, + 0.15556512782814827846e-11, + 0.75775607822222222221e-14) + IMPL_ERFCX_Y100_CASE( + 27, + 0.53263363664388864181e-1, + 0.13240082443256975769e-2, + 0.86967260015007658418e-5, + 0.53662102750396795566e-7, + 0.30914568786634796807e-9, + 0.16494420240828493176e-11, + 0.80591079644444444445e-14) + IMPL_ERFCX_Y100_CASE( + 28, + 0.55946601353500013794e-1, + 0.13594491197408190706e-2, + 0.90262520233016380987e-5, + 0.56202552975056695376e-7, + 0.32613310410503135996e-9, + 0.17491936862246367398e-11, + 0.85713381688888888890e-14) + IMPL_ERFCX_Y100_CASE( + 29, + 0.58702059496154081813e-1, + 0.13962391363223647892e-2, + 0.93714365487312784270e-5, + 0.58882975670265286526e-7, + 0.34414937110591753387e-9, + 0.18552853109751857859e-11, + 0.91160736711111111110e-14) + IMPL_ERFCX_Y100_CASE( + 30, + 0.61532500145144778048e-1, + 0.14344426411912015247e-2, + 0.97331446201016809696e-5, + 0.61711860507347175097e-7, + 0.36325987418295300221e-9, + 0.19681183310134518232e-11, + 0.96952238400000000000e-14) + IMPL_ERFCX_Y100_CASE( + 31, + 0.64440817576653297993e-1, + 0.14741275456383131151e-2, + 0.10112293819576437838e-4, + 0.64698236605933246196e-7, + 0.38353412915303665586e-9, + 0.20881176114385120186e-11, + 0.10310784480000000000e-13) + IMPL_ERFCX_Y100_CASE( + 32, + 0.67430045633130393282e-1, + 0.15153655418916540370e-2, + 0.10509857606888328667e-4, + 0.67851706529363332855e-7, + 0.40504602194811140006e-9, + 0.22157325110542534469e-11, + 0.10964842115555555556e-13) + IMPL_ERFCX_Y100_CASE( + 33, + 0.70503365513338850709e-1, + 0.15582323336495709827e-2, + 0.10926868866865231089e-4, + 0.71182482239613507542e-7, + 0.42787405890153386710e-9, + 0.23514379522274416437e-11, + 0.11659571751111111111e-13) + IMPL_ERFCX_Y100_CASE( + 34, + 0.73664114037944596353e-1, + 0.16028078812438820413e-2, + 0.11364423678778207991e-4, + 0.74701423097423182009e-7, + 0.45210162777476488324e-9, + 0.24957355004088569134e-11, + 0.12397238257777777778e-13) + IMPL_ERFCX_Y100_CASE( + 35, + 0.76915792420819562379e-1, + 0.16491766623447889354e-2, + 0.11823685320041302169e-4, + 0.78420075993781544386e-7, + 0.47781726956916478925e-9, + 0.26491544403815724749e-11, + 0.13180196462222222222e-13) + IMPL_ERFCX_Y100_CASE( + 36, + 0.80262075578094612819e-1, + 0.16974279491709504117e-2, + 0.12305888517309891674e-4, + 0.82350717698979042290e-7, + 0.50511496109857113929e-9, + 0.28122528497626897696e-11, + 0.14010889635555555556e-13) + IMPL_ERFCX_Y100_CASE( + 37, + 0.83706822008980357446e-1, + 0.17476561032212656962e-2, + 0.12812343958540763368e-4, + 0.86506399515036435592e-7, + 0.53409440823869467453e-9, + 0.29856186620887555043e-11, + 0.14891851591111111111e-13) + IMPL_ERFCX_Y100_CASE( + 38, + 0.87254084284461718231e-1, + 0.17999608886001962327e-2, + 0.13344443080089492218e-4, + 0.90900994316429008631e-7, + 0.56486134972616465316e-9, + 0.31698707080033956934e-11, + 0.15825697795555555556e-13) + IMPL_ERFCX_Y100_CASE( + 39, + 0.90908120182172748487e-1, + 0.18544478050657699758e-2, + 0.13903663143426120077e-4, + 0.95549246062549906177e-7, + 0.59752787125242054315e-9, + 0.33656597366099099413e-11, + 0.16815130613333333333e-13) + IMPL_ERFCX_Y100_CASE( + 40, + 0.94673404508075481121e-1, + 0.19112284419887303347e-2, + 0.14491572616545004930e-4, + 0.10046682186333613697e-6, + 0.63221272959791000515e-9, + 0.35736693975589130818e-11, + 0.17862931591111111111e-13) + IMPL_ERFCX_Y100_CASE( + 41, + 0.98554641648004456555e-1, + 0.19704208544725622126e-2, + 0.15109836875625443935e-4, + 0.10567036667675984067e-6, + 0.66904168640019354565e-9, + 0.37946171850824333014e-11, + 0.18971959040000000000e-13) + IMPL_ERFCX_Y100_CASE( + 42, + 0.10255677889470089531e0, + 0.20321499629472857418e-2, + 0.15760224242962179564e-4, + 0.11117756071353507391e-6, + 0.70814785110097658502e-9, + 0.40292553276632563925e-11, + 0.20145143075555555556e-13) + IMPL_ERFCX_Y100_CASE( + 43, + 0.10668502059865093318e0, + 0.20965479776148731610e-2, + 0.16444612377624983565e-4, + 0.11700717962026152749e-6, + 0.74967203250938418991e-9, + 0.42783716186085922176e-11, + 0.21385479360000000000e-13) + IMPL_ERFCX_Y100_CASE( + 44, + 0.11094484319386444474e0, + 0.21637548491908170841e-2, + 0.17164995035719657111e-4, + 0.12317915750735938089e-6, + 0.79376309831499633734e-9, + 0.45427901763106353914e-11, + 0.22696025653333333333e-13) + IMPL_ERFCX_Y100_CASE( + 45, + 0.11534201115268804714e0, + 0.22339187474546420375e-2, + 0.17923489217504226813e-4, + 0.12971465288245997681e-6, + 0.84057834180389073587e-9, + 0.48233721206418027227e-11, + 0.24079890062222222222e-13) + IMPL_ERFCX_Y100_CASE( + 46, + 0.11988259392684094740e0, + 0.23071965691918689601e-2, + 0.18722342718958935446e-4, + 0.13663611754337957520e-6, + 0.89028385488493287005e-9, + 0.51210161569225846701e-11, + 0.25540227111111111111e-13) + IMPL_ERFCX_Y100_CASE( + 47, + 0.12457298393509812907e0, + 0.23837544771809575380e-2, + 0.19563942105711612475e-4, + 0.14396736847739470782e-6, + 0.94305490646459247016e-9, + 0.54366590583134218096e-11, + 0.27080225920000000000e-13) + IMPL_ERFCX_Y100_CASE( + 48, + 0.12941991566142438816e0, + 0.24637684719508859484e-2, + 0.20450821127475879816e-4, + 0.15173366280523906622e-6, + 0.99907632506389027739e-9, + 0.57712760311351625221e-11, + 0.28703099555555555556e-13) + IMPL_ERFCX_Y100_CASE( + 49, + 0.13443048593088696613e0, + 0.25474249981080823877e-2, + 0.21385669591362915223e-4, + 0.15996177579900443030e-6, + 0.10585428844575134013e-8, + 0.61258809536787882989e-11, + 0.30412080142222222222e-13) + IMPL_ERFCX_Y100_CASE( + 50, + 0.13961217543434561353e0, + 0.26349215871051761416e-2, + 0.22371342712572567744e-4, + 0.16868008199296822247e-6, + 0.11216596910444996246e-8, + 0.65015264753090890662e-11, + 0.32210394506666666666e-13) + IMPL_ERFCX_Y100_CASE( + 51, + 0.14497287157673800690e0, + 0.27264675383982439814e-2, + 0.23410870961050950197e-4, + 0.17791863939526376477e-6, + 0.11886425714330958106e-8, + 0.68993039665054288034e-11, + 0.34101266222222222221e-13) + IMPL_ERFCX_Y100_CASE( + 52, + 0.15052089272774618151e0, + 0.28222846410136238008e-2, + 0.24507470422713397006e-4, + 0.18770927679626136909e-6, + 0.12597184587583370712e-8, + 0.73203433049229821618e-11, + 0.36087889048888888890e-13) + IMPL_ERFCX_Y100_CASE( + 53, + 0.15626501395774612325e0, + 0.29226079376196624949e-2, + 0.25664553693768450545e-4, + 0.19808568415654461964e-6, + 0.13351257759815557897e-8, + 0.77658124891046760667e-11, + 0.38173420035555555555e-13) + IMPL_ERFCX_Y100_CASE( + 54, + 0.16221449434620737567e0, + 0.30276865332726475672e-2, + 0.26885741326534564336e-4, + 0.20908350604346384143e-6, + 0.14151148144240728728e-8, + 0.82369170665974313027e-11, + 0.40360957457777777779e-13) + IMPL_ERFCX_Y100_CASE( + 55, + 0.16837910595412130659e0, + 0.31377844510793082301e-2, + 0.28174873844911175026e-4, + 0.22074043807045782387e-6, + 0.14999481055996090039e-8, + 0.87348993661930809254e-11, + 0.42653528977777777779e-13) + IMPL_ERFCX_Y100_CASE( + 56, + 0.17476916455659369953e0, + 0.32531815370903068316e-2, + 0.29536024347344364074e-4, + 0.23309632627767074202e-6, + 0.15899007843582444846e-8, + 0.92610375235427359475e-11, + 0.45054073102222222221e-13) + IMPL_ERFCX_Y100_CASE( + 57, + 0.18139556223643701364e0, + 0.33741744168096996041e-2, + 0.30973511714709500836e-4, + 0.24619326937592290996e-6, + 0.16852609412267750744e-8, + 0.98166442942854895573e-11, + 0.47565418097777777779e-13) + IMPL_ERFCX_Y100_CASE( + 58, + 0.18826980194443664549e0, + 0.35010775057740317997e-2, + 0.32491914440014267480e-4, + 0.26007572375886319028e-6, + 0.17863299617388376116e-8, + 0.10403065638343878679e-10, + 0.50190265831111111110e-13) + IMPL_ERFCX_Y100_CASE( + 59, + 0.19540403413693967350e0, + 0.36342240767211326315e-2, + 0.34096085096200907289e-4, + 0.27479061117017637474e-6, + 0.18934228504790032826e-8, + 0.11021679075323598664e-10, + 0.52931171733333333334e-13) + IMPL_ERFCX_Y100_CASE( + 60, + 0.20281109560651886959e0, + 0.37739673859323597060e-2, + 0.35791165457592409054e-4, + 0.29038742889416172404e-6, + 0.20068685374849001770e-8, + 0.11673891799578381999e-10, + 0.55790523093333333334e-13) + IMPL_ERFCX_Y100_CASE( + 61, + 0.21050455062669334978e0, + 0.39206818613925652425e-2, + 0.37582602289680101704e-4, + 0.30691836231886877385e-6, + 0.21270101645763677824e-8, + 0.12361138551062899455e-10, + 0.58770520160000000000e-13) + IMPL_ERFCX_Y100_CASE( + 62, + 0.21849873453703332479e0, + 0.40747643554689586041e-2, + 0.39476163820986711501e-4, + 0.32443839970139918836e-6, + 0.22542053491518680200e-8, + 0.13084879235290858490e-10, + 0.61873153262222222221e-13) + IMPL_ERFCX_Y100_CASE( + 63, + 0.22680879990043229327e0, + 0.42366354648628516935e-2, + 0.41477956909656896779e-4, + 0.34300544894502810002e-6, + 0.23888264229264067658e-8, + 0.13846596292818514601e-10, + 0.65100183751111111110e-13) + IMPL_ERFCX_Y100_CASE( + 64, + 0.23545076536988703937e0, + 0.44067409206365170888e-2, + 0.43594444916224700881e-4, + 0.36268045617760415178e-6, + 0.25312606430853202748e-8, + 0.14647791812837903061e-10, + 0.68453122631111111110e-13) + IMPL_ERFCX_Y100_CASE( + 65, + 0.24444156740777432838e0, + 0.45855530511605787178e-2, + 0.45832466292683085475e-4, + 0.38352752590033030472e-6, + 0.26819103733055603460e-8, + 0.15489984390884756993e-10, + 0.71933206364444444445e-13) + IMPL_ERFCX_Y100_CASE( + 66, + 0.25379911500634264643e0, + 0.47735723208650032167e-2, + 0.48199253896534185372e-4, + 0.40561404245564732314e-6, + 0.28411932320871165585e-8, + 0.16374705736458320149e-10, + 0.75541379822222222221e-13) + IMPL_ERFCX_Y100_CASE( + 67, + 0.26354234756393613032e0, + 0.49713289477083781266e-2, + 0.50702455036930367504e-4, + 0.42901079254268185722e-6, + 0.30095422058900481753e-8, + 0.17303497025347342498e-10, + 0.79278273368888888890e-13) + IMPL_ERFCX_Y100_CASE( + 68, + 0.27369129607732343398e0, + 0.51793846023052643767e-2, + 0.53350152258326602629e-4, + 0.45379208848865015485e-6, + 0.31874057245814381257e-8, + 0.18277905010245111046e-10, + 0.83144182364444444445e-13) + IMPL_ERFCX_Y100_CASE( + 69, + 0.28426714781640316172e0, + 0.53983341916695141966e-2, + 0.56150884865255810638e-4, + 0.48003589196494734238e-6, + 0.33752476967570796349e-8, + 0.19299477888083469086e-10, + 0.87139049137777777779e-13) + IMPL_ERFCX_Y100_CASE( + 70, + 0.29529231465348519920e0, + 0.56288077305420795663e-2, + 0.59113671189913307427e-4, + 0.50782393781744840482e-6, + 0.35735475025851713168e-8, + 0.20369760937017070382e-10, + 0.91262442613333333334e-13) + IMPL_ERFCX_Y100_CASE( + 71, + 0.30679050522528838613e0, + 0.58714723032745403331e-2, + 0.62248031602197686791e-4, + 0.53724185766200945789e-6, + 0.37827999418960232678e-8, + 0.21490291930444538307e-10, + 0.95513539182222222221e-13) + IMPL_ERFCX_Y100_CASE( + 72, + 0.31878680111173319425e0, + 0.61270341192339103514e-2, + 0.65564012259707640976e-4, + 0.56837930287837738996e-6, + 0.40035151353392378882e-8, + 0.22662596341239294792e-10, + 0.99891109760000000000e-13) + IMPL_ERFCX_Y100_CASE( + 73, + 0.33130773722152622027e0, + 0.63962406646798080903e-2, + 0.69072209592942396666e-4, + 0.60133006661885941812e-6, + 0.42362183765883466691e-8, + 0.23888182347073698382e-10, + 0.10439349811555555556e-12) + IMPL_ERFCX_Y100_CASE( + 74, + 0.34438138658041336523e0, + 0.66798829540414007258e-2, + 0.72783795518603561144e-4, + 0.63619220443228800680e-6, + 0.44814499336514453364e-8, + 0.25168535651285475274e-10, + 0.10901861383111111111e-12) + IMPL_ERFCX_Y100_CASE( + 75, + 0.35803744972380175583e0, + 0.69787978834882685031e-2, + 0.76710543371454822497e-4, + 0.67306815308917386747e-6, + 0.47397647975845228205e-8, + 0.26505114141143050509e-10, + 0.11376390933333333333e-12) + IMPL_ERFCX_Y100_CASE( + 76, + 0.37230734890119724188e0, + 0.72938706896461381003e-2, + 0.80864854542670714092e-4, + 0.71206484718062688779e-6, + 0.50117323769745883805e-8, + 0.27899342394100074165e-10, + 0.11862637614222222222e-12) + IMPL_ERFCX_Y100_CASE( + 77, + 0.38722432730555448223e0, + 0.76260375162549802745e-2, + 0.85259785810004603848e-4, + 0.75329383305171327677e-6, + 0.52979361368388119355e-8, + 0.29352606054164086709e-10, + 0.12360253370666666667e-12) + IMPL_ERFCX_Y100_CASE( + 78, + 0.40282355354616940667e0, + 0.79762880915029728079e-2, + 0.89909077342438246452e-4, + 0.79687137961956194579e-6, + 0.55989731807360403195e-8, + 0.30866246101464869050e-10, + 0.12868841946666666667e-12) + IMPL_ERFCX_Y100_CASE( + 79, + 0.41914223158913787649e0, + 0.83456685186950463538e-2, + 0.94827181359250161335e-4, + 0.84291858561783141014e-6, + 0.59154537751083485684e-8, + 0.32441553034347469291e-10, + 0.13387957943111111111e-12) + IMPL_ERFCX_Y100_CASE( + 80, + 0.43621971639463786896e0, + 0.87352841828289495773e-2, + 0.10002929142066799966e-3, + 0.89156148280219880024e-6, + 0.62480008150788597147e-8, + 0.34079760983458878910e-10, + 0.13917107176888888889e-12) + IMPL_ERFCX_Y100_CASE( + 81, + 0.45409763548534330981e0, + 0.91463027755548240654e-2, + 0.10553137232446167258e-3, + 0.94293113464638623798e-6, + 0.65972492312219959885e-8, + 0.35782041795476563662e-10, + 0.14455745872000000000e-12) + IMPL_ERFCX_Y100_CASE( + 82, + 0.47282001668512331468e0, + 0.95799574408860463394e-2, + 0.11135019058000067469e-3, + 0.99716373005509038080e-6, + 0.69638453369956970347e-8, + 0.37549499088161345850e-10, + 0.15003280712888888889e-12) + IMPL_ERFCX_Y100_CASE( + 83, + 0.49243342227179841649e0, + 0.10037550043909497071e-1, + 0.11750334542845234952e-3, + 0.10544006716188967172e-5, + 0.73484461168242224872e-8, + 0.39383162326435752965e-10, + 0.15559069118222222222e-12) + IMPL_ERFCX_Y100_CASE( + 84, + 0.51298708979209258326e0, + 0.10520454564612427224e-1, + 0.12400930037494996655e-3, + 0.11147886579371265246e-5, + 0.77517184550568711454e-8, + 0.41283980931872622611e-10, + 0.16122419680000000000e-12) + IMPL_ERFCX_Y100_CASE( + 85, + 0.53453307979101369843e0, + 0.11030120618800726938e-1, + 0.13088741519572269581e-3, + 0.11784797595374515432e-5, + 0.81743383063044825400e-8, + 0.43252818449517081051e-10, + 0.16692592640000000000e-12) + IMPL_ERFCX_Y100_CASE( + 86, + 0.55712643071169299478e0, + 0.11568077107929735233e-1, + 0.13815797838036651289e-3, + 0.12456314879260904558e-5, + 0.86169898078969313597e-8, + 0.45290446811539652525e-10, + 0.17268801084444444444e-12) + IMPL_ERFCX_Y100_CASE( + 87, + 0.58082532122519320968e0, + 0.12135935999503877077e-1, + 0.14584223996665838559e-3, + 0.13164068573095710742e-5, + 0.90803643355106020163e-8, + 0.47397540713124619155e-10, + 0.17850211608888888889e-12) + IMPL_ERFCX_Y100_CASE( + 88, + 0.60569124025293375554e0, + 0.12735396239525550361e-1, + 0.15396244472258863344e-3, + 0.13909744385382818253e-5, + 0.95651595032306228245e-8, + 0.49574672127669041550e-10, + 0.18435945564444444444e-12) + IMPL_ERFCX_Y100_CASE( + 89, + 0.63178916494715716894e0, + 0.13368247798287030927e-1, + 0.16254186562762076141e-3, + 0.14695084048334056083e-5, + 0.10072078109604152350e-7, + 0.51822304995680707483e-10, + 0.19025081422222222222e-12) + IMPL_ERFCX_Y100_CASE( + 90, + 0.65918774689725319200e0, + 0.14036375850601992063e-1, + 0.17160483760259706354e-3, + 0.15521885688723188371e-5, + 0.10601827031535280590e-7, + 0.54140790105837520499e-10, + 0.19616655146666666667e-12) + IMPL_ERFCX_Y100_CASE( + 91, + 0.68795950683174433822e0, + 0.14741765091365869084e-1, + 0.18117679143520433835e-3, + 0.16392004108230585213e-5, + 0.11155116068018043001e-7, + 0.56530360194925690374e-10, + 0.20209663662222222222e-12) + IMPL_ERFCX_Y100_CASE( + 92, + 0.71818103808729967036e0, + 0.15486504187117112279e-1, + 0.19128428784550923217e-3, + 0.17307350969359975848e-5, + 0.11732656736113607751e-7, + 0.58991125287563833603e-10, + 0.20803065333333333333e-12) + IMPL_ERFCX_Y100_CASE( + 93, + 0.74993321911726254661e0, + 0.16272790364044783382e-1, + 0.20195505163377912645e-3, + 0.18269894883203346953e-5, + 0.12335161021630225535e-7, + 0.61523068312169087227e-10, + 0.21395783431111111111e-12) + IMPL_ERFCX_Y100_CASE( + 94, + 0.78330143531283492729e0, + 0.17102934132652429240e-1, + 0.21321800585063327041e-3, + 0.19281661395543913713e-5, + 0.12963340087354341574e-7, + 0.64126040998066348872e-10, + 0.21986708942222222222e-12) + IMPL_ERFCX_Y100_CASE( + 95, + 0.81837581041023811832e0, + 0.17979364149044223802e-1, + 0.22510330592753129006e-3, + 0.20344732868018175389e-5, + 0.13617902941839949718e-7, + 0.66799760083972474642e-10, + 0.22574701262222222222e-12) + IMPL_ERFCX_Y100_CASE( + 96, + 0.85525144775685126237e0, + 0.18904632212547561026e-1, + 0.23764237370371255638e-3, + 0.21461248251306387979e-5, + 0.14299555071870523786e-7, + 0.69543803864694171934e-10, + 0.23158593688888888889e-12) + IMPL_ERFCX_Y100_CASE( + 97, + 0.89402868170849933734e0, + 0.19881418399127202569e-1, + 0.25086793128395995798e-3, + 0.22633402747585233180e-5, + 0.15008997042116532283e-7, + 0.72357609075043941261e-10, + 0.23737194737777777778e-12) + IMPL_ERFCX_Y100_CASE( + 98, + 0.93481333942870796363e0, + 0.20912536329780368893e-1, + 0.26481403465998477969e-3, + 0.23863447359754921676e-5, + 0.15746923065472184451e-7, + 0.75240468141720143653e-10, + 0.24309291271111111111e-12) + IMPL_ERFCX_Y100_CASE( + 99, + 0.97771701335885035464e0, + 0.22000938572830479551e-1, + 0.27951610702682383001e-3, + 0.25153688325245314530e-5, + 0.16514019547822821453e-7, + 0.78191526829368231251e-10, + 0.24873652355555555556e-12) + } + // we only get here if y = 1, i.e. |x| < 4*eps, in which case + // erfcx is within 1e-15 of 1.. + return 1.0; +} + +template +float erfcx(T x) { + if (x != x) { + return x; + } + + if (x >= 0) { + if (x > 50) { // continued-fraction expansion is faster + const auto ispi = 0.56418958354775628694807945156; // 1 / sqrt(pi) + if (x > 5e7) { // 1-term expansion, important to avoid overflow + return ispi / x; + } + /* 5-term expansion (rely on compiler for CSE), simplified from: + ispi / (x+0.5/(x+1/(x+1.5/(x+2/x)))) */ + return ispi * ((x * x) * (x * x + 4.5) + 2) / + (x * ((x * x) * (x * x + 5) + 3.75)); + } + return erfcx_y100(400.0f / (4.0f + x)); + } else { + if (x < -26.7) { + return ::metal::numeric_limits::infinity(); + } else if (x < -6.1) { + return 2 * exp(float(x) * x); + } else { + return 2 * exp(float(x) * x) - erfcx_y100(400.0f / (4 - x)); + } + } +} + +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/utils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..7228b95fd4f4cbda0824e3f955d43782445bc869 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/metal/utils.h @@ -0,0 +1,528 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Metal helper functions +#pragma once +#include +#include + +namespace c10 { +namespace metal { + +namespace detail { +template +struct vectypes {}; + +template <> +struct vectypes { + using type4 = float4; + using type3 = float3; + using type2 = float2; +}; + +template <> +struct vectypes { + using type4 = half4; + using type3 = half3; + using type2 = half2; +}; + +template <> +struct vectypes { + using type4 = bfloat4; + using type3 = bfloat3; + using type2 = bfloat2; +}; + +template <> +struct vectypes { + using type4 = short4; + using type3 = short3; + using type2 = short2; +}; + +template <> +struct vectypes { + using type4 = int4; + using type3 = int3; + using type2 = int2; +}; + +template <> +struct vectypes { + using type4 = short4; + using type3 = short3; + using type2 = short2; +}; + +template +struct OpMathType { + using type = T; +}; + +template <> +struct OpMathType { + using type = float; +}; + +template <> +struct OpMathType { + using type = int; +}; + +template <> +struct OpMathType { + using type = int; +}; + +template <> +struct OpMathType { + using type = int; +}; + +template <> +struct OpMathType { + using type = float; +}; + +// Type promotion structure for higher precision accumulation +template +struct AccumulationType { + using type = T; +}; + +// Specialization for half - promote to float for accumulation +template <> +struct AccumulationType { + using type = float; +}; + +// Specialization for bfloat - promote to float for accumulation +template <> +struct AccumulationType { + using type = float; +}; + +} // namespace detail + +template +::metal::enable_if_t<::metal::is_floating_point_v, T> max(T a, T b) { + return ::metal::isunordered(a, b) ? NAN : ::metal::max(a, b); +} + +template +::metal::enable_if_t<::metal::is_integral_v&& ::metal::is_integral_v, T> +max(T a, U b) { + return ::metal::max(a, static_cast(b)); +} + +template +::metal::enable_if_t<::metal::is_floating_point_v, T> min(T a, T b) { + return ::metal::isunordered(a, b) ? NAN : ::metal::min(a, b); +} + +template +::metal::enable_if_t<::metal::is_integral_v&& ::metal::is_integral_v, T> +min(T a, U b) { + return ::metal::min(a, static_cast(b)); +} + +template <> +inline bfloat min(bfloat a, bfloat b) { + return bfloat( + ::metal::isunordered(a, b) ? NAN : ::metal::min(float(a), float(b))); +} + +template <> +inline bfloat max(bfloat a, bfloat b) { + return bfloat( + ::metal::isunordered(a, b) ? NAN : ::metal::max(float(a), float(b))); +} + +template +using vec2type_t = typename detail::vectypes::type2; + +template +using vec4type_t = typename detail::vectypes::type4; + +template +using opmath_t = typename detail::OpMathType::type; + +template +using accum_t = typename detail::AccumulationType::type; + +// TODO: Move it to type_traits header may be +template +using result_of = decltype(::metal::declval()(::metal::declval()...)); + +template +constexpr constant bool is_complex_v = + ::metal::is_same_v || ::metal::is_same_v; + +template +constexpr constant bool is_scalar_floating_point_v = + ::metal::is_floating_point_v && ::metal::is_scalar_v; + +template +constexpr constant bool is_scalar_integral_v = + ::metal::is_integral_v && ::metal::is_scalar_v; + +template +using common_dtype = decltype(U(0) + V(0)); + +// floor_divide +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_integral_v && is_scalar_integral_v, + bool> = true> +inline common_dtype floor_divide(T x, U y) { + const auto quot = x / y; + return (x < 0) == (y < 0) ? quot : (x % y != 0) ? quot - 1 : quot; +} + +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_floating_point_v && is_scalar_floating_point_v, + bool> = true> +inline common_dtype floor_divide(T x, U y) { + return ::metal::floor(x / y); +} + +// Workaround for Metal compiler bug: the compiler produces wrong results +// when optimizing fused (x / A) % B expressions for integral types. +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_integral_v && is_scalar_integral_v, + bool> = true> +inline common_dtype safe_mod(volatile T x, U y) { + return x % y; +} + +// fmod +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_integral_v && is_scalar_integral_v, + bool> = true> +inline common_dtype fmod(T x, U y) { + return x % y; +} + +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_floating_point_v && is_scalar_floating_point_v, + bool> = true> +inline common_dtype fmod(T x, U y) { + return ::metal::fmod(x, y); +} + +// cast_to primitives +// - No-op if types as the same +template < + typename T, + typename U, + ::metal::enable_if_t<::metal::is_same_v, bool> = true> +inline T cast_to(const U from) { + return from; +} +// - Simple cast between scalar and complex dtypes +template < + typename T, + typename U, + ::metal::enable_if_t< + !::metal::is_same_v && (is_complex_v == is_complex_v), + bool> = true> +inline T cast_to(const U from) { + return static_cast(from); +} + +// - Scalar to complex +template < + typename T, + typename U, + ::metal::enable_if_t && !is_complex_v, bool> = true> +inline T cast_to(const U from) { + return T(float(from), 0.0); +} +// - Complex to scalar (should not really be used, but exists for compliteness) +template < + typename T, + typename U, + ::metal::enable_if_t && is_complex_v, bool> = true> +inline T cast_to(const U from) { + return static_cast(from.x); +} + +// Generalizable math operators (used for both scalar and complex) + +template < + typename T, + typename U, + ::metal::enable_if_t, bool> = true> +inline common_dtype mul(const T x, const U y) { + return x * y; +} + +template < + typename T, + typename U, + ::metal::enable_if_t && is_complex_v, bool> = true> +inline common_dtype mul(const T x, const U y) { + return T(x.x * y.x - x.y * y.y, x.x * y.y + x.y * y.x); +} + +template < + typename T, + typename U, + ::metal::enable_if_t, bool> = true> +inline common_dtype div(const T x, const U y) { + return x / y; +} + +template < + typename T, + typename U, + ::metal::enable_if_t && is_complex_v, bool> = true> +inline common_dtype div(const T x, const U y) { + return T(::metal::dot(x, y), x.y * y.x - x.x * y.y) / ::metal::dot(y, y); +} + +// Remainder operator +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_floating_point_v || is_scalar_floating_point_v, + bool> = true> +inline float remainder(const T x, const U y) { + const auto x_f = static_cast(x); + const auto y_f = static_cast(y); + return x_f - y_f * floor_divide(x_f, y_f); +} + +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_integral_v && is_scalar_integral_v, + bool> = true> +inline common_dtype remainder(const T x, const U y) { + auto rc = x % y; + return rc == 0 || (x ^ y) > 0 ? rc : rc + y; +} + +// Based on aten/src/ATen/native/Pow.h +template < + typename T, + ::metal::enable_if_t, bool> = true> +inline T powi_impl(T a, T b) { + T result = 1; + while (b) { + if (b & 1) { + result *= a; + } + b /= 2; + a *= a; + } + return result; +} + +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_floating_point_v || is_scalar_floating_point_v, + bool> = true> +inline float pow(T a, U b) { + return ::metal::precise::pow(static_cast(a), static_cast(b)); +} + +// Complex pow - use polar form: a = r*e^(i*theta) +// a^b = exp(b * log(a)) = exp(b * (log(r) + i*theta)) +template < + typename T, + typename U, + ::metal::enable_if_t && is_complex_v, bool> = true> +inline float2 pow(T a, U b) { + // Convert a to polar form + // Use explicit computation instead of length() due to numerical issues + const auto r = ::metal::precise::sqrt(a.x * a.x + a.y * a.y); + + // Special case: if r is 0, return 0 + if (r == 0.0) { + return float2(0.0, 0.0); + } + + const auto theta = ::metal::precise::atan2(a.y, a.x); + const auto log_r = ::metal::precise::log(r); + + // Calculate a^b = r^b * e^(i*theta*b) + // new_r = exp(b.x * log(r) - b.y * theta) + // new_theta = b.x * theta + b.y * log(r) + const auto new_r = ::metal::precise::exp(b.x * log_r - b.y * theta); + const auto new_theta = b.x * theta + b.y * log_r; + + return float2( + new_r * ::metal::precise::cos(new_theta), + new_r * ::metal::precise::sin(new_theta)); +} + +// Integral pow - unsigned types +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_integral_v && !::metal::is_signed_v, + bool> = true> +inline T pow(T a, U b) { + return powi_impl(a, T(b)); +} + +// Integral pow - signed types +template < + typename T, + typename U, + ::metal::enable_if_t< + is_scalar_integral_v&& ::metal::is_signed_v, + bool> = true> +inline T pow(T a, U b) { + if (b < 0) { + if (a == 1) { + return 1; + } else if (a == -1) { + auto negative = (-b) % static_cast(2); + return negative ? -1 : 1; + } else { + return 0; + } + } + return powi_impl(a, T(b)); +} + +// Based on algorithm described in +// https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html#1202 +inline float log1p(float x) { + const auto xp1 = 1.0f + x; + // First two elements of Taylor series for log(1+x) in Horner's form are: + // log(1+x) = x * (1 - x * (.5 ...)), but if 1 + x == x, then it's just x + if (xp1 == 1.0f) { + return x; + } + auto rc = ::metal::precise::log(xp1); + if (x > -.5 && x < .5) { + // Order of operations is important here for higher precision + rc *= x / (xp1 - 1.0f); + } + return rc; +} + +// The function is ported from mlx +inline float2 log1p(float2 in) { + float x = in.x; + float y = in.y; + float zabs = ::metal::precise::sqrt(x * x + y * y); + float theta = ::metal::atan2(y, x + 1); + if (zabs < 0.5f) { + float r = x * (2 + x) + y * y; + if (r == 0) { // handle underflow + return {x, theta}; + } + return {0.5f * log1p(r), theta}; + } else { + auto z0 = ::metal::sqrt((x + 1) * (x + 1) + y * y); + return {::metal::log(z0), theta}; + } +} + +template +struct pair { + T1 first; + T2 second; +}; + +template +inline T conj(T a) { + return a; +} + +template <> +inline half2 conj(half2 a) { + return half2(a.x, -a.y); +} + +template <> +inline float2 conj(float2 a) { + return float2(a.x, -a.y); +} + +// The following implementation of hypot provides better numerical stability +// than the naive implementation. It is based on: +// https://github.com/pearu/functional_algorithms/blob/7dbbfd7db225b1c202e0e364fc435423ccf52dbe/functional_algorithms/algorithms.py#L168 +// +// This implementation changes the naive formula for the hypotenuse of a right +// triangle, `h = sqrt(a^2 + b^2)`, into three alternate forms to be used in +// different cases. The reason why the naive formula is unstable is because of +// the square terms. If `a` or `b` are very large or very small floating point +// numbers, then their squares will resolve to inf or 0. +// +// Assume `a >= b >= 0`. We can first change the formula to: +// `h = a sqrt(1 + (b / a)^2)` +// `h = a sqrt(1 + r)` +// where `r = (b / a)^2`. Since `a >= b >= 0`, then `1 >= r >= 0`. +// +// Case 1: `a == b` +// The formula simplifies to `h = a sqrt(2)`. +// +// Case 2: `1 >> r > 0` +// Due to floating point error, `sqrt(1 + r)` resolves to 1. So we use the +// binomial approximation `sqrt(1 + r) ≈ 1 + r / 2`, and the formula becomes +// `h ≈ a + a r / 2`. +// +// Case 3: All other cases. +// Use `h = a sqrt(1 + r)`. +inline float hypot(float a_, float b_) { + auto a = max(a_, b_); + auto b = min(a_, b_); + + auto b_over_a = c10::metal::div(b, a); + auto r = c10::metal::mul(b_over_a, b_over_a); + auto sqrt_1_plus_r = ::metal::precise::sqrt(1 + r); + + auto h1 = M_SQRT2_F * a; + auto h2 = a + a * r / 2; + auto h3 = a * sqrt_1_plus_r; + bool is_h1 = (a == b); + bool is_h2 = ((sqrt_1_plus_r == 1) && (r > 0)); + + return ::metal::select(::metal::select(h3, h2, is_h2), h1, is_h1); +} + +#define INSTANTIATE_FOR_ALL_TYPES(MACRO) \ + MACRO(float); \ + MACRO(half); \ + MACRO(bfloat); \ + MACRO(float2); \ + MACRO(long); \ + MACRO(char); \ + MACRO(uchar); \ + MACRO(short); \ + MACRO(int); + +#define INSTANTIATE_FOR_FLOAT_TYPES(MACRO) \ + MACRO(float); \ + MACRO(half); \ + MACRO(bfloat); + +} // namespace metal +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/mobile/CPUCachingAllocator.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/mobile/CPUCachingAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..ad6854b8871d9e55324bea686b1313f64c1f5883 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/mobile/CPUCachingAllocator.h @@ -0,0 +1,111 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include +#include +#include + +/* + * CPUCachingAllocator: + * DISCLAIMER: + * This is subject to change (beta) and only supported on mobile builds. + * If code snippet such as in 'Usage pattern' is used outside of mobile + * build you will not observe the intended behavior. + * See below for more information. + * Why? + * It has been observed that some mobile platforms, such as pixel 3, return + * memory aggressively to the system. This results in page faults in some + * cases and ends up hurting performance. This caching allocator aims to address + * that. Furthermore it also allows users to specify their own allocator by + * implementing allocate/free virtual interfaces. What are the cons? There are + * some cons that were observed where use of caching allocator led to worse + * performance on some platforms. Reason being that the caching mechanism used + * by this allocator left us worse off compared to the corresponding platform's + * tuned memory allocator. In that case it seemed better to not use this + * allocator. Note there are some ideas to fix this in the works. + * + * Usage: + * Usage pattern: + * Instantiate and own the caching allocator. + * std::unique_ptr caching_allocator = + * std::make_unique(); + * Use caching allocator with a scoped guard at inference time. + * { + * WithCPUCachingAllocatorGuard(caching_allocator.get()); + * ... model.forward(...); + * } + */ + +namespace c10 { + +class C10_API CPUCachingAllocator { + /* + * What it does: + * Caches all the allocations carried out by this allocator. + * Cache key is the size of the allocation. + * If requested size is found in the cache returns the cached pointer. + * What it does not do: + * No speculative allocation for any future allocations. + */ + private: + inline void* allocate_and_cache(const size_t bytes); + void free_cached(); + + protected: + // Invariants. + // 1. If memory is ever allocated via this allocator then + // the pointer will exist in allocation_map_, unless the allocator + // returned the memory to OS via free_cached. + // 1.1. Therefore even when the said memory is "freed" via this + // allocator (and thus cached), it will continue to stay + // in allocation_map_. Furthermore it will also exist in + // available_map_. Thus an allocated memory pointer can be in both + // allocation_map_ and available_map_ simultaneously. + // 2. Memory pointer maybe removed from allocation_map_, when it + // is freed outside of the scope of this allocator, but was allocated + // by this allocator. + // 3. Available map only contains that memory which was allocated + // by this allocator and subsequently freed by this allocator. + // As a result of above invariants, allocated memory ptr cannot be in + // available_map_ unless it is in allocation_map_ as well. + ska::flat_hash_map> available_map_; + static ska::flat_hash_map allocation_map_; + // Since allocation_map, which is a global instance, is mutated/read via + // all public APIs we need a global mutex. + static std::mutex mutex_; + + public: + static void record_free(void* ptr); + virtual ~CPUCachingAllocator(); + // Checks the cache to see if allocation of size bytes can be found. + // If so return cached memory, else + // allocates memory, records it for caching and returns. + virtual void* allocate(const size_t bytes); + // Checks if the memory being freed is was marked for allocation by + // an earlier call to allocate. If so cache the allocation. + // Otherwise free. + virtual void free(void* ptr); +}; + +CPUCachingAllocator* GetDefaultCPUCachingAllocator(); + +bool ThreadLocalCachingAllocatorEnabled(); +CPUCachingAllocator* GetThreadLocalCachingAllocator(); + +class C10_API WithCPUCachingAllocatorGuard { + public: + WithCPUCachingAllocatorGuard(CPUCachingAllocator* allocator); + ~WithCPUCachingAllocatorGuard(); + + private: + CPUCachingAllocator* prev_caching_allocator_ptr_{nullptr}; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/mobile/CPUProfilingAllocator.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/mobile/CPUProfilingAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..07064210e115bb5799906828fac135ccb63a3146 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/mobile/CPUProfilingAllocator.h @@ -0,0 +1,157 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace c10 { + +/* + * Given a sequence of allocations in a thread, AllocationPlan records + * 1. size of each allocation + * 2. Lifetime of each allocation. + * 3. allocation offsets: Memory offset for each allocation in a single blob of + * memory + * 4. Total size of a blob of memory required to satisfy all the allocations. + */ +class C10_API AllocationPlan { + private: + // Records size of each allocation by their sequential allocation ids. + std::vector allocation_sizes; + // This maps one allocation id (X) to another allocation id (Y). + // Allocation X is alive until allocation Y. From allocation Y onwards + // allocation X is not referenced. + // Thus Y is the id of the first allocation after X is freed. + // NB: When an allocation is recorded, along with recording its size, + // we also set the lifetime to be numeric_limits::max() + // This is to track allocations that are made during the scope of + // profiling but were not freed until after the scope ended. + // Such allocations are not managed by profiling allocator. + std::vector allocation_lifetimes; + // Maps an allocation to some offset in a blob of memory. + std::vector allocation_offsets; + uint64_t total_size{0}; + void clear(); + friend class AllocationPlanner; + friend class CPUProfilingAllocator; +}; + +/* + * Map of memory ptr to allocation id. This is auxiliary information only + * used to establish lifetime of allocations. + */ +class C10_API AllocationPlanner { + private: + AllocationPlan* allocation_plan_{nullptr}; + // Maps allocated ptr to its allocation id. + // This is used when freeing the memory to look up the allocation id + // in order to establish the lifetime of a particular allocation. + ska::flat_hash_map allocation_ptr_to_id_; + uint64_t allocation_id_{0}; + bool validation_mode_{false}; + + bool validate_allocation(const uint64_t size, const void* ptr); + bool validate_free(const void* ptr); + + public: + bool validation_success{true}; + + AllocationPlanner() = delete; + AllocationPlanner(AllocationPlan* plan, bool validate = false) + : allocation_plan_(plan), validation_mode_(validate) {} + void record_allocation(const uint64_t size, const void* ptr); + void record_free(const void* ptr); + void formulate_plan(); + void clear(); +}; + +// NOT THREAD SAFE profiling allocator. +class C10_API CPUProfilingAllocator { + private: + const AllocationPlan* plan_{nullptr}; + uint64_t allocation_id_{0}; + uint64_t current_size_{0}; + void* blob_{nullptr}; + ska::flat_hash_map allocation_ptr_to_id_; + + public: + ~CPUProfilingAllocator(); + void set_plan(const AllocationPlan* plan); + void unset_plan(); + void* allocate(const size_t bytes); + void free(void* const ptr); +}; + +/* + * Usage: Profile allocations made by one run of the model. + * AllocationPlan plan; + * { + * WithProfileAllocationGuard profile_guard(&plan); + * module.forward(...); + * } + * plan now contains allocation plan. + */ +class C10_API WithProfileAllocationsGuard { + public: + WithProfileAllocationsGuard(AllocationPlan* plan); + ~WithProfileAllocationsGuard(); + + private: + std::unique_ptr planner_; +}; + +/* + * Usage: Validate allocation plan made with WithProfileAllocationGuard + * bool plan_validation_success, success = true; + * for (some number of representative inputs) + * { + * WithValidateAllocationPlanGuard(&plan, &plan_validation_success); + * module.forward(...); + * success = success && plan_validation_success; + * } + * success == true means allocations are according to plan + * else for some inputs allocation pattern changed. + */ +class C10_API WithValidateAllocationPlanGuard { + public: + WithValidateAllocationPlanGuard(AllocationPlan* plan, bool* success); + ~WithValidateAllocationPlanGuard(); + + private: + std::unique_ptr planner_; + bool* success_; +}; + +AllocationPlanner* GetThreadLocalAllocationPlanner(); + +/* + * Usage: Allocate tensors accordingly to allocation plan + * First make allocation plan. + * See WithProfileAllocationsGuard usage. + * Second validate allocation plan. + * See WithValidateAllocationPlanGuard usage. + * CPUProfilingAllocator profiling_allocator; + * { + * WithProfilingAllocatorGuard allocator_guard(&profiling_allocator, &plan); + * module.forward(...); + * } + */ +class C10_API WithProfilingAllocatorGuard { + public: + WithProfilingAllocatorGuard( + CPUProfilingAllocator* allocator, + const AllocationPlan* plan); + ~WithProfilingAllocatorGuard(); +}; + +CPUProfilingAllocator* GetThreadLocalProfilingAllocator(); + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/test/util/Macros.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/test/util/Macros.h new file mode 100644 index 0000000000000000000000000000000000000000..026570edcd7f2be024266f65b5745a65036bbeed --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/test/util/Macros.h @@ -0,0 +1,14 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_TEST_CORE_MACROS_MACROS_H_ + +#ifdef _WIN32 +#define DISABLED_ON_WINDOWS(x) DISABLED_##x +#else +#define DISABLED_ON_WINDOWS(x) x +#endif + +#endif // C10_MACROS_MACROS_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/test/util/complex_math_test_common.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/test/util/complex_math_test_common.h new file mode 100644 index 0000000000000000000000000000000000000000..a68a35cd968a95ef35b61b92594837fcbdbf79a6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/test/util/complex_math_test_common.h @@ -0,0 +1,672 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Warning: this file is included twice in +// aten/src/ATen/test/cuda_complex_math_test.cu + +#include +#include + +#ifndef PI +#define PI 3.141592653589793238463 +#endif + +#ifndef tol +#define tol 1e-6 +#endif + +// Exponential functions + +C10_DEFINE_TEST(TestExponential, IPi) { + // exp(i*pi) = -1 + { + c10::complex e_i_pi = std::exp(c10::complex(0, float(PI))); + C10_ASSERT_NEAR(e_i_pi.real(), -1, tol); + C10_ASSERT_NEAR(e_i_pi.imag(), 0, tol); + } + { + c10::complex e_i_pi = ::exp(c10::complex(0, float(PI))); + C10_ASSERT_NEAR(e_i_pi.real(), -1, tol); + C10_ASSERT_NEAR(e_i_pi.imag(), 0, tol); + } + { + c10::complex e_i_pi = std::exp(c10::complex(0, PI)); + C10_ASSERT_NEAR(e_i_pi.real(), -1, tol); + C10_ASSERT_NEAR(e_i_pi.imag(), 0, tol); + } + { + c10::complex e_i_pi = ::exp(c10::complex(0, PI)); + C10_ASSERT_NEAR(e_i_pi.real(), -1, tol); + C10_ASSERT_NEAR(e_i_pi.imag(), 0, tol); + } +} + +C10_DEFINE_TEST(TestExponential, EulerFormula) { + // exp(ix) = cos(x) + i * sin(x) + { + c10::complex x(0.1, 1.2); + c10::complex e = std::exp(x); + float expected_real = std::exp(x.real()) * std::cos(x.imag()); + float expected_imag = std::exp(x.real()) * std::sin(x.imag()); + C10_ASSERT_NEAR(e.real(), expected_real, tol); + C10_ASSERT_NEAR(e.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex e = ::exp(x); + float expected_real = ::exp(x.real()) * ::cos(x.imag()); + float expected_imag = ::exp(x.real()) * ::sin(x.imag()); + C10_ASSERT_NEAR(e.real(), expected_real, tol); + C10_ASSERT_NEAR(e.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex e = std::exp(x); + float expected_real = std::exp(x.real()) * std::cos(x.imag()); + float expected_imag = std::exp(x.real()) * std::sin(x.imag()); + C10_ASSERT_NEAR(e.real(), expected_real, tol); + C10_ASSERT_NEAR(e.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex e = ::exp(x); + float expected_real = ::exp(x.real()) * ::cos(x.imag()); + float expected_imag = ::exp(x.real()) * ::sin(x.imag()); + C10_ASSERT_NEAR(e.real(), expected_real, tol); + C10_ASSERT_NEAR(e.imag(), expected_imag, tol); + } +} + +C10_DEFINE_TEST(TestExpm1, Normal) { + // expm1(x) = exp(x) - 1 + { + c10::complex x(0.1, 1.2); + c10::complex l1 = std::expm1(x); + c10::complex l2 = std::exp(x) - 1.0f; + C10_ASSERT_NEAR(l1.real(), l2.real(), tol); + C10_ASSERT_NEAR(l1.imag(), l2.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex l1 = std::expm1(x); + c10::complex l2 = std::exp(x) - 1.0; + C10_ASSERT_NEAR(l1.real(), l2.real(), tol); + C10_ASSERT_NEAR(l1.imag(), l2.imag(), tol); + } +} + +C10_DEFINE_TEST(TestExpm1, Small) { + // expm1(x) = exp(x) - 1 + // expm1(x) provides greater precision than exp(x) - 1 for small values of x + { + c10::complex x(1e-30, 1e-30); + c10::complex l1 = std::expm1(x); + C10_ASSERT_NEAR(l1.real(), 1e-30, tol); + C10_ASSERT_NEAR(l1.imag(), 1e-30, tol); + } + { + c10::complex x(1e-100, 1e-100); + c10::complex l1 = std::expm1(x); + C10_ASSERT_NEAR(l1.real(), 1e-30, tol); + C10_ASSERT_NEAR(l1.imag(), 1e-30, tol); + } +} + +C10_DEFINE_TEST(TestLog, Definition) { + // log(x) = log(r) + i*theta + { + c10::complex x(1.2, 3.4); + c10::complex l = std::log(x); + float expected_real = std::log(std::abs(x)); + float expected_imag = std::arg(x); + C10_ASSERT_NEAR(l.real(), expected_real, tol); + C10_ASSERT_NEAR(l.imag(), expected_imag, tol); + } + { + c10::complex x(1.2, 3.4); + c10::complex l = ::log(x); + float expected_real = ::log(std::abs(x)); + float expected_imag = std::arg(x); + C10_ASSERT_NEAR(l.real(), expected_real, tol); + C10_ASSERT_NEAR(l.imag(), expected_imag, tol); + } + { + c10::complex x(1.2, 3.4); + c10::complex l = std::log(x); + float expected_real = std::log(std::abs(x)); + float expected_imag = std::arg(x); + C10_ASSERT_NEAR(l.real(), expected_real, tol); + C10_ASSERT_NEAR(l.imag(), expected_imag, tol); + } + { + c10::complex x(1.2, 3.4); + c10::complex l = ::log(x); + float expected_real = ::log(std::abs(x)); + float expected_imag = std::arg(x); + C10_ASSERT_NEAR(l.real(), expected_real, tol); + C10_ASSERT_NEAR(l.imag(), expected_imag, tol); + } +} + +C10_DEFINE_TEST(TestLog10, Rev) { + // log10(10^x) = x + { + c10::complex x(0.1, 1.2); + c10::complex l = std::log10(std::pow(float(10), x)); + C10_ASSERT_NEAR(l.real(), float(0.1), tol); + C10_ASSERT_NEAR(l.imag(), float(1.2), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex l = ::log10(::pow(float(10), x)); + C10_ASSERT_NEAR(l.real(), float(0.1), tol); + C10_ASSERT_NEAR(l.imag(), float(1.2), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex l = std::log10(std::pow(double(10), x)); + C10_ASSERT_NEAR(l.real(), double(0.1), tol); + C10_ASSERT_NEAR(l.imag(), double(1.2), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex l = ::log10(::pow(double(10), x)); + C10_ASSERT_NEAR(l.real(), double(0.1), tol); + C10_ASSERT_NEAR(l.imag(), double(1.2), tol); + } +} + +C10_DEFINE_TEST(TestLog2, Rev) { + // log2(2^x) = x + { + c10::complex x(0.1, 1.2); + c10::complex l = std::log2(std::pow(float(2), x)); + C10_ASSERT_NEAR(l.real(), float(0.1), tol); + C10_ASSERT_NEAR(l.imag(), float(1.2), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex l = ::log2(std::pow(float(2), x)); + C10_ASSERT_NEAR(l.real(), float(0.1), tol); + C10_ASSERT_NEAR(l.imag(), float(1.2), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex l = std::log2(std::pow(double(2), x)); + C10_ASSERT_NEAR(l.real(), double(0.1), tol); + C10_ASSERT_NEAR(l.imag(), double(1.2), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex l = ::log2(std::pow(double(2), x)); + C10_ASSERT_NEAR(l.real(), double(0.1), tol); + C10_ASSERT_NEAR(l.imag(), double(1.2), tol); + } +} + +C10_DEFINE_TEST(TestLog1p, Normal) { + // log1p(x) = log(1 + x) + { + c10::complex x(0.1, 1.2); + c10::complex l1 = std::log1p(x); + c10::complex l2 = std::log(1.0f + x); + C10_ASSERT_NEAR(l1.real(), l2.real(), tol); + C10_ASSERT_NEAR(l1.imag(), l2.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex l1 = std::log1p(x); + c10::complex l2 = std::log(1.0 + x); + C10_ASSERT_NEAR(l1.real(), l2.real(), tol); + C10_ASSERT_NEAR(l1.imag(), l2.imag(), tol); + } +} + +C10_DEFINE_TEST(TestLog1p, Small) { + // log(1 + x) ~ x for |x| << 1 + { + c10::complex x(1e-9, 2e-9); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real() / x.real(), 1, tol); + C10_ASSERT_NEAR(l.imag() / x.imag(), 1, tol); + } + { + c10::complex x(1e-100, 2e-100); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real() / x.real(), 1, tol); + C10_ASSERT_NEAR(l.imag() / x.imag(), 1, tol); + } +} + +C10_DEFINE_TEST(TestLog1p, Extreme) { + // log(1 + x) ~ x for |x| << 1 and in the brink of overflow / underflow + { + c10::complex x(-1, 1e-30); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), -69.07755278982137, tol); + C10_ASSERT_NEAR(l.imag(), 1.5707963267948966, tol); + } + { + c10::complex x(-1, 1e30); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 69.07755278982137, tol); + C10_ASSERT_NEAR(l.imag(), 1.5707963267948966, tol); + } + { + c10::complex x(1e30, 1); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 69.07755278982137, tol); + C10_ASSERT_NEAR(l.imag(), 1e-30, tol); + } + { + c10::complex x(1e-30, 1); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 0.34657359027997264, tol); + C10_ASSERT_NEAR(l.imag(), 0.7853981633974483, tol); + } + { + c10::complex x(1e30, 1e30); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 69.42412638010134, tol); + C10_ASSERT_NEAR(l.imag(), 0.7853981633974483, tol); + } + { + c10::complex x(1e-38, 1e-38); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 1e-38, tol); + C10_ASSERT_NEAR(l.imag(), 1e-38, tol); + } + { + c10::complex x(1e-38, 2e-30); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 1e-30, tol); + C10_ASSERT_NEAR(l.imag(), 2e-30, tol); + } + { + c10::complex x(-1, 1e-250); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), -575.6462732485114, tol); + C10_ASSERT_NEAR(l.imag(), 1.5707963267948966, tol); + } + { + c10::complex x(-1, 1e250); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 575.6462732485114, tol); + C10_ASSERT_NEAR(l.imag(), 1.5707963267948966, tol); + } + { + c10::complex x(1e250, 1); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 575.6462732485114, tol); + C10_ASSERT_NEAR(l.imag(), 1e-250, tol); + } + { + c10::complex x(1e-250, 1); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 0.34657359027997264, tol); + C10_ASSERT_NEAR(l.imag(), 0.7853981633974483, tol); + } + { + c10::complex x(1e250, 1e250); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 575.9928468387914, tol); + C10_ASSERT_NEAR(l.imag(), 0.7853981633974483, tol); + } + { + c10::complex x(1e-250, 1e-250); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 1e-250, tol); + C10_ASSERT_NEAR(l.imag(), 1e-250, tol); + } + { + c10::complex x(1e-250, 2e-250); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 1e-250, tol); + C10_ASSERT_NEAR(l.imag(), 2e-250, tol); + } + { + c10::complex x(2e-308, 1.5e-250); + c10::complex l = std::log1p(x); + C10_ASSERT_NEAR(l.real(), 2e-308, tol); + C10_ASSERT_NEAR(l.imag(), 1.5e-308, tol); + } +} + +// Power functions + +C10_DEFINE_TEST(TestPowSqrt, Equal) { + // x^0.5 = sqrt(x) + { + c10::complex x(0.1, 1.2); + c10::complex y = std::pow(x, float(0.5)); + c10::complex z = std::sqrt(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::pow(x, float(0.5)); + c10::complex z = ::sqrt(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = std::pow(x, double(0.5)); + c10::complex z = std::sqrt(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::pow(x, double(0.5)); + c10::complex z = ::sqrt(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } +} + +C10_DEFINE_TEST(TestPow, Square) { + // x^2 = x * x + { + c10::complex x(0.1, 1.2); + c10::complex y = std::pow(x, float(2)); + c10::complex z = x * x; + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::pow(x, float(2)); + c10::complex z = x * x; + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = std::pow(x, double(2)); + c10::complex z = x * x; + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::pow(x, double(2)); + c10::complex z = x * x; + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } +} + +// Trigonometric functions and hyperbolic functions + +C10_DEFINE_TEST(TestSinCosSinhCosh, Identity) { + // sin(x + i * y) = sin(x) * cosh(y) + i * cos(x) * sinh(y) + // cos(x + i * y) = cos(x) * cosh(y) - i * sin(x) * sinh(y) + { + c10::complex x(0.1, 1.2); + c10::complex y = std::sin(x); + float expected_real = std::sin(x.real()) * std::cosh(x.imag()); + float expected_imag = std::cos(x.real()) * std::sinh(x.imag()); + C10_ASSERT_NEAR(y.real(), expected_real, tol); + C10_ASSERT_NEAR(y.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::sin(x); + float expected_real = ::sin(x.real()) * ::cosh(x.imag()); + float expected_imag = ::cos(x.real()) * ::sinh(x.imag()); + C10_ASSERT_NEAR(y.real(), expected_real, tol); + C10_ASSERT_NEAR(y.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = std::cos(x); + float expected_real = std::cos(x.real()) * std::cosh(x.imag()); + float expected_imag = -std::sin(x.real()) * std::sinh(x.imag()); + C10_ASSERT_NEAR(y.real(), expected_real, tol); + C10_ASSERT_NEAR(y.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::cos(x); + float expected_real = ::cos(x.real()) * ::cosh(x.imag()); + float expected_imag = -::sin(x.real()) * ::sinh(x.imag()); + C10_ASSERT_NEAR(y.real(), expected_real, tol); + C10_ASSERT_NEAR(y.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = std::sin(x); + float expected_real = std::sin(x.real()) * std::cosh(x.imag()); + float expected_imag = std::cos(x.real()) * std::sinh(x.imag()); + C10_ASSERT_NEAR(y.real(), expected_real, tol); + C10_ASSERT_NEAR(y.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::sin(x); + float expected_real = ::sin(x.real()) * ::cosh(x.imag()); + float expected_imag = ::cos(x.real()) * ::sinh(x.imag()); + C10_ASSERT_NEAR(y.real(), expected_real, tol); + C10_ASSERT_NEAR(y.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = std::cos(x); + float expected_real = std::cos(x.real()) * std::cosh(x.imag()); + float expected_imag = -std::sin(x.real()) * std::sinh(x.imag()); + C10_ASSERT_NEAR(y.real(), expected_real, tol); + C10_ASSERT_NEAR(y.imag(), expected_imag, tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::cos(x); + float expected_real = ::cos(x.real()) * ::cosh(x.imag()); + float expected_imag = -::sin(x.real()) * ::sinh(x.imag()); + C10_ASSERT_NEAR(y.real(), expected_real, tol); + C10_ASSERT_NEAR(y.imag(), expected_imag, tol); + } +} + +C10_DEFINE_TEST(TestTan, Identity) { + // tan(x) = sin(x) / cos(x) + { + c10::complex x(0.1, 1.2); + c10::complex y = std::tan(x); + c10::complex z = std::sin(x) / std::cos(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::tan(x); + c10::complex z = ::sin(x) / ::cos(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = std::tan(x); + c10::complex z = std::sin(x) / std::cos(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::tan(x); + c10::complex z = ::sin(x) / ::cos(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } +} + +C10_DEFINE_TEST(TestTanh, Identity) { + // tanh(x) = sinh(x) / cosh(x) + { + c10::complex x(0.1, 1.2); + c10::complex y = std::tanh(x); + c10::complex z = std::sinh(x) / std::cosh(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::tanh(x); + c10::complex z = ::sinh(x) / ::cosh(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = std::tanh(x); + c10::complex z = std::sinh(x) / std::cosh(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } + { + c10::complex x(0.1, 1.2); + c10::complex y = ::tanh(x); + c10::complex z = ::sinh(x) / ::cosh(x); + C10_ASSERT_NEAR(y.real(), z.real(), tol); + C10_ASSERT_NEAR(y.imag(), z.imag(), tol); + } +} + +// Rev trigonometric functions + +C10_DEFINE_TEST(TestRevTrigonometric, Rev) { + // asin(sin(x)) = x + // acos(cos(x)) = x + // atan(tan(x)) = x + { + c10::complex x(0.5, 0.6); + c10::complex s = std::sin(x); + c10::complex ss = std::asin(s); + c10::complex c = std::cos(x); + c10::complex cc = std::acos(c); + c10::complex t = std::tan(x); + c10::complex tt = std::atan(t); + C10_ASSERT_NEAR(x.real(), ss.real(), tol); + C10_ASSERT_NEAR(x.imag(), ss.imag(), tol); + C10_ASSERT_NEAR(x.real(), cc.real(), tol); + C10_ASSERT_NEAR(x.imag(), cc.imag(), tol); + C10_ASSERT_NEAR(x.real(), tt.real(), tol); + C10_ASSERT_NEAR(x.imag(), tt.imag(), tol); + } + { + c10::complex x(0.5, 0.6); + c10::complex s = ::sin(x); + c10::complex ss = ::asin(s); + c10::complex c = ::cos(x); + c10::complex cc = ::acos(c); + c10::complex t = ::tan(x); + c10::complex tt = ::atan(t); + C10_ASSERT_NEAR(x.real(), ss.real(), tol); + C10_ASSERT_NEAR(x.imag(), ss.imag(), tol); + C10_ASSERT_NEAR(x.real(), cc.real(), tol); + C10_ASSERT_NEAR(x.imag(), cc.imag(), tol); + C10_ASSERT_NEAR(x.real(), tt.real(), tol); + C10_ASSERT_NEAR(x.imag(), tt.imag(), tol); + } + { + c10::complex x(0.5, 0.6); + c10::complex s = std::sin(x); + c10::complex ss = std::asin(s); + c10::complex c = std::cos(x); + c10::complex cc = std::acos(c); + c10::complex t = std::tan(x); + c10::complex tt = std::atan(t); + C10_ASSERT_NEAR(x.real(), ss.real(), tol); + C10_ASSERT_NEAR(x.imag(), ss.imag(), tol); + C10_ASSERT_NEAR(x.real(), cc.real(), tol); + C10_ASSERT_NEAR(x.imag(), cc.imag(), tol); + C10_ASSERT_NEAR(x.real(), tt.real(), tol); + C10_ASSERT_NEAR(x.imag(), tt.imag(), tol); + } + { + c10::complex x(0.5, 0.6); + c10::complex s = ::sin(x); + c10::complex ss = ::asin(s); + c10::complex c = ::cos(x); + c10::complex cc = ::acos(c); + c10::complex t = ::tan(x); + c10::complex tt = ::atan(t); + C10_ASSERT_NEAR(x.real(), ss.real(), tol); + C10_ASSERT_NEAR(x.imag(), ss.imag(), tol); + C10_ASSERT_NEAR(x.real(), cc.real(), tol); + C10_ASSERT_NEAR(x.imag(), cc.imag(), tol); + C10_ASSERT_NEAR(x.real(), tt.real(), tol); + C10_ASSERT_NEAR(x.imag(), tt.imag(), tol); + } +} + +// Rev hyperbolic functions + +C10_DEFINE_TEST(TestRevHyperbolic, Rev) { + // asinh(sinh(x)) = x + // acosh(cosh(x)) = x + // atanh(tanh(x)) = x + { + c10::complex x(0.5, 0.6); + c10::complex s = std::sinh(x); + c10::complex ss = std::asinh(s); + c10::complex c = std::cosh(x); + c10::complex cc = std::acosh(c); + c10::complex t = std::tanh(x); + c10::complex tt = std::atanh(t); + C10_ASSERT_NEAR(x.real(), ss.real(), tol); + C10_ASSERT_NEAR(x.imag(), ss.imag(), tol); + C10_ASSERT_NEAR(x.real(), cc.real(), tol); + C10_ASSERT_NEAR(x.imag(), cc.imag(), tol); + C10_ASSERT_NEAR(x.real(), tt.real(), tol); + C10_ASSERT_NEAR(x.imag(), tt.imag(), tol); + } + { + c10::complex x(0.5, 0.6); + c10::complex s = ::sinh(x); + c10::complex ss = ::asinh(s); + c10::complex c = ::cosh(x); + c10::complex cc = ::acosh(c); + c10::complex t = ::tanh(x); + c10::complex tt = ::atanh(t); + C10_ASSERT_NEAR(x.real(), ss.real(), tol); + C10_ASSERT_NEAR(x.imag(), ss.imag(), tol); + C10_ASSERT_NEAR(x.real(), cc.real(), tol); + C10_ASSERT_NEAR(x.imag(), cc.imag(), tol); + C10_ASSERT_NEAR(x.real(), tt.real(), tol); + C10_ASSERT_NEAR(x.imag(), tt.imag(), tol); + } + { + c10::complex x(0.5, 0.6); + c10::complex s = std::sinh(x); + c10::complex ss = std::asinh(s); + c10::complex c = std::cosh(x); + c10::complex cc = std::acosh(c); + c10::complex t = std::tanh(x); + c10::complex tt = std::atanh(t); + C10_ASSERT_NEAR(x.real(), ss.real(), tol); + C10_ASSERT_NEAR(x.imag(), ss.imag(), tol); + C10_ASSERT_NEAR(x.real(), cc.real(), tol); + C10_ASSERT_NEAR(x.imag(), cc.imag(), tol); + C10_ASSERT_NEAR(x.real(), tt.real(), tol); + C10_ASSERT_NEAR(x.imag(), tt.imag(), tol); + } + { + c10::complex x(0.5, 0.6); + c10::complex s = ::sinh(x); + c10::complex ss = ::asinh(s); + c10::complex c = ::cosh(x); + c10::complex cc = ::acosh(c); + c10::complex t = ::tanh(x); + c10::complex tt = ::atanh(t); + C10_ASSERT_NEAR(x.real(), ss.real(), tol); + C10_ASSERT_NEAR(x.imag(), ss.imag(), tol); + C10_ASSERT_NEAR(x.real(), cc.real(), tol); + C10_ASSERT_NEAR(x.imag(), cc.imag(), tol); + C10_ASSERT_NEAR(x.real(), tt.real(), tol); + C10_ASSERT_NEAR(x.imag(), tt.imag(), tol); + } +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/test/util/complex_test_common.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/test/util/complex_test_common.h new file mode 100644 index 0000000000000000000000000000000000000000..5987975e44f96edec195cdb00b970962ca629d18 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/test/util/complex_test_common.h @@ -0,0 +1,655 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include +#include +#include +#include +#include +#include +#include +#include + +#if (defined(__CUDACC__) || defined(__HIPCC__)) +#define MAYBE_GLOBAL __global__ +#else +#define MAYBE_GLOBAL +#endif + +#define PI 3.141592653589793238463 + +namespace memory { + +MAYBE_GLOBAL void test_size() { + static_assert(sizeof(c10::complex) == 2 * sizeof(float), ""); + static_assert(sizeof(c10::complex) == 2 * sizeof(double), ""); +} + +MAYBE_GLOBAL void test_align() { + static_assert(alignof(c10::complex) == 2 * sizeof(float), ""); + static_assert(alignof(c10::complex) == 2 * sizeof(double), ""); +} + +MAYBE_GLOBAL void test_pod() { + static_assert(std::is_standard_layout>::value, ""); + static_assert(std::is_standard_layout>::value, ""); +} + +TEST(TestMemory, ReinterpretCast) { + { + std::complex z(1, 2); + c10::complex zz = *reinterpret_cast*>(&z); + ASSERT_EQ(zz.real(), float(1)); + ASSERT_EQ(zz.imag(), float(2)); + } + + { + c10::complex z(3, 4); + std::complex zz = *reinterpret_cast*>(&z); + ASSERT_EQ(zz.real(), float(3)); + ASSERT_EQ(zz.imag(), float(4)); + } + + { + std::complex z(1, 2); + c10::complex zz = *reinterpret_cast*>(&z); + ASSERT_EQ(zz.real(), double(1)); + ASSERT_EQ(zz.imag(), double(2)); + } + + { + c10::complex z(3, 4); + std::complex zz = *reinterpret_cast*>(&z); + ASSERT_EQ(zz.real(), double(3)); + ASSERT_EQ(zz.imag(), double(4)); + } +} + +#if defined(__CUDACC__) || defined(__HIPCC__) +TEST(TestMemory, ThrustReinterpretCast) { + { + thrust::complex z(1, 2); + c10::complex zz = *reinterpret_cast*>(&z); + ASSERT_EQ(zz.real(), float(1)); + ASSERT_EQ(zz.imag(), float(2)); + } + + { + c10::complex z(3, 4); + thrust::complex zz = *reinterpret_cast*>(&z); + ASSERT_EQ(zz.real(), float(3)); + ASSERT_EQ(zz.imag(), float(4)); + } + + { + thrust::complex z(1, 2); + c10::complex zz = *reinterpret_cast*>(&z); + ASSERT_EQ(zz.real(), double(1)); + ASSERT_EQ(zz.imag(), double(2)); + } + + { + c10::complex z(3, 4); + thrust::complex zz = + *reinterpret_cast*>(&z); + ASSERT_EQ(zz.real(), double(3)); + ASSERT_EQ(zz.imag(), double(4)); + } +} +#endif + +} // namespace memory + +namespace constructors { + +template +C10_HOST_DEVICE void test_construct_from_scalar() { + constexpr scalar_t num1 = scalar_t(1.23); + constexpr scalar_t num2 = scalar_t(4.56); + constexpr scalar_t zero = scalar_t(); + static_assert(c10::complex(num1, num2).real() == num1, ""); + static_assert(c10::complex(num1, num2).imag() == num2, ""); + static_assert(c10::complex(num1).real() == num1, ""); + static_assert(c10::complex(num1).imag() == zero, ""); + static_assert(c10::complex().real() == zero, ""); + static_assert(c10::complex().imag() == zero, ""); +} + +template +C10_HOST_DEVICE void test_construct_from_other() { + constexpr other_t num1 = other_t(1.23); + constexpr other_t num2 = other_t(4.56); + constexpr scalar_t num3 = scalar_t(num1); + constexpr scalar_t num4 = scalar_t(num2); + static_assert( + c10::complex(c10::complex(num1, num2)).real() == num3, + ""); + static_assert( + c10::complex(c10::complex(num1, num2)).imag() == num4, + ""); +} + +MAYBE_GLOBAL void test_convert_constructors() { + test_construct_from_scalar(); + test_construct_from_scalar(); + + static_assert( + std::is_convertible, c10::complex>::value, ""); + static_assert( + !std::is_convertible, c10::complex>::value, + ""); + static_assert( + std::is_convertible, c10::complex>::value, + ""); + static_assert( + std::is_convertible, c10::complex>::value, + ""); + + static_assert( + std::is_constructible, c10::complex>::value, + ""); + static_assert( + std::is_constructible, c10::complex>::value, + ""); + static_assert( + std::is_constructible, c10::complex>::value, + ""); + static_assert( + std::is_constructible, c10::complex>::value, + ""); + + test_construct_from_other(); + test_construct_from_other(); + test_construct_from_other(); + test_construct_from_other(); +} + +template +C10_HOST_DEVICE void test_construct_from_std() { + constexpr scalar_t num1 = scalar_t(1.23); + constexpr scalar_t num2 = scalar_t(4.56); + static_assert( + c10::complex(std::complex(num1, num2)).real() == num1, + ""); + static_assert( + c10::complex(std::complex(num1, num2)).imag() == num2, + ""); +} + +MAYBE_GLOBAL void test_std_conversion() { + test_construct_from_std(); + test_construct_from_std(); +} + +#if defined(__CUDACC__) || defined(__HIPCC__) +template +void test_construct_from_thrust() { + constexpr scalar_t num1 = scalar_t(1.23); + constexpr scalar_t num2 = scalar_t(4.56); + ASSERT_EQ( + c10::complex(thrust::complex(num1, num2)).real(), + num1); + ASSERT_EQ( + c10::complex(thrust::complex(num1, num2)).imag(), + num2); +} + +TEST(TestConstructors, FromThrust) { + test_construct_from_thrust(); + test_construct_from_thrust(); +} +#endif + +TEST(TestConstructors, UnorderedMap) { + std::unordered_map< + c10::complex, + c10::complex, + c10::hash>> + m; + auto key1 = c10::complex(2.5, 3); + auto key2 = c10::complex(2, 0); + auto val1 = c10::complex(2, -3.2); + auto val2 = c10::complex(0, -3); + m[key1] = val1; + m[key2] = val2; + ASSERT_EQ(m[key1], val1); + ASSERT_EQ(m[key2], val2); +} + +} // namespace constructors + +namespace assignment { + +template +constexpr c10::complex one() { + c10::complex result(3, 4); + result = scalar_t(1); + return result; +} + +MAYBE_GLOBAL void test_assign_real() { + static_assert(one().real() == float(1), ""); + static_assert(one().imag() == float(), ""); + static_assert(one().real() == double(1), ""); + static_assert(one().imag() == double(), ""); +} + +constexpr std::tuple, c10::complex> one_two() { + constexpr c10::complex src(1, 2); + c10::complex ret0; + c10::complex ret1; + ret0 = ret1 = src; + return std::make_tuple(ret0, ret1); +} + +MAYBE_GLOBAL void test_assign_other() { + constexpr auto tup = one_two(); + static_assert(std::get>(tup).real() == double(1), ""); + static_assert(std::get>(tup).imag() == double(2), ""); + static_assert(std::get>(tup).real() == float(1), ""); + static_assert(std::get>(tup).imag() == float(2), ""); +} + +constexpr std::tuple, c10::complex> one_two_std() { + constexpr std::complex src(1, 1); + c10::complex ret0; + c10::complex ret1; + ret0 = ret1 = src; + return std::make_tuple(ret0, ret1); +} + +MAYBE_GLOBAL void test_assign_std() { + constexpr auto tup = one_two(); + static_assert(std::get>(tup).real() == double(1), ""); + static_assert(std::get>(tup).imag() == double(2), ""); + static_assert(std::get>(tup).real() == float(1), ""); + static_assert(std::get>(tup).imag() == float(2), ""); +} + +#if defined(__CUDACC__) || defined(__HIPCC__) +C10_HOST_DEVICE std::tuple, c10::complex> +one_two_thrust() { + thrust::complex src(1, 2); + c10::complex ret0; + c10::complex ret1; + ret0 = ret1 = src; + return std::make_tuple(ret0, ret1); +} + +TEST(TestAssignment, FromThrust) { + auto tup = one_two_thrust(); + ASSERT_EQ(std::get>(tup).real(), double(1)); + ASSERT_EQ(std::get>(tup).imag(), double(2)); + ASSERT_EQ(std::get>(tup).real(), float(1)); + ASSERT_EQ(std::get>(tup).imag(), float(2)); +} +#endif + +} // namespace assignment + +namespace literals { + +MAYBE_GLOBAL void test_complex_literals() { + using namespace c10::complex_literals; + static_assert(std::is_same>::value, ""); + static_assert((0.5_if).real() == float(), ""); + static_assert((0.5_if).imag() == float(0.5), ""); + static_assert( + std::is_same>::value, ""); + static_assert((0.5_id).real() == float(), ""); + static_assert((0.5_id).imag() == float(0.5), ""); + + static_assert(std::is_same>::value, ""); + static_assert((1_if).real() == float(), ""); + static_assert((1_if).imag() == float(1), ""); + static_assert(std::is_same>::value, ""); + static_assert((1_id).real() == double(), ""); + static_assert((1_id).imag() == double(1), ""); +} + +} // namespace literals + +namespace real_imag { + +template +constexpr c10::complex zero_one() { + c10::complex result; + result.imag(scalar_t(1)); + return result; +} + +template +constexpr c10::complex one_zero() { + c10::complex result; + result.real(scalar_t(1)); + return result; +} + +MAYBE_GLOBAL void test_real_imag_modify() { + static_assert(zero_one().real() == float(0), ""); + static_assert(zero_one().imag() == float(1), ""); + static_assert(zero_one().real() == double(0), ""); + static_assert(zero_one().imag() == double(1), ""); + + static_assert(one_zero().real() == float(1), ""); + static_assert(one_zero().imag() == float(0), ""); + static_assert(one_zero().real() == double(1), ""); + static_assert(one_zero().imag() == double(0), ""); +} + +} // namespace real_imag + +namespace arithmetic_assign { + +template +constexpr c10::complex p(scalar_t value) { + c10::complex result(scalar_t(2), scalar_t(2)); + result += value; + return result; +} + +template +constexpr c10::complex m(scalar_t value) { + c10::complex result(scalar_t(2), scalar_t(2)); + result -= value; + return result; +} + +template +constexpr c10::complex t(scalar_t value) { + c10::complex result(scalar_t(2), scalar_t(2)); + result *= value; + return result; +} + +template +constexpr c10::complex d(scalar_t value) { + c10::complex result(scalar_t(2), scalar_t(2)); + result /= value; + return result; +} + +template +C10_HOST_DEVICE void test_arithmetic_assign_scalar() { + constexpr c10::complex x = p(scalar_t(1)); + static_assert(x.real() == scalar_t(3), ""); + static_assert(x.imag() == scalar_t(2), ""); + constexpr c10::complex y = m(scalar_t(1)); + static_assert(y.real() == scalar_t(1), ""); + static_assert(y.imag() == scalar_t(2), ""); + constexpr c10::complex z = t(scalar_t(2)); + static_assert(z.real() == scalar_t(4), ""); + static_assert(z.imag() == scalar_t(4), ""); + constexpr c10::complex t = d(scalar_t(2)); + static_assert(t.real() == scalar_t(1), ""); + static_assert(t.imag() == scalar_t(1), ""); +} + +template +constexpr c10::complex p( + scalar_t real, + scalar_t imag, + c10::complex rhs) { + c10::complex result(real, imag); + result += rhs; + return result; +} + +template +constexpr c10::complex m( + scalar_t real, + scalar_t imag, + c10::complex rhs) { + c10::complex result(real, imag); + result -= rhs; + return result; +} + +template +constexpr c10::complex t( + scalar_t real, + scalar_t imag, + c10::complex rhs) { + c10::complex result(real, imag); + result *= rhs; + return result; +} + +template +constexpr c10::complex d( + scalar_t real, + scalar_t imag, + c10::complex rhs) { + c10::complex result(real, imag); + result /= rhs; + return result; +} + +template +C10_HOST_DEVICE void test_arithmetic_assign_complex() { + using namespace c10::complex_literals; + constexpr c10::complex x2 = p(scalar_t(2), scalar_t(2), 1.0_if); + static_assert(x2.real() == scalar_t(2), ""); + static_assert(x2.imag() == scalar_t(3), ""); + constexpr c10::complex x3 = p(scalar_t(2), scalar_t(2), 1.0_id); + static_assert(x3.real() == scalar_t(2), ""); + + static_assert(x3.imag() == scalar_t(3), ""); + + constexpr c10::complex y2 = m(scalar_t(2), scalar_t(2), 1.0_if); + static_assert(y2.real() == scalar_t(2), ""); + static_assert(y2.imag() == scalar_t(1), ""); + constexpr c10::complex y3 = m(scalar_t(2), scalar_t(2), 1.0_id); + static_assert(y3.real() == scalar_t(2), ""); + + static_assert(y3.imag() == scalar_t(1), ""); + + constexpr c10::complex z2 = t(scalar_t(1), scalar_t(-2), 1.0_if); + static_assert(z2.real() == scalar_t(2), ""); + static_assert(z2.imag() == scalar_t(1), ""); + constexpr c10::complex z3 = t(scalar_t(1), scalar_t(-2), 1.0_id); + static_assert(z3.real() == scalar_t(2), ""); + static_assert(z3.imag() == scalar_t(1), ""); + + constexpr c10::complex t2 = d(scalar_t(-1), scalar_t(2), 1.0_if); + static_assert(t2.real() == scalar_t(2), ""); + static_assert(t2.imag() == scalar_t(1), ""); + constexpr c10::complex t3 = d(scalar_t(-1), scalar_t(2), 1.0_id); + static_assert(t3.real() == scalar_t(2), ""); + static_assert(t3.imag() == scalar_t(1), ""); +} + +MAYBE_GLOBAL void test_arithmetic_assign() { + test_arithmetic_assign_scalar(); + test_arithmetic_assign_scalar(); + test_arithmetic_assign_complex(); + test_arithmetic_assign_complex(); +} + +} // namespace arithmetic_assign + +namespace arithmetic { + +template +C10_HOST_DEVICE void test_arithmetic_() { + static_assert( + c10::complex(1, 2) == +c10::complex(1, 2), ""); + static_assert( + c10::complex(-1, -2) == -c10::complex(1, 2), ""); + + static_assert( + c10::complex(1, 2) + c10::complex(3, 4) == + c10::complex(4, 6), + ""); + static_assert( + c10::complex(1, 2) + scalar_t(3) == + c10::complex(4, 2), + ""); + static_assert( + scalar_t(3) + c10::complex(1, 2) == + c10::complex(4, 2), + ""); + + static_assert( + c10::complex(1, 2) - c10::complex(3, 4) == + c10::complex(-2, -2), + ""); + static_assert( + c10::complex(1, 2) - scalar_t(3) == + c10::complex(-2, 2), + ""); + static_assert( + scalar_t(3) - c10::complex(1, 2) == + c10::complex(2, -2), + ""); + + static_assert( + c10::complex(1, 2) * c10::complex(3, 4) == + c10::complex(-5, 10), + ""); + static_assert( + c10::complex(1, 2) * scalar_t(3) == + c10::complex(3, 6), + ""); + static_assert( + scalar_t(3) * c10::complex(1, 2) == + c10::complex(3, 6), + ""); + + static_assert( + c10::complex(-5, 10) / c10::complex(3, 4) == + c10::complex(1, 2), + ""); + static_assert( + c10::complex(5, 10) / scalar_t(5) == + c10::complex(1, 2), + ""); + static_assert( + scalar_t(25) / c10::complex(3, 4) == + c10::complex(3, -4), + ""); +} + +MAYBE_GLOBAL void test_arithmetic() { + test_arithmetic_(); + test_arithmetic_(); +} + +template +void test_binary_ops_for_int_type_(T real, T img, int_t num) { + c10::complex c(real, img); + ASSERT_EQ(c + num, c10::complex(real + num, img)); + ASSERT_EQ(num + c, c10::complex(num + real, img)); + ASSERT_EQ(c - num, c10::complex(real - num, img)); + ASSERT_EQ(num - c, c10::complex(num - real, -img)); + ASSERT_EQ(c * num, c10::complex(real * num, img * num)); + ASSERT_EQ(num * c, c10::complex(num * real, num * img)); + ASSERT_EQ(c / num, c10::complex(real / num, img / num)); + ASSERT_EQ( + num / c, + c10::complex(num * real / std::norm(c), -num * img / std::norm(c))); +} + +template +void test_binary_ops_for_all_int_types_(T real, T img, int8_t i) { + test_binary_ops_for_int_type_(real, img, i); + test_binary_ops_for_int_type_(real, img, i); + test_binary_ops_for_int_type_(real, img, i); + test_binary_ops_for_int_type_(real, img, i); +} + +TEST(TestArithmeticIntScalar, All) { + test_binary_ops_for_all_int_types_(1.0, 0.1, 1); + test_binary_ops_for_all_int_types_(-1.3, -0.2, -2); +} + +} // namespace arithmetic + +namespace equality { + +template +C10_HOST_DEVICE void test_equality_() { + static_assert( + c10::complex(1, 2) == c10::complex(1, 2), ""); + static_assert(c10::complex(1, 0) == scalar_t(1), ""); + static_assert(scalar_t(1) == c10::complex(1, 0), ""); + static_assert( + c10::complex(1, 2) != c10::complex(3, 4), ""); + static_assert(c10::complex(1, 2) != scalar_t(1), ""); + static_assert(scalar_t(1) != c10::complex(1, 2), ""); +} + +MAYBE_GLOBAL void test_equality() { + test_equality_(); + test_equality_(); +} + +} // namespace equality + +namespace io { + +template +void test_io_() { + std::stringstream ss; + c10::complex a(1, 2); + ss << a; + ASSERT_EQ(ss.str(), "(1,2)"); + ss.str("(3,4)"); + ss >> a; + ASSERT_TRUE(a == c10::complex(3, 4)); +} + +TEST(TestIO, All) { + test_io_(); + test_io_(); +} + +} // namespace io + +namespace test_std { + +template +C10_HOST_DEVICE void test_callable_() { + static_assert(std::real(c10::complex(1, 2)) == scalar_t(1), ""); + static_assert(std::imag(c10::complex(1, 2)) == scalar_t(2), ""); + std::abs(c10::complex(1, 2)); + std::arg(c10::complex(1, 2)); + static_assert(std::norm(c10::complex(3, 4)) == scalar_t(25), ""); + static_assert( + std::conj(c10::complex(3, 4)) == c10::complex(3, -4), + ""); + c10::polar(float(1), float(PI / 2)); + c10::polar(double(1), double(PI / 2)); +} + +MAYBE_GLOBAL void test_callable() { + test_callable_(); + test_callable_(); +} + +template +void test_values_() { + ASSERT_EQ(std::abs(c10::complex(3, 4)), scalar_t(5)); + ASSERT_LT(std::abs(std::arg(c10::complex(0, 1)) - PI / 2), 1e-6); + ASSERT_LT( + std::abs( + c10::polar(scalar_t(1), scalar_t(PI / 2)) - + c10::complex(0, 1)), + 1e-6); +} + +TEST(TestStd, BasicFunctions) { + test_values_(); + test_values_(); + // CSQRT edge cases: checks for overflows which are likely to occur + // if square root is computed using polar form + ASSERT_LT( + std::abs(std::sqrt(c10::complex(-1e20, -4988429.2)).real()), 3e-4); + ASSERT_LT( + std::abs(std::sqrt(c10::complex(-1e60, -4988429.2)).real()), + 3e-4); +} + +} // namespace test_std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/AbortHandler.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/AbortHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..f7bcaaa28af3871f95280a9bd764aea260405ca1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/AbortHandler.h @@ -0,0 +1,88 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { +class AbortHandlerHelper { + public: + static AbortHandlerHelper& getInstance() { +#ifdef _WIN32 + thread_local +#endif // _WIN32 + static AbortHandlerHelper instance; + return instance; + } + + void set(std::terminate_handler handler) { + std::lock_guard lk(mutex); + if (!inited) { + prev = std::set_terminate(handler); + curr = std::get_terminate(); + inited = true; + } + } + + std::terminate_handler getPrev() const { + return prev; + } + + private: + std::terminate_handler prev = nullptr; + std::terminate_handler curr = nullptr; + bool inited = false; + std::mutex mutex; + AbortHandlerHelper() = default; + ~AbortHandlerHelper() { + // Only restore the handler if we are the current one + if (inited && curr == std::get_terminate()) { + std::set_terminate(prev); + } + } + + public: + AbortHandlerHelper(AbortHandlerHelper const&) = delete; + void operator=(AbortHandlerHelper const&) = delete; + AbortHandlerHelper(AbortHandlerHelper&&) = delete; + void operator=(AbortHandlerHelper&&) = delete; +}; + +namespace detail { +C10_ALWAYS_INLINE void terminate_handler() { + std::cout << "Unhandled exception caught in c10/util/AbortHandler.h" << '\n'; + auto backtrace = get_backtrace(); + std::cout << backtrace << '\n' << std::flush; + auto prev_handler = AbortHandlerHelper::getInstance().getPrev(); + if (prev_handler) { + prev_handler(); + } else { + std::abort(); + } +} +} // namespace detail + +C10_ALWAYS_INLINE void set_terminate_handler() { + bool use_custom_terminate = false; + // On Windows it is enabled by default based on + // https://github.com/pytorch/pytorch/pull/50320#issuecomment-763147062 +#ifdef _WIN32 + use_custom_terminate = true; +#endif // _WIN32 + auto result = c10::utils::check_env("TORCH_CUSTOM_TERMINATE"); + if (result != std::nullopt) { + use_custom_terminate = result.value(); + } + if (use_custom_terminate) { + AbortHandlerHelper::getInstance().set(detail::terminate_handler); + } +} +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/AlignOf.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/AlignOf.h new file mode 100644 index 0000000000000000000000000000000000000000..ce9fe90961700f2a1dd3f9c25e120eaa9609fc03 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/AlignOf.h @@ -0,0 +1,181 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +//===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the AlignedCharArray and AlignedCharArrayUnion classes. +// +//===----------------------------------------------------------------------===// + +// ATen: modified from llvm::AlignOf +// replaced LLVM_ALIGNAS with alignas + +#pragma once + +#include + +namespace c10 { + +/// \struct AlignedCharArray +/// \brief Helper for building an aligned character array type. +/// +/// This template is used to explicitly build up a collection of aligned +/// character array types. We have to build these up using a macro and explicit +/// specialization to cope with MSVC (at least till 2015) where only an +/// integer literal can be used to specify an alignment constraint. Once built +/// up here, we can then begin to indirect between these using normal C++ +/// template parameters. + +// MSVC requires special handling here. +#ifndef _MSC_VER + +template +struct AlignedCharArray { + // NOLINTNEXTLINE(*c-arrays) + alignas(Alignment) char buffer[Size]; +}; + +#else // _MSC_VER + +/// \brief Create a type with an aligned char buffer. +template +struct AlignedCharArray; + +// We provide special variations of this template for the most common +// alignments because __declspec(align(...)) doesn't actually work when it is +// a member of a by-value function argument in MSVC, even if the alignment +// request is something reasonably like 8-byte or 16-byte. Note that we can't +// even include the declspec with the union that forces the alignment because +// MSVC warns on the existence of the declspec despite the union member forcing +// proper alignment. + +template +struct AlignedCharArray<1, Size> { + union { + char aligned; + char buffer[Size]; + }; +}; + +template +struct AlignedCharArray<2, Size> { + union { + short aligned; + char buffer[Size]; + }; +}; + +template +struct AlignedCharArray<4, Size> { + union { + int aligned; + char buffer[Size]; + }; +}; + +template +struct AlignedCharArray<8, Size> { + union { + double aligned; + char buffer[Size]; + }; +}; + +// The rest of these are provided with a __declspec(align(...)) and we simply +// can't pass them by-value as function arguments on MSVC. + +#define AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ + template \ + struct AlignedCharArray { \ + __declspec(align(x)) char buffer[Size]; \ + }; + +AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16) +AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32) +AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64) +AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) + +#undef AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT + +#endif // _MSC_VER + +namespace detail { +template < + typename T1, + typename T2 = char, + typename T3 = char, + typename T4 = char, + typename T5 = char, + typename T6 = char, + typename T7 = char, + typename T8 = char, + typename T9 = char, + typename T10 = char> +class AlignerImpl { + T1 t1; + T2 t2; + T3 t3; + T4 t4; + T5 t5; + T6 t6; + T7 t7; + T8 t8; + T9 t9; + T10 t10; + + public: + AlignerImpl() = delete; +}; + +template < + typename T1, + typename T2 = char, + typename T3 = char, + typename T4 = char, + typename T5 = char, + typename T6 = char, + typename T7 = char, + typename T8 = char, + typename T9 = char, + typename T10 = char> +union SizerImpl { + // NOLINTNEXTLINE(*c-arrays) + char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)], + arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)], + arr9[sizeof(T9)], arr10[sizeof(T10)]; +}; +} // end namespace detail + +/// \brief This union template exposes a suitably aligned and sized character +/// array member which can hold elements of any of up to ten types. +/// +/// These types may be arrays, structs, or any other types. The goal is to +/// expose a char array buffer member which can be used as suitable storage for +/// a placement new of any of these types. Support for more than ten types can +/// be added at the cost of more boilerplate. +template < + typename T1, + typename T2 = char, + typename T3 = char, + typename T4 = char, + typename T5 = char, + typename T6 = char, + typename T7 = char, + typename T8 = char, + typename T9 = char, + typename T10 = char> +struct AlignedCharArrayUnion + : AlignedCharArray< + alignof(detail::AlignerImpl), + sizeof(::c10::detail:: + SizerImpl)> {}; +} // end namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ApproximateClock.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ApproximateClock.h new file mode 100644 index 0000000000000000000000000000000000000000..71528d334c33b40c7b5bb4ba7f0f11d706c83221 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ApproximateClock.h @@ -0,0 +1,132 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Copyright 2023-present Facebook. All Rights Reserved. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(C10_IOS) && defined(C10_MOBILE) +#include // for gettimeofday() +#endif + +#if defined(__i386__) || defined(__x86_64__) || defined(__amd64__) +#define C10_RDTSC +#if defined(_MSC_VER) +#include +#elif defined(__CUDACC__) || defined(__HIPCC__) +#undef C10_RDTSC +#elif defined(__clang__) +// `__rdtsc` is available by default. +// NB: This has to be first, because Clang will also define `__GNUC__` +#elif defined(__GNUC__) +#include +#else +#undef C10_RDTSC +#endif +#elif defined(__aarch64__) && !defined(__CUDACC__) && !defined(__HIPCC__) +#define C10_ARMTSC +#endif + +namespace c10 { + +using time_t = int64_t; +using steady_clock_t = std::conditional_t< + std::chrono::high_resolution_clock::is_steady, + std::chrono::high_resolution_clock, + std::chrono::steady_clock>; + +inline time_t getTimeSinceEpoch() { + auto now = std::chrono::system_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count(); +} + +inline time_t getTime(bool allow_monotonic = false) { +#if defined(C10_IOS) && defined(C10_MOBILE) + // clock_gettime is only available on iOS 10.0 or newer. Unlike OS X, iOS + // can't rely on CLOCK_REALTIME, as it is defined no matter if clock_gettime + // is implemented or not + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000000000 + + static_cast(now.tv_usec) * 1000; +#elif defined(_WIN32) || defined(__MACH__) + return std::chrono::duration_cast( + steady_clock_t::now().time_since_epoch()) + .count(); +#else + // clock_gettime is *much* faster than std::chrono implementation on Linux + struct timespec t{}; + auto mode = CLOCK_REALTIME; + if (allow_monotonic) { + mode = CLOCK_MONOTONIC; + } + clock_gettime(mode, &t); + return static_cast(t.tv_sec) * 1000000000 + + static_cast(t.tv_nsec); +#endif +} + +#if defined(C10_ARMTSC) +inline uint64_t getArmApproximateTime() { + uint64_t val; + __asm__ __volatile__("mrs %0, cntvct_el0" : "=r"(val)); + return val; +} +#endif + +// We often do not need to capture true wall times. If a fast mechanism such +// as TSC is available we can use that instead and convert back to epoch time +// during post processing. This greatly reduce the clock's contribution to +// profiling. +// http://btorpey.github.io/blog/2014/02/18/clock-sources-in-linux/ +// https://quick-bench.com/q/r8opkkGZSJMu9wM_XTbDouq-0Io +// TODO: We should use +// `https://github.com/google/benchmark/blob/main/src/cycleclock.h` +inline auto getApproximateTime() { +#if defined(C10_RDTSC) + return static_cast(__rdtsc()); +#elif defined(C10_ARMTSC) + return getArmApproximateTime(); +#else + return getTime(); +#endif +} + +using approx_time_t = decltype(getApproximateTime()); +static_assert( + std::is_same_v || + std::is_same_v, + "Expected either int64_t (`getTime`) or uint64_t (some TSC reads)."); + +// Convert `getCount` results to Nanoseconds since unix epoch. +class C10_API ApproximateClockToUnixTimeConverter final { + public: + ApproximateClockToUnixTimeConverter(); + std::function makeConverter(); + + struct UnixAndApproximateTimePair { + time_t t_; + approx_time_t approx_t_; + }; + static UnixAndApproximateTimePair measurePair(); + + private: + static constexpr size_t replicates = 1001; + using time_pairs = std::array; + time_pairs measurePairs(); + + time_pairs start_times_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Array.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Array.h new file mode 100644 index 0000000000000000000000000000000000000000..5cb2d8dff74253bf9c54d53b3aa532d91bee89a8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Array.h @@ -0,0 +1,23 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10 { + +// This helper function creates a constexpr std::array +// From a compile time list of values, without requiring you to explicitly +// write out the length. +// +// See also https://stackoverflow.com/a/26351760/23845 +template +inline constexpr auto array_of(T&&... t) -> std::array { + return {{std::forward(t)...}}; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ArrayRef.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ArrayRef.h new file mode 100644 index 0000000000000000000000000000000000000000..9da524e96ce718b7782e1584a795c919af0ecd78 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ArrayRef.h @@ -0,0 +1,326 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// ATen: modified from llvm::ArrayRef. +// removed llvm-specific functionality +// removed some implicit const -> non-const conversions that rely on +// complicated std::enable_if meta-programming +// removed a bunch of slice variants for simplicity... + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { +/// ArrayRef - Represent a constant reference to an array (0 or more elements +/// consecutively in memory), i.e. a start pointer and a length. It allows +/// various APIs to take consecutive elements easily and conveniently. +/// +/// This class does not own the underlying data, it is expected to be used in +/// situations where the data resides in some other buffer, whose lifetime +/// extends past that of the ArrayRef. For this reason, it is not in general +/// safe to store an ArrayRef. +/// +/// This is intended to be trivially copyable, so it should be passed by +/// value. +/// +/// NOTE: We have refactored out the headeronly parts of the ArrayRef struct +/// into HeaderOnlyArrayRef. As adding `virtual` would change the performance of +/// the underlying constexpr calls, we rely on apparent-type dispatch for +/// inheritance. This should be fine because their memory format is the same, +/// and it is never incorrect for ArrayRef to call HeaderOnlyArrayRef methods. +/// However, you should prefer to use ArrayRef when possible, because its use +/// of TORCH_CHECK will lead to better user-facing error messages. +template +// ArrayRef cannot be derived from. Normally, we would use `final` +// specifier to force this constraint at compile time. However, Intel +// compiler does not recognize ArrayRef as a class template (which is +// required in the definition of at::TensorAccessor, for instance) +// when `final` specifier is used. So, we cannot define ArrayRef as +// final because of the Intel compiler issue. +class ArrayRef : public HeaderOnlyArrayRef { + public: + /// @name Constructors, all inherited from HeaderOnlyArrayRef except for + /// SmallVector. As inherited constructors won't work with class template + /// argument deduction (CTAD) until C++23, we add deduction guides after + /// the class definition to enable CTAD. + /// @{ + + using HeaderOnlyArrayRef::HeaderOnlyArrayRef; + + /// Construct an ArrayRef from a SmallVector. This is templated in order to + /// avoid instantiating SmallVectorTemplateCommon whenever we + /// copy-construct an ArrayRef. + /// NOTE: this is the only constructor that is not inherited from + /// HeaderOnlyArrayRef. + template + /* implicit */ ArrayRef(const SmallVectorTemplateCommon& Vec) + : HeaderOnlyArrayRef(Vec.data(), Vec.size()) {} + + /// @} + /// @name Simple Operations, mostly inherited from HeaderOnlyArrayRef + /// @{ + + /// front - Get the first element. + /// We deviate from HeaderOnlyArrayRef by using TORCH_CHECK instead of + /// STD_TORCH_CHECK + constexpr const T& front() const { + TORCH_CHECK( + !this->empty(), "ArrayRef: attempted to access front() of empty list"); + return this->Data[0]; + } + + /// back - Get the last element. + /// We deviate from HeaderOnlyArrayRef by using TORCH_CHECK instead of + /// STD_TORCH_CHECK + constexpr const T& back() const { + TORCH_CHECK( + !this->empty(), "ArrayRef: attempted to access back() of empty list"); + return this->Data[this->Length - 1]; + } + + /// slice(n, m) - Take M elements of the array starting at element N + /// We deviate from HeaderOnlyArrayRef by using TORCH_CHECK instead of + /// STD_TORCH_CHECK + constexpr ArrayRef slice(size_t N, size_t M) const { + TORCH_CHECK( + N + M <= this->size(), + "ArrayRef: invalid slice, N = ", + N, + "; M = ", + M, + "; size = ", + this->size()); + return ArrayRef(this->data() + N, M); + } + + /// slice(n) - Chop off the first N elements of the array. + /// We deviate from HeaderOnlyArrayRef by using TORCH_CHECK instead of + /// STD_TORCH_CHECK + constexpr ArrayRef slice(size_t N) const { + TORCH_CHECK( + N <= this->size(), + "ArrayRef: invalid slice, N = ", + N, + "; size = ", + this->size()); + return slice(N, this->size() - N); // should this slice be this->slice? + } + + /// @} + /// @name Operator Overloads + /// @{ + + /// Vector compatibility + /// We deviate from HeaderOnlyArrayRef by using TORCH_CHECK instead of + /// STD_TORCH_CHECK + constexpr const T& at(size_t Index) const { + TORCH_CHECK( + Index < this->Length, + "ArrayRef: invalid index Index = ", + Index, + "; Length = ", + this->Length); + return this->Data[Index]; + } + + /// Disallow accidental assignment from a temporary. + /// + /// The declaration here is extra complicated so that "arrayRef = {}" + /// continues to select the move assignment operator. + template + std::enable_if_t, ArrayRef>& operator=( + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) + U&& Temporary) = delete; + + /// Disallow accidental assignment from a temporary. + /// + /// The declaration here is extra complicated so that "arrayRef = {}" + /// continues to select the move assignment operator. + template + std::enable_if_t, ArrayRef>& operator=( + std::initializer_list) = delete; + + /// @} +}; + +/// Deduction guides for ArrayRef to support CTAD with inherited constructors +/// These mirror the constructors inherited from HeaderOnlyArrayRef +/// @{ + +// Single element constructor +template +ArrayRef(const T&) -> ArrayRef; + +// Pointer and length constructor +template +ArrayRef(const T*, size_t) -> ArrayRef; + +// Range constructor (begin, end) +template +ArrayRef(const T*, const T*) -> ArrayRef; + +// Generic container constructor (anything with .data() and .size()) +template +ArrayRef(const Container&) -> ArrayRef< + std::remove_pointer_t().data())>>; + +// std::vector constructor +template +ArrayRef(const std::vector&) -> ArrayRef; + +// std::array constructor +template +ArrayRef(const std::array&) -> ArrayRef; + +// C array constructor +template +ArrayRef(const T (&)[N]) -> ArrayRef; + +// std::initializer_list constructor +template +ArrayRef(const std::initializer_list&) -> ArrayRef; + +/// @} + +template +std::ostream& operator<<(std::ostream& out, ArrayRef list) { + int i = 0; + out << '['; + for (const auto& e : list) { + if (i++ > 0) + out << ", "; + out << e; + } + out << ']'; + return out; +} + +/// @name ArrayRef Convenience constructors +/// @{ + +/// Construct an ArrayRef from a single element. +template +ArrayRef makeArrayRef(const T& OneElt) { + return OneElt; +} + +/// Construct an ArrayRef from a pointer and length. +template +ArrayRef makeArrayRef(const T* data, size_t length) { + return ArrayRef(data, length); +} + +/// Construct an ArrayRef from a range. +template +ArrayRef makeArrayRef(const T* begin, const T* end) { + return ArrayRef(begin, end); +} + +/// Construct an ArrayRef from a SmallVector. +template +ArrayRef makeArrayRef(const SmallVectorImpl& Vec) { + return Vec; +} + +/// Construct an ArrayRef from a SmallVector. +template +ArrayRef makeArrayRef(const SmallVector& Vec) { + return Vec; +} + +/// Construct an ArrayRef from a std::vector. +template +ArrayRef makeArrayRef(const std::vector& Vec) { + return Vec; +} + +/// Construct an ArrayRef from a std::array. +template +ArrayRef makeArrayRef(const std::array& Arr) { + return Arr; +} + +/// Construct an ArrayRef from an ArrayRef (no-op) (const) +template +ArrayRef makeArrayRef(const ArrayRef& Vec) { + return Vec; +} + +/// Construct an ArrayRef from an ArrayRef (no-op) +template +ArrayRef& makeArrayRef(ArrayRef& Vec) { + return Vec; +} + +/// Construct an ArrayRef from a C array. +template +// NOLINTNEXTLINE(*c-arrays*) +ArrayRef makeArrayRef(const T (&Arr)[N]) { + return ArrayRef(Arr); +} + +// WARNING: Template instantiation will NOT be willing to do an implicit +// conversions to get you to an c10::ArrayRef, which is why we need so +// many overloads. + +template +bool operator==(c10::ArrayRef a1, c10::ArrayRef a2) { + return a1.equals(a2); +} + +template +bool operator!=(c10::ArrayRef a1, c10::ArrayRef a2) { + return !a1.equals(a2); +} + +template +bool operator==(const std::vector& a1, c10::ArrayRef a2) { + return c10::ArrayRef(a1).equals(a2); +} + +template +bool operator!=(const std::vector& a1, c10::ArrayRef a2) { + return !c10::ArrayRef(a1).equals(a2); +} + +template +bool operator==(c10::ArrayRef a1, const std::vector& a2) { + return a1.equals(c10::ArrayRef(a2)); +} + +template +bool operator!=(c10::ArrayRef a1, const std::vector& a2) { + return !a1.equals(c10::ArrayRef(a2)); +} + +using IntArrayRef = ArrayRef; + +using IntList [[deprecated( + "This alias is deprecated because it doesn't make ownership semantics obvious. Use IntArrayRef instead!")]] = + ArrayRef; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/BFloat16-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/BFloat16-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..90ca6b677ab3740550f4700479497fd58c35536b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/BFloat16-inl.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/BFloat16-math.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/BFloat16-math.h new file mode 100644 index 0000000000000000000000000000000000000000..6865f84fa6af5dbd8e2fb60ff46f1bbabdead1fd --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/BFloat16-math.h @@ -0,0 +1,304 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +C10_CLANG_DIAGNOSTIC_PUSH() +#if C10_CLANG_HAS_WARNING("-Wimplicit-float-conversion") +C10_CLANG_DIAGNOSTIC_IGNORE("-Wimplicit-float-conversion") +#endif + +namespace c10 { +template +struct is_reduced_floating_point + : std::integral_constant< + bool, + std::is_same_v || std::is_same_v> {}; + +template +constexpr bool is_reduced_floating_point_v = + is_reduced_floating_point::value; +} // namespace c10 + +namespace std { + +#if !defined(FBCODE_CAFFE2) && !defined(C10_NODEPRECATED) +using c10::is_reduced_floating_point; +using c10::is_reduced_floating_point_v; +#endif // !defined(FBCODE_CAFFE2) && !defined(C10_NODEPRECATED) + +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T acos(T a) { + return std::acos(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T asin(T a) { + return std::asin(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T atan(T a) { + return std::atan(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T atanh(T a) { + return std::atanh(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T erf(T a) { + return std::erf(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T erfc(T a) { + return std::erfc(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T exp(T a) { + return std::exp(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T expm1(T a) { + return std::expm1(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline bool isfinite(T a) { + return std::isfinite(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T log(T a) { + return std::log(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T log10(T a) { + return std::log10(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T log1p(T a) { + return std::log1p(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T log2(T a) { + return std::log2(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T ceil(T a) { + return std::ceil(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T cos(T a) { + return std::cos(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T floor(T a) { + return std::floor(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T nearbyint(T a) { + return std::nearbyint(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T sin(T a) { + return std::sin(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T tan(T a) { + return std::tan(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T sinh(T a) { + return std::sinh(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T cosh(T a) { + return std::cosh(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T tanh(T a) { + return std::tanh(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T trunc(T a) { + return std::trunc(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T lgamma(T a) { + return std::lgamma(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T sqrt(T a) { + return std::sqrt(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T rsqrt(T a) { + return 1.0 / std::sqrt(float(a)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T abs(T a) { + return std::abs(float(a)); +} +#if defined(_MSC_VER) && defined(__CUDACC__) +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T pow(T a, double b) { + return std::pow(float(a), float(b)); +} +#else +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T pow(T a, double b) { + return std::pow(float(a), b); +} +#endif +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T pow(T a, T b) { + return std::pow(float(a), float(b)); +} +template < + typename T, + typename std::enable_if_t, int> = 0> +inline T fmod(T a, T b) { + return std::fmod(float(a), float(b)); +} + +/* + The following function is inspired from the implementation in `musl` + Link to License: https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT + ---------------------------------------------------------------------- + Copyright © 2005-2020 Rich Felker, et al. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ---------------------------------------------------------------------- + */ +template < + typename T, + typename std::enable_if_t, int> = 0> +C10_HOST_DEVICE inline T nextafter(T from, T to) { + // Reference: + // https://git.musl-libc.org/cgit/musl/tree/src/math/nextafter.c + using int_repr_t = uint16_t; + constexpr uint8_t bits = 16; + union { + T f; + int_repr_t i; + } ufrom = {from}, uto = {to}; + + // get a mask to get the sign bit i.e. MSB + int_repr_t sign_mask = int_repr_t{1} << (bits - 1); + + // short-circuit: if either is NaN, return NaN + if (from != from || to != to) { + return from + to; + } + + // short-circuit: if they are exactly the same. + if (ufrom.i == uto.i) { + return from; + } + + // mask the sign-bit to zero i.e. positive + // equivalent to abs(x) + int_repr_t abs_from = ufrom.i & ~sign_mask; + int_repr_t abs_to = uto.i & ~sign_mask; + if (abs_from == 0) { + // if both are zero but with different sign, + // preserve the sign of `to`. + if (abs_to == 0) { + return to; + } + // smallest subnormal with sign of `to`. + ufrom.i = (uto.i & sign_mask) | int_repr_t{1}; + return ufrom.f; + } + + // if abs(from) > abs(to) or sign(from) != sign(to) + if (abs_from > abs_to || ((ufrom.i ^ uto.i) & sign_mask)) { + ufrom.i--; + } else { + ufrom.i++; + } + + return ufrom.f; +} + +} // namespace std + +C10_CLANG_DIAGNOSTIC_POP() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/BFloat16.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/BFloat16.h new file mode 100644 index 0000000000000000000000000000000000000000..90ca6b677ab3740550f4700479497fd58c35536b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/BFloat16.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Backtrace.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Backtrace.h new file mode 100644 index 0000000000000000000000000000000000000000..0a9e8d2c27ff43ab571d3883567ef5535c3287db --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Backtrace.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_BACKTRACE_H_ +#define C10_UTIL_BACKTRACE_H_ + +#include +#include +#include +#include + +#include +#include + +namespace c10 { + +// Symbolizing the backtrace can be expensive; pass it around as a lazy string +// so it is symbolized only if actually needed. +using Backtrace = std::shared_ptr>; + +// DEPRECATED: Prefer get_lazy_backtrace(). +C10_API std::string get_backtrace( + size_t frames_to_skip = 0, + size_t maximum_number_of_frames = 64, + bool skip_python_frames = true); + +C10_API Backtrace get_lazy_backtrace( + size_t frames_to_skip = 0, + size_t maximum_number_of_frames = 64, + bool skip_python_frames = true); + +} // namespace c10 + +#endif // C10_UTIL_BACKTRACE_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Bitset.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Bitset.h new file mode 100644 index 0000000000000000000000000000000000000000..1e01d94ea590ccd96414ec760b09a48419de9de8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Bitset.h @@ -0,0 +1,123 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#if defined(_MSC_VER) +#include +#endif + +namespace c10::utils { + +/** + * This is a simple bitset class with sizeof(long long int) bits. + * You can set bits, unset bits, query bits by index, + * and query for the first set bit. + * Before using this class, please also take a look at std::bitset, + * which has more functionality and is more generic. It is probably + * a better fit for your use case. The sole reason for c10::utils::bitset + * to exist is that std::bitset misses a find_first_set() method. + */ +struct bitset final { + private: +#if defined(_MSC_VER) + // MSVCs _BitScanForward64 expects int64_t + using bitset_type = int64_t; +#else + // POSIX ffsll expects long long int + using bitset_type = long long int; +#endif + public: + static constexpr size_t NUM_BITS() { + return 8 * sizeof(bitset_type); + } + + constexpr bitset() noexcept = default; + constexpr bitset(const bitset&) noexcept = default; + constexpr bitset(bitset&&) noexcept = default; + // there is an issue for gcc 5.3.0 when define default function as constexpr + // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68754. + bitset& operator=(const bitset&) noexcept = default; + bitset& operator=(bitset&&) noexcept = default; + ~bitset() = default; + + constexpr void set(size_t index) noexcept { + bitset_ |= (static_cast(1) << index); + } + + constexpr void unset(size_t index) noexcept { + bitset_ &= ~(static_cast(1) << index); + } + + constexpr bool get(size_t index) const noexcept { + return bitset_ & (static_cast(1) << index); + } + + constexpr bool is_entirely_unset() const noexcept { + return 0 == bitset_; + } + + // Call the given functor with the index of each bit that is set + template + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) + void for_each_set_bit(Func&& func) const { + bitset cur = *this; + size_t index = cur.find_first_set(); + while (0 != index) { + // -1 because find_first_set() is not one-indexed. + index -= 1; + func(index); + cur.unset(index); + index = cur.find_first_set(); + } + } + + private: + // Return the index of the first set bit. The returned index is one-indexed + // (i.e. if the very first bit is set, this function returns '1'), and a + // return of '0' means that there was no bit set. + size_t find_first_set() const { +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) + unsigned long result; + bool has_bits_set = (0 != _BitScanForward64(&result, bitset_)); + if (!has_bits_set) { + return 0; + } + return result + 1; +#elif defined(_MSC_VER) && defined(_M_IX86) + unsigned long result; + if (static_cast(bitset_) != 0) { + bool has_bits_set = + (0 != _BitScanForward(&result, static_cast(bitset_))); + if (!has_bits_set) { + return 0; + } + return result + 1; + } else { + bool has_bits_set = + (0 != _BitScanForward(&result, static_cast(bitset_ >> 32))); + if (!has_bits_set) { + return 32; + } + return result + 33; + } +#else + return __builtin_ffsll(bitset_); +#endif + } + + friend bool operator==(bitset lhs, bitset rhs) noexcept { + return lhs.bitset_ == rhs.bitset_; + } + + bitset_type bitset_{0}; +}; + +inline bool operator!=(bitset lhs, bitset rhs) noexcept { + return !(lhs == rhs); +} + +} // namespace c10::utils + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/C++17.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/C++17.h new file mode 100644 index 0000000000000000000000000000000000000000..d12608c05d5e14e8706dad9835e2360a54fc3009 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/C++17.h @@ -0,0 +1,43 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#ifndef C10_UTIL_CPP17_H_ +#define C10_UTIL_CPP17_H_ + +#include +#include +#include + +namespace c10::guts { + +#if defined(__HIP__) + +// std::apply is not available in HIP device code because it lacks +// __host__ __device__ annotations in the standard library. +namespace detail { +template +C10_HOST_DEVICE constexpr auto apply_impl( + F&& f, + Tuple&& t, + std::index_sequence) { + return std::forward(f)(std::get(std::forward(t))...); +} +} // namespace detail + +template +C10_HOST_DEVICE constexpr auto apply(F&& f, Tuple&& t) { + return detail::apply_impl( + std::forward(f), + std::forward(t), + std::make_index_sequence< + std::tuple_size>::value>{}); +} + +#endif + +} // namespace c10::guts + +#endif // C10_UTIL_CPP17_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/CallOnce.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/CallOnce.h new file mode 100644 index 0000000000000000000000000000000000000000..015414a60ed9260289c596b650d46730ff6b6f2a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/CallOnce.h @@ -0,0 +1,74 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include +#include +#include +#include + +namespace c10 { + +// custom c10 call_once implementation to avoid the deadlock in std::call_once. +// The implementation here is a simplified version from folly and likely much +// much higher memory footprint. +template +inline void call_once(Flag& flag, F&& f, Args&&... args) { + if (C10_LIKELY(flag.test_once())) { + return; + } + flag.call_once_slow(std::forward(f), std::forward(args)...); +} + +class once_flag { + public: +#ifndef _WIN32 + // running into build error on MSVC. Can't seem to get a repro locally so I'm + // just avoiding constexpr + // + // C:/actions-runner/_work/pytorch/pytorch\c10/util/CallOnce.h(26): error: + // defaulted default constructor cannot be constexpr because the + // corresponding implicitly declared default constructor would not be + // constexpr 1 error detected in the compilation of + // "C:/actions-runner/_work/pytorch/pytorch/aten/src/ATen/cuda/cub.cu". + constexpr +#endif + once_flag() noexcept = default; + once_flag(const once_flag&) = delete; + once_flag& operator=(const once_flag&) = delete; + once_flag(once_flag&&) = delete; + once_flag& operator=(once_flag&&) = delete; + ~once_flag() = default; + bool test_once() { + return init_.load(std::memory_order_acquire); + } + + private: + template + friend void call_once(Flag& flag, F&& f, Args&&... args); + + template + void call_once_slow(F&& f, Args&&... args) { + std::lock_guard guard(mutex_); + if (init_.load(std::memory_order_relaxed)) { + return; + } + std::invoke(std::forward(f), std::forward(args)...); + init_.store(true, std::memory_order_release); + } + + void reset_once() { + init_.store(false, std::memory_order_release); + } + + private: + std::mutex mutex_; + std::atomic init_{false}; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ConstexprCrc.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ConstexprCrc.h new file mode 100644 index 0000000000000000000000000000000000000000..56dd979ce833087e264e6e8faef8563019fa3ea5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ConstexprCrc.h @@ -0,0 +1,137 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace c10::util { + +namespace detail { +// NOLINTNEXTLINE(*c-arrays*) +constexpr uint64_t crc64_table[] = { + 0x0000000000000000, 0x7ad870c830358979, 0xf5b0e190606b12f2, + 0x8f689158505e9b8b, 0xc038e5739841b68f, 0xbae095bba8743ff6, + 0x358804e3f82aa47d, 0x4f50742bc81f2d04, 0xab28ecb46814fe75, + 0xd1f09c7c5821770c, 0x5e980d24087fec87, 0x24407dec384a65fe, + 0x6b1009c7f05548fa, 0x11c8790fc060c183, 0x9ea0e857903e5a08, + 0xe478989fa00bd371, 0x7d08ff3b88be6f81, 0x07d08ff3b88be6f8, + 0x88b81eabe8d57d73, 0xf2606e63d8e0f40a, 0xbd301a4810ffd90e, + 0xc7e86a8020ca5077, 0x4880fbd87094cbfc, 0x32588b1040a14285, + 0xd620138fe0aa91f4, 0xacf86347d09f188d, 0x2390f21f80c18306, + 0x594882d7b0f40a7f, 0x1618f6fc78eb277b, 0x6cc0863448deae02, + 0xe3a8176c18803589, 0x997067a428b5bcf0, 0xfa11fe77117cdf02, + 0x80c98ebf2149567b, 0x0fa11fe77117cdf0, 0x75796f2f41224489, + 0x3a291b04893d698d, 0x40f16bccb908e0f4, 0xcf99fa94e9567b7f, + 0xb5418a5cd963f206, 0x513912c379682177, 0x2be1620b495da80e, + 0xa489f35319033385, 0xde51839b2936bafc, 0x9101f7b0e12997f8, + 0xebd98778d11c1e81, 0x64b116208142850a, 0x1e6966e8b1770c73, + 0x8719014c99c2b083, 0xfdc17184a9f739fa, 0x72a9e0dcf9a9a271, + 0x08719014c99c2b08, 0x4721e43f0183060c, 0x3df994f731b68f75, + 0xb29105af61e814fe, 0xc849756751dd9d87, 0x2c31edf8f1d64ef6, + 0x56e99d30c1e3c78f, 0xd9810c6891bd5c04, 0xa3597ca0a188d57d, + 0xec09088b6997f879, 0x96d1784359a27100, 0x19b9e91b09fcea8b, + 0x636199d339c963f2, 0xdf7adabd7a6e2d6f, 0xa5a2aa754a5ba416, + 0x2aca3b2d1a053f9d, 0x50124be52a30b6e4, 0x1f423fcee22f9be0, + 0x659a4f06d21a1299, 0xeaf2de5e82448912, 0x902aae96b271006b, + 0x74523609127ad31a, 0x0e8a46c1224f5a63, 0x81e2d7997211c1e8, + 0xfb3aa75142244891, 0xb46ad37a8a3b6595, 0xceb2a3b2ba0eecec, + 0x41da32eaea507767, 0x3b024222da65fe1e, 0xa2722586f2d042ee, + 0xd8aa554ec2e5cb97, 0x57c2c41692bb501c, 0x2d1ab4dea28ed965, + 0x624ac0f56a91f461, 0x1892b03d5aa47d18, 0x97fa21650afae693, + 0xed2251ad3acf6fea, 0x095ac9329ac4bc9b, 0x7382b9faaaf135e2, + 0xfcea28a2faafae69, 0x8632586aca9a2710, 0xc9622c4102850a14, + 0xb3ba5c8932b0836d, 0x3cd2cdd162ee18e6, 0x460abd1952db919f, + 0x256b24ca6b12f26d, 0x5fb354025b277b14, 0xd0dbc55a0b79e09f, + 0xaa03b5923b4c69e6, 0xe553c1b9f35344e2, 0x9f8bb171c366cd9b, + 0x10e3202993385610, 0x6a3b50e1a30ddf69, 0x8e43c87e03060c18, + 0xf49bb8b633338561, 0x7bf329ee636d1eea, 0x012b592653589793, + 0x4e7b2d0d9b47ba97, 0x34a35dc5ab7233ee, 0xbbcbcc9dfb2ca865, + 0xc113bc55cb19211c, 0x5863dbf1e3ac9dec, 0x22bbab39d3991495, + 0xadd33a6183c78f1e, 0xd70b4aa9b3f20667, 0x985b3e827bed2b63, + 0xe2834e4a4bd8a21a, 0x6debdf121b863991, 0x1733afda2bb3b0e8, + 0xf34b37458bb86399, 0x8993478dbb8deae0, 0x06fbd6d5ebd3716b, + 0x7c23a61ddbe6f812, 0x3373d23613f9d516, 0x49aba2fe23cc5c6f, + 0xc6c333a67392c7e4, 0xbc1b436e43a74e9d, 0x95ac9329ac4bc9b5, + 0xef74e3e19c7e40cc, 0x601c72b9cc20db47, 0x1ac40271fc15523e, + 0x5594765a340a7f3a, 0x2f4c0692043ff643, 0xa02497ca54616dc8, + 0xdafce7026454e4b1, 0x3e847f9dc45f37c0, 0x445c0f55f46abeb9, + 0xcb349e0da4342532, 0xb1eceec59401ac4b, 0xfebc9aee5c1e814f, + 0x8464ea266c2b0836, 0x0b0c7b7e3c7593bd, 0x71d40bb60c401ac4, + 0xe8a46c1224f5a634, 0x927c1cda14c02f4d, 0x1d148d82449eb4c6, + 0x67ccfd4a74ab3dbf, 0x289c8961bcb410bb, 0x5244f9a98c8199c2, + 0xdd2c68f1dcdf0249, 0xa7f41839ecea8b30, 0x438c80a64ce15841, + 0x3954f06e7cd4d138, 0xb63c61362c8a4ab3, 0xcce411fe1cbfc3ca, + 0x83b465d5d4a0eece, 0xf96c151de49567b7, 0x76048445b4cbfc3c, + 0x0cdcf48d84fe7545, 0x6fbd6d5ebd3716b7, 0x15651d968d029fce, + 0x9a0d8ccedd5c0445, 0xe0d5fc06ed698d3c, 0xaf85882d2576a038, + 0xd55df8e515432941, 0x5a3569bd451db2ca, 0x20ed197575283bb3, + 0xc49581ead523e8c2, 0xbe4df122e51661bb, 0x3125607ab548fa30, + 0x4bfd10b2857d7349, 0x04ad64994d625e4d, 0x7e7514517d57d734, + 0xf11d85092d094cbf, 0x8bc5f5c11d3cc5c6, 0x12b5926535897936, + 0x686de2ad05bcf04f, 0xe70573f555e26bc4, 0x9ddd033d65d7e2bd, + 0xd28d7716adc8cfb9, 0xa85507de9dfd46c0, 0x273d9686cda3dd4b, + 0x5de5e64efd965432, 0xb99d7ed15d9d8743, 0xc3450e196da80e3a, + 0x4c2d9f413df695b1, 0x36f5ef890dc31cc8, 0x79a59ba2c5dc31cc, + 0x037deb6af5e9b8b5, 0x8c157a32a5b7233e, 0xf6cd0afa9582aa47, + 0x4ad64994d625e4da, 0x300e395ce6106da3, 0xbf66a804b64ef628, + 0xc5bed8cc867b7f51, 0x8aeeace74e645255, 0xf036dc2f7e51db2c, + 0x7f5e4d772e0f40a7, 0x05863dbf1e3ac9de, 0xe1fea520be311aaf, + 0x9b26d5e88e0493d6, 0x144e44b0de5a085d, 0x6e963478ee6f8124, + 0x21c640532670ac20, 0x5b1e309b16452559, 0xd476a1c3461bbed2, + 0xaeaed10b762e37ab, 0x37deb6af5e9b8b5b, 0x4d06c6676eae0222, + 0xc26e573f3ef099a9, 0xb8b627f70ec510d0, 0xf7e653dcc6da3dd4, + 0x8d3e2314f6efb4ad, 0x0256b24ca6b12f26, 0x788ec2849684a65f, + 0x9cf65a1b368f752e, 0xe62e2ad306bafc57, 0x6946bb8b56e467dc, + 0x139ecb4366d1eea5, 0x5ccebf68aecec3a1, 0x2616cfa09efb4ad8, + 0xa97e5ef8cea5d153, 0xd3a62e30fe90582a, 0xb0c7b7e3c7593bd8, + 0xca1fc72bf76cb2a1, 0x45775673a732292a, 0x3faf26bb9707a053, + 0x70ff52905f188d57, 0x0a2722586f2d042e, 0x854fb3003f739fa5, + 0xff97c3c80f4616dc, 0x1bef5b57af4dc5ad, 0x61372b9f9f784cd4, + 0xee5fbac7cf26d75f, 0x9487ca0fff135e26, 0xdbd7be24370c7322, + 0xa10fceec0739fa5b, 0x2e675fb4576761d0, 0x54bf2f7c6752e8a9, + 0xcdcf48d84fe75459, 0xb71738107fd2dd20, 0x387fa9482f8c46ab, + 0x42a7d9801fb9cfd2, 0x0df7adabd7a6e2d6, 0x772fdd63e7936baf, + 0xf8474c3bb7cdf024, 0x829f3cf387f8795d, 0x66e7a46c27f3aa2c, + 0x1c3fd4a417c62355, 0x935745fc4798b8de, 0xe98f353477ad31a7, + 0xa6df411fbfb21ca3, 0xdc0731d78f8795da, 0x536fa08fdfd90e51, + 0x29b7d047efec8728, +}; + +inline constexpr uint64_t crc64impl( + uint64_t accumulator, + const char* data, + size_t size) { + for (size_t i = 0; i < size; ++i) { + accumulator = + crc64_table[(accumulator ^ data[i]) & 0xFF] ^ (accumulator >> 8); + } + return accumulator; +} +} // namespace detail + +struct crc64_t final : IdWrapper { + constexpr crc64_t(uint64_t checksum) : IdWrapper(checksum) {} + constexpr uint64_t checksum() const { + return this->underlyingId(); + } +}; + +// CRC64 with Jones coefficients and an init value of 0. +inline constexpr crc64_t crc64(const char* str, size_t size) { + return crc64_t{detail::crc64impl(0, str, size)}; +} + +inline constexpr crc64_t crc64(std::string_view str) { + return crc64(str.data(), str.size()); +} +} // namespace c10::util + +// Allow usage of crc64_t in std::unordered_set +C10_DEFINE_HASH_FOR_IDWRAPPER(c10::util::crc64_t) + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/DeadlockDetection.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/DeadlockDetection.h new file mode 100644 index 0000000000000000000000000000000000000000..5fd611a2add7563d8c6ca6fba28e704765c4ec79 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/DeadlockDetection.h @@ -0,0 +1,57 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +/// This file provides some simple utilities for detecting common deadlocks in +/// PyTorch. For now, we focus exclusively on detecting Python GIL deadlocks, +/// as the GIL is a wide ranging lock that is taken out in many situations. +/// The basic strategy is before performing an operation that may block, you +/// can use TORCH_ASSERT_NO_GIL_WITHOUT_PYTHON_DEP() to assert that the GIL is +/// not held. This macro is to be used in contexts where no static dependency +/// on Python is available (we will handle indirecting a virtual call for you). +/// +/// If the GIL is held by a torchdeploy interpreter, we always report false. +/// If you are in a context where Python bindings are available, it's better +/// to directly assert on PyGILState_Check (as it avoids a vcall and also +/// works correctly with torchdeploy.) + +#define TORCH_ASSERT_NO_GIL_WITHOUT_PYTHON_DEP() \ + TORCH_INTERNAL_ASSERT( \ + !c10::impl::check_python_gil(), \ + "Holding GIL before a blocking operation! Please release the GIL before blocking, or see https://github.com/pytorch/pytorch/issues/56297 for how to release the GIL for destructors of objects") + +namespace c10::impl { + +C10_API bool check_python_gil(); + +struct C10_API PythonGILHooks { + virtual ~PythonGILHooks() = default; + // Returns true if we hold the GIL. If not linked against Python we + // always return false. + virtual bool check_python_gil() const = 0; +}; + +C10_API void SetPythonGILHooks(PythonGILHooks* factory); + +// DO NOT call this registerer from a torch deploy instance! You will clobber +// other registrations +struct C10_API PythonGILHooksRegisterer { + explicit PythonGILHooksRegisterer(PythonGILHooks* factory) { + SetPythonGILHooks(factory); + } + PythonGILHooksRegisterer(const PythonGILHooksRegisterer&) = delete; + PythonGILHooksRegisterer(PythonGILHooksRegisterer&&) = delete; + PythonGILHooksRegisterer& operator=(const PythonGILHooksRegisterer&) = delete; + PythonGILHooksRegisterer& operator=(PythonGILHooksRegisterer&&) = delete; + ~PythonGILHooksRegisterer() { + SetPythonGILHooks(nullptr); + } +}; + +} // namespace c10::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Deprecated.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Deprecated.h new file mode 100644 index 0000000000000000000000000000000000000000..ccd1ac50400d3dcdc160c42e8745bac7139c8217 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Deprecated.h @@ -0,0 +1,7 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/DimVector.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/DimVector.h new file mode 100644 index 0000000000000000000000000000000000000000..682b8f364a2094c0feec2b6c19a8e2e54d296ee1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/DimVector.h @@ -0,0 +1,22 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace c10 { + +constexpr size_t kDimVectorStaticSize = C10_SIZES_AND_STRIDES_MAX_INLINE_SIZE; + +/// A container for sizes or strides +using DimVector = SmallVector; +using SymDimVector = SmallVector; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/DynamicCounter.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/DynamicCounter.h new file mode 100644 index 0000000000000000000000000000000000000000..37e0af4319435c223442cc52d2b34d8e12e2715b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/DynamicCounter.h @@ -0,0 +1,54 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +#include + +namespace c10::monitor { + +class C10_API DynamicCounter { + public: + using Callback = std::function; + + // Creates a dynamic counter that can be queried at any point in time by + // multiple backends. Only one counter with a given key can exist at any point + // in time. + // + // The callback is invoked every time the counter is queried. + // The callback must be thread-safe. + // The callback must not throw. + // The callback must not block. + DynamicCounter(std::string_view key, Callback getCounterCallback); + + // Unregisters the callback. + // Waits for all ongoing callback invocations to finish. + ~DynamicCounter(); + + private: + struct Guard; + std::unique_ptr guard_; +}; + +namespace detail { +class DynamicCounterBackendIf { + public: + virtual ~DynamicCounterBackendIf() = default; + + virtual void registerCounter( + std::string_view key, + DynamicCounter::Callback getCounterCallback) = 0; + // MUST wait for all ongoing callback invocations to finish + virtual void unregisterCounter(std::string_view key) = 0; +}; + +void C10_API registerDynamicCounterBackend( + std::unique_ptr /*backend*/); +} // namespace detail +} // namespace c10::monitor + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Enumerate.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Enumerate.h new file mode 100644 index 0000000000000000000000000000000000000000..441e158ccc4ab86cd7c19a25963d1da7005c82e9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Enumerate.h @@ -0,0 +1,164 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Ported from folly/container/Enumerate.h + */ + +#pragma once + +#include +#include + +#ifdef _WIN32 +#include // @manual +using ssize_t = SSIZE_T; +#endif + +#include + +/** + * Similar to Python's enumerate(), enumerate() can be used to + * iterate a range with a for-range loop, and it also allows to + * retrieve the count of iterations so far. Can be used in constexpr + * context. + * + * For example: + * + * for (auto&& [index, element] : enumerate(vec)) { + * // index is a const reference to a size_t containing the iteration count. + * // element is a reference to the type contained within vec, mutable + * // unless vec is const. + * } + * + * If the binding is const, the element reference is too. + * + * for (const auto&& [index, element] : enumerate(vec)) { + * // element is always a const reference. + * } + * + * It can also be used as follows: + * + * for (auto&& it : enumerate(vec)) { + * // *it is a reference to the current element. Mutable unless vec is const. + * // it->member can be used as well. + * // it.index contains the iteration count. + * } + * + * As before, const auto&& it can also be used. + */ + +namespace c10 { + +namespace detail { + +template +struct MakeConst { + using type = const T; +}; +template +struct MakeConst { + using type = const T&; +}; +template +struct MakeConst { + using type = const T*; +}; + +template +class Enumerator { + public: + constexpr explicit Enumerator(Iterator it) : it_(std::move(it)) {} + + class Proxy { + public: + using difference_type = ssize_t; + using value_type = typename std::iterator_traits::value_type; + using reference = typename std::iterator_traits::reference; + using pointer = typename std::iterator_traits::pointer; + using iterator_category = std::input_iterator_tag; + + C10_ALWAYS_INLINE constexpr explicit Proxy(const Enumerator& e) + : index(e.idx_), element(*e.it_) {} + + // Non-const Proxy: Forward constness from Iterator. + C10_ALWAYS_INLINE constexpr reference operator*() { + return element; + } + C10_ALWAYS_INLINE constexpr pointer operator->() { + return std::addressof(element); + } + + // Const Proxy: Force const references. + C10_ALWAYS_INLINE constexpr typename MakeConst::type operator*() + const { + return element; + } + C10_ALWAYS_INLINE constexpr typename MakeConst::type operator->() + const { + return std::addressof(element); + } + + public: + size_t index; + reference element; + }; + + C10_ALWAYS_INLINE constexpr Proxy operator*() const { + return Proxy(*this); + } + + C10_ALWAYS_INLINE constexpr Enumerator& operator++() { + ++it_; + ++idx_; + return *this; + } + + template + C10_ALWAYS_INLINE constexpr bool operator==( + const Enumerator& rhs) const { + return it_ == rhs.it_; + } + + template + C10_ALWAYS_INLINE constexpr bool operator!=( + const Enumerator& rhs) const { + return !(it_ == rhs.it_); + } + + private: + template + friend class Enumerator; + + Iterator it_; + size_t idx_ = 0; +}; + +template +class RangeEnumerator { + Range r_; + using BeginIteratorType = decltype(std::declval().begin()); + using EndIteratorType = decltype(std::declval().end()); + + public: + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + constexpr explicit RangeEnumerator(Range&& r) : r_(std::forward(r)) {} + + constexpr Enumerator begin() { + return Enumerator(r_.begin()); + } + constexpr Enumerator end() { + return Enumerator(r_.end()); + } +}; + +} // namespace detail + +template +constexpr detail::RangeEnumerator enumerate(Range&& r) { + return detail::RangeEnumerator(std::forward(r)); +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Exception.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Exception.h new file mode 100644 index 0000000000000000000000000000000000000000..fe4f97949d0541c7da1d09a03045e4f4c321195f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Exception.h @@ -0,0 +1,880 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// @allow-raw-throw +#ifndef C10_UTIL_EXCEPTION_H_ +#define C10_UTIL_EXCEPTION_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER <= 1900 +#define __func__ __FUNCTION__ +#endif + +namespace c10 { + +/// The primary ATen error class. +/// Provides a complete error message with source location information via +/// `what()`, and a more concise message via `what_without_backtrace()`. +/// Don't throw this directly; use TORCH_CHECK/TORCH_INTERNAL_ASSERT instead. +/// +/// NB: c10::Error is handled specially by the default torch to suppress the +/// backtrace, see torch/csrc/Exceptions.h +class C10_API Error : public std::exception { + private: + // The actual error message. + std::string msg_; + + // Context for the message (in order of decreasing specificity). Context will + // be automatically formatted appropriately, so it is not necessary to add + // extra leading/trailing newlines to strings inside this vector + std::vector context_; + + // The C++ backtrace at the point when this exception was raised. This + // may be empty if there is no valid backtrace. (We don't use optional + // here to reduce the dependencies this file has.) + Backtrace backtrace_; + + // These two are derived fields from msg_stack_ and backtrace_, but we need + // fields for the strings so that we can return a const char* (as the + // signature of std::exception requires). Currently, the invariant + // is that these fields are ALWAYS populated consistently with respect + // to msg_stack_ and backtrace_. + mutable OptimisticLazy what_; + std::string what_without_backtrace_; + + // This is a little debugging trick: you can stash a relevant pointer + // in caller, and then when you catch the exception, you can compare + // against pointers you have on hand to get more information about + // where the exception came from. In Caffe2, this is used to figure + // out which operator raised an exception. + const void* caller_; + + public: + // PyTorch-style Error constructor. NB: the implementation of this + // is actually in Logging.cpp + Error(SourceLocation source_location, std::string msg); + + // Caffe2-style error message + Error( + const char* file, + const uint32_t line, + const char* condition, + const std::string& msg, + Backtrace backtrace, + const void* caller = nullptr); + + // Base constructor + Error( + std::string msg, + Backtrace backtrace = nullptr, + const void* caller = nullptr); + + // Add some new context to the message stack. The last added context + // will be formatted at the end of the context list upon printing. + // WARNING: This method is O(n) in the size of the stack, so don't go + // wild adding a ridiculous amount of context to error messages. + void add_context(std::string msg); + + const std::string& msg() const { + return msg_; + } + + const std::vector& context() const { + return context_; + } + + const Backtrace& backtrace() const; + + /// Returns the complete error message, including the source location. + /// The returned pointer is invalidated if you call add_context() on + /// this object. + const char* what() const noexcept override; + + const void* caller() const noexcept { + return caller_; + } + + /// Returns only the error message string, without source location. + /// The returned pointer is invalidated if you call add_context() on + /// this object. + virtual const char* what_without_backtrace() const noexcept { + return what_without_backtrace_.c_str(); + } + + private: + void refresh_what(); + std::string compute_what(bool include_backtrace) const; +}; + +class C10_API Warning { + public: + class C10_API UserWarning{}; + class C10_API DeprecationWarning{}; + + using warning_variant_t = std::variant; + + Warning( + warning_variant_t type, + const SourceLocation& source_location, + std::string msg, + bool verbatim); + + Warning( + warning_variant_t type, + SourceLocation source_location, + const char* msg, + bool verbatim); + + Warning( + warning_variant_t type, + SourceLocation source_location, + ::c10::detail::CompileTimeEmptyString msg, + bool verbatim); + + // Getters for members + warning_variant_t type() const; + const SourceLocation& source_location() const; + const std::string& msg() const; + bool verbatim() const; + + private: + // The type of warning + warning_variant_t type_; + + // Where the warning happened. + SourceLocation source_location_; + + // The actual warning message. + std::string msg_; + + // See note: [Verbatim Warnings] + bool verbatim_; +}; + +using UserWarning = Warning::UserWarning; +using DeprecationWarning = Warning::DeprecationWarning; + +// Issue a warning with a given message. Dispatched to the current +// warning handler. +void C10_API warn(const Warning& warning); + +class C10_API WarningHandler { + public: + virtual ~WarningHandler() = default; + /// The default warning handler. Prints the message to stderr. + virtual void process(const Warning& warning); +}; + +namespace WarningUtils { + +// Note: [Verbatim Warnings] +// Warnings originating in C++ code can appear out-of-place to Python users: +// a user runs a line in Python, but the warning references a line in C++. +// Some parts of PyTorch, like the JIT, are cognizant of this mismatch +// and take care to map warnings back to the user's program, but most +// of PyTorch simply throws a context-free warning. To allow warning +// handlers to add context where appropriate, warn takes the +// "verbatim" flag. When this is false a warning handler might append +// the C++ warning to a Python warning message that relates the warning +// back to the user's program. Callers who have already accounted for +// context in their warnings should set verbatim to true so their warnings +// appear without modification. + +/// Sets the global warning handler. This is not thread-safe, so it should +/// generally be called once during initialization or while holding the GIL +/// for programs that use python. +/// User is responsible for keeping the WarningHandler alive until +/// it is not needed. +C10_API void set_warning_handler(WarningHandler* handler) noexcept(true); +/// Gets the global warning handler. +C10_API WarningHandler* get_warning_handler() noexcept(true); + +class C10_API WarningHandlerGuard { + WarningHandler* prev_handler_; + + public: + WarningHandlerGuard(WarningHandler* new_handler) + : prev_handler_(c10::WarningUtils::get_warning_handler()) { + c10::WarningUtils::set_warning_handler(new_handler); + } + WarningHandlerGuard(WarningHandlerGuard&& other) = delete; + WarningHandlerGuard(const WarningHandlerGuard&) = delete; + WarningHandlerGuard& operator=(const WarningHandlerGuard&) = delete; + WarningHandlerGuard& operator=(WarningHandlerGuard&&) = delete; + ~WarningHandlerGuard() { + c10::WarningUtils::set_warning_handler(prev_handler_); + } +}; + +/// The TORCH_WARN_ONCE macro is difficult to test for. Use +/// setWarnAlways(true) to turn it into TORCH_WARN, which can be +/// tested for more easily. +C10_API void set_warnAlways(bool /*setting*/) noexcept(true); +C10_API bool get_warnAlways() noexcept(true); + +// A RAII guard that sets warn_always (not thread-local) on +// construction, and sets it back to the original value upon destruction. +struct C10_API WarnAlways { + public: + explicit WarnAlways(bool setting = true); + ~WarnAlways(); + + private: + bool prev_setting; +}; + +} // namespace WarningUtils + +// Like Error, but we always report the C++ backtrace, instead of only +// reporting when TORCH_SHOW_CPP_STACKTRACES +class C10_API ErrorAlwaysShowCppStacktrace : public Error { + using Error::Error; + const char* what_without_backtrace() const noexcept override { + return what(); + } +}; + +// Used in ATen for out-of-bound indices that can reasonably only be detected +// lazily inside a kernel (See: advanced indexing). These turn into +// IndexError when they cross to Python. +class C10_API IndexError : public Error { + using Error::Error; +}; + +// Used in ATen for invalid values. These turn into +// ValueError when they cross to Python. +class C10_API ValueError : public Error { + using Error::Error; +}; + +// Used in ATen for invalid types. These turn into +// TypeError when they cross to Python. +class C10_API TypeError : public Error { + using Error::Error; +}; + +// Used in ATen for functionality that is not implemented. These turn into +// NotImplementedError when they cross to Python. +class C10_API NotImplementedError : public Error { + using Error::Error; +}; + +// Used in ATen for buffer-related errors, e.g. trying to create a DLPack of +// an unsupported device. These turn into BufferError when they cross to +// Python. +class C10_API BufferError : public Error { + using Error::Error; +}; + +// Used in ATen for non finite indices. These turn into +// ExitException when they cross to Python. +class C10_API EnforceFiniteError : public Error { + using Error::Error; +}; + +// Used in Onnxifi backend lowering. These turn into +// ExitException when they cross to Python. +class C10_API OnnxfiBackendSystemError : public Error { + using Error::Error; +}; + +// Used for numerical errors from the linalg module. These +// turn into LinAlgError when they cross into Python. +class C10_API LinAlgError : public Error { + using Error::Error; +}; + +class C10_API OutOfMemoryError : public Error { + using Error::Error; +}; + +// Used for handling syntactic errors in input arguments. +// These turn into SyntaxError when the cross into Python. +class C10_API SyntaxError : public Error { + using Error::Error; +}; + +// Raised when accelerator API call hits an error. +// These turn into AcceleratorError when the cross into Python +class C10_API AcceleratorError : public Error { + int32_t error_code; + + public: + AcceleratorError(SourceLocation loc, int32_t code, const std::string& msg) + : Error(loc, msg), error_code(code) {} + int32_t get_error_code() const { + return error_code; + } +}; + +// Base error type for all distributed errors. +// These turn into DistError when they cross into Python. +class C10_API DistError : public Error { + using Error::Error; +}; + +// Used for collective communication library errors from the distributed module. +// These turn into DistBackendError when they cross into Python. +class C10_API DistBackendError : public DistError { + using DistError::DistError; +}; + +// Used for errors originating from the store. +// These turn into DistStoreError when they cross into Python. +class C10_API DistStoreError : public DistError { + using DistError::DistError; +}; + +// Used for errors originating from the TCP/IP stack and not from collective +// libraries. These turn into DistNetworkError when they cross into Python. +class C10_API DistNetworkError : public DistError { + using DistError::DistError; +}; + +// Raised when a queue is empty and a non-blocking pop is called. +// Translated to torch.distributed.QueueEmptyError in Python +class C10_API DistQueueEmptyError : public DistStoreError { + using DistStoreError::DistStoreError; +}; + +// A utility function to return an exception std::string by prepending its +// exception type before its what() content +C10_API std::string GetExceptionString(const std::exception& e); + +} // namespace c10 + +// Private helper macro for implementing TORCH_INTERNAL_ASSERT and TORCH_CHECK +// +// Note: In the debug build With MSVC, __LINE__ might be of long type (a.k.a +// int32_t), which is different from the definition of `SourceLocation` that +// requires unsigned int (a.k.a uint32_t) and may cause a compile error with the +// message: error C2397: conversion from 'long' to 'uint32_t' requires a +// narrowing conversion Here the static cast is used to pass the build. if this +// is used inside a lambda the __func__ macro expands to operator(), which isn't +// very useful, but hard to fix in a macro so suppressing the warning. +#define C10_THROW_ERROR(err_type, msg) \ + throw ::c10::err_type( \ + {__func__, __FILE__, static_cast(__LINE__)}, msg) + +#define C10_BUILD_ERROR(err_type, msg) \ + ::c10::err_type({__func__, __FILE__, static_cast(__LINE__)}, msg) + +// Private helper macro for workaround MSVC misexpansion of nested macro +// invocations involving __VA_ARGS__. See +// https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly +#define C10_EXPAND_MSVC_WORKAROUND(x) x + +#include + +// ---------------------------------------------------------------------------- +// Error reporting macros +// ---------------------------------------------------------------------------- + +#ifdef STRIP_ERROR_MESSAGES +#define TORCH_RETHROW(e, ...) \ + do { \ + (void)e; /* Suppress unused variable warning */ \ + throw; \ + } while (false) +#else +#define TORCH_RETHROW(e, ...) \ + do { \ + e.add_context(::c10::str(__VA_ARGS__)); \ + throw; \ + } while (false) +#endif + +// A utility macro to provide assert()-like functionality; that is, enforcement +// of internal invariants in code. It supports an arbitrary number of extra +// arguments (evaluated only on failure), which will be printed in the assert +// failure message using operator<< (this is useful to print some variables +// which may be useful for debugging.) +// +// Usage: +// TORCH_INTERNAL_ASSERT(should_be_true); +// TORCH_INTERNAL_ASSERT(x == 0, "x = ", x); +// +// Assuming no bugs in PyTorch, the conditions tested by this macro should +// always be true; e.g., it should be possible to disable all of these +// conditions without changing observable user behavior. If you would like to +// do error reporting for user input, please use TORCH_CHECK instead. +// +// NOTE: It is SAFE to use this macro in production code; on failure, this +// simply raises an exception, it does NOT unceremoniously quit the process +// (unlike assert()). +// +#ifdef STRIP_ERROR_MESSAGES +#define TORCH_INTERNAL_ASSERT(cond, ...) \ + if (C10_UNLIKELY_OR_CONST(!(cond))) { \ + ::c10::detail::torchCheckFail( \ + __func__, \ + __FILE__, \ + static_cast(__LINE__), \ + #cond " INTERNAL ASSERT FAILED at " C10_STRINGIZE(__FILE__)); \ + } +#else +// It would be nice if we could build a combined string literal out of +// the TORCH_INTERNAL_ASSERT prefix and a user-provided string literal +// as the first argument, but there doesn't seem to be any good way to +// do that while still supporting having a first argument that isn't a +// string literal. +#define TORCH_INTERNAL_ASSERT(cond, ...) \ + if (C10_UNLIKELY_OR_CONST(!(cond))) { \ + ::c10::detail::torchInternalAssertFail( \ + __func__, \ + __FILE__, \ + static_cast(__LINE__), \ + #cond \ + " INTERNAL ASSERT FAILED at " C10_STRINGIZE(__FILE__) ":" C10_STRINGIZE( \ + __LINE__) ", please report a bug to PyTorch. ", \ + c10::str(__VA_ARGS__)); \ + } +#endif + +// A utility macro to make it easier to test for error conditions from user +// input. Like TORCH_INTERNAL_ASSERT, it supports an arbitrary number of extra +// arguments (evaluated only on failure), which will be printed in the error +// message using operator<< (e.g., you can pass any object which has +// operator<< defined. Most objects in PyTorch have these definitions!) +// +// Usage: +// TORCH_CHECK(should_be_true); // A default error message will be provided +// // in this case; but we recommend writing an +// // explicit error message, as it is more +// // user friendly. +// TORCH_CHECK(x == 0, "Expected x to be 0, but got ", x); +// +// On failure, this macro will raise an exception. If this exception propagates +// to Python, it will convert into a Python RuntimeError. +// +// NOTE: It is SAFE to use this macro in production code; on failure, this +// simply raises an exception, it does NOT unceremoniously quit the process +// (unlike CHECK() from glog.) +// +#define TORCH_CHECK_WITH(error_t, cond, ...) \ + TORCH_CHECK_WITH_MSG(error_t, cond, "", __VA_ARGS__) + +#ifdef STRIP_ERROR_MESSAGES +#define TORCH_CHECK_MSG(cond, type, ...) \ + (#cond #type " CHECK FAILED at " C10_STRINGIZE(__FILE__)) +#define TORCH_CHECK_WITH_MSG(error_t, cond, type, ...) \ + if (C10_UNLIKELY_OR_CONST(!(cond))) { \ + C10_THROW_ERROR(Error, TORCH_CHECK_MSG(cond, type, __VA_ARGS__)); \ + } +#else + +namespace c10::detail { +template +auto torchCheckMsgImpl(const char* /*msg*/, const Args&... args) { + return ::c10::str(args...); +} +inline C10_API const char* torchCheckMsgImpl(const char* msg) { + return msg; +} +// If there is just 1 user-provided C-string argument, use it. +inline C10_API const char* torchCheckMsgImpl( + const char* /*msg*/, + const char* args) { + return args; +} +} // namespace c10::detail + +#define TORCH_CHECK_MSG(cond, type, ...) \ + (::c10::detail::torchCheckMsgImpl( \ + "Expected " #cond \ + " to be true, but got false. " \ + "(Could this error message be improved? If so, " \ + "please report an enhancement request to PyTorch.)", \ + ##__VA_ARGS__)) +#define TORCH_CHECK_WITH_MSG(error_t, cond, type, ...) \ + if (C10_UNLIKELY_OR_CONST(!(cond))) { \ + C10_THROW_ERROR(error_t, TORCH_CHECK_MSG(cond, type, __VA_ARGS__)); \ + } +#endif + +namespace c10::detail { + +[[noreturn]] C10_API void torchCheckFail( + const char* func, + const char* file, + uint32_t line, + const std::string& msg); +[[noreturn]] C10_API void torchCheckFail( + const char* func, + const char* file, + uint32_t line, + const char* msg); + +// The c10::str() call that creates userMsg can have 1 of 3 return +// types depending on the number and types of arguments passed to +// TORCH_INTERNAL_ASSERT. 0 arguments will get a +// CompileTimeEmptyString, 1 const char * will be passed straight +// through, and anything else will get converted to std::string. +[[noreturn]] C10_API void torchInternalAssertFail( + const char* func, + const char* file, + uint32_t line, + const char* condMsg, + const char* userMsg); +[[noreturn]] inline C10_API void torchInternalAssertFail( + const char* func, + const char* file, + uint32_t line, + const char* condMsg, + ::c10::detail::CompileTimeEmptyString /*userMsg*/) { + torchCheckFail(func, file, line, condMsg); +} +[[noreturn]] C10_API void torchInternalAssertFail( + const char* func, + const char* file, + uint32_t line, + const char* condMsg, + const std::string& userMsg); + +} // namespace c10::detail + +#ifdef STANDALONE_TORCH_HEADER + +// TORCH_CHECK throws std::runtime_error instead of c10::Error which is +// useful when certain headers are used in a libtorch-independent way, +// e.g. when Vectorized is used in AOTInductor generated code. +#ifdef STRIP_ERROR_MESSAGES +#define TORCH_CHECK(cond, ...) \ + if (C10_UNLIKELY_OR_CONST(!(cond))) { \ + throw std::runtime_error(TORCH_CHECK_MSG( \ + cond, \ + "", \ + __func__, \ + ", ", \ + __FILE__, \ + ":", \ + __LINE__, \ + ", ", \ + __VA_ARGS__)); \ + } +#else +#define TORCH_CHECK(cond, ...) \ + if (C10_UNLIKELY_OR_CONST(!(cond))) { \ + throw std::runtime_error(TORCH_CHECK_MSG( \ + cond, \ + "", \ + __func__, \ + ", ", \ + __FILE__, \ + ":", \ + __LINE__, \ + ", ", \ + ##__VA_ARGS__)); \ + } +#endif + +#else + +#ifdef STRIP_ERROR_MESSAGES +#define TORCH_CHECK(cond, ...) \ + if (C10_UNLIKELY_OR_CONST(!(cond))) { \ + ::c10::detail::torchCheckFail( \ + __func__, \ + __FILE__, \ + static_cast(__LINE__), \ + TORCH_CHECK_MSG(cond, "", __VA_ARGS__)); \ + } +#else +#define TORCH_CHECK(cond, ...) \ + if (C10_UNLIKELY_OR_CONST(!(cond))) { \ + ::c10::detail::torchCheckFail( \ + __func__, \ + __FILE__, \ + static_cast(__LINE__), \ + TORCH_CHECK_MSG(cond, "", ##__VA_ARGS__)); \ + } +#endif + +#endif + +// An utility macro that does what `TORCH_CHECK` does if compiled in the host +// code, otherwise does nothing. Supposed to be used in the code shared between +// host and device code as an alternative for `TORCH_CHECK`. +#if defined(__CUDACC__) || defined(__HIPCC__) +#define TORCH_CHECK_IF_NOT_ON_CUDA(cond, ...) +#else +#define TORCH_CHECK_IF_NOT_ON_CUDA(cond, ...) TORCH_CHECK(cond, ##__VA_ARGS__) +#endif + +// Debug only version of TORCH_INTERNAL_ASSERT. This macro only checks in debug +// build, and does nothing in release build. It is appropriate to use +// in situations where you want to add an assert to a hotpath, but it is +// too expensive to run this assert on production builds. +#ifdef NDEBUG +// Optimized version - generates no code. +#define TORCH_INTERNAL_ASSERT_DEBUG_ONLY(...) \ + while (false) \ + C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(__VA_ARGS__)) +#else +#define TORCH_INTERNAL_ASSERT_DEBUG_ONLY(...) \ + C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(__VA_ARGS__)) +#endif + +// TODO: We're going to get a lot of similar looking string literals +// this way; check if this actually affects binary size. + +// Like TORCH_CHECK, but raises LinAlgError instead of Error. +#define TORCH_CHECK_LINALG(cond, ...) \ + TORCH_CHECK_WITH_MSG(LinAlgError, cond, "LINALG", __VA_ARGS__) + +// Like TORCH_CHECK, but raises IndexErrors instead of Errors. +#define TORCH_CHECK_INDEX(cond, ...) \ + TORCH_CHECK_WITH_MSG(IndexError, cond, "INDEX", __VA_ARGS__) + +// Like TORCH_CHECK, but raises ValueErrors instead of Errors. +#define TORCH_CHECK_VALUE(cond, ...) \ + TORCH_CHECK_WITH_MSG(ValueError, cond, "VALUE", __VA_ARGS__) + +// Like TORCH_CHECK, but raises TypeErrors instead of Errors. +#define TORCH_CHECK_TYPE(cond, ...) \ + TORCH_CHECK_WITH_MSG(TypeError, cond, "TYPE", __VA_ARGS__) + +// Like TORCH_CHECK, but raises NotImplementedErrors instead of Errors. +#define TORCH_CHECK_NOT_IMPLEMENTED(cond, ...) \ + TORCH_CHECK_WITH_MSG(NotImplementedError, cond, "TYPE", __VA_ARGS__) + +// Like TORCH_CHECK, but raises BufferError instead of Errors. +#define TORCH_CHECK_BUFFER(cond, ...) \ + TORCH_CHECK_WITH_MSG(BufferError, cond, "TYPE", __VA_ARGS__) + +#define TORCH_CHECK_ALWAYS_SHOW_CPP_STACKTRACE(cond, ...) \ + TORCH_CHECK_WITH_MSG( \ + ErrorAlwaysShowCppStacktrace, cond, "TYPE", ##__VA_ARGS__) + +#ifdef STRIP_ERROR_MESSAGES +#define WARNING_MESSAGE_STRING(...) \ + ::c10::detail::CompileTimeEmptyString {} +#else +#define WARNING_MESSAGE_STRING(...) ::c10::str(__VA_ARGS__) +#endif + +// Report a warning to the user. Accepts an arbitrary number of extra +// arguments which are concatenated into the warning message using operator<< +// +#ifdef DISABLE_WARN +#define _TORCH_WARN_WITH(...) ((void)0); +#else +#define _TORCH_WARN_WITH(warning_t, ...) \ + ::c10::warn(::c10::Warning( \ + warning_t(), \ + {__func__, __FILE__, static_cast(__LINE__)}, \ + WARNING_MESSAGE_STRING(__VA_ARGS__), \ + false)); +#endif + +#define TORCH_WARN(...) _TORCH_WARN_WITH(::c10::UserWarning, __VA_ARGS__); + +#define TORCH_WARN_DEPRECATION(...) \ + _TORCH_WARN_WITH(::c10::DeprecationWarning, __VA_ARGS__); + +// Report a warning to the user only once. Accepts an arbitrary number of extra +// arguments which are concatenated into the warning message using operator<< +// +#define _TORCH_WARN_ONCE(...) \ + [[maybe_unused]] static const auto C10_ANONYMOUS_VARIABLE( \ + torch_warn_once_) = [&] { \ + TORCH_WARN(__VA_ARGS__); \ + return true; \ + }() + +#ifdef DISABLE_WARN +#define TORCH_WARN_ONCE(...) ((void)0); +#else +#define TORCH_WARN_ONCE(...) \ + if (::c10::WarningUtils::get_warnAlways()) { \ + TORCH_WARN(__VA_ARGS__); \ + } else { \ + _TORCH_WARN_ONCE(__VA_ARGS__); \ + } +#endif + +// Report an error with a specific argument +// NOTE: using the argument name in TORCH_CHECK's message is preferred +#define TORCH_CHECK_ARG(cond, argN, ...) \ + TORCH_CHECK(cond, "invalid argument ", argN, ": ", __VA_ARGS__) + +#ifndef FATAL_IF +#ifdef C10_USE_GLOG +#define FATAL_IF(condition) \ + condition ? (void)0 \ + : ::c10::LoggerVoidify() & \ + ::c10::MessageLogger( \ + ::c10::SourceLocation::current(), ::google::GLOG_FATAL) \ + .stream() +#else +#define FATAL_IF(condition) \ + condition ? (void)0 \ + : ::c10::LoggerVoidify() & \ + ::c10::MessageLogger( \ + ::c10::SourceLocation::current(), ::c10::GLOG_FATAL) \ + .stream() +#endif +#endif + +#ifndef NON_FATAL_IF +#ifdef C10_USE_GLOG +#define NON_FATAL_IF(condition) \ + condition ? (void)0 \ + : ::c10::LoggerVoidify() & \ + ::c10::MessageLogger( \ + ::c10::SourceLocation::current(), ::google::GLOG_FATAL, false) \ + .stream() +#else +#define NON_FATAL_IF(condition) \ + condition ? (void)0 \ + : ::c10::LoggerVoidify() & \ + ::c10::MessageLogger( \ + ::c10::SourceLocation::current(), ::c10::GLOG_FATAL, false) \ + .stream() +#endif +#endif + +// Binary comparison check macros +#define TORCH_CHECK_OP(val1, val2, op) \ + NON_FATAL_IF(((val1)op(val2))) \ + << "Check failed: " #val1 " " #op " " #val2 " (" << (val1) << " vs. " \ + << (val2) << "). " + +#define TORCH_DCHECK_OP(val1, val2, op) \ + FATAL_IF(((val1)op(val2))) << "Check failed: " #val1 " " #op " " #val2 " (" \ + << (val1) << " vs. " << (val2) << "). " + +#define TORCH_CHECK_EQ(val1, val2) TORCH_CHECK_OP(val1, val2, ==) +#define TORCH_CHECK_NE(val1, val2) TORCH_CHECK_OP(val1, val2, !=) +#define TORCH_CHECK_LE(val1, val2) TORCH_CHECK_OP(val1, val2, <=) +#define TORCH_CHECK_LT(val1, val2) TORCH_CHECK_OP(val1, val2, <) +#define TORCH_CHECK_GE(val1, val2) TORCH_CHECK_OP(val1, val2, >=) +#define TORCH_CHECK_GT(val1, val2) TORCH_CHECK_OP(val1, val2, >) + +// Debug versions of TORCH_CHECK_OP macros +#ifndef NDEBUG +#define TORCH_DCHECK_EQ(val1, val2) TORCH_DCHECK_OP(val1, val2, ==) +#define TORCH_DCHECK_NE(val1, val2) TORCH_DCHECK_OP(val1, val2, !=) +#define TORCH_DCHECK_LE(val1, val2) TORCH_DCHECK_OP(val1, val2, <=) +#define TORCH_DCHECK_LT(val1, val2) TORCH_DCHECK_OP(val1, val2, <) +#define TORCH_DCHECK_GE(val1, val2) TORCH_DCHECK_OP(val1, val2, >=) +#define TORCH_DCHECK_GT(val1, val2) TORCH_DCHECK_OP(val1, val2, >) +#else // !NDEBUG +// Optimized versions - generate no code +#define TORCH_DCHECK_EQ(val1, val2) \ + while (false) \ + TORCH_DCHECK_OP(val1, val2, ==) +#define TORCH_DCHECK_NE(val1, val2) \ + while (false) \ + TORCH_DCHECK_OP(val1, val2, !=) +#define TORCH_DCHECK_LE(val1, val2) \ + while (false) \ + TORCH_DCHECK_OP(val1, val2, <=) +#define TORCH_DCHECK_LT(val1, val2) \ + while (false) \ + TORCH_DCHECK_OP(val1, val2, <) +#define TORCH_DCHECK_GE(val1, val2) \ + while (false) \ + TORCH_DCHECK_OP(val1, val2, >=) +#define TORCH_DCHECK_GT(val1, val2) \ + while (false) \ + TORCH_DCHECK_OP(val1, val2, >) +#endif // NDEBUG + +// Null pointer check macro +#define TORCH_CHECK_NOTNULL(val) \ + ::c10::CheckNotNull(__FILE__, __LINE__, #val, (val), false) + +#ifndef NDEBUG +#define TORCH_DCHECK_NOTNULL(val) \ + ::c10::CheckNotNull(__FILE__, __LINE__, #val, (val), true) +#else // !NDEBUG +#define TORCH_DCHECK_NOTNULL(val) \ + while (false) \ + TORCH_CHECK_NOTNULL(val) +#endif // NDEBUG + +// ---------------------------------------------------------------------------- +// Deprecated macros +// ---------------------------------------------------------------------------- + +namespace c10::detail { + +/* +// Deprecation disabled until we fix sites in our codebase +[[deprecated("AT_ERROR(msg) is deprecated, use TORCH_CHECK(false, msg) +instead.")]] +*/ +inline void deprecated_AT_ERROR() {} + +/* +// Deprecation disabled until we fix sites in our codebase +[[deprecated("AT_ASSERT is deprecated, if you mean to indicate an +internal invariant failure, use " \ + "TORCH_INTERNAL_ASSERT instead; if you mean to do user +error checking, use " \ "TORCH_CHECK. See +https://github.com/pytorch/pytorch/issues/20287 for more details.")]] +*/ +inline void deprecated_AT_ASSERT() {} + +/* +// Deprecation disabled until we fix sites in our codebase +[[deprecated("AT_ASSERTM is deprecated, if you mean to indicate an +internal invariant failure, use " \ + "TORCH_INTERNAL_ASSERT instead; if you mean to do user +error checking, use " \ "TORCH_CHECK. See +https://github.com/pytorch/pytorch/issues/20287 for more details.")]] +*/ +inline void deprecated_AT_ASSERTM() {} + +} // namespace c10::detail + +// Deprecated alias; this alias was deprecated because people kept mistakenly +// using it for user error checking. Use TORCH_INTERNAL_ASSERT or TORCH_CHECK +// instead. See https://github.com/pytorch/pytorch/issues/20287 for more +// details. +#define AT_ASSERT(...) \ + do { \ + ::c10::detail::deprecated_AT_ASSERT(); \ + C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(__VA_ARGS__)); \ + } while (false) + +// Deprecated alias, like AT_ASSERT. The new TORCH_INTERNAL_ASSERT macro +// supports both 0-ary and variadic calls, so having a separate +// message-accepting macro is not necessary. +// +// NB: we MUST include cond explicitly here, as MSVC will miscompile the macro +// expansion, shunting all of __VA_ARGS__ to cond. An alternate workaround +// can be seen at +// https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly +#define AT_ASSERTM(cond, ...) \ + do { \ + ::c10::detail::deprecated_AT_ASSERTM(); \ + C10_EXPAND_MSVC_WORKAROUND(TORCH_INTERNAL_ASSERT(cond, __VA_ARGS__)); \ + } while (false) + +// Deprecated alias; this alias was deprecated because it represents extra API +// surface that makes it hard for people to understand what macro to use. +// Use TORCH_CHECK(false, ...) or TORCH_INTERNAL_ASSERT(false, ...) to +// unconditionally fail at a line of code. +#define AT_ERROR(...) \ + do { \ + ::c10::detail::deprecated_AT_ERROR(); \ + C10_EXPAND_MSVC_WORKAROUND(TORCH_CHECK(false, ::c10::str(__VA_ARGS__))); \ + } while (false) + +#endif // C10_UTIL_EXCEPTION_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ExclusivelyOwned.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ExclusivelyOwned.h new file mode 100644 index 0000000000000000000000000000000000000000..24cdba8d3ea3d9850b673974971c9eca37ff365f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ExclusivelyOwned.h @@ -0,0 +1,145 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace c10 { + +// See example implementation in TensorBase.h and TensorBody.h. +// Synopsis: +// +// repr_type -- type to use to store an owned T in ExclusivelyOwned. +// +// pointer_type -- pointer-esque type to return from +// ExclusivelyOwned's get() and operator*() methods. +// +// const_pointer_type -- similar to pointer_type, used for the const methods. +// +// static repr_type nullRepr() -- return a null instance of repr_type. +// +// template +// static repr_type createInPlace(Args&&... args) -- used by the in-place +// ExclusivelyOwned constructor. +// +// static repr_type moveToRepr(T&& x) -- move the given x into an +// instance of repr_type. used by the ExclusivelyOwned(T&&) +// constructor. +// +// static void destroyOwned(repr_type x) -- free memory for a +// known-exclusively-owned instance of x. Replaces calling repr_type's +// destructor. Being able to implement this more efficiently than +// repr_type's destructor is the main reason to use ExclusivelyOwned +// for a type. +// +// static T take(repr_type&) -- move out of the given repr_type into an owned T. +// +// static pointer_type getImpl(const repr_type&) -- return a pointer +// to the given repr_type. May take repr_type by value if that is more +// efficient. +template +struct ExclusivelyOwnedTraits; + +/// ExclusivelyOwned is a smart-pointer-like wrapper around an +/// exclusively-owned instance of some type T that normally has +/// mandatory reference counting (currently just Tensor). If you have +/// an isolated piece of code that knows that it has sole ownership of +/// an object of one of these types (i.e., because you created it +/// directly or using a factory function) and that object will not +/// escape from that isolated piece of code, then moving the object +/// into an ExclusivelyOwned will avoid an atomic reference count +/// decrement at destruction time. +/// +/// If you directly create the Tensor in the first +/// place, you can use the in_place constructor of ExclusivelyOwned to +/// additionally avoid doing any stores to initialize the refcount & +/// weakcount. +template +class ExclusivelyOwned { + using EOT = ExclusivelyOwnedTraits; + typename ExclusivelyOwnedTraits::repr_type repr_; + + public: + ExclusivelyOwned() : repr_(EOT::nullRepr()) {} + + explicit ExclusivelyOwned(T&& t) : repr_(EOT::moveToRepr(std::move(t))) {} + + template + explicit ExclusivelyOwned(std::in_place_t /*unused*/, Args&&... args) + : repr_(EOT::createInPlace(std::forward(args)...)) {} + + ExclusivelyOwned(const ExclusivelyOwned&) = delete; + + ExclusivelyOwned(ExclusivelyOwned&& rhs) noexcept + : repr_(std::move(rhs.repr_)) { + rhs.repr_ = EOT::nullRepr(); + } + + ExclusivelyOwned& operator=(const ExclusivelyOwned&) = delete; + + ExclusivelyOwned& operator=(ExclusivelyOwned&& rhs) noexcept { + EOT::destroyOwned(repr_); + repr_ = std::move(rhs.repr_); + rhs.repr_ = EOT::nullRepr(); + return *this; + } + + ExclusivelyOwned& operator=(T&& rhs) noexcept { + EOT::destroyOwned(repr_); + repr_ = EOT::moveToRepr(std::move(rhs)); + return *this; + } + + ~ExclusivelyOwned() { + EOT::destroyOwned(repr_); + // Don't bother to call the destructor of repr_, since we already + // did specialized destruction for the exclusively-owned case in + // destroyOwned! + } + + // We don't provide this because it would require us to be able to + // differentiate an owned-but-empty T from a lack of T. This is + // particularly problematic for Tensor, which wants to use an + // undefined Tensor as its null state. + explicit operator bool() const noexcept = delete; + + operator T() && { + return take(); + } + + // NOTE: the equivalent operation on MaybeOwned is a moving + // operator*. For ExclusivelyOwned, take() and operator*() may well + // have different return types, so they are different functions. + T take() && { + return EOT::take(repr_); + } + + typename EOT::const_pointer_type operator->() const { + return get(); + } + + typename EOT::const_pointer_type get() const { + return EOT::getImpl(repr_); + } + + typename EOT::pointer_type operator->() { + return get(); + } + + typename EOT::pointer_type get() { + return EOT::getImpl(repr_); + } + + std::remove_pointer_t& operator*() const { + return *get(); + } + + std::remove_pointer_t& operator*() { + return *get(); + } +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ExclusivelyOwnedTensorTraits.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ExclusivelyOwnedTensorTraits.h new file mode 100644 index 0000000000000000000000000000000000000000..5b3a76fe9fc94776a70538d212e657435189b350 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ExclusivelyOwnedTensorTraits.h @@ -0,0 +1,80 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include + +namespace c10 { +// Shared ExclusivelyOwnedTraits implementation between caffe2::Tensor and +// at::TensorBase. +template +struct ExclusivelyOwnedTensorTraits { + using repr_type = TensorType; + using pointer_type = TensorType*; + using const_pointer_type = const TensorType*; + + static repr_type nullRepr() { + return TensorType(); + } + + template + static repr_type createInPlace(Args&&... args) { + return TensorType(std::forward(args)...); + } + + static repr_type moveToRepr(TensorType&& x) { + return std::move(x); + } + + static void destroyOwned(TensorType& x) { + TensorImpl* const toDestroy = x.unsafeReleaseTensorImpl(); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + toDestroy != nullptr, "Tensor somehow got null TensorImpl?"); + // May be 0 because UndefinedTensorImpl doesn't get its refcount + // incremented. + const bool isUndefined = toDestroy == UndefinedTensorImpl::singleton(); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + toDestroy->refcount() == 1 || + (toDestroy->refcount() == 0 && isUndefined), + "ExclusivelyOwned destroyed with isUndefined ", + isUndefined, + " and refcount ", + toDestroy->refcount(), + ", expected 1 or, if isUndefined, 0!"); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + toDestroy->weakcount() == 1 || + (toDestroy->weakcount() == 0 && + toDestroy == UndefinedTensorImpl::singleton()), + "ExclusivelyOwned destroyed with isUndefined ", + isUndefined, + " and weakcount ", + toDestroy->weakcount(), + ", expected 1 or, if isUndefined, 0!"); + if (!isUndefined) { +#ifndef NDEBUG + // Needed to pass the debug assertions in ~intrusive_ptr_target. + toDestroy->combined_refcount_.store(0, std::memory_order_relaxed); +#endif + delete toDestroy; + } + } + + static TensorType take(TensorType& x) { + return std::move(x); + } + + static pointer_type getImpl(repr_type& x) { + return &x; + } + + static const_pointer_type getImpl(const repr_type& x) { + return &x; + } +}; +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/FbcodeMaps.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/FbcodeMaps.h new file mode 100644 index 0000000000000000000000000000000000000000..8ce3648d928f50cf474d26cab63c16df16dda728 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/FbcodeMaps.h @@ -0,0 +1,34 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_FBCODEMAPS_H_ +#define C10_UTIL_FBCODEMAPS_H_ + +// Map typedefs so that we can use folly's F14 maps in fbcode without +// taking a folly dependency. + +#ifdef FBCODE_CAFFE2 +#include +#include +#else +#include +#include +#endif + +namespace c10 { +#ifdef FBCODE_CAFFE2 +template +using FastMap = folly::F14FastMap; +template +using FastSet = folly::F14FastSet; +#else +template +using FastMap = std::unordered_map; +template +using FastSet = std::unordered_set; +#endif +} // namespace c10 + +#endif // C10_UTIL_FBCODEMAPS_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/FileSystem.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/FileSystem.h new file mode 100644 index 0000000000000000000000000000000000000000..964c57668f629d342576a50f173247192e9f6c4d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/FileSystem.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Shim header for filesystem for compilers that are too old to have it not +// in the experimental namespace + +#if __has_include() +#include +#elif __has_include() +#include +#else +#error "Neither nor is available." +#endif + +namespace c10 { + +#if __has_include() +// NOLINTNEXTLINE(misc-unused-alias-decls) +namespace filesystem = std::filesystem; +#elif __has_include() +// NOLINTNEXTLINE(misc-unused-alias-decls) +namespace filesystem = std::experimental::filesystem; +#endif + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Flags.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Flags.h new file mode 100644 index 0000000000000000000000000000000000000000..c2485bfdebae3a17f0fc8131cfcf24c01052c2a9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Flags.h @@ -0,0 +1,247 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_FLAGS_H_ +#define C10_UTIL_FLAGS_H_ + +/* Commandline flags support for C10. + * + * This is a portable commandline flags tool for c10, so we can optionally + * choose to use gflags or a lightweight custom implementation if gflags is + * not possible on a certain platform. If you have gflags installed, set the + * macro C10_USE_GFLAGS will seamlessly route everything to gflags. + * + * To define a flag foo of type bool default to true, do the following in the + * *global* namespace: + * C10_DEFINE_bool(foo, true, "An example."); + * + * To use it in another .cc file, you can use C10_DECLARE_* as follows: + * C10_DECLARE_bool(foo); + * + * In both cases, you can then access the flag via FLAGS_foo. + * + * It is recommended that you build with gflags. To learn more about the flags + * usage, refer to the gflags page here: + * + * https://gflags.github.io/gflags/ + * + * Note about Python users / devs: gflags is initiated from a C++ function + * ParseCommandLineFlags, and is usually done in native binaries in the main + * function. As Python does not have a modifiable main function, it is usually + * difficult to change the flags after Python starts. Hence, it is recommended + * that one sets the default value of the flags to one that's acceptable in + * general - that will allow Python to run without wrong flags. + */ + +#include +#include + +#include + +namespace c10 { +/** + * Sets the usage message when a commandline tool is called with "--help". + */ +C10_API void SetUsageMessage(const std::string& str); + +/** + * Returns the usage message for the commandline tool set by SetUsageMessage. + */ +C10_API const char* UsageMessage(); + +/** + * Parses the commandline flags. + * + * This command parses all the commandline arguments passed in via pargc + * and argv. Once it is finished, partc and argv will contain the remaining + * commandline args that c10 does not deal with. Note that following + * convention, argv[0] contains the binary name and is not parsed. + */ +C10_API bool ParseCommandLineFlags(int* pargc, char*** pargv); + +/** + * Checks if the commandline flags has already been passed. + */ +C10_API bool CommandLineFlagsHasBeenParsed(); + +} // namespace c10 + +//////////////////////////////////////////////////////////////////////////////// +// Below are gflags and non-gflags specific implementations. +// In general, they define the following macros for one to declare (use +// C10_DECLARE) or define (use C10_DEFINE) flags: +// C10_{DECLARE,DEFINE}_{int,int64,double,bool,string} +//////////////////////////////////////////////////////////////////////////////// + +#ifdef C10_USE_GFLAGS + +//////////////////////////////////////////////////////////////////////////////// +// Begin gflags section: most functions are basically rerouted to gflags. +//////////////////////////////////////////////////////////////////////////////// +#include + +// C10 uses hidden visibility by default. However, in gflags, it only uses +// export on Windows platform (with dllexport) but not on linux/mac (with +// default visibility). As a result, to ensure that we are always exporting +// global variables, we will redefine the GFLAGS_DLL_DEFINE_FLAG macro if we +// are building C10 as a shared library. +// This has to be done after the inclusion of gflags, because some early +// versions of gflags.h (e.g. 2.0 on ubuntu 14.04) directly defines the +// macros, so we need to do definition after gflags is done. +#ifdef GFLAGS_DLL_DEFINE_FLAG +#undef GFLAGS_DLL_DEFINE_FLAG +#endif // GFLAGS_DLL_DEFINE_FLAG +#ifdef GFLAGS_DLL_DECLARE_FLAG +#undef GFLAGS_DLL_DECLARE_FLAG +#endif // GFLAGS_DLL_DECLARE_FLAG +#define GFLAGS_DLL_DEFINE_FLAG C10_EXPORT +#define GFLAGS_DLL_DECLARE_FLAG C10_IMPORT + +// gflags before 2.0 uses namespace google and after 2.1 uses namespace gflags. +// Using GFLAGS_GFLAGS_H_ to capture this change. +#ifndef GFLAGS_GFLAGS_H_ +namespace gflags = google; +#endif // GFLAGS_GFLAGS_H_ + +// Motivation about the gflags wrapper: +// (1) We would need to make sure that the gflags version and the non-gflags +// version of C10 are going to expose the same flags abstraction. One should +// explicitly use FLAGS_flag_name to access the flags. +// (2) For flag names, it is recommended to start with c10_ to distinguish it +// from regular gflags flags. For example, do +// C10_DEFINE_BOOL(c10_my_flag, true, "An example"); +// to allow one to use FLAGS_c10_my_flag. +// (3) Gflags has a design issue that does not properly expose the global flags, +// if one builds the library with -fvisibility=hidden. The current gflags (as of +// Aug 2018) only deals with the Windows case using dllexport, and not the Linux +// counterparts. As a result, we will explicitly use C10_EXPORT to export the +// flags defined in C10. This is done via a global reference, so the flag +// itself is not duplicated - under the hood it is the same global gflags flag. +#define C10_GFLAGS_DEF_WRAPPER(type, real_type, name, default_value, help_str) \ + DEFINE_##type(name, default_value, help_str); + +#define C10_DEFINE_int(name, default_value, help_str) \ + C10_GFLAGS_DEF_WRAPPER(int32, gflags::int32, name, default_value, help_str) +#define C10_DEFINE_int32(name, default_value, help_str) \ + C10_DEFINE_int(name, default_value, help_str) +#define C10_DEFINE_int64(name, default_value, help_str) \ + C10_GFLAGS_DEF_WRAPPER(int64, gflags::int64, name, default_value, help_str) +#define C10_DEFINE_double(name, default_value, help_str) \ + C10_GFLAGS_DEF_WRAPPER(double, double, name, default_value, help_str) +#define C10_DEFINE_bool(name, default_value, help_str) \ + C10_GFLAGS_DEF_WRAPPER(bool, bool, name, default_value, help_str) +#define C10_DEFINE_string(name, default_value, help_str) \ + C10_GFLAGS_DEF_WRAPPER(string, ::fLS::clstring, name, default_value, help_str) + +// DECLARE_typed_var should be used in header files and in the global namespace. +#define C10_GFLAGS_DECLARE_WRAPPER(type, real_type, name) DECLARE_##type(name); + +#define C10_DECLARE_int(name) \ + C10_GFLAGS_DECLARE_WRAPPER(int32, gflags::int32, name) +#define C10_DECLARE_int32(name) C10_DECLARE_int(name) +#define C10_DECLARE_int64(name) \ + C10_GFLAGS_DECLARE_WRAPPER(int64, gflags::int64, name) +#define C10_DECLARE_double(name) \ + C10_GFLAGS_DECLARE_WRAPPER(double, double, name) +#define C10_DECLARE_bool(name) C10_GFLAGS_DECLARE_WRAPPER(bool, bool, name) +#define C10_DECLARE_string(name) \ + C10_GFLAGS_DECLARE_WRAPPER(string, ::fLS::clstring, name) + +#define TORCH_DECLARE_int(name) C10_DECLARE_int(name) +#define TORCH_DECLARE_int32(name) C10_DECLARE_int32(name) +#define TORCH_DECLARE_int64(name) C10_DECLARE_int64(name) +#define TORCH_DECLARE_double(name) C10_DECLARE_double(name) +#define TORCH_DECLARE_bool(name) C10_DECLARE_bool(name) +#define TORCH_DECLARE_string(name) C10_DECLARE_string(name) + +//////////////////////////////////////////////////////////////////////////////// +// End gflags section. +//////////////////////////////////////////////////////////////////////////////// + +#else // C10_USE_GFLAGS + +//////////////////////////////////////////////////////////////////////////////// +// Begin non-gflags section: providing equivalent functionality. +//////////////////////////////////////////////////////////////////////////////// + +namespace c10 { + +class C10_API C10FlagParser { + public: + bool success() { + return success_; + } + + protected: + template + bool Parse(const std::string& content, T* value); + bool success_{false}; +}; + +C10_DECLARE_REGISTRY(C10FlagsRegistry, C10FlagParser, const std::string&); + +} // namespace c10 + +// The macros are defined outside the c10 namespace. In your code, you should +// write the C10_DEFINE_* and C10_DECLARE_* macros outside any namespace +// as well. + +#define C10_DEFINE_typed_var(type, name, default_value, help_str) \ + C10_EXPORT type FLAGS_##name = default_value; \ + namespace c10 { \ + namespace { \ + class C10FlagParser_##name : public C10FlagParser { \ + public: \ + explicit C10FlagParser_##name(const std::string& content) { \ + success_ = C10FlagParser::Parse(content, &FLAGS_##name); \ + } \ + }; \ + RegistererC10FlagsRegistry g_C10FlagsRegistry_##name( \ + #name, \ + C10FlagsRegistry(), \ + RegistererC10FlagsRegistry::DefaultCreator, \ + "(" #type ", default " #default_value ") " help_str); \ + } \ + } + +#define C10_DEFINE_int(name, default_value, help_str) \ + C10_DEFINE_typed_var(int, name, default_value, help_str) +#define C10_DEFINE_int32(name, default_value, help_str) \ + C10_DEFINE_int(name, default_value, help_str) +#define C10_DEFINE_int64(name, default_value, help_str) \ + C10_DEFINE_typed_var(int64_t, name, default_value, help_str) +#define C10_DEFINE_double(name, default_value, help_str) \ + C10_DEFINE_typed_var(double, name, default_value, help_str) +#define C10_DEFINE_bool(name, default_value, help_str) \ + C10_DEFINE_typed_var(bool, name, default_value, help_str) +#define C10_DEFINE_string(name, default_value, help_str) \ + C10_DEFINE_typed_var(std::string, name, default_value, help_str) + +// DECLARE_typed_var should be used in header files and in the global namespace. +#define C10_DECLARE_typed_var(type, name) C10_API extern type FLAGS_##name + +#define C10_DECLARE_int(name) C10_DECLARE_typed_var(int, name) +#define C10_DECLARE_int32(name) C10_DECLARE_int(name) +#define C10_DECLARE_int64(name) C10_DECLARE_typed_var(int64_t, name) +#define C10_DECLARE_double(name) C10_DECLARE_typed_var(double, name) +#define C10_DECLARE_bool(name) C10_DECLARE_typed_var(bool, name) +#define C10_DECLARE_string(name) C10_DECLARE_typed_var(std::string, name) + +#define TORCH_DECLARE_typed_var(type, name) TORCH_API extern type FLAGS_##name + +#define TORCH_DECLARE_int(name) TORCH_DECLARE_typed_var(int, name) +#define TORCH_DECLARE_int32(name) TORCH_DECLARE_int(name) +#define TORCH_DECLARE_int64(name) TORCH_DECLARE_typed_var(int64_t, name) +#define TORCH_DECLARE_double(name) TORCH_DECLARE_typed_var(double, name) +#define TORCH_DECLARE_bool(name) TORCH_DECLARE_typed_var(bool, name) +#define TORCH_DECLARE_string(name) TORCH_DECLARE_typed_var(std::string, name) + +//////////////////////////////////////////////////////////////////////////////// +// End non-gflags section. +//////////////////////////////////////////////////////////////////////////////// + +#endif // C10_USE_GFLAGS + +#endif // C10_UTIL_FLAGS_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float4_e2m1fn_x2.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float4_e2m1fn_x2.h new file mode 100644 index 0000000000000000000000000000000000000000..fd690e5aa345ac097a2b4022b6e5a42677e403f8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float4_e2m1fn_x2.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fn-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fn-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..ed07b955168f7ab08b4a20657d8f36ea7cd4123c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fn-inl.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fn.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fn.h new file mode 100644 index 0000000000000000000000000000000000000000..ed07b955168f7ab08b4a20657d8f36ea7cd4123c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fn.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fnuz-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fnuz-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..30481a62430fdf08f2107bc1ab50e811314767f3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fnuz-inl.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fnuz.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fnuz.h new file mode 100644 index 0000000000000000000000000000000000000000..30481a62430fdf08f2107bc1ab50e811314767f3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e4m3fnuz.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..f4e0802e2f7b1a6712f95dea5b82267d8a8498dc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2-inl.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2.h new file mode 100644 index 0000000000000000000000000000000000000000..f4e0802e2f7b1a6712f95dea5b82267d8a8498dc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2fnuz-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2fnuz-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..f3e8c25099a630204f3c4ee345fd2a3653c14116 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2fnuz-inl.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2fnuz.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2fnuz.h new file mode 100644 index 0000000000000000000000000000000000000000..f3e8c25099a630204f3c4ee345fd2a3653c14116 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e5m2fnuz.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e8m0fnu-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e8m0fnu-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..030b23d64750b7378c8fc281c96d2fe662e38d88 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e8m0fnu-inl.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e8m0fnu.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e8m0fnu.h new file mode 100644 index 0000000000000000000000000000000000000000..030b23d64750b7378c8fc281c96d2fe662e38d88 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Float8_e8m0fnu.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/FunctionRef.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/FunctionRef.h new file mode 100644 index 0000000000000000000000000000000000000000..342824b5b9095219b123ab4bfb19fbb3cd1a7819 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/FunctionRef.h @@ -0,0 +1,80 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains some templates that are useful if you are working with the +// STL at all. +// +// No library is required when using these functions. +// +//===----------------------------------------------------------------------===// + +// c10: modified from llvm::function_ref +// c10: added more SFINAE to enable use in overloaded functions + +#pragma once + +#include +#include +#include + +namespace c10 { + +/// An efficient, type-erasing, non-owning reference to a callable. This is +/// intended for use as the type of a function parameter that is not used +/// after the function in question returns. +/// +/// This class does not own the callable, so it is not in general safe to store +/// a function_ref. +template +class function_ref; + +template +class function_ref { + Ret (*callback)(intptr_t callable, Params... params) = nullptr; + intptr_t callable{}; + + template + static Ret callback_fn(intptr_t callable, Params... params) { + return (*reinterpret_cast(callable))( + std::forward(params)...); + } + + public: + function_ref() = default; + function_ref(std::nullptr_t) {} + + template + function_ref( + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) + Callable&& callable, + std::enable_if_t, + function_ref>>* /*unused*/ + = nullptr, + std::enable_if_t, + Ret>>* /*unused*/ + = nullptr) + : callback(callback_fn>), + callable(reinterpret_cast(&callable)) {} + + Ret operator()(Params... params) const { + return callback(callable, std::forward(params)...); + } + + operator bool() const { + return callback; + } +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Gauge.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Gauge.h new file mode 100644 index 0000000000000000000000000000000000000000..b10ed7f5c9b33b99adbd031069af7c4e2fd3d0e3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Gauge.h @@ -0,0 +1,55 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include +#include + +namespace c10::monitor { +namespace detail { + +class GaugeImpl; + +class GaugeBackendIf { + public: + virtual ~GaugeBackendIf() = default; + virtual void record(int64_t value) noexcept = 0; +}; + +class GaugeBackendFactoryIf { + public: + virtual ~GaugeBackendFactoryIf() = default; + + // May return nullptr if the gauge will be ignored by the given backend. + virtual std::unique_ptr create( + std::string_view key) noexcept = 0; +}; + +void C10_API + registerGaugeBackend(std::unique_ptr /*backend*/); +} // namespace detail + +// A handle to a Gauge. +class C10_API GaugeHandle { + public: + explicit GaugeHandle(std::string_view key); + void record(int64_t value); + + private: + // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) + detail::GaugeImpl& impl_; +}; + +} // namespace c10::monitor + +#define STATIC_GAUGE(_key) \ + []() -> ::c10::monitor::GaugeHandle& { \ + static ::c10::monitor::GaugeHandle handle(#_key); \ + return handle; \ + }() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Half-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Half-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..78c3d37c1698db15f05b3b3367765075be2d9046 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Half-inl.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Half.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Half.h new file mode 100644 index 0000000000000000000000000000000000000000..0a3d4462657c7aa4d4e3827a2de811132911632b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Half.h @@ -0,0 +1,13 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +// need to keep the following for BC because the APIs in here were exposed +// before migrating Half to torch/headeronly +#if (defined(CPU_CAPABILITY_AVX2) || defined(CPU_CAPABILITY_AVX512)) && \ + !defined(__APPLE__) +#include +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/IdWrapper.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/IdWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..b985cd3e51c325b50dd5ee368c216689888123d6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/IdWrapper.h @@ -0,0 +1,82 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10 { + +/** + * This template simplifies generation of simple classes that wrap an id + * in a typesafe way. Namely, you can use it to create a very lightweight + * type that only offers equality comparators and hashing. Example: + * + * struct MyIdType final : IdWrapper { + * constexpr explicit MyIdType(uint32_t id): IdWrapper(id) {} + * }; + * + * Then in the global top level namespace: + * + * C10_DEFINE_HASH_FOR_IDWRAPPER(MyIdType); + * + * That's it - equality operators and hash functions are automatically defined + * for you, given the underlying type supports it. + */ +template +class IdWrapper { + public: + using underlying_type = UnderlyingType; + using concrete_type = ConcreteType; + + protected: + constexpr explicit IdWrapper(underlying_type id) noexcept( + noexcept(underlying_type(std::declval()))) + : id_(id) {} + + constexpr underlying_type underlyingId() const + noexcept(noexcept(underlying_type(std::declval()))) { + return id_; + } + + private: + friend size_t hash_value(const concrete_type& v) { + return std::hash()(v.id_); + } + + // TODO Making operator== noexcept if underlying type is noexcept equality + // comparable doesn't work with GCC 4.8. + // Fix this once we don't need GCC 4.8 anymore. + friend constexpr bool operator==( + const concrete_type& lhs, + const concrete_type& rhs) noexcept { + return lhs.id_ == rhs.id_; + } + + // TODO Making operator!= noexcept if operator== is noexcept doesn't work with + // GCC 4.8. + // Fix this once we don't need GCC 4.8 anymore. + friend constexpr bool operator!=( + const concrete_type& lhs, + const concrete_type& rhs) noexcept { + return !(lhs == rhs); + } + + underlying_type id_; +}; + +} // namespace c10 + +#define C10_DEFINE_HASH_FOR_IDWRAPPER(ClassName) \ + namespace std { \ + template <> \ + struct hash { \ + size_t operator()(ClassName x) const { \ + return hash_value(x); \ + } \ + }; \ + } + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/IntrusiveList.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/IntrusiveList.h new file mode 100644 index 0000000000000000000000000000000000000000..a28803082f7b641b92dae8acf320b7b9be348d74 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/IntrusiveList.h @@ -0,0 +1,211 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace c10 { + +template +class IntrusiveList; + +class IntrusiveListHook { + template + friend class ListIterator; + + template + friend class IntrusiveList; + + IntrusiveListHook* next_{nullptr}; + IntrusiveListHook* prev_{nullptr}; + + void link_before(IntrusiveListHook* next_node) { + next_ = next_node; + prev_ = next_node->prev_; + next_node->prev_ = this; + prev_->next_ = this; + } + + public: + IntrusiveListHook() : next_(this), prev_(this) {} + + IntrusiveListHook(const IntrusiveListHook&) = delete; + IntrusiveListHook& operator=(const IntrusiveListHook&) = delete; + IntrusiveListHook(IntrusiveListHook&&) = delete; + IntrusiveListHook& operator=(IntrusiveListHook&&) = delete; + + void unlink() { + TORCH_CHECK(is_linked()); + next_->prev_ = prev_; + prev_->next_ = next_; + next_ = this; + prev_ = this; + } + + ~IntrusiveListHook() { + if (is_linked()) { + unlink(); + } + } + + bool is_linked() const { + return next_ != this; + } +}; + +template +class ListIterator { + static_assert(std::is_same_v, IntrusiveListHook>); + static_assert(std::is_base_of_v); + P* ptr_; + + friend class IntrusiveList; + + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::conditional_t, const T, T>; + using difference_type = std::ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + + explicit ListIterator(P* ptr) : ptr_(ptr) {} + ~ListIterator() = default; + + ListIterator(const ListIterator&) = default; + ListIterator& operator=(const ListIterator&) = default; + ListIterator(ListIterator&&) = default; + ListIterator& operator=(ListIterator&&) = default; + + template < + typename Q, + class = std::enable_if_t && !std::is_const_v>> + ListIterator(const ListIterator& rhs) : ptr_(rhs.ptr_) {} + + template < + typename Q, + class = std::enable_if_t && !std::is_const_v>> + ListIterator& operator=(const ListIterator& rhs) { + ptr_ = rhs.ptr_; + return *this; + } + + template + bool operator==(const ListIterator& other) const { + return ptr_ == other.ptr_; + } + + template + bool operator!=(const ListIterator& other) const { + return !(*this == other); + } + + auto& operator*() const { + return static_cast(*ptr_); + } + + ListIterator& operator++() { + TORCH_CHECK(ptr_); + ptr_ = ptr_->next_; + return *this; + } + + ListIterator& operator--() { + TORCH_CHECK(ptr_); + ptr_ = ptr_->prev_; + return *this; + } + + auto* operator->() const { + return static_cast(ptr_); + } +}; + +template +class IntrusiveList { + static_assert(std::is_base_of_v); + + public: + IntrusiveList() = default; + IntrusiveList(const std::initializer_list>& items) { + for (auto& item : items) { + insert(this->end(), item); + } + } + ~IntrusiveList() { + while (head_.is_linked()) { + head_.next_->unlink(); + } + } + IntrusiveList(const IntrusiveList&) = delete; + IntrusiveList& operator=(const IntrusiveList&) = delete; + IntrusiveList(IntrusiveList&&) = delete; + IntrusiveList& operator=(IntrusiveList&&) = delete; + + using iterator = ListIterator; + using const_iterator = ListIterator; + + auto begin() const { + return ++const_iterator{&head_}; + } + + auto begin() { + return ++iterator{&head_}; + } + + auto end() const { + return const_iterator{&head_}; + } + + auto end() { + return iterator{&head_}; + } + + auto rbegin() const { + return std::reverse_iterator{end()}; + } + + auto rbegin() { + return std::reverse_iterator{end()}; + } + + auto rend() const { + return std::reverse_iterator{begin()}; + } + + auto rend() { + return std::reverse_iterator{begin()}; + } + + auto iterator_to(const T& n) const { + return const_iterator{&n}; + } + + auto iterator_to(T& n) { + return iterator{&n}; + } + + iterator insert(iterator pos, T& n) { + n.link_before(pos.ptr_); + return iterator{&n}; + } + + size_t size() const { + size_t ret = 0; + for ([[maybe_unused]] auto& _ : *this) { + ret++; + } + return ret; + } + + bool empty() const { + return !head_.is_linked(); + } + + private: + IntrusiveListHook head_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Lazy.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Lazy.h new file mode 100644 index 0000000000000000000000000000000000000000..204fc205ef9940c397de23915c4fee7dba8673ec --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Lazy.h @@ -0,0 +1,125 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10 { + +/** + * Thread-safe lazy value with opportunistic concurrency: on concurrent first + * access, the factory may be called by multiple threads, but only one result is + * stored and its reference returned to all the callers. + * + * Value is heap-allocated; this optimizes for the case in which the value is + * never actually computed. + */ +template +class OptimisticLazy { + public: + OptimisticLazy() = default; + OptimisticLazy(const OptimisticLazy& other) { + if (T* value = other.value_.load(std::memory_order_acquire)) { + value_ = new T(*value); + } + } + OptimisticLazy(OptimisticLazy&& other) noexcept + : value_(other.value_.exchange(nullptr, std::memory_order_acq_rel)) {} + ~OptimisticLazy() { + reset(); + } + + template + T& ensure(const Factory& factory) { + if (T* value = value_.load(std::memory_order_acquire)) { + return *value; + } + T* value = new T(factory()); + T* old = nullptr; + if (!value_.compare_exchange_strong( + old, value, std::memory_order_release, std::memory_order_acquire)) { + delete value; + value = old; + } + return *value; + } + + // The following methods are not thread-safe: they should not be called + // concurrently with any other method. + + OptimisticLazy& operator=(const OptimisticLazy& other) { + *this = OptimisticLazy{other}; + return *this; + } + + OptimisticLazy& operator=(OptimisticLazy&& other) noexcept { + if (this != &other) { + reset(); + value_.store( + other.value_.exchange(nullptr, std::memory_order_acquire), + std::memory_order_release); + } + return *this; + } + + void reset() { + if (T* old = value_.load(std::memory_order_relaxed)) { + value_.store(nullptr, std::memory_order_relaxed); + delete old; + } + } + + private: + std::atomic value_{nullptr}; +}; + +/** + * Interface for a value that is computed on first access. + */ +template +class LazyValue { + public: + virtual ~LazyValue() = default; + + virtual const T& get() const = 0; +}; + +/** + * Convenience thread-safe LazyValue implementation with opportunistic + * concurrency. + */ +template +class OptimisticLazyValue : public LazyValue { + public: + const T& get() const override { + return value_.ensure([this] { return compute(); }); + } + + private: + virtual T compute() const = 0; + + mutable OptimisticLazy value_; +}; + +/** + * Convenience immutable (thus thread-safe) LazyValue implementation for cases + * in which the value is not actually lazy. + */ +template +class PrecomputedLazyValue : public LazyValue { + public: + PrecomputedLazyValue(T value) : value_(std::move(value)) {} + + const T& get() const override { + return value_; + } + + private: + T value_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/LeftRight.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/LeftRight.h new file mode 100644 index 0000000000000000000000000000000000000000..0435fffb73fdd7a8e6ef0cedc7d6feac6b818651 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/LeftRight.h @@ -0,0 +1,234 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace c10 { + +namespace detail { + +struct IncrementRAII final { + public: + explicit IncrementRAII(std::atomic* counter) : _counter(counter) { + _counter->fetch_add(1); + } + + ~IncrementRAII() { + _counter->fetch_sub(1); + } + IncrementRAII(IncrementRAII&&) = delete; + IncrementRAII& operator=(IncrementRAII&&) = delete; + + private: + std::atomic* _counter; + + C10_DISABLE_COPY_AND_ASSIGN(IncrementRAII); +}; + +} // namespace detail + +// LeftRight wait-free readers synchronization primitive +// https://hal.archives-ouvertes.fr/hal-01207881/document +// +// LeftRight is quite easy to use (it can make an arbitrary +// data structure permit wait-free reads), but it has some +// particular performance characteristics you should be aware +// of if you're deciding to use it: +// +// - Reads still incur an atomic write (this is how LeftRight +// keeps track of how long it needs to keep around the old +// data structure) +// +// - Writes get executed twice, to keep both the left and right +// versions up to date. So if your write is expensive or +// nondeterministic, this is also an inappropriate structure +// +// LeftRight is used fairly rarely in PyTorch's codebase. If you +// are still not sure if you need it or not, consult your local +// C++ expert. +// +template +class LeftRight final { + public: + template + explicit LeftRight(const Args&... args) + : _counters{{{0}, {0}}}, + _foregroundCounterIndex(0), + _foregroundDataIndex(0), + _data{{T{args...}, T{args...}}} {} + + // Copying and moving would not be threadsafe. + // Needs more thought and careful design to make that work. + LeftRight(const LeftRight&) = delete; + LeftRight(LeftRight&&) noexcept = delete; + LeftRight& operator=(const LeftRight&) = delete; + LeftRight& operator=(LeftRight&&) noexcept = delete; + + ~LeftRight() { + // wait until any potentially running writers are finished + { + std::unique_lock lock(_writeMutex); + } + + // wait until any potentially running readers are finished + while (_counters[0].load() != 0 || _counters[1].load() != 0) { + std::this_thread::yield(); + } + } + + template + auto read(F&& readFunc) const { + detail::IncrementRAII _increment_counter( + &_counters[_foregroundCounterIndex.load()]); + + return std::forward(readFunc)(_data[_foregroundDataIndex.load()]); + } + + // Throwing an exception in writeFunc is ok but causes the state to be either + // the old or the new state, depending on if the first or the second call to + // writeFunc threw. + template + auto write(F&& writeFunc) { + std::unique_lock lock(_writeMutex); + + return _write(std::forward(writeFunc)); + } + + private: + template + auto _write(const F& writeFunc) { + /* + * Assume, A is in background and B in foreground. In simplified terms, we + * want to do the following: + * 1. Write to A (old background) + * 2. Switch A/B + * 3. Write to B (new background) + * + * More detailed algorithm (explanations on why this is important are below + * in code): + * 1. Write to A + * 2. Switch A/B data pointers + * 3. Wait until A counter is zero + * 4. Switch A/B counters + * 5. Wait until B counter is zero + * 6. Write to B + */ + + auto localDataIndex = _foregroundDataIndex.load(); + + // 1. Write to A + _callWriteFuncOnBackgroundInstance(writeFunc, localDataIndex); + + // 2. Switch A/B data pointers + localDataIndex = localDataIndex ^ 1; + _foregroundDataIndex = localDataIndex; + + /* + * 3. Wait until A counter is zero + * + * In the previous write run, A was foreground and B was background. + * There was a time after switching _foregroundDataIndex (B to foreground) + * and before switching _foregroundCounterIndex, in which new readers could + * have read B but incremented A's counter. + * + * In this current run, we just switched _foregroundDataIndex (A back to + * foreground), but before writing to the new background B, we have to make + * sure A's counter was zero briefly, so all these old readers are gone. + */ + auto localCounterIndex = _foregroundCounterIndex.load(); + _waitForBackgroundCounterToBeZero(localCounterIndex); + + /* + * 4. Switch A/B counters + * + * Now that we know all readers on B are really gone, we can switch the + * counters and have new readers increment A's counter again, which is the + * correct counter since they're reading A. + */ + localCounterIndex = localCounterIndex ^ 1; + _foregroundCounterIndex = localCounterIndex; + + /* + * 5. Wait until B counter is zero + * + * This waits for all the readers on B that came in while both data and + * counter for B was in foreground, i.e. normal readers that happened + * outside of that brief gap between switching data and counter. + */ + _waitForBackgroundCounterToBeZero(localCounterIndex); + + // 6. Write to B + return _callWriteFuncOnBackgroundInstance(writeFunc, localDataIndex); + } + + template + auto _callWriteFuncOnBackgroundInstance( + const F& writeFunc, + uint8_t localDataIndex) { + try { + return writeFunc(_data[localDataIndex ^ 1]); + } catch (...) { + // recover invariant by copying from the foreground instance + _data[localDataIndex ^ 1] = _data[localDataIndex]; + // rethrow + throw; + } + } + + void _waitForBackgroundCounterToBeZero(uint8_t counterIndex) { + while (_counters[counterIndex ^ 1].load() != 0) { + std::this_thread::yield(); + } + } + + mutable std::array, 2> _counters; + std::atomic _foregroundCounterIndex; + std::atomic _foregroundDataIndex; + std::array _data; + std::mutex _writeMutex; +}; + +// RWSafeLeftRightWrapper is API compatible with LeftRight and uses a +// read-write lock to protect T (data). +template +class RWSafeLeftRightWrapper final { + public: + template + explicit RWSafeLeftRightWrapper(const Args&... args) : data_{args...} {} + + // RWSafeLeftRightWrapper is not copyable or moveable since LeftRight + // is not copyable or moveable. + RWSafeLeftRightWrapper(const RWSafeLeftRightWrapper&) = delete; + RWSafeLeftRightWrapper(RWSafeLeftRightWrapper&&) noexcept = delete; + RWSafeLeftRightWrapper& operator=(const RWSafeLeftRightWrapper&) = delete; + RWSafeLeftRightWrapper& operator=(RWSafeLeftRightWrapper&&) noexcept = delete; + ~RWSafeLeftRightWrapper() = default; + + template + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) + auto read(F&& readFunc) const { + return data_.withLock( + [&readFunc](T const& data) { return std::forward(readFunc)(data); }); + } + + template + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) + auto write(F&& writeFunc) { + return data_.withLock( + [&writeFunc](T& data) { return std::forward(writeFunc)(data); }); + } + + private: + c10::Synchronized data_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Load.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Load.h new file mode 100644 index 0000000000000000000000000000000000000000..38aef4c1ea38d790799e49f3f594ff8c3c7a0d78 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Load.h @@ -0,0 +1,43 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include + +namespace c10 { +namespace detail { + +template +struct LoadImpl { + C10_HOST_DEVICE static T apply(const void* src) { + return *reinterpret_cast(src); + } +}; + +template <> +struct LoadImpl { + C10_HOST_DEVICE static bool apply(const void* src) { + static_assert(sizeof(bool) == sizeof(char)); + // NOTE: [Loading boolean values] + // Protect against invalid boolean values by loading as a byte + // first, then converting to bool (see gh-54789). + return *reinterpret_cast(src); + } +}; + +} // namespace detail + +template +C10_HOST_DEVICE constexpr T load(const void* src) { + return c10::detail::LoadImpl::apply(src); +} + +template +C10_HOST_DEVICE constexpr scalar_t load(const scalar_t* src) { + return c10::detail::LoadImpl::apply(src); +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Logging.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Logging.h new file mode 100644 index 0000000000000000000000000000000000000000..49420110eb333a07e7b15cc6f21a8c77af52e84d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Logging.h @@ -0,0 +1,378 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_LOGGING_H_ +#define C10_UTIL_LOGGING_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +// CAFFE2_LOG_THRESHOLD is a compile time flag that would allow us to turn off +// logging at compile time so no logging message below that level is produced +// at all. The value should be between INT_MIN and CAFFE_FATAL. +#ifndef CAFFE2_LOG_THRESHOLD +// If we have not defined the compile time log threshold, we keep all the +// log cases. +#define CAFFE2_LOG_THRESHOLD INT_MIN +#endif // CAFFE2_LOG_THRESHOLD + +// Below are different implementations for glog and non-glog cases. +#ifdef C10_USE_GLOG +#include +#else // !C10_USE_GLOG +#include +#endif // C10_USE_GLOG + +C10_DECLARE_int(caffe2_log_level); +C10_DECLARE_bool(caffe2_use_fatal_for_enforce); + +// Some versions of GLOG support less-spammy version of LOG_EVERY_MS. If it's +// not available - just short-circuit to the always working one one. +// We define the C10_ name to avoid confusing other files +#ifdef LOG_EVERY_MS +#define C10_LOG_EVERY_MS(severity, ms) LOG_EVERY_MS(severity, ms) +#else +#define C10_LOG_EVERY_MS(severity, ms) LOG(severity) +#endif + +// Same for LOG_FIRST_N +#ifdef LOG_FIRST_N +#define C10_LOG_FIRST_N(severity, n) LOG_FIRST_N(severity, n) +#else +#define C10_LOG_FIRST_N(severity, n) LOG(severity) +#endif + +// Same for LOG_EVERY_N +#ifdef LOG_EVERY_N +#define C10_LOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n) +#else +#define C10_LOG_EVERY_N(severity, n) LOG(severity) +#endif + +namespace c10 { + +#if !defined(C10_NODEPRECATED) +using std::string; +#endif + +// Functions that we use for initialization. +C10_API bool InitCaffeLogging(int* argc, char** argv); +C10_API void UpdateLoggingLevelsFromFlags(); + +[[noreturn]] C10_API void ThrowEnforceNotMet( + const char* file, + const int line, + const char* condition, + const std::string& msg, + const void* caller = nullptr); + +[[noreturn]] C10_API void ThrowEnforceNotMet( + const char* file, + const int line, + const char* condition, + const char* msg, + const void* caller = nullptr); + +[[noreturn]] inline void ThrowEnforceNotMet( + const char* file, + const int line, + const char* condition, + detail::CompileTimeEmptyString /*msg*/, + const void* caller = nullptr) { + ThrowEnforceNotMet(file, line, condition, "", caller); +} + +[[noreturn]] C10_API void ThrowEnforceFiniteNotMet( + const char* file, + const int line, + const char* condition, + const std::string& msg, + const void* caller = nullptr); + +[[noreturn]] C10_API void ThrowEnforceFiniteNotMet( + const char* file, + const int line, + const char* condition, + const char* msg, + const void* caller = nullptr); + +[[noreturn]] inline void ThrowEnforceFiniteNotMet( + const char* file, + const int line, + const char* condition, + detail::CompileTimeEmptyString /*msg*/, + const void* caller = nullptr) { + ThrowEnforceFiniteNotMet(file, line, condition, "", caller); +} + +constexpr bool IsUsingGoogleLogging() { +#ifdef C10_USE_GLOG + return true; +#else + return false; +#endif +} + +/** + * A utility to allow one to show log info to stderr after the program starts. + * + * This is similar to calling GLOG's --logtostderr, or setting caffe2_log_level + * to smaller than INFO. You are recommended to only use this in a few sparse + * cases, such as when you want to write a tutorial or something. Normally, use + * the commandline flags to set the log level. + */ +C10_API void ShowLogInfoToStderr(); + +C10_API void SetStackTraceFetcher(std::function<::c10::Backtrace()> fetcher); + +/** + * Convenience function for non-lazy stack trace fetchers. The Backtrace + * overload should be preferred when stringifying the backtrace is expensive. + */ +C10_API void SetStackTraceFetcher(std::function fetcher); + +using EnforceNotMet = ::c10::Error; + +#define CAFFE_ENFORCE(condition, ...) \ + do { \ + if (C10_UNLIKELY(!(condition))) { \ + ::c10::ThrowEnforceNotMet( \ + __FILE__, __LINE__, #condition, ::c10::str(__VA_ARGS__)); \ + } \ + } while (false) + +#define CAFFE_ENFORCE_FINITE(condition, ...) \ + do { \ + if (C10_UNLIKELY(!(condition))) { \ + ::c10::ThrowEnforceFiniteNotMet( \ + __FILE__, __LINE__, #condition, ::c10::str(__VA_ARGS__)); \ + } \ + } while (false) + +#define CAFFE_ENFORCE_WITH_CALLER(condition, ...) \ + do { \ + if (C10_UNLIKELY(!(condition))) { \ + ::c10::ThrowEnforceNotMet( \ + __FILE__, __LINE__, #condition, ::c10::str(__VA_ARGS__), this); \ + } \ + } while (false) + +#define CAFFE_THROW(...) \ + ::c10::ThrowEnforceNotMet(__FILE__, __LINE__, "", ::c10::str(__VA_ARGS__)) + +/** + * Rich logging messages + * + * CAFFE_ENFORCE_THAT can be used with one of the "checker functions" that + * capture input argument values and add it to the exception message. E.g. + * `CAFFE_ENFORCE_THAT(Equals(foo(x), bar(y)), "Optional additional message")` + * would evaluate both foo and bar only once and if the results are not equal - + * include them in the exception message. + * + * Some of the basic checker functions like Equals or Greater are already + * defined below. Other header might define customized checkers by adding + * functions to caffe2::enforce_detail namespace. For example: + * + * namespace caffe2 { namespace enforce_detail { + * inline EnforceFailMessage IsVector(const vector& shape) { + * if (shape.size() == 1) { return EnforceOK(); } + * return c10::str("Shape ", shape, " is not a vector"); + * } + * }} + * + * With further usages like `CAFFE_ENFORCE_THAT(IsVector(Input(0).dims()))` + * + * Convenient wrappers for binary operations like CAFFE_ENFORCE_EQ are provided + * too. Please use them instead of TORCH_CHECK_EQ and friends for failures in + * user-provided input. + */ + +namespace enforce_detail { + +template +std::string enforceFailMsgImpl(const T1& x, const T2& y) { + return c10::str(x, " vs ", y); +} + +template +std::string enforceFailMsgImpl(const T1& x, const T2& y, const Args&... args) { + return c10::str(x, " vs ", y, ". ", args...); +} + +template +void enforceThatImpl( + Pred p, + const T1& lhs, + const T2& rhs, + const char* file, + int line, + const char* expr, + const void* caller, + GetFailMsgFunc getFailMsg) { + if (C10_UNLIKELY(!(p(lhs, rhs)))) { + ::c10::ThrowEnforceNotMet(file, line, expr, getFailMsg(lhs, rhs), caller); + } +} + +#define CAFFE_ENFORCE_THAT_IMPL(op, lhs, rhs, expr, ...) \ + ::c10::enforce_detail::enforceThatImpl( \ + op, \ + (lhs), \ + (rhs), \ + __FILE__, \ + __LINE__, \ + expr, \ + nullptr, \ + [&](const auto& arg1, const auto& arg2) { \ + return ::c10::enforce_detail::enforceFailMsgImpl( \ + arg1, arg2, ##__VA_ARGS__); \ + }) + +#define CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER(op, lhs, rhs, expr, ...) \ + ::c10::enforce_detail::enforceThatImpl( \ + op, \ + (lhs), \ + (rhs), \ + __FILE__, \ + __LINE__, \ + expr, \ + this, \ + [&](const auto& arg1, const auto& arg2) { \ + return ::c10::enforce_detail::enforceFailMsgImpl( \ + arg1, arg2, ##__VA_ARGS__); \ + }) + +} // namespace enforce_detail + +#define CAFFE_ENFORCE_THAT(cmp, op, lhs, rhs, ...) \ + CAFFE_ENFORCE_THAT_IMPL(cmp, lhs, rhs, #lhs " " #op " " #rhs, ##__VA_ARGS__) + +#define CAFFE_ENFORCE_BINARY_OP(cmp, op, x, y, ...) \ + CAFFE_ENFORCE_THAT_IMPL(cmp, x, y, #x " " #op " " #y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_EQ(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP(std::equal_to(), ==, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_NE(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP(std::not_equal_to(), !=, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_LE(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP(std::less_equal(), <=, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_LT(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP(std::less(), <, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_GE(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP(std::greater_equal(), >=, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_GT(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP(std::greater(), >, x, y, ##__VA_ARGS__) + +#define CAFFE_ENFORCE_BINARY_OP_WITH_CALLER(cmp, op, x, y, ...) \ + CAFFE_ENFORCE_THAT_IMPL_WITH_CALLER( \ + cmp, x, y, #x " " #op " " #y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_EQ_WITH_CALLER(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP_WITH_CALLER( \ + std::equal_to(), ==, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_NE_WITH_CALLER(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP_WITH_CALLER( \ + std::not_equal_to(), !=, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_LE_WITH_CALLER(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP_WITH_CALLER( \ + std::less_equal(), <=, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_LT_WITH_CALLER(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP_WITH_CALLER(std::less(), <, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_GE_WITH_CALLER(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP_WITH_CALLER( \ + std::greater_equal(), >=, x, y, ##__VA_ARGS__) +#define CAFFE_ENFORCE_GT_WITH_CALLER(x, y, ...) \ + CAFFE_ENFORCE_BINARY_OP_WITH_CALLER( \ + std::greater(), >, x, y, ##__VA_ARGS__) + +struct IValue; +class C10_API EventSampledHandler { + public: + virtual void log( + std::string_view model_id, + const std::vector& args) = 0; + virtual ~EventSampledHandler() = default; +}; + +#define C10_LOG_EVENT_SAMPLED(event, ...) \ + static const std::unique_ptr<::c10::EventSampledHandler>& \ + _##event##EventSampledHandler = ::c10::GetEventSampledHandler(#event); \ + if (_##event##EventSampledHandler) { \ + _##event##EventSampledHandler->log(__VA_ARGS__); \ + } + +// Must be called in the main thread before any other threads are spawned. +C10_API void InitEventSampledHandlers( + std::vector>> /*handlers*/); +C10_API const std::unique_ptr& GetEventSampledHandler( + std::string_view /*event*/); + +/** + * Very lightweight logging for the first time API usage. It's beneficial for + * tracking of individual functionality usage in larger applications. + * + * In order to ensure light-weightedness of logging, we utilize static variable + * trick - LogAPIUsage will be invoked only once and further invocations will + * just do an atomic check. + * + * Example: + * // Logs caller info with an arbitrary text event, if there is a usage. + * C10_LOG_API_USAGE_ONCE("my_api"); + */ +#define C10_LOG_API_USAGE_ONCE(...) \ + [[maybe_unused]] static bool C10_ANONYMOUS_VARIABLE(logFlag) = \ + ::c10::detail::LogAPIUsageFakeReturn(__VA_ARGS__); + +// API usage logging capabilities +C10_API void SetAPIUsageLogger(std::function logger); +C10_API void LogAPIUsage(const std::string& context); + +C10_API void SetAPIUsageMetadataLogger( + std::function& metadata_map)> logger); +C10_API void LogAPIUsageMetadata( + const std::string& context, + const std::map& metadata_map); + +// PyTorch ddp usage logging capabilities +// DDPLoggingData holds data that can be logged in applications +// for analysis and debugging. Data structure is defined in +// c10 directory so that it can be easily imported by both c10 +// and torch files. +struct DDPLoggingData { + // logging fields that are string types. + std::map strs_map; + // logging fields that are int64_t types. + std::map ints_map; +}; + +C10_API void SetPyTorchDDPUsageLogger( + std::function logger); +C10_API void LogPyTorchDDPUsage(const DDPLoggingData& ddpData); + +namespace detail { +// Return value is needed to do the static variable initialization trick +C10_API bool LogAPIUsageFakeReturn(const std::string& context); +} // namespace detail + +// Initializes the c10 logger. +C10_API void initLogging(); + +// Sets the rank, which will be included in log messages +C10_API void SetGlobalRank(int64_t rank); + +} // namespace c10 + +#endif // C10_UTIL_LOGGING_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/MathConstants.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/MathConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..f3e86ce2e1da5bc4d1d40ad22e4f31280ac16c2e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/MathConstants.h @@ -0,0 +1,147 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +C10_CLANG_DIAGNOSTIC_PUSH() +#if C10_CLANG_HAS_WARNING("-Wimplicit-float-conversion") +C10_CLANG_DIAGNOSTIC_IGNORE("-Wimplicit-float-conversion") +#endif + +namespace c10 { +// TODO: Replace me with inline constexpr variable when C++17 becomes available +namespace detail { +template +C10_HOST_DEVICE inline constexpr T e() { + return static_cast(2.718281828459045235360287471352662); +} + +template +C10_HOST_DEVICE inline constexpr T euler() { + return static_cast(0.577215664901532860606512090082402); +} + +template +C10_HOST_DEVICE inline constexpr T frac_1_pi() { + return static_cast(0.318309886183790671537767526745028); +} + +template +C10_HOST_DEVICE inline constexpr T frac_1_sqrt_pi() { + return static_cast(0.564189583547756286948079451560772); +} + +template +C10_HOST_DEVICE inline constexpr T frac_sqrt_2() { + return static_cast(0.707106781186547524400844362104849); +} + +template +C10_HOST_DEVICE inline constexpr T frac_sqrt_3() { + return static_cast(0.577350269189625764509148780501957); +} + +template +C10_HOST_DEVICE inline constexpr T golden_ratio() { + return static_cast(1.618033988749894848204586834365638); +} + +template +C10_HOST_DEVICE inline constexpr T ln_10() { + return static_cast(2.302585092994045684017991454684364); +} + +template +C10_HOST_DEVICE inline constexpr T ln_2() { + return static_cast(0.693147180559945309417232121458176); +} + +template +C10_HOST_DEVICE inline constexpr T log_10_e() { + return static_cast(0.434294481903251827651128918916605); +} + +template +C10_HOST_DEVICE inline constexpr T log_2_e() { + return static_cast(1.442695040888963407359924681001892); +} + +template +C10_HOST_DEVICE inline constexpr T pi() { + return static_cast(3.141592653589793238462643383279502); +} + +template +C10_HOST_DEVICE inline constexpr T sqrt_2() { + return static_cast(1.414213562373095048801688724209698); +} + +template +C10_HOST_DEVICE inline constexpr T sqrt_3() { + return static_cast(1.732050807568877293527446341505872); +} + +template <> +C10_HOST_DEVICE inline constexpr BFloat16 pi() { + // According to + // https://en.wikipedia.org/wiki/Bfloat16_floating-point_format#Special_values + // pi is encoded as 4049 + return BFloat16(0x4049, BFloat16::from_bits()); +} + +template <> +C10_HOST_DEVICE inline constexpr Half pi() { + return Half(0x4248, Half::from_bits()); +} +} // namespace detail + +template +constexpr T e = c10::detail::e(); + +template +constexpr T euler = c10::detail::euler(); + +template +constexpr T frac_1_pi = c10::detail::frac_1_pi(); + +template +constexpr T frac_1_sqrt_pi = c10::detail::frac_1_sqrt_pi(); + +template +constexpr T frac_sqrt_2 = c10::detail::frac_sqrt_2(); + +template +constexpr T frac_sqrt_3 = c10::detail::frac_sqrt_3(); + +template +constexpr T golden_ratio = c10::detail::golden_ratio(); + +template +constexpr T ln_10 = c10::detail::ln_10(); + +template +constexpr T ln_2 = c10::detail::ln_2(); + +template +constexpr T log_10_e = c10::detail::log_10_e(); + +template +constexpr T log_2_e = c10::detail::log_2_e(); + +template +constexpr T pi = c10::detail::pi(); + +template +constexpr T sqrt_2 = c10::detail::sqrt_2(); + +template +constexpr T sqrt_3 = c10::detail::sqrt_3(); +} // namespace c10 + +C10_CLANG_DIAGNOSTIC_POP() + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/MaybeOwned.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/MaybeOwned.h new file mode 100644 index 0000000000000000000000000000000000000000..61e6ed82f27a4a2b91300f0987612f5a03c3bea1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/MaybeOwned.h @@ -0,0 +1,242 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include +#include +#include + +namespace c10 { + +/// MaybeOwnedTraits describes how to borrow from T. Here is how we +/// can implement borrowing from an arbitrary type T using a raw +/// pointer to const: +template +struct MaybeOwnedTraitsGenericImpl { + using owned_type = T; + using borrow_type = const T*; + + static borrow_type createBorrow(const owned_type& from) { + return &from; + } + + static void assignBorrow(borrow_type& lhs, borrow_type rhs) { + lhs = rhs; + } + + static void destroyBorrow(borrow_type& /*toDestroy*/) {} + + static const owned_type& referenceFromBorrow(const borrow_type& borrow) { + return *borrow; + } + + static const owned_type* pointerFromBorrow(const borrow_type& borrow) { + return borrow; + } + + static bool debugBorrowIsValid(const borrow_type& borrow) { + return borrow != nullptr; + } +}; + +/// It is possible to eliminate the extra layer of indirection for +/// borrows for some types that we control. For examples, see +/// intrusive_ptr.h and TensorBody.h. + +template +struct MaybeOwnedTraits; + +// Explicitly enable MaybeOwned>, rather than allowing +// MaybeOwned to be used for any type right away. +template +struct MaybeOwnedTraits> + : public MaybeOwnedTraitsGenericImpl> {}; + +/// A smart pointer around either a borrowed or owned T. When +/// constructed with borrowed(), the caller MUST ensure that the +/// borrowed-from argument outlives this MaybeOwned. Compare to +/// Rust's std::borrow::Cow +/// (https://doc.rust-lang.org/std/borrow/enum.Cow.html), but note +/// that it is probably not suitable for general use because C++ has +/// no borrow checking. Included here to support +/// Tensor::expect_contiguous. +template +class MaybeOwned final { + using borrow_type = typename MaybeOwnedTraits::borrow_type; + using owned_type = typename MaybeOwnedTraits::owned_type; + + bool isBorrowed_; + union { + borrow_type borrow_; + owned_type own_; + }; + + /// Don't use this; use borrowed() instead. + explicit MaybeOwned(const owned_type& t) + : isBorrowed_(true), borrow_(MaybeOwnedTraits::createBorrow(t)) {} + + /// Don't use this; use owned() instead. + explicit MaybeOwned(T&& t) noexcept(std::is_nothrow_move_constructible_v) + : isBorrowed_(false), own_(std::move(t)) {} + + /// Don't use this; use owned() instead. + template + explicit MaybeOwned(std::in_place_t /*unused*/, Args&&... args) + : isBorrowed_(false), own_(std::forward(args)...) {} + + public: + explicit MaybeOwned() : isBorrowed_(true), borrow_() {} + + // Copying a borrow yields another borrow of the original, as with a + // T*. Copying an owned T yields another owned T for safety: no + // chains of borrowing by default! (Note you could get that behavior + // with MaybeOwned::borrowed(*rhs) if you wanted it.) + MaybeOwned(const MaybeOwned& rhs) : isBorrowed_(rhs.isBorrowed_) { + if (C10_LIKELY(rhs.isBorrowed_)) { + MaybeOwnedTraits::assignBorrow(borrow_, rhs.borrow_); + } else { + new (&own_) T(rhs.own_); + } + } + + MaybeOwned& operator=(const MaybeOwned& rhs) { + if (this == &rhs) { + return *this; + } + if (C10_UNLIKELY(!isBorrowed_)) { + if (rhs.isBorrowed_) { + own_.~T(); + MaybeOwnedTraits::assignBorrow(borrow_, rhs.borrow_); + isBorrowed_ = true; + } else { + own_ = rhs.own_; + } + } else { + if (C10_LIKELY(rhs.isBorrowed_)) { + MaybeOwnedTraits::assignBorrow(borrow_, rhs.borrow_); + } else { + MaybeOwnedTraits::destroyBorrow(borrow_); + new (&own_) T(rhs.own_); + isBorrowed_ = false; + } + } + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(isBorrowed_ == rhs.isBorrowed_); + return *this; + } + + MaybeOwned(MaybeOwned&& rhs) noexcept( + // NOLINTNEXTLINE(*-noexcept-move-*) + std::is_nothrow_move_constructible_v && + std::is_nothrow_move_assignable_v) + : isBorrowed_(rhs.isBorrowed_) { + if (C10_LIKELY(rhs.isBorrowed_)) { + MaybeOwnedTraits::assignBorrow(borrow_, rhs.borrow_); + } else { + new (&own_) T(std::move(rhs.own_)); + } + } + + MaybeOwned& operator=(MaybeOwned&& rhs) noexcept( + std::is_nothrow_move_assignable_v && + std::is_nothrow_move_assignable_v && + std::is_nothrow_move_constructible_v && + // NOLINTNEXTLINE(*-noexcept-move-*) + std::is_nothrow_destructible_v && + std::is_nothrow_destructible_v) { + if (this == &rhs) { + return *this; + } + if (C10_UNLIKELY(!isBorrowed_)) { + if (rhs.isBorrowed_) { + own_.~T(); + MaybeOwnedTraits::assignBorrow(borrow_, rhs.borrow_); + isBorrowed_ = true; + } else { + own_ = std::move(rhs.own_); + } + } else { + if (C10_LIKELY(rhs.isBorrowed_)) { + MaybeOwnedTraits::assignBorrow(borrow_, rhs.borrow_); + } else { + MaybeOwnedTraits::destroyBorrow(borrow_); + new (&own_) T(std::move(rhs.own_)); + isBorrowed_ = false; + } + } + return *this; + } + + static MaybeOwned borrowed(const T& t) { + return MaybeOwned(t); + } + + static MaybeOwned owned(T&& t) noexcept( + std::is_nothrow_move_constructible_v) { + return MaybeOwned(std::move(t)); + } + + template + static MaybeOwned owned(std::in_place_t /*unused*/, Args&&... args) { + return MaybeOwned(std::in_place, std::forward(args)...); + } + + ~MaybeOwned() noexcept( + // NOLINTNEXTLINE(*-noexcept-destructor) + std::is_nothrow_destructible_v && + std::is_nothrow_destructible_v) { + if (C10_UNLIKELY(!isBorrowed_)) { + own_.~T(); + } else { + MaybeOwnedTraits::destroyBorrow(borrow_); + } + } + + // This is an implementation detail! You should know what you're doing + // if you are testing this. If you just want to guarantee ownership move + // this into a T + bool unsafeIsBorrowed() const { + return isBorrowed_; + } + + const T& operator*() const& { + if (isBorrowed_) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + MaybeOwnedTraits::debugBorrowIsValid(borrow_)); + } + return C10_LIKELY(isBorrowed_) + ? MaybeOwnedTraits::referenceFromBorrow(borrow_) + : own_; + } + + const T* operator->() const { + if (isBorrowed_) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + MaybeOwnedTraits::debugBorrowIsValid(borrow_)); + } + return C10_LIKELY(isBorrowed_) + ? MaybeOwnedTraits::pointerFromBorrow(borrow_) + : &own_; + } + + // If borrowed, copy the underlying T. If owned, move from + // it. borrowed/owned state remains the same, and either we + // reference the same borrow as before or we are an owned moved-from + // T. + T operator*() && { + if (isBorrowed_) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + MaybeOwnedTraits::debugBorrowIsValid(borrow_)); + return MaybeOwnedTraits::referenceFromBorrow(borrow_); + } else { + return std::move(own_); + } + } +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Metaprogramming.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Metaprogramming.h new file mode 100644 index 0000000000000000000000000000000000000000..55c3fb2ba6db0dbc8bf8d00e616aefc3acab7c85 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Metaprogramming.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/NetworkFlow.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/NetworkFlow.h new file mode 100644 index 0000000000000000000000000000000000000000..e029ae65773be41aa7d05402fc3e1c3d50dbb8a8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/NetworkFlow.h @@ -0,0 +1,59 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include +#include + +/** + * This file provides a network flow implementation. + * https://en.wikipedia.org/wiki/Flow_network + * + * It aims to mirror some of the behavior of networkx, which is/was used by + * functorch partitioners for splitting the graph into a forward and backward + * graph. + */ + +namespace c10 { + +enum class C10_API_ENUM MinCutStatus { + SUCCESS = 0, + UNBOUNDED = 1, + OVERFLOW_INF = 2, + INVALID = 3, +}; + +struct MinCutResult { + MinCutStatus status; + int64_t max_flow; + std::vector reachable; + std::vector unreachable; +}; + +// Modeled after networkx implementation +class C10_API NetworkFlowGraph { + public: + // selected such that INF + INF is < INT64_MAX + constexpr static int64_t INF = (1LL << 62) - 1; + + struct Edge { + std::string source, dest; + int64_t capacity; + }; + + MinCutStatus add_edge( + const std::string& source, + const std::string& dest, + int64_t capacity = 1); + + MinCutResult minimum_cut(const std::string& s, const std::string& t) const; + + std::vector edges; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Optional.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Optional.h new file mode 100644 index 0000000000000000000000000000000000000000..55c4697368c60f86b69db1b1bc65cf0cb2e99404 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Optional.h @@ -0,0 +1,65 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_OPTIONAL_H_ +#define C10_UTIL_OPTIONAL_H_ + +#include +#include + +// Macros.h is not needed, but it does namespace shenanigans that lots +// of downstream code seems to rely on. Feel free to remove it and fix +// up builds. + +namespace c10 { + +#if !defined(FBCODE_CAFFE2) && !defined(C10_NODEPRECATED) +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::bad_optional_access; +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::make_optional; +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::nullopt; +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::nullopt_t; +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::optional; +#endif + +#if !defined(FBCODE_CAFFE2) && !defined(C10_NODEPRECATED) + +namespace detail_ { +// the call to convert(b) has return type A and converts b to type A iff b +// decltype(b) is implicitly convertible to A +template +constexpr U convert(U v) { + return v; +} +} // namespace detail_ +template +[[deprecated( + "Please use std::optional::value_or instead of c10::value_or_else")]] constexpr T +value_or_else(const std::optional& v, F&& func) { + static_assert( + std::is_convertible_v, T>, + "func parameters must be a callable that returns a type convertible to the value stored in the optional"); + return v.has_value() ? *v : detail_::convert(std::forward(func)()); +} + +template +[[deprecated( + "Please use std::optional::value_or instead of c10::value_or_else")]] constexpr T +value_or_else(std::optional&& v, F&& func) { + static_assert( + std::is_convertible_v, T>, + "func parameters must be a callable that returns a type convertible to the value stored in the optional"); + return v.has_value() ? constexpr_move(std::move(v).contained_val()) + : detail_::convert(std::forward(func)()); +} + +#endif + +} // namespace c10 +#endif // C10_UTIL_OPTIONAL_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/OptionalArrayRef.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/OptionalArrayRef.h new file mode 100644 index 0000000000000000000000000000000000000000..cd15a5f19d1db7673c8f3485a136d1730e34f433 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/OptionalArrayRef.h @@ -0,0 +1,242 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// This file defines OptionalArrayRef, a class that has almost the same +// exact functionality as std::optional>, except that its +// converting constructor fixes a dangling pointer issue. +// +// The implicit converting constructor of both std::optional> and +// std::optional> can cause the underlying ArrayRef to store +// a dangling pointer. OptionalArrayRef prevents this by wrapping +// a std::optional> and fixing the constructor implementation. +// +// See https://github.com/pytorch/pytorch/issues/63645 for more on this. + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace c10 { + +template +class OptionalArrayRef final { + public: + // Constructors + + constexpr OptionalArrayRef() noexcept = default; + + constexpr OptionalArrayRef(std::nullopt_t /*unused*/) noexcept {} + + OptionalArrayRef(const OptionalArrayRef& other) = default; + + OptionalArrayRef(OptionalArrayRef&& other) noexcept = default; + + constexpr OptionalArrayRef(const std::optional>& other) noexcept + : wrapped_opt_array_ref(other) {} + + constexpr OptionalArrayRef(std::optional>&& other) noexcept + : wrapped_opt_array_ref(std::move(other)) {} + + constexpr OptionalArrayRef(const T& value) noexcept + : wrapped_opt_array_ref(value) {} + + template < + typename U = ArrayRef, + std::enable_if_t< + !std::is_same_v, OptionalArrayRef> && + !std::is_same_v, std::in_place_t> && + std::is_constructible_v, U&&> && + std::is_convertible_v> && + !std::is_convertible_v, + bool> = false> + constexpr OptionalArrayRef(U&& value) noexcept( + std::is_nothrow_constructible_v, U&&>) + : wrapped_opt_array_ref(std::forward(value)) {} + + template < + typename U = ArrayRef, + std::enable_if_t< + !std::is_same_v, OptionalArrayRef> && + !std::is_same_v, std::in_place_t> && + std::is_constructible_v, U&&> && + !std::is_convertible_v>, + bool> = false> + constexpr explicit OptionalArrayRef(U&& value) noexcept( + std::is_nothrow_constructible_v, U&&>) + : wrapped_opt_array_ref(std::forward(value)) {} + + template + constexpr explicit OptionalArrayRef( + std::in_place_t ip, + Args&&... args) noexcept + : wrapped_opt_array_ref(ip, std::forward(args)...) {} + + template + constexpr explicit OptionalArrayRef( + std::in_place_t ip, + std::initializer_list il, + Args&&... args) + : wrapped_opt_array_ref(ip, il, std::forward(args)...) {} + + constexpr OptionalArrayRef(const std::initializer_list& Vec) + : wrapped_opt_array_ref(ArrayRef(Vec)) {} + + // Destructor + + ~OptionalArrayRef() = default; + + // Assignment + + constexpr OptionalArrayRef& operator=(std::nullopt_t /*unused*/) noexcept { + wrapped_opt_array_ref = std::nullopt; + return *this; + } + + OptionalArrayRef& operator=(const OptionalArrayRef& other) = default; + + OptionalArrayRef& operator=(OptionalArrayRef&& other) noexcept = default; + + constexpr OptionalArrayRef& operator=( + const std::optional>& other) noexcept { + wrapped_opt_array_ref = other; + return *this; + } + + constexpr OptionalArrayRef& operator=( + std::optional>&& other) noexcept { + wrapped_opt_array_ref = std::move(other); + return *this; + } + + template < + typename U = ArrayRef, + typename = std::enable_if_t< + !std::is_same_v, OptionalArrayRef> && + std::is_constructible_v, U&&> && + std::is_assignable_v&, U&&>>> + constexpr OptionalArrayRef& operator=(U&& value) noexcept( + std::is_nothrow_constructible_v, U&&> && + std::is_nothrow_assignable_v&, U&&>) { + wrapped_opt_array_ref = std::forward(value); + return *this; + } + + // Observers + + constexpr ArrayRef* operator->() noexcept { + return &wrapped_opt_array_ref.value(); + } + + constexpr const ArrayRef* operator->() const noexcept { + return &wrapped_opt_array_ref.value(); + } + + constexpr ArrayRef& operator*() & noexcept { + return wrapped_opt_array_ref.value(); + } + + constexpr const ArrayRef& operator*() const& noexcept { + return wrapped_opt_array_ref.value(); + } + + constexpr ArrayRef&& operator*() && noexcept { + return std::move(wrapped_opt_array_ref.value()); + } + + constexpr const ArrayRef&& operator*() const&& noexcept { + return std::move(wrapped_opt_array_ref.value()); + } + + constexpr explicit operator bool() const noexcept { + return wrapped_opt_array_ref.has_value(); + } + + constexpr bool has_value() const noexcept { + return wrapped_opt_array_ref.has_value(); + } + + constexpr ArrayRef& value() & { + return wrapped_opt_array_ref.value(); + } + + constexpr const ArrayRef& value() const& { + // NOLINTNEXTLINE(bugprone-unchecked-optional-access) + return wrapped_opt_array_ref.value(); + } + + constexpr ArrayRef&& value() && { + return std::move(wrapped_opt_array_ref.value()); + } + + constexpr const ArrayRef&& value() const&& { + return std::move(wrapped_opt_array_ref.value()); + } + + template + constexpr std:: + enable_if_t>, ArrayRef> + value_or(U&& default_value) const& { + return wrapped_opt_array_ref.value_or(std::forward(default_value)); + } + + template + constexpr std:: + enable_if_t>, ArrayRef> + value_or(U&& default_value) && { + return wrapped_opt_array_ref.value_or(std::forward(default_value)); + } + + // Modifiers + + constexpr void swap(OptionalArrayRef& other) noexcept { + std::swap(wrapped_opt_array_ref, other.wrapped_opt_array_ref); + } + + constexpr void reset() noexcept { + wrapped_opt_array_ref.reset(); + } + + template + constexpr std:: + enable_if_t, Args&&...>, ArrayRef&> + emplace(Args&&... args) noexcept( + std::is_nothrow_constructible_v, Args&&...>) { + return wrapped_opt_array_ref.emplace(std::forward(args)...); + } + + template + constexpr ArrayRef& emplace( + std::initializer_list il, + Args&&... args) noexcept { + return wrapped_opt_array_ref.emplace(il, std::forward(args)...); + } + + private: + std::optional> wrapped_opt_array_ref; +}; + +using OptionalIntArrayRef = OptionalArrayRef; + +inline bool operator==( + const OptionalIntArrayRef& a1, + const IntArrayRef& other) { + if (!a1.has_value()) { + return false; + } + return a1.value() == other; +} + +inline bool operator==( + const c10::IntArrayRef& a1, + const c10::OptionalIntArrayRef& a2) { + return a2 == a1; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ParallelGuard.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ParallelGuard.h new file mode 100644 index 0000000000000000000000000000000000000000..e577497980fbf93d2e928b9c879f085cc1852a4d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ParallelGuard.h @@ -0,0 +1,25 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace c10 { + +// RAII thread local guard that tracks whether code is being executed in +// `at::parallel_for` or `at::parallel_reduce` loop function. +class C10_API ParallelGuard { + public: + static bool is_enabled(); + + ParallelGuard(bool state); + ~ParallelGuard(); + + private: + bool previous_state_; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Registry.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Registry.h new file mode 100644 index 0000000000000000000000000000000000000000..92d1809d8c3094d19c927d9594afab15eba475ad --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Registry.h @@ -0,0 +1,334 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_REGISTRY_H_ +#define C10_UTIL_REGISTRY_H_ + +/** + * Simple registry implementation that uses static variables to + * register object creators during program initialization time. + */ + +// NB: This Registry works poorly when you have other namespaces. +// Make all macro invocations from inside the at namespace. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace c10 { + +template +inline std::string KeyStrRepr(const KeyType& /*key*/) { + return "[key type printing not supported]"; +} + +template <> +inline std::string KeyStrRepr(const std::string& key) { + return key; +} + +enum RegistryPriority { + REGISTRY_FALLBACK = 1, + REGISTRY_DEFAULT = 2, + REGISTRY_PREFERRED = 3, +}; + +/** + * @brief A template class that allows one to register classes by keys. + * + * The keys are usually a std::string specifying the name, but can be anything + * that can be used in a std::map. + * + * You should most likely not use the Registry class explicitly, but use the + * helper macros below to declare specific registries as well as registering + * objects. + */ +template +class Registry { + public: + typedef std::function Creator; + + Registry(bool warning = true) : registry_(), priority_(), warning_(warning) {} + ~Registry() = default; + + void Register( + const SrcType& key, + Creator creator, + const RegistryPriority priority = REGISTRY_DEFAULT) { + std::lock_guard lock(register_mutex_); + // The if statement below is essentially the same as the following line: + // TORCH_CHECK_EQ(registry_.count(key), 0) << "Key " << key + // << " registered twice."; + // However, TORCH_CHECK_EQ depends on google logging, and since registration + // is carried out at static initialization time, we do not want to have an + // explicit dependency on glog's initialization function. + if (registry_.count(key) != 0) { + auto cur_priority = priority_[key]; + if (priority > cur_priority) { +#ifdef DEBUG + std::string warn_msg = + "Overwriting already registered item for key " + KeyStrRepr(key); + fprintf(stderr, "%s\n", warn_msg.c_str()); +#endif + registry_[key] = creator; + priority_[key] = priority; + } else if (priority == cur_priority) { + std::string err_msg = + "Key already registered with the same priority: " + KeyStrRepr(key); + fprintf(stderr, "%s\n", err_msg.c_str()); + if (terminate_) { + std::exit(1); + } else { + throw std::runtime_error(err_msg); + } + } else if (warning_) { + std::string warn_msg = + "Higher priority item already registered, skipping registration of " + + KeyStrRepr(key); + fprintf(stderr, "%s\n", warn_msg.c_str()); + } + } else { + registry_[key] = creator; + priority_[key] = priority; + } + } + + void Register( + const SrcType& key, + Creator creator, + const std::string& help_msg, + const RegistryPriority priority = REGISTRY_DEFAULT) { + Register(key, creator, priority); + help_message_[key] = help_msg; + } + + inline bool Has(const SrcType& key) { + return (registry_.count(key) != 0); + } + + ObjectPtrType Create(const SrcType& key, Args... args) { + auto it = registry_.find(key); + if (it == registry_.end()) { + // Returns nullptr if the key is not registered. + return nullptr; + } + return it->second(args...); + } + + /** + * Returns the keys currently registered as a std::vector. + */ + std::vector Keys() const { + std::vector keys; + keys.reserve(registry_.size()); + for (const auto& it : registry_) { + keys.push_back(it.first); + } + return keys; + } + + inline const std::unordered_map& HelpMessage() const { + return help_message_; + } + + const char* HelpMessage(const SrcType& key) const { + auto it = help_message_.find(key); + if (it == help_message_.end()) { + return nullptr; + } + return it->second.c_str(); + } + + // Used for testing, if terminate is unset, Registry throws instead of + // calling std::exit + void SetTerminate(bool terminate) { + terminate_ = terminate; + } + + C10_DISABLE_COPY_AND_ASSIGN(Registry); + Registry(Registry&&) = delete; + Registry& operator=(Registry&&) = delete; + + private: + std::unordered_map registry_; + std::unordered_map priority_; + bool terminate_{true}; + const bool warning_; + std::unordered_map help_message_; + std::mutex register_mutex_; +}; + +template +class Registerer { + public: + explicit Registerer( + const SrcType& key, + Registry* registry, + typename Registry::Creator creator, + const std::string& help_msg = "") { + registry->Register(key, creator, help_msg); + } + + explicit Registerer( + const SrcType& key, + const RegistryPriority priority, + Registry* registry, + typename Registry::Creator creator, + const std::string& help_msg = "") { + registry->Register(key, creator, help_msg, priority); + } + + template + static ObjectPtrType DefaultCreator(Args... args) { + return ObjectPtrType(new DerivedType(args...)); + } +}; + +/** + * C10_DECLARE_TYPED_REGISTRY is a macro that expands to a function + * declaration, as well as creating a convenient typename for its corresponding + * registerer. + */ +// Note on C10_IMPORT and C10_EXPORT below: we need to explicitly mark DECLARE +// as import and DEFINE as export, because these registry macros will be used +// in downstream shared libraries as well, and one cannot use *_API - the API +// macro will be defined on a per-shared-library basis. Semantically, when one +// declares a typed registry it is always going to be IMPORT, and when one +// defines a registry (which should happen ONLY ONCE and ONLY IN SOURCE FILE), +// the instantiation unit is always going to be exported. +// +// The only unique condition is when in the same file one does DECLARE and +// DEFINE - in Windows compilers, this generates a warning that dllimport and +// dllexport are mixed, but the warning is fine and linker will be properly +// exporting the symbol. Same thing happens in the gflags flag declaration and +// definition caes. +#define C10_DECLARE_TYPED_REGISTRY( \ + RegistryName, SrcType, ObjectType, PtrType, ...) \ + C10_API ::c10::Registry, ##__VA_ARGS__>* \ + RegistryName(); \ + typedef ::c10::Registerer, ##__VA_ARGS__> \ + Registerer##RegistryName + +#define TORCH_DECLARE_TYPED_REGISTRY( \ + RegistryName, SrcType, ObjectType, PtrType, ...) \ + TORCH_API ::c10::Registry, ##__VA_ARGS__>* \ + RegistryName(); \ + typedef ::c10::Registerer, ##__VA_ARGS__> \ + Registerer##RegistryName + +#define C10_DEFINE_TYPED_REGISTRY( \ + RegistryName, SrcType, ObjectType, PtrType, ...) \ + C10_EXPORT ::c10::Registry, ##__VA_ARGS__>* \ + RegistryName() { \ + static ::c10::Registry, ##__VA_ARGS__>* \ + registry = new ::c10:: \ + Registry, ##__VA_ARGS__>(); \ + return registry; \ + } + +#define C10_DEFINE_TYPED_REGISTRY_WITHOUT_WARNING( \ + RegistryName, SrcType, ObjectType, PtrType, ...) \ + C10_EXPORT ::c10::Registry, ##__VA_ARGS__>* \ + RegistryName() { \ + static ::c10::Registry, ##__VA_ARGS__>* \ + registry = \ + new ::c10::Registry, ##__VA_ARGS__>( \ + false); \ + return registry; \ + } + +// Note(Yangqing): The __VA_ARGS__ below allows one to specify a templated +// creator with comma in its templated arguments. +#define C10_REGISTER_TYPED_CREATOR(RegistryName, key, ...) \ + static Registerer##RegistryName C10_ANONYMOUS_VARIABLE(g_##RegistryName)( \ + key, RegistryName(), ##__VA_ARGS__); + +#define C10_REGISTER_TYPED_CREATOR_WITH_PRIORITY( \ + RegistryName, key, priority, ...) \ + static Registerer##RegistryName C10_ANONYMOUS_VARIABLE(g_##RegistryName)( \ + key, priority, RegistryName(), ##__VA_ARGS__); + +#define C10_REGISTER_TYPED_CLASS(RegistryName, key, ...) \ + static Registerer##RegistryName C10_ANONYMOUS_VARIABLE(g_##RegistryName)( \ + key, \ + RegistryName(), \ + Registerer##RegistryName::DefaultCreator<__VA_ARGS__>, \ + ::c10::demangle_type<__VA_ARGS__>()); + +#define C10_REGISTER_TYPED_CLASS_WITH_PRIORITY( \ + RegistryName, key, priority, ...) \ + static Registerer##RegistryName C10_ANONYMOUS_VARIABLE(g_##RegistryName)( \ + key, \ + priority, \ + RegistryName(), \ + Registerer##RegistryName::DefaultCreator<__VA_ARGS__>, \ + ::c10::demangle_type<__VA_ARGS__>()); + +// C10_DECLARE_REGISTRY and C10_DEFINE_REGISTRY are hard-wired to use +// std::string as the key type, because that is the most commonly used cases. +#define C10_DECLARE_REGISTRY(RegistryName, ObjectType, ...) \ + C10_DECLARE_TYPED_REGISTRY( \ + RegistryName, std::string, ObjectType, std::unique_ptr, ##__VA_ARGS__) + +#define TORCH_DECLARE_REGISTRY(RegistryName, ObjectType, ...) \ + TORCH_DECLARE_TYPED_REGISTRY( \ + RegistryName, std::string, ObjectType, std::unique_ptr, ##__VA_ARGS__) + +#define C10_DEFINE_REGISTRY(RegistryName, ObjectType, ...) \ + C10_DEFINE_TYPED_REGISTRY( \ + RegistryName, std::string, ObjectType, std::unique_ptr, ##__VA_ARGS__) + +#define C10_DEFINE_REGISTRY_WITHOUT_WARNING(RegistryName, ObjectType, ...) \ + C10_DEFINE_TYPED_REGISTRY_WITHOUT_WARNING( \ + RegistryName, std::string, ObjectType, std::unique_ptr, ##__VA_ARGS__) + +#define C10_DECLARE_SHARED_REGISTRY(RegistryName, ObjectType, ...) \ + C10_DECLARE_TYPED_REGISTRY( \ + RegistryName, std::string, ObjectType, std::shared_ptr, ##__VA_ARGS__) + +#define TORCH_DECLARE_SHARED_REGISTRY(RegistryName, ObjectType, ...) \ + TORCH_DECLARE_TYPED_REGISTRY( \ + RegistryName, std::string, ObjectType, std::shared_ptr, ##__VA_ARGS__) + +#define C10_DEFINE_SHARED_REGISTRY(RegistryName, ObjectType, ...) \ + C10_DEFINE_TYPED_REGISTRY( \ + RegistryName, std::string, ObjectType, std::shared_ptr, ##__VA_ARGS__) + +#define C10_DEFINE_SHARED_REGISTRY_WITHOUT_WARNING( \ + RegistryName, ObjectType, ...) \ + C10_DEFINE_TYPED_REGISTRY_WITHOUT_WARNING( \ + RegistryName, std::string, ObjectType, std::shared_ptr, ##__VA_ARGS__) + +// C10_REGISTER_CREATOR and C10_REGISTER_CLASS are hard-wired to use std::string +// as the key +// type, because that is the most commonly used cases. +#define C10_REGISTER_CREATOR(RegistryName, key, ...) \ + C10_REGISTER_TYPED_CREATOR(RegistryName, #key, __VA_ARGS__) + +#define C10_REGISTER_CREATOR_WITH_PRIORITY(RegistryName, key, priority, ...) \ + C10_REGISTER_TYPED_CREATOR_WITH_PRIORITY( \ + RegistryName, #key, priority, __VA_ARGS__) + +#define C10_REGISTER_CLASS(RegistryName, key, ...) \ + C10_REGISTER_TYPED_CLASS(RegistryName, #key, __VA_ARGS__) + +#define C10_REGISTER_CLASS_WITH_PRIORITY(RegistryName, key, priority, ...) \ + C10_REGISTER_TYPED_CLASS_WITH_PRIORITY( \ + RegistryName, #key, priority, __VA_ARGS__) + +} // namespace c10 + +#endif // C10_UTIL_REGISTRY_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ScopeExit.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ScopeExit.h new file mode 100644 index 0000000000000000000000000000000000000000..fa4eaaceadd2588bbe53fcd51d3cbffde5d3b220 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ScopeExit.h @@ -0,0 +1,55 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10 { + +/** + * Mostly copied from https://llvm.org/doxygen/ScopeExit_8h_source.html + */ +template +class scope_exit { + Callable ExitFunction; + bool Engaged = true; // False once moved-from or release()d. + + public: + template + // NOLINTNEXTLINE(bugprone-forwarding-reference-overload) + explicit scope_exit(Fp&& F) : ExitFunction(std::forward(F)) {} + + scope_exit(scope_exit&& Rhs) noexcept + : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) { + Rhs.release(); + } + scope_exit(const scope_exit&) = delete; + scope_exit& operator=(scope_exit&&) = delete; + scope_exit& operator=(const scope_exit&) = delete; + + void release() { + Engaged = false; + } + + ~scope_exit() { + if (Engaged) { + ExitFunction(); + } + } +}; + +// Keeps the callable object that is passed in, and execute it at the +// destruction of the returned object (usually at the scope exit where the +// returned object is kept). +// +// Interface is specified by p0052r2. +template +scope_exit> make_scope_exit(Callable&& F) { + return scope_exit>(std::forward(F)); +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Semaphore.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Semaphore.h new file mode 100644 index 0000000000000000000000000000000000000000..7ef5da6252b52c4b7729532eb0eddc8691c0f03e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Semaphore.h @@ -0,0 +1,82 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +/* + a simple semaphore interface. +*/ + +// note: __cpp_lib_semaphore will not be defined in some apple platforms +// even if >= C++20. +// +// libstdc++'s __atomic_semaphore has a lost-wakeup bug: _M_release skips +// the futex notify when the counter is already positive, but a concurrent +// _S_do_try_acquire can fail its CAS, see zero, and block — missing the +// wakeup. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98033 +#if __has_include() && defined(__cpp_lib_semaphore) && \ + __cpp_lib_semaphore >= 201907L && !defined(__GLIBCXX__) +#define C10_SEMAPHORE_USE_STL +#endif + +#ifdef C10_SEMAPHORE_USE_STL +#include +#else +// To use moodycamel semaphore, we need to include the header file +// for concurrentqueue first. Hiding implementation detail here. +#ifdef BLOCK_SIZE +#pragma push_macro("BLOCK_SIZE") +#undef BLOCK_SIZE +#include // @manual +#pragma pop_macro("BLOCK_SIZE") +#else +#include // @manual +#endif + +#include // @manual +#endif + +namespace c10 { + +class Semaphore { + public: + Semaphore(int32_t initial_count = 0) : impl_(initial_count) {} + + void release(int32_t n = 1) { +#ifdef C10_SEMAPHORE_USE_STL + impl_.release(n); +#else + impl_.signal(n); +#endif + } + + void acquire() { +#ifdef C10_SEMAPHORE_USE_STL + impl_.acquire(); +#else + impl_.wait(); +#endif + } + + bool tryAcquire() { +#ifdef C10_SEMAPHORE_USE_STL + return impl_.try_acquire(); +#else + return impl_.tryWait(); +#endif + } + + private: +#ifdef C10_SEMAPHORE_USE_STL + std::counting_semaphore<> impl_; +#else + moodycamel::LightweightSemaphore impl_; +#endif +}; +} // namespace c10 + +#undef C10_SEMAPHORE_USE_STL + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/SmallBuffer.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/SmallBuffer.h new file mode 100644 index 0000000000000000000000000000000000000000..1c40d21a692f0470d02d25bc8794f1b8d58c55a0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/SmallBuffer.h @@ -0,0 +1,92 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include +#include +#include + +/** Helper class for allocating temporary fixed size arrays with SBO. + * + * This is intentionally much simpler than SmallVector, to improve performance + * at the expense of many features: + * - No zero-initialization for numeric types + * - No resizing after construction + * - No copy/move + * - No non-trivial types + */ + +namespace c10 { + +template +class SmallBuffer { + static_assert(std::is_trivial_v, "SmallBuffer is intended for POD types"); + + std::array storage_; + size_t size_{}; + T* data_{}; + + public: + SmallBuffer(size_t size) : size_(size) { + if (size > N) { + data_ = new T[size]; + } else { + data_ = &storage_[0]; + } + } + + SmallBuffer(const SmallBuffer&) = delete; + SmallBuffer& operator=(const SmallBuffer&) = delete; + + // move constructor is needed in function return + SmallBuffer(SmallBuffer&& rhs) noexcept : size_{rhs.size_} { + rhs.size_ = 0; + if (size_ > N) { + data_ = rhs.data_; + rhs.data_ = nullptr; + } else { + storage_ = std::move(rhs.storage_); + data_ = &storage_[0]; + } + } + + SmallBuffer& operator=(SmallBuffer&&) = delete; + + ~SmallBuffer() { + if (size_ > N) { + delete[] data_; + } + } + T& operator[](size_t idx) { + return data()[idx]; + } + const T& operator[](size_t idx) const { + return data()[idx]; + } + T* data() { + return data_; + } + const T* data() const { + return data_; + } + size_t size() const { + return size_; + } + T* begin() { + return data_; + } + const T* begin() const { + return data_; + } + T* end() { + return data_ + size_; + } + const T* end() const { + return data_ + size_; + } +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/SmallVector.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/SmallVector.h new file mode 100644 index 0000000000000000000000000000000000000000..2957baca7b90d993a589179ba6dbc9acf67c40dc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/SmallVector.h @@ -0,0 +1,1472 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the SmallVector class. +// +//===----------------------------------------------------------------------===// + +// ATen: modified from llvm::SmallVector. +// used std::is_trivially_{copy,move}_constructible +// replaced iterator_range constructor with inline Container&& constructor +// replaced LLVM_NODISCARD, LLVM_LIKELY, and LLVM_UNLIKELY with c10 equivalents +// removed LLVM_GSL_OWNER +// added SmallVector::at +// added operator<< for std::ostream +// added C10_API to export SmallVectorBase + +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +/// This is all the stuff common to all SmallVectors. +/// +/// The template parameter specifies the type which should be used to hold the +/// Size and Capacity of the SmallVector, so it can be adjusted. +/// Using 32 bit size is desirable to shrink the size of the SmallVector. +/// Using 64 bit size is desirable for cases like SmallVector, where a +/// 32 bit size would limit the vector to ~4GB. SmallVectors are used for +/// buffering bitcode output - which can exceed 4GB. +template +class C10_API SmallVectorBase { + protected: + void* BeginX; + Size_T Size = 0, Capacity; + + /// The maximum value of the Size_T used. + static constexpr size_t SizeTypeMax() { + return std::numeric_limits::max(); + } + + SmallVectorBase(void* FirstEl, size_t TotalCapacity) + : BeginX(FirstEl), Capacity(TotalCapacity) {} + + /// This is a helper for \a grow() that's out of line to reduce code + /// duplication. This function will report a fatal error if it can't grow at + /// least to \p MinSize. + void* mallocForGrow(size_t MinSize, size_t TSize, size_t& NewCapacity); + + /// This is an implementation of the grow() method which only works + /// on POD-like data types and is out of line to reduce code duplication. + /// This function will report a fatal error if it cannot increase capacity. + void grow_pod(const void* FirstEl, size_t MinSize, size_t TSize); + + public: + SmallVectorBase() = delete; + size_t size() const { + return Size; + } + size_t capacity() const { + return Capacity; + } + + [[nodiscard]] bool empty() const { + return !Size; + } + + /// Set the array size to \p N, which the current array must have enough + /// capacity for. + /// + /// This does not construct or destroy any elements in the vector. + /// + /// Clients can use this in conjunction with capacity() to write past the end + /// of the buffer when they know that more elements are available, and only + /// update the size later. This avoids the cost of value initializing elements + /// which will only be overwritten. + void set_size(size_t N) { + assert(N <= capacity()); + Size = N; + } +}; + +template +using SmallVectorSizeType = + std::conditional_t= 8, uint64_t, uint32_t>; + +/// Figure out the offset of the first element. +template +struct SmallVectorAlignmentAndSize { + // NOLINTNEXTLINE(*c-arrays*) + alignas(SmallVectorBase>) char Base[sizeof( + SmallVectorBase>)]; + // NOLINTNEXTLINE(*c-arrays*) + alignas(T) char FirstEl[sizeof(T)]; +}; + +/// This is the part of SmallVectorTemplateBase which does not depend on whether +/// the type T is a POD. The extra dummy template argument is used by ArrayRef +/// to avoid unnecessarily requiring T to be complete. +template +class SmallVectorTemplateCommon + : public SmallVectorBase> { + using Base = SmallVectorBase>; + + /// Find the address of the first element. For this pointer math to be valid + /// with small-size of 0 for T with lots of alignment, it's important that + /// SmallVectorStorage is properly-aligned even for small-size of 0. + void* getFirstEl() const { + return const_cast(reinterpret_cast( + reinterpret_cast(this) + + offsetof(SmallVectorAlignmentAndSize, FirstEl))); + } + // Space after 'FirstEl' is clobbered, do not add any instance vars after it. + + protected: + SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {} + + void grow_pod(size_t MinSize, size_t TSize) { + Base::grow_pod(getFirstEl(), MinSize, TSize); + } + + /// Return true if this is a smallvector which has not had dynamic + /// memory allocated for it. + bool isSmall() const { + return this->BeginX == getFirstEl(); + } + + /// Put this vector in a state of being small. + void resetToSmall() { + this->BeginX = getFirstEl(); + this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect. + } + + /// Return true if V is an internal reference to the given range. + bool isReferenceToRange(const void* V, const void* First, const void* Last) + const { + // Use std::less to avoid UB. + std::less<> LessThan; + return !LessThan(V, First) && LessThan(V, Last); + } + + /// Return true if V is an internal reference to this vector. + bool isReferenceToStorage(const void* V) const { + return isReferenceToRange(V, this->begin(), this->end()); + } + + /// Return true if First and Last form a valid (possibly empty) range in this + /// vector's storage. + bool isRangeInStorage(const void* First, const void* Last) const { + // Use std::less to avoid UB. + std::less<> LessThan; + return !LessThan(First, this->begin()) && !LessThan(Last, First) && + !LessThan(this->end(), Last); + } + + /// Return true unless Elt will be invalidated by resizing the vector to + /// NewSize. + bool isSafeToReferenceAfterResize(const void* Elt, size_t NewSize) { + // Past the end. + if (C10_LIKELY(!isReferenceToStorage(Elt))) + return true; + + // Return false if Elt will be destroyed by shrinking. + if (NewSize <= this->size()) + return Elt < this->begin() + NewSize; + + // Return false if we need to grow. + return NewSize <= this->capacity(); + } + + /// Check whether Elt will be invalidated by resizing the vector to NewSize. + void assertSafeToReferenceAfterResize(const void* Elt, size_t NewSize) { + (void)Elt; // Suppress unused variable warning + (void)NewSize; // Suppress unused variable warning + assert( + isSafeToReferenceAfterResize(Elt, NewSize) && + "Attempting to reference an element of the vector in an operation " + "that invalidates it"); + } + + /// Check whether Elt will be invalidated by increasing the size of the + /// vector by N. + void assertSafeToAdd(const void* Elt, size_t N = 1) { + this->assertSafeToReferenceAfterResize(Elt, this->size() + N); + } + + /// Check whether any part of the range will be invalidated by clearing. + void assertSafeToReferenceAfterClear(const T* From, const T* To) { + if (From == To) + return; + this->assertSafeToReferenceAfterResize(From, 0); + this->assertSafeToReferenceAfterResize(To - 1, 0); + } + template < + class ItTy, + std::enable_if_t, T*>, bool> = + false> + void assertSafeToReferenceAfterClear(ItTy /*unused*/, ItTy /*unused*/) {} + + /// Check whether any part of the range will be invalidated by growing. + void assertSafeToAddRange(const T* From, const T* To) { + if (From == To) + return; + this->assertSafeToAdd(From, To - From); + this->assertSafeToAdd(To - 1, To - From); + } + template < + class ItTy, + std::enable_if_t, T*>, bool> = + false> + void assertSafeToAddRange(ItTy /*unused*/, ItTy /*unused*/) {} + + /// Reserve enough space to add one element, and return the updated element + /// pointer in case it was a reference to the storage. + template + static const T* reserveForParamAndGetAddressImpl( + U* This, + const T& Elt, + size_t N) { + size_t NewSize = This->size() + N; + if (C10_LIKELY(NewSize <= This->capacity())) + return &Elt; + + bool ReferencesStorage = false; + int64_t Index = -1; + if constexpr (!U::TakesParamByValue) { + if (C10_UNLIKELY(This->isReferenceToStorage(&Elt))) { + ReferencesStorage = true; + Index = &Elt - This->begin(); + } + } + This->grow(NewSize); + return ReferencesStorage ? This->begin() + Index : &Elt; + } + + public: + using size_type = size_t; + using difference_type = ptrdiff_t; + using value_type = T; + using iterator = T*; + using const_iterator = const T*; + + using const_reverse_iterator = std::reverse_iterator; + using reverse_iterator = std::reverse_iterator; + + using reference = T&; + using const_reference = const T&; + using pointer = T*; + using const_pointer = const T*; + + using Base::capacity; + using Base::empty; + using Base::size; + + // forward iterator creation methods. + iterator begin() { + return (iterator)this->BeginX; + } + const_iterator begin() const { + return (const_iterator)this->BeginX; + } + iterator end() { + return begin() + size(); + } + const_iterator end() const { + return begin() + size(); + } + + // reverse iterator creation methods. + reverse_iterator rbegin() { + return reverse_iterator(end()); + } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + reverse_iterator rend() { + return reverse_iterator(begin()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + size_type size_in_bytes() const { + return size() * sizeof(T); + } + constexpr size_type max_size() const { + return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T)); + } + + size_t capacity_in_bytes() const { + return capacity() * sizeof(T); + } + + /// Return a pointer to the vector's buffer, even if empty(). + pointer data() { + return pointer(begin()); + } + /// Return a pointer to the vector's buffer, even if empty(). + const_pointer data() const { + return const_pointer(begin()); + } + + // SmallVector::at is NOT from LLVM. + reference at(size_type idx) { + assert(idx < size()); + return begin()[idx]; + } + const_reference at(size_type idx) const { + assert(idx < size()); + return begin()[idx]; + } + reference operator[](size_type idx) { + assert(idx < size()); + return begin()[idx]; + } + const_reference operator[](size_type idx) const { + assert(idx < size()); + return begin()[idx]; + } + + reference front() { + assert(!empty()); + return begin()[0]; + } + const_reference front() const { + assert(!empty()); + return begin()[0]; + } + + reference back() { + assert(!empty()); + return end()[-1]; + } + const_reference back() const { + assert(!empty()); + return end()[-1]; + } +}; + +/// SmallVectorTemplateBase - This is where we put +/// method implementations that are designed to work with non-trivial T's. +/// +/// We approximate is_trivially_copyable with trivial move/copy construction and +/// trivial destruction. While the standard doesn't specify that you're allowed +/// copy these types with memcpy, there is no way for the type to observe this. +/// This catches the important case of std::pair, which is not +/// trivially assignable. +/// +/// XXX: if build fails here fall back to C10_IS_TRIVIALLY_COPYABLE and make a +/// note +template < + typename T, + bool = (std::is_trivially_copy_constructible_v) && + (std::is_trivially_move_constructible_v) && + std::is_trivially_destructible_v> +class SmallVectorTemplateBase : public SmallVectorTemplateCommon { + friend class SmallVectorTemplateCommon; + + protected: + static constexpr bool TakesParamByValue = false; + using ValueParamT = const T&; + + SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} + + static void destroy_range(T* S, T* E) { + while (S != E) { + --E; + E->~T(); + } + } + + /// Move the range [I, E) into the uninitialized memory starting with "Dest", + /// constructing elements as needed. + template + static void uninitialized_move(It1 I, It1 E, It2 Dest) { + std::uninitialized_copy( + std::make_move_iterator(I), std::make_move_iterator(E), Dest); + } + + /// Copy the range [I, E) onto the uninitialized memory starting with "Dest", + /// constructing elements as needed. + template + static void uninitialized_copy(It1 I, It1 E, It2 Dest) { + std::uninitialized_copy(I, E, Dest); + } + + /// Grow the allocated memory (without initializing new elements), doubling + /// the size of the allocated memory. Guarantees space for at least one more + /// element, or MinSize more elements if specified. + void grow(size_t MinSize = 0); + + /// Create a new allocation big enough for \p MinSize and pass back its size + /// in \p NewCapacity. This is the first section of \a grow(). + T* mallocForGrow(size_t MinSize, size_t& NewCapacity) { + return static_cast( + SmallVectorBase>::mallocForGrow( + MinSize, sizeof(T), NewCapacity)); + } + + /// Move existing elements over to the new allocation \p NewElts, the middle + /// section of \a grow(). + void moveElementsForGrow(T* NewElts); + + /// Transfer ownership of the allocation, finishing up \a grow(). + void takeAllocationForGrow(T* NewElts, size_t NewCapacity); + + /// Reserve enough space to add one element, and return the updated element + /// pointer in case it was a reference to the storage. + const T* reserveForParamAndGetAddress(const T& Elt, size_t N = 1) { + return this->reserveForParamAndGetAddressImpl(this, Elt, N); + } + + /// Reserve enough space to add one element, and return the updated element + /// pointer in case it was a reference to the storage. + T* reserveForParamAndGetAddress(T& Elt, size_t N = 1) { + return const_cast(this->reserveForParamAndGetAddressImpl(this, Elt, N)); + } + + static T&& forward_value_param(T&& V) { + return std::move(V); + } + static const T& forward_value_param(const T& V) { + return V; + } + + void growAndAssign(size_t NumElts, const T& Elt) { + // Grow manually in case Elt is an internal reference. + size_t NewCapacity = 0; + T* NewElts = mallocForGrow(NumElts, NewCapacity); + std::uninitialized_fill_n(NewElts, NumElts, Elt); + this->destroy_range(this->begin(), this->end()); + takeAllocationForGrow(NewElts, NewCapacity); + this->set_size(NumElts); + } + + template + T& growAndEmplaceBack(ArgTypes&&... Args) { + // Grow manually in case one of Args is an internal reference. + size_t NewCapacity = 0; + T* NewElts = mallocForGrow(0, NewCapacity); + ::new ((void*)(NewElts + this->size())) T(std::forward(Args)...); + moveElementsForGrow(NewElts); + takeAllocationForGrow(NewElts, NewCapacity); + this->set_size(this->size() + 1); + return this->back(); + } + + public: + void push_back(const T& Elt) { + const T* EltPtr = reserveForParamAndGetAddress(Elt); + ::new ((void*)this->end()) T(*EltPtr); + this->set_size(this->size() + 1); + } + + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + void push_back(T&& Elt) { + T* EltPtr = reserveForParamAndGetAddress(Elt); + ::new ((void*)this->end()) T(::std::move(*EltPtr)); + this->set_size(this->size() + 1); + } + + void pop_back() { + this->set_size(this->size() - 1); + this->end()->~T(); + } +}; + +// Define this out-of-line to dissuade the C++ compiler from inlining it. +template +void SmallVectorTemplateBase::grow(size_t MinSize) { + size_t NewCapacity = 0; + T* NewElts = mallocForGrow(MinSize, NewCapacity); + moveElementsForGrow(NewElts); + takeAllocationForGrow(NewElts, NewCapacity); +} + +// Define this out-of-line to dissuade the C++ compiler from inlining it. +template +void SmallVectorTemplateBase::moveElementsForGrow( + T* NewElts) { + // Move the elements over. + this->uninitialized_move(this->begin(), this->end(), NewElts); + + // Destroy the original elements. + destroy_range(this->begin(), this->end()); +} + +// Define this out-of-line to dissuade the C++ compiler from inlining it. +template +void SmallVectorTemplateBase::takeAllocationForGrow( + T* NewElts, + size_t NewCapacity) { + // If this wasn't grown from the inline copy, deallocate the old space. + if (!this->isSmall()) + free(this->begin()); + + this->BeginX = NewElts; + this->Capacity = NewCapacity; +} + +/// SmallVectorTemplateBase - This is where we put +/// method implementations that are designed to work with trivially copyable +/// T's. This allows using memcpy in place of copy/move construction and +/// skipping destruction. +template +class SmallVectorTemplateBase : public SmallVectorTemplateCommon { + friend class SmallVectorTemplateCommon; + + protected: + /// True if it's cheap enough to take parameters by value. Doing so avoids + /// overhead related to mitigations for reference invalidation. + static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void*); + + /// Either const T& or T, depending on whether it's cheap enough to take + /// parameters by value. + using ValueParamT = std::conditional_t; + + SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} + + // No need to do a destroy loop for POD's. + static void destroy_range(T* /*unused*/, T* /*unused*/) {} + + /// Move the range [I, E) onto the uninitialized memory + /// starting with "Dest", constructing elements into it as needed. + template + static void uninitialized_move(It1 I, It1 E, It2 Dest) { + // Just do a copy. + uninitialized_copy(I, E, Dest); + } + + /// Copy the range [I, E) onto the uninitialized memory + /// starting with "Dest", constructing elements into it as needed. + template + static void uninitialized_copy(It1 I, It1 E, It2 Dest) { + // Arbitrary iterator types; just use the basic implementation. + std::uninitialized_copy(I, E, Dest); + } + + /// Copy the range [I, E) onto the uninitialized memory + /// starting with "Dest", constructing elements into it as needed. + template + static void uninitialized_copy( + T1* I, + T1* E, + T2* Dest, + std::enable_if_t, T2>>* /*unused*/ + = nullptr) { + // Use memcpy for PODs iterated by pointers (which includes SmallVector + // iterators): std::uninitialized_copy optimizes to memmove, but we can + // use memcpy here. Note that I and E are iterators and thus might be + // invalid for memcpy if they are equal. + if (I != E) + memcpy(reinterpret_cast(Dest), I, (E - I) * sizeof(T)); + } + + /// Double the size of the allocated memory, guaranteeing space for at + /// least one more element or MinSize if specified. + void grow(size_t MinSize = 0) { + this->grow_pod(MinSize, sizeof(T)); + } + + /// Reserve enough space to add one element, and return the updated element + /// pointer in case it was a reference to the storage. + const T* reserveForParamAndGetAddress(const T& Elt, size_t N = 1) { + return this->reserveForParamAndGetAddressImpl(this, Elt, N); + } + + /// Reserve enough space to add one element, and return the updated element + /// pointer in case it was a reference to the storage. + T* reserveForParamAndGetAddress(T& Elt, size_t N = 1) { + return const_cast(this->reserveForParamAndGetAddressImpl(this, Elt, N)); + } + + /// Copy \p V or return a reference, depending on \a ValueParamT. + static ValueParamT forward_value_param(ValueParamT V) { + return V; + } + + void growAndAssign(size_t NumElts, T Elt) { + // Elt has been copied in case it's an internal reference, side-stepping + // reference invalidation problems without losing the realloc optimization. + this->set_size(0); + this->grow(NumElts); + std::uninitialized_fill_n(this->begin(), NumElts, Elt); + this->set_size(NumElts); + } + + template + T& growAndEmplaceBack(ArgTypes&&... Args) { + // Use push_back with a copy in case Args has an internal reference, + // side-stepping reference invalidation problems without losing the realloc + // optimization. + push_back(T(std::forward(Args)...)); + return this->back(); + } + + public: + void push_back(ValueParamT Elt) { + const T* EltPtr = reserveForParamAndGetAddress(Elt); + memcpy(reinterpret_cast(this->end()), EltPtr, sizeof(T)); + this->set_size(this->size() + 1); + } + + void pop_back() { + this->set_size(this->size() - 1); + } +}; + +/// This class consists of common code factored out of the SmallVector class to +/// reduce code duplication based on the SmallVector 'N' template parameter. +template +class SmallVectorImpl : public SmallVectorTemplateBase { + using SuperClass = SmallVectorTemplateBase; + + public: + using iterator = typename SuperClass::iterator; + using const_iterator = typename SuperClass::const_iterator; + using reference = typename SuperClass::reference; + using size_type = typename SuperClass::size_type; + + protected: + using SmallVectorTemplateBase::TakesParamByValue; + using ValueParamT = typename SuperClass::ValueParamT; + + // Default ctor - Initialize to empty. + explicit SmallVectorImpl(unsigned N) : SmallVectorTemplateBase(N) {} + + public: + SmallVectorImpl(const SmallVectorImpl&) = delete; + + ~SmallVectorImpl() { + // Subclass has already destructed this vector's elements. + // If this wasn't grown from the inline copy, deallocate the old space. + if (!this->isSmall()) + free(this->begin()); + } + + void clear() { + this->destroy_range(this->begin(), this->end()); + this->Size = 0; + } + + private: + template + void resizeImpl(size_type N) { + if (N < this->size()) { + this->pop_back_n(this->size() - N); + } else if (N > this->size()) { + this->reserve(N); + for (auto I = this->end(), E = this->begin() + N; I != E; ++I) + if (ForOverwrite) + new (&*I) T; + else + new (&*I) T(); + this->set_size(N); + } + } + + public: + void resize(size_type N) { + resizeImpl(N); + } + + /// Like resize, but \ref T is POD, the new values won't be initialized. + void resize_for_overwrite(size_type N) { + resizeImpl(N); + } + + void resize(size_type N, ValueParamT NV) { + if (N == this->size()) + return; + + if (N < this->size()) { + this->pop_back_n(this->size() - N); + return; + } + + // N > this->size(). Defer to append. + this->append(N - this->size(), NV); + } + + void reserve(size_type N) { + if (this->capacity() < N) + this->grow(N); + } + + void pop_back_n(size_type NumItems) { + assert(this->size() >= NumItems); + this->destroy_range(this->end() - NumItems, this->end()); + this->set_size(this->size() - NumItems); + } + + [[nodiscard]] T pop_back_val() { + T Result = ::std::move(this->back()); + this->pop_back(); + return Result; + } + + void swap(SmallVectorImpl& RHS) noexcept; + + /// Add the specified range to the end of the SmallVector. + template < + typename in_iter, + typename = std::enable_if_t::iterator_category, + std::input_iterator_tag>>> + void append(in_iter in_start, in_iter in_end) { + this->assertSafeToAddRange(in_start, in_end); + size_type NumInputs = std::distance(in_start, in_end); + this->reserve(this->size() + NumInputs); + this->uninitialized_copy(in_start, in_end, this->end()); + this->set_size(this->size() + NumInputs); + } + + /// Append \p NumInputs copies of \p Elt to the end. + void append(size_type NumInputs, ValueParamT Elt) { + const T* EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs); + std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr); + this->set_size(this->size() + NumInputs); + } + + void append(std::initializer_list IL) { + append(IL.begin(), IL.end()); + } + + void append(const SmallVectorImpl& RHS) { + append(RHS.begin(), RHS.end()); + } + + void assign(size_type NumElts, ValueParamT Elt) { + // Note that Elt could be an internal reference. + if (NumElts > this->capacity()) { + this->growAndAssign(NumElts, Elt); + return; + } + + // Assign over existing elements. + std::fill_n(this->begin(), std::min(NumElts, this->size()), Elt); + if (NumElts > this->size()) + std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt); + else if (NumElts < this->size()) + this->destroy_range(this->begin() + NumElts, this->end()); + this->set_size(NumElts); + } + + // FIXME: Consider assigning over existing elements, rather than clearing & + // re-initializing them - for all assign(...) variants. + + template < + typename in_iter, + typename = std::enable_if_t::iterator_category, + std::input_iterator_tag>>> + void assign(in_iter in_start, in_iter in_end) { + this->assertSafeToReferenceAfterClear(in_start, in_end); + clear(); + append(in_start, in_end); + } + + void assign(std::initializer_list IL) { + clear(); + append(IL); + } + + void assign(const SmallVectorImpl& RHS) { + assign(RHS.begin(), RHS.end()); + } + + iterator erase(iterator I) { + assert( + this->isReferenceToStorage(I) && "Iterator to erase is out of bounds."); + + iterator N = I; + // Shift all elts down one. + std::move(I + 1, this->end(), I); + // Drop the last elt. + this->pop_back(); + return N; + } + + iterator erase(iterator S, iterator E) { + assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds."); + + iterator N = S; + // Shift all elts down. + iterator I = std::move(E, this->end(), S); + // Drop the last elts. + this->destroy_range(I, this->end()); + this->set_size(I - this->begin()); + return N; + } + + private: + template + iterator insert_one_impl(iterator I, ArgType&& Elt) { + // Callers ensure that ArgType is derived from T. + static_assert( + std:: + is_same_v>, T>, + "ArgType must be derived from T!"); + + if (I == this->end()) { // Important special case for empty vector. + this->push_back(::std::forward(Elt)); + return this->end() - 1; + } + + assert( + this->isReferenceToStorage(I) && + "Insertion iterator is out of bounds."); + + // Grow if necessary. + size_t Index = I - this->begin(); + std::remove_reference_t* EltPtr = + this->reserveForParamAndGetAddress(Elt); + I = this->begin() + Index; + + ::new ((void*)this->end()) T(::std::move(this->back())); + // Push everything else over. + std::move_backward(I, this->end() - 1, this->end()); + this->set_size(this->size() + 1); + + // If we just moved the element we're inserting, be sure to update + // the reference (never happens if TakesParamByValue). + static_assert( + !TakesParamByValue || std::is_same_v, + "ArgType must be 'T' when taking by value!"); + if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end())) + ++EltPtr; + + *I = ::std::forward(*EltPtr); + return I; + } + + public: + iterator insert(iterator I, T&& Elt) { + return insert_one_impl(I, this->forward_value_param(std::move(Elt))); + } + + iterator insert(iterator I, const T& Elt) { + return insert_one_impl(I, this->forward_value_param(Elt)); + } + + iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt) { + // Convert iterator to elt# to avoid invalidating iterator when we reserve() + size_t InsertElt = I - this->begin(); + + if (I == this->end()) { // Important special case for empty vector. + append(NumToInsert, Elt); + return this->begin() + InsertElt; + } + + assert( + this->isReferenceToStorage(I) && + "Insertion iterator is out of bounds."); + + // Ensure there is enough space, and get the (maybe updated) address of + // Elt. + const T* EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert); + + // Uninvalidate the iterator. + I = this->begin() + InsertElt; + + // If there are more elements between the insertion point and the end of the + // range than there are being inserted, we can use a simple approach to + // insertion. Since we already reserved space, we know that this won't + // reallocate the vector. + if (size_t(this->end() - I) >= NumToInsert) { + T* OldEnd = this->end(); + append( + std::move_iterator(this->end() - NumToInsert), + std::move_iterator(this->end())); + + // Copy the existing elements that get replaced. + std::move_backward(I, OldEnd - NumToInsert, OldEnd); + + // If we just moved the element we're inserting, be sure to update + // the reference (never happens if TakesParamByValue). + if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end()) + EltPtr += NumToInsert; + + std::fill_n(I, NumToInsert, *EltPtr); + return I; + } + + // Otherwise, we're inserting more elements than exist already, and we're + // not inserting at the end. + + // Move over the elements that we're about to overwrite. + T* OldEnd = this->end(); + this->set_size(this->size() + NumToInsert); + size_t NumOverwritten = OldEnd - I; + this->uninitialized_move(I, OldEnd, this->end() - NumOverwritten); + + // If we just moved the element we're inserting, be sure to update + // the reference (never happens if TakesParamByValue). + if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end()) + EltPtr += NumToInsert; + + // Replace the overwritten part. + std::fill_n(I, NumOverwritten, *EltPtr); + + // Insert the non-overwritten middle part. + std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr); + return I; + } + + template < + typename ItTy, + typename = std::enable_if_t::iterator_category, + std::input_iterator_tag>>> + iterator insert(iterator I, ItTy From, ItTy To) { + // Convert iterator to elt# to avoid invalidating iterator when we reserve() + size_t InsertElt = I - this->begin(); + + if (I == this->end()) { // Important special case for empty vector. + append(From, To); + return this->begin() + InsertElt; + } + + assert( + this->isReferenceToStorage(I) && + "Insertion iterator is out of bounds."); + + // Check that the reserve that follows doesn't invalidate the iterators. + this->assertSafeToAddRange(From, To); + + size_t NumToInsert = std::distance(From, To); + + // Ensure there is enough space. + reserve(this->size() + NumToInsert); + + // Uninvalidate the iterator. + I = this->begin() + InsertElt; + + // If there are more elements between the insertion point and the end of the + // range than there are being inserted, we can use a simple approach to + // insertion. Since we already reserved space, we know that this won't + // reallocate the vector. + if (size_t(this->end() - I) >= NumToInsert) { + T* OldEnd = this->end(); + append( + std::move_iterator(this->end() - NumToInsert), + std::move_iterator(this->end())); + + // Copy the existing elements that get replaced. + std::move_backward(I, OldEnd - NumToInsert, OldEnd); + + std::copy(From, To, I); + return I; + } + + // Otherwise, we're inserting more elements than exist already, and we're + // not inserting at the end. + + // Move over the elements that we're about to overwrite. + T* OldEnd = this->end(); + this->set_size(this->size() + NumToInsert); + size_t NumOverwritten = OldEnd - I; + this->uninitialized_move(I, OldEnd, this->end() - NumOverwritten); + + // Replace the overwritten part. + for (T* J = I; NumOverwritten > 0; --NumOverwritten) { + *J = *From; + ++J; + ++From; + } + + // Insert the non-overwritten middle part. + this->uninitialized_copy(From, To, OldEnd); + return I; + } + + void insert(iterator I, std::initializer_list IL) { + insert(I, IL.begin(), IL.end()); + } + + template + reference emplace_back(ArgTypes&&... Args) { + if (C10_UNLIKELY(this->size() >= this->capacity())) + return this->growAndEmplaceBack(std::forward(Args)...); + + ::new ((void*)this->end()) T(std::forward(Args)...); + this->set_size(this->size() + 1); + return this->back(); + } + + SmallVectorImpl& operator=(const SmallVectorImpl& RHS); + + SmallVectorImpl& operator=(SmallVectorImpl&& RHS) noexcept( + std::is_nothrow_move_constructible_v && + std::is_nothrow_destructible_v); + + bool operator==(const SmallVectorImpl& RHS) const { + if (this->size() != RHS.size()) + return false; + return std::equal(this->begin(), this->end(), RHS.begin()); + } + bool operator!=(const SmallVectorImpl& RHS) const { + return !(*this == RHS); + } + + bool operator<(const SmallVectorImpl& RHS) const { + return std::lexicographical_compare( + this->begin(), this->end(), RHS.begin(), RHS.end()); + } +}; + +template +void SmallVectorImpl::swap(SmallVectorImpl& RHS) noexcept { + if (this == &RHS) + return; + + // We can only avoid copying elements if neither vector is small. + if (!this->isSmall() && !RHS.isSmall()) { + std::swap(this->BeginX, RHS.BeginX); + std::swap(this->Size, RHS.Size); + std::swap(this->Capacity, RHS.Capacity); + return; + } + this->reserve(RHS.size()); + RHS.reserve(this->size()); + + // Swap the shared elements. + size_t NumShared = this->size(); + if (NumShared > RHS.size()) + NumShared = RHS.size(); + for (size_type i = 0; i != NumShared; ++i) + std::swap((*this)[i], RHS[i]); + + // Copy over the extra elts. + if (this->size() > RHS.size()) { + size_t EltDiff = this->size() - RHS.size(); + this->uninitialized_copy(this->begin() + NumShared, this->end(), RHS.end()); + RHS.set_size(RHS.size() + EltDiff); + this->destroy_range(this->begin() + NumShared, this->end()); + this->set_size(NumShared); + } else if (RHS.size() > this->size()) { + size_t EltDiff = RHS.size() - this->size(); + this->uninitialized_copy(RHS.begin() + NumShared, RHS.end(), this->end()); + this->set_size(this->size() + EltDiff); + this->destroy_range(RHS.begin() + NumShared, RHS.end()); + RHS.set_size(NumShared); + } +} + +template +SmallVectorImpl& SmallVectorImpl::operator=( + const SmallVectorImpl& RHS) { + // Avoid self-assignment. + if (this == &RHS) + return *this; + + // If we already have sufficient space, assign the common elements, then + // destroy any excess. + size_t RHSSize = RHS.size(); + size_t CurSize = this->size(); + if (CurSize >= RHSSize) { + // Assign common elements. + iterator NewEnd; + if (RHSSize) + NewEnd = std::copy(RHS.begin(), RHS.begin() + RHSSize, this->begin()); + else + NewEnd = this->begin(); + + // Destroy excess elements. + this->destroy_range(NewEnd, this->end()); + + // Trim. + this->set_size(RHSSize); + return *this; + } + + // If we have to grow to have enough elements, destroy the current elements. + // This allows us to avoid copying them during the grow. + // FIXME: don't do this if they're efficiently moveable. + if (this->capacity() < RHSSize) { + // Destroy current elements. + this->clear(); + CurSize = 0; + this->grow(RHSSize); + } else if (CurSize) { + // Otherwise, use assignment for the already-constructed elements. + std::copy(RHS.begin(), RHS.begin() + CurSize, this->begin()); + } + + // Copy construct the new elements in place. + this->uninitialized_copy( + RHS.begin() + CurSize, RHS.end(), this->begin() + CurSize); + + // Set end. + this->set_size(RHSSize); + return *this; +} + +template +SmallVectorImpl& SmallVectorImpl:: +operator=(SmallVectorImpl&& RHS) noexcept( + std::is_nothrow_move_constructible_v && + std::is_nothrow_destructible_v) { + // Avoid self-assignment. + if (this == &RHS) + return *this; + + // If the RHS isn't small, clear this vector and then steal its buffer. + if (!RHS.isSmall()) { + this->destroy_range(this->begin(), this->end()); + if (!this->isSmall()) + free(this->begin()); + this->BeginX = RHS.BeginX; + this->Size = RHS.Size; + this->Capacity = RHS.Capacity; + RHS.resetToSmall(); + return *this; + } + + // If we already have sufficient space, assign the common elements, then + // destroy any excess. + size_t RHSSize = RHS.size(); + size_t CurSize = this->size(); + if (CurSize >= RHSSize) { + // Assign common elements. + iterator NewEnd = this->begin(); + if (RHSSize) + NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd); + + // Destroy excess elements and trim the bounds. + this->destroy_range(NewEnd, this->end()); + this->set_size(RHSSize); + + // Clear the RHS. + RHS.clear(); + + return *this; + } + + // If we have to grow to have enough elements, destroy the current elements. + // This allows us to avoid copying them during the grow. + // FIXME: this may not actually make any sense if we can efficiently move + // elements. + if (this->capacity() < RHSSize) { + // Destroy current elements. + this->clear(); + CurSize = 0; + this->grow(RHSSize); + } else if (CurSize) { + // Otherwise, use assignment for the already-constructed elements. + std::move(RHS.begin(), RHS.begin() + CurSize, this->begin()); + } + + // Move-construct the new elements in place. + this->uninitialized_move( + RHS.begin() + CurSize, RHS.end(), this->begin() + CurSize); + + // Set end. + this->set_size(RHSSize); + + RHS.clear(); + return *this; +} + +/// Storage for the SmallVector elements. This is specialized for the N=0 case +/// to avoid allocating unnecessary storage. +template +struct SmallVectorStorage { + alignas(T) char InlineElts[N * sizeof(T)]; +}; + +/// We need the storage to be properly aligned even for small-size of 0 so that +/// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is +/// well-defined. +template +struct alignas(T) SmallVectorStorage {}; + +/// Forward declaration of SmallVector so that +/// calculateSmallVectorDefaultInlinedElements can reference +/// `sizeof(SmallVector)`. +template +class /* LLVM_GSL_OWNER */ SmallVector; + +/// Helper class for calculating the default number of inline elements for +/// `SmallVector`. +/// +/// This should be migrated to a constexpr function when our minimum +/// compiler support is enough for multi-statement constexpr functions. +template +struct CalculateSmallVectorDefaultInlinedElements { + // Parameter controlling the default number of inlined elements + // for `SmallVector`. + // + // The default number of inlined elements ensures that + // 1. There is at least one inlined element. + // 2. `sizeof(SmallVector) <= kPreferredSmallVectorSizeof` unless + // it contradicts 1. + static constexpr size_t kPreferredSmallVectorSizeof = 64; + + // static_assert that sizeof(T) is not "too big". + // + // Because our policy guarantees at least one inlined element, it is possible + // for an arbitrarily large inlined element to allocate an arbitrarily large + // amount of inline storage. We generally consider it an antipattern for a + // SmallVector to allocate an excessive amount of inline storage, so we want + // to call attention to these cases and make sure that users are making an + // intentional decision if they request a lot of inline storage. + // + // We want this assertion to trigger in pathological cases, but otherwise + // not be too easy to hit. To accomplish that, the cutoff is actually somewhat + // larger than kPreferredSmallVectorSizeof (otherwise, + // `SmallVector>` would be one easy way to trip it, and that + // pattern seems useful in practice). + // + // One wrinkle is that this assertion is in theory non-portable, since + // sizeof(T) is in general platform-dependent. However, we don't expect this + // to be much of an issue, because most LLVM development happens on 64-bit + // hosts, and therefore sizeof(T) is expected to *decrease* when compiled for + // 32-bit hosts, dodging the issue. The reverse situation, where development + // happens on a 32-bit host and then fails due to sizeof(T) *increasing* on a + // 64-bit host, is expected to be very rare. + static_assert( + sizeof(T) <= 256, + "You are trying to use a default number of inlined elements for " + "`SmallVector` but `sizeof(T)` is really big! Please use an " + "explicit number of inlined elements with `SmallVector` to make " + "sure you really want that much inline storage."); + + // Discount the size of the header itself when calculating the maximum inline + // bytes. + static constexpr size_t PreferredInlineBytes = + kPreferredSmallVectorSizeof - sizeof(SmallVector); + static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T); + static constexpr size_t value = + NumElementsThatFit == 0 ? 1 : NumElementsThatFit; +}; + +/// This is a 'vector' (really, a variable-sized array), optimized +/// for the case when the array is small. It contains some number of elements +/// in-place, which allows it to avoid heap allocation when the actual number of +/// elements is below that threshold. This allows normal "small" cases to be +/// fast without losing generality for large inputs. +/// +/// \note +/// In the absence of a well-motivated choice for the number of inlined +/// elements \p N, it is recommended to use \c SmallVector (that is, +/// omitting the \p N). This will choose a default number of inlined elements +/// reasonable for allocation on the stack (for example, trying to keep \c +/// sizeof(SmallVector) around 64 bytes). +/// +/// \warning This does not attempt to be exception safe. +/// +/// \see https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h +template < + typename T, + unsigned N = CalculateSmallVectorDefaultInlinedElements::value> +class /* LLVM_GSL_OWNER */ SmallVector : public SmallVectorImpl, + SmallVectorStorage { + public: + SmallVector() : SmallVectorImpl(N) {} + + ~SmallVector() { + // Destroy the constructed elements in the vector. + this->destroy_range(this->begin(), this->end()); + } + + explicit SmallVector(size_t Size, const T& Value = T()) + : SmallVectorImpl(N) { + this->assign(Size, Value); + } + + template < + typename ItTy, + typename = std::enable_if_t::iterator_category, + std::input_iterator_tag>>> + SmallVector(ItTy S, ItTy E) : SmallVectorImpl(N) { + this->append(S, E); + } + + // note: The enable_if restricts Container to types that have a .begin() and + // .end() that return valid input iterators. + template < + typename Container, + std::enable_if_t< + std::is_convertible_v< + typename std::iterator_traits< + decltype(std::declval() + .begin())>::iterator_category, + std::input_iterator_tag> && + std::is_convertible_v< + typename std::iterator_traits< + decltype(std::declval() + .end())>::iterator_category, + std::input_iterator_tag>, + int> = 0> + explicit SmallVector(Container&& c) : SmallVectorImpl(N) { + this->append(c.begin(), c.end()); + } + + SmallVector(std::initializer_list IL) : SmallVectorImpl(N) { + this->assign(IL); + } + + SmallVector(const SmallVector& RHS) : SmallVectorImpl(N) { + if (!RHS.empty()) + SmallVectorImpl::operator=(RHS); + } + + SmallVector& operator=(const SmallVector& RHS) { + SmallVectorImpl::operator=(RHS); + return *this; + } + + SmallVector(SmallVector&& RHS) noexcept( + std::is_nothrow_move_assignable_v>) + : SmallVectorImpl(N) { + if (!RHS.empty()) + SmallVectorImpl::operator=(::std::move(RHS)); + } + + // note: The enable_if restricts Container to types that have a .begin() and + // .end() that return valid input iterators. + template < + typename Container, + std::enable_if_t< + std::is_convertible_v< + typename std::iterator_traits< + decltype(std::declval() + .begin())>::iterator_category, + std::input_iterator_tag> && + std::is_convertible_v< + typename std::iterator_traits< + decltype(std::declval() + .end())>::iterator_category, + std::input_iterator_tag>, + int> = 0> + SmallVector& operator=(const Container& RHS) { + this->assign(RHS.begin(), RHS.end()); + return *this; + } + + SmallVector(SmallVectorImpl&& RHS) noexcept( + std::is_nothrow_move_assignable_v>) + : SmallVectorImpl(N) { + if (!RHS.empty()) + SmallVectorImpl::operator=(::std::move(RHS)); + } + + SmallVector& operator=(SmallVector&& RHS) noexcept( + std::is_nothrow_move_assignable_v>) { + SmallVectorImpl::operator=(::std::move(RHS)); + return *this; + } + + SmallVector& operator=(SmallVectorImpl&& RHS) noexcept( + std::is_nothrow_move_constructible_v>) { + SmallVectorImpl::operator=(::std::move(RHS)); + return *this; + } + + // note: The enable_if restricts Container to types that have a .begin() and + // .end() that return valid input iterators. + template < + typename Container, + std::enable_if_t< + std::is_convertible_v< + typename std::iterator_traits< + decltype(std::declval() + .begin())>::iterator_category, + std::input_iterator_tag> && + std::is_convertible_v< + typename std::iterator_traits< + decltype(std::declval() + .end())>::iterator_category, + std::input_iterator_tag>, + int> = 0> + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) + SmallVector& operator=(Container&& C) { + this->assign(C.begin(), C.end()); + return *this; + } + + SmallVector& operator=(std::initializer_list IL) { + this->assign(IL); + return *this; + } +}; + +template +inline size_t capacity_in_bytes(const SmallVector& X) { + return X.capacity_in_bytes(); +} + +template +std::ostream& operator<<(std::ostream& out, const SmallVector& list) { + int i = 0; + out << '['; + for (auto e : list) { + if (i++ > 0) + out << ", "; + out << e; + } + out << ']'; + return out; +} + +template +using ValueTypeFromRangeType = std::remove_const_t< + std::remove_reference_t()))>>; + +/// Given a range of type R, iterate the entire range and return a +/// SmallVector with elements of the vector. This is useful, for example, +/// when you want to iterate a range and then sort the results. +template +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +SmallVector, Size> to_vector(R&& Range) { + return {std::begin(Range), std::end(Range)}; +} +template +SmallVector< + ValueTypeFromRangeType, + CalculateSmallVectorDefaultInlinedElements< + ValueTypeFromRangeType>::value> +// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) +to_vector(R&& Range) { + return {std::begin(Range), std::end(Range)}; +} + +} // end namespace c10 + +namespace std { + +/// Implement std::swap in terms of SmallVector swap. +template +inline void swap( + c10::SmallVectorImpl& LHS, + c10::SmallVectorImpl& RHS) noexcept { + LHS.swap(RHS); +} + +/// Implement std::swap in terms of SmallVector swap. +template +inline void swap( + c10::SmallVector& LHS, + c10::SmallVector& RHS) noexcept { + LHS.swap(RHS); +} + +} // end namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/StringUtil.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/StringUtil.h new file mode 100644 index 0000000000000000000000000000000000000000..55c24487cb8deabc8059100b45f02aa2b162e3c7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/StringUtil.h @@ -0,0 +1,274 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_STRINGUTIL_H_ +#define C10_UTIL_STRINGUTIL_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +C10_CLANG_DIAGNOSTIC_PUSH() +#if C10_CLANG_HAS_WARNING("-Wshorten-64-to-32") +C10_CLANG_DIAGNOSTIC_IGNORE("-Wshorten-64-to-32") +#endif + +namespace c10 { + +namespace detail { + +// Obtains the base name from a full path. +C10_API std::string StripBasename(const std::string& full_path); + +C10_API std::string ExcludeFileExtension(const std::string& full_path); + +struct CompileTimeEmptyString { + operator const std::string&() const { + static const std::string empty_string_literal; + return empty_string_literal; + } + operator const char*() const { + return ""; + } +}; + +template +struct CanonicalizeStrTypes { + using type = const T&; +}; + +template +// NOLINTNEXTLINE(*c-arrays*) +struct CanonicalizeStrTypes { + using type = const char*; +}; + +inline std::ostream& _str(std::ostream& ss) { + return ss; +} + +template +struct Streamable : std::false_type {}; + +template +struct Streamable() << T{})> + : std::true_type {}; + +template +inline std::ostream& _str(std::ostream& ss, const T& t) { + if constexpr (std::is_enum_v && !Streamable::value) { + // NOLINTNEXTLINE(modernize-type-traits) + return _str(ss, static_cast::type>(t)); + } else { + // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) + ss << t; + return ss; + } +} + +template +inline std::ostream& _str(std::ostream& ss, const std::optional& t) { + if (t.has_value()) { + return _str(ss, t.value()); + } + ss << "std::nullopt"; + return ss; +} +// Overloads of _str for wide types; forces narrowing. +C10_API std::ostream& _str(std::ostream& ss, const wchar_t* wCStr); +C10_API std::ostream& _str(std::ostream& ss, const wchar_t& wChar); +C10_API std::ostream& _str(std::ostream& ss, const std::wstring& wString); + +template <> +inline std::ostream& _str( + std::ostream& ss, + const CompileTimeEmptyString& /*unused*/) { + return ss; +} + +template +inline std::ostream& _str(std::ostream& ss, const T& t, const Args&... args) { + return _str(_str(ss, t), args...); +} + +template +struct _str_wrapper final { + static std::string call(const Args&... args) { + std::ostringstream ss; + _str(ss, args...); + return ss.str(); + } +}; + +// Specializations for already-a-string types. +template <> +struct _str_wrapper final { + // return by reference to avoid the binary size of a string copy + static const std::string& call(const std::string& str) { + return str; + } +}; + +template <> +struct _str_wrapper final { + static const char* call(const char* str) { + return str; + } +}; + +// For c10::str() with an empty argument list (which is common in our assert +// macros), we don't want to pay the binary size for constructing and +// destructing a stringstream or even constructing a string. +template <> +struct _str_wrapper<> final { + static CompileTimeEmptyString call() { + return CompileTimeEmptyString(); + } +}; + +} // namespace detail + +// Convert a list of string-like arguments into a single string. +template +inline auto str(const Args&... args) { + return detail::_str_wrapper< + typename detail::CanonicalizeStrTypes::type...>::call(args...); +} + +template +inline std::string Join(const std::string& delimiter, const Container& v) { + std::stringstream s; + int cnt = static_cast(v.size()) - 1; + for (auto i = v.begin(); i != v.end(); ++i, --cnt) { + s << (*i) << (cnt ? delimiter : ""); + } + return std::move(s).str(); +} + +// Replace all occurrences of "from" substring to "to" string. +// Returns number of replacements +size_t C10_API +ReplaceAll(std::string& s, std::string_view from, std::string_view to); + +/// Represents a location in source code (for debugging). +struct C10_API SourceLocation { + const char* function; + const char* file; + uint32_t line; + + static constexpr SourceLocation current( + const char* file = __builtin_FILE(), + const char* function = __builtin_FUNCTION(), + const std::uint_least32_t line = __builtin_LINE()) noexcept { + return {function, file, line}; + } +}; + +std::ostream& operator<<(std::ostream& out, const SourceLocation& loc); + +// unix isprint but insensitive to locale +inline bool isPrint(char s) { + return s > 0x1f && s < 0x7f; +} + +inline void printQuotedString(std::ostream& stmt, const std::string_view str) { + stmt << '"'; + for (auto s : str) { + switch (s) { + case '\\': + stmt << "\\\\"; + break; + case '\'': + stmt << "\\'"; + break; + case '\"': + stmt << "\\\""; + break; + case '\a': + stmt << "\\a"; + break; + case '\b': + stmt << "\\b"; + break; + case '\f': + stmt << "\\f"; + break; + case '\n': + stmt << "\\n"; + break; + case '\r': + stmt << "\\r"; + break; + case '\t': + stmt << "\\t"; + break; + case '\v': + stmt << "\\v"; + break; + default: + if (isPrint(s)) { + stmt << s; + } else { + // C++ io has stateful formatting settings. Messing with + // them is probably worse than doing this manually. + // NOLINTNEXTLINE(*c-arrays*) + char buf[4] = "000"; + // NOLINTNEXTLINE(*narrowing-conversions) + buf[2] += s % 8; + s /= 8; + // NOLINTNEXTLINE(*narrowing-conversions) + buf[1] += s % 8; + s /= 8; + // NOLINTNEXTLINE(*narrowing-conversions) + buf[0] += s; + stmt << "\\" << buf; + } + break; + } + } + stmt << '"'; +} + +template +std::optional tryToNumber(const char* symbol) = delete; +template +std::optional tryToNumber(const std::string& symbol) = delete; + +/* + * Convert a string to a 64 bit integer. Trailing whitespaces are not supported. + * Similarly, integer string with trailing characters like "123abc" will be + * rejected. + */ +template <> +C10_API std::optional tryToNumber(const char* symbol); +template <> +C10_API std::optional tryToNumber(const std::string& symbol); + +/* + * Convert a string to a double. Trailing whitespaces are not supported. + * Similarly, integer string with trailing characters like "123abc" will + * be rejected. + */ +template <> +C10_API std::optional tryToNumber(const char* symbol); +template <> +C10_API std::optional tryToNumber(const std::string& symbol); + +C10_API std::vector split( + std::string_view target, + char delimiter); +} // namespace c10 + +C10_CLANG_DIAGNOSTIC_POP() + +#endif // C10_UTIL_STRINGUTIL_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Synchronized.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Synchronized.h new file mode 100644 index 0000000000000000000000000000000000000000..c78564263ebfe172abcb5c097a8c222606e8f019 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Synchronized.h @@ -0,0 +1,67 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace c10 { + +/** + * A very simple Synchronization class for error-free use of data + * in a multi-threaded context. See folly/docs/Synchronized.md for + * the inspiration of this class. + * + * Full URL: + * https://github.com/facebook/folly/blob/main/folly/docs/Synchronized.md + * + * This class implements a small subset of the generic functionality + * implemented by folly:Synchronized. Specifically, only withLock + * is implemented here since it's the smallest possible API that is + * able to cover a large surface area of functionality offered by + * folly::Synchronized. + */ +template +class Synchronized final { + mutable std::mutex mutex_; + T data_; + + public: + Synchronized() = default; + Synchronized(T const& data) : data_(data) {} + Synchronized(T&& data) : data_(std::move(data)) {} + + // Don't permit copy construction, move, assignment, or + // move assignment, since the underlying std::mutex + // isn't necessarily copyable/moveable. + Synchronized(Synchronized const&) = delete; + Synchronized(Synchronized&&) = delete; + Synchronized operator=(Synchronized const&) = delete; + Synchronized operator=(Synchronized&&) = delete; + ~Synchronized() = default; + + /** + * To use, call withLock with a callback that accepts T either + * by copy or by reference. Use the protected variable in the + * provided callback safely. + */ + template + auto withLock(CB&& cb) { + std::lock_guard guard(this->mutex_); + return std::forward(cb)(this->data_); + } + + /** + * To use, call withLock with a callback that accepts T either + * by copy or by const reference. Use the protected variable in + * the provided callback safely. + */ + template + auto withLock(CB&& cb) const { + std::lock_guard guard(this->mutex_); + return std::forward(cb)(this->data_); + } +}; +} // end namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ThreadLocal.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ThreadLocal.h new file mode 100644 index 0000000000000000000000000000000000000000..e5b92117a67fed4731ba92dc0b116b6c5aa80bcd --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ThreadLocal.h @@ -0,0 +1,161 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +/** + * Android versions with libgnustl incorrectly handle thread_local C++ + * qualifier with composite types. NDK up to r17 version is affected. + * + * (A fix landed on Jun 4 2018: + * https://android-review.googlesource.com/c/toolchain/gcc/+/683601) + * + * In such cases, use c10::ThreadLocal wrapper + * which is `pthread_*` based with smart pointer semantics. + * + * In addition, convenient macro C10_DEFINE_TLS_static is available. + * To define static TLS variable of type std::string, do the following + * ``` + * C10_DEFINE_TLS_static(std::string, str_tls_); + * /////// + * { + * *str_tls_ = "abc"; + * assert(str_tls_->length(), 3); + * } + * ``` + * + * (see c10/test/util/ThreadLocal_test.cpp for more examples) + */ +#if !defined(C10_PREFER_CUSTOM_THREAD_LOCAL_STORAGE) + +#if defined(C10_ANDROID) && defined(__GLIBCXX__) && __GLIBCXX__ < 20180604 +#define C10_PREFER_CUSTOM_THREAD_LOCAL_STORAGE +#endif // defined(C10_ANDROID) && defined(__GLIBCXX__) && __GLIBCXX__ < 20180604 + +#endif // !defined(C10_PREFER_CUSTOM_THREAD_LOCAL_STORAGE) + +#if defined(C10_PREFER_CUSTOM_THREAD_LOCAL_STORAGE) +#include +#include +#include +#include +namespace c10 { + +/** + * @brief Temporary thread_local C++ qualifier replacement for Android + * based on `pthread_*`. + * To be used with composite types that provide default ctor. + */ +template +class ThreadLocal { + public: + ThreadLocal() { + pthread_key_create( + &key_, [](void* buf) { delete static_cast(buf); }); + } + + ~ThreadLocal() { + if (void* current = pthread_getspecific(key_)) { + delete static_cast(current); + } + + pthread_key_delete(key_); + } + + ThreadLocal(const ThreadLocal&) = delete; + ThreadLocal& operator=(const ThreadLocal&) = delete; + + Type& get() { + if (void* current = pthread_getspecific(key_)) { + return *static_cast(current); + } + + std::unique_ptr ptr = std::make_unique(); + if (0 == pthread_setspecific(key_, ptr.get())) { + return *ptr.release(); + } + + int err = errno; + TORCH_INTERNAL_ASSERT(false, "pthread_setspecific() failed, errno = ", err); + } + + Type& operator*() { + return get(); + } + + Type* operator->() { + return &get(); + } + + private: + pthread_key_t key_; +}; + +} // namespace c10 + +#define C10_DEFINE_TLS_static(Type, Name) static ::c10::ThreadLocal Name + +#define C10_DECLARE_TLS_class_static(Class, Type, Name) \ + static ::c10::ThreadLocal Name + +#define C10_DEFINE_TLS_class_static(Class, Type, Name) \ + ::c10::ThreadLocal Class::Name + +#else // defined(C10_PREFER_CUSTOM_THREAD_LOCAL_STORAGE) + +namespace c10 { + +/** + * @brief Default thread_local implementation for non-Android cases. + * To be used with composite types that provide default ctor. + */ +template +class ThreadLocal { + public: + using Accessor = Type* (*)(); + explicit ThreadLocal(Accessor accessor) : accessor_(accessor) {} + + ThreadLocal(const ThreadLocal&) = delete; + ThreadLocal(ThreadLocal&&) noexcept = default; + ThreadLocal& operator=(const ThreadLocal&) = delete; + ThreadLocal& operator=(ThreadLocal&&) noexcept = default; + ~ThreadLocal() = default; + + Type& get() { + return *accessor_(); + } + + Type& operator*() { + return get(); + } + + Type* operator->() { + return &get(); + } + + private: + Accessor accessor_; +}; + +} // namespace c10 + +#define C10_DEFINE_TLS_static(Type, Name) \ + static ::c10::ThreadLocal Name([]() { \ + static thread_local Type var; \ + return &var; \ + }) + +#define C10_DECLARE_TLS_class_static(Class, Type, Name) \ + static ::c10::ThreadLocal Name + +#define C10_DEFINE_TLS_class_static(Class, Type, Name) \ + ::c10::ThreadLocal Class::Name([]() { \ + static thread_local Type var; \ + return &var; \ + }) + +#endif // defined(C10_PREFER_CUSTOM_THREAD_LOCAL_STORAGE) + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ThreadLocalDebugInfo.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ThreadLocalDebugInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..03ba6f5b39ba567f65bfa375df66c413a88c171b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ThreadLocalDebugInfo.h @@ -0,0 +1,90 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include +#include + +namespace c10 { + +enum class C10_API_ENUM DebugInfoKind : uint8_t { + PRODUCER_INFO = 0, + MOBILE_RUNTIME_INFO, + PROFILER_STATE, + INFERENCE_CONTEXT, // for inference usage + PARAM_COMMS_INFO, + + TEST_INFO, // used only in tests + TEST_INFO_2, // used only in tests +}; + +class C10_API DebugInfoBase { + public: + DebugInfoBase() = default; + virtual ~DebugInfoBase() = default; +}; + +// Thread local debug information is propagated across the forward +// (including async fork tasks) and backward passes and is supposed +// to be utilized by the user's code to pass extra information from +// the higher layers (e.g. model id) down to the lower levels +// (e.g. to the operator observers used for debugging, logging, +// profiling, etc) +class C10_API ThreadLocalDebugInfo { + public: + static DebugInfoBase* get(DebugInfoKind kind); + + // Get current ThreadLocalDebugInfo + static std::shared_ptr current(); + + // Internal, use DebugInfoGuard/ThreadLocalStateGuard + static void _forceCurrentDebugInfo( + std::shared_ptr info); + + // Push debug info struct of a given kind + static void _push(DebugInfoKind kind, std::shared_ptr info); + // Pop debug info, throws in case the last pushed + // debug info is not of a given kind + static std::shared_ptr _pop(DebugInfoKind kind); + // Peek debug info, throws in case the last pushed debug info is not of the + // given kind + static std::shared_ptr _peek(DebugInfoKind kind); + + private: + std::shared_ptr info_; + DebugInfoKind kind_; + std::shared_ptr parent_info_; + + friend class DebugInfoGuard; +}; + +// DebugInfoGuard is used to set debug information, +// ThreadLocalDebugInfo is semantically immutable, the values are set +// through the scope-based guard object. +// Nested DebugInfoGuard adds/overrides existing values in the scope, +// restoring the original values after exiting the scope. +// Users can access the values through the ThreadLocalDebugInfo::get() call; +class C10_API DebugInfoGuard { + public: + DebugInfoGuard(DebugInfoKind kind, std::shared_ptr info); + + explicit DebugInfoGuard(std::shared_ptr info); + + ~DebugInfoGuard(); + + DebugInfoGuard(const DebugInfoGuard&) = delete; + DebugInfoGuard(DebugInfoGuard&&) = delete; + DebugInfoGuard& operator=(const DebugInfoGuard&) = delete; + DebugInfoGuard& operator=(DebugInfoGuard&&) = delete; + + private: + bool active_ = false; + std::shared_ptr prev_info_ = nullptr; +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Type.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Type.h new file mode 100644 index 0000000000000000000000000000000000000000..9f460d4bde11da8629abece4d994a800e7918fc4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Type.h @@ -0,0 +1,35 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_TYPE_H_ +#define C10_UTIL_TYPE_H_ + +#include +#include +#ifdef __GXX_RTTI +#include +#endif // __GXX_RTTI + +#include + +namespace c10 { + +/// Utility to demangle a C++ symbol name. +C10_API std::string demangle(const char* name); + +/// Returns the printable name of the type. +template +inline const char* demangle_type() { +#ifdef __GXX_RTTI + static const auto& name = *(new std::string(demangle(typeid(T).name()))); + return name.c_str(); +#else // __GXX_RTTI + return "(RTTI disabled, cannot show name)"; +#endif // __GXX_RTTI +} + +} // namespace c10 + +#endif // C10_UTIL_TYPE_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeCast.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeCast.h new file mode 100644 index 0000000000000000000000000000000000000000..1d95fd90929796735962e4fb4fe1855cda857ac5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeCast.h @@ -0,0 +1,215 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +C10_CLANG_DIAGNOSTIC_PUSH() +#if C10_CLANG_HAS_WARNING("-Wimplicit-float-conversion") +C10_CLANG_DIAGNOSTIC_IGNORE("-Wimplicit-float-conversion") +#endif +#if C10_CLANG_HAS_WARNING("-Wimplicit-int-float-conversion") +C10_CLANG_DIAGNOSTIC_IGNORE("-Wimplicit-int-float-conversion") +#endif + +namespace c10 { + +template +struct needs_real { + constexpr static bool value = + (is_complex::value && !is_complex::value); +}; + +template +struct maybe_real { + C10_HOST_DEVICE static inline src_t apply(src_t src) { + return src; + } +}; + +template +struct maybe_real { + C10_HOST_DEVICE static inline decltype(auto) apply(src_t src) { + return src.real(); + } +}; + +template +struct maybe_bool { + C10_HOST_DEVICE static inline src_t apply(src_t src) { + return src; + } +}; + +template +struct maybe_bool { + C10_HOST_DEVICE static inline decltype(auto) apply(src_t src) { + // Don't use bool operator so as to also compile for ComplexHalf. + return src.real() || src.imag(); + } +}; + +// Note: deliberately ignores undefined behavior, consistent with NumPy. +// PyTorch's type conversions can cause a variety of undefined behavior, +// including float to integral overflow and signed to unsigned integer overflow. +// Some of this undefined behavior is addressed below. +template +struct static_cast_with_inter_type { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline dest_t apply( + src_t src) { + constexpr bool real = needs_real::value; + auto r = maybe_real::apply(src); + return static_cast(r); + } +}; + +// Partial template specialization for casting to bool. +// Need to handle complex types separately, as we don't +// simply want to cast the real part to bool. +template +struct static_cast_with_inter_type { + C10_HOST_DEVICE static inline bool apply(src_t src) { + constexpr bool complex = needs_real::value; + return static_cast(maybe_bool::apply(src)); + } +}; + +// Partial template instantiation for casting to uint8. +// Note: Converting from negative float values to unsigned integer types is +// undefined behavior in C++, and current CPU and GPU compilers exhibit +// divergent behavior. Casting from negative float values to signed +// integer types and then to unsigned integer types is not undefined, +// however, so this cast improves the consistency of type conversions +// to uint8 across compilers. +// Further note: Type conversions across compilers still have other undefined +// and divergent behavior. +template +struct static_cast_with_inter_type { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline uint8_t apply( + src_t src) { + constexpr bool real = needs_real::value; + return static_cast( + static_cast(maybe_real::apply(src))); + } +}; + +template <> +struct static_cast_with_inter_type, c10::BFloat16> { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline c10::complex< + c10::Half> + apply(c10::BFloat16 src) { + return static_cast>(c10::complex{src}); + } +}; + +template <> +struct static_cast_with_inter_type, c10::Float8_e5m2> { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline c10::complex< + c10::Half> + apply(c10::Float8_e5m2 src) { + return static_cast>(c10::complex{src}); + } +}; + +template <> +struct static_cast_with_inter_type< + c10::complex, + c10::Float8_e5m2fnuz> { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline c10::complex< + c10::Half> + apply(c10::Float8_e5m2fnuz src) { + return static_cast>(c10::complex{src}); + } +}; + +template <> +struct static_cast_with_inter_type< + c10::complex, + c10::Float8_e4m3fn> { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline c10::complex< + c10::Half> + apply(c10::Float8_e4m3fn src) { + return static_cast>(c10::complex{src}); + } +}; + +template <> +struct static_cast_with_inter_type< + c10::complex, + c10::Float8_e4m3fnuz> { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline c10::complex< + c10::Half> + apply(c10::Float8_e4m3fnuz src) { + return static_cast>(c10::complex{src}); + } +}; + +// TODO(#146647): Can we make all these template specialization happen +// based off our apply macros? +template <> +struct static_cast_with_inter_type< + c10::complex, + c10::Float8_e8m0fnu> { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline c10::complex< + c10::Half> + apply(c10::Float8_e8m0fnu src) { + return static_cast>(c10::complex{src}); + } +}; + +template <> +struct static_cast_with_inter_type, c10::Half> { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline c10::complex< + c10::Half> + apply(c10::Half src) { + return static_cast>(c10::complex{src}); + } +}; + +template <> +struct static_cast_with_inter_type< + c10::complex, + c10::complex> { + C10_HOST_DEVICE __ubsan_ignore_undefined__ static inline c10::complex< + c10::Half> + apply(c10::complex src) { + return static_cast>( + static_cast>(src)); + } +}; + +template +C10_HOST_DEVICE To convert(From f) { + return static_cast_with_inter_type::apply(f); +} + +// Define separately to avoid being inlined and prevent code-size bloat +[[noreturn]] C10_API void report_overflow(const char* name); + +template +To checked_convert(From f, const char* name) { + // Converting to bool can't overflow so we exclude this case from checking. + if (!std::is_same_v && overflows(f)) { + report_overflow(name); + } + return convert(f); +} + +} // namespace c10 + +C10_CLANG_DIAGNOSTIC_POP() + +// Trigger tests for D25440771. TODO: Remove this line any time you want. + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeIndex.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeIndex.h new file mode 100644 index 0000000000000000000000000000000000000000..fe2282d2973c030f2abb788009acf8ce661f3fd8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeIndex.h @@ -0,0 +1,132 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(FBCODE_CAFFE2) && !defined(C10_NODEPRECATED) +#define C10_TYPENAME_SUPPORTS_CONSTEXPR 1 +#define C10_TYPENAME_CONSTEXPR constexpr +#endif + +namespace c10::util { + +struct type_index final : IdWrapper { + constexpr explicit type_index(uint64_t checksum) : IdWrapper(checksum) {} + + // Allow usage in std::map / std::set + // TODO Disallow this and rather use std::unordered_map/set everywhere + friend constexpr bool operator<(type_index lhs, type_index rhs) noexcept { + return lhs.underlyingId() < rhs.underlyingId(); + } + + friend std::ostream& operator<<(std::ostream& stream, type_index typeId) { + return stream << typeId.underlyingId(); + } +}; + +namespace detail { + +template +inline constexpr c10::c10_string_view fully_qualified_type_name_impl() { +#if defined(_MSC_VER) && !defined(__clang__) + constexpr std::string_view fun_sig = __FUNCSIG__; +#if defined(__NVCC__) + constexpr std::string_view prefix = + "c10::basic_string_view c10::util::detail::fully_qualified_type_name_impl<"; + constexpr std::string_view suffix = ">()"; +#else + constexpr std::string_view prefix = + "class c10::basic_string_view __cdecl c10::util::detail::fully_qualified_type_name_impl<"; + constexpr std::string_view suffix = ">(void)"; +#endif +#elif defined(__clang__) + constexpr std::string_view fun_sig = __PRETTY_FUNCTION__; + constexpr std::string_view prefix = + "c10::c10_string_view c10::util::detail::fully_qualified_type_name_impl() [T = "; + constexpr std::string_view suffix = "]"; +#elif defined(__GNUC__) + constexpr std::string_view fun_sig = __PRETTY_FUNCTION__; + constexpr std::string_view prefix = + "constexpr c10::c10_string_view c10::util::detail::fully_qualified_type_name_impl() [with T = "; + constexpr std::string_view suffix = + "; c10::c10_string_view = c10::basic_string_view]"; +#endif +#if !defined(__CUDA_ARCH__) && !defined(__CUDA_ARCH_LIST__) + static_assert(c10::starts_with( + static_cast(fun_sig), + static_cast(prefix))); + static_assert(c10::ends_with( + static_cast(fun_sig), + static_cast(suffix))); +#endif + return fun_sig.substr( + prefix.size(), fun_sig.size() - prefix.size() - suffix.size()); +} + +#if !defined(__CUDA_ARCH__) && !defined(__CUDA_ARCH_LIST__) +template +inline constexpr uint64_t type_index_impl() { +// Idea: __PRETTY_FUNCTION__ (or __FUNCSIG__ on msvc) contains a qualified name +// of this function, including its template parameter, i.e. including the +// type we want an id for. We use this name and run crc64 on it to get a type +// id. +#if defined(_MSC_VER) && !defined(__clang__) + return crc64(__FUNCSIG__, sizeof(__FUNCSIG__)).checksum(); +#elif defined(__clang__) + return crc64(__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__)).checksum(); +#elif defined(__GNUC__) + return crc64(__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__)).checksum(); +#endif +} +#endif + +} // namespace detail + +template +inline constexpr type_index get_type_index() { +#if !defined(__CUDA_ARCH__) && !defined(__CUDA_ARCH_LIST__) + // To enforce that this is really computed at compile time, we pass the + // type index through std::integral_constant. + return type_index{std::integral_constant< + uint64_t, + detail::type_index_impl>()>::value}; +#else + // There's nothing in theory preventing us from running this on device code + // except for nvcc throwing a compiler error if we enable it. + return (abort(), type_index(0)); +#endif +} + +#if !defined(TORCH_PEDANTIC) +// Use precomputed hashsum for std::string +// Needed to workaround ambiguity in class name resolution +// into __PRETTY_FUNCTION__ when abovementioned class is defined in inlined +// namespace. In multi-ABI C++ library, `std::string` is an alias to +// `std::__cxx11::basic_string` which depending on compiler flags can be +// resolved to `basic_string` either in `std` namespace or in +// `std::__cxx11` one (`__cxx11` is an inline namespace) +template <> +inline constexpr type_index get_type_index() { + // hashsum for std::basic_string + return type_index{4193213214807308375ULL}; +} +#endif + +template +inline constexpr std::string_view get_fully_qualified_type_name() noexcept { + return static_cast( + detail::fully_qualified_type_name_impl()); +} +} // namespace c10::util + +C10_DEFINE_HASH_FOR_IDWRAPPER(c10::util::type_index) + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeList.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeList.h new file mode 100644 index 0000000000000000000000000000000000000000..7386baccad1420dd13c2530c31b52b0344fe5b9e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeList.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeSafeSignMath.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeSafeSignMath.h new file mode 100644 index 0000000000000000000000000000000000000000..f511333fc7d9ca2b9e29fd7512e4cd0cb8776b25 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeSafeSignMath.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeTraits.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeTraits.h new file mode 100644 index 0000000000000000000000000000000000000000..9d49c82cbd8948cdd7bb2b9fd758f7875e5dfdb7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/TypeTraits.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Unicode.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Unicode.h new file mode 100644 index 0000000000000000000000000000000000000000..68d2c2ce7feac15b4fab16f4124e41633433a213 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Unicode.h @@ -0,0 +1,19 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#if defined(_WIN32) +#include +#include +#include +#endif + +namespace c10 { +#if defined(_WIN32) +C10_API std::wstring u8u16(const std::string& str); +C10_API std::string u16u8(const std::wstring& wstr); +#endif +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/UniqueVoidPtr.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/UniqueVoidPtr.h new file mode 100644 index 0000000000000000000000000000000000000000..dc2ba274cb76d7d7b7c810c8cc318abbe412106a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/UniqueVoidPtr.h @@ -0,0 +1,145 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include +#include + +#include +#include + +namespace c10 { + +using DeleterFnPtr = void (*)(void*); + +namespace detail { + +// Does not delete anything +C10_API void deleteNothing(void* /*unused*/); + +// A detail::UniqueVoidPtr is an owning smart pointer like unique_ptr, but +// with three major differences: +// +// 1) It is specialized to void +// +// 2) It is specialized for a function pointer deleter +// void(void* ctx); i.e., the deleter doesn't take a +// reference to the data, just to a context pointer +// (erased as void*). In fact, internally, this pointer +// is implemented as having an owning reference to +// context, and a non-owning reference to data; this is why +// you release_context(), not release() (the conventional +// API for release() wouldn't give you enough information +// to properly dispose of the object later.) +// +// 3) The deleter is guaranteed to be called when the unique +// pointer is destructed and the context is non-null; this is different +// from std::unique_ptr where the deleter is not called if the +// data pointer is null. +// +// Some of the methods have slightly different types than std::unique_ptr +// to reflect this. +// +class UniqueVoidPtr { + private: + // Lifetime tied to ctx_ + void* data_; + std::unique_ptr ctx_; + + public: + UniqueVoidPtr() : data_(nullptr), ctx_(nullptr, &deleteNothing) {} + explicit UniqueVoidPtr(void* data) + : data_(data), ctx_(nullptr, &deleteNothing) {} + UniqueVoidPtr(void* data, void* ctx, DeleterFnPtr ctx_deleter) + : data_(data), ctx_(ctx, ctx_deleter ? ctx_deleter : &deleteNothing) {} + void* operator->() const { + return data_; + } + void clear() { + ctx_ = nullptr; + data_ = nullptr; + } + void* get() const { + return data_; + } + + bool /* success */ unsafe_reset_data_and_ctx(void* new_data_and_ctx) { + if (C10_UNLIKELY(ctx_.get_deleter() != &deleteNothing)) { + return false; + } + // seems quicker than calling the no-op deleter when we reset + // NOLINTNEXTLINE(bugprone-unused-return-value) + ctx_.release(); + ctx_.reset(new_data_and_ctx); + data_ = new_data_and_ctx; + return true; + } + + void* get_context() const { + return ctx_.get(); + } + void* release_context() { + return ctx_.release(); + } + std::unique_ptr&& move_context() { + return std::move(ctx_); + } + [[nodiscard]] bool compare_exchange_deleter( + DeleterFnPtr expected_deleter, + DeleterFnPtr new_deleter) { + if (get_deleter() != expected_deleter) + return false; + ctx_ = std::unique_ptr(ctx_.release(), new_deleter); + return true; + } + + template + T* cast_context(DeleterFnPtr expected_deleter) const { + if (get_deleter() != expected_deleter) + return nullptr; + return static_cast(get_context()); + } + operator bool() const { + return data_ || ctx_; + } + DeleterFnPtr get_deleter() const { + return ctx_.get_deleter(); + } +}; + +// Note [How UniqueVoidPtr is implemented] +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// UniqueVoidPtr solves a common problem for allocators of tensor data, which +// is that the data pointer (e.g., float*) which you are interested in, is not +// the same as the context pointer (e.g., DLManagedTensor) which you need +// to actually deallocate the data. Under a conventional deleter design, you +// have to store extra context in the deleter itself so that you can actually +// delete the right thing. Implementing this with standard C++ is somewhat +// error-prone: if you use a std::unique_ptr to manage tensors, the deleter will +// not be called if the data pointer is nullptr, which can cause a leak if the +// context pointer is non-null (and the deleter is responsible for freeing both +// the data pointer and the context pointer). +// +// So, in our reimplementation of unique_ptr, which just store the context +// directly in the unique pointer, and attach the deleter to the context +// pointer itself. In simple cases, the context pointer is just the pointer +// itself. + +inline bool operator==(const UniqueVoidPtr& sp, std::nullptr_t) noexcept { + return !sp; +} +inline bool operator==(std::nullptr_t, const UniqueVoidPtr& sp) noexcept { + return !sp; +} +inline bool operator!=(const UniqueVoidPtr& sp, std::nullptr_t) noexcept { + return sp; +} +inline bool operator!=(std::nullptr_t, const UniqueVoidPtr& sp) noexcept { + return sp; +} + +} // namespace detail +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Unroll.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Unroll.h new file mode 100644 index 0000000000000000000000000000000000000000..c1470391c8c4ac75f5055848de538b66beea00b7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/Unroll.h @@ -0,0 +1,35 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include + +// Utility to guarantee complete unrolling of a loop where the bounds are known +// at compile time. Various pragmas achieve similar effects, but are not as +// portable across compilers. + +// Example: c10::ForcedUnroll<4>{}(f); is equivalent to f(0); f(1); f(2); f(3); + +namespace c10 { + +template +struct ForcedUnroll { + template + C10_ALWAYS_INLINE void operator()(const Func& f, Args... args) const { + ForcedUnroll{}(f, args...); + f(std::integral_constant{}, args...); + } +}; + +template <> +struct ForcedUnroll<1> { + template + C10_ALWAYS_INLINE void operator()(const Func& f, Args... args) const { + f(std::integral_constant{}, args...); + } +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/WaitCounter.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/WaitCounter.h new file mode 100644 index 0000000000000000000000000000000000000000..c58f31f828cceb0d38e23d5ee0716593d08a2dd7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/WaitCounter.h @@ -0,0 +1,109 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +namespace c10::monitor { +namespace detail { +class WaitCounterImpl; + +class WaitCounterBackendIf { + public: + virtual ~WaitCounterBackendIf() = default; + + virtual intptr_t start( + std::chrono::steady_clock::time_point now) noexcept = 0; + virtual void stop( + std::chrono::steady_clock::time_point now, + intptr_t ctx) noexcept = 0; +}; + +class WaitCounterBackendFactoryIf { + public: + virtual ~WaitCounterBackendFactoryIf() = default; + + // May return nullptr. + // In this case the counter will be ignored by the given backend. + virtual std::unique_ptr create( + std::string_view key) noexcept = 0; +}; + +C10_API void registerWaitCounterBackend( + std::unique_ptr /*factory*/); + +C10_API std::vector> +getRegisteredWaitCounterBackends(); +} // namespace detail + +// A handle to a wait counter. +class C10_API WaitCounterHandle { + public: + explicit WaitCounterHandle(std::string_view key); + + class WaitGuard { + public: + WaitGuard(WaitGuard&& other) noexcept + : handle_{std::exchange(other.handle_, {})}, + ctxs_{std::move(other.ctxs_)} {} + WaitGuard(const WaitGuard&) = delete; + WaitGuard& operator=(const WaitGuard&) = delete; + WaitGuard& operator=(WaitGuard&&) = delete; + + ~WaitGuard() { + stop(); + } + + void stop() { + if (auto handle = std::exchange(handle_, nullptr)) { + handle->stop(ctxs_); + } + } + + private: + WaitGuard(WaitCounterHandle& handle, SmallVector&& ctxs) + : handle_{&handle}, ctxs_{std::move(ctxs)} {} + + friend class WaitCounterHandle; + + WaitCounterHandle* handle_; + SmallVector ctxs_; + }; + + // Starts a waiter + WaitGuard start(); + + private: + // Stops the waiter. Each start() call should be matched by exactly one stop() + // call. + void stop(const SmallVector& ctxs); + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) + detail::WaitCounterImpl& impl_; +}; +} // namespace c10::monitor + +#define STATIC_WAIT_COUNTER(_key) \ + []() -> ::c10::monitor::WaitCounterHandle& { \ + static ::c10::monitor::WaitCounterHandle handle(#_key); \ + return handle; \ + }() + +#define STATIC_SCOPED_WAIT_COUNTER(_name) \ + auto C10_ANONYMOUS_VARIABLE(SCOPE_GUARD) = STATIC_WAIT_COUNTER(_name).start(); + +#define WITH_WAIT_COUNTER(_name, _expr) \ + [&]() { \ + STATIC_SCOPED_WAIT_COUNTER(_name); \ + return _expr; \ + }(); + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/WaitCounterDynamicBackend.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/WaitCounterDynamicBackend.h new file mode 100644 index 0000000000000000000000000000000000000000..141d5431adcc1f51286b864d02cc30c2035e3371 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/WaitCounterDynamicBackend.h @@ -0,0 +1,26 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10::monitor::detail { + +struct WaitCounterDynamicBackend { + void* self{nullptr}; + intptr_t (*start)(void* self, int64_t nowUs){nullptr}; + void (*stop)(void* self, int64_t nowUs, intptr_t ctx){nullptr}; + void (*destroy)(void* self){nullptr}; +}; + +using WaitCounterDynamicBackendInit = + void (*)(WaitCounterDynamicBackend*, const char* key, std::size_t keyLen); + +// This name needs to be updated if anything in the API above is changed. +constexpr std::string_view kWaitCounterDynamicBackendInitFn = + "c10_monitor_wait_counter_dynamic_backend_init_v1"; +} // namespace c10::monitor::detail + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/accumulate.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/accumulate.h new file mode 100644 index 0000000000000000000000000000000000000000..df0899a2ce0697b9ff2d8c395dc81fbb9c2d0f84 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/accumulate.h @@ -0,0 +1,129 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Copyright 2004-present Facebook. All Rights Reserved. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +/// Sum of a list of integers; accumulates into the int64_t datatype +template < + typename C, + std::enable_if_t, int> = 0> +inline int64_t sum_integers(const C& container) { + // std::accumulate infers return type from `init` type, so if the `init` type + // is not large enough to hold the result, computation can overflow. We use + // `int64_t` here to avoid this. + return std::accumulate( + container.begin(), container.end(), static_cast(0)); +} + +/// Sum of integer elements referred to by iterators; accumulates into the +/// int64_t datatype +template < + typename Iter, + std::enable_if_t< + std::is_integral_v::value_type>, + int> = 0> +inline int64_t sum_integers(Iter begin, Iter end) { + // std::accumulate infers return type from `init` type, so if the `init` type + // is not large enough to hold the result, computation can overflow. We use + // `int64_t` here to avoid this. + return std::accumulate(begin, end, static_cast(0)); +} + +/// Product of a list of integers; accumulates into the int64_t datatype +template < + typename C, + std::enable_if_t, int> = 0> +inline int64_t multiply_integers(const C& container) { + // std::accumulate infers return type from `init` type, so if the `init` type + // is not large enough to hold the result, computation can overflow. We use + // `int64_t` here to avoid this. + return std::accumulate( + container.begin(), + container.end(), + static_cast(1), + std::multiplies<>()); +} + +/// Product of integer elements referred to by iterators; accumulates into the +/// int64_t datatype +template < + typename Iter, + std::enable_if_t< + std::is_integral_v::value_type>, + int> = 0> +inline int64_t multiply_integers(Iter begin, Iter end) { + // std::accumulate infers return type from `init` type, so if the `init` type + // is not large enough to hold the result, computation can overflow. We use + // `int64_t` here to avoid this. + return std::accumulate( + begin, end, static_cast(1), std::multiplies<>()); +} + +/// Return product of all dimensions starting from k +/// Returns 1 if k>=dims.size() +template < + typename C, + std::enable_if_t, int> = 0> +inline int64_t numelements_from_dim(const int k, const C& dims) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(k >= 0); + + if (k > static_cast(dims.size())) { + return 1; + } else { + auto cbegin = dims.cbegin(); + std::advance(cbegin, k); + return multiply_integers(cbegin, dims.cend()); + } +} + +/// Product of all dims up to k (not including dims[k]) +/// Throws an error if k>dims.size() +template < + typename C, + std::enable_if_t, int> = 0> +inline int64_t numelements_to_dim(const int k, const C& dims) { + TORCH_INTERNAL_ASSERT(0 <= k); + TORCH_INTERNAL_ASSERT((unsigned)k <= dims.size()); + + auto cend = dims.cbegin(); + std::advance(cend, k); + return multiply_integers(dims.cbegin(), cend); +} + +/// Product of all dims between k and l (including dims[k] and excluding +/// dims[l]) k and l may be supplied in either order +template < + typename C, + std::enable_if_t, int> = 0> +inline int64_t numelements_between_dim(int k, int l, const C& dims) { + TORCH_INTERNAL_ASSERT(0 <= k); + TORCH_INTERNAL_ASSERT(0 <= l); + + if (k > l) { + std::swap(k, l); + } + + TORCH_INTERNAL_ASSERT((unsigned)l < dims.size()); + + auto cbegin = dims.cbegin(); + auto cend = dims.cbegin(); + std::advance(cbegin, k); + std::advance(cend, l); + return multiply_integers(cbegin, cend); +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/bit_cast.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/bit_cast.h new file mode 100644 index 0000000000000000000000000000000000000000..948d03d509175254b3f54c60a4b501dd62f870b5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/bit_cast.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/bits.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/bits.h new file mode 100644 index 0000000000000000000000000000000000000000..fe5b67c454490e06d88752b708d9543cda0ae6d1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/bits.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/complex.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/complex.h new file mode 100644 index 0000000000000000000000000000000000000000..ff5ea55c508872c075b181518ff6e1cf537bbc3a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/complex.h @@ -0,0 +1,83 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include +#include +#include + +// std functions +// +// The implementation of these functions also follow the design of C++20 + +namespace std { + +template +constexpr T real(const c10::complex& z) { + return z.real(); +} + +template +constexpr T imag(const c10::complex& z) { + return z.imag(); +} + +template +C10_HOST_DEVICE T abs(const c10::complex& z) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return thrust::abs(static_cast>(z)); +#else + return std::abs(static_cast>(z)); +#endif +} + +#if defined(USE_ROCM) +#define ROCm_Bug(x) +#else +#define ROCm_Bug(x) x +#endif + +template +C10_HOST_DEVICE T arg(const c10::complex& z) { + return ROCm_Bug(std)::atan2(std::imag(z), std::real(z)); +} + +#undef ROCm_Bug + +template +constexpr T norm(const c10::complex& z) { + return z.real() * z.real() + z.imag() * z.imag(); +} + +// For std::conj, there are other versions of it: +// constexpr std::complex conj( float z ); +// template< class DoubleOrInteger > +// constexpr std::complex conj( DoubleOrInteger z ); +// constexpr std::complex conj( long double z ); +// These are not implemented +// TODO(@zasdfgbnm): implement them as c10::conj +template +constexpr c10::complex conj(const c10::complex& z) { + return c10::complex(z.real(), -z.imag()); +} + +// Thrust does not have complex --> complex version of thrust::proj, +// so this function is not implemented at c10 right now. +// TODO(@zasdfgbnm): implement it by ourselves + +// There is no c10 version of std::polar, because std::polar always +// returns std::complex. Use c10::polar instead; + +} // namespace std + +#define C10_INTERNAL_INCLUDE_COMPLEX_REMAINING_H +// math functions are included in a separate file +#include // IWYU pragma: keep +// utilities for complex types +#include // IWYU pragma: keep +#undef C10_INTERNAL_INCLUDE_COMPLEX_REMAINING_H + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/complex_math.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/complex_math.h new file mode 100644 index 0000000000000000000000000000000000000000..8a9dbab5cfbde582b857f7e62467c724f7fb18ea --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/complex_math.h @@ -0,0 +1,446 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#if !defined(C10_INTERNAL_INCLUDE_COMPLEX_REMAINING_H) +#error \ + "c10/util/complex_math.h is not meant to be individually included. Include c10/util/complex.h instead." +#endif + +namespace c10_complex_math { + +// Exponential functions + +template +C10_HOST_DEVICE inline c10::complex exp(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::exp(static_cast>(x))); +#else + return static_cast>( + std::exp(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex log(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::log(static_cast>(x))); +#else + return static_cast>( + std::log(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex log10(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::log10(static_cast>(x))); +#else + return static_cast>( + std::log10(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex log2(const c10::complex& x) { + const c10::complex log2 = c10::complex(::log(2.0), 0.0); + return c10_complex_math::log(x) / log2; +} + +// Power functions +// +#if defined(_LIBCPP_VERSION) || \ + (defined(__GLIBCXX__) && !defined(_GLIBCXX11_USE_C99_COMPLEX)) +namespace _detail { +C10_API c10::complex sqrt(const c10::complex& in); +C10_API c10::complex sqrt(const c10::complex& in); +C10_API c10::complex acos(const c10::complex& in); +C10_API c10::complex acos(const c10::complex& in); +} // namespace _detail +#endif + +template +C10_HOST_DEVICE inline c10::complex sqrt(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::sqrt(static_cast>(x))); +#elif !( \ + defined(_LIBCPP_VERSION) || \ + (defined(__GLIBCXX__) && !defined(_GLIBCXX11_USE_C99_COMPLEX))) + return static_cast>( + std::sqrt(static_cast>(x))); +#else + return _detail::sqrt(x); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex pow( + const c10::complex& x, + const c10::complex& y) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>(thrust::pow( + static_cast>(x), static_cast>(y))); +#else + return static_cast>(std::pow( + static_cast>(x), static_cast>(y))); +#endif +} + +// Regression in ROCm 7.2. See https://github.com/ROCm/rocm-libraries/pull/3836. +// Specialized version for complex on AMD GPUs to use FMA-based +// multiplication +#if defined(__HIPCC__) +namespace detail { +// FMA-aware complex multiplication for float precision on AMD GPUs. +// This prevents SLP vectorizer from breaking FMA formation, which causes +// numerical precision loss in complex arithmetic. +// The issue occurs when vectorizer packs scalar multiplies before backend +// can form FMA instructions, resulting in double rounding instead of single. +C10_HOST_DEVICE inline thrust::complex complex_mul_fma( + thrust::complex a, + thrust::complex b) { + // Complex multiplication: (a.r + a.i*i) * (b.r + b.i*i) + // = (a.r*b.r - a.i*b.i) + (a.r*b.i + a.i*b.r)*i + // Using __builtin_fmaf ensures FMA at source level: + // real: a.r*b.r + (-(a.i*b.i)) = FMA(a.r, b.r, -(a.i*b.i)) + // imag: a.i*b.r + a.r*b.i = FMA(a.r, b.i, a.i*b.r) + float real_part = __builtin_fmaf(a.real(), b.real(), -(a.imag() * b.imag())); + float imag_part = __builtin_fmaf(a.real(), b.imag(), a.imag() * b.real()); + return thrust::complex(real_part, imag_part); +} +} // namespace detail + +template <> +C10_HOST_DEVICE inline c10::complex pow( + const c10::complex& x, + const c10::complex& y) { + auto log_x = thrust::log(static_cast>(x)); + auto y_log_x = + detail::complex_mul_fma(static_cast>(y), log_x); + return static_cast>(thrust::exp(y_log_x)); +} +#endif + +template +C10_HOST_DEVICE inline c10::complex pow( + const c10::complex& x, + const T& y) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::pow(static_cast>(x), y)); +#else + return static_cast>( + std::pow(static_cast>(x), y)); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex pow( + const T& x, + const c10::complex& y) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::pow(x, static_cast>(y))); +#else + return static_cast>( + std::pow(x, static_cast>(y))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex pow( + const c10::complex& x, + const c10::complex& y) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>(thrust::pow( + static_cast>(x), static_cast>(y))); +#else + return static_cast>(std::pow( + static_cast>(x), static_cast>(y))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex pow( + const c10::complex& x, + const U& y) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::pow(static_cast>(x), y)); +#else + return static_cast>( + std::pow(static_cast>(x), y)); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex pow( + const T& x, + const c10::complex& y) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::pow(x, static_cast>(y))); +#else + return static_cast>( + std::pow(x, static_cast>(y))); +#endif +} + +// Trigonometric functions + +template +C10_HOST_DEVICE inline c10::complex sin(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::sin(static_cast>(x))); +#else + return static_cast>( + std::sin(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex cos(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::cos(static_cast>(x))); +#else + return static_cast>( + std::cos(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex tan(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::tan(static_cast>(x))); +#else + return static_cast>( + std::tan(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex asin(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::asin(static_cast>(x))); +#else + return static_cast>( + std::asin(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex acos(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::acos(static_cast>(x))); +#elif !defined(_LIBCPP_VERSION) + return static_cast>( + std::acos(static_cast>(x))); +#else + return _detail::acos(x); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex atan(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::atan(static_cast>(x))); +#else + return static_cast>( + std::atan(static_cast>(x))); +#endif +} + +// Hyperbolic functions + +template +C10_HOST_DEVICE inline c10::complex sinh(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::sinh(static_cast>(x))); +#else + return static_cast>( + std::sinh(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex cosh(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::cosh(static_cast>(x))); +#else + return static_cast>( + std::cosh(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex tanh(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::tanh(static_cast>(x))); +#else + return static_cast>( + std::tanh(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex asinh(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::asinh(static_cast>(x))); +#else + return static_cast>( + std::asinh(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex acosh(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::acosh(static_cast>(x))); +#else + return static_cast>( + std::acosh(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex atanh(const c10::complex& x) { +#if defined(__CUDACC__) || defined(__HIPCC__) + return static_cast>( + thrust::atanh(static_cast>(x))); +#else + return static_cast>( + std::atanh(static_cast>(x))); +#endif +} + +template +C10_HOST_DEVICE inline c10::complex log1p(const c10::complex& z) { +#if defined(__APPLE__) || defined(__MACOSX) || defined(__CUDACC__) || \ + defined(__HIPCC__) + // For Mac, the new implementation yielded a high relative error. Falling back + // to the old version for now. + // See https://github.com/numpy/numpy/pull/22611#issuecomment-1667945354 + // For CUDA we also use this one, as thrust::log(thrust::complex) takes + // *forever* to compile + + // log1p(z) = log(1 + z) + // Let's define 1 + z = r * e ^ (i * a), then we have + // log(r * e ^ (i * a)) = log(r) + i * a + // With z = x + iy, the term r can be written as + // r = ((1 + x) ^ 2 + y ^ 2) ^ 0.5 + // = (1 + x ^ 2 + 2 * x + y ^ 2) ^ 0.5 + // So, log(r) is + // log(r) = 0.5 * log(1 + x ^ 2 + 2 * x + y ^ 2) + // = 0.5 * log1p(x * (x + 2) + y ^ 2) + // we need to use the expression only on certain condition to avoid overflow + // and underflow from `(x * (x + 2) + y ^ 2)` + T x = z.real(); + T y = z.imag(); + T zabs = std::abs(z); + T theta = std::atan2(y, x + T(1)); + if (zabs < 0.5) { + T r = x * (T(2) + x) + y * y; + if (r == 0) { // handle underflow + return {x, theta}; + } + return {T(0.5) * std::log1p(r), theta}; + } else { + T z0 = std::hypot(x + 1, y); + return {std::log(z0), theta}; + } +#else + // CPU path + // Based on https://github.com/numpy/numpy/pull/22611#issuecomment-1667945354 + c10::complex u = z + T(1); + if (u == T(1)) { + return z; + } else { + auto log_u = log(u); + if (u - T(1) == z) { + return log_u; + } + return log_u * (z / (u - T(1))); + } +#endif +} + +template +C10_HOST_DEVICE inline c10::complex expm1(const c10::complex& z) { + // expm1(z) = exp(z) - 1 + // Define z = x + i * y + // f = e ^ (x + i * y) - 1 + // = e ^ x * e ^ (i * y) - 1 + // = (e ^ x * cos(y) - 1) + i * (e ^ x * sin(y)) + // = (e ^ x - 1) * cos(y) - (1 - cos(y)) + i * e ^ x * sin(y) + // = expm1(x) * cos(y) - 2 * sin(y / 2) ^ 2 + i * e ^ x * sin(y) + T x = z.real(); + T y = z.imag(); + T a = std::sin(y / 2); + T er = std::expm1(x) * std::cos(y) - T(2) * a * a; + T ei = std::exp(x) * std::sin(y); + return {er, ei}; +} + +} // namespace c10_complex_math + +using c10_complex_math::acos; +using c10_complex_math::acosh; +using c10_complex_math::asin; +using c10_complex_math::asinh; +using c10_complex_math::atan; +using c10_complex_math::atanh; +using c10_complex_math::cos; +using c10_complex_math::cosh; +using c10_complex_math::exp; +using c10_complex_math::expm1; +using c10_complex_math::log; +using c10_complex_math::log10; +using c10_complex_math::log1p; +using c10_complex_math::log2; +using c10_complex_math::pow; +using c10_complex_math::sin; +using c10_complex_math::sinh; +using c10_complex_math::sqrt; +using c10_complex_math::tan; +using c10_complex_math::tanh; + +namespace std { + +using c10_complex_math::acos; +using c10_complex_math::acosh; +using c10_complex_math::asin; +using c10_complex_math::asinh; +using c10_complex_math::atan; +using c10_complex_math::atanh; +using c10_complex_math::cos; +using c10_complex_math::cosh; +using c10_complex_math::exp; +using c10_complex_math::expm1; +using c10_complex_math::log; +using c10_complex_math::log10; +using c10_complex_math::log1p; +using c10_complex_math::log2; +using c10_complex_math::pow; +using c10_complex_math::sin; +using c10_complex_math::sinh; +using c10_complex_math::sqrt; +using c10_complex_math::tan; +using c10_complex_math::tanh; + +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/complex_utils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/complex_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..44152b72cb35b7df727ece02b089350be04a9f7f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/complex_utils.h @@ -0,0 +1,51 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#if !defined(C10_INTERNAL_INCLUDE_COMPLEX_REMAINING_H) +#error \ + "c10/util/complex_utils.h is not meant to be individually included. Include c10/util/complex.h instead." +#endif + +#include + +namespace c10 { + +template +struct is_complex : public std::false_type {}; + +template +struct is_complex> : public std::true_type {}; + +template +struct is_complex> : public std::true_type {}; + +// Extract double from std::complex; is identity otherwise +// TODO: Write in more idiomatic C++17 +template +struct scalar_value_type { + using type = T; +}; +template +struct scalar_value_type> { + using type = T; +}; +template +struct scalar_value_type> { + using type = T; +}; + +} // namespace c10 + +namespace std { + +template +class numeric_limits> : public numeric_limits {}; + +template +bool isnan(const c10::complex& v) { + return std::isnan(v.real()) || std::isnan(v.imag()); +} + +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/copysign.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/copysign.h new file mode 100644 index 0000000000000000000000000000000000000000..6bc7c7956f3986ca3c3f10252bd6eb06a7fd1104 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/copysign.h @@ -0,0 +1,32 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10 { + +// Note: Explicit implementation of copysign for Half and BFloat16 +// is needed to workaround g++-7/8 crash on aarch64, but also makes +// copysign faster for the half-precision types +template +inline auto copysign(const T& a, const U& b) { + return std::copysign(a, b); +} + +// Implement copysign for half precision floats using bit ops +// Sign is the most significant bit for both half and bfloat16 types +inline c10::Half copysign(c10::Half a, c10::Half b) { + return c10::Half((a.x & 0x7fff) | (b.x & 0x8000), c10::Half::from_bits()); +} + +inline c10::BFloat16 copysign(c10::BFloat16 a, c10::BFloat16 b) { + return c10::BFloat16( + (a.x & 0x7fff) | (b.x & 0x8000), c10::BFloat16::from_bits()); +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/env.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/env.h new file mode 100644 index 0000000000000000000000000000000000000000..538a6e271f9d56564bcd8ff73071974991513009 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/env.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10::utils { + +// Set an environment variable. +C10_API void set_env( + const char* name, + const char* value, + bool overwrite = true); + +// Checks an environment variable is set. +C10_API bool has_env(const char* name) noexcept; + +// Reads an environment variable and returns +// - std::optional, if set equal to "1" +// - std::optional, if set equal to "0" +// - nullopt, otherwise +// +// NB: +// Issues a warning if the value of the environment variable is not 0 or 1. +C10_API std::optional check_env(const char* name); + +// Reads the value of an environment variable if it is set. +// However, check_env should be used if the value is assumed to be a flag. +C10_API std::optional get_env(const char* name) noexcept; + +} // namespace c10::utils + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/error.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/error.h new file mode 100644 index 0000000000000000000000000000000000000000..4afd8a9ab673ff71cb1d0a58e209262096e86347 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/error.h @@ -0,0 +1,16 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10::utils { + +// Get an error string in the thread-safe way. +C10_API std::string str_error(int errnum); + +} // namespace c10::utils + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/flat_hash_map.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/flat_hash_map.h new file mode 100644 index 0000000000000000000000000000000000000000..653401395d4098ea77752e4bafdb64682ac8c242 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/flat_hash_map.h @@ -0,0 +1,2107 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Taken from +// https://github.com/skarupke/flat_hash_map/blob/2c4687431f978f02a3780e24b8b701d22aa32d9c/flat_hash_map.hpp +// with fixes applied: +// - https://github.com/skarupke/flat_hash_map/pull/25 +// - https://github.com/skarupke/flat_hash_map/pull/26 +// - replace size_t with uint64_t to fix it for 32bit +// - add "GCC diagnostic" pragma to ignore -Wshadow +// - make sherwood_v3_table::convertible_to_iterator public because GCC5 seems +// to have issues with it otherwise +// - fix compiler warnings in operator templated_iterator +// - make use of 'if constexpr' and eliminate AssignIfTrue template + +// Copyright Malte Skarupke 2017. +// Distributed under the Boost Software License, Version 1.0. +// (See http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +C10_CLANG_DIAGNOSTIC_PUSH() +#if C10_CLANG_HAS_WARNING("-Wimplicit-int-float-conversion") +C10_CLANG_DIAGNOSTIC_IGNORE("-Wimplicit-int-float-conversion") +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning(disable : 4624) // destructor was implicitly defined as deleted +#endif + +#ifdef _MSC_VER +#define SKA_NOINLINE(...) __declspec(noinline) __VA_ARGS__ +#else +#define SKA_NOINLINE(...) __VA_ARGS__ __attribute__((noinline)) +#endif + +namespace ska { +struct prime_number_hash_policy; +struct power_of_two_hash_policy; +struct fibonacci_hash_policy; + +namespace detailv3 { +template +struct functor_storage : Functor { + functor_storage() = default; + functor_storage(const Functor& functor) : Functor(functor) {} + template + Result operator()(Args&&... args) { + return static_cast(*this)(std::forward(args)...); + } + template + Result operator()(Args&&... args) const { + return static_cast(*this)(std::forward(args)...); + } +}; +template +struct functor_storage { + typedef Result (*function_ptr)(Args...); + function_ptr function; + functor_storage(function_ptr function) : function(function) {} + Result operator()(Args... args) const { + return function(std::forward(args)...); + } + operator function_ptr&() { + return function; + } + operator const function_ptr&() { + return function; + } +}; +template +struct KeyOrValueHasher : functor_storage { + typedef functor_storage hasher_storage; + KeyOrValueHasher() = default; + KeyOrValueHasher(const hasher& hash) : hasher_storage(hash) {} + uint64_t operator()(const key_type& key) { + return static_cast(*this)(key); + } + uint64_t operator()(const key_type& key) const { + return static_cast(*this)(key); + } + uint64_t operator()(const value_type& value) { + return static_cast(*this)(value.first); + } + uint64_t operator()(const value_type& value) const { + return static_cast(*this)(value.first); + } + template + uint64_t operator()(const std::pair& value) { + return static_cast(*this)(value.first); + } + template + uint64_t operator()(const std::pair& value) const { + return static_cast(*this)(value.first); + } +}; +template +struct KeyOrValueEquality : functor_storage { + typedef functor_storage equality_storage; + KeyOrValueEquality() = default; + KeyOrValueEquality(const key_equal& equality) : equality_storage(equality) {} + bool operator()(const key_type& lhs, const key_type& rhs) { + return static_cast(*this)(lhs, rhs); + } + bool operator()(const key_type& lhs, const value_type& rhs) { + return static_cast(*this)(lhs, rhs.first); + } + bool operator()(const value_type& lhs, const key_type& rhs) { + return static_cast(*this)(lhs.first, rhs); + } + bool operator()(const value_type& lhs, const value_type& rhs) { + return static_cast(*this)(lhs.first, rhs.first); + } + template + bool operator()(const key_type& lhs, const std::pair& rhs) { + return static_cast(*this)(lhs, rhs.first); + } + template + bool operator()(const std::pair& lhs, const key_type& rhs) { + return static_cast(*this)(lhs.first, rhs); + } + template + bool operator()(const value_type& lhs, const std::pair& rhs) { + return static_cast(*this)(lhs.first, rhs.first); + } + template + bool operator()(const std::pair& lhs, const value_type& rhs) { + return static_cast(*this)(lhs.first, rhs.first); + } + template + bool operator()(const std::pair& lhs, const std::pair& rhs) { + return static_cast(*this)(lhs.first, rhs.first); + } +}; +static constexpr int8_t min_lookups = 4; +template +struct sherwood_v3_entry { + sherwood_v3_entry() = default; + sherwood_v3_entry(int8_t distance_from_desired) + : distance_from_desired(distance_from_desired) {} + ~sherwood_v3_entry() = default; + + bool has_value() const { + return distance_from_desired >= 0; + } + bool is_empty() const { + return distance_from_desired < 0; + } + bool is_at_desired_position() const { + return distance_from_desired <= 0; + } + template + void emplace(int8_t distance, Args&&... args) { + new (std::addressof(value)) T(std::forward(args)...); + distance_from_desired = distance; + } + + void destroy_value() { + value.~T(); + distance_from_desired = -1; + } + + int8_t distance_from_desired = -1; + static constexpr int8_t special_end_value = 0; + union { + T value; + }; +}; + +inline int8_t log2(uint64_t value) { + // NOLINTNEXTLINE(*c-arrays*) + static constexpr int8_t table[64] = { + 63, 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, + 61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, + 62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, + 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5}; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value |= value >> 32; + return table[((value - (value >> 1)) * 0x07EDD5E59A4E28C2) >> 58]; +} + +inline uint64_t next_power_of_two(uint64_t i) { + --i; + i |= i >> 1; + i |= i >> 2; + i |= i >> 4; + i |= i >> 8; + i |= i >> 16; + i |= i >> 32; + ++i; + return i; +} + +// Implementation taken from http://en.cppreference.com/w/cpp/types/void_t +// (it takes CWG1558 into account and also works for older compilers) +template +struct make_void { + typedef void type; +}; +template +using void_t = typename make_void::type; + +template +struct HashPolicySelector { + typedef fibonacci_hash_policy type; +}; +template +struct HashPolicySelector> { + typedef typename T::hash_policy type; +}; + +template < + typename T, + typename FindKey, + typename ArgumentHash, + typename DetailHasher, + typename ArgumentEqual, + typename Equal, + typename ArgumentAlloc, + typename EntryAlloc> +class sherwood_v3_table : private EntryAlloc, + private DetailHasher, + private Equal { + using Entry = detailv3::sherwood_v3_entry; + using AllocatorTraits = std::allocator_traits; + using EntryPointer = typename AllocatorTraits::pointer; + + public: + struct convertible_to_iterator; + + using value_type = T; + using size_type = uint64_t; + using difference_type = std::ptrdiff_t; + using hasher = ArgumentHash; + using key_equal = ArgumentEqual; + using allocator_type = EntryAlloc; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + + sherwood_v3_table() = default; + explicit sherwood_v3_table( + size_type bucket_count, + const ArgumentHash& hash = ArgumentHash(), + const ArgumentEqual& equal = ArgumentEqual(), + const ArgumentAlloc& alloc = ArgumentAlloc()) + : EntryAlloc(alloc), DetailHasher(hash), Equal(equal) { + rehash(bucket_count); + } + sherwood_v3_table(size_type bucket_count, const ArgumentAlloc& alloc) + : sherwood_v3_table( + bucket_count, + ArgumentHash(), + ArgumentEqual(), + alloc) {} + sherwood_v3_table( + size_type bucket_count, + const ArgumentHash& hash, + const ArgumentAlloc& alloc) + : sherwood_v3_table(bucket_count, hash, ArgumentEqual(), alloc) {} + explicit sherwood_v3_table(const ArgumentAlloc& alloc) : EntryAlloc(alloc) {} + template + sherwood_v3_table( + It first, + It last, + size_type bucket_count = 0, + const ArgumentHash& hash = ArgumentHash(), + const ArgumentEqual& equal = ArgumentEqual(), + const ArgumentAlloc& alloc = ArgumentAlloc()) + : sherwood_v3_table(bucket_count, hash, equal, alloc) { + insert(first, last); + } + template + sherwood_v3_table( + It first, + It last, + size_type bucket_count, + const ArgumentAlloc& alloc) + : sherwood_v3_table( + first, + last, + bucket_count, + ArgumentHash(), + ArgumentEqual(), + alloc) {} + template + sherwood_v3_table( + It first, + It last, + size_type bucket_count, + const ArgumentHash& hash, + const ArgumentAlloc& alloc) + : sherwood_v3_table( + first, + last, + bucket_count, + hash, + ArgumentEqual(), + alloc) {} + sherwood_v3_table( + std::initializer_list il, + size_type bucket_count = 0, + const ArgumentHash& hash = ArgumentHash(), + const ArgumentEqual& equal = ArgumentEqual(), + const ArgumentAlloc& alloc = ArgumentAlloc()) + : sherwood_v3_table(bucket_count, hash, equal, alloc) { + if (bucket_count == 0) + rehash(il.size()); + insert(il.begin(), il.end()); + } + sherwood_v3_table( + std::initializer_list il, + size_type bucket_count, + const ArgumentAlloc& alloc) + : sherwood_v3_table( + il, + bucket_count, + ArgumentHash(), + ArgumentEqual(), + alloc) {} + sherwood_v3_table( + std::initializer_list il, + size_type bucket_count, + const ArgumentHash& hash, + const ArgumentAlloc& alloc) + : sherwood_v3_table(il, bucket_count, hash, ArgumentEqual(), alloc) {} + sherwood_v3_table(const sherwood_v3_table& other) + : sherwood_v3_table( + other, + AllocatorTraits::select_on_container_copy_construction( + other.get_allocator())) {} + sherwood_v3_table(const sherwood_v3_table& other, const ArgumentAlloc& alloc) + : EntryAlloc(alloc), + DetailHasher(other), + Equal(other), + _max_load_factor(other._max_load_factor) { + rehash_for_other_container(other); + try { + insert(other.begin(), other.end()); + } catch (...) { + clear(); + deallocate_data(entries, num_slots_minus_one, max_lookups); + throw; + } + } + sherwood_v3_table(sherwood_v3_table&& other) noexcept + : EntryAlloc(std::move(other)), + DetailHasher(std::move(other)), + Equal(std::move(other)) { + swap_pointers(other); + } + sherwood_v3_table( + sherwood_v3_table&& other, + const ArgumentAlloc& alloc) noexcept + : EntryAlloc(alloc), + DetailHasher(std::move(other)), + Equal(std::move(other)) { + swap_pointers(other); + } + sherwood_v3_table& operator=(const sherwood_v3_table& other) { + if (this == std::addressof(other)) + return *this; + + clear(); + if constexpr (AllocatorTraits::propagate_on_container_copy_assignment:: + value) { + if (static_cast(*this) != + static_cast(other)) { + reset_to_empty_state(); + } + static_cast(*this) = other; + } + _max_load_factor = other._max_load_factor; + static_cast(*this) = other; + static_cast(*this) = other; + rehash_for_other_container(other); + insert(other.begin(), other.end()); + return *this; + } + sherwood_v3_table& operator=(sherwood_v3_table&& other) noexcept { + if (this == std::addressof(other)) + return *this; + else if constexpr (AllocatorTraits::propagate_on_container_move_assignment:: + value) { + clear(); + reset_to_empty_state(); + static_cast(*this) = std::move(other); + swap_pointers(other); + } else if ( + static_cast(*this) == static_cast(other)) { + swap_pointers(other); + } else { + clear(); + _max_load_factor = other._max_load_factor; + rehash_for_other_container(other); + for (T& elem : other) + emplace(std::move(elem)); + other.clear(); + } + static_cast(*this) = std::move(other); + static_cast(*this) = std::move(other); + return *this; + } + ~sherwood_v3_table() { + clear(); + deallocate_data(entries, num_slots_minus_one, max_lookups); + } + + const allocator_type& get_allocator() const { + return static_cast(*this); + } + const ArgumentEqual& key_eq() const { + return static_cast(*this); + } + const ArgumentHash& hash_function() const { + return static_cast(*this); + } + + template + struct templated_iterator { + templated_iterator() = default; + templated_iterator(EntryPointer current) : current(current) {} + EntryPointer current = EntryPointer(); + + using iterator_category = std::forward_iterator_tag; + using value_type = ValueType; + using difference_type = ptrdiff_t; + using pointer = ValueType*; + using reference = ValueType&; + + friend bool operator==( + const templated_iterator& lhs, + const templated_iterator& rhs) { + return lhs.current == rhs.current; + } + friend bool operator!=( + const templated_iterator& lhs, + const templated_iterator& rhs) { + return !(lhs == rhs); + } + + templated_iterator& operator++() { + do { + ++current; + } while (current->is_empty()); + return *this; + } + templated_iterator operator++(int) { + templated_iterator copy(*this); + ++*this; + return copy; + } + + ValueType& operator*() const { + return current->value; + } + ValueType* operator->() const { + return std::addressof(current->value); + } + + // the template automatically disables the operator when value_type is + // already const, because that would cause a lot of compiler warnings + // otherwise. + template < + class target_type = const value_type, + class = std::enable_if_t< + std::is_same_v && + !std::is_same_v>> + operator templated_iterator() const { + return {current}; + } + }; + using iterator = templated_iterator; + using const_iterator = templated_iterator; + + iterator begin() { + for (EntryPointer it = entries;; ++it) { + if (it->has_value()) + return {it}; + } + } + const_iterator begin() const { + for (EntryPointer it = entries;; ++it) { + if (it->has_value()) + return {it}; + } + } + const_iterator cbegin() const { + return begin(); + } + iterator end() { + return { + entries + static_cast(num_slots_minus_one + max_lookups)}; + } + const_iterator end() const { + return { + entries + static_cast(num_slots_minus_one + max_lookups)}; + } + const_iterator cend() const { + return end(); + } + + iterator find(const FindKey& key) { + uint64_t index = + hash_policy.index_for_hash(hash_object(key), num_slots_minus_one); + EntryPointer it = entries + ptrdiff_t(index); + for (int8_t distance = 0; it->distance_from_desired >= distance; + ++distance, ++it) { + if (compares_equal(key, it->value)) + return {it}; + } + return end(); + } + const_iterator find(const FindKey& key) const { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + return const_cast(this)->find(key); + } + uint64_t count(const FindKey& key) const { + return find(key) == end() ? 0 : 1; + } + std::pair equal_range(const FindKey& key) { + iterator found = find(key); + if (found == end()) + return {found, found}; + else + return {found, std::next(found)}; + } + std::pair equal_range( + const FindKey& key) const { + const_iterator found = find(key); + if (found == end()) + return {found, found}; + else + return {found, std::next(found)}; + } + + template + std::pair emplace(Key&& key, Args&&... args) { + uint64_t index = + hash_policy.index_for_hash(hash_object(key), num_slots_minus_one); + EntryPointer current_entry = entries + ptrdiff_t(index); + int8_t distance_from_desired = 0; + for (; current_entry->distance_from_desired >= distance_from_desired; + ++current_entry, ++distance_from_desired) { + if (compares_equal(key, current_entry->value)) + return {{current_entry}, false}; + } + return emplace_new_key( + distance_from_desired, + current_entry, + std::forward(key), + std::forward(args)...); + } + + std::pair insert(const value_type& value) { + return emplace(value); + } + std::pair insert(value_type&& value) { + return emplace(std::move(value)); + } + template + iterator emplace_hint(const_iterator /*unused*/, Args&&... args) { + return emplace(std::forward(args)...).first; + } + iterator insert(const_iterator /*unused*/, const value_type& value) { + return emplace(value).first; + } + iterator insert(const_iterator /*unused*/, value_type&& value) { + return emplace(std::move(value)).first; + } + + template + void insert(It begin, It end) { + for (; begin != end; ++begin) { + emplace(*begin); + } + } + void insert(std::initializer_list il) { + insert(il.begin(), il.end()); + } + + void rehash(uint64_t num_buckets) { + num_buckets = std::max( + num_buckets, + static_cast( + std::ceil(num_elements / static_cast(_max_load_factor)))); + if (num_buckets == 0) { + reset_to_empty_state(); + return; + } + auto new_prime_index = hash_policy.next_size_over(num_buckets); + if (num_buckets == bucket_count()) + return; + int8_t new_max_lookups = compute_max_lookups(num_buckets); + EntryPointer new_buckets( + AllocatorTraits::allocate(*this, num_buckets + new_max_lookups)); + EntryPointer special_end_item = + new_buckets + static_cast(num_buckets + new_max_lookups - 1); + for (EntryPointer it = new_buckets; it != special_end_item; ++it) + it->distance_from_desired = -1; + special_end_item->distance_from_desired = Entry::special_end_value; + std::swap(entries, new_buckets); + std::swap(num_slots_minus_one, num_buckets); + --num_slots_minus_one; + hash_policy.commit(new_prime_index); + int8_t old_max_lookups = max_lookups; + max_lookups = new_max_lookups; + num_elements = 0; + for (EntryPointer + it = new_buckets, + end = it + static_cast(num_buckets + old_max_lookups); + it != end; + ++it) { + if (it->has_value()) { + emplace(std::move(it->value)); + it->destroy_value(); + } + } + deallocate_data(new_buckets, num_buckets, old_max_lookups); + } + + void reserve(uint64_t num_elements_) { + uint64_t required_buckets = num_buckets_for_reserve(num_elements_); + if (required_buckets > bucket_count()) + rehash(required_buckets); + } + + // the return value is a type that can be converted to an iterator + // the reason for doing this is that it's not free to find the + // iterator pointing at the next element. if you care about the + // next iterator, turn the return value into an iterator + convertible_to_iterator erase(const_iterator to_erase) { + EntryPointer current = to_erase.current; + current->destroy_value(); + --num_elements; + for (EntryPointer next = current + ptrdiff_t(1); + !next->is_at_desired_position(); + ++current, ++next) { + current->emplace(next->distance_from_desired - 1, std::move(next->value)); + next->destroy_value(); + } + return {to_erase.current}; + } + + iterator erase(const_iterator begin_it, const_iterator end_it) { + if (begin_it == end_it) + return {begin_it.current}; + for (EntryPointer it = begin_it.current, end = end_it.current; it != end; + ++it) { + if (it->has_value()) { + it->destroy_value(); + --num_elements; + } + } + if (end_it == this->end()) + return this->end(); + ptrdiff_t num_to_move = std::min( + static_cast(end_it.current->distance_from_desired), + end_it.current - begin_it.current); + EntryPointer to_return = end_it.current - num_to_move; + for (EntryPointer it = end_it.current; !it->is_at_desired_position();) { + EntryPointer target = it - num_to_move; + target->emplace( + it->distance_from_desired - num_to_move, std::move(it->value)); + it->destroy_value(); + ++it; + num_to_move = std::min( + static_cast(it->distance_from_desired), num_to_move); + } + return {to_return}; + } + + uint64_t erase(const FindKey& key) { + auto found = find(key); + if (found == end()) + return 0; + else { + erase(found); + return 1; + } + } + + void clear() { + for (EntryPointer it = entries, + end = it + + static_cast(num_slots_minus_one + max_lookups); + it != end; + ++it) { + if (it->has_value()) + it->destroy_value(); + } + num_elements = 0; + } + + void shrink_to_fit() { + rehash_for_other_container(*this); + } + + void swap(sherwood_v3_table& other) noexcept { + using std::swap; + swap_pointers(other); + swap(static_cast(*this), static_cast(other)); + swap( + static_cast(*this), static_cast(other)); + if (AllocatorTraits::propagate_on_container_swap::value) + swap(static_cast(*this), static_cast(other)); + } + + uint64_t size() const { + return num_elements; + } + uint64_t max_size() const { + return (AllocatorTraits::max_size(*this)) / sizeof(Entry); + } + uint64_t bucket_count() const { + return num_slots_minus_one ? num_slots_minus_one + 1 : 0; + } + size_type max_bucket_count() const { + return (AllocatorTraits::max_size(*this) - min_lookups) / sizeof(Entry); + } + uint64_t bucket(const FindKey& key) const { + return hash_policy.index_for_hash(hash_object(key), num_slots_minus_one); + } + float load_factor() const { + uint64_t buckets = bucket_count(); + if (buckets) + return static_cast(num_elements) / bucket_count(); + else + return 0; + } + void max_load_factor(float value) { + _max_load_factor = value; + } + float max_load_factor() const { + return _max_load_factor; + } + + bool empty() const { + return num_elements == 0; + } + + private: + EntryPointer entries = empty_default_table(); + uint64_t num_slots_minus_one = 0; + typename HashPolicySelector::type hash_policy; + int8_t max_lookups = detailv3::min_lookups - 1; + float _max_load_factor = 0.5f; + uint64_t num_elements = 0; + + EntryPointer empty_default_table() { + EntryPointer result = + AllocatorTraits::allocate(*this, detailv3::min_lookups); + EntryPointer special_end_item = + result + static_cast(detailv3::min_lookups - 1); + for (EntryPointer it = result; it != special_end_item; ++it) + it->distance_from_desired = -1; + special_end_item->distance_from_desired = Entry::special_end_value; + return result; + } + + static int8_t compute_max_lookups(uint64_t num_buckets) { + int8_t desired = detailv3::log2(num_buckets); + return std::max(detailv3::min_lookups, desired); + } + + uint64_t num_buckets_for_reserve(uint64_t num_elements_) const { + return static_cast(std::ceil( + static_cast(num_elements_) / + std::min(0.5, static_cast(_max_load_factor)))); + } + void rehash_for_other_container(const sherwood_v3_table& other) { + rehash( + std::min(num_buckets_for_reserve(other.size()), other.bucket_count())); + } + + void swap_pointers(sherwood_v3_table& other) { + using std::swap; + swap(hash_policy, other.hash_policy); + swap(entries, other.entries); + swap(num_slots_minus_one, other.num_slots_minus_one); + swap(num_elements, other.num_elements); + swap(max_lookups, other.max_lookups); + swap(_max_load_factor, other._max_load_factor); + } + + template + SKA_NOINLINE(std::pair) + emplace_new_key( + int8_t distance_from_desired, + EntryPointer current_entry, + Key&& key, + Args&&... args) { + using std::swap; + if (num_slots_minus_one == 0 || distance_from_desired == max_lookups || + num_elements + 1 > + (num_slots_minus_one + 1) * static_cast(_max_load_factor)) { + grow(); + return emplace(std::forward(key), std::forward(args)...); + } else if (current_entry->is_empty()) { + current_entry->emplace( + distance_from_desired, + std::forward(key), + std::forward(args)...); + ++num_elements; + return {{current_entry}, true}; + } + value_type to_insert(std::forward(key), std::forward(args)...); + swap(distance_from_desired, current_entry->distance_from_desired); + swap(to_insert, current_entry->value); + iterator result = {current_entry}; + for (++distance_from_desired, ++current_entry;; ++current_entry) { + if (current_entry->is_empty()) { + current_entry->emplace(distance_from_desired, std::move(to_insert)); + ++num_elements; + return {result, true}; + } else if (current_entry->distance_from_desired < distance_from_desired) { + swap(distance_from_desired, current_entry->distance_from_desired); + swap(to_insert, current_entry->value); + ++distance_from_desired; + } else { + ++distance_from_desired; + if (distance_from_desired == max_lookups) { + swap(to_insert, result.current->value); + grow(); + return emplace(std::move(to_insert)); + } + } + } + } + + void grow() { + rehash(std::max(uint64_t(4), 2 * bucket_count())); + } + + void deallocate_data( + EntryPointer begin, + uint64_t num_slots_minus_one_, + int8_t max_lookups_) { + AllocatorTraits::deallocate( + *this, begin, num_slots_minus_one_ + max_lookups_ + 1); + } + + void reset_to_empty_state() { + deallocate_data(entries, num_slots_minus_one, max_lookups); + entries = empty_default_table(); + num_slots_minus_one = 0; + hash_policy.reset(); + max_lookups = detailv3::min_lookups - 1; + } + + template + uint64_t hash_object(const U& key) { + return static_cast(*this)(key); + } + template + uint64_t hash_object(const U& key) const { + return static_cast(*this)(key); + } + template + bool compares_equal(const L& lhs, const R& rhs) { + return static_cast(*this)(lhs, rhs); + } + + public: + struct convertible_to_iterator { + EntryPointer it; + + operator iterator() { + if (it->has_value()) + return {it}; + else + return ++iterator{it}; + } + operator const_iterator() { + if (it->has_value()) + return {it}; + else + return ++const_iterator{it}; + } + }; +}; +} // namespace detailv3 + +struct prime_number_hash_policy { + static uint64_t mod0(uint64_t /*unused*/) { + return 0llu; + } + static uint64_t mod2(uint64_t hash) { + return hash % 2llu; + } + static uint64_t mod3(uint64_t hash) { + return hash % 3llu; + } + static uint64_t mod5(uint64_t hash) { + return hash % 5llu; + } + static uint64_t mod7(uint64_t hash) { + return hash % 7llu; + } + static uint64_t mod11(uint64_t hash) { + return hash % 11llu; + } + static uint64_t mod13(uint64_t hash) { + return hash % 13llu; + } + static uint64_t mod17(uint64_t hash) { + return hash % 17llu; + } + static uint64_t mod23(uint64_t hash) { + return hash % 23llu; + } + static uint64_t mod29(uint64_t hash) { + return hash % 29llu; + } + static uint64_t mod37(uint64_t hash) { + return hash % 37llu; + } + static uint64_t mod47(uint64_t hash) { + return hash % 47llu; + } + static uint64_t mod59(uint64_t hash) { + return hash % 59llu; + } + static uint64_t mod73(uint64_t hash) { + return hash % 73llu; + } + static uint64_t mod97(uint64_t hash) { + return hash % 97llu; + } + static uint64_t mod127(uint64_t hash) { + return hash % 127llu; + } + static uint64_t mod151(uint64_t hash) { + return hash % 151llu; + } + static uint64_t mod197(uint64_t hash) { + return hash % 197llu; + } + static uint64_t mod251(uint64_t hash) { + return hash % 251llu; + } + static uint64_t mod313(uint64_t hash) { + return hash % 313llu; + } + static uint64_t mod397(uint64_t hash) { + return hash % 397llu; + } + static uint64_t mod499(uint64_t hash) { + return hash % 499llu; + } + static uint64_t mod631(uint64_t hash) { + return hash % 631llu; + } + static uint64_t mod797(uint64_t hash) { + return hash % 797llu; + } + static uint64_t mod1009(uint64_t hash) { + return hash % 1009llu; + } + static uint64_t mod1259(uint64_t hash) { + return hash % 1259llu; + } + static uint64_t mod1597(uint64_t hash) { + return hash % 1597llu; + } + static uint64_t mod2011(uint64_t hash) { + return hash % 2011llu; + } + static uint64_t mod2539(uint64_t hash) { + return hash % 2539llu; + } + static uint64_t mod3203(uint64_t hash) { + return hash % 3203llu; + } + static uint64_t mod4027(uint64_t hash) { + return hash % 4027llu; + } + static uint64_t mod5087(uint64_t hash) { + return hash % 5087llu; + } + static uint64_t mod6421(uint64_t hash) { + return hash % 6421llu; + } + static uint64_t mod8089(uint64_t hash) { + return hash % 8089llu; + } + static uint64_t mod10193(uint64_t hash) { + return hash % 10193llu; + } + static uint64_t mod12853(uint64_t hash) { + return hash % 12853llu; + } + static uint64_t mod16193(uint64_t hash) { + return hash % 16193llu; + } + static uint64_t mod20399(uint64_t hash) { + return hash % 20399llu; + } + static uint64_t mod25717(uint64_t hash) { + return hash % 25717llu; + } + static uint64_t mod32401(uint64_t hash) { + return hash % 32401llu; + } + static uint64_t mod40823(uint64_t hash) { + return hash % 40823llu; + } + static uint64_t mod51437(uint64_t hash) { + return hash % 51437llu; + } + static uint64_t mod64811(uint64_t hash) { + return hash % 64811llu; + } + static uint64_t mod81649(uint64_t hash) { + return hash % 81649llu; + } + static uint64_t mod102877(uint64_t hash) { + return hash % 102877llu; + } + static uint64_t mod129607(uint64_t hash) { + return hash % 129607llu; + } + static uint64_t mod163307(uint64_t hash) { + return hash % 163307llu; + } + static uint64_t mod205759(uint64_t hash) { + return hash % 205759llu; + } + static uint64_t mod259229(uint64_t hash) { + return hash % 259229llu; + } + static uint64_t mod326617(uint64_t hash) { + return hash % 326617llu; + } + static uint64_t mod411527(uint64_t hash) { + return hash % 411527llu; + } + static uint64_t mod518509(uint64_t hash) { + return hash % 518509llu; + } + static uint64_t mod653267(uint64_t hash) { + return hash % 653267llu; + } + static uint64_t mod823117(uint64_t hash) { + return hash % 823117llu; + } + static uint64_t mod1037059(uint64_t hash) { + return hash % 1037059llu; + } + static uint64_t mod1306601(uint64_t hash) { + return hash % 1306601llu; + } + static uint64_t mod1646237(uint64_t hash) { + return hash % 1646237llu; + } + static uint64_t mod2074129(uint64_t hash) { + return hash % 2074129llu; + } + static uint64_t mod2613229(uint64_t hash) { + return hash % 2613229llu; + } + static uint64_t mod3292489(uint64_t hash) { + return hash % 3292489llu; + } + static uint64_t mod4148279(uint64_t hash) { + return hash % 4148279llu; + } + static uint64_t mod5226491(uint64_t hash) { + return hash % 5226491llu; + } + static uint64_t mod6584983(uint64_t hash) { + return hash % 6584983llu; + } + static uint64_t mod8296553(uint64_t hash) { + return hash % 8296553llu; + } + static uint64_t mod10453007(uint64_t hash) { + return hash % 10453007llu; + } + static uint64_t mod13169977(uint64_t hash) { + return hash % 13169977llu; + } + static uint64_t mod16593127(uint64_t hash) { + return hash % 16593127llu; + } + static uint64_t mod20906033(uint64_t hash) { + return hash % 20906033llu; + } + static uint64_t mod26339969(uint64_t hash) { + return hash % 26339969llu; + } + static uint64_t mod33186281(uint64_t hash) { + return hash % 33186281llu; + } + static uint64_t mod41812097(uint64_t hash) { + return hash % 41812097llu; + } + static uint64_t mod52679969(uint64_t hash) { + return hash % 52679969llu; + } + static uint64_t mod66372617(uint64_t hash) { + return hash % 66372617llu; + } + static uint64_t mod83624237(uint64_t hash) { + return hash % 83624237llu; + } + static uint64_t mod105359939(uint64_t hash) { + return hash % 105359939llu; + } + static uint64_t mod132745199(uint64_t hash) { + return hash % 132745199llu; + } + static uint64_t mod167248483(uint64_t hash) { + return hash % 167248483llu; + } + static uint64_t mod210719881(uint64_t hash) { + return hash % 210719881llu; + } + static uint64_t mod265490441(uint64_t hash) { + return hash % 265490441llu; + } + static uint64_t mod334496971(uint64_t hash) { + return hash % 334496971llu; + } + static uint64_t mod421439783(uint64_t hash) { + return hash % 421439783llu; + } + static uint64_t mod530980861(uint64_t hash) { + return hash % 530980861llu; + } + static uint64_t mod668993977(uint64_t hash) { + return hash % 668993977llu; + } + static uint64_t mod842879579(uint64_t hash) { + return hash % 842879579llu; + } + static uint64_t mod1061961721(uint64_t hash) { + return hash % 1061961721llu; + } + static uint64_t mod1337987929(uint64_t hash) { + return hash % 1337987929llu; + } + static uint64_t mod1685759167(uint64_t hash) { + return hash % 1685759167llu; + } + static uint64_t mod2123923447(uint64_t hash) { + return hash % 2123923447llu; + } + static uint64_t mod2675975881(uint64_t hash) { + return hash % 2675975881llu; + } + static uint64_t mod3371518343(uint64_t hash) { + return hash % 3371518343llu; + } + static uint64_t mod4247846927(uint64_t hash) { + return hash % 4247846927llu; + } + static uint64_t mod5351951779(uint64_t hash) { + return hash % 5351951779llu; + } + static uint64_t mod6743036717(uint64_t hash) { + return hash % 6743036717llu; + } + static uint64_t mod8495693897(uint64_t hash) { + return hash % 8495693897llu; + } + static uint64_t mod10703903591(uint64_t hash) { + return hash % 10703903591llu; + } + static uint64_t mod13486073473(uint64_t hash) { + return hash % 13486073473llu; + } + static uint64_t mod16991387857(uint64_t hash) { + return hash % 16991387857llu; + } + static uint64_t mod21407807219(uint64_t hash) { + return hash % 21407807219llu; + } + static uint64_t mod26972146961(uint64_t hash) { + return hash % 26972146961llu; + } + static uint64_t mod33982775741(uint64_t hash) { + return hash % 33982775741llu; + } + static uint64_t mod42815614441(uint64_t hash) { + return hash % 42815614441llu; + } + static uint64_t mod53944293929(uint64_t hash) { + return hash % 53944293929llu; + } + static uint64_t mod67965551447(uint64_t hash) { + return hash % 67965551447llu; + } + static uint64_t mod85631228929(uint64_t hash) { + return hash % 85631228929llu; + } + static uint64_t mod107888587883(uint64_t hash) { + return hash % 107888587883llu; + } + static uint64_t mod135931102921(uint64_t hash) { + return hash % 135931102921llu; + } + static uint64_t mod171262457903(uint64_t hash) { + return hash % 171262457903llu; + } + static uint64_t mod215777175787(uint64_t hash) { + return hash % 215777175787llu; + } + static uint64_t mod271862205833(uint64_t hash) { + return hash % 271862205833llu; + } + static uint64_t mod342524915839(uint64_t hash) { + return hash % 342524915839llu; + } + static uint64_t mod431554351609(uint64_t hash) { + return hash % 431554351609llu; + } + static uint64_t mod543724411781(uint64_t hash) { + return hash % 543724411781llu; + } + static uint64_t mod685049831731(uint64_t hash) { + return hash % 685049831731llu; + } + static uint64_t mod863108703229(uint64_t hash) { + return hash % 863108703229llu; + } + static uint64_t mod1087448823553(uint64_t hash) { + return hash % 1087448823553llu; + } + static uint64_t mod1370099663459(uint64_t hash) { + return hash % 1370099663459llu; + } + static uint64_t mod1726217406467(uint64_t hash) { + return hash % 1726217406467llu; + } + static uint64_t mod2174897647073(uint64_t hash) { + return hash % 2174897647073llu; + } + static uint64_t mod2740199326961(uint64_t hash) { + return hash % 2740199326961llu; + } + static uint64_t mod3452434812973(uint64_t hash) { + return hash % 3452434812973llu; + } + static uint64_t mod4349795294267(uint64_t hash) { + return hash % 4349795294267llu; + } + static uint64_t mod5480398654009(uint64_t hash) { + return hash % 5480398654009llu; + } + static uint64_t mod6904869625999(uint64_t hash) { + return hash % 6904869625999llu; + } + static uint64_t mod8699590588571(uint64_t hash) { + return hash % 8699590588571llu; + } + static uint64_t mod10960797308051(uint64_t hash) { + return hash % 10960797308051llu; + } + static uint64_t mod13809739252051(uint64_t hash) { + return hash % 13809739252051llu; + } + static uint64_t mod17399181177241(uint64_t hash) { + return hash % 17399181177241llu; + } + static uint64_t mod21921594616111(uint64_t hash) { + return hash % 21921594616111llu; + } + static uint64_t mod27619478504183(uint64_t hash) { + return hash % 27619478504183llu; + } + static uint64_t mod34798362354533(uint64_t hash) { + return hash % 34798362354533llu; + } + static uint64_t mod43843189232363(uint64_t hash) { + return hash % 43843189232363llu; + } + static uint64_t mod55238957008387(uint64_t hash) { + return hash % 55238957008387llu; + } + static uint64_t mod69596724709081(uint64_t hash) { + return hash % 69596724709081llu; + } + static uint64_t mod87686378464759(uint64_t hash) { + return hash % 87686378464759llu; + } + static uint64_t mod110477914016779(uint64_t hash) { + return hash % 110477914016779llu; + } + static uint64_t mod139193449418173(uint64_t hash) { + return hash % 139193449418173llu; + } + static uint64_t mod175372756929481(uint64_t hash) { + return hash % 175372756929481llu; + } + static uint64_t mod220955828033581(uint64_t hash) { + return hash % 220955828033581llu; + } + static uint64_t mod278386898836457(uint64_t hash) { + return hash % 278386898836457llu; + } + static uint64_t mod350745513859007(uint64_t hash) { + return hash % 350745513859007llu; + } + static uint64_t mod441911656067171(uint64_t hash) { + return hash % 441911656067171llu; + } + static uint64_t mod556773797672909(uint64_t hash) { + return hash % 556773797672909llu; + } + static uint64_t mod701491027718027(uint64_t hash) { + return hash % 701491027718027llu; + } + static uint64_t mod883823312134381(uint64_t hash) { + return hash % 883823312134381llu; + } + static uint64_t mod1113547595345903(uint64_t hash) { + return hash % 1113547595345903llu; + } + static uint64_t mod1402982055436147(uint64_t hash) { + return hash % 1402982055436147llu; + } + static uint64_t mod1767646624268779(uint64_t hash) { + return hash % 1767646624268779llu; + } + static uint64_t mod2227095190691797(uint64_t hash) { + return hash % 2227095190691797llu; + } + static uint64_t mod2805964110872297(uint64_t hash) { + return hash % 2805964110872297llu; + } + static uint64_t mod3535293248537579(uint64_t hash) { + return hash % 3535293248537579llu; + } + static uint64_t mod4454190381383713(uint64_t hash) { + return hash % 4454190381383713llu; + } + static uint64_t mod5611928221744609(uint64_t hash) { + return hash % 5611928221744609llu; + } + static uint64_t mod7070586497075177(uint64_t hash) { + return hash % 7070586497075177llu; + } + static uint64_t mod8908380762767489(uint64_t hash) { + return hash % 8908380762767489llu; + } + static uint64_t mod11223856443489329(uint64_t hash) { + return hash % 11223856443489329llu; + } + static uint64_t mod14141172994150357(uint64_t hash) { + return hash % 14141172994150357llu; + } + static uint64_t mod17816761525534927(uint64_t hash) { + return hash % 17816761525534927llu; + } + static uint64_t mod22447712886978529(uint64_t hash) { + return hash % 22447712886978529llu; + } + static uint64_t mod28282345988300791(uint64_t hash) { + return hash % 28282345988300791llu; + } + static uint64_t mod35633523051069991(uint64_t hash) { + return hash % 35633523051069991llu; + } + static uint64_t mod44895425773957261(uint64_t hash) { + return hash % 44895425773957261llu; + } + static uint64_t mod56564691976601587(uint64_t hash) { + return hash % 56564691976601587llu; + } + static uint64_t mod71267046102139967(uint64_t hash) { + return hash % 71267046102139967llu; + } + static uint64_t mod89790851547914507(uint64_t hash) { + return hash % 89790851547914507llu; + } + static uint64_t mod113129383953203213(uint64_t hash) { + return hash % 113129383953203213llu; + } + static uint64_t mod142534092204280003(uint64_t hash) { + return hash % 142534092204280003llu; + } + static uint64_t mod179581703095829107(uint64_t hash) { + return hash % 179581703095829107llu; + } + static uint64_t mod226258767906406483(uint64_t hash) { + return hash % 226258767906406483llu; + } + static uint64_t mod285068184408560057(uint64_t hash) { + return hash % 285068184408560057llu; + } + static uint64_t mod359163406191658253(uint64_t hash) { + return hash % 359163406191658253llu; + } + static uint64_t mod452517535812813007(uint64_t hash) { + return hash % 452517535812813007llu; + } + static uint64_t mod570136368817120201(uint64_t hash) { + return hash % 570136368817120201llu; + } + static uint64_t mod718326812383316683(uint64_t hash) { + return hash % 718326812383316683llu; + } + static uint64_t mod905035071625626043(uint64_t hash) { + return hash % 905035071625626043llu; + } + static uint64_t mod1140272737634240411(uint64_t hash) { + return hash % 1140272737634240411llu; + } + static uint64_t mod1436653624766633509(uint64_t hash) { + return hash % 1436653624766633509llu; + } + static uint64_t mod1810070143251252131(uint64_t hash) { + return hash % 1810070143251252131llu; + } + static uint64_t mod2280545475268481167(uint64_t hash) { + return hash % 2280545475268481167llu; + } + static uint64_t mod2873307249533267101(uint64_t hash) { + return hash % 2873307249533267101llu; + } + static uint64_t mod3620140286502504283(uint64_t hash) { + return hash % 3620140286502504283llu; + } + static uint64_t mod4561090950536962147(uint64_t hash) { + return hash % 4561090950536962147llu; + } + static uint64_t mod5746614499066534157(uint64_t hash) { + return hash % 5746614499066534157llu; + } + static uint64_t mod7240280573005008577(uint64_t hash) { + return hash % 7240280573005008577llu; + } + static uint64_t mod9122181901073924329(uint64_t hash) { + return hash % 9122181901073924329llu; + } + static uint64_t mod11493228998133068689(uint64_t hash) { + return hash % 11493228998133068689llu; + } + static uint64_t mod14480561146010017169(uint64_t hash) { + return hash % 14480561146010017169llu; + } + static uint64_t mod18446744073709551557(uint64_t hash) { + return hash % 18446744073709551557llu; + } + + using mod_function = uint64_t (*)(uint64_t); + + mod_function next_size_over(uint64_t& size) const { + // prime numbers generated by the following method: + // 1. start with a prime p = 2 + // 2. go to wolfram alpha and get p = NextPrime(2 * p) + // 3. repeat 2. until you overflow 64 bits + // you now have large gaps which you would hit if somebody called reserve() + // with an unlucky number. + // 4. to fill the gaps for every prime p go to wolfram alpha and get + // ClosestPrime(p * 2^(1/3)) and ClosestPrime(p * 2^(2/3)) and put those in + // the gaps + // 5. get PrevPrime(2^64) and put it at the end + // NOLINTNEXTLINE(*c-arrays*) + static constexpr const uint64_t prime_list[] = { + 2llu, + 3llu, + 5llu, + 7llu, + 11llu, + 13llu, + 17llu, + 23llu, + 29llu, + 37llu, + 47llu, + 59llu, + 73llu, + 97llu, + 127llu, + 151llu, + 197llu, + 251llu, + 313llu, + 397llu, + 499llu, + 631llu, + 797llu, + 1009llu, + 1259llu, + 1597llu, + 2011llu, + 2539llu, + 3203llu, + 4027llu, + 5087llu, + 6421llu, + 8089llu, + 10193llu, + 12853llu, + 16193llu, + 20399llu, + 25717llu, + 32401llu, + 40823llu, + 51437llu, + 64811llu, + 81649llu, + 102877llu, + 129607llu, + 163307llu, + 205759llu, + 259229llu, + 326617llu, + 411527llu, + 518509llu, + 653267llu, + 823117llu, + 1037059llu, + 1306601llu, + 1646237llu, + 2074129llu, + 2613229llu, + 3292489llu, + 4148279llu, + 5226491llu, + 6584983llu, + 8296553llu, + 10453007llu, + 13169977llu, + 16593127llu, + 20906033llu, + 26339969llu, + 33186281llu, + 41812097llu, + 52679969llu, + 66372617llu, + 83624237llu, + 105359939llu, + 132745199llu, + 167248483llu, + 210719881llu, + 265490441llu, + 334496971llu, + 421439783llu, + 530980861llu, + 668993977llu, + 842879579llu, + 1061961721llu, + 1337987929llu, + 1685759167llu, + 2123923447llu, + 2675975881llu, + 3371518343llu, + 4247846927llu, + 5351951779llu, + 6743036717llu, + 8495693897llu, + 10703903591llu, + 13486073473llu, + 16991387857llu, + 21407807219llu, + 26972146961llu, + 33982775741llu, + 42815614441llu, + 53944293929llu, + 67965551447llu, + 85631228929llu, + 107888587883llu, + 135931102921llu, + 171262457903llu, + 215777175787llu, + 271862205833llu, + 342524915839llu, + 431554351609llu, + 543724411781llu, + 685049831731llu, + 863108703229llu, + 1087448823553llu, + 1370099663459llu, + 1726217406467llu, + 2174897647073llu, + 2740199326961llu, + 3452434812973llu, + 4349795294267llu, + 5480398654009llu, + 6904869625999llu, + 8699590588571llu, + 10960797308051llu, + 13809739252051llu, + 17399181177241llu, + 21921594616111llu, + 27619478504183llu, + 34798362354533llu, + 43843189232363llu, + 55238957008387llu, + 69596724709081llu, + 87686378464759llu, + 110477914016779llu, + 139193449418173llu, + 175372756929481llu, + 220955828033581llu, + 278386898836457llu, + 350745513859007llu, + 441911656067171llu, + 556773797672909llu, + 701491027718027llu, + 883823312134381llu, + 1113547595345903llu, + 1402982055436147llu, + 1767646624268779llu, + 2227095190691797llu, + 2805964110872297llu, + 3535293248537579llu, + 4454190381383713llu, + 5611928221744609llu, + 7070586497075177llu, + 8908380762767489llu, + 11223856443489329llu, + 14141172994150357llu, + 17816761525534927llu, + 22447712886978529llu, + 28282345988300791llu, + 35633523051069991llu, + 44895425773957261llu, + 56564691976601587llu, + 71267046102139967llu, + 89790851547914507llu, + 113129383953203213llu, + 142534092204280003llu, + 179581703095829107llu, + 226258767906406483llu, + 285068184408560057llu, + 359163406191658253llu, + 452517535812813007llu, + 570136368817120201llu, + 718326812383316683llu, + 905035071625626043llu, + 1140272737634240411llu, + 1436653624766633509llu, + 1810070143251252131llu, + 2280545475268481167llu, + 2873307249533267101llu, + 3620140286502504283llu, + 4561090950536962147llu, + 5746614499066534157llu, + 7240280573005008577llu, + 9122181901073924329llu, + 11493228998133068689llu, + 14480561146010017169llu, + 18446744073709551557llu}; + // NOLINTNEXTLINE(*c-arrays*) + static constexpr uint64_t (*const mod_functions[])(uint64_t) = { + &mod0, + &mod2, + &mod3, + &mod5, + &mod7, + &mod11, + &mod13, + &mod17, + &mod23, + &mod29, + &mod37, + &mod47, + &mod59, + &mod73, + &mod97, + &mod127, + &mod151, + &mod197, + &mod251, + &mod313, + &mod397, + &mod499, + &mod631, + &mod797, + &mod1009, + &mod1259, + &mod1597, + &mod2011, + &mod2539, + &mod3203, + &mod4027, + &mod5087, + &mod6421, + &mod8089, + &mod10193, + &mod12853, + &mod16193, + &mod20399, + &mod25717, + &mod32401, + &mod40823, + &mod51437, + &mod64811, + &mod81649, + &mod102877, + &mod129607, + &mod163307, + &mod205759, + &mod259229, + &mod326617, + &mod411527, + &mod518509, + &mod653267, + &mod823117, + &mod1037059, + &mod1306601, + &mod1646237, + &mod2074129, + &mod2613229, + &mod3292489, + &mod4148279, + &mod5226491, + &mod6584983, + &mod8296553, + &mod10453007, + &mod13169977, + &mod16593127, + &mod20906033, + &mod26339969, + &mod33186281, + &mod41812097, + &mod52679969, + &mod66372617, + &mod83624237, + &mod105359939, + &mod132745199, + &mod167248483, + &mod210719881, + &mod265490441, + &mod334496971, + &mod421439783, + &mod530980861, + &mod668993977, + &mod842879579, + &mod1061961721, + &mod1337987929, + &mod1685759167, + &mod2123923447, + &mod2675975881, + &mod3371518343, + &mod4247846927, + &mod5351951779, + &mod6743036717, + &mod8495693897, + &mod10703903591, + &mod13486073473, + &mod16991387857, + &mod21407807219, + &mod26972146961, + &mod33982775741, + &mod42815614441, + &mod53944293929, + &mod67965551447, + &mod85631228929, + &mod107888587883, + &mod135931102921, + &mod171262457903, + &mod215777175787, + &mod271862205833, + &mod342524915839, + &mod431554351609, + &mod543724411781, + &mod685049831731, + &mod863108703229, + &mod1087448823553, + &mod1370099663459, + &mod1726217406467, + &mod2174897647073, + &mod2740199326961, + &mod3452434812973, + &mod4349795294267, + &mod5480398654009, + &mod6904869625999, + &mod8699590588571, + &mod10960797308051, + &mod13809739252051, + &mod17399181177241, + &mod21921594616111, + &mod27619478504183, + &mod34798362354533, + &mod43843189232363, + &mod55238957008387, + &mod69596724709081, + &mod87686378464759, + &mod110477914016779, + &mod139193449418173, + &mod175372756929481, + &mod220955828033581, + &mod278386898836457, + &mod350745513859007, + &mod441911656067171, + &mod556773797672909, + &mod701491027718027, + &mod883823312134381, + &mod1113547595345903, + &mod1402982055436147, + &mod1767646624268779, + &mod2227095190691797, + &mod2805964110872297, + &mod3535293248537579, + &mod4454190381383713, + &mod5611928221744609, + &mod7070586497075177, + &mod8908380762767489, + &mod11223856443489329, + &mod14141172994150357, + &mod17816761525534927, + &mod22447712886978529, + &mod28282345988300791, + &mod35633523051069991, + &mod44895425773957261, + &mod56564691976601587, + &mod71267046102139967, + &mod89790851547914507, + &mod113129383953203213, + &mod142534092204280003, + &mod179581703095829107, + &mod226258767906406483, + &mod285068184408560057, + &mod359163406191658253, + &mod452517535812813007, + &mod570136368817120201, + &mod718326812383316683, + &mod905035071625626043, + &mod1140272737634240411, + &mod1436653624766633509, + &mod1810070143251252131, + &mod2280545475268481167, + &mod2873307249533267101, + &mod3620140286502504283, + &mod4561090950536962147, + &mod5746614499066534157, + &mod7240280573005008577, + &mod9122181901073924329, + &mod11493228998133068689, + &mod14480561146010017169, + &mod18446744073709551557}; + const uint64_t* found = std::lower_bound( + std::begin(prime_list), std::end(prime_list) - 1, size); + size = *found; + return mod_functions[1 + found - prime_list]; + } + void commit(mod_function new_mod_function) { + current_mod_function = new_mod_function; + } + void reset() { + current_mod_function = &mod0; + } + + uint64_t index_for_hash(uint64_t hash, uint64_t /*num_slots_minus_one*/) + const { + return current_mod_function(hash); + } + uint64_t keep_in_range(uint64_t index, uint64_t num_slots_minus_one) const { + return index > num_slots_minus_one ? current_mod_function(index) : index; + } + + private: + mod_function current_mod_function = &mod0; +}; + +struct power_of_two_hash_policy { + uint64_t index_for_hash(uint64_t hash, uint64_t num_slots_minus_one) const { + return hash & num_slots_minus_one; + } + uint64_t keep_in_range(uint64_t index, uint64_t num_slots_minus_one) const { + return index_for_hash(index, num_slots_minus_one); + } + int8_t next_size_over(uint64_t& size) const { + size = detailv3::next_power_of_two(size); + return 0; + } + void commit(int8_t /*unused*/) {} + void reset() {} +}; + +struct fibonacci_hash_policy { + uint64_t index_for_hash(uint64_t hash, uint64_t /*num_slots_minus_one*/) + const { + return (11400714819323198485ull * hash) >> shift; + } + uint64_t keep_in_range(uint64_t index, uint64_t num_slots_minus_one) const { + return index & num_slots_minus_one; + } + + int8_t next_size_over(uint64_t& size) const { + size = std::max(uint64_t(2), detailv3::next_power_of_two(size)); + return static_cast(64 - detailv3::log2(size)); + } + void commit(int8_t shift_) { + shift = shift_; + } + void reset() { + shift = 63; + } + + private: + int8_t shift = 63; +}; + +template < + typename K, + typename V, + typename H = std::hash, + typename E = std::equal_to, + typename A = std::allocator>> +class flat_hash_map + : public detailv3::sherwood_v3_table< + std::pair, + K, + H, + detailv3::KeyOrValueHasher, H>, + E, + detailv3::KeyOrValueEquality, E>, + A, + typename std::allocator_traits::template rebind_alloc< + detailv3::sherwood_v3_entry>>> { + using Table = detailv3::sherwood_v3_table< + std::pair, + K, + H, + detailv3::KeyOrValueHasher, H>, + E, + detailv3::KeyOrValueEquality, E>, + A, + typename std::allocator_traits::template rebind_alloc< + detailv3::sherwood_v3_entry>>>; + + public: + using key_type = K; + using mapped_type = V; + + using Table::Table; + flat_hash_map() = default; + + inline V& operator[](const K& key) { + return emplace(key, convertible_to_value()).first->second; + } + inline V& operator[](K&& key) { + return emplace(std::move(key), convertible_to_value()).first->second; + } + V& at(const K& key) { + auto found = this->find(key); + if (found == this->end()) + throw std::out_of_range("Argument passed to at() was not in the map."); + return found->second; + } + const V& at(const K& key) const { + auto found = this->find(key); + if (found == this->end()) + throw std::out_of_range("Argument passed to at() was not in the map."); + return found->second; + } + + using Table::emplace; + std::pair emplace() { + return emplace(key_type(), convertible_to_value()); + } + template + std::pair insert_or_assign( + const key_type& key, + M&& m) { + auto emplace_result = emplace(key, std::forward(m)); + if (!emplace_result.second) + emplace_result.first->second = std::forward(m); + return emplace_result; + } + template + std::pair insert_or_assign( + key_type&& key, + M&& m) { + auto emplace_result = emplace(std::move(key), std::forward(m)); + if (!emplace_result.second) + emplace_result.first->second = std::forward(m); + return emplace_result; + } + template + typename Table::iterator insert_or_assign( + typename Table::const_iterator /*unused*/, + const key_type& key, + M&& m) { + return insert_or_assign(key, std::forward(m)).first; + } + template + typename Table::iterator insert_or_assign( + typename Table::const_iterator /*unused*/, + key_type&& key, + M&& m) { + return insert_or_assign(std::move(key), std::forward(m)).first; + } + + friend bool operator==(const flat_hash_map& lhs, const flat_hash_map& rhs) { + if (lhs.size() != rhs.size()) + return false; + for (const typename Table::value_type& value : lhs) { + auto found = rhs.find(value.first); + if (found == rhs.end() || value.second != found->second) + return false; + } + return true; + } + friend bool operator!=(const flat_hash_map& lhs, const flat_hash_map& rhs) { + return !(lhs == rhs); + } + + private: + struct convertible_to_value { + operator V() const { + return V(); + } + }; +}; + +template < + typename T, + typename H = std::hash, + typename E = std::equal_to, + typename A = std::allocator> +class flat_hash_set + : public detailv3::sherwood_v3_table< + T, + T, + H, + detailv3::functor_storage, + E, + detailv3::functor_storage, + A, + typename std::allocator_traits::template rebind_alloc< + detailv3::sherwood_v3_entry>> { + using Table = detailv3::sherwood_v3_table< + T, + T, + H, + detailv3::functor_storage, + E, + detailv3::functor_storage, + A, + typename std::allocator_traits::template rebind_alloc< + detailv3::sherwood_v3_entry>>; + + public: + using key_type = T; + + using Table::Table; + flat_hash_set() = default; + + template + std::pair emplace(Args&&... args) { + return Table::emplace(T(std::forward(args)...)); + } + std::pair emplace(const key_type& arg) { + return Table::emplace(arg); + } + std::pair emplace(key_type& arg) { + return Table::emplace(arg); + } + std::pair emplace(const key_type&& arg) { + return Table::emplace(std::move(arg)); + } + std::pair emplace(key_type&& arg) { + return Table::emplace(std::move(arg)); + } + + friend bool operator==(const flat_hash_set& lhs, const flat_hash_set& rhs) { + if (lhs.size() != rhs.size()) + return false; + for (const T& value : lhs) { + if (rhs.find(value) == rhs.end()) + return false; + } + return true; + } + friend bool operator!=(const flat_hash_set& lhs, const flat_hash_set& rhs) { + return !(lhs == rhs); + } +}; + +template +struct power_of_two_std_hash : std::hash { + typedef ska::power_of_two_hash_policy hash_policy; +}; + +} // end namespace ska + +C10_CLANG_DIAGNOSTIC_POP() + +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/floating_point_utils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/floating_point_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..b83f9c931e4cf13b648336b4331a6f33b0a6fda2 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/floating_point_utils.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/generic_math.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/generic_math.h new file mode 100644 index 0000000000000000000000000000000000000000..13452ae9c100396f39b42b27582f04828d290bb1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/generic_math.h @@ -0,0 +1,118 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +#if defined(__CUDA_ARCH__) || defined(__HIPCC__) +#if defined(__CUDA_ARCH__) +#include +#elif defined(__HIPCC__) +#include +#endif +#define C10_COMPAT_COPYSIGN c10::cuda::compat::copysign +#else +#include +#define C10_COMPAT_COPYSIGN c10::copysign +#endif + +// The functions in this file should be header-only as it is used under +// ABI-compatibility mode. + +namespace c10 { + +// NOTE: [Floor Division in Python] +// Python's __floordiv__ operator is more complicated than just floor(a / b). +// It aims to maintain the property: a == (a // b) * b + remainder(a, b) +// which can otherwise fail due to rounding errors in the remainder. +// So, instead it is calculated as: a // b = (a - remainder(a, b)) / b +// With some additional fix-ups added to the result. +// +// For reference, see CPython's implementation: +// https://github.com/python/cpython/blob/ace008c531dd685a30c1dd68f9b5ba35f20171cf/Objects/floatobject.c#L636 + +template +inline C10_HOST_DEVICE scalar_t div_floor_floating(scalar_t a, scalar_t b) + __ubsan_ignore_float_divide_by_zero__ { + if (C10_UNLIKELY(b == 0)) { + // Divide by zero: return standard IEEE result + return a / b; + } + + auto mod = std::fmod(a, b); + auto div = (a - mod) / b; + if ((mod != 0) && (b < 0) != (mod < 0)) { + div -= scalar_t(1); + } + + scalar_t floordiv; + if (div != 0) { + floordiv = std::floor(div); + if (div - floordiv > scalar_t(0.5)) { + floordiv += scalar_t(1.0); + } + } else { + floordiv = C10_COMPAT_COPYSIGN(scalar_t(0), a / b); + } + return floordiv; +} + +template +inline C10_HOST_DEVICE scalar_t div_floor_integer(scalar_t a, scalar_t b) { + if (C10_UNLIKELY(b == 0)) { + return scalar_t(0); + } + + if (C10_UNLIKELY( + std::is_signed::value && + a == std::numeric_limits::min() && b == scalar_t(-1))) { + return a; + } + + if (c10::signs_differ(a, b)) { + // Subtracts one from the results of truncation division if the + // divisor and dividend have different sign(bit)s and the remainder of + // the division is nonzero + const auto quot = a / b; + const auto rem = a % b; + return rem ? quot - 1 : quot; + } + return a / b; +} + +template < + typename scalar_t, + std::enable_if_t, int> = 0> +inline C10_HOST_DEVICE scalar_t div_mod(scalar_t a, scalar_t b) + __ubsan_ignore_float_divide_by_zero__ { + if (C10_UNLIKELY(b == 0)) { + // Divide by zero: return standard IEEE result + return std::fmod(a, b); + } + + auto mod = std::fmod(a, b); + if (mod == 0) { + mod = C10_COMPAT_COPYSIGN(scalar_t(0), b); + } else if ((b < 0) != (mod < 0)) { + mod += b; + } + return mod; +} + +template < + typename scalar_t, + std::enable_if_t, int> = 0> +inline C10_HOST_DEVICE scalar_t div_mod(scalar_t a, scalar_t b) { + auto mod = a % b; + if (mod != 0 && (b < 0) != (mod < 0)) { + mod += b; + } + return mod; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/hash.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/hash.h new file mode 100644 index 0000000000000000000000000000000000000000..c3fff128439efb6d4ddf143493fd9a3d46b04435 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/hash.h @@ -0,0 +1,384 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace c10 { + +// NOTE: hash_combine and SHA1 hashing is based on implementation from Boost +// +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +inline size_t hash_combine(size_t seed, size_t value) { + return seed ^ (value + 0x9e3779b9 + (seed << 6u) + (seed >> 2u)); +} + +// Creates the SHA1 hash of a string. A 160-bit hash. +// Based on the implementation in Boost (see notice above). +// Note that SHA1 hashes are no longer considered cryptographically +// secure, but are the standard hash for generating unique ids. +// Usage: +// // Let 'code' be a std::string +// c10::sha1 sha1_hash{code}; +// const auto hash_code = sha1_hash.str(); +// TODO: Compare vs OpenSSL and/or CryptoPP implementations +struct sha1 { + typedef unsigned int(digest_type)[5]; + + sha1(const std::string& s = "") { + if (!s.empty()) { + reset(); + process_bytes(s.c_str(), s.size()); + } + } + + void reset() { + h_[0] = 0x67452301; + h_[1] = 0xEFCDAB89; + h_[2] = 0x98BADCFE; + h_[3] = 0x10325476; + h_[4] = 0xC3D2E1F0; + + block_byte_index_ = 0; + bit_count_low = 0; + bit_count_high = 0; + } + + std::string str() { + unsigned int digest[5]; + get_digest(digest); + + std::ostringstream buf; + for (unsigned int i : digest) { + buf << std::hex << std::setfill('0') << std::setw(8) << i; + } + + return buf.str(); + } + + private: + unsigned int left_rotate(unsigned int x, std::size_t n) { + return (x << n) ^ (x >> (32 - n)); + } + + void process_block_impl() { + unsigned int w[80]; + + for (std::size_t i = 0; i < 16; ++i) { + w[i] = (block_[i * 4 + 0] << 24); + w[i] |= (block_[i * 4 + 1] << 16); + w[i] |= (block_[i * 4 + 2] << 8); + w[i] |= (block_[i * 4 + 3]); + } + + for (std::size_t i = 16; i < 80; ++i) { + w[i] = left_rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1); + } + + unsigned int a = h_[0]; + unsigned int b = h_[1]; + unsigned int c = h_[2]; + unsigned int d = h_[3]; + unsigned int e = h_[4]; + + for (std::size_t i = 0; i < 80; ++i) { + unsigned int f = 0; + unsigned int k = 0; + + if (i < 20) { + f = (b & c) | (~b & d); + k = 0x5A827999; + } else if (i < 40) { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } else if (i < 60) { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } else { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + + unsigned temp = left_rotate(a, 5) + f + e + k + w[i]; + e = d; + d = c; + c = left_rotate(b, 30); + b = a; + a = temp; + } + + h_[0] += a; + h_[1] += b; + h_[2] += c; + h_[3] += d; + h_[4] += e; + } + + void process_byte_impl(unsigned char byte) { + block_[block_byte_index_++] = byte; + + if (block_byte_index_ == 64) { + block_byte_index_ = 0; + process_block_impl(); + } + } + + void process_byte(unsigned char byte) { + process_byte_impl(byte); + + // size_t max value = 0xFFFFFFFF + // if (bit_count_low + 8 >= 0x100000000) { // would overflow + // if (bit_count_low >= 0x100000000-8) { + if (bit_count_low < 0xFFFFFFF8) { + bit_count_low += 8; + } else { + bit_count_low = 0; + + if (bit_count_high <= 0xFFFFFFFE) { + ++bit_count_high; + } else { + TORCH_CHECK(false, "sha1 too many bytes"); + } + } + } + + void process_block(void const* bytes_begin, void const* bytes_end) { + unsigned char const* begin = static_cast(bytes_begin); + unsigned char const* end = static_cast(bytes_end); + for (; begin != end; ++begin) { + process_byte(*begin); + } + } + + void process_bytes(void const* buffer, std::size_t byte_count) { + unsigned char const* b = static_cast(buffer); + process_block(b, b + byte_count); + } + + void get_digest(digest_type& digest) { + // append the bit '1' to the message + process_byte_impl(0x80); + + // append k bits '0', where k is the minimum number >= 0 + // such that the resulting message length is congruent to 56 (mod 64) + // check if there is enough space for padding and bit_count + if (block_byte_index_ > 56) { + // finish this block + while (block_byte_index_ != 0) { + process_byte_impl(0); + } + + // one more block + while (block_byte_index_ < 56) { + process_byte_impl(0); + } + } else { + while (block_byte_index_ < 56) { + process_byte_impl(0); + } + } + + // append length of message (before pre-processing) + // as a 64-bit big-endian integer + process_byte_impl( + static_cast((bit_count_high >> 24) & 0xFF)); + process_byte_impl( + static_cast((bit_count_high >> 16) & 0xFF)); + process_byte_impl(static_cast((bit_count_high >> 8) & 0xFF)); + process_byte_impl(static_cast((bit_count_high) & 0xFF)); + process_byte_impl(static_cast((bit_count_low >> 24) & 0xFF)); + process_byte_impl(static_cast((bit_count_low >> 16) & 0xFF)); + process_byte_impl(static_cast((bit_count_low >> 8) & 0xFF)); + process_byte_impl(static_cast((bit_count_low) & 0xFF)); + + // get final digest + digest[0] = h_[0]; + digest[1] = h_[1]; + digest[2] = h_[2]; + digest[3] = h_[3]; + digest[4] = h_[4]; + } + + unsigned int h_[5]{}; + unsigned char block_[64]{}; + std::size_t block_byte_index_{}; + std::size_t bit_count_low{}; + std::size_t bit_count_high{}; +}; + +constexpr uint64_t twang_mix64(uint64_t key) noexcept { + key = (~key) + (key << 21); // key *= (1 << 21) - 1; key -= 1; + key = key ^ (key >> 24); + key = key + (key << 3) + (key << 8); // key *= 1 + (1 << 3) + (1 << 8) + key = key ^ (key >> 14); + key = key + (key << 2) + (key << 4); // key *= 1 + (1 << 2) + (1 << 4) + key = key ^ (key >> 28); + key = key + (key << 31); // key *= 1 + (1 << 31) + return key; +} + +//////////////////////////////////////////////////////////////////////////////// +// c10::hash implementation +//////////////////////////////////////////////////////////////////////////////// + +namespace _hash_detail { + +// Use template argument deduction to shorten calls to c10::hash +template +size_t simple_get_hash(const T& o); + +template +using type_if_not_enum = std::enable_if_t, V>; + +// Use SFINAE to dispatch to std::hash if possible, cast enum types to int +// automatically, and fall back to T::hash otherwise. NOTE: C++14 added support +// for hashing enum types to the standard, and some compilers implement it even +// when C++14 flags aren't specified. This is why we have to disable this +// overload if T is an enum type (and use the one below in this case). +template +auto dispatch_hash(const T& o) + -> decltype(std::hash()(o), type_if_not_enum()) { + return std::hash()(o); +} + +template +std::enable_if_t, size_t> dispatch_hash(const T& o) { + using R = std::underlying_type_t; + return std::hash()(static_cast(o)); +} + +template +auto dispatch_hash(const T& o) -> decltype(T::hash(o), size_t()) { + return T::hash(o); +} + +} // namespace _hash_detail + +// Hasher struct +template +struct hash { + size_t operator()(const T& o) const { + return _hash_detail::dispatch_hash(o); + } +}; + +// Specialization for std::tuple +template +struct hash> { + template + struct tuple_hash { + size_t operator()(const std::tuple& t) const { + return hash_combine( + _hash_detail::simple_get_hash(std::get(t)), + tuple_hash()(t)); + } + }; + + template + struct tuple_hash<0, Ts...> { + size_t operator()(const std::tuple& t) const { + return _hash_detail::simple_get_hash(std::get<0>(t)); + } + }; + + size_t operator()(const std::tuple& t) const { + return tuple_hash()(t); + } +}; + +template +struct hash> { + size_t operator()(const std::pair& pair) const { + std::tuple tuple = std::make_tuple(pair.first, pair.second); + return _hash_detail::simple_get_hash(tuple); + } +}; + +template +struct hash> { + size_t operator()(c10::ArrayRef v) const { + size_t seed = 0; + for (const auto& elem : v) { + seed = hash_combine(seed, _hash_detail::simple_get_hash(elem)); + } + return seed; + } +}; + +// Specialization for std::vector +template +struct hash> { + size_t operator()(const std::vector& v) const { + return hash>()(v); + } +}; + +namespace _hash_detail { + +template +size_t simple_get_hash(const T& o) { + return c10::hash()(o); +} + +} // namespace _hash_detail + +// Use this function to actually hash multiple things in one line. +// Dispatches to c10::hash, so it can hash containers. +// Example: +// +// static size_t hash(const MyStruct& s) { +// return get_hash(s.member1, s.member2, s.member3); +// } +template +size_t get_hash(const Types&... args) { + return c10::hash()(std::tie(args...)); +} + +// Specialization for c10::complex +template +struct hash> { + size_t operator()(const c10::complex& c) const { + return get_hash(c.real(), c.imag()); + } +}; + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/int128.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/int128.h new file mode 100644 index 0000000000000000000000000000000000000000..73687a69d1bbc0bfe4a0d449cbf43f10437e29bd --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/int128.h @@ -0,0 +1,403 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// This file is based on the uint128 implementation of protobuf at +// https://github.com/protocolbuffers/protobuf/blob/1e88936fce10cf773cb72b44c6a7f48b38c7578b/src/google/protobuf/stubs/int128.h +// +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#pragma once + +#include +#include +#include + +namespace c10 { + +struct uint128_pod; + +// TODO(xiaofeng): Define GOOGLE_PROTOBUF_HAS_CONSTEXPR when constexpr is +// available. +#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR +#define UINT128_CONSTEXPR constexpr +#else +#define UINT128_CONSTEXPR +#endif + +class uint128; +inline uint128& operator<<=(uint128& self, int amount); + +// An unsigned 128-bit integer type. Thread-compatible. +class C10_API uint128 { + public: + UINT128_CONSTEXPR uint128(); // Sets to 0, but don't trust on this behavior. + UINT128_CONSTEXPR uint128(uint64_t top, uint64_t bottom); +#ifndef SWIG + UINT128_CONSTEXPR uint128(int bottom); + UINT128_CONSTEXPR uint128(uint32_t bottom); // Top 96 bits = 0 +#endif + UINT128_CONSTEXPR uint128(uint64_t bottom); // hi_ = 0 + UINT128_CONSTEXPR uint128(const uint128_pod& val); + + // Trivial copy constructor, assignment operator and destructor. + + void Initialize(uint64_t top, uint64_t bottom); + + // Arithmetic operators. + uint128& operator+=(const uint128& b); + uint128& operator-=(const uint128& b); + uint128& operator*=(const uint128& b); + // Long division/modulo for uint128. + uint128& operator/=(const uint128& b); + uint128& operator%=(const uint128& b); + uint128 operator++(int); + uint128 operator--(int); + // Make msvc happy with using operator<<= from DivModImpl + // which is a static function, and linker complained about missing + // static version of this overload + friend uint128& operator<<=(uint128& /*self*/, int /*amount*/); + uint128& operator>>=(int /*amount*/); + uint128& operator&=(const uint128& b); + uint128& operator|=(const uint128& b); + uint128& operator^=(const uint128& b); + uint128& operator++(); + uint128& operator--(); + + friend uint64_t Uint128Low64(const uint128& v); + friend uint64_t Uint128High64(const uint128& v); + + // We add "std::" to avoid including all of port.h. + C10_API friend std::ostream& operator<<(std::ostream& o, const uint128& b); + + private: + static void DivModImpl( + uint128 dividend, + uint128 divisor, + uint128* quotient_ret, + uint128* remainder_ret); + + // Little-endian memory order optimizations can benefit from + // having lo_ first, hi_ last. + // See util/endian/endian.h and Load128/Store128 for storing a uint128. + uint64_t lo_; + uint64_t hi_; + + // Not implemented, just declared for catching automatic type conversions. + uint128(uint8_t); + uint128(uint16_t); + uint128(float v); + uint128(double v); +}; + +// This is a POD form of uint128 which can be used for static variables which +// need to be operated on as uint128. +struct uint128_pod { + // Note: The ordering of fields is different than 'class uint128' but the + // same as its 2-arg constructor. This enables more obvious initialization + // of static instances, which is the primary reason for this struct in the + // first place. This does not seem to defeat any optimizations wrt + // operations involving this struct. + uint64_t hi; + uint64_t lo; +}; + +C10_API extern const uint128_pod kuint128max; + +// allow uint128 to be logged +C10_API extern std::ostream& operator<<(std::ostream& o, const uint128& b); + +// Methods to access low and high pieces of 128-bit value. +// Defined externally from uint128 to facilitate conversion +// to native 128-bit types when compilers support them. +inline uint64_t Uint128Low64(const uint128& v) { + return v.lo_; +} +inline uint64_t Uint128High64(const uint128& v) { + return v.hi_; +} + +// TODO: perhaps it would be nice to have int128, a signed 128-bit type? + +// -------------------------------------------------------------------------- +// Implementation details follow +// -------------------------------------------------------------------------- +inline bool operator==(const uint128& lhs, const uint128& rhs) { + return ( + Uint128Low64(lhs) == Uint128Low64(rhs) && + Uint128High64(lhs) == Uint128High64(rhs)); +} +inline bool operator!=(const uint128& lhs, const uint128& rhs) { + return !(lhs == rhs); +} + +inline UINT128_CONSTEXPR uint128::uint128() : lo_(0), hi_(0) {} +inline UINT128_CONSTEXPR uint128::uint128(uint64_t top, uint64_t bottom) + : lo_(bottom), hi_(top) {} +inline UINT128_CONSTEXPR uint128::uint128(const uint128_pod& v) + : lo_(v.lo), hi_(v.hi) {} +inline UINT128_CONSTEXPR uint128::uint128(uint64_t bottom) + : lo_(bottom), hi_(0) {} +#ifndef SWIG +inline UINT128_CONSTEXPR uint128::uint128(uint32_t bottom) + : lo_(bottom), hi_(0) {} +inline UINT128_CONSTEXPR uint128::uint128(int bottom) + : lo_(bottom), hi_(static_cast((bottom < 0) ? -1 : 0)) {} +#endif + +#undef UINT128_CONSTEXPR + +inline void uint128::Initialize(uint64_t top, uint64_t bottom) { + hi_ = top; + lo_ = bottom; +} + +// Comparison operators. + +#define CMP128(op) \ + inline bool operator op(const uint128& lhs, const uint128& rhs) { \ + return (Uint128High64(lhs) == Uint128High64(rhs)) \ + ? (Uint128Low64(lhs) op Uint128Low64(rhs)) \ + : (Uint128High64(lhs) op Uint128High64(rhs)); \ + } + +CMP128(<) +CMP128(>) +CMP128(>=) +CMP128(<=) + +#undef CMP128 + +// Unary operators + +inline uint128 operator-(const uint128& val) { + const uint64_t hi_flip = ~Uint128High64(val); + const uint64_t lo_flip = ~Uint128Low64(val); + const uint64_t lo_add = lo_flip + 1; + if (lo_add < lo_flip) { + return uint128(hi_flip + 1, lo_add); + } + return uint128(hi_flip, lo_add); +} + +inline bool operator!(const uint128& val) { + return !Uint128High64(val) && !Uint128Low64(val); +} + +// Logical operators. + +inline uint128 operator~(const uint128& val) { + return uint128(~Uint128High64(val), ~Uint128Low64(val)); +} + +#define LOGIC128(op) \ + inline uint128 operator op(const uint128& lhs, const uint128& rhs) { \ + return uint128( \ + Uint128High64(lhs) op Uint128High64(rhs), \ + Uint128Low64(lhs) op Uint128Low64(rhs)); \ + } + +LOGIC128(|) +LOGIC128(&) +LOGIC128(^) + +#undef LOGIC128 + +#define LOGICASSIGN128(op) \ + inline uint128& uint128::operator op(const uint128 & other) { \ + hi_ op other.hi_; \ + lo_ op other.lo_; \ + return *this; \ + } + +LOGICASSIGN128(|=) +LOGICASSIGN128(&=) +LOGICASSIGN128(^=) + +#undef LOGICASSIGN128 + +// Shift operators. + +inline uint128 operator<<(const uint128& val, int amount) { + // uint64_t shifts of >= 64 are undefined, so we will need some + // special-casing. + if (amount < 64) { + if (amount == 0) { + return val; + } + uint64_t new_hi = + (Uint128High64(val) << amount) | (Uint128Low64(val) >> (64 - amount)); + uint64_t new_lo = Uint128Low64(val) << amount; + return uint128(new_hi, new_lo); + } else if (amount < 128) { + return uint128(Uint128Low64(val) << (amount - 64), 0); + } else { + return uint128(0, 0); + } +} + +inline uint128 operator>>(const uint128& val, int amount) { + // uint64_t shifts of >= 64 are undefined, so we will need some + // special-casing. + if (amount < 64) { + if (amount == 0) { + return val; + } + uint64_t new_hi = Uint128High64(val) >> amount; + uint64_t new_lo = + (Uint128Low64(val) >> amount) | (Uint128High64(val) << (64 - amount)); + return uint128(new_hi, new_lo); + } else if (amount < 128) { + return uint128(0, Uint128High64(val) >> (amount - 64)); + } else { + return uint128(0, 0); + } +} + +inline uint128& operator<<=(uint128& self, int amount) { + // uint64_t shifts of >= 64 are undefined, so we will need some + // special-casing. + if (amount < 64) { + if (amount != 0) { + self.hi_ = (self.hi_ << amount) | (self.lo_ >> (64 - amount)); + self.lo_ = self.lo_ << amount; + } + } else if (amount < 128) { + self.hi_ = self.lo_ << (amount - 64); + self.lo_ = 0; + } else { + self.hi_ = 0; + self.lo_ = 0; + } + return self; +} + +inline uint128& uint128::operator>>=(int amount) { + // uint64_t shifts of >= 64 are undefined, so we will need some + // special-casing. + if (amount < 64) { + if (amount != 0) { + lo_ = (lo_ >> amount) | (hi_ << (64 - amount)); + hi_ = hi_ >> amount; + } + } else if (amount < 128) { + lo_ = hi_ >> (amount - 64); + hi_ = 0; + } else { + lo_ = 0; + hi_ = 0; + } + return *this; +} + +inline uint128 operator+(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) += rhs; +} + +inline uint128 operator-(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) -= rhs; +} + +inline uint128 operator*(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) *= rhs; +} + +inline uint128 operator/(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) /= rhs; +} + +inline uint128 operator%(const uint128& lhs, const uint128& rhs) { + return uint128(lhs) %= rhs; +} + +inline uint128& uint128::operator+=(const uint128& b) { + hi_ += b.hi_; + uint64_t lolo = lo_ + b.lo_; + if (lolo < lo_) + ++hi_; + lo_ = lolo; + return *this; +} + +inline uint128& uint128::operator-=(const uint128& b) { + hi_ -= b.hi_; + if (b.lo_ > lo_) + --hi_; + lo_ -= b.lo_; + return *this; +} + +inline uint128& uint128::operator*=(const uint128& b) { + uint64_t a96 = hi_ >> 32; + uint64_t a64 = hi_ & 0xffffffffu; + uint64_t a32 = lo_ >> 32; + uint64_t a00 = lo_ & 0xffffffffu; + uint64_t b96 = b.hi_ >> 32; + uint64_t b64 = b.hi_ & 0xffffffffu; + uint64_t b32 = b.lo_ >> 32; + uint64_t b00 = b.lo_ & 0xffffffffu; + // multiply [a96 .. a00] x [b96 .. b00] + // terms higher than c96 disappear off the high side + // terms c96 and c64 are safe to ignore carry bit + uint64_t c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96; + uint64_t c64 = a64 * b00 + a32 * b32 + a00 * b64; + this->hi_ = (c96 << 32) + c64; + this->lo_ = 0; + // add terms after this one at a time to capture carry + *this += uint128(a32 * b00) << 32; + *this += uint128(a00 * b32) << 32; + *this += a00 * b00; + return *this; +} + +inline uint128 uint128::operator++(int) { + uint128 tmp(*this); + *this += 1; + return tmp; +} + +inline uint128 uint128::operator--(int) { + uint128 tmp(*this); + *this -= 1; + return tmp; +} + +inline uint128& uint128::operator++() { + *this += 1; + return *this; +} + +inline uint128& uint128::operator--() { + *this -= 1; + return *this; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/intrusive_ptr.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/intrusive_ptr.h new file mode 100644 index 0000000000000000000000000000000000000000..148a9bf4a20002de4396c9e0a26ea695b8ed1c98 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/intrusive_ptr.h @@ -0,0 +1,1278 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace pybind11 { +template +class class_; +} + +namespace torch::utils { +class PyObjectPreservation; +} + +namespace c10 { +class intrusive_ptr_target; +namespace raw { +namespace weak_intrusive_ptr { +inline void incref(intrusive_ptr_target* self); +} +namespace intrusive_ptr { +inline void incref(intrusive_ptr_target* self); +} + +// constructor tag used by intrusive_ptr constructors +struct DontIncreaseRefcount {}; +} // namespace raw + +namespace detail { +constexpr uint64_t kImpracticallyHugeReferenceCount = 0x0FFFFFFF; +constexpr uint64_t kImpracticallyHugeWeakReferenceCount = + (kImpracticallyHugeReferenceCount << 32); +constexpr uint64_t kReferenceCountOne = 1; +constexpr uint64_t kWeakReferenceCountOne = (kReferenceCountOne << 32); +constexpr uint64_t kUniqueRef = (kReferenceCountOne | kWeakReferenceCountOne); +// Indicates whether the object has a PyObject wrapper. +constexpr uint64_t kHasPyObject = (uint64_t(1) << 63); + +template +struct intrusive_target_default_null_type final { + static constexpr TTarget* singleton() noexcept { + return nullptr; + } +}; + +template +TTarget* assign_ptr_(TTarget* rhs) { + if (FromNullType::singleton() == rhs) { + return ToNullType::singleton(); + } else { + return rhs; + } +} + +inline uint32_t refcount(uint64_t combined_refcount) { + return static_cast(combined_refcount); +} + +inline uint32_t weakcount(uint64_t combined_refcount) { + return static_cast((combined_refcount & ~kHasPyObject) >> 32); +} + +inline bool has_pyobject(uint64_t combined_refcount) { + return (combined_refcount & kHasPyObject) != 0; +} + +inline bool is_uniquely_owned(uint64_t combined_refcount) { + return (combined_refcount & ~detail::kHasPyObject) == detail::kUniqueRef; +} + +// The only requirement for refcount increment is that it happens-before +// decrement, so no additional memory ordering is needed. +inline uint64_t atomic_combined_refcount_increment( + std::atomic& combined_refcount, + uint64_t inc) { + return combined_refcount.fetch_add(inc, std::memory_order_relaxed) + inc; +} + +inline uint32_t atomic_weakcount_increment( + std::atomic& combined_refcount) { + return detail::weakcount(atomic_combined_refcount_increment( + combined_refcount, kWeakReferenceCountOne)); +} + +// The requirement is that all modifications to the managed object happen-before +// invocation of the managed object destructor, and that allocation of the +// managed object storage happens-before deallocation of the storage. +// +// To get this ordering, all non-final decrements must synchronize-with the +// final decrement. So all non-final decrements have to store-release while the +// final decrement has to load-acquire, either directly or with the help of +// fences. But it's easiest just to have all decrements be acq-rel. And it turns +// out, on modern architectures and chips, it's also fastest. +inline uint64_t atomic_combined_refcount_decrement( + std::atomic& combined_refcount, + uint64_t dec) { + return combined_refcount.fetch_sub(dec, std::memory_order_acq_rel) - dec; +} + +inline uint32_t atomic_weakcount_decrement( + std::atomic& combined_refcount) { + return detail::weakcount(atomic_combined_refcount_decrement( + combined_refcount, kWeakReferenceCountOne)); +} + +template +struct TargetTraits { + static constexpr bool can_have_pyobject = false; +}; + +} // namespace detail + +/** + * intrusive_ptr is an alternative to shared_ptr that has better + * performance because it does the refcounting intrusively + * (i.e. in a member of the object itself). + * Your class T needs to inherit from intrusive_ptr_target to allow it to be + * used in an intrusive_ptr. Your class's constructor should not allow + *`this` to escape to other threads or create an intrusive_ptr from `this`. + */ + +// Note [Stack allocated intrusive_ptr_target safety] +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// A well known problem with std::enable_shared_from_this is that it +// allows you to create a std::shared_ptr from a stack allocated object, +// which is totally bogus because the object will die once you return +// from the stack. In intrusive_ptr, we can detect that this has occurred, +// because we set the refcount/weakcount of objects which inherit from +// intrusive_ptr_target to zero, *unless* we can prove that the object +// was dynamically allocated (e.g., via make_intrusive). +// +// Thus, whenever you transmute a T* into a intrusive_ptr, we check +// and make sure that the refcount isn't zero (or, a more subtle +// test for weak_intrusive_ptr, for which the refcount may validly +// be zero, but the weak refcount better not be zero), because that +// tells us if the object was allocated by us. If it wasn't, no +// intrusive_ptr for you! + +// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor) +class C10_API intrusive_ptr_target { + // Note [Weak references for intrusive refcounting] + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Here's the scheme: + // + // - refcount == number of strong references to the object + // weakcount == number of weak references to the object, + // plus one more if refcount > 0 + // An invariant: refcount > 0 => weakcount > 0 + // + // - c10::StorageImpl stays live as long as there are any strong + // or weak pointers to it (weakcount > 0, since strong + // references count as a +1 to weakcount) + // + // - finalizers are called and data_ptr is deallocated when refcount == 0 + // + // - Once refcount == 0, it can never again be > 0 (the transition + // from > 0 to == 0 is monotonic) + // + // - When you access c10::StorageImpl via a weak pointer, you must + // atomically increment the use count, if it is greater than 0. + // If it is not, you must report that the storage is dead. + // + //.We use a single combined count for refcount and weakcount so that + // we can atomically operate on both at the same time for performance + // and defined behaviors. + // + // Note [PyObject preservation for Tensor and Storages] + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // intrusive_ptr has special support for preserving PyObject wrappers + // for TensorImpl and StorageImpl. The most significant bit (kHasPyObject) of + // the combined_refcount_ is used to indicate whether the object has a + // PyObject wrapper. + // + // - The PyObject, if it exists, holds a strong reference to the + // intrusive_ptr_target. + // + // - When the refcount goes from 1 to 2, we incref the PyObject. + // + // - When the refcount goes from 2 to 1, we decref the PyObject. + // + // In other words, the intrusive_ptr keeps the PyObject alive as long as there + // are other C++ references to the intrusive_ptr_target. + + mutable std::atomic combined_refcount_; + static_assert(sizeof(std::atomic) == 8); + static_assert(alignof(std::atomic) == 8); + static_assert(std::atomic::is_always_lock_free); + + template + friend class intrusive_ptr; + friend inline void raw::intrusive_ptr::incref(intrusive_ptr_target* self); + + template + friend class weak_intrusive_ptr; + friend inline void raw::weak_intrusive_ptr::incref( + intrusive_ptr_target* self); + + template + friend struct ExclusivelyOwnedTensorTraits; + + friend class torch::utils::PyObjectPreservation; + + protected: + // protected destructor. We never want to destruct intrusive_ptr_target* + // directly. + virtual ~intrusive_ptr_target() { +// Disable -Wterminate and -Wexceptions so we're allowed to use assertions +// (i.e. throw exceptions) in a destructor. +// We also have to disable -Wunknown-warning-option and -Wpragmas, because +// some other compilers don't know about -Wterminate or -Wexceptions and +// will show a warning about unknown warning options otherwise. +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning( \ + disable : 4297) // function assumed not to throw an exception but does +#else +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wunknown-warning-option" +#pragma GCC diagnostic ignored "-Wterminate" +#pragma GCC diagnostic ignored "-Wexceptions" +#endif + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + // Second condition is there to accommodate + // unsafe_adapt_non_heap_allocated: since we are doing our own + // deallocation in that case, it is correct for each + // expected_decref to have happened (some user code tried to + // decref and thus free the object, but it didn't happen right + // away) or not (no user code tried to free the object, and + // now it's getting destroyed through whatever mechanism the + // caller of unsafe_adapt_non_heap_allocated wanted to + // use). We choose our reference count such that the count + // will not dip below kImpracticallyHugeReferenceCount regardless. + refcount() == 0 || + refcount() >= detail::kImpracticallyHugeReferenceCount, + "Tried to destruct an intrusive_ptr_target that still has intrusive_ptr to it; refcount was ", + refcount()); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + // See ~intrusive_ptr for optimization that will frequently result in 1 + // at destruction time. + weakcount() == 1 || weakcount() == 0 || + weakcount() == detail::kImpracticallyHugeReferenceCount - 1 || + weakcount() == detail::kImpracticallyHugeReferenceCount, + "Tried to destruct an intrusive_ptr_target that still has weak_intrusive_ptr to it"); +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#else +#pragma GCC diagnostic pop +#endif + } + + constexpr intrusive_ptr_target() noexcept : combined_refcount_(0) {} + + // intrusive_ptr_target supports copy and move: but refcount and weakcount + // don't participate (since they are intrinsic properties of the memory + // location) + intrusive_ptr_target(intrusive_ptr_target&& /*other*/) noexcept + : intrusive_ptr_target() {} + + intrusive_ptr_target& operator=(intrusive_ptr_target&& /*other*/) noexcept { + return *this; + } + + intrusive_ptr_target(const intrusive_ptr_target& /*other*/) noexcept + : intrusive_ptr_target() {} + + intrusive_ptr_target& operator=( + const intrusive_ptr_target& /*other*/) noexcept { + return *this; + } + + private: + /** + * This is called when refcount reaches zero. + * You can override this to release expensive resources. + * There might still be weak references, so your object might not get + * destructed yet, but you can assume the object isn't used anymore, + * i.e. no more calls to methods or accesses to members (we just can't + * destruct it yet because we need the weakcount accessible). + * + * If there are no weak references (i.e. your class is about to be + * destructed), this function WILL NOT be called. + */ + virtual void release_resources() {} + + /** + * These two methods are called when the refcount transitions between one + * and two and the object has a PyObject wrapper. + */ + virtual void incref_pyobject() const noexcept {} + virtual void decref_pyobject() const noexcept {} + virtual bool try_incref_pyobject() const noexcept { + return false; + } + + uint32_t refcount(std::memory_order order = std::memory_order_relaxed) const { + return detail::refcount(combined_refcount_.load(order)); + } + + uint32_t weakcount( + std::memory_order order = std::memory_order_relaxed) const { + return detail::weakcount(combined_refcount_.load(order)); + } +}; + +namespace detail { + +#ifndef C10_MOBILE +template <> +struct TargetTraits { + // A generic intrusive_ptr may actually be a TensorImpl + // or StorageImpl, so we have to allow for PyObject support. + static constexpr bool can_have_pyobject = true; +}; +#endif + +} // namespace detail + +template +class weak_intrusive_ptr; + +template < + class TTarget, + class NullType = detail::intrusive_target_default_null_type> +class intrusive_ptr final { + private: +// the following static assert would be nice to have but it requires +// the target class T to be fully defined when intrusive_ptr is instantiated +// this is a problem for classes that contain pointers to themselves +// static_assert( +// std::is_base_of_v, +// "intrusive_ptr can only be used for classes that inherit from +// intrusive_ptr_target."); +#ifndef _WIN32 + // This static_assert triggers on MSVC + // error C2131: expression did not evaluate to a constant + static_assert( + // NOLINTNEXTLINE(misc-redundant-expression) + NullType::singleton() == NullType::singleton(), + "NullType must have a constexpr singleton() method"); +#endif + static_assert( + std::is_base_of_v< + TTarget, + std::remove_pointer_t>, + "NullType::singleton() must return a element_type* pointer"); + + TTarget* target_; + + template + friend struct ExclusivelyOwnedTensorTraits; + template + friend class intrusive_ptr; + friend class weak_intrusive_ptr; + + // Make pybind11::class_ be a friend class of intrusive_ptr, so that custom + // smart holder in pybind11 could access the private constructor of + // intrusive_ptr(T*) which took the ownership of the object. This is required + // by customer holder macro PYBIND11_DECLARE_HOLDER_TYPE, where it uses + // intrusive_ptr(TTarget*) to initialize and take ownership of the object. For + // details, see + // https://pybind11.readthedocs.io/en/stable/advanced/smart_ptrs.html#custom-smart-pointers + template + friend class pybind11::class_; + + void retain_() noexcept { + if (target_ != NullType::singleton()) { + uint64_t combined = detail::atomic_combined_refcount_increment( + target_->combined_refcount_, detail::kReferenceCountOne); + uint32_t new_refcount = detail::refcount(combined); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + new_refcount != 1, + "intrusive_ptr: Cannot increase refcount after it reached zero."); + + if constexpr (detail::TargetTraits::can_have_pyobject) { + // If the refcount transitioned from 1 to 2, we need to incref the + // PyObject. In other words, we need to ensure that the PyObject stays + // alive now that we have a C++ reference to this object in addition to + // the PyObject itself. + if (detail::has_pyobject(combined) && detail::refcount(combined) == 2) { + target_->incref_pyobject(); + } + } else { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + !detail::has_pyobject(combined), + "TargetTraits indicates that type cannot have PyObject, but refcount has PyObject bit set."); + } + } + } + + void reset_() noexcept { + if (target_ != NullType::singleton()) { + reset_not_null_(target_); + } + } + + // C10_NOINLINE to keep binary size a bit smaller. We pass TTarget* here + // to avoid an extra pointer dereference in the call from reset_(). + C10_NOINLINE static void reset_not_null_(TTarget* target) noexcept { + if (detail::is_uniquely_owned( + target->combined_refcount_.load(std::memory_order_acquire))) { + // Both counts are 1, so there are no weak references and + // we are releasing the last strong reference. No other + // threads can observe the effects of this target deletion + // call (e.g. calling use_count()) without a data race. + target->combined_refcount_.store(0, std::memory_order_relaxed); + delete target; + return; + } + + auto combined_refcount = detail::atomic_combined_refcount_decrement( + target->combined_refcount_, detail::kReferenceCountOne); + uint32_t new_refcount = detail::refcount(combined_refcount); + bool has_pyobject = detail::has_pyobject(combined_refcount); + if (new_refcount == 0) { + if (detail::weakcount(combined_refcount) == 1) { + delete target; + return; + } + // See comment above about weakcount. As long as refcount>0, + // weakcount is one larger than the actual number of weak references. + // So we need to decrement it here. + release_resources_and_decrement_weakrefs_(target); + } else if constexpr (detail::TargetTraits::can_have_pyobject) { + // If the refcount transitioned from 2 to 1, we need to decref the + // PyObject. In other words, we don't want to keep the PyObject alive if + // there are no C++ references to this object other than the PyObject + // itself. + if (has_pyobject && new_refcount == 1) { + target->decref_pyobject(); + } + } else { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + !has_pyobject, + "TargetTraits indicates that type cannot have PyObject, but refcount has PyObject bit set."); + } + } + + C10_NOINLINE static void release_resources_and_decrement_weakrefs_( + TTarget* target) noexcept { + // justification for const_cast: release_resources is basically a + // destructor and a destructor always mutates the object, even for + // const objects. + const_cast*>(target)->release_resources(); + if (detail::atomic_weakcount_decrement(target->combined_refcount_) == 0) { + delete target; + } + } + + // raw pointer constructors are not public because we shouldn't make + // intrusive_ptr out of raw pointers except from inside the make_intrusive(), + // reclaim() and weak_intrusive_ptr::lock() implementations. + + // This constructor will increase the ref counter for you. + // This constructor will be used by the make_intrusive(), and also pybind11, + // which wrap the intrusive_ptr holder around the raw pointer and incref + // correspondingly (pybind11 requires raw pointer constructor to incref by + // default). + explicit intrusive_ptr(TTarget* target) + : intrusive_ptr(target, raw::DontIncreaseRefcount{}) { + if (target_ != NullType::singleton()) { + // We just created result.target_, so we know no other thread has + // access to it, so we know we needn't care about memory ordering. + // (On x86_64, a store with memory_order_relaxed generates a plain old + // `mov`, whereas an atomic increment does a lock-prefixed `add`, which is + // much more expensive: https://godbolt.org/z/eKPzj8.) + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + target_->combined_refcount_.load(std::memory_order_relaxed) == 0, + "intrusive_ptr: Newly-created target had non-zero refcounts. Does its " + "constructor do something strange like incref or create an " + "intrusive_ptr from `this`?"); + target_->combined_refcount_.store( + detail::kUniqueRef, std::memory_order_relaxed); + } + } + + public: + using element_type = TTarget; + + intrusive_ptr() noexcept + : intrusive_ptr(NullType::singleton(), raw::DontIncreaseRefcount{}) {} + + /* implicit */ intrusive_ptr(std::nullptr_t) noexcept + : intrusive_ptr(NullType::singleton(), raw::DontIncreaseRefcount{}) {} + + // This constructor will not increase the ref counter for you. + // We use the tagged dispatch mechanism to explicitly mark this constructor + // to not increase the refcount + explicit intrusive_ptr( + TTarget* target, + raw::DontIncreaseRefcount /*unused*/) noexcept + : target_(target) {} + + explicit intrusive_ptr(std::unique_ptr rhs) noexcept + : intrusive_ptr(rhs.release()) {} + + intrusive_ptr(intrusive_ptr&& rhs) noexcept : target_(rhs.target_) { + rhs.target_ = NullType::singleton(); + } + + template + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + /* implicit */ intrusive_ptr(intrusive_ptr&& rhs) noexcept + : target_( + detail::assign_ptr_(rhs.target_)) { + static_assert( + std::is_convertible_v, + "Type mismatch. intrusive_ptr move constructor got pointer of wrong type."); + rhs.target_ = FromNullType::singleton(); + } + + intrusive_ptr(const intrusive_ptr& rhs) : target_(rhs.target_) { + retain_(); + } + + template + /* implicit */ intrusive_ptr(const intrusive_ptr& rhs) + : target_( + detail::assign_ptr_(rhs.target_)) { + static_assert( + std::is_convertible_v, + "Type mismatch. intrusive_ptr copy constructor got pointer of wrong type."); + retain_(); + } + + ~intrusive_ptr() noexcept { + reset_(); + } + + intrusive_ptr& operator=(intrusive_ptr&& rhs) & noexcept { + // NOLINTNEXTLINE(*assign*) + return this->template operator= (std::move(rhs)); + } + + template + intrusive_ptr& operator=(intrusive_ptr&& rhs) & noexcept { + static_assert( + std::is_convertible_v, + "Type mismatch. intrusive_ptr move assignment got pointer of wrong type."); + intrusive_ptr tmp = std::move(rhs); + swap(tmp); + return *this; + } + + // Assignment is implemented using copy and swap. That's safe for self + // assignment. + // NOLINTNEXTLINE(bugprone-unhandled-self-assignment) + intrusive_ptr& operator=(const intrusive_ptr& rhs) & noexcept { + // NOLINTNEXTLINE(*assign-operator, *assignment-signature) + return this->template operator= (rhs); + } + + template + intrusive_ptr& operator=( + const intrusive_ptr& rhs) & noexcept { + static_assert( + std::is_convertible_v, + "Type mismatch. intrusive_ptr copy assignment got pointer of wrong type."); + intrusive_ptr tmp = rhs; + swap(tmp); + return *this; + } + + TTarget* get() const noexcept { + return target_; + } + + TTarget& operator*() const noexcept { + return *target_; + } + + TTarget* operator->() const noexcept { + return target_; + } + + operator bool() const noexcept { + return target_ != NullType::singleton(); + } + + void reset() noexcept { + reset_(); + target_ = NullType::singleton(); + } + + void swap(intrusive_ptr& rhs) noexcept { + std::swap(target_, rhs.target_); + } + + // We do a lot of null-pointer checks in our code, good to have this be cheap. + bool defined() const noexcept { + return target_ != NullType::singleton(); + } + + uint32_t use_count() const noexcept { + if (target_ == NullType::singleton()) { + return 0; + } + return target_->refcount(std::memory_order_relaxed); + } + + uint32_t weak_use_count() const noexcept { + if (target_ == NullType::singleton()) { + return 0; + } + return target_->weakcount(std::memory_order_relaxed); + } + + bool unique() const noexcept { + return use_count() == 1; + } + + /** + * Stronger than unique() in that it must not have any weakrefs as well. + */ + bool is_uniquely_owned() const noexcept { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(target_ != NullType::singleton()); + return detail::is_uniquely_owned( + target_->combined_refcount_.load(std::memory_order_acquire)); + } + + /** + * Returns an owning (!) pointer to the underlying object and makes the + * intrusive_ptr instance invalid. That means the refcount is not decreased. + * You *must* put the returned pointer back into a intrusive_ptr using + * intrusive_ptr::reclaim(ptr) to properly destruct it. + * This is helpful for C APIs. + */ + TTarget* release() noexcept { + // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) + TTarget* result = target_; + target_ = NullType::singleton(); + return result; + } + + /** + * Takes an owning pointer to TTarget* and creates an intrusive_ptr that takes + * over ownership. That means the refcount is not increased. + * This is the counter-part to intrusive_ptr::release() and the pointer + * passed in *must* have been created using intrusive_ptr::release(). + */ + static intrusive_ptr reclaim(TTarget* owning_ptr) { + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + owning_ptr == NullType::singleton() || owning_ptr->refcount() == 0 || + owning_ptr->weakcount(), + "TTarget violates the invariant that refcount > 0 => weakcount > 0"); + return intrusive_ptr(owning_ptr, raw::DontIncreaseRefcount{}); + } + + /** + * Takes an owning pointer to TTarget* and creates an intrusive_ptr + * representing a new reference, i.e. the raw pointer retains + * ownership. + */ + static intrusive_ptr reclaim_copy(TTarget* owning_ptr) { + auto ret = reclaim(owning_ptr); + ret.retain_(); + return ret; + } + + /** + * Allocate a heap object with args and wrap it inside a intrusive_ptr and + * incref. This is a helper function to let make_intrusive() access private + * intrusive_ptr constructors. + */ + template + static intrusive_ptr make(Args&&... args) { + return intrusive_ptr(new TTarget(std::forward(args)...)); + } + + /** + * Turn a new instance of TTarget (e.g., literally allocated + * using new TTarget(...) into an intrusive_ptr. If possible, + * use intrusive_ptr::make instead which statically guarantees + * that the allocation was done properly. + * + * At the moment, the only reason this method exists is because + * pybind11 holder types expect to be able to allocate in + * this way (because pybind11 handles the new allocation itself). + */ + static intrusive_ptr unsafe_steal_from_new(TTarget* raw_ptr) { + return intrusive_ptr(raw_ptr); + } + + /** + * Turn an instance of TTarget that should not be reference counted + * (e.g., allocated into an arena with placement new) into an + * intrusive_ptr. This is gratuitously unsafe and should only be + * used if you can guarantee that the pointer will not escape and be + * refcounted as normal. + * + * `expected_decrefs` is a debugging parameter: it indicates the + * number of strong owners the intrusive_ptr_target in question is + * expected to get. In most use cases, this will likely be 1. + * + * The reason this method exists is for manually sharing + * StorageImpls across Tensors in the static runtime. It needs + * access to private intrusive_ptr members so that the refcounts can + * be initialized to custom values. + */ + static intrusive_ptr unsafe_adapt_non_heap_allocated( + TTarget* raw_ptr, + uint32_t expected_decrefs) { + intrusive_ptr result(raw_ptr, raw::DontIncreaseRefcount{}); + // kImpracticallyHugeReferenceCount is impractically huge for a reference + // count, while being in no danger of overflowing uint32_t. We actually only + // need to initialize the refcount to 2 -- we are just doing an unbalanced + // incref to prevent the non-heap-allocated target from being + // freed, and we are optimizing that incref by directly + // initializing the refcounts rather than doing an expensive + // atomic increment. The reason to use kImpracticallyHugeReferenceCount is + // to accommodate the debug assertions in ~intrusive_ptr_target. +#ifdef NDEBUG + expected_decrefs = 0; +#endif + result.target_->combined_refcount_.store( + detail::refcount( + detail::kImpracticallyHugeReferenceCount + expected_decrefs) | + detail::kImpracticallyHugeWeakReferenceCount, + std::memory_order_relaxed); + return result; + } + + /** + * Turn a **non-owning raw pointer** to an intrusive_ptr. It is + * the moral equivalent of enable_shared_from_this on a shared pointer. + * + * This method is only valid for objects that are already live. If + * you are looking for the moral equivalent of unique_ptr(T*) + * constructor, see steal_from_new. + * + * TODO: https://github.com/pytorch/pytorch/issues/56482 + */ + static intrusive_ptr unsafe_reclaim_from_nonowning(TTarget* raw_ptr) { + // See Note [Stack allocated intrusive_ptr_target safety] + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + raw_ptr == NullType::singleton() || raw_ptr->refcount() > 0, + "intrusive_ptr: Can only reclaim pointers that are owned by someone"); + auto ptr = reclaim(raw_ptr); // doesn't increase refcount + ptr.retain_(); + return ptr; + } +}; + +template < + class TTarget, + class NullType = detail::intrusive_target_default_null_type, + class... Args> +inline intrusive_ptr make_intrusive(Args&&... args) { + return intrusive_ptr::make(std::forward(args)...); +} + +template +inline void swap( + intrusive_ptr& lhs, + intrusive_ptr& rhs) noexcept { + lhs.swap(rhs); +} + +// To allow intrusive_ptr inside std::map or std::set, we need operator< +template +inline bool operator<( + const intrusive_ptr& lhs, + const intrusive_ptr& rhs) noexcept { + return lhs.get() < rhs.get(); +} + +template +inline bool operator==( + const intrusive_ptr& lhs, + const intrusive_ptr& rhs) noexcept { + return lhs.get() == rhs.get(); +} + +template +inline bool operator==( + const intrusive_ptr& lhs, + std::nullptr_t) noexcept { + return lhs.get() == nullptr; +} + +template +inline bool operator==( + std::nullptr_t, + const intrusive_ptr& rhs) noexcept { + return nullptr == rhs.get(); +} + +template +inline bool operator!=( + const intrusive_ptr& lhs, + const intrusive_ptr& rhs) noexcept { + return !operator==(lhs, rhs); +} + +template +inline bool operator!=( + const intrusive_ptr& lhs, + std::nullptr_t) noexcept { + return !operator==(lhs, nullptr); +} + +template +inline bool operator!=( + std::nullptr_t, + const intrusive_ptr& rhs) noexcept { + return !operator==(nullptr, rhs); +} +template +struct MaybeOwnedTraits> { + using owned_type = c10::intrusive_ptr; + using borrow_type = c10::intrusive_ptr; + + static borrow_type createBorrow(const owned_type& from) { + return borrow_type::reclaim(from.get()); + } + + static void assignBorrow(borrow_type& lhs, const borrow_type& rhs) { + lhs.release(); + lhs = borrow_type::reclaim(rhs.get()); + } + + static void destroyBorrow(borrow_type& toDestroy) { + toDestroy.release(); + } + + static const owned_type& referenceFromBorrow( + const borrow_type& borrow) noexcept { + return borrow; + } + + static const owned_type* pointerFromBorrow( + const borrow_type& borrow) noexcept { + return &borrow; + } + + static bool debugBorrowIsValid(const borrow_type& /*borrow*/) noexcept { + return true; + } +}; + +template < + typename TTarget, + class NullType = detail::intrusive_target_default_null_type> +class weak_intrusive_ptr final { + private: + static_assert( + std::is_base_of_v, + "intrusive_ptr can only be used for classes that inherit from intrusive_ptr_target."); +#ifndef _WIN32 + // This static_assert triggers on MSVC + // error C2131: expression did not evaluate to a constant + static_assert( + NullType::singleton() == NullType::singleton(), + "NullType must have a constexpr singleton() method"); +#endif + static_assert( + std::is_base_of_v< + TTarget, + std::remove_pointer_t>, + "NullType::singleton() must return a element_type* pointer"); + + TTarget* target_; + + template + friend class weak_intrusive_ptr; + + void retain_() { + if (target_ != NullType::singleton()) { + uint32_t new_weakcount = + detail::atomic_weakcount_increment(target_->combined_refcount_); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + new_weakcount != 1, + "weak_intrusive_ptr: Cannot increase weakcount after it reached zero."); + } + } + + void reset_() noexcept { + if (target_ != NullType::singleton() && + detail::atomic_weakcount_decrement(target_->combined_refcount_) == 0) { + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDelete) + delete target_; + } + target_ = NullType::singleton(); + } + + constexpr explicit weak_intrusive_ptr(TTarget* target) : target_(target) {} + + public: + using element_type = TTarget; + + explicit weak_intrusive_ptr(const intrusive_ptr& ptr) + : weak_intrusive_ptr(ptr.get()) { + retain_(); + } + + weak_intrusive_ptr(weak_intrusive_ptr&& rhs) noexcept : target_(rhs.target_) { + rhs.target_ = NullType::singleton(); + } + + template + /* implicit */ weak_intrusive_ptr( + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + weak_intrusive_ptr&& rhs) noexcept + : target_( + detail::assign_ptr_(rhs.target_)) { + static_assert( + std::is_convertible_v, + "Type mismatch. weak_intrusive_ptr move constructor got pointer of wrong type."); + rhs.target_ = FromNullType::singleton(); + } + + weak_intrusive_ptr(const weak_intrusive_ptr& rhs) : target_(rhs.target_) { + retain_(); + } + + template + /* implicit */ weak_intrusive_ptr( + const weak_intrusive_ptr& rhs) + : target_( + detail::assign_ptr_(rhs.target_)) { + static_assert( + std::is_convertible_v, + "Type mismatch. weak_intrusive_ptr copy constructor got pointer of wrong type."); + retain_(); + } + + ~weak_intrusive_ptr() noexcept { + reset_(); + } + + weak_intrusive_ptr& operator=(weak_intrusive_ptr&& rhs) & noexcept { + // NOLINTNEXTLINE(*assign*) + return this->template operator= (std::move(rhs)); + } + + template + weak_intrusive_ptr& operator=( + weak_intrusive_ptr&& rhs) & noexcept { + static_assert( + std::is_convertible_v, + "Type mismatch. weak_intrusive_ptr move assignment got pointer of wrong type."); + weak_intrusive_ptr tmp = std::move(rhs); + swap(tmp); + return *this; + } + + weak_intrusive_ptr& operator=(const weak_intrusive_ptr& rhs) & noexcept { + if (this == &rhs) { + return *this; + } + // NOLINTNEXTLINE(*assign*) + return this->template operator= (rhs); + } + + weak_intrusive_ptr& operator=( + const intrusive_ptr& rhs) & noexcept { + weak_intrusive_ptr tmp(rhs); + swap(tmp); + return *this; + } + + template + weak_intrusive_ptr& operator=( + const weak_intrusive_ptr& rhs) & noexcept { + static_assert( + std::is_convertible_v, + "Type mismatch. weak_intrusive_ptr copy assignment got pointer of wrong type."); + weak_intrusive_ptr tmp = rhs; + swap(tmp); + return *this; + } + + void reset() noexcept { + reset_(); + } + + void swap(weak_intrusive_ptr& rhs) noexcept { + TTarget* tmp = target_; + target_ = rhs.target_; + rhs.target_ = tmp; + } + + // NB: This should ONLY be used by the std::hash implementation + // for weak_intrusive_ptr. Another way you could do this is + // friend std::hash, but this triggers two + // bugs: + // + // (1) It triggers an nvcc bug, where std::hash in a friend class + // declaration gets preprocessed into hash, which then cannot + // actually be found. The error in this case looks like: + // + // error: no template named 'hash'; did you mean 'std::hash'? + // + // (2) On OS X, std::hash is declared as a struct, not a class. + // This twings: + // + // error: class 'hash' was previously declared as a struct + // [-Werror,-Wmismatched-tags] + // + // Both of these are work-aroundable, but on the whole, I decided + // it would be simpler and easier to make work if we just expose + // an unsafe getter for target_ + // + TTarget* _unsafe_get_target() const noexcept { + return target_; + } + + uint32_t use_count() const noexcept { + if (target_ == NullType::singleton()) { + return 0; + } + return target_->refcount( + std::memory_order_relaxed); // refcount, not weakcount! + } + + uint32_t weak_use_count() const noexcept { + if (target_ == NullType::singleton()) { + return 0; + } + return target_->weakcount(std::memory_order_relaxed); + } + + bool expired() const noexcept { + return use_count() == 0; + } + + intrusive_ptr lock() const noexcept { + if (target_ == NullType::singleton()) { + return intrusive_ptr(); + } else { + bool increfed = false; + auto combined_refcount = + target_->combined_refcount_.load(std::memory_order_relaxed); + do { + if (detail::refcount(combined_refcount) == 0) { + // Object already destructed, no strong references left anymore. + // Return nullptr. + return intrusive_ptr(); + } + if constexpr (detail::TargetTraits::can_have_pyobject) { + if (detail::has_pyobject(combined_refcount) && + detail::refcount(combined_refcount) == 1 && !increfed) { + // Object has a python wrapper with no other C++ references. + // We need to to incref the Python object before we acquire a + // strong reference to the C++ object to avoid a situation + // where the Python object is deallocated concurrently. + if (!target_->try_incref_pyobject()) { + return intrusive_ptr(); + } + increfed = true; + } + } + } while (!target_->combined_refcount_.compare_exchange_weak( + combined_refcount, + combined_refcount + detail::kReferenceCountOne, + std::memory_order_acquire, + std::memory_order_relaxed)); + + if constexpr (detail::TargetTraits::can_have_pyobject) { + if (increfed && detail::refcount(combined_refcount) != 1) { + target_->decref_pyobject(); + } + } + + return intrusive_ptr( + target_, raw::DontIncreaseRefcount{}); + } + } + + /** + * Returns an owning (but still only weakly referenced) pointer to the + * underlying object and makes the weak_intrusive_ptr instance invalid. + * That means the weakcount is not decreased. + * You *must* put the returned pointer back into a weak_intrusive_ptr using + * weak_intrusive_ptr::reclaim(ptr) to properly destruct it. + * This is helpful for C APIs. + */ + TTarget* release() noexcept { + TTarget* result = target_; + target_ = NullType::singleton(); + return result; + } + + /** + * Takes an owning (but must be weakly referenced) pointer to TTarget* and + * creates a weak_intrusive_ptr that takes over ownership. + * This means that the weakcount is not increased. + * This is the counter-part to weak_intrusive_ptr::release() and the pointer + * passed in *must* have been created using weak_intrusive_ptr::release(). + */ + static weak_intrusive_ptr reclaim(TTarget* owning_weak_ptr) { + // See Note [Stack allocated intrusive_ptr_target safety] + // if refcount > 0, weakcount must be >1 for weak references to exist. + // see weak counting explanation at top of this file. + // if refcount == 0, weakcount only must be >0. + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + owning_weak_ptr == NullType::singleton() || + owning_weak_ptr->weakcount() > 1 || + (owning_weak_ptr->refcount() == 0 && + owning_weak_ptr->weakcount() > 0), + "weak_intrusive_ptr: Can only weak_intrusive_ptr::reclaim() owning pointers that were created using weak_intrusive_ptr::release()."); + return weak_intrusive_ptr(owning_weak_ptr); + } + + /** + * Takes a pointer to TTarget* (may be weak or strong) and creates a + * new weak_intrusive_ptr representing a new weak reference, i.e. + * the raw pointer retains ownership. + */ + static weak_intrusive_ptr reclaim_copy(TTarget* owning_ptr) { + auto ret = reclaim(owning_ptr); + ret.retain_(); + return ret; + } + + template + friend bool operator<( + const weak_intrusive_ptr& lhs, + const weak_intrusive_ptr& rhs) noexcept; + template + friend bool operator==( + const weak_intrusive_ptr& lhs, + const weak_intrusive_ptr& rhs) noexcept; +}; + +template +inline void swap( + weak_intrusive_ptr& lhs, + weak_intrusive_ptr& rhs) noexcept { + lhs.swap(rhs); +} + +// To allow weak_intrusive_ptr inside std::map or std::set, we need operator< +template +inline bool operator<( + const weak_intrusive_ptr& lhs, + const weak_intrusive_ptr& rhs) noexcept { + return lhs.target_ < rhs.target_; +} + +template +inline bool operator==( + const weak_intrusive_ptr& lhs, + const weak_intrusive_ptr& rhs) noexcept { + return lhs.target_ == rhs.target_; +} + +template +inline bool operator!=( + const weak_intrusive_ptr& lhs, + const weak_intrusive_ptr& rhs) noexcept { + return !operator==(lhs, rhs); +} + +// Alias for documentary purposes, to more easily distinguish +// weak raw intrusive pointers from intrusive pointers. +using weak_intrusive_ptr_target = intrusive_ptr_target; + +// This namespace provides some methods for working with +// raw pointers that subclass intrusive_ptr_target. They are not provided +// as methods on intrusive_ptr_target, because ideally you would not need these +// methods at all (use smart pointers), but if you are dealing with legacy code +// that still needs to pass around raw pointers, you may find these quite +// useful. +// +// An important usage note: some functions are only valid if you have a +// strong raw pointer to the object, while others are only valid if you +// have a weak raw pointer to the object. ONLY call intrusive_ptr namespace +// functions on strong pointers, and weak_intrusive_ptr namespace functions +// on weak pointers. If you mix it up, you may get an assert failure. +namespace raw { + +namespace intrusive_ptr { + +// WARNING: Unlike the reclaim() API, it is NOT valid to pass +// NullType::singleton to this function +inline void incref(intrusive_ptr_target* self) { + if (self) { + uint64_t combined = detail::atomic_combined_refcount_increment( + self->combined_refcount_, detail::kReferenceCountOne); + +#ifndef C10_MOBILE + if (detail::has_pyobject(combined) && detail::refcount(combined) == 2) { + self->incref_pyobject(); + } +#else + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(!detail::has_pyobject(combined)); +#endif + } +} + +// WARNING: Unlike the reclaim() API, it is NOT valid to pass +// NullType::singleton to this function +inline void decref(intrusive_ptr_target* self) { + // Let it die + c10::intrusive_ptr::reclaim(self); + // NB: Caller still has 'self' pointer, but it's now invalid. + // If you want more safety, used the actual c10::intrusive_ptr class +} + +template +inline T* make_weak(T* self) { + // NB: 'this' is a strong pointer, but we return a weak pointer + auto ptr = c10::intrusive_ptr::reclaim(self); + c10::weak_intrusive_ptr wptr(ptr); + ptr.release(); + return wptr.release(); +} + +inline uint32_t use_count(intrusive_ptr_target* self) { + auto ptr = c10::intrusive_ptr::reclaim(self); + auto r = ptr.use_count(); + ptr.release(); + return r; +} + +} // namespace intrusive_ptr + +namespace weak_intrusive_ptr { + +inline void incref(weak_intrusive_ptr_target* self) { + detail::atomic_weakcount_increment(self->combined_refcount_); +} + +inline void decref(weak_intrusive_ptr_target* self) { + // Let it die + c10::weak_intrusive_ptr::reclaim(self); + // NB: You still "have" the 'self' pointer, but it's now invalid. + // If you want more safety, used the actual c10::weak_intrusive_ptr class +} + +template +inline T* lock(T* self) { + auto wptr = c10::weak_intrusive_ptr::reclaim(self); + auto ptr = wptr.lock(); + wptr.release(); + return ptr.release(); +} + +// This gives the STRONG refcount of a WEAK pointer +inline uint32_t use_count(weak_intrusive_ptr_target* self) { + auto wptr = c10::weak_intrusive_ptr::reclaim(self); + auto r = wptr.use_count(); + wptr.release(); + return r; +} + +} // namespace weak_intrusive_ptr + +} // namespace raw + +} // namespace c10 + +namespace std { +// To allow intrusive_ptr and weak_intrusive_ptr inside std::unordered_map or +// std::unordered_set, we need std::hash +template +struct hash> { + size_t operator()(const c10::intrusive_ptr& x) const { + return std::hash()(x.get()); + } +}; +template +struct hash> { + size_t operator()(const c10::weak_intrusive_ptr& x) const { + return std::hash()(x._unsafe_get_target()); + } +}; +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/irange.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/irange.h new file mode 100644 index 0000000000000000000000000000000000000000..bc2a018db397a56dee0199af77509fc23dfe405b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/irange.h @@ -0,0 +1,128 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Copyright 2004-present Facebook. All Rights Reserved. + +#pragma once + +#include + +#include +#include +#include +#include + +namespace c10 { + +namespace detail { + +template < + typename I, + bool one_sided = false, + std::enable_if_t, int> = 0> +struct integer_iterator { + using iterator_category = std::input_iterator_tag; + using value_type = I; + using difference_type = std::ptrdiff_t; + using pointer = I*; + using reference = I&; + + explicit constexpr integer_iterator(I val) : value(val) {} + + constexpr I operator*() const { + return value; + } + + constexpr I const* operator->() const { + return &value; + } + + constexpr integer_iterator& operator++() { + ++value; + return *this; + } + + constexpr integer_iterator operator++(int) { + const auto copy = *this; + ++*this; + return copy; + } + + constexpr bool operator==(const integer_iterator& other) const { + if constexpr (one_sided) { + // Range-for loops' end test is `begin != end`, not `begin < + // end`. To handle `c10::irange(n)` where n < 0 (which should be + // empty), we just make `begin != end` fail whenever `end` is + // negative. + return is_negative(other.value) || value == other.value; + } else { + return value == other.value; + } + // Suppress "warning: missing return statement at end of non-void function" + // which Nvidia's Robert Crovella confirms is an NVCC compiler error + // here https://stackoverflow.com/a/64561686/752843 on 2020-10-27 + // `__builtin_unreachable();` would be best here, but it's not + // available with all compilers. So we instead return an arbitrary + // value trusting that this line will, in fact, never be reached. + return false; // Horrible hack + } + + constexpr bool operator!=(const integer_iterator& other) const { + return !(*this == other); + } + + protected: + I value; +}; + +} // namespace detail + +template < + typename I, + bool one_sided = false, + std::enable_if_t, bool> = true> +struct integer_range { + public: + constexpr integer_range(I begin, I end) : begin_(begin), end_(end) {} + using iterator = detail::integer_iterator; + constexpr iterator begin() const { + return begin_; + } + constexpr iterator end() const { + return end_; + } + + private: + iterator begin_; + iterator end_; +}; + +/// Creates an integer range for the half-open interval [begin, end) +/// If end<=begin, then the range is empty. +/// The range has the type of the `end` integer; `begin` integer is +/// cast to this type. +template < + typename Integer1, + typename Integer2, + std::enable_if_t, bool> = true, + std::enable_if_t, bool> = true> +constexpr integer_range irange(Integer1 begin, Integer2 end) { + // If end<=begin then the range is empty; we can achieve this effect by + // choosing the larger of {begin, end} as the loop terminator + return { + static_cast(begin), + std::max(static_cast(begin), end)}; +} + +/// Creates an integer range for the half-open interval [0, end) +/// If end<=begin, then the range is empty +template < + typename Integer, + std::enable_if_t, bool> = true> +constexpr integer_range irange(Integer end) { + return {Integer(), end}; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/llvmMathExtras.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/llvmMathExtras.h new file mode 100644 index 0000000000000000000000000000000000000000..6884e20d112ace8886c69b10499f830c58c3703f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/llvmMathExtras.h @@ -0,0 +1,910 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains some functions that are useful for math stuff. +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __ANDROID_NDK__ +#include +#endif + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + +#ifndef LLVM_GNUC_PREREQ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +#define LLVM_GNUC_PREREQ(maj, min, patch) \ + ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \ + ((maj) << 20) + ((min) << 10) + (patch)) +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) +#define LLVM_GNUC_PREREQ(maj, min, patch) \ + ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10)) +#else +#define LLVM_GNUC_PREREQ(maj, min, patch) 0 +#endif +#endif + +#ifdef _MSC_VER +// Declare these intrinsics manually rather including intrin.h. It's very +// expensive, and MathExtras.h is popular. +// #include +extern "C" { +unsigned char _BitScanForward(unsigned long* _Index, unsigned long _Mask); +unsigned char _BitScanForward64(unsigned long* _Index, unsigned __int64 _Mask); +unsigned char _BitScanReverse(unsigned long* _Index, unsigned long _Mask); +unsigned char _BitScanReverse64(unsigned long* _Index, unsigned __int64 _Mask); +} +#endif + +namespace c10::llvm { +/// The behavior an operation has on an input of 0. +enum ZeroBehavior { + /// The returned value is undefined. + ZB_Undefined, + /// The returned value is numeric_limits::max() + ZB_Max, + /// The returned value is numeric_limits::digits + ZB_Width +}; + +namespace detail { +template +struct TrailingZerosCounter { + static std::size_t count(T Val, ZeroBehavior /*unused*/) { + if (!Val) + return std::numeric_limits::digits; + if (Val & 0x1) + return 0; + + // Bisection method. + std::size_t ZeroBits = 0; + T Shift = std::numeric_limits::digits >> 1; + T Mask = std::numeric_limits::max() >> Shift; + while (Shift) { + if ((Val & Mask) == 0) { + Val >>= Shift; + ZeroBits |= Shift; + } + Shift >>= 1; + Mask >>= Shift; + } + return ZeroBits; + } +}; + +#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(_MSC_VER) +template +struct TrailingZerosCounter { + static std::size_t count(T Val, ZeroBehavior ZB) { + if (ZB != ZB_Undefined && Val == 0) + return 32; + +#if __has_builtin(__builtin_ctz) || LLVM_GNUC_PREREQ(4, 0, 0) + return __builtin_ctz(Val); +#elif defined(_MSC_VER) + unsigned long Index; + _BitScanForward(&Index, Val); + return Index; +#endif + } +}; + +#if !defined(_MSC_VER) || defined(_M_X64) +template +struct TrailingZerosCounter { + static std::size_t count(T Val, ZeroBehavior ZB) { + if (ZB != ZB_Undefined && Val == 0) + return 64; + +#if __has_builtin(__builtin_ctzll) || LLVM_GNUC_PREREQ(4, 0, 0) + return __builtin_ctzll(Val); +#elif defined(_MSC_VER) + unsigned long Index; + _BitScanForward64(&Index, Val); + return Index; +#endif + } +}; +#endif +#endif +} // namespace detail + +/// Count number of 0's from the least significant bit to the most +/// stopping at the first 1. +/// +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are +/// valid arguments. +template +std::size_t countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { + static_assert( + std::numeric_limits::is_integer && !std::numeric_limits::is_signed, + "Only unsigned integral types are allowed."); + return llvm::detail::TrailingZerosCounter::count(Val, ZB); +} + +namespace detail { +template +struct LeadingZerosCounter { + static std::size_t count(T Val, ZeroBehavior /*unused*/) { + if (!Val) + return std::numeric_limits::digits; + + // Bisection method. + std::size_t ZeroBits = 0; + for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { + T Tmp = Val >> Shift; + if (Tmp) + Val = Tmp; + else + ZeroBits |= Shift; + } + return ZeroBits; + } +}; + +#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(_MSC_VER) +template +struct LeadingZerosCounter { + static std::size_t count(T Val, ZeroBehavior ZB) { + if (ZB != ZB_Undefined && Val == 0) + return 32; + +#if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0) + return __builtin_clz(Val); +#elif defined(_MSC_VER) + unsigned long Index; + _BitScanReverse(&Index, Val); + return Index ^ 31; +#endif + } +}; + +#if !defined(_MSC_VER) || defined(_M_X64) +template +struct LeadingZerosCounter { + static std::size_t count(T Val, ZeroBehavior ZB) { + if (ZB != ZB_Undefined && Val == 0) + return 64; + +#if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0) + return __builtin_clzll(Val); +#elif defined(_MSC_VER) + unsigned long Index; + _BitScanReverse64(&Index, Val); + return Index ^ 63; +#endif + } +}; +#endif +#endif +} // namespace detail + +/// Count number of 0's from the most significant bit to the least +/// stopping at the first 1. +/// +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are +/// valid arguments. +template +std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { + static_assert( + std::numeric_limits::is_integer && !std::numeric_limits::is_signed, + "Only unsigned integral types are allowed."); + return llvm::detail::LeadingZerosCounter::count(Val, ZB); +} + +/// Get the index of the first set bit starting from the least +/// significant bit. +/// +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are +/// valid arguments. +template +T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { + if (ZB == ZB_Max && Val == 0) + return std::numeric_limits::max(); + + return countTrailingZeros(Val, ZB_Undefined); +} + +/// Create a bitmask with the N right-most bits set to 1, and all other +/// bits set to 0. Only unsigned types are allowed. +template +T maskTrailingOnes(unsigned N) { + static_assert(std::is_unsigned_v, "Invalid type!"); + const unsigned Bits = CHAR_BIT * sizeof(T); + assert(N <= Bits && "Invalid bit index"); + return N == 0 ? 0 : (T(-1) >> (Bits - N)); +} + +/// Create a bitmask with the N left-most bits set to 1, and all other +/// bits set to 0. Only unsigned types are allowed. +template +T maskLeadingOnes(unsigned N) { + return ~maskTrailingOnes(CHAR_BIT * sizeof(T) - N); +} + +/// Create a bitmask with the N right-most bits set to 0, and all other +/// bits set to 1. Only unsigned types are allowed. +template +T maskTrailingZeros(unsigned N) { + return maskLeadingOnes(CHAR_BIT * sizeof(T) - N); +} + +/// Create a bitmask with the N left-most bits set to 0, and all other +/// bits set to 1. Only unsigned types are allowed. +template +T maskLeadingZeros(unsigned N) { + return maskTrailingOnes(CHAR_BIT * sizeof(T) - N); +} + +/// Get the index of the last set bit starting from the least +/// significant bit. +/// +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are +/// valid arguments. +template +T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { + if (ZB == ZB_Max && Val == 0) + return std::numeric_limits::max(); + + // Use ^ instead of - because both gcc and llvm can remove the associated ^ + // in the __builtin_clz intrinsic on x86. + return countLeadingZeros(Val, ZB_Undefined) ^ + (std::numeric_limits::digits - 1); +} + +/// Macro compressed bit reversal table for 256 bits. +/// +/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable +/// NOLINTNEXTLINE(*c-arrays*) +static constexpr unsigned char BitReverseTable256[256] = { +#define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64 +#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16) +#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4) + R6(0), + R6(2), + R6(1), + R6(3) +#undef R2 +#undef R4 +#undef R6 +}; + +/// Reverse the bits in \p Val. +template +T reverseBits(T Val) { + // NOLINTNEXTLINE(*c-arrays*) + unsigned char in[sizeof(Val)]; + // NOLINTNEXTLINE(*c-arrays*) + unsigned char out[sizeof(Val)]; + std::memcpy(in, &Val, sizeof(Val)); + for (unsigned i = 0; i < sizeof(Val); ++i) + out[(sizeof(Val) - i) - 1] = BitReverseTable256[in[i]]; + std::memcpy(&Val, out, sizeof(Val)); + return Val; +} + +// NOTE: The following support functions use the _32/_64 extensions instead of +// type overloading so that signed and unsigned integers can be used without +// ambiguity. + +/// Return the high 32 bits of a 64 bit value. +constexpr inline uint32_t Hi_32(uint64_t Value) { + return static_cast(Value >> 32); +} + +/// Return the low 32 bits of a 64 bit value. +constexpr inline uint32_t Lo_32(uint64_t Value) { + return static_cast(Value); +} + +/// Make a 64-bit integer from a high / low pair of 32-bit integers. +constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) { + return ((uint64_t)High << 32) | (uint64_t)Low; +} + +/// Checks if an integer fits into the given bit width. +template +constexpr inline bool isInt(int64_t x) { + return N >= 64 || + (-(INT64_C(1) << (N - 1)) <= x && x < (INT64_C(1) << (N - 1))); +} +// Template specializations to get better code for common cases. +template <> +constexpr inline bool isInt<8>(int64_t x) { + return static_cast(x) == x; +} +template <> +constexpr inline bool isInt<16>(int64_t x) { + return static_cast(x) == x; +} +template <> +constexpr inline bool isInt<32>(int64_t x) { + return static_cast(x) == x; +} + +/// Checks if a signed integer is an N bit number shifted left by S. +template +constexpr inline bool isShiftedInt(int64_t x) { + static_assert( + N > 0, "isShiftedInt<0> doesn't make sense (refers to a 0-bit number."); + static_assert(N + S <= 64, "isShiftedInt with N + S > 64 is too wide."); + return isInt(x) && (x % (UINT64_C(1) << S) == 0); +} + +/// Checks if an unsigned integer fits into the given bit width. +/// +/// This is written as two functions rather than as simply +/// +/// return N >= 64 || X < (UINT64_C(1) << N); +/// +/// to keep MSVC from (incorrectly) warning on isUInt<64> that we're shifting +/// left too many places. +template +constexpr inline std::enable_if_t<(N < 64), bool> isUInt(uint64_t X) { + static_assert(N > 0, "isUInt<0> doesn't make sense"); + return X < (UINT64_C(1) << N); +} +template +constexpr inline std::enable_if_t= 64, bool> isUInt(uint64_t /*X*/) { + return true; +} + +// Template specializations to get better code for common cases. +template <> +constexpr inline bool isUInt<8>(uint64_t x) { + return static_cast(x) == x; +} +template <> +constexpr inline bool isUInt<16>(uint64_t x) { + return static_cast(x) == x; +} +template <> +constexpr inline bool isUInt<32>(uint64_t x) { + return static_cast(x) == x; +} + +/// Checks if a unsigned integer is an N bit number shifted left by S. +template +constexpr inline bool isShiftedUInt(uint64_t x) { + static_assert( + N > 0, "isShiftedUInt<0> doesn't make sense (refers to a 0-bit number)"); + static_assert( + N + S <= 64, "isShiftedUInt with N + S > 64 is too wide."); + // Per the two static_asserts above, S must be strictly less than 64. So + // 1 << S is not undefined behavior. + return isUInt(x) && (x % (UINT64_C(1) << S) == 0); +} + +/// Gets the maximum value for a N-bit unsigned integer. +inline uint64_t maxUIntN(uint64_t N) { + assert(N > 0 && N <= 64 && "integer width out of range"); + + // uint64_t(1) << 64 is undefined behavior, so we can't do + // (uint64_t(1) << N) - 1 + // without checking first that N != 64. But this works and doesn't have a + // branch. + return UINT64_MAX >> (64 - N); +} + +// Ignore the false warning "Arithmetic overflow" for MSVC +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4146) +#endif + +/// Gets the minimum value for a N-bit signed integer. +inline int64_t minIntN(int64_t N) { + assert(N > 0 && N <= 64 && "integer width out of range"); + // NOLINTNEXTLINE(*-narrowing-conversions) + return -(UINT64_C(1) << (N - 1)); +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +/// Gets the maximum value for a N-bit signed integer. +inline int64_t maxIntN(int64_t N) { + assert(N > 0 && N <= 64 && "integer width out of range"); + + // This relies on two's complement wraparound when N == 64, so we convert to + // int64_t only at the very end to avoid UB. + // NOLINTNEXTLINE(*-narrowing-conversions) + return (UINT64_C(1) << (N - 1)) - 1; +} + +/// Checks if an unsigned integer fits into the given (dynamic) bit width. +inline bool isUIntN(unsigned N, uint64_t x) { + return N >= 64 || x <= maxUIntN(N); +} + +/// Checks if an signed integer fits into the given (dynamic) bit width. +inline bool isIntN(unsigned N, int64_t x) { + return N >= 64 || (minIntN(N) <= x && x <= maxIntN(N)); +} + +/// Return true if the argument is a non-empty sequence of ones starting at the +/// least significant bit with the remainder zero (32 bit version). +/// Ex. isMask_32(0x0000FFFFU) == true. +constexpr inline bool isMask_32(uint32_t Value) { + return Value && ((Value + 1) & Value) == 0; +} + +/// Return true if the argument is a non-empty sequence of ones starting at the +/// least significant bit with the remainder zero (64 bit version). +constexpr inline bool isMask_64(uint64_t Value) { + return Value && ((Value + 1) & Value) == 0; +} + +/// Return true if the argument contains a non-empty sequence of ones with the +/// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true. +constexpr inline bool isShiftedMask_32(uint32_t Value) { + return Value && isMask_32((Value - 1) | Value); +} + +/// Return true if the argument contains a non-empty sequence of ones with the +/// remainder zero (64 bit version.) +constexpr inline bool isShiftedMask_64(uint64_t Value) { + return Value && isMask_64((Value - 1) | Value); +} + +/// Return true if the argument is a power of two > 0. +/// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.) +constexpr inline bool isPowerOf2_32(uint32_t Value) { + return Value && !(Value & (Value - 1)); +} + +/// Return true if the argument is a power of two > 0 (64 bit edition.) +constexpr inline bool isPowerOf2_64(uint64_t Value) { + return Value && !(Value & (Value - 1)); +} + +/// Count the number of ones from the most significant bit to the first +/// zero bit. +/// +/// Ex. countLeadingOnes(0xFF0FFF00) == 8. +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of all ones. Only ZB_Width and +/// ZB_Undefined are valid arguments. +template +std::size_t countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) { + static_assert( + std::numeric_limits::is_integer && !std::numeric_limits::is_signed, + "Only unsigned integral types are allowed."); + return countLeadingZeros(~Value, ZB); +} + +/// Count the number of ones from the least significant bit to the first +/// zero bit. +/// +/// Ex. countTrailingOnes(0x00FF00FF) == 8. +/// Only unsigned integral types are allowed. +/// +/// \param ZB the behavior on an input of all ones. Only ZB_Width and +/// ZB_Undefined are valid arguments. +template +std::size_t countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) { + static_assert( + std::numeric_limits::is_integer && !std::numeric_limits::is_signed, + "Only unsigned integral types are allowed."); + return countTrailingZeros(~Value, ZB); +} + +namespace detail { +template +struct PopulationCounter { + static unsigned count(T Value) { + // Generic version, forward to 32 bits. + static_assert(SizeOfT <= 4, "Not implemented!"); +#if defined(__GNUC__) && __GNUC__ >= 4 + return __builtin_popcount(Value); +#else + uint32_t v = Value; + v = v - ((v >> 1) & 0x55555555); + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); + return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; +#endif + } +}; + +template +struct PopulationCounter { + static unsigned count(T Value) { +#if defined(__GNUC__) && __GNUC__ >= 4 + return __builtin_popcountll(Value); +#else + uint64_t v = Value; + v = v - ((v >> 1) & 0x5555555555555555ULL); + v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL); + v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL; + return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56); +#endif + } +}; +} // namespace detail + +/// Count the number of set bits in a value. +/// Ex. countPopulation(0xF000F000) = 8 +/// Returns 0 if the word is zero. +template +inline unsigned countPopulation(T Value) { + static_assert( + std::numeric_limits::is_integer && !std::numeric_limits::is_signed, + "Only unsigned integral types are allowed."); + return detail::PopulationCounter::count(Value); +} + +/// Return the log base 2 of the specified value. +inline double Log2(double Value) { +#if defined(__ANDROID_API__) && __ANDROID_API__ < 18 + return __builtin_log(Value) / __builtin_log(2.0); +#else + return log2(Value); +#endif +} + +/// Return the floor log base 2 of the specified value, -1 if the value is zero. +/// (32 bit edition.) +/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 +inline unsigned Log2_32(uint32_t Value) { + return static_cast(31 - countLeadingZeros(Value)); +} + +/// Return the floor log base 2 of the specified value, -1 if the value is zero. +/// (64 bit edition.) +inline unsigned Log2_64(uint64_t Value) { + return static_cast(63 - countLeadingZeros(Value)); +} + +/// Return the ceil log base 2 of the specified value, 32 if the value is zero. +/// (32 bit edition). +/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 +inline unsigned Log2_32_Ceil(uint32_t Value) { + return static_cast(32 - countLeadingZeros(Value - 1)); +} + +/// Return the ceil log base 2 of the specified value, 64 if the value is zero. +/// (64 bit edition.) +inline unsigned Log2_64_Ceil(uint64_t Value) { + return static_cast(64 - countLeadingZeros(Value - 1)); +} + +/// Return the greatest common divisor of the values using Euclid's algorithm. +inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) { + while (B) { + uint64_t T = B; + B = A % B; + A = T; + } + return A; +} + +/// This function takes a 64-bit integer and returns the bit equivalent double. +inline double BitsToDouble(uint64_t Bits) { + double D = 0; + static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes"); + memcpy(&D, &Bits, sizeof(Bits)); + return D; +} + +/// This function takes a 32-bit integer and returns the bit equivalent float. +inline float BitsToFloat(uint32_t Bits) { + // TODO: Use std::bit_cast once C++20 becomes available. + return c10::bit_cast(Bits); +} + +/// This function takes a double and returns the bit equivalent 64-bit integer. +/// Note that copying doubles around changes the bits of NaNs on some hosts, +/// notably x86, so this routine cannot be used if these bits are needed. +inline uint64_t DoubleToBits(double Double) { + // NOLINTNEXTLINE(cppcoreguidelines-init-variables) + uint64_t Bits; + static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes"); + memcpy(&Bits, &Double, sizeof(Double)); + return Bits; +} + +/// This function takes a float and returns the bit equivalent 32-bit integer. +/// Note that copying floats around changes the bits of NaNs on some hosts, +/// notably x86, so this routine cannot be used if these bits are needed. +inline uint32_t FloatToBits(float Float) { + // NOLINTNEXTLINE(cppcoreguidelines-init-variables) + uint32_t Bits; + static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes"); + memcpy(&Bits, &Float, sizeof(Float)); + return Bits; +} + +/// A and B are either alignments or offsets. Return the minimum alignment that +/// may be assumed after adding the two together. +constexpr inline uint64_t MinAlign(uint64_t A, uint64_t B) { + // The largest power of 2 that divides both A and B. + // + // Replace "-Value" by "1+~Value" in the following commented code to avoid + // MSVC warning C4146 + // return (A | B) & -(A | B); + return (A | B) & (1 + ~(A | B)); +} + +/// Aligns \c Addr to \c Alignment bytes, rounding up. +/// +/// Alignment should be a power of two. This method rounds up, so +/// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8. +inline uintptr_t alignAddr(const void* Addr, size_t Alignment) { + assert( + Alignment && isPowerOf2_64((uint64_t)Alignment) && + "Alignment is not a power of two!"); + + assert((uintptr_t)Addr + Alignment - 1 >= (uintptr_t)Addr); + + return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1)); +} + +/// Returns the necessary adjustment for aligning \c Ptr to \c Alignment +/// bytes, rounding up. +inline size_t alignmentAdjustment(const void* Ptr, size_t Alignment) { + return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr; +} + +/// Returns the next power of two (in 64-bits) that is strictly greater than A. +/// Returns zero on overflow. +inline uint64_t NextPowerOf2(uint64_t A) { + A |= (A >> 1); + A |= (A >> 2); + A |= (A >> 4); + A |= (A >> 8); + A |= (A >> 16); + A |= (A >> 32); + return A + 1; +} + +/// Returns the power of two which is less than or equal to the given value. +/// Essentially, it is a floor operation across the domain of powers of two. +inline uint64_t PowerOf2Floor(uint64_t A) { + if (!A) + return 0; + return 1ull << (63 - countLeadingZeros(A, ZB_Undefined)); +} + +/// Returns the power of two which is greater than or equal to the given value. +/// Essentially, it is a ceil operation across the domain of powers of two. +inline uint64_t PowerOf2Ceil(uint64_t A) { + if (!A) + return 0; + return NextPowerOf2(A - 1); +} + +/// Returns the next integer (mod 2**64) that is greater than or equal to +/// \p Value and is a multiple of \p Align. \p Align must be non-zero. +/// +/// If non-zero \p Skew is specified, the return value will be a minimal +/// integer that is greater than or equal to \p Value and equal to +/// \p Align * N + \p Skew for some integer N. If \p Skew is larger than +/// \p Align, its value is adjusted to '\p Skew mod \p Align'. +/// +/// Examples: +/// \code +/// alignTo(5, 8) = 8 +/// alignTo(17, 8) = 24 +/// alignTo(~0LL, 8) = 0 +/// alignTo(321, 255) = 510 +/// +/// alignTo(5, 8, 7) = 7 +/// alignTo(17, 8, 1) = 17 +/// alignTo(~0LL, 8, 3) = 3 +/// alignTo(321, 255, 42) = 552 +/// \endcode +inline uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew = 0) { + assert(Align != 0u && "Align can't be 0."); + Skew %= Align; + return (Value + Align - 1 - Skew) / Align * Align + Skew; +} + +/// Returns the next integer (mod 2**64) that is greater than or equal to +/// \p Value and is a multiple of \c Align. \c Align must be non-zero. +template +constexpr inline uint64_t alignTo(uint64_t Value) { + static_assert(Align != 0u, "Align must be non-zero"); + return (Value + Align - 1) / Align * Align; +} + +/// Returns the integer ceil(Numerator / Denominator). +inline uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) { + return alignTo(Numerator, Denominator) / Denominator; +} + +/// \c alignTo for contexts where a constant expression is required. +/// \sa alignTo +/// +/// \todo FIXME: remove when \c constexpr becomes really \c constexpr +template +struct AlignTo { + static_assert(Align != 0u, "Align must be non-zero"); + template + struct from_value { + static const uint64_t value = (Value + Align - 1) / Align * Align; + }; +}; + +/// Returns the largest uint64_t less than or equal to \p Value and is +/// \p Skew mod \p Align. \p Align must be non-zero +inline uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew = 0) { + assert(Align != 0u && "Align can't be 0."); + Skew %= Align; + return (Value - Skew) / Align * Align + Skew; +} + +/// Returns the offset to the next integer (mod 2**64) that is greater than +/// or equal to \p Value and is a multiple of \p Align. \p Align must be +/// non-zero. +inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) { + return alignTo(Value, Align) - Value; +} + +/// Sign-extend the number in the bottom B bits of X to a 32-bit integer. +/// Requires 0 < B <= 32. +template +constexpr inline int32_t SignExtend32(uint32_t X) { + static_assert(B > 0, "Bit width can't be 0."); + static_assert(B <= 32, "Bit width out of range."); + return int32_t(X << (32 - B)) >> (32 - B); +} + +/// Sign-extend the number in the bottom B bits of X to a 32-bit integer. +/// Requires 0 < B < 32. +inline int32_t SignExtend32(uint32_t X, unsigned B) { + assert(B > 0 && "Bit width can't be 0."); + assert(B <= 32 && "Bit width out of range."); + return int32_t(X << (32 - B)) >> (32 - B); +} + +/// Sign-extend the number in the bottom B bits of X to a 64-bit integer. +/// Requires 0 < B < 64. +template +constexpr inline int64_t SignExtend64(uint64_t x) { + static_assert(B > 0, "Bit width can't be 0."); + static_assert(B <= 64, "Bit width out of range."); + return int64_t(x << (64 - B)) >> (64 - B); +} + +/// Sign-extend the number in the bottom B bits of X to a 64-bit integer. +/// Requires 0 < B < 64. +inline int64_t SignExtend64(uint64_t X, unsigned B) { + assert(B > 0 && "Bit width can't be 0."); + assert(B <= 64 && "Bit width out of range."); + return int64_t(X << (64 - B)) >> (64 - B); +} + +/// Subtract two unsigned integers, X and Y, of type T and return the absolute +/// value of the result. +template +std::enable_if_t, T> AbsoluteDifference(T X, T Y) { + return std::max(X, Y) - std::min(X, Y); +} + +/// Add two unsigned integers, X and Y, of type T. Clamp the result to the +/// maximum representable value of T on overflow. ResultOverflowed indicates if +/// the result is larger than the maximum representable value of type T. +template +std::enable_if_t, T> SaturatingAdd( + T X, + T Y, + bool* ResultOverflowed = nullptr) { + // NOLINTNEXTLINE(cppcoreguidelines-init-variables) + bool Dummy; + bool& Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; + // Hacker's Delight, p. 29 + T Z = X + Y; + Overflowed = (Z < X || Z < Y); + if (Overflowed) + return std::numeric_limits::max(); + else + return Z; +} + +/// Multiply two unsigned integers, X and Y, of type T. Clamp the result to the +/// maximum representable value of T on overflow. ResultOverflowed indicates if +/// the result is larger than the maximum representable value of type T. +template +std::enable_if_t, T> SaturatingMultiply( + T X, + T Y, + bool* ResultOverflowed = nullptr) { + // NOLINTNEXTLINE(cppcoreguidelines-init-variables) + bool Dummy; + bool& Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; + + // Hacker's Delight, p. 30 has a different algorithm, but we don't use that + // because it fails for uint16_t (where multiplication can have undefined + // behavior due to promotion to int), and requires a division in addition + // to the multiplication. + + Overflowed = false; + + // Log2(Z) would be either Log2Z or Log2Z + 1. + // Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z + // will necessarily be less than Log2Max as desired. + int Log2Z = Log2_64(X) + Log2_64(Y); + const T Max = std::numeric_limits::max(); + int Log2Max = Log2_64(Max); + if (Log2Z < Log2Max) { + return X * Y; + } + if (Log2Z > Log2Max) { + Overflowed = true; + return Max; + } + + // We're going to use the top bit, and maybe overflow one + // bit past it. Multiply all but the bottom bit then add + // that on at the end. + T Z = (X >> 1) * Y; + if (Z & ~(Max >> 1)) { + Overflowed = true; + return Max; + } + Z <<= 1; + if (X & 1) + return SaturatingAdd(Z, Y, ResultOverflowed); + + return Z; +} + +/// Multiply two unsigned integers, X and Y, and add the unsigned integer, A to +/// the product. Clamp the result to the maximum representable value of T on +/// overflow. ResultOverflowed indicates if the result is larger than the +/// maximum representable value of type T. +template +std::enable_if_t, T> SaturatingMultiplyAdd( + T X, + T Y, + T A, + bool* ResultOverflowed = nullptr) { + // NOLINTNEXTLINE(cppcoreguidelines-init-variables) + bool Dummy; + bool& Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; + + T Product = SaturatingMultiply(X, Y, &Overflowed); + if (Overflowed) + return Product; + + return SaturatingAdd(A, Product, &Overflowed); +} + +/// Use this rather than HUGE_VALF; the latter causes warnings on MSVC. +extern const float huge_valf; +} // namespace c10::llvm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/logging_common.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/logging_common.h new file mode 100644 index 0000000000000000000000000000000000000000..b554f68e18e1e8cccce5f3315cf8e0d0d8a0e9b4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/logging_common.h @@ -0,0 +1,80 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_LOGGING_COMMON_H_ +#define C10_UTIL_LOGGING_COMMON_H_ + +#include +#include +#include + +namespace c10 { + +// MessageLogger that throws exceptions instead of aborting (glog version) +// or logs and may abort (non-glog version). +class C10_API MessageLogger { + public: + MessageLogger( + SourceLocation source_location, + int severity, + bool exit_on_fatal = true); + ~MessageLogger() noexcept(false); + + // Return the stream associated with the logger object. + std::stringstream& stream(); + + private: + // When there is a fatal log, and fatal == true, we abort + // otherwise, we throw. + void DealWithFatal(); + +#if defined(ANDROID) && !defined(C10_USE_GLOG) + const char* tag_{"native"}; +#endif + std::stringstream stream_; + int severity_; + bool exit_on_fatal_; + SourceLocation source_location_; +}; + +// This class is used to explicitly ignore values in the conditional +// logging macros. This avoids compiler warnings like "value computed +// is not used" and "statement has no effect". +class C10_API LoggerVoidify { + public: + LoggerVoidify() = default; + // This has to be an operator with a precedence lower than << but + // higher than ?: + void operator&(const std::ostream& s [[maybe_unused]]) {} +}; + +// Forward declarations for CheckNotNull functions +template +T& CheckNotNullCommon( + const char* file, + int line, + const char* names, + T& t, + bool fatal = true); + +template +T* CheckNotNull( + const char* file, + int line, + const char* names, + T* t, + bool fatal = true); + +template +T& CheckNotNull( + const char* file, + int line, + const char* names, + T& t, + bool fatal = true); + +} // namespace c10 + +#endif // C10_UTIL_LOGGING_COMMON_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/logging_is_google_glog.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/logging_is_google_glog.h new file mode 100644 index 0000000000000000000000000000000000000000..1e8db989b5e545edc8f44b11fc3e763c2d333cb9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/logging_is_google_glog.h @@ -0,0 +1,114 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_LOGGING_IS_GOOGLE_GLOG_H_ +#define C10_UTIL_LOGGING_IS_GOOGLE_GLOG_H_ + +#include +#include +#include + +#include // because some of the caffe2 code uses e.g. std::setw +// Using google glog. For glog 0.3.2 versions, stl_logging.h needs to be before +// logging.h to actually use stl_logging. Because template magic. +// In addition, we do not do stl logging in .cu files because nvcc does not like +// it. Some mobile platforms do not like stl_logging, so we add an +// overload in that case as well. + +#ifdef __CUDACC__ +#include +#endif + +#if !defined(__CUDACC__) && !defined(C10_USE_MINIMAL_GLOG) +#include + +// Old versions of glog don't declare this using declaration, so help +// them out. Fortunately, C++ won't complain if you declare the same +// using declaration multiple times. +namespace std { +using ::operator<<; +} + +#else // !defined(__CUDACC__) && !defined(C10_USE_MINIMAL_GLOG) + +// In the cudacc compiler scenario, we will simply ignore the container +// printout feature. Basically we need to register a fake overload for +// vector/string - here, we just ignore the entries in the logs. + +namespace std { +#define INSTANTIATE_FOR_CONTAINER(container) \ + template \ + ostream& operator<<(ostream& out, const container&) { \ + return out; \ + } + +INSTANTIATE_FOR_CONTAINER(vector) +INSTANTIATE_FOR_CONTAINER(map) +INSTANTIATE_FOR_CONTAINER(set) +#undef INSTANTIATE_FOR_CONTAINER +} // namespace std + +#endif + +#include +#include + +namespace c10 { + +[[noreturn]] void ThrowEnforceNotMet( + const char* file, + const int line, + const char* condition, + const std::string& msg, + const void* caller); + +template +T& CheckNotNullCommon( + const char* file, + int line, + const char* names, + T& t, + bool fatal) { + if (t == nullptr) { + MessageLogger( + SourceLocation::current(file, nullptr, line), + ::google::GLOG_FATAL, + fatal) + .stream() + << "Check failed: '" << names << "' must be non NULL. "; + } + return t; +} + +template +T* CheckNotNull( + const char* file, + int line, + const char* names, + T* t, + bool fatal) { + return CheckNotNullCommon(file, line, names, t, fatal); +} + +template +T& CheckNotNull( + const char* file, + int line, + const char* names, + T& t, + bool fatal) { + return CheckNotNullCommon(file, line, names, t, fatal); +} + +} // namespace c10 + +// Log with source location information override (to be used in generic +// warning/error handlers implemented as functions, not macros) +// +// Note, we don't respect GOOGLE_STRIP_LOG here for simplicity +#define LOG_AT_FILE_LINE(n, file, line) \ + ::google::LogMessage(file, line, ::google::GLOG_##n).stream() + +#endif // C10_UTIL_LOGGING_IS_GOOGLE_GLOG_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/logging_is_not_google_glog.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/logging_is_not_google_glog.h new file mode 100644 index 0000000000000000000000000000000000000000..8aaf7b7164ab741ceeb46b1901688a414e34fe4a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/logging_is_not_google_glog.h @@ -0,0 +1,195 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef C10_UTIL_LOGGING_IS_NOT_GOOGLE_GLOG_H_ +#define C10_UTIL_LOGGING_IS_NOT_GOOGLE_GLOG_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +const char CAFFE2_SEVERITY_PREFIX[] = "FEWIV"; + +namespace c10 { + +// Log severity level constants. +const int GLOG_FATAL = 3; +const int GLOG_ERROR = 2; +const int GLOG_WARNING = 1; +const int GLOG_INFO = 0; + +// Helpers for TORCH_CHECK_NOTNULL(). Two are necessary to support both raw +// pointers and smart pointers. +template +T& CheckNotNullCommon( + const char* file, + int line, + const char* names, + T& t, + bool fatal) { + if (t == nullptr) { + MessageLogger( + SourceLocation::current(file, nullptr, line), GLOG_FATAL, fatal) + .stream() + << "Check failed: '" << names << "' must be non NULL. "; + } + return t; +} + +template +T* CheckNotNull( + const char* file, + int line, + const char* names, + T* t, + bool fatal) { + return CheckNotNullCommon(file, line, names, t, fatal); +} + +template +T& CheckNotNull( + const char* file, + int line, + const char* names, + T& t, + bool fatal) { + return CheckNotNullCommon(file, line, names, t, fatal); +} +} // namespace c10 + +// ---------------------- Logging Macro definitions -------------------------- + +static_assert( + CAFFE2_LOG_THRESHOLD <= ::c10::GLOG_FATAL, + "CAFFE2_LOG_THRESHOLD should at most be GLOG_FATAL."); +// If n is under the compile time caffe log threshold, The _CAFFE_LOG(n) +// should not generate anything in optimized code. +#define LOG(n) \ + if (::c10::GLOG_##n >= CAFFE2_LOG_THRESHOLD) \ + ::c10::MessageLogger(::c10::SourceLocation::current(), ::c10::GLOG_##n) \ + .stream() +#define VLOG(n) \ + if (-n >= CAFFE2_LOG_THRESHOLD) \ + ::c10::MessageLogger(::c10::SourceLocation::current(), -n).stream() + +#define LOG_IF(n, condition) \ + if (::c10::GLOG_##n >= CAFFE2_LOG_THRESHOLD && (condition)) \ + ::c10::MessageLogger(::c10::SourceLocation::current(), ::c10::GLOG_##n) \ + .stream() +#define VLOG_IF(n, condition) \ + if (-n >= CAFFE2_LOG_THRESHOLD && (condition)) \ + ::c10::MessageLogger(::c10::SourceLocation::current(), -n).stream() + +#define VLOG_IS_ON(verboselevel) (CAFFE2_LOG_THRESHOLD <= -(verboselevel)) + +// Log with source location information override (to be used in generic +// warning/error handlers implemented as functions, not macros) +#define LOG_AT_FILE_LINE(n, file, line) \ + if (::c10::GLOG_##n >= CAFFE2_LOG_THRESHOLD) \ + ::c10::MessageLogger( \ + ::c10::SourceLocation::current(file, nullptr, line), ::c10::GLOG_##n) \ + .stream() +// Log only if condition is met. Otherwise evaluates to void. +#define FATAL_IF(condition) \ + condition ? (void)0 \ + : ::c10::LoggerVoidify() & \ + ::c10::MessageLogger( \ + ::c10::SourceLocation::current(), ::c10::GLOG_FATAL) \ + .stream() + +// Check for a given boolean condition. +#define CHECK(condition) FATAL_IF(condition) << "Check failed: " #condition " " + +#ifndef NDEBUG +// Debug only version of CHECK +#define DCHECK(condition) FATAL_IF(condition) << "Check failed: " #condition " " +#define DLOG(severity) LOG(severity) +#else // NDEBUG +// Optimized version - generates no code. +#define DCHECK(condition) \ + while (false) \ + CHECK(condition) + +#define DLOG(n) \ + true ? (void)0 \ + : ::c10::LoggerVoidify() & \ + ::c10::MessageLogger( \ + ::c10::SourceLocation::current(), ::c10::GLOG_##n) \ + .stream() +#endif // NDEBUG + +// ---------------------- Support for std objects -------------------------- +// These are adapted from glog to support a limited set of logging capability +// for STL objects. + +namespace std { +// Forward declare these two, and define them after all the container streams +// operators so that we can recurse from pair -> container -> container -> pair +// properly. +template +std::ostream& operator<<(std::ostream& out, const std::pair& p); +} // namespace std + +namespace c10 { +template +void PrintSequence(std::ostream& ss, Iter begin, Iter end); +} // namespace c10 + +namespace std { +#define INSTANTIATE_FOR_CONTAINER(container) \ + template \ + std::ostream& operator<<( \ + std::ostream& out, const container& seq) { \ + c10::PrintSequence(out, seq.begin(), seq.end()); \ + return out; \ + } + +INSTANTIATE_FOR_CONTAINER(std::vector) +INSTANTIATE_FOR_CONTAINER(std::map) +INSTANTIATE_FOR_CONTAINER(std::set) +#undef INSTANTIATE_FOR_CONTAINER + +template +inline std::ostream& operator<<( + std::ostream& out, + const std::pair& p) { + out << '(' << p.first << ", " << p.second << ')'; + return out; +} + +inline std::ostream& operator<<( + std::ostream& out, + const std::nullptr_t& /*unused*/) { + out << "(null)"; + return out; +} +} // namespace std + +namespace c10 { +template +inline void PrintSequence(std::ostream& out, Iter begin, Iter end) { + // Output at most 100 elements -- appropriate if used for logging. + for (int i = 0; begin != end && i < 100; ++i, ++begin) { + if (i > 0) + out << ' '; + out << *begin; + } + if (begin != end) { + out << " ..."; + } +} +} // namespace c10 + +#endif // C10_UTIL_LOGGING_IS_NOT_GOOGLE_GLOG_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/numa.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/numa.h new file mode 100644 index 0000000000000000000000000000000000000000..4ae58609b5d56135e59075d5428e03a6c99ff230 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/numa.h @@ -0,0 +1,46 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +C10_DECLARE_bool(caffe2_cpu_numa_enabled); + +namespace c10 { + +/** + * Check whether NUMA is enabled + */ +C10_API bool IsNUMAEnabled(); + +/** + * Bind to a given NUMA node + */ +C10_API void NUMABind(int numa_node_id); + +/** + * Get the NUMA id for a given pointer `ptr` + */ +C10_API int GetNUMANode(const void* ptr); + +/** + * Get number of NUMA nodes + */ +C10_API int GetNumNUMANodes(); + +/** + * Move the memory pointed to by `ptr` of a given size to another NUMA node + */ +C10_API void NUMAMove(void* ptr, size_t size, int numa_node_id); + +/** + * Get the current NUMA node id + */ +C10_API int GetCurrentNUMANode(); + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/order_preserving_flat_hash_map.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/order_preserving_flat_hash_map.h new file mode 100644 index 0000000000000000000000000000000000000000..e991a567ec5eac9c967f4743255de1eb51c9338a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/order_preserving_flat_hash_map.h @@ -0,0 +1,2222 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Taken from +// https://github.com/skarupke/flat_hash_map/blob/2c4687431f978f02a3780e24b8b701d22aa32d9c/flat_hash_map.hpp +// with fixes applied: +// - https://github.com/skarupke/flat_hash_map/pull/25 +// - https://github.com/skarupke/flat_hash_map/pull/26 +// - replace size_t with uint64_t to fix it for 32bit +// - add "GCC diagnostic" pragma to ignore -Wshadow +// - make sherwood_v3_table::convertible_to_iterator public because GCC5 seems +// to have issues with it otherwise +// - fix compiler warnings in operator templated_iterator +// - make use of 'if constexpr' and eliminate AssignIfTrue template + +// Copyright Malte Skarupke 2017. +// Distributed under the Boost Software License, Version 1.0. +// (See http://www.boost.org/LICENSE_1_0.txt) + +// Modified to maintain insertion and deletion order through a doubly-linked +// list + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#define SKA_NOINLINE(...) __declspec(noinline) __VA_ARGS__ +#else +#define SKA_NOINLINE(...) __VA_ARGS__ __attribute__((noinline)) +#endif + +namespace ska_ordered { + +struct prime_number_hash_policy; +struct power_of_two_hash_policy; +struct fibonacci_hash_policy; + +namespace detailv3 { +template +struct functor_storage : Functor { + functor_storage() = default; + functor_storage(const Functor& functor) : Functor(functor) {} + template + Result operator()(Args&&... args) { + return static_cast(*this)(std::forward(args)...); + } + template + Result operator()(Args&&... args) const { + return static_cast(*this)(std::forward(args)...); + } +}; +template +struct functor_storage { + typedef Result (*function_ptr)(Args...); + function_ptr function; + functor_storage(function_ptr function) : function(function) {} + Result operator()(Args... args) const { + return function(std::forward(args)...); + } + operator function_ptr&() { + return function; + } + operator const function_ptr&() { + return function; + } +}; +template +struct KeyOrValueHasher : functor_storage { + typedef functor_storage hasher_storage; + KeyOrValueHasher() = default; + KeyOrValueHasher(const hasher& hash) : hasher_storage(hash) {} + uint64_t operator()(const key_type& key) { + return static_cast(*this)(key); + } + uint64_t operator()(const key_type& key) const { + return static_cast(*this)(key); + } + uint64_t operator()(const value_type& value) { + return static_cast(*this)(value.first); + } + uint64_t operator()(const value_type& value) const { + return static_cast(*this)(value.first); + } + template + uint64_t operator()(const std::pair& value) { + return static_cast(*this)(value.first); + } + template + uint64_t operator()(const std::pair& value) const { + return static_cast(*this)(value.first); + } +}; +template +struct KeyOrValueEquality : functor_storage { + typedef functor_storage equality_storage; + KeyOrValueEquality() = default; + KeyOrValueEquality(const key_equal& equality) : equality_storage(equality) {} + bool operator()(const key_type& lhs, const key_type& rhs) { + return static_cast(*this)(lhs, rhs); + } + bool operator()(const key_type& lhs, const value_type& rhs) { + return static_cast(*this)(lhs, rhs.first); + } + bool operator()(const value_type& lhs, const key_type& rhs) { + return static_cast(*this)(lhs.first, rhs); + } + bool operator()(const value_type& lhs, const value_type& rhs) { + return static_cast(*this)(lhs.first, rhs.first); + } + template + bool operator()(const key_type& lhs, const std::pair& rhs) { + return static_cast(*this)(lhs, rhs.first); + } + template + bool operator()(const std::pair& lhs, const key_type& rhs) { + return static_cast(*this)(lhs.first, rhs); + } + template + bool operator()(const value_type& lhs, const std::pair& rhs) { + return static_cast(*this)(lhs.first, rhs.first); + } + template + bool operator()(const std::pair& lhs, const value_type& rhs) { + return static_cast(*this)(lhs.first, rhs.first); + } + template + bool operator()(const std::pair& lhs, const std::pair& rhs) { + return static_cast(*this)(lhs.first, rhs.first); + } +}; +static constexpr int8_t min_lookups = 4; +template +// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions) +struct sherwood_v3_entry { + // NOLINTNEXTLINE(modernize-use-equals-default) + sherwood_v3_entry() {} + sherwood_v3_entry(int8_t distance_from_desired) + : distance_from_desired(distance_from_desired) {} + // NOLINTNEXTLINE(modernize-use-equals-default) + ~sherwood_v3_entry() {} + + bool has_value() const { + return distance_from_desired >= 0; + } + bool is_empty() const { + return distance_from_desired < 0; + } + bool is_at_desired_position() const { + return distance_from_desired <= 0; + } + template + void emplace(int8_t distance, Args&&... args) { + new (std::addressof(value)) T(std::forward(args)...); + distance_from_desired = distance; + } + + void destroy_value() { + value.~T(); + distance_from_desired = -1; + } + + sherwood_v3_entry* prev = nullptr; + sherwood_v3_entry* next = nullptr; + int8_t distance_from_desired = -1; + static constexpr int8_t special_end_value = 0; + union { + T value; + }; +}; + +inline int8_t log2(uint64_t value) { + static constexpr std::array table = { + 63, 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, + 61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, + 62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, + 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5}; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value |= value >> 32; + return table[((value - (value >> 1)) * 0x07EDD5E59A4E28C2) >> 58]; +} + +inline uint64_t next_power_of_two(uint64_t i) { + --i; + i |= i >> 1; + i |= i >> 2; + i |= i >> 4; + i |= i >> 8; + i |= i >> 16; + i |= i >> 32; + ++i; + return i; +} + +// Implementation taken from http://en.cppreference.com/w/cpp/types/void_t +// (it takes CWG1558 into account and also works for older compilers) +template +struct make_void { + typedef void type; +}; +template +using void_t = typename make_void::type; + +template +struct HashPolicySelector { + typedef fibonacci_hash_policy type; +}; +template +struct HashPolicySelector> { + typedef typename T::hash_policy type; +}; + +template < + typename T, + typename FindKey, + typename ArgumentHash, + typename Hasher, + typename ArgumentEqual, + typename Equal, + typename ArgumentAlloc, + typename EntryAlloc> +class sherwood_v3_table : private EntryAlloc, private Hasher, private Equal { + using Entry = detailv3::sherwood_v3_entry; + using AllocatorTraits = std::allocator_traits; + using EntryPointer = typename AllocatorTraits::pointer; + + public: + struct convertible_to_iterator; + + using value_type = T; + using size_type = uint64_t; + using difference_type = std::ptrdiff_t; + using hasher = ArgumentHash; + using key_equal = ArgumentEqual; + using allocator_type = EntryAlloc; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + + sherwood_v3_table() = default; + explicit sherwood_v3_table( + size_type bucket_count, + const ArgumentHash& hash = ArgumentHash(), + const ArgumentEqual& equal = ArgumentEqual(), + const ArgumentAlloc& alloc = ArgumentAlloc()) + : EntryAlloc(alloc), Hasher(hash), Equal(equal) { + rehash(bucket_count); + } + sherwood_v3_table(size_type bucket_count, const ArgumentAlloc& alloc) + : sherwood_v3_table( + bucket_count, + ArgumentHash(), + ArgumentEqual(), + alloc) {} + sherwood_v3_table( + size_type bucket_count, + const ArgumentHash& hash, + const ArgumentAlloc& alloc) + : sherwood_v3_table(bucket_count, hash, ArgumentEqual(), alloc) {} + explicit sherwood_v3_table(const ArgumentAlloc& alloc) : EntryAlloc(alloc) {} + template + sherwood_v3_table( + It first, + It last, + size_type bucket_count = 0, + const ArgumentHash& hash = ArgumentHash(), + const ArgumentEqual& equal = ArgumentEqual(), + const ArgumentAlloc& alloc = ArgumentAlloc()) + : sherwood_v3_table(bucket_count, hash, equal, alloc) { + insert(first, last); + } + template + sherwood_v3_table( + It first, + It last, + size_type bucket_count, + const ArgumentAlloc& alloc) + : sherwood_v3_table( + first, + last, + bucket_count, + ArgumentHash(), + ArgumentEqual(), + alloc) {} + template + sherwood_v3_table( + It first, + It last, + size_type bucket_count, + const ArgumentHash& hash, + const ArgumentAlloc& alloc) + : sherwood_v3_table( + first, + last, + bucket_count, + hash, + ArgumentEqual(), + alloc) {} + sherwood_v3_table( + std::initializer_list il, + size_type bucket_count = 0, + const ArgumentHash& hash = ArgumentHash(), + const ArgumentEqual& equal = ArgumentEqual(), + const ArgumentAlloc& alloc = ArgumentAlloc()) + : sherwood_v3_table(bucket_count, hash, equal, alloc) { + if (bucket_count == 0) + rehash(il.size()); + insert(il.begin(), il.end()); + } + sherwood_v3_table( + std::initializer_list il, + size_type bucket_count, + const ArgumentAlloc& alloc) + : sherwood_v3_table( + il, + bucket_count, + ArgumentHash(), + ArgumentEqual(), + alloc) {} + sherwood_v3_table( + std::initializer_list il, + size_type bucket_count, + const ArgumentHash& hash, + const ArgumentAlloc& alloc) + : sherwood_v3_table(il, bucket_count, hash, ArgumentEqual(), alloc) {} + sherwood_v3_table(const sherwood_v3_table& other) + : sherwood_v3_table( + other, + AllocatorTraits::select_on_container_copy_construction( + other.get_allocator())) {} + sherwood_v3_table(const sherwood_v3_table& other, const ArgumentAlloc& alloc) + : EntryAlloc(alloc), + Hasher(other), + Equal(other), + _max_load_factor(other._max_load_factor) { + rehash_for_other_container(other); + try { + insert(other.begin(), other.end()); + } catch (...) { + clear(); + deallocate_data(entries, num_slots_minus_one, max_lookups); + throw; + } + } + sherwood_v3_table(sherwood_v3_table&& other) noexcept + : EntryAlloc(std::move(other)), + Hasher(std::move(other)), + Equal(std::move(other)) { + swap_pointers(other); + } + sherwood_v3_table( + sherwood_v3_table&& other, + const ArgumentAlloc& alloc) noexcept + : EntryAlloc(alloc), Hasher(std::move(other)), Equal(std::move(other)) { + swap_pointers(other); + } + sherwood_v3_table& operator=(const sherwood_v3_table& other) { + if (this == std::addressof(other)) + return *this; + + clear(); + if constexpr (AllocatorTraits::propagate_on_container_copy_assignment:: + value) { + if (static_cast(*this) != + static_cast(other)) { + reset_to_empty_state(); + } + static_cast(*this) = other; + } + _max_load_factor = other._max_load_factor; + static_cast(*this) = other; + static_cast(*this) = other; + rehash_for_other_container(other); + insert(other.begin(), other.end()); + return *this; + } + sherwood_v3_table& operator=(sherwood_v3_table&& other) noexcept { + if (this == std::addressof(other)) + return *this; + else if constexpr (AllocatorTraits::propagate_on_container_move_assignment:: + value) { + clear(); + reset_to_empty_state(); + static_cast(*this) = std::move(other); + swap_pointers(other); + } else if ( + static_cast(*this) == static_cast(other)) { + swap_pointers(other); + } else { + clear(); + _max_load_factor = other._max_load_factor; + rehash_for_other_container(other); + for (T& elem : other) + emplace(std::move(elem)); + other.clear(); + } + static_cast(*this) = std::move(other); + static_cast(*this) = std::move(other); + return *this; + } + ~sherwood_v3_table() { + clear(); + deallocate_data(entries, num_slots_minus_one, max_lookups); + } + + const allocator_type& get_allocator() const { + return static_cast(*this); + } + const ArgumentEqual& key_eq() const { + return static_cast(*this); + } + const ArgumentHash& hash_function() const { + return static_cast(*this); + } + + template + struct templated_iterator { + templated_iterator() = default; + templated_iterator(EntryPointer current) : current(current) {} + EntryPointer current = EntryPointer(); + + using iterator_category = std::forward_iterator_tag; + using value_type = ValueType; + using difference_type = ptrdiff_t; + using pointer = ValueType*; + using reference = ValueType&; + + friend bool operator==( + const templated_iterator& lhs, + const templated_iterator& rhs) { + return lhs.current == rhs.current; + } + friend bool operator!=( + const templated_iterator& lhs, + const templated_iterator& rhs) { + return !(lhs == rhs); + } + + templated_iterator& operator++() { + current = current->next; + return *this; + } + templated_iterator operator++(int) { + templated_iterator copy(*this); + ++*this; + return copy; + } + + ValueType& operator*() const { + return current->value; + } + ValueType* operator->() const { + return std::addressof(current->value); + } + + // the template automatically disables the operator when value_type is + // already const, because that would cause a lot of compiler warnings + // otherwise. + template < + class target_type = const value_type, + class = std::enable_if_t< + std::is_same_v && + !std::is_same_v>> + operator templated_iterator() const { + return {current}; + } + }; + using iterator = templated_iterator; + using const_iterator = templated_iterator; + + iterator begin() { + return sentinel->next; + } + const_iterator begin() const { + return sentinel->next; + } + const_iterator cbegin() const { + return begin(); + } + iterator end() { + return sentinel; + } + const_iterator end() const { + return sentinel; + } + const_iterator cend() const { + return end(); + } + + iterator find(const FindKey& key) { + uint64_t index = + hash_policy.index_for_hash(hash_object(key), num_slots_minus_one); + EntryPointer it = entries + ptrdiff_t(index); + for (int8_t distance = 0; it->distance_from_desired >= distance; + ++distance, ++it) { + if (compares_equal(key, it->value)) + return {it}; + } + return end(); + } + const_iterator find(const FindKey& key) const { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + return const_cast(this)->find(key); + } + uint64_t count(const FindKey& key) const { + return find(key) == end() ? 0 : 1; + } + std::pair equal_range(const FindKey& key) { + iterator found = find(key); + if (found == end()) + return {found, found}; + else + return {found, std::next(found)}; + } + std::pair equal_range( + const FindKey& key) const { + const_iterator found = find(key); + if (found == end()) + return {found, found}; + else + return {found, std::next(found)}; + } + + template + std::pair emplace(Key&& key, Args&&... args) { + uint64_t index = + hash_policy.index_for_hash(hash_object(key), num_slots_minus_one); + EntryPointer current_entry = entries + ptrdiff_t(index); + int8_t distance_from_desired = 0; + for (; current_entry->distance_from_desired >= distance_from_desired; + ++current_entry, ++distance_from_desired) { + // insertion of an existing key does not change ordering + if (compares_equal(key, current_entry->value)) + return {{current_entry}, false}; + } + return emplace_new_key( + distance_from_desired, + current_entry, + std::forward(key), + std::forward(args)...); + } + + std::pair insert(const value_type& value) { + return emplace(value); + } + std::pair insert(value_type&& value) { + return emplace(std::move(value)); + } + template + iterator emplace_hint(const_iterator /*unused*/, Args&&... args) { + return emplace(std::forward(args)...).first; + } + iterator insert(const_iterator /*unused*/, const value_type& value) { + return emplace(value).first; + } + iterator insert(const_iterator /*unused*/, value_type&& value) { + return emplace(std::move(value)).first; + } + + template + void insert(It begin, It end) { + for (; begin != end; ++begin) { + emplace(*begin); + } + } + void insert(std::initializer_list il) { + insert(il.begin(), il.end()); + } + + void rehash(uint64_t num_buckets) { + num_buckets = std::max( + num_buckets, + static_cast(std::ceil( + static_cast(num_elements) / + static_cast(_max_load_factor)))); + if (num_buckets == 0) { + reset_to_empty_state(); + return; + } + auto new_prime_index = hash_policy.next_size_over(num_buckets); + if (num_buckets == bucket_count()) + return; + int8_t new_max_lookups = compute_max_lookups(num_buckets); + EntryPointer new_buckets( + AllocatorTraits::allocate(*this, num_buckets + new_max_lookups)); + EntryPointer special_end_item = + new_buckets + static_cast(num_buckets + new_max_lookups - 1); + for (EntryPointer it = new_buckets; it != special_end_item; ++it) + it->distance_from_desired = -1; + special_end_item->distance_from_desired = Entry::special_end_value; + std::swap(entries, new_buckets); + std::swap(num_slots_minus_one, num_buckets); + --num_slots_minus_one; + hash_policy.commit(new_prime_index); + int8_t old_max_lookups = max_lookups; + max_lookups = new_max_lookups; + num_elements = 0; + + auto start = sentinel->next; + // point sentinel to itself; + reset_list(); + // reinsert list + for (EntryPointer it = start; it != sentinel;) { + auto next = it->next; + emplace(std::move(it->value)); + it->destroy_value(); + it = next; + } + + deallocate_data(new_buckets, num_buckets, old_max_lookups); + } + + void reserve(uint64_t num_elements_) { + uint64_t required_buckets = num_buckets_for_reserve(num_elements_); + if (required_buckets > bucket_count()) + rehash(required_buckets); + } + + void replace_linked_list_position( + EntryPointer to_be_replaced, + EntryPointer new_node) { + remove_from_list(new_node); + insert_after(new_node, to_be_replaced->prev); + remove_from_list(to_be_replaced); + } + + // the return value is a type that can be converted to an iterator + // the reason for doing this is that it's not free to find the + // iterator pointing at the next element. if you care about the + // next iterator, turn the return value into an iterator + convertible_to_iterator erase(const_iterator to_erase) { + EntryPointer current = to_erase.current; + remove_from_list(current); + current->destroy_value(); + --num_elements; + + for (EntryPointer next = current + ptrdiff_t(1); + !next->is_at_desired_position(); + ++current, ++next) { + // if an entry is being removed, and there are other entries with the + // same hash, the other entries get moved to their desired position by + // reinserting. + current->emplace(next->distance_from_desired - 1, std::move(next->value)); + replace_linked_list_position(next, current); + next->destroy_value(); + } + return {to_erase.current}; + } + + iterator erase(const_iterator begin_it, const_iterator end_it) { + // whenever an entry is removed and there are other entries with the same + // hash, the other entries must get moved to their desired position. + // any reference to a moved entry is invalidated. + // here, we iterate through the range, and make sure that we update + // the pointer to our next entry in the list or the end of the iterator + // when it is invalidated. + + auto curr_iter = begin_it.current; + auto next_iter = curr_iter->next; + auto end_iter = end_it.current; + + while (curr_iter != end_iter) { + remove_from_list(curr_iter); + curr_iter->destroy_value(); + --num_elements; + + for (EntryPointer next_hash_slot = curr_iter + ptrdiff_t(1); + !next_hash_slot->is_at_desired_position(); + ++curr_iter, ++next_hash_slot) { + curr_iter->emplace( + next_hash_slot->distance_from_desired - 1, + std::move(next_hash_slot->value)); + replace_linked_list_position(next_hash_slot, curr_iter); + next_hash_slot->destroy_value(); + + // we are invalidating next_iter or end_iter + if (next_hash_slot == end_iter) { + end_iter = curr_iter; + } else if (next_hash_slot == next_iter) { + next_iter = curr_iter; + } + } + curr_iter = next_iter; + next_iter = curr_iter->next; + } + + return {end_iter}; + } + + uint64_t erase(const FindKey& key) { + auto found = find(key); + if (found == end()) + return 0; + else { + erase(found); + return 1; + } + } + + void clear() { + for (EntryPointer it = entries, + end = it + + static_cast(num_slots_minus_one + max_lookups); + it != end; + ++it) { + if (it->has_value()) + it->destroy_value(); + } + reset_list(); + num_elements = 0; + } + + void shrink_to_fit() { + rehash_for_other_container(*this); + } + + void swap(sherwood_v3_table& other) noexcept { + using std::swap; + swap_pointers(other); + swap(static_cast(*this), static_cast(other)); + swap( + static_cast(*this), static_cast(other)); + if (AllocatorTraits::propagate_on_container_swap::value) + swap(static_cast(*this), static_cast(other)); + } + + uint64_t size() const { + return num_elements; + } + uint64_t max_size() const { + return (AllocatorTraits::max_size(*this)) / sizeof(Entry); + } + uint64_t bucket_count() const { + return num_slots_minus_one ? num_slots_minus_one + 1 : 0; + } + size_type max_bucket_count() const { + return (AllocatorTraits::max_size(*this) - min_lookups) / sizeof(Entry); + } + uint64_t bucket(const FindKey& key) const { + return hash_policy.index_for_hash(hash_object(key), num_slots_minus_one); + } + float load_factor() const { + uint64_t buckets = bucket_count(); + if (buckets) + return static_cast(num_elements) / bucket_count(); + else + return 0; + } + void max_load_factor(float value) { + _max_load_factor = value; + } + float max_load_factor() const { + return _max_load_factor; + } + + bool empty() const { + return num_elements == 0; + } + + private: + EntryPointer entries = empty_default_table(); + uint64_t num_slots_minus_one = 0; + typename HashPolicySelector::type hash_policy; + int8_t max_lookups = detailv3::min_lookups - 1; + float _max_load_factor = 0.5f; + uint64_t num_elements = 0; + std::unique_ptr> sentinel_val; + + // head of doubly linked list + EntryPointer sentinel = initSentinel(); + + EntryPointer initSentinel() { + // needs to be a pointer so that hash map can be used with forward declared + // types + sentinel_val = std::make_unique>(); + sentinel = sentinel_val.get(); + reset_list(); + return sentinel; + } + + EntryPointer empty_default_table() { + EntryPointer result = + AllocatorTraits::allocate(*this, detailv3::min_lookups); + EntryPointer special_end_item = + result + static_cast(detailv3::min_lookups - 1); + for (EntryPointer it = result; it != special_end_item; ++it) + it->distance_from_desired = -1; + special_end_item->distance_from_desired = Entry::special_end_value; + return result; + } + + static int8_t compute_max_lookups(uint64_t num_buckets) { + int8_t desired = detailv3::log2(num_buckets); + return std::max(detailv3::min_lookups, desired); + } + + uint64_t num_buckets_for_reserve(uint64_t num_elements_) const { + return static_cast(std::ceil( + static_cast(num_elements_) / + std::min(0.5, static_cast(_max_load_factor)))); + } + void rehash_for_other_container(const sherwood_v3_table& other) { + rehash( + std::min(num_buckets_for_reserve(other.size()), other.bucket_count())); + } + + void swap_pointers(sherwood_v3_table& other) { + using std::swap; + swap(hash_policy, other.hash_policy); + swap(entries, other.entries); + swap(num_slots_minus_one, other.num_slots_minus_one); + swap(num_elements, other.num_elements); + swap(max_lookups, other.max_lookups); + swap(_max_load_factor, other._max_load_factor); + swap(sentinel, other.sentinel); + swap(sentinel_val, other.sentinel_val); + } + + void reset_list() { + sentinel->next = sentinel; + sentinel->prev = sentinel; + } + + void remove_from_list(EntryPointer elem) { + elem->prev->next = elem->next; + elem->next->prev = elem->prev; + } + + void insert_after(EntryPointer new_elem, EntryPointer prev) { + auto next = prev->next; + + prev->next = new_elem; + new_elem->prev = prev; + + new_elem->next = next; + next->prev = new_elem; + } + + void swap_adjacent_nodes(EntryPointer before, EntryPointer after) { + // sentinel stays constant, so before->prev cannot equal after + auto before_prev = before->prev; + auto after_next = after->next; + + before_prev->next = after; + after->prev = before_prev; + + after_next->prev = before; + before->next = after_next; + + before->prev = after; + after->next = before; + } + + void swap_positions(EntryPointer p1, EntryPointer p2) { + if (p1 == p2) { + return; + } + if (p1->next == p2) { + return swap_adjacent_nodes(p1, p2); + } else if (p2->next == p1) { + return swap_adjacent_nodes(p2, p1); + } + + auto p1_prev = p1->prev; + auto p1_next = p1->next; + + auto p2_prev = p2->prev; + auto p2_next = p2->next; + + p1_prev->next = p2; + p2->prev = p1_prev; + + p1_next->prev = p2; + p2->next = p1_next; + + p2_prev->next = p1; + p1->prev = p2_prev; + + p2_next->prev = p1; + p1->next = p2_next; + } + + void append_to_list(EntryPointer new_tail) { + insert_after(new_tail, sentinel->prev); + } + + template + SKA_NOINLINE(std::pair) + emplace_new_key( + int8_t distance_from_desired, + EntryPointer current_entry, + Key&& key, + Args&&... args) { + using std::swap; + if (num_slots_minus_one == 0 || distance_from_desired == max_lookups || + static_cast(num_elements + 1) > + static_cast(num_slots_minus_one + 1) * + static_cast(_max_load_factor)) { + grow(); + return emplace(std::forward(key), std::forward(args)...); + } else if (current_entry->is_empty()) { + current_entry->emplace( + distance_from_desired, + std::forward(key), + std::forward(args)...); + ++num_elements; + append_to_list(current_entry); + return {{current_entry}, true}; + } + value_type to_insert(std::forward(key), std::forward(args)...); + swap(distance_from_desired, current_entry->distance_from_desired); + // We maintain the invariant that: + // - result.current_entry contains the new value we're inserting + // and is in the LinkedList position of to_insert + // - to_insert contains the value that represents the position of + // result.current_entry + swap(to_insert, current_entry->value); + iterator result = {current_entry}; + for (++distance_from_desired, ++current_entry;; ++current_entry) { + if (current_entry->is_empty()) { + current_entry->emplace(distance_from_desired, std::move(to_insert)); + append_to_list(current_entry); + // now we can swap back the displaced value to its correct position, + // putting the new value we're inserting to the front of the list + swap_positions(current_entry, result.current); + ++num_elements; + return {result, true}; + } else if (current_entry->distance_from_desired < distance_from_desired) { + swap(distance_from_desired, current_entry->distance_from_desired); + swap(to_insert, current_entry->value); + // to maintain our invariants we need to swap positions + // of result.current & current_entry: + swap_positions(result.current, current_entry); + ++distance_from_desired; + } else { + ++distance_from_desired; + if (distance_from_desired == max_lookups) { + // the displaced element gets put back into its correct position + // we grow the hash table, and then try again to reinsert the new + // element + swap(to_insert, result.current->value); + grow(); + return emplace(std::move(to_insert)); + } + } + } + } + + void grow() { + rehash(std::max(uint64_t(4), 2 * bucket_count())); + } + + void deallocate_data( + EntryPointer begin, + uint64_t num_slots_minus_one_, + int8_t max_lookups_) { + AllocatorTraits::deallocate( + *this, begin, num_slots_minus_one_ + max_lookups_ + 1); + } + + void reset_to_empty_state() { + deallocate_data(entries, num_slots_minus_one, max_lookups); + entries = empty_default_table(); + num_slots_minus_one = 0; + hash_policy.reset(); + max_lookups = detailv3::min_lookups - 1; + } + + template + uint64_t hash_object(const U& key) { + return static_cast(*this)(key); + } + template + uint64_t hash_object(const U& key) const { + return static_cast(*this)(key); + } + template + bool compares_equal(const L& lhs, const R& rhs) { + return static_cast(*this)(lhs, rhs); + } + + public: + struct convertible_to_iterator { + EntryPointer it; + + operator iterator() { + if (it->has_value()) + return {it}; + else + return ++iterator{it}; + } + operator const_iterator() { + if (it->has_value()) + return {it}; + else + return ++const_iterator{it}; + } + }; +}; +} // namespace detailv3 + +struct prime_number_hash_policy { + static uint64_t mod0(uint64_t /*unused*/) { + return 0llu; + } + static uint64_t mod2(uint64_t hash) { + return hash % 2llu; + } + static uint64_t mod3(uint64_t hash) { + return hash % 3llu; + } + static uint64_t mod5(uint64_t hash) { + return hash % 5llu; + } + static uint64_t mod7(uint64_t hash) { + return hash % 7llu; + } + static uint64_t mod11(uint64_t hash) { + return hash % 11llu; + } + static uint64_t mod13(uint64_t hash) { + return hash % 13llu; + } + static uint64_t mod17(uint64_t hash) { + return hash % 17llu; + } + static uint64_t mod23(uint64_t hash) { + return hash % 23llu; + } + static uint64_t mod29(uint64_t hash) { + return hash % 29llu; + } + static uint64_t mod37(uint64_t hash) { + return hash % 37llu; + } + static uint64_t mod47(uint64_t hash) { + return hash % 47llu; + } + static uint64_t mod59(uint64_t hash) { + return hash % 59llu; + } + static uint64_t mod73(uint64_t hash) { + return hash % 73llu; + } + static uint64_t mod97(uint64_t hash) { + return hash % 97llu; + } + static uint64_t mod127(uint64_t hash) { + return hash % 127llu; + } + static uint64_t mod151(uint64_t hash) { + return hash % 151llu; + } + static uint64_t mod197(uint64_t hash) { + return hash % 197llu; + } + static uint64_t mod251(uint64_t hash) { + return hash % 251llu; + } + static uint64_t mod313(uint64_t hash) { + return hash % 313llu; + } + static uint64_t mod397(uint64_t hash) { + return hash % 397llu; + } + static uint64_t mod499(uint64_t hash) { + return hash % 499llu; + } + static uint64_t mod631(uint64_t hash) { + return hash % 631llu; + } + static uint64_t mod797(uint64_t hash) { + return hash % 797llu; + } + static uint64_t mod1009(uint64_t hash) { + return hash % 1009llu; + } + static uint64_t mod1259(uint64_t hash) { + return hash % 1259llu; + } + static uint64_t mod1597(uint64_t hash) { + return hash % 1597llu; + } + static uint64_t mod2011(uint64_t hash) { + return hash % 2011llu; + } + static uint64_t mod2539(uint64_t hash) { + return hash % 2539llu; + } + static uint64_t mod3203(uint64_t hash) { + return hash % 3203llu; + } + static uint64_t mod4027(uint64_t hash) { + return hash % 4027llu; + } + static uint64_t mod5087(uint64_t hash) { + return hash % 5087llu; + } + static uint64_t mod6421(uint64_t hash) { + return hash % 6421llu; + } + static uint64_t mod8089(uint64_t hash) { + return hash % 8089llu; + } + static uint64_t mod10193(uint64_t hash) { + return hash % 10193llu; + } + static uint64_t mod12853(uint64_t hash) { + return hash % 12853llu; + } + static uint64_t mod16193(uint64_t hash) { + return hash % 16193llu; + } + static uint64_t mod20399(uint64_t hash) { + return hash % 20399llu; + } + static uint64_t mod25717(uint64_t hash) { + return hash % 25717llu; + } + static uint64_t mod32401(uint64_t hash) { + return hash % 32401llu; + } + static uint64_t mod40823(uint64_t hash) { + return hash % 40823llu; + } + static uint64_t mod51437(uint64_t hash) { + return hash % 51437llu; + } + static uint64_t mod64811(uint64_t hash) { + return hash % 64811llu; + } + static uint64_t mod81649(uint64_t hash) { + return hash % 81649llu; + } + static uint64_t mod102877(uint64_t hash) { + return hash % 102877llu; + } + static uint64_t mod129607(uint64_t hash) { + return hash % 129607llu; + } + static uint64_t mod163307(uint64_t hash) { + return hash % 163307llu; + } + static uint64_t mod205759(uint64_t hash) { + return hash % 205759llu; + } + static uint64_t mod259229(uint64_t hash) { + return hash % 259229llu; + } + static uint64_t mod326617(uint64_t hash) { + return hash % 326617llu; + } + static uint64_t mod411527(uint64_t hash) { + return hash % 411527llu; + } + static uint64_t mod518509(uint64_t hash) { + return hash % 518509llu; + } + static uint64_t mod653267(uint64_t hash) { + return hash % 653267llu; + } + static uint64_t mod823117(uint64_t hash) { + return hash % 823117llu; + } + static uint64_t mod1037059(uint64_t hash) { + return hash % 1037059llu; + } + static uint64_t mod1306601(uint64_t hash) { + return hash % 1306601llu; + } + static uint64_t mod1646237(uint64_t hash) { + return hash % 1646237llu; + } + static uint64_t mod2074129(uint64_t hash) { + return hash % 2074129llu; + } + static uint64_t mod2613229(uint64_t hash) { + return hash % 2613229llu; + } + static uint64_t mod3292489(uint64_t hash) { + return hash % 3292489llu; + } + static uint64_t mod4148279(uint64_t hash) { + return hash % 4148279llu; + } + static uint64_t mod5226491(uint64_t hash) { + return hash % 5226491llu; + } + static uint64_t mod6584983(uint64_t hash) { + return hash % 6584983llu; + } + static uint64_t mod8296553(uint64_t hash) { + return hash % 8296553llu; + } + static uint64_t mod10453007(uint64_t hash) { + return hash % 10453007llu; + } + static uint64_t mod13169977(uint64_t hash) { + return hash % 13169977llu; + } + static uint64_t mod16593127(uint64_t hash) { + return hash % 16593127llu; + } + static uint64_t mod20906033(uint64_t hash) { + return hash % 20906033llu; + } + static uint64_t mod26339969(uint64_t hash) { + return hash % 26339969llu; + } + static uint64_t mod33186281(uint64_t hash) { + return hash % 33186281llu; + } + static uint64_t mod41812097(uint64_t hash) { + return hash % 41812097llu; + } + static uint64_t mod52679969(uint64_t hash) { + return hash % 52679969llu; + } + static uint64_t mod66372617(uint64_t hash) { + return hash % 66372617llu; + } + static uint64_t mod83624237(uint64_t hash) { + return hash % 83624237llu; + } + static uint64_t mod105359939(uint64_t hash) { + return hash % 105359939llu; + } + static uint64_t mod132745199(uint64_t hash) { + return hash % 132745199llu; + } + static uint64_t mod167248483(uint64_t hash) { + return hash % 167248483llu; + } + static uint64_t mod210719881(uint64_t hash) { + return hash % 210719881llu; + } + static uint64_t mod265490441(uint64_t hash) { + return hash % 265490441llu; + } + static uint64_t mod334496971(uint64_t hash) { + return hash % 334496971llu; + } + static uint64_t mod421439783(uint64_t hash) { + return hash % 421439783llu; + } + static uint64_t mod530980861(uint64_t hash) { + return hash % 530980861llu; + } + static uint64_t mod668993977(uint64_t hash) { + return hash % 668993977llu; + } + static uint64_t mod842879579(uint64_t hash) { + return hash % 842879579llu; + } + static uint64_t mod1061961721(uint64_t hash) { + return hash % 1061961721llu; + } + static uint64_t mod1337987929(uint64_t hash) { + return hash % 1337987929llu; + } + static uint64_t mod1685759167(uint64_t hash) { + return hash % 1685759167llu; + } + static uint64_t mod2123923447(uint64_t hash) { + return hash % 2123923447llu; + } + static uint64_t mod2675975881(uint64_t hash) { + return hash % 2675975881llu; + } + static uint64_t mod3371518343(uint64_t hash) { + return hash % 3371518343llu; + } + static uint64_t mod4247846927(uint64_t hash) { + return hash % 4247846927llu; + } + static uint64_t mod5351951779(uint64_t hash) { + return hash % 5351951779llu; + } + static uint64_t mod6743036717(uint64_t hash) { + return hash % 6743036717llu; + } + static uint64_t mod8495693897(uint64_t hash) { + return hash % 8495693897llu; + } + static uint64_t mod10703903591(uint64_t hash) { + return hash % 10703903591llu; + } + static uint64_t mod13486073473(uint64_t hash) { + return hash % 13486073473llu; + } + static uint64_t mod16991387857(uint64_t hash) { + return hash % 16991387857llu; + } + static uint64_t mod21407807219(uint64_t hash) { + return hash % 21407807219llu; + } + static uint64_t mod26972146961(uint64_t hash) { + return hash % 26972146961llu; + } + static uint64_t mod33982775741(uint64_t hash) { + return hash % 33982775741llu; + } + static uint64_t mod42815614441(uint64_t hash) { + return hash % 42815614441llu; + } + static uint64_t mod53944293929(uint64_t hash) { + return hash % 53944293929llu; + } + static uint64_t mod67965551447(uint64_t hash) { + return hash % 67965551447llu; + } + static uint64_t mod85631228929(uint64_t hash) { + return hash % 85631228929llu; + } + static uint64_t mod107888587883(uint64_t hash) { + return hash % 107888587883llu; + } + static uint64_t mod135931102921(uint64_t hash) { + return hash % 135931102921llu; + } + static uint64_t mod171262457903(uint64_t hash) { + return hash % 171262457903llu; + } + static uint64_t mod215777175787(uint64_t hash) { + return hash % 215777175787llu; + } + static uint64_t mod271862205833(uint64_t hash) { + return hash % 271862205833llu; + } + static uint64_t mod342524915839(uint64_t hash) { + return hash % 342524915839llu; + } + static uint64_t mod431554351609(uint64_t hash) { + return hash % 431554351609llu; + } + static uint64_t mod543724411781(uint64_t hash) { + return hash % 543724411781llu; + } + static uint64_t mod685049831731(uint64_t hash) { + return hash % 685049831731llu; + } + static uint64_t mod863108703229(uint64_t hash) { + return hash % 863108703229llu; + } + static uint64_t mod1087448823553(uint64_t hash) { + return hash % 1087448823553llu; + } + static uint64_t mod1370099663459(uint64_t hash) { + return hash % 1370099663459llu; + } + static uint64_t mod1726217406467(uint64_t hash) { + return hash % 1726217406467llu; + } + static uint64_t mod2174897647073(uint64_t hash) { + return hash % 2174897647073llu; + } + static uint64_t mod2740199326961(uint64_t hash) { + return hash % 2740199326961llu; + } + static uint64_t mod3452434812973(uint64_t hash) { + return hash % 3452434812973llu; + } + static uint64_t mod4349795294267(uint64_t hash) { + return hash % 4349795294267llu; + } + static uint64_t mod5480398654009(uint64_t hash) { + return hash % 5480398654009llu; + } + static uint64_t mod6904869625999(uint64_t hash) { + return hash % 6904869625999llu; + } + static uint64_t mod8699590588571(uint64_t hash) { + return hash % 8699590588571llu; + } + static uint64_t mod10960797308051(uint64_t hash) { + return hash % 10960797308051llu; + } + static uint64_t mod13809739252051(uint64_t hash) { + return hash % 13809739252051llu; + } + static uint64_t mod17399181177241(uint64_t hash) { + return hash % 17399181177241llu; + } + static uint64_t mod21921594616111(uint64_t hash) { + return hash % 21921594616111llu; + } + static uint64_t mod27619478504183(uint64_t hash) { + return hash % 27619478504183llu; + } + static uint64_t mod34798362354533(uint64_t hash) { + return hash % 34798362354533llu; + } + static uint64_t mod43843189232363(uint64_t hash) { + return hash % 43843189232363llu; + } + static uint64_t mod55238957008387(uint64_t hash) { + return hash % 55238957008387llu; + } + static uint64_t mod69596724709081(uint64_t hash) { + return hash % 69596724709081llu; + } + static uint64_t mod87686378464759(uint64_t hash) { + return hash % 87686378464759llu; + } + static uint64_t mod110477914016779(uint64_t hash) { + return hash % 110477914016779llu; + } + static uint64_t mod139193449418173(uint64_t hash) { + return hash % 139193449418173llu; + } + static uint64_t mod175372756929481(uint64_t hash) { + return hash % 175372756929481llu; + } + static uint64_t mod220955828033581(uint64_t hash) { + return hash % 220955828033581llu; + } + static uint64_t mod278386898836457(uint64_t hash) { + return hash % 278386898836457llu; + } + static uint64_t mod350745513859007(uint64_t hash) { + return hash % 350745513859007llu; + } + static uint64_t mod441911656067171(uint64_t hash) { + return hash % 441911656067171llu; + } + static uint64_t mod556773797672909(uint64_t hash) { + return hash % 556773797672909llu; + } + static uint64_t mod701491027718027(uint64_t hash) { + return hash % 701491027718027llu; + } + static uint64_t mod883823312134381(uint64_t hash) { + return hash % 883823312134381llu; + } + static uint64_t mod1113547595345903(uint64_t hash) { + return hash % 1113547595345903llu; + } + static uint64_t mod1402982055436147(uint64_t hash) { + return hash % 1402982055436147llu; + } + static uint64_t mod1767646624268779(uint64_t hash) { + return hash % 1767646624268779llu; + } + static uint64_t mod2227095190691797(uint64_t hash) { + return hash % 2227095190691797llu; + } + static uint64_t mod2805964110872297(uint64_t hash) { + return hash % 2805964110872297llu; + } + static uint64_t mod3535293248537579(uint64_t hash) { + return hash % 3535293248537579llu; + } + static uint64_t mod4454190381383713(uint64_t hash) { + return hash % 4454190381383713llu; + } + static uint64_t mod5611928221744609(uint64_t hash) { + return hash % 5611928221744609llu; + } + static uint64_t mod7070586497075177(uint64_t hash) { + return hash % 7070586497075177llu; + } + static uint64_t mod8908380762767489(uint64_t hash) { + return hash % 8908380762767489llu; + } + static uint64_t mod11223856443489329(uint64_t hash) { + return hash % 11223856443489329llu; + } + static uint64_t mod14141172994150357(uint64_t hash) { + return hash % 14141172994150357llu; + } + static uint64_t mod17816761525534927(uint64_t hash) { + return hash % 17816761525534927llu; + } + static uint64_t mod22447712886978529(uint64_t hash) { + return hash % 22447712886978529llu; + } + static uint64_t mod28282345988300791(uint64_t hash) { + return hash % 28282345988300791llu; + } + static uint64_t mod35633523051069991(uint64_t hash) { + return hash % 35633523051069991llu; + } + static uint64_t mod44895425773957261(uint64_t hash) { + return hash % 44895425773957261llu; + } + static uint64_t mod56564691976601587(uint64_t hash) { + return hash % 56564691976601587llu; + } + static uint64_t mod71267046102139967(uint64_t hash) { + return hash % 71267046102139967llu; + } + static uint64_t mod89790851547914507(uint64_t hash) { + return hash % 89790851547914507llu; + } + static uint64_t mod113129383953203213(uint64_t hash) { + return hash % 113129383953203213llu; + } + static uint64_t mod142534092204280003(uint64_t hash) { + return hash % 142534092204280003llu; + } + static uint64_t mod179581703095829107(uint64_t hash) { + return hash % 179581703095829107llu; + } + static uint64_t mod226258767906406483(uint64_t hash) { + return hash % 226258767906406483llu; + } + static uint64_t mod285068184408560057(uint64_t hash) { + return hash % 285068184408560057llu; + } + static uint64_t mod359163406191658253(uint64_t hash) { + return hash % 359163406191658253llu; + } + static uint64_t mod452517535812813007(uint64_t hash) { + return hash % 452517535812813007llu; + } + static uint64_t mod570136368817120201(uint64_t hash) { + return hash % 570136368817120201llu; + } + static uint64_t mod718326812383316683(uint64_t hash) { + return hash % 718326812383316683llu; + } + static uint64_t mod905035071625626043(uint64_t hash) { + return hash % 905035071625626043llu; + } + static uint64_t mod1140272737634240411(uint64_t hash) { + return hash % 1140272737634240411llu; + } + static uint64_t mod1436653624766633509(uint64_t hash) { + return hash % 1436653624766633509llu; + } + static uint64_t mod1810070143251252131(uint64_t hash) { + return hash % 1810070143251252131llu; + } + static uint64_t mod2280545475268481167(uint64_t hash) { + return hash % 2280545475268481167llu; + } + static uint64_t mod2873307249533267101(uint64_t hash) { + return hash % 2873307249533267101llu; + } + static uint64_t mod3620140286502504283(uint64_t hash) { + return hash % 3620140286502504283llu; + } + static uint64_t mod4561090950536962147(uint64_t hash) { + return hash % 4561090950536962147llu; + } + static uint64_t mod5746614499066534157(uint64_t hash) { + return hash % 5746614499066534157llu; + } + static uint64_t mod7240280573005008577(uint64_t hash) { + return hash % 7240280573005008577llu; + } + static uint64_t mod9122181901073924329(uint64_t hash) { + return hash % 9122181901073924329llu; + } + static uint64_t mod11493228998133068689(uint64_t hash) { + return hash % 11493228998133068689llu; + } + static uint64_t mod14480561146010017169(uint64_t hash) { + return hash % 14480561146010017169llu; + } + static uint64_t mod18446744073709551557(uint64_t hash) { + return hash % 18446744073709551557llu; + } + + using mod_function = uint64_t (*)(uint64_t); + + mod_function next_size_over(uint64_t& size) const { + // prime numbers generated by the following method: + // 1. start with a prime p = 2 + // 2. go to wolfram alpha and get p = NextPrime(2 * p) + // 3. repeat 2. until you overflow 64 bits + // you now have large gaps which you would hit if somebody called reserve() + // with an unlucky number. + // 4. to fill the gaps for every prime p go to wolfram alpha and get + // ClosestPrime(p * 2^(1/3)) and ClosestPrime(p * 2^(2/3)) and put those in + // the gaps + // 5. get PrevPrime(2^64) and put it at the end + // NOLINTNEXTLINE(*c-array*) + static constexpr const uint64_t prime_list[] = { + 2llu, + 3llu, + 5llu, + 7llu, + 11llu, + 13llu, + 17llu, + 23llu, + 29llu, + 37llu, + 47llu, + 59llu, + 73llu, + 97llu, + 127llu, + 151llu, + 197llu, + 251llu, + 313llu, + 397llu, + 499llu, + 631llu, + 797llu, + 1009llu, + 1259llu, + 1597llu, + 2011llu, + 2539llu, + 3203llu, + 4027llu, + 5087llu, + 6421llu, + 8089llu, + 10193llu, + 12853llu, + 16193llu, + 20399llu, + 25717llu, + 32401llu, + 40823llu, + 51437llu, + 64811llu, + 81649llu, + 102877llu, + 129607llu, + 163307llu, + 205759llu, + 259229llu, + 326617llu, + 411527llu, + 518509llu, + 653267llu, + 823117llu, + 1037059llu, + 1306601llu, + 1646237llu, + 2074129llu, + 2613229llu, + 3292489llu, + 4148279llu, + 5226491llu, + 6584983llu, + 8296553llu, + 10453007llu, + 13169977llu, + 16593127llu, + 20906033llu, + 26339969llu, + 33186281llu, + 41812097llu, + 52679969llu, + 66372617llu, + 83624237llu, + 105359939llu, + 132745199llu, + 167248483llu, + 210719881llu, + 265490441llu, + 334496971llu, + 421439783llu, + 530980861llu, + 668993977llu, + 842879579llu, + 1061961721llu, + 1337987929llu, + 1685759167llu, + 2123923447llu, + 2675975881llu, + 3371518343llu, + 4247846927llu, + 5351951779llu, + 6743036717llu, + 8495693897llu, + 10703903591llu, + 13486073473llu, + 16991387857llu, + 21407807219llu, + 26972146961llu, + 33982775741llu, + 42815614441llu, + 53944293929llu, + 67965551447llu, + 85631228929llu, + 107888587883llu, + 135931102921llu, + 171262457903llu, + 215777175787llu, + 271862205833llu, + 342524915839llu, + 431554351609llu, + 543724411781llu, + 685049831731llu, + 863108703229llu, + 1087448823553llu, + 1370099663459llu, + 1726217406467llu, + 2174897647073llu, + 2740199326961llu, + 3452434812973llu, + 4349795294267llu, + 5480398654009llu, + 6904869625999llu, + 8699590588571llu, + 10960797308051llu, + 13809739252051llu, + 17399181177241llu, + 21921594616111llu, + 27619478504183llu, + 34798362354533llu, + 43843189232363llu, + 55238957008387llu, + 69596724709081llu, + 87686378464759llu, + 110477914016779llu, + 139193449418173llu, + 175372756929481llu, + 220955828033581llu, + 278386898836457llu, + 350745513859007llu, + 441911656067171llu, + 556773797672909llu, + 701491027718027llu, + 883823312134381llu, + 1113547595345903llu, + 1402982055436147llu, + 1767646624268779llu, + 2227095190691797llu, + 2805964110872297llu, + 3535293248537579llu, + 4454190381383713llu, + 5611928221744609llu, + 7070586497075177llu, + 8908380762767489llu, + 11223856443489329llu, + 14141172994150357llu, + 17816761525534927llu, + 22447712886978529llu, + 28282345988300791llu, + 35633523051069991llu, + 44895425773957261llu, + 56564691976601587llu, + 71267046102139967llu, + 89790851547914507llu, + 113129383953203213llu, + 142534092204280003llu, + 179581703095829107llu, + 226258767906406483llu, + 285068184408560057llu, + 359163406191658253llu, + 452517535812813007llu, + 570136368817120201llu, + 718326812383316683llu, + 905035071625626043llu, + 1140272737634240411llu, + 1436653624766633509llu, + 1810070143251252131llu, + 2280545475268481167llu, + 2873307249533267101llu, + 3620140286502504283llu, + 4561090950536962147llu, + 5746614499066534157llu, + 7240280573005008577llu, + 9122181901073924329llu, + 11493228998133068689llu, + 14480561146010017169llu, + 18446744073709551557llu}; + // NOLINTNEXTLINE(*c-array*) + static constexpr uint64_t (*const mod_functions[])(uint64_t) = { + &mod0, + &mod2, + &mod3, + &mod5, + &mod7, + &mod11, + &mod13, + &mod17, + &mod23, + &mod29, + &mod37, + &mod47, + &mod59, + &mod73, + &mod97, + &mod127, + &mod151, + &mod197, + &mod251, + &mod313, + &mod397, + &mod499, + &mod631, + &mod797, + &mod1009, + &mod1259, + &mod1597, + &mod2011, + &mod2539, + &mod3203, + &mod4027, + &mod5087, + &mod6421, + &mod8089, + &mod10193, + &mod12853, + &mod16193, + &mod20399, + &mod25717, + &mod32401, + &mod40823, + &mod51437, + &mod64811, + &mod81649, + &mod102877, + &mod129607, + &mod163307, + &mod205759, + &mod259229, + &mod326617, + &mod411527, + &mod518509, + &mod653267, + &mod823117, + &mod1037059, + &mod1306601, + &mod1646237, + &mod2074129, + &mod2613229, + &mod3292489, + &mod4148279, + &mod5226491, + &mod6584983, + &mod8296553, + &mod10453007, + &mod13169977, + &mod16593127, + &mod20906033, + &mod26339969, + &mod33186281, + &mod41812097, + &mod52679969, + &mod66372617, + &mod83624237, + &mod105359939, + &mod132745199, + &mod167248483, + &mod210719881, + &mod265490441, + &mod334496971, + &mod421439783, + &mod530980861, + &mod668993977, + &mod842879579, + &mod1061961721, + &mod1337987929, + &mod1685759167, + &mod2123923447, + &mod2675975881, + &mod3371518343, + &mod4247846927, + &mod5351951779, + &mod6743036717, + &mod8495693897, + &mod10703903591, + &mod13486073473, + &mod16991387857, + &mod21407807219, + &mod26972146961, + &mod33982775741, + &mod42815614441, + &mod53944293929, + &mod67965551447, + &mod85631228929, + &mod107888587883, + &mod135931102921, + &mod171262457903, + &mod215777175787, + &mod271862205833, + &mod342524915839, + &mod431554351609, + &mod543724411781, + &mod685049831731, + &mod863108703229, + &mod1087448823553, + &mod1370099663459, + &mod1726217406467, + &mod2174897647073, + &mod2740199326961, + &mod3452434812973, + &mod4349795294267, + &mod5480398654009, + &mod6904869625999, + &mod8699590588571, + &mod10960797308051, + &mod13809739252051, + &mod17399181177241, + &mod21921594616111, + &mod27619478504183, + &mod34798362354533, + &mod43843189232363, + &mod55238957008387, + &mod69596724709081, + &mod87686378464759, + &mod110477914016779, + &mod139193449418173, + &mod175372756929481, + &mod220955828033581, + &mod278386898836457, + &mod350745513859007, + &mod441911656067171, + &mod556773797672909, + &mod701491027718027, + &mod883823312134381, + &mod1113547595345903, + &mod1402982055436147, + &mod1767646624268779, + &mod2227095190691797, + &mod2805964110872297, + &mod3535293248537579, + &mod4454190381383713, + &mod5611928221744609, + &mod7070586497075177, + &mod8908380762767489, + &mod11223856443489329, + &mod14141172994150357, + &mod17816761525534927, + &mod22447712886978529, + &mod28282345988300791, + &mod35633523051069991, + &mod44895425773957261, + &mod56564691976601587, + &mod71267046102139967, + &mod89790851547914507, + &mod113129383953203213, + &mod142534092204280003, + &mod179581703095829107, + &mod226258767906406483, + &mod285068184408560057, + &mod359163406191658253, + &mod452517535812813007, + &mod570136368817120201, + &mod718326812383316683, + &mod905035071625626043, + &mod1140272737634240411, + &mod1436653624766633509, + &mod1810070143251252131, + &mod2280545475268481167, + &mod2873307249533267101, + &mod3620140286502504283, + &mod4561090950536962147, + &mod5746614499066534157, + &mod7240280573005008577, + &mod9122181901073924329, + &mod11493228998133068689, + &mod14480561146010017169, + &mod18446744073709551557}; + const uint64_t* found = std::lower_bound( + std::begin(prime_list), std::end(prime_list) - 1, size); + size = *found; + return mod_functions[1 + found - prime_list]; + } + void commit(mod_function new_mod_function) { + current_mod_function = new_mod_function; + } + void reset() { + current_mod_function = &mod0; + } + + uint64_t index_for_hash(uint64_t hash, uint64_t /*num_slots_minus_one*/) + const { + return current_mod_function(hash); + } + uint64_t keep_in_range(uint64_t index, uint64_t num_slots_minus_one) const { + return index > num_slots_minus_one ? current_mod_function(index) : index; + } + + private: + mod_function current_mod_function = &mod0; +}; + +struct power_of_two_hash_policy { + uint64_t index_for_hash(uint64_t hash, uint64_t num_slots_minus_one) const { + return hash & num_slots_minus_one; + } + uint64_t keep_in_range(uint64_t index, uint64_t num_slots_minus_one) const { + return index_for_hash(index, num_slots_minus_one); + } + int8_t next_size_over(uint64_t& size) const { + size = detailv3::next_power_of_two(size); + return 0; + } + void commit(int8_t /*unused*/) {} + void reset() {} +}; + +struct fibonacci_hash_policy { + uint64_t index_for_hash(uint64_t hash, uint64_t /*num_slots_minus_one*/) + const { + return (11400714819323198485ull * hash) >> shift; + } + uint64_t keep_in_range(uint64_t index, uint64_t num_slots_minus_one) const { + return index & num_slots_minus_one; + } + + int8_t next_size_over(uint64_t& size) const { + size = std::max(uint64_t(2), detailv3::next_power_of_two(size)); + return static_cast(64 - detailv3::log2(size)); + } + void commit(int8_t shift_) { + shift = shift_; + } + void reset() { + shift = 63; + } + + private: + int8_t shift = 63; +}; + +template < + typename K, + typename V, + typename H = std::hash, + typename E = std::equal_to, + typename A = std::allocator>> +class order_preserving_flat_hash_map + : public detailv3::sherwood_v3_table< + std::pair, + K, + H, + detailv3::KeyOrValueHasher, H>, + E, + detailv3::KeyOrValueEquality, E>, + A, + typename std::allocator_traits::template rebind_alloc< + detailv3::sherwood_v3_entry>>> { + using Table = detailv3::sherwood_v3_table< + std::pair, + K, + H, + detailv3::KeyOrValueHasher, H>, + E, + detailv3::KeyOrValueEquality, E>, + A, + typename std::allocator_traits::template rebind_alloc< + detailv3::sherwood_v3_entry>>>; + + public: + using key_type = K; + using mapped_type = V; + + using Table::Table; + order_preserving_flat_hash_map() = default; + + inline V& operator[](const K& key) { + return emplace(key, convertible_to_value()).first->second; + } + inline V& operator[](K&& key) { + return emplace(std::move(key), convertible_to_value()).first->second; + } + V& at(const K& key) { + auto found = this->find(key); + if (found == this->end()) + throw std::out_of_range("Argument passed to at() was not in the map."); + return found->second; + } + const V& at(const K& key) const { + auto found = this->find(key); + if (found == this->end()) + throw std::out_of_range("Argument passed to at() was not in the map."); + return found->second; + } + + using Table::emplace; + std::pair emplace() { + return emplace(key_type(), convertible_to_value()); + } + template + std::pair insert_or_assign( + const key_type& key, + M&& m) { + auto emplace_result = emplace(key, std::forward(m)); + if (!emplace_result.second) + emplace_result.first->second = std::forward(m); + return emplace_result; + } + template + std::pair insert_or_assign( + key_type&& key, + M&& m) { + auto emplace_result = emplace(std::move(key), std::forward(m)); + if (!emplace_result.second) + emplace_result.first->second = std::forward(m); + return emplace_result; + } + template + typename Table::iterator insert_or_assign( + typename Table::const_iterator /*unused*/, + const key_type& key, + M&& m) { + return insert_or_assign(key, std::forward(m)).first; + } + template + typename Table::iterator insert_or_assign( + typename Table::const_iterator /*unused*/, + key_type&& key, + M&& m) { + return insert_or_assign(std::move(key), std::forward(m)).first; + } + + friend bool operator==( + const order_preserving_flat_hash_map& lhs, + const order_preserving_flat_hash_map& rhs) { + if (lhs.size() != rhs.size()) + return false; + for (const typename Table::value_type& value : lhs) { + auto found = rhs.find(value.first); + if (found == rhs.end() || value.second != found->second) + return false; + } + return true; + } + friend bool operator!=( + const order_preserving_flat_hash_map& lhs, + const order_preserving_flat_hash_map& rhs) { + return !(lhs == rhs); + } + + private: + struct convertible_to_value { + operator V() const { + return V(); + } + }; +}; + +template < + typename T, + typename H = std::hash, + typename E = std::equal_to, + typename A = std::allocator> +class flat_hash_set + : public detailv3::sherwood_v3_table< + T, + T, + H, + detailv3::functor_storage, + E, + detailv3::functor_storage, + A, + typename std::allocator_traits::template rebind_alloc< + detailv3::sherwood_v3_entry>> { + using Table = detailv3::sherwood_v3_table< + T, + T, + H, + detailv3::functor_storage, + E, + detailv3::functor_storage, + A, + typename std::allocator_traits::template rebind_alloc< + detailv3::sherwood_v3_entry>>; + + public: + using key_type = T; + + using Table::Table; + flat_hash_set() = default; + + template + std::pair emplace(Args&&... args) { + return Table::emplace(T(std::forward(args)...)); + } + std::pair emplace(const key_type& arg) { + return Table::emplace(arg); + } + std::pair emplace(key_type& arg) { + return Table::emplace(arg); + } + std::pair emplace(const key_type&& arg) { + return Table::emplace(std::move(arg)); + } + std::pair emplace(key_type&& arg) { + return Table::emplace(std::move(arg)); + } + + friend bool operator==(const flat_hash_set& lhs, const flat_hash_set& rhs) { + if (lhs.size() != rhs.size()) + return false; + for (const T& value : lhs) { + if (rhs.find(value) == rhs.end()) + return false; + } + return true; + } + friend bool operator!=(const flat_hash_set& lhs, const flat_hash_set& rhs) { + return !(lhs == rhs); + } +}; + +template +struct power_of_two_std_hash : std::hash { + typedef ska_ordered::power_of_two_hash_policy hash_policy; +}; + +} // namespace ska_ordered + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/overflows.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/overflows.h new file mode 100644 index 0000000000000000000000000000000000000000..e414de5aaab43b00062139b718067b14be4422ac --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/overflows.h @@ -0,0 +1,105 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace c10 { +// In some versions of MSVC, there will be a compiler error when building. +// C4146: unary minus operator applied to unsigned type, result still unsigned +// C4804: unsafe use of type 'bool' in operation +// It can be addressed by disabling the following warning. +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4146) +#pragma warning(disable : 4804) +#pragma warning(disable : 4018) +#endif + +// The overflow checks may involve float to int conversion which may +// trigger precision loss warning. Re-enable the warning once the code +// is fixed. See T58053069. +C10_CLANG_DIAGNOSTIC_PUSH() +#if C10_CLANG_HAS_WARNING("-Wimplicit-float-conversion") +C10_CLANG_DIAGNOSTIC_IGNORE("-Wimplicit-float-conversion") +#endif + +// bool can be converted to any type. +// Without specializing on bool, in pytorch_linux_trusty_py2_7_9_build: +// `error: comparison of constant '255' with boolean expression is always false` +// for `f > limit::max()` below +template +std::enable_if_t, bool> overflows( + From /*f*/, + bool strict_unsigned [[maybe_unused]] = false) { + return false; +} + +// skip isnan and isinf check for integral types +template +std::enable_if_t && !std::is_same_v, bool> +overflows(From f, bool strict_unsigned = false) { + using limit = std::numeric_limits::type>; + if constexpr (!limit::is_signed && std::numeric_limits::is_signed) { + // allow for negative numbers to wrap using two's complement arithmetic. + // For example, with uint8, this allows for `a - b` to be treated as + // `a + 255 * b`. + if (!strict_unsigned) { + return greater_than_max(f) || + (c10::is_negative(f) && + -static_cast(f) > static_cast(limit::max())); + } + } + return c10::less_than_lowest(f) || greater_than_max(f); +} + +template +std::enable_if_t, bool> overflows( + From f, + bool strict_unsigned [[maybe_unused]] = false) { + using limit = std::numeric_limits::type>; + if (limit::has_infinity && std::isinf(static_cast(f))) { + return false; + } + if (!limit::has_quiet_NaN && (f != f)) { + return true; + } + return f < limit::lowest() || f > limit::max(); +} + +C10_CLANG_DIAGNOSTIC_POP() + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +std::enable_if_t::value, bool> overflows( + From f, + bool strict_unsigned = false) { + // casts from complex to real are considered to overflow if the + // imaginary component is non-zero + if (!is_complex::value && f.imag() != 0) { + return true; + } + // Check for overflow componentwise + // (Technically, the imag overflow check is guaranteed to be false + // when !is_complex, but any optimizer worth its salt will be + // able to figure it out.) + return overflows< + typename scalar_value_type::type, + typename From::value_type>(f.real(), strict_unsigned) || + overflows< + typename scalar_value_type::type, + typename From::value_type>(f.imag(), strict_unsigned); +} +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/overloaded.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/overloaded.h new file mode 100644 index 0000000000000000000000000000000000000000..9c1571b57e808ab068dd5456e1ea83dfd9fd6342 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/overloaded.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +namespace c10 { +namespace detail { + +template +struct overloaded_t {}; + +template +struct overloaded_t : T0 { + using T0::operator(); + overloaded_t(T0 t0) : T0(std::move(t0)) {} +}; +template +struct overloaded_t : T0, overloaded_t { + using T0::operator(); + using overloaded_t::operator(); + overloaded_t(T0 t0, Ts... ts) + : T0(std::move(t0)), overloaded_t(std::move(ts)...) {} +}; + +} // namespace detail + +// Construct an overloaded callable combining multiple callables, e.g. lambdas +template +detail::overloaded_t overloaded(Ts... ts) { + return {std::move(ts)...}; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/python_stub.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/python_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..f457be5949a775e9ce3f4b8b39d8c4bbe95985b8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/python_stub.h @@ -0,0 +1,9 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +struct _object; +using PyObject = _object; + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/qint32.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/qint32.h new file mode 100644 index 0000000000000000000000000000000000000000..2b48a5a89c503e4a3ddae1aee65695044d1a3384 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/qint32.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/qint8.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/qint8.h new file mode 100644 index 0000000000000000000000000000000000000000..47f7a9e42540c917299479e9bda73da37083e082 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/qint8.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/quint2x4.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/quint2x4.h new file mode 100644 index 0000000000000000000000000000000000000000..b7781bc5772828da4ec97e1db4bbab2b7f54dd42 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/quint2x4.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/quint4x2.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/quint4x2.h new file mode 100644 index 0000000000000000000000000000000000000000..b4603a707c35a3a24eee27c4eea54c025f49454b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/quint4x2.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/quint8.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/quint8.h new file mode 100644 index 0000000000000000000000000000000000000000..5445be70945ff028d6ad98cff1732b678c7245da --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/quint8.h @@ -0,0 +1,6 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/safe_numerics.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/safe_numerics.h new file mode 100644 index 0000000000000000000000000000000000000000..f376f9dfd8a529851dd45a9319da482eae1c7c60 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/safe_numerics.h @@ -0,0 +1,119 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include + +#include +#include +#include + +// GCC has __builtin_mul_overflow from before it supported __has_builtin +#ifdef _MSC_VER +#define C10_HAS_BUILTIN_OVERFLOW() (0) +#include +#include +#else +#define C10_HAS_BUILTIN_OVERFLOW() (1) +#endif + +namespace c10 { + +template , int> = 0> +C10_ALWAYS_INLINE bool add_overflows(T a, T b, T* out) { +#if C10_HAS_BUILTIN_OVERFLOW() + return __builtin_add_overflow(a, b, out); +#else + if constexpr (std::is_signed_v) { + // For signed types, detect overflow by checking sign changes + volatile T tmp = a + b; + *out = tmp; + + // If both operands have the same sign, check if result changed sign + // unexpectedly. + if ((a > 0) == (b > 0)) { + if ((a > 0) && (tmp <= 0)) { + return true; // Positive overflow + } + if ((a < 0) && (tmp >= 0)) { + return true; // Negative overflow + } + } + return false; + } else { + // For unsigned types, overflow causes wrap-around + volatile T tmp = a + b; + *out = tmp; + return (tmp < a || tmp < b); + } +#endif +} + +C10_ALWAYS_INLINE bool add_overflows(uint64_t a, uint64_t b, uint64_t* out) { + return add_overflows(a, b, out); +} + +template , int> = 0> +C10_ALWAYS_INLINE bool mul_overflows(T a, T b, T* out) { +#if C10_HAS_BUILTIN_OVERFLOW() + return __builtin_mul_overflow(a, b, out); +#else + if constexpr (std::is_signed_v) { + // For signed types, use the division-based check + volatile T tmp = a * b; + *out = tmp; + if (a == 0 || b == 0) { + return false; + } + return !(a == tmp / b); + } else { + // For unsigned types, use leading zeros approach + // This test isn't exact, but avoids doing integer division + *out = a * b; + constexpr int bits = sizeof(T) * 8; + return ( + (c10::llvm::countLeadingZeros(a) + c10::llvm::countLeadingZeros(b)) < + bits); + } +#endif +} + +C10_ALWAYS_INLINE bool mul_overflows(uint64_t a, uint64_t b, uint64_t* out) { + return mul_overflows(a, b, out); +} + +template +bool safe_multiplies_u64(It first, It last, uint64_t* out) { +#if C10_HAS_BUILTIN_OVERFLOW() + uint64_t prod = 1; + bool overflow = false; + for (; first != last; ++first) { + overflow |= c10::mul_overflows(prod, *first, &prod); + } + *out = prod; + return overflow; +#else + uint64_t prod = 1; + uint64_t prod_log2 = 0; + bool is_zero = false; + for (; first != last; ++first) { + auto x = static_cast(*first); + prod *= x; + // log2(0) isn't valid, so need to track it specially + is_zero |= (x == 0); + prod_log2 += c10::llvm::Log2_64_Ceil(x); + } + *out = prod; + // This test isn't exact, but avoids doing integer division + return !is_zero && (prod_log2 >= 64); +#endif +} + +template +bool safe_multiplies_u64(const Container& c, uint64_t* out) { + return safe_multiplies_u64(c.begin(), c.end(), out); +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/signal_handler.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/signal_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..196d9687885fad0487b8e63e73302d2b558f83ad --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/signal_handler.h @@ -0,0 +1,124 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +#include + +#if defined(__APPLE__) +#define C10_SUPPORTS_SIGNAL_HANDLER +#elif defined(__linux__) && !defined(C10_DISABLE_SIGNAL_HANDLERS) +#define C10_SUPPORTS_FATAL_SIGNAL_HANDLERS +#define C10_SUPPORTS_SIGNAL_HANDLER +#endif + +#if defined(C10_SUPPORTS_FATAL_SIGNAL_HANDLERS) +#include +#endif + +namespace c10 { + +class C10_API SignalHandler { + public: + enum class Action { NONE, STOP }; + + // Constructor. Specify what action to take when a signal is received. + SignalHandler(Action SIGINT_action, Action SIGHUP_action); + + SignalHandler(const SignalHandler&) = delete; + SignalHandler(SignalHandler&&) = delete; + SignalHandler& operator=(const SignalHandler&) = delete; + SignalHandler& operator=(SignalHandler&&) = delete; + ~SignalHandler(); + + Action CheckForSignals(); + + bool GotSIGINT(); + bool GotSIGHUP(); + + Action SIGINT_action_; + Action SIGHUP_action_; + std::atomic my_sigint_count_; + std::atomic my_sighup_count_; +}; + +#if defined(C10_SUPPORTS_FATAL_SIGNAL_HANDLERS) +class C10_API FatalSignalHandler { + // This works by setting up certain fatal signal handlers. Previous fatal + // signal handlers will still be called when the signal is raised. Defaults + // to being off. + public: + C10_API void setPrintStackTracesOnFatalSignal(bool print); + C10_API bool printStackTracesOnFatalSignal(); + static FatalSignalHandler& getInstance(); + FatalSignalHandler(const FatalSignalHandler&) = delete; + FatalSignalHandler(FatalSignalHandler&&) = delete; + FatalSignalHandler& operator=(const FatalSignalHandler&) = delete; + FatalSignalHandler& operator=(FatalSignalHandler&&) = delete; + virtual ~FatalSignalHandler() = default; + + protected: + explicit FatalSignalHandler(); + + private: + void installFatalSignalHandlers(); + void uninstallFatalSignalHandlers(); + static void fatalSignalHandlerStatic(int signum, siginfo_t* info, void* ctx); + void fatalSignalHandler(int signum, siginfo_t* info); + virtual void fatalSignalHandlerPostProcess(); + struct sigaction* getPreviousSigaction(int signum); + const char* getSignalName(int signum); + void callPreviousSignalHandler( + struct sigaction* action, + int signum, + siginfo_t* info, + void* ctx); + void stacktraceSignalHandler(bool needsLock); + static void stacktraceSignalHandlerStatic( + int signum, + siginfo_t* info, + void* ctx); + void stacktraceSignalHandler(int signum, siginfo_t* info, void* ctx); + + // The mutex protects the bool. + std::mutex fatalSignalHandlersInstallationMutex; + bool fatalSignalHandlersInstalled; + // We need to hold a reference to call the previous SIGUSR2 handler in case + // we didn't signal it + struct sigaction previousSigusr2{}; + // Flag dictating whether the SIGUSR2 handler falls back to previous handlers + // or is intercepted in order to print a stack trace. + std::atomic fatalSignalReceived; + // Global state set when a fatal signal is received so that backtracing + // threads know why they're printing a stacktrace. + const char* fatalSignalName; + int fatalSignum = -1; + // This wait condition is used to wait for other threads to finish writing + // their stack trace when in fatal sig handler (we can't use pthread_join + // because there's no way to convert from a tid to a pthread_t). + std::condition_variable writingCond; + std::mutex writingMutex; + // used to indicate if the other thread responded to the signal + bool signalReceived; + + struct signal_handler { + const char* name; + int signum; + struct sigaction previous; + }; + + // NOLINTNEXTLINE(*c-arrays*) + static signal_handler kSignalHandlers[]; +}; + +#endif // defined(C10_SUPPORTS_SIGNAL_HANDLER) + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/sparse_bitset.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/sparse_bitset.h new file mode 100644 index 0000000000000000000000000000000000000000..877b4fb52f0ed04a6bb555201f0cc58163bfe552 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/sparse_bitset.h @@ -0,0 +1,898 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +//===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the SparseBitVector class. See the doxygen comment for +// SparseBitVector for more details on the algorithm used. +// +//===----------------------------------------------------------------------===// + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +namespace c10 { + +/// SparseBitVector is an implementation of a bitvector that is sparse by only +/// storing the elements that have non-zero bits set. In order to make this +/// fast for the most common cases, SparseBitVector is implemented as a linked +/// list of SparseBitVectorElements. We maintain a pointer to the last +/// SparseBitVectorElement accessed (in the form of a list iterator), in order +/// to make multiple in-order test/set constant time after the first one is +/// executed. Note that using vectors to store SparseBitVectorElement's does +/// not work out very well because it causes insertion in the middle to take +/// enormous amounts of time with a large amount of bits. Other structures that +/// have better worst cases for insertion in the middle (various balanced trees, +/// etc) do not perform as well in practice as a linked list with this iterator +/// kept up to date. They are also significantly more memory intensive. + +template +struct SparseBitVectorElement { + public: + using BitWord = unsigned long; + using size_type = unsigned; + enum { + BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT, + BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE, + BITS_PER_ELEMENT = ElementSize + }; + + private: + // Index of Element in terms of where first bit starts. + unsigned ElementIndex; + std::array Bits{}; + + SparseBitVectorElement() : ElementIndex(~0U) {} + + public: + explicit SparseBitVectorElement(unsigned Idx) : ElementIndex(Idx) {} + + // Comparison. + bool operator==(const SparseBitVectorElement& RHS) const { + if (ElementIndex != RHS.ElementIndex) + return false; + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) + if (Bits[i] != RHS.Bits[i]) + return false; + return true; + } + + bool operator!=(const SparseBitVectorElement& RHS) const { + return !(*this == RHS); + } + + // Return the bits that make up word Idx in our element. + BitWord word(unsigned Idx) const { + assert(Idx < BITWORDS_PER_ELEMENT); + return Bits[Idx]; + } + + unsigned index() const { + return ElementIndex; + } + + bool empty() const { + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) + if (Bits[i]) + return false; + return true; + } + + void set(unsigned Idx) { + Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE); + } + + bool test_and_set(unsigned Idx) { + bool old = test(Idx); + if (!old) { + set(Idx); + return true; + } + return false; + } + + void reset(unsigned Idx) { + Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE)); + } + + bool test(unsigned Idx) const { + return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE)); + } + + size_type count() const { + unsigned NumBits = 0; + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) + NumBits += llvm::countPopulation(Bits[i]); + return NumBits; + } + + /// find_first - Returns the index of the first set bit. + int find_first() const { + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) + if (Bits[i] != 0) + return i * BITWORD_SIZE + llvm::countTrailingZeros(Bits[i]); + throw std::runtime_error("Illegal empty element"); + } + + /// find_last - Returns the index of the last set bit. + int find_last() const { + for (unsigned I = 0; I < BITWORDS_PER_ELEMENT; ++I) { + unsigned Idx = BITWORDS_PER_ELEMENT - I - 1; + if (Bits[Idx] != 0) + return Idx * BITWORD_SIZE + BITWORD_SIZE - + llvm::countLeadingZeros(Bits[Idx]); + } + throw std::runtime_error("Illegal empty element"); + } + + /// find_next - Returns the index of the next set bit starting from the + /// "Curr" bit. Returns -1 if the next set bit is not found. + int find_next(unsigned Curr) const { + if (Curr >= BITS_PER_ELEMENT) + return -1; + + unsigned WordPos = Curr / BITWORD_SIZE; + unsigned BitPos = Curr % BITWORD_SIZE; + BitWord Copy = Bits[WordPos]; + assert( + WordPos <= BITWORDS_PER_ELEMENT && "Word Position outside of element"); + + // Mask off previous bits. + Copy &= ~0UL << BitPos; + + if (Copy != 0) + return WordPos * BITWORD_SIZE + llvm::countTrailingZeros(Copy); + + // Check subsequent words. + for (unsigned i = WordPos + 1; i < BITWORDS_PER_ELEMENT; ++i) + if (Bits[i] != 0) + return i * BITWORD_SIZE + llvm::countTrailingZeros(Bits[i]); + return -1; + } + + // Union this element with RHS and return true if this one changed. + bool unionWith(const SparseBitVectorElement& RHS) { + bool changed = false; + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) { + BitWord old = changed ? 0 : Bits[i]; + + Bits[i] |= RHS.Bits[i]; + if (!changed && old != Bits[i]) + changed = true; + } + return changed; + } + + // Return true if we have any bits in common with RHS + bool intersects(const SparseBitVectorElement& RHS) const { + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) { + if (RHS.Bits[i] & Bits[i]) + return true; + } + return false; + } + + // Intersect this Element with RHS and return true if this one changed. + // BecameZero is set to true if this element became all-zero bits. + bool intersectWith(const SparseBitVectorElement& RHS, bool& BecameZero) { + bool changed = false; + bool allzero = true; + + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) { + BitWord old = changed ? 0 : Bits[i]; + + Bits[i] &= RHS.Bits[i]; + if (Bits[i] != 0) + allzero = false; + + if (!changed && old != Bits[i]) + changed = true; + } + BecameZero = allzero; + return changed; + } + + // Intersect this Element with the complement of RHS and return true if this + // one changed. BecameZero is set to true if this element became all-zero + // bits. + bool intersectWithComplement( + const SparseBitVectorElement& RHS, + bool& BecameZero) { + bool changed = false; + bool allzero = true; + + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) { + BitWord old = changed ? 0 : Bits[i]; + + Bits[i] &= ~RHS.Bits[i]; + if (Bits[i] != 0) + allzero = false; + + if (!changed && old != Bits[i]) + changed = true; + } + BecameZero = allzero; + return changed; + } + + // Three argument version of intersectWithComplement that intersects + // RHS1 & ~RHS2 into this element + void intersectWithComplement( + const SparseBitVectorElement& RHS1, + const SparseBitVectorElement& RHS2, + bool& BecameZero) { + bool allzero = true; + + for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) { + Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i]; + if (Bits[i] != 0) + allzero = false; + } + BecameZero = allzero; + } +}; + +template +class SparseBitVector { + using ElementList = std::list>; + using ElementListIter = typename ElementList::iterator; + using ElementListConstIter = typename ElementList::const_iterator; + enum { BITWORD_SIZE = SparseBitVectorElement::BITWORD_SIZE }; + + ElementList Elements; + // Pointer to our current Element. This has no visible effect on the external + // state of a SparseBitVector, it's just used to improve performance in the + // common case of testing/modifying bits with similar indices. + mutable ElementListIter CurrElementIter; + + // This is like std::lower_bound, except we do linear searching from the + // current position. + ElementListIter FindLowerBoundImpl(unsigned ElementIndex) const { + // We cache a non-const iterator so we're forced to resort to const_cast to + // get the begin/end in the case where 'this' is const. To avoid duplication + // of code with the only difference being whether the const cast is present + // 'this' is always const in this particular function and we sort out the + // difference in FindLowerBound and FindLowerBoundConst. + ElementListIter Begin = + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + const_cast*>(this)->Elements.begin(); + ElementListIter End = + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) + const_cast*>(this)->Elements.end(); + + if (Elements.empty()) { + CurrElementIter = Begin; + return CurrElementIter; + } + + // Make sure our current iterator is valid. + if (CurrElementIter == End) + --CurrElementIter; + + // Search from our current iterator, either backwards or forwards, + // depending on what element we are looking for. + ElementListIter ElementIter = CurrElementIter; + if (CurrElementIter->index() == ElementIndex) { + return ElementIter; + } else if (CurrElementIter->index() > ElementIndex) { + while (ElementIter != Begin && ElementIter->index() > ElementIndex) + --ElementIter; + } else { + while (ElementIter != End && ElementIter->index() < ElementIndex) + ++ElementIter; + } + CurrElementIter = ElementIter; + return ElementIter; + } + ElementListConstIter FindLowerBoundConst(unsigned ElementIndex) const { + return FindLowerBoundImpl(ElementIndex); + } + ElementListIter FindLowerBound(unsigned ElementIndex) { + return FindLowerBoundImpl(ElementIndex); + } + + // Iterator to walk set bits in the bitmap. This iterator is a lot uglier + // than it would be, in order to be efficient. + class SparseBitVectorIterator { + private: + bool AtEnd{false}; + + const SparseBitVector* BitVector = nullptr; + + // Current element inside of bitmap. + ElementListConstIter Iter; + + // Current bit number inside of our bitmap. + unsigned BitNumber{0}; + + // Current word number inside of our element. + unsigned WordNumber{0}; + + // Current bits from the element. + typename SparseBitVectorElement::BitWord Bits{0}; + + // Move our iterator to the first non-zero bit in the bitmap. + void AdvanceToFirstNonZero() { + if (AtEnd) + return; + if (BitVector->Elements.empty()) { + AtEnd = true; + return; + } + Iter = BitVector->Elements.begin(); + BitNumber = Iter->index() * ElementSize; + unsigned BitPos = Iter->find_first(); + BitNumber += BitPos; + WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE; + Bits = Iter->word(WordNumber); + Bits >>= BitPos % BITWORD_SIZE; + } + + // Move our iterator to the next non-zero bit. + void AdvanceToNextNonZero() { + if (AtEnd) + return; + + while (Bits && !(Bits & 1)) { + Bits >>= 1; + BitNumber += 1; + } + + // See if we ran out of Bits in this word. + if (!Bits) { + int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize); + // If we ran out of set bits in this element, move to next element. + if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) { + ++Iter; + WordNumber = 0; + + // We may run out of elements in the bitmap. + if (Iter == BitVector->Elements.end()) { + AtEnd = true; + return; + } + // Set up for next non-zero word in bitmap. + BitNumber = Iter->index() * ElementSize; + NextSetBitNumber = Iter->find_first(); + BitNumber += NextSetBitNumber; + WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE; + Bits = Iter->word(WordNumber); + Bits >>= NextSetBitNumber % BITWORD_SIZE; + } else { + WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE; + Bits = Iter->word(WordNumber); + Bits >>= NextSetBitNumber % BITWORD_SIZE; + BitNumber = Iter->index() * ElementSize; + BitNumber += NextSetBitNumber; + } + } + } + + public: + SparseBitVectorIterator() = default; + + SparseBitVectorIterator( + const SparseBitVector* RHS, + bool end = false) + : AtEnd(end), + BitVector(RHS), + Iter(BitVector->Elements.begin()), + WordNumber(~0) { + AdvanceToFirstNonZero(); + } + + // Preincrement. + inline SparseBitVectorIterator& operator++() { + ++BitNumber; + Bits >>= 1; + AdvanceToNextNonZero(); + return *this; + } + + // Postincrement. + inline SparseBitVectorIterator operator++(int) { + SparseBitVectorIterator tmp = *this; + ++*this; + return tmp; + } + + // Return the current set bit number. + unsigned operator*() const { + return BitNumber; + } + + bool operator==(const SparseBitVectorIterator& RHS) const { + // If they are both at the end, ignore the rest of the fields. + if (AtEnd && RHS.AtEnd) + return true; + // Otherwise they are the same if they have the same bit number and + // bitmap. + return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber; + } + + bool operator!=(const SparseBitVectorIterator& RHS) const { + return !(*this == RHS); + } + }; + + public: + using iterator = SparseBitVectorIterator; + + SparseBitVector() : Elements(), CurrElementIter(Elements.begin()) {} + + SparseBitVector(const SparseBitVector& RHS) + : Elements(RHS.Elements), CurrElementIter(Elements.begin()) {} + SparseBitVector(SparseBitVector&& RHS) noexcept + : Elements(std::move(RHS.Elements)), CurrElementIter(Elements.begin()) {} + ~SparseBitVector() = default; + + // Clear. + void clear() { + Elements.clear(); + } + + // Assignment + SparseBitVector& operator=(const SparseBitVector& RHS) { + if (this == &RHS) + return *this; + + Elements = RHS.Elements; + CurrElementIter = Elements.begin(); + return *this; + } + SparseBitVector& operator=(SparseBitVector&& RHS) noexcept { + Elements = std::move(RHS.Elements); + CurrElementIter = Elements.begin(); + return *this; + } + + // Test, Reset, and Set a bit in the bitmap. + bool test(unsigned Idx) const { + if (Elements.empty()) + return false; + + unsigned ElementIndex = Idx / ElementSize; + ElementListConstIter ElementIter = FindLowerBoundConst(ElementIndex); + + // If we can't find an element that is supposed to contain this bit, there + // is nothing more to do. + if (ElementIter == Elements.end() || ElementIter->index() != ElementIndex) + return false; + return ElementIter->test(Idx % ElementSize); + } + + void reset(unsigned Idx) { + if (Elements.empty()) + return; + + unsigned ElementIndex = Idx / ElementSize; + ElementListIter ElementIter = FindLowerBound(ElementIndex); + + // If we can't find an element that is supposed to contain this bit, there + // is nothing more to do. + if (ElementIter == Elements.end() || ElementIter->index() != ElementIndex) + return; + ElementIter->reset(Idx % ElementSize); + + // When the element is zeroed out, delete it. + if (ElementIter->empty()) { + ++CurrElementIter; + Elements.erase(ElementIter); + } + } + + void set(unsigned Idx) { + unsigned ElementIndex = Idx / ElementSize; + ElementListIter ElementIter; + if (Elements.empty()) { + ElementIter = Elements.emplace(Elements.end(), ElementIndex); + } else { + ElementIter = FindLowerBound(ElementIndex); + + if (ElementIter == Elements.end() || + ElementIter->index() != ElementIndex) { + // We may have hit the beginning of our SparseBitVector, in which case, + // we may need to insert right after this element, which requires moving + // the current iterator forward one, because insert does insert before. + if (ElementIter != Elements.end() && + ElementIter->index() < ElementIndex) + ++ElementIter; + ElementIter = Elements.emplace(ElementIter, ElementIndex); + } + } + CurrElementIter = ElementIter; + + ElementIter->set(Idx % ElementSize); + } + + bool test_and_set(unsigned Idx) { + bool old = test(Idx); + if (!old) { + set(Idx); + return true; + } + return false; + } + + bool operator!=(const SparseBitVector& RHS) const { + return !(*this == RHS); + } + + bool operator==(const SparseBitVector& RHS) const { + ElementListConstIter Iter1 = Elements.begin(); + ElementListConstIter Iter2 = RHS.Elements.begin(); + + for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end(); + ++Iter1, ++Iter2) { + if (*Iter1 != *Iter2) + return false; + } + return Iter1 == Elements.end() && Iter2 == RHS.Elements.end(); + } + + // Union our bitmap with the RHS and return true if we changed. + bool operator|=(const SparseBitVector& RHS) { + if (this == &RHS) + return false; + + if (empty()) { + *this = RHS; + return true; + } + + bool changed = false; + ElementListIter Iter1 = Elements.begin(); + ElementListConstIter Iter2 = RHS.Elements.begin(); + + // If RHS is empty, we are done + if (RHS.Elements.empty()) + return false; + + while (Iter2 != RHS.Elements.end()) { + if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) { + Elements.insert(Iter1, *Iter2); + ++Iter2; + changed = true; + } else if (Iter1->index() == Iter2->index()) { + changed |= Iter1->unionWith(*Iter2); + ++Iter1; + ++Iter2; + } else { + ++Iter1; + } + } + CurrElementIter = Elements.begin(); + return changed; + } + + // Intersect our bitmap with the RHS and return true if ours changed. + bool operator-=(const SparseBitVector& RHS) { + return intersectWithComplement(RHS); + } + + // Intersect our bitmap with the RHS and return true if ours changed. + bool operator&=(const SparseBitVector& RHS) { + if (this == &RHS) + return false; + + bool changed = false; + ElementListIter Iter1 = Elements.begin(); + ElementListConstIter Iter2 = RHS.Elements.begin(); + + // Check if both bitmaps are empty. + if (Elements.empty() && RHS.Elements.empty()) + return false; + + // Loop through, intersecting as we go, erasing elements when necessary. + while (Iter2 != RHS.Elements.end()) { + if (Iter1 == Elements.end()) { + CurrElementIter = Elements.begin(); + return changed; + } + + if (Iter1->index() > Iter2->index()) { + ++Iter2; + } else if (Iter1->index() == Iter2->index()) { + bool BecameZero = false; + changed |= Iter1->intersectWith(*Iter2, BecameZero); + if (BecameZero) { + ElementListIter IterTmp = Iter1; + ++Iter1; + Elements.erase(IterTmp); + } else { + ++Iter1; + } + ++Iter2; + } else { + ElementListIter IterTmp = Iter1; + ++Iter1; + Elements.erase(IterTmp); + changed = true; + } + } + if (Iter1 != Elements.end()) { + Elements.erase(Iter1, Elements.end()); + changed = true; + } + CurrElementIter = Elements.begin(); + return changed; + } + + // Intersect our bitmap with the complement of the RHS and return true + // if ours changed. + bool intersectWithComplement(const SparseBitVector& RHS) { + if (this == &RHS) { + if (!empty()) { + clear(); + return true; + } + return false; + } + + bool changed = false; + ElementListIter Iter1 = Elements.begin(); + ElementListConstIter Iter2 = RHS.Elements.begin(); + + // If either our bitmap or RHS is empty, we are done + if (Elements.empty() || RHS.Elements.empty()) + return false; + + // Loop through, intersecting as we go, erasing elements when necessary. + while (Iter2 != RHS.Elements.end()) { + if (Iter1 == Elements.end()) { + CurrElementIter = Elements.begin(); + return changed; + } + + if (Iter1->index() > Iter2->index()) { + ++Iter2; + } else if (Iter1->index() == Iter2->index()) { + bool BecameZero = false; + changed |= Iter1->intersectWithComplement(*Iter2, BecameZero); + if (BecameZero) { + ElementListIter IterTmp = Iter1; + ++Iter1; + Elements.erase(IterTmp); + } else { + ++Iter1; + } + ++Iter2; + } else { + ++Iter1; + } + } + CurrElementIter = Elements.begin(); + return changed; + } + + bool intersectWithComplement(const SparseBitVector* RHS) const { + return intersectWithComplement(*RHS); + } + + // Three argument version of intersectWithComplement. + // Result of RHS1 & ~RHS2 is stored into this bitmap. + void intersectWithComplement( + const SparseBitVector& RHS1, + const SparseBitVector& RHS2) { + if (this == &RHS1) { + intersectWithComplement(RHS2); + return; + } else if (this == &RHS2) { + SparseBitVector RHS2Copy(RHS2); + intersectWithComplement(RHS1, RHS2Copy); + return; + } + + Elements.clear(); + CurrElementIter = Elements.begin(); + ElementListConstIter Iter1 = RHS1.Elements.begin(); + ElementListConstIter Iter2 = RHS2.Elements.begin(); + + // If RHS1 is empty, we are done + // If RHS2 is empty, we still have to copy RHS1 + if (RHS1.Elements.empty()) + return; + + // Loop through, intersecting as we go, erasing elements when necessary. + while (Iter2 != RHS2.Elements.end()) { + if (Iter1 == RHS1.Elements.end()) + return; + + if (Iter1->index() > Iter2->index()) { + ++Iter2; + } else if (Iter1->index() == Iter2->index()) { + bool BecameZero = false; + Elements.emplace_back(Iter1->index()); + Elements.back().intersectWithComplement(*Iter1, *Iter2, BecameZero); + if (BecameZero) + Elements.pop_back(); + ++Iter1; + ++Iter2; + } else { + Elements.push_back(*Iter1++); + } + } + + // copy the remaining elements + std::copy(Iter1, RHS1.Elements.end(), std::back_inserter(Elements)); + } + + void intersectWithComplement( + const SparseBitVector* RHS1, + const SparseBitVector* RHS2) { + intersectWithComplement(*RHS1, *RHS2); + } + + bool intersects(const SparseBitVector* RHS) const { + return intersects(*RHS); + } + + // Return true if we share any bits in common with RHS + bool intersects(const SparseBitVector& RHS) const { + ElementListConstIter Iter1 = Elements.begin(); + ElementListConstIter Iter2 = RHS.Elements.begin(); + + // Check if both bitmaps are empty. + if (Elements.empty() && RHS.Elements.empty()) + return false; + + // Loop through, intersecting stopping when we hit bits in common. + while (Iter2 != RHS.Elements.end()) { + if (Iter1 == Elements.end()) + return false; + + if (Iter1->index() > Iter2->index()) { + ++Iter2; + } else if (Iter1->index() == Iter2->index()) { + if (Iter1->intersects(*Iter2)) + return true; + ++Iter1; + ++Iter2; + } else { + ++Iter1; + } + } + return false; + } + + // Return true iff all bits set in this SparseBitVector are + // also set in RHS. + bool contains(const SparseBitVector& RHS) const { + SparseBitVector Result(*this); + Result &= RHS; + return (Result == RHS); + } + + // Return the first set bit in the bitmap. Return -1 if no bits are set. + int find_first() const { + if (Elements.empty()) + return -1; + const SparseBitVectorElement& First = *(Elements.begin()); + return (First.index() * ElementSize) + First.find_first(); + } + + // Return the last set bit in the bitmap. Return -1 if no bits are set. + int find_last() const { + if (Elements.empty()) + return -1; + const SparseBitVectorElement& Last = *(Elements.rbegin()); + return (Last.index() * ElementSize) + Last.find_last(); + } + + // Return true if the SparseBitVector is empty + bool empty() const { + return Elements.empty(); + } + + unsigned count() const { + unsigned BitCount = 0; + for (ElementListConstIter Iter = Elements.begin(); Iter != Elements.end(); + ++Iter) + BitCount += Iter->count(); + + return BitCount; + } + + iterator begin() const { + return iterator(this); + } + + iterator end() const { + return iterator(this, true); + } +}; + +// Convenience functions to allow Or and And without dereferencing in the user +// code. + +template +inline bool operator|=( + SparseBitVector& LHS, + const SparseBitVector* RHS) { + return LHS |= *RHS; +} + +template +inline bool operator|=( + SparseBitVector* LHS, + const SparseBitVector& RHS) { + return LHS->operator|=(RHS); +} + +template +inline bool operator&=( + SparseBitVector* LHS, + const SparseBitVector& RHS) { + return LHS->operator&=(RHS); +} + +template +inline bool operator&=( + SparseBitVector& LHS, + const SparseBitVector* RHS) { + return LHS &= *RHS; +} + +// Convenience functions for infix union, intersection, difference operators. + +template +inline SparseBitVector operator|( + const SparseBitVector& LHS, + const SparseBitVector& RHS) { + SparseBitVector Result(LHS); + Result |= RHS; + return Result; +} + +template +inline SparseBitVector operator&( + const SparseBitVector& LHS, + const SparseBitVector& RHS) { + SparseBitVector Result(LHS); + Result &= RHS; + return Result; +} + +template +inline SparseBitVector operator-( + const SparseBitVector& LHS, + const SparseBitVector& RHS) { + SparseBitVector Result; + Result.intersectWithComplement(LHS, RHS); + return Result; +} + +template +std::ostream& operator<<( + std::ostream& stream, + const SparseBitVector& vec) { + bool first = true; + stream << '{'; + for (auto el : vec) { + if (first) { + first = false; + } else { + stream << ", "; + } + stream << el; + } + stream << '}'; + return stream; +} + +} // end namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ssize.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ssize.h new file mode 100644 index 0000000000000000000000000000000000000000..395bf8a2eb7c5ef35f0de9530f4f9ccb9fe18e42 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/ssize.h @@ -0,0 +1,51 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include +#include + +namespace c10 { + +// Implementations of std::ssize() from C++ 20. +// +// This is useful in particular for avoiding -Werror=sign-compare +// issues. +// +// Use this with argument-dependent lookup, e.g.: +// use c10::ssize; +// auto size = ssize(container); +// +// As with the standard library version, containers are permitted to +// specialize this with a free function defined in the same namespace. +// +// See https://en.cppreference.com/w/cpp/iterator/size for more +// information as well as the source of our implementations. +// +// We augment the implementation by adding an assert() if an overflow +// would occur. + +template +constexpr auto ssize(const C& c) -> std:: + common_type_t> { + using R = std:: + common_type_t>; + // We expect this to be exceedingly rare to fire and don't wish to + // pay a performance hit in release mode. + TORCH_INTERNAL_ASSERT_DEBUG_ONLY(!greater_than_max(c.size())); + return static_cast(c.size()); +} + +template +// NOLINTNEXTLINE(*-c-arrays) +constexpr auto ssize(const T (&array)[N]) noexcept -> std::ptrdiff_t { + return N; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/static_tracepoint.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/static_tracepoint.h new file mode 100644 index 0000000000000000000000000000000000000000..4030828469d45cdbef603bbb8588071a41b9b398 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/static_tracepoint.h @@ -0,0 +1,39 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#if defined(__ELF__) && (defined(__x86_64__) || defined(__i386__)) && \ + !(defined(TORCH_DISABLE_SDT) && TORCH_DISABLE_SDT) + +#define TORCH_HAVE_SDT 1 + +#include + +#define TORCH_SDT(name, ...) \ + TORCH_SDT_PROBE_N( \ + pytorch, name, 0, TORCH_SDT_NARG(0, ##__VA_ARGS__), ##__VA_ARGS__) +// Use TORCH_SDT_DEFINE_SEMAPHORE(name) to define the semaphore +// as global variable before using the TORCH_SDT_WITH_SEMAPHORE macro +#define TORCH_SDT_WITH_SEMAPHORE(name, ...) \ + TORCH_SDT_PROBE_N( \ + pytorch, name, 1, TORCH_SDT_NARG(0, ##__VA_ARGS__), ##__VA_ARGS__) +#define TORCH_SDT_IS_ENABLED(name) (TORCH_SDT_SEMAPHORE(pytorch, name) > 0) + +#else + +#define TORCH_HAVE_SDT 0 + +#define TORCH_SDT(name, ...) \ + do { \ + } while (0) +#define TORCH_SDT_WITH_SEMAPHORE(name, ...) \ + do { \ + } while (0) +#define TORCH_SDT_IS_ENABLED(name) (false) +#define TORCH_SDT_DEFINE_SEMAPHORE(name) +#define TORCH_SDT_DECLARE_SEMAPHORE(name) + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/static_tracepoint_elfx86.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/static_tracepoint_elfx86.h new file mode 100644 index 0000000000000000000000000000000000000000..a3afe767fee1e9cf92062b2ece5e2f0520dcb9e4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/static_tracepoint_elfx86.h @@ -0,0 +1,149 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// clang-format off + +// Default constraint for the probe arguments as operands. +#ifndef TORCH_SDT_ARG_CONSTRAINT +#define TORCH_SDT_ARG_CONSTRAINT "nor" +#endif + +// Instruction to emit for the probe. +#define TORCH_SDT_NOP nop + +// Note section properties. +#define TORCH_SDT_NOTE_NAME "stapsdt" +#define TORCH_SDT_NOTE_TYPE 3 + +// Semaphore variables are put in this section +#define TORCH_SDT_SEMAPHORE_SECTION ".probes" + +// Size of address depending on platform. +#ifdef __LP64__ +#define TORCH_SDT_ASM_ADDR .8byte +#else +#define TORCH_SDT_ASM_ADDR .4byte +#endif + +// Assembler helper Macros. +#define TORCH_SDT_S(x) #x +#define TORCH_SDT_ASM_1(x) TORCH_SDT_S(x) "\n" +#define TORCH_SDT_ASM_2(a, b) TORCH_SDT_S(a) "," TORCH_SDT_S(b) "\n" +#define TORCH_SDT_ASM_3(a, b, c) TORCH_SDT_S(a) "," TORCH_SDT_S(b) "," \ + TORCH_SDT_S(c) "\n" +#define TORCH_SDT_ASM_STRING(x) TORCH_SDT_ASM_1(.asciz TORCH_SDT_S(x)) + +// Helper to determine the size of an argument. +#define TORCH_SDT_IS_ARRAY_POINTER(x) ((__builtin_classify_type(x) == 14) || \ + (__builtin_classify_type(x) == 5)) +#define TORCH_SDT_ARGSIZE(x) (TORCH_SDT_IS_ARRAY_POINTER(x) \ + ? sizeof(void*) \ + : sizeof(x)) + +// Format of each probe arguments as operand. +// Size of the argument tagged with TORCH_SDT_Sn, with "n" constraint. +// Value of the argument tagged with TORCH_SDT_An, with configured constraint. +#define TORCH_SDT_ARG(n, x) \ + [TORCH_SDT_S##n] "n" ((size_t)TORCH_SDT_ARGSIZE(x)), \ + [TORCH_SDT_A##n] TORCH_SDT_ARG_CONSTRAINT (x) + +// Templates to append arguments as operands. +#define TORCH_SDT_OPERANDS_0() [__sdt_dummy] "g" (0) +#define TORCH_SDT_OPERANDS_1(_1) TORCH_SDT_ARG(1, _1) +#define TORCH_SDT_OPERANDS_2(_1, _2) \ + TORCH_SDT_OPERANDS_1(_1), TORCH_SDT_ARG(2, _2) +#define TORCH_SDT_OPERANDS_3(_1, _2, _3) \ + TORCH_SDT_OPERANDS_2(_1, _2), TORCH_SDT_ARG(3, _3) +#define TORCH_SDT_OPERANDS_4(_1, _2, _3, _4) \ + TORCH_SDT_OPERANDS_3(_1, _2, _3), TORCH_SDT_ARG(4, _4) +#define TORCH_SDT_OPERANDS_5(_1, _2, _3, _4, _5) \ + TORCH_SDT_OPERANDS_4(_1, _2, _3, _4), TORCH_SDT_ARG(5, _5) +#define TORCH_SDT_OPERANDS_6(_1, _2, _3, _4, _5, _6) \ + TORCH_SDT_OPERANDS_5(_1, _2, _3, _4, _5), TORCH_SDT_ARG(6, _6) +#define TORCH_SDT_OPERANDS_7(_1, _2, _3, _4, _5, _6, _7) \ + TORCH_SDT_OPERANDS_6(_1, _2, _3, _4, _5, _6), TORCH_SDT_ARG(7, _7) +#define TORCH_SDT_OPERANDS_8(_1, _2, _3, _4, _5, _6, _7, _8) \ + TORCH_SDT_OPERANDS_7(_1, _2, _3, _4, _5, _6, _7), TORCH_SDT_ARG(8, _8) +#define TORCH_SDT_OPERANDS_9(_1, _2, _3, _4, _5, _6, _7, _8, _9) \ + TORCH_SDT_OPERANDS_8(_1, _2, _3, _4, _5, _6, _7, _8), TORCH_SDT_ARG(9, _9) + +// Templates to reference the arguments from operands in note section. +#define TORCH_SDT_ARGFMT(no) %n[TORCH_SDT_S##no]@%[TORCH_SDT_A##no] +#define TORCH_SDT_ARG_TEMPLATE_0 /*No arguments*/ +#define TORCH_SDT_ARG_TEMPLATE_1 TORCH_SDT_ARGFMT(1) +#define TORCH_SDT_ARG_TEMPLATE_2 TORCH_SDT_ARG_TEMPLATE_1 TORCH_SDT_ARGFMT(2) +#define TORCH_SDT_ARG_TEMPLATE_3 TORCH_SDT_ARG_TEMPLATE_2 TORCH_SDT_ARGFMT(3) +#define TORCH_SDT_ARG_TEMPLATE_4 TORCH_SDT_ARG_TEMPLATE_3 TORCH_SDT_ARGFMT(4) +#define TORCH_SDT_ARG_TEMPLATE_5 TORCH_SDT_ARG_TEMPLATE_4 TORCH_SDT_ARGFMT(5) +#define TORCH_SDT_ARG_TEMPLATE_6 TORCH_SDT_ARG_TEMPLATE_5 TORCH_SDT_ARGFMT(6) +#define TORCH_SDT_ARG_TEMPLATE_7 TORCH_SDT_ARG_TEMPLATE_6 TORCH_SDT_ARGFMT(7) +#define TORCH_SDT_ARG_TEMPLATE_8 TORCH_SDT_ARG_TEMPLATE_7 TORCH_SDT_ARGFMT(8) +#define TORCH_SDT_ARG_TEMPLATE_9 TORCH_SDT_ARG_TEMPLATE_8 TORCH_SDT_ARGFMT(9) + +// Resolvable by name macros +// An attribute that marks a function or variable as needing to be resolvable +// by name. This generally is needed if inline assembly refers to the variable +// by string name. +#ifdef __roar__ +#define TORCH_NAME_RESOLVABLE __attribute__((roar_resolvable_by_name)) +#else +#define TORCH_NAME_RESOLVABLE +#endif + +// Semaphore define, declare and probe note format + +#define TORCH_SDT_SEMAPHORE(provider, name) \ + torch_sdt_semaphore_##provider##_##name + +#define TORCH_SDT_DEFINE_SEMAPHORE(name) \ + extern "C" { \ + TORCH_NAME_RESOLVABLE \ + volatile unsigned short TORCH_SDT_SEMAPHORE(pytorch, name) \ + __attribute__((section(TORCH_SDT_SEMAPHORE_SECTION), used)) = 0; \ + } + +#define TORCH_SDT_DECLARE_SEMAPHORE(name) \ + extern "C" TORCH_NAME_RESOLVABLE volatile unsigned short \ + TORCH_SDT_SEMAPHORE(pytorch, name) + +#define TORCH_SDT_SEMAPHORE_NOTE_0(provider, name) \ + TORCH_SDT_ASM_1( TORCH_SDT_ASM_ADDR 0) /*No Semaphore*/ \ + +#define TORCH_SDT_SEMAPHORE_NOTE_1(provider, name) \ + TORCH_SDT_ASM_1(TORCH_SDT_ASM_ADDR TORCH_SDT_SEMAPHORE(provider, name)) + +// Structure of note section for the probe. +#define TORCH_SDT_NOTE_CONTENT(provider, name, has_semaphore, arg_template) \ + TORCH_SDT_ASM_1(990: TORCH_SDT_NOP) \ + TORCH_SDT_ASM_3( .pushsection .note.stapsdt,"","note") \ + TORCH_SDT_ASM_1( .balign 4) \ + TORCH_SDT_ASM_3( .4byte 992f-991f, 994f-993f, TORCH_SDT_NOTE_TYPE) \ + TORCH_SDT_ASM_1(991: .asciz TORCH_SDT_NOTE_NAME) \ + TORCH_SDT_ASM_1(992: .balign 4) \ + TORCH_SDT_ASM_1(993: TORCH_SDT_ASM_ADDR 990b) \ + TORCH_SDT_ASM_1( TORCH_SDT_ASM_ADDR 0) /*Reserved for Base Address*/ \ + TORCH_SDT_SEMAPHORE_NOTE_##has_semaphore(provider, name) \ + TORCH_SDT_ASM_STRING(provider) \ + TORCH_SDT_ASM_STRING(name) \ + TORCH_SDT_ASM_STRING(arg_template) \ + TORCH_SDT_ASM_1(994: .balign 4) \ + TORCH_SDT_ASM_1( .popsection) + +// Main probe Macro. +#define TORCH_SDT_PROBE(provider, name, has_semaphore, n, arglist) \ + __asm__ __volatile__ ( \ + TORCH_SDT_NOTE_CONTENT( \ + provider, name, has_semaphore, TORCH_SDT_ARG_TEMPLATE_##n) \ + :: TORCH_SDT_OPERANDS_##n arglist \ + ) \ + +// Helper Macros to handle variadic arguments. +#define TORCH_SDT_NARG_(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N +#define TORCH_SDT_NARG(...) \ + TORCH_SDT_NARG_(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define TORCH_SDT_PROBE_N(provider, name, has_semaphore, N, ...) \ + TORCH_SDT_PROBE(provider, name, has_semaphore, N, (__VA_ARGS__)) + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/strides.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/strides.h new file mode 100644 index 0000000000000000000000000000000000000000..1e74cffc5e6338d234846bac166d5fcac7db63b0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/strides.h @@ -0,0 +1,29 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include +#include + +namespace c10 { + +// Computes the contiguous strides of a tensor, given its sizes. +inline DimVector contiguous_strides(const IntArrayRef sizes) { + using Int = IntArrayRef::value_type; + const Int dims = static_cast(sizes.size()); + + // With this initialisation we get the case dim == 0 or 1 right + DimVector strides(dims, 1); + + for (auto i = dims - 2; i >= 0; --i) { + // Strides can't be 0 even if sizes are 0. + strides[i] = strides[i + 1] * std::max(sizes[i + 1], Int{1}); + } + + return strides; +} + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/string_utils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/string_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..cbcf0b1f3c95d2e0e572ae58b6e066efc893f582 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/string_utils.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#if !defined(FBCODE_CAFFE2) && !defined(C10_NO_DEPRECATED) + +namespace c10 { + +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::stod; +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::stoi; +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::stoll; +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::stoull; +// NOLINTNEXTLINE(misc-unused-using-decls) +using std::to_string; + +} // namespace c10 + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/string_view.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/string_view.h new file mode 100644 index 0000000000000000000000000000000000000000..559cde09f9c35071293f0ed62d481ea7f6940710 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/string_view.h @@ -0,0 +1,648 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace c10 { + +/** + * Port of std::string_view with methods from C++20. + * Implemented following the interface definition in + * https://en.cppreference.com/w/cpp/string/basic_string_view + * See there for the API documentation. + * + * Difference: We don't have a Traits template parameter because + * std::char_traits isn't constexpr and we'd have to reimplement + * std::char_traits if we wanted to use it with our constexpr basic_string_view. + */ +template +// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions) +class basic_string_view final { + public: + using value_type = CharT; + using pointer = CharT*; + using const_pointer = const CharT*; + using reference = CharT&; + using const_reference = const CharT&; + using const_iterator = const CharT*; + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator; + using reverse_iterator = const_reverse_iterator; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + static constexpr size_type npos = size_type(-1); + + constexpr basic_string_view() noexcept : begin_(nullptr) {} + + explicit constexpr basic_string_view(const_pointer str, size_type count) + : begin_(str), size_(count) {} + + /* implicit */ constexpr basic_string_view(const_pointer str) + : basic_string_view(str, strlen_(str)) {} + + /* implicit */ basic_string_view(const ::std::basic_string& str) + : basic_string_view(str.data(), str.size()) {} + + /* implicit */ constexpr basic_string_view( + const ::std::basic_string_view& str) + : basic_string_view(str.data(), str.size()) {} + + constexpr basic_string_view(const basic_string_view&) noexcept = default; + + constexpr basic_string_view& operator=( + const basic_string_view& rhs) noexcept = default; + + constexpr operator ::std::basic_string_view() const { + return ::std::basic_string_view(data(), size()); + } + + explicit operator ::std::basic_string() const { + return ::std::basic_string(data(), size()); + } + + constexpr const_iterator begin() const noexcept { + return cbegin(); + } + + constexpr const_iterator cbegin() const noexcept { + return begin_; + } + + constexpr const_iterator end() const noexcept { + return cend(); + } + + constexpr const_iterator cend() const noexcept { + return begin_ + size_; + } + + constexpr const_reverse_iterator rbegin() const noexcept { + return crbegin(); + } + + constexpr const_reverse_iterator crbegin() const noexcept { + return const_reverse_iterator(this->end()); + } + + constexpr const_reverse_iterator rend() const noexcept { + return crend(); + } + + constexpr const_reverse_iterator crend() const noexcept { + return const_reverse_iterator(this->begin()); + } + + friend constexpr const_iterator begin(basic_string_view sv) noexcept { + return sv.begin(); + } + + friend constexpr const_iterator end(basic_string_view sv) noexcept { + return sv.end(); + } + + constexpr const_reference operator[](size_type pos) const { + // TODO: split out + return at_(pos); + } + + constexpr const_reference at(size_type pos) const { +#if !defined( \ + __CUDA_ARCH__) // CUDA doesn't like std::out_of_range in device code + return C10_UNLIKELY(pos >= size_) + ? (throw std::out_of_range( + "string_view::operator[] or string_view::at() out of range. Index: " + + std::to_string(pos) + ", size: " + std::to_string(size())), + at_(0)) + : at_(pos); +#else + return at_(pos); +#endif + } + + constexpr const_reference front() const { + return *begin_; + } + + constexpr const_reference back() const { + return *(begin_ + size_ - 1); + } + + constexpr const_pointer data() const noexcept { + return begin_; + } + + constexpr size_type size() const noexcept { + return size_; + } + + constexpr size_type length() const noexcept { + return size(); + } + + constexpr size_type max_size() const noexcept { + return std::numeric_limits::max(); + } + + [[nodiscard]] constexpr bool empty() const noexcept { + return size() == 0; + } + + constexpr void remove_prefix(size_type n) { + if (n > size()) { + throw std::out_of_range( + "basic_string_view::remove_prefix: out of range. PrefixLength: " + + std::to_string(n) + ", size: " + std::to_string(size())); + } + begin_ += n; + size_ -= n; + } + + constexpr void remove_suffix(size_type n) { + if (n > size()) { + throw std::out_of_range( + "basic_string_view::remove_suffix: out of range. SuffixLength: " + + std::to_string(n) + ", size: " + std::to_string(size())); + } + size_ -= n; + } + + constexpr void swap(basic_string_view& sv) noexcept { + auto tmp = *this; + *this = sv; + sv = tmp; + } + + size_type copy(pointer dest, size_type count, size_type pos = 0) const { + if (pos > size_) { + throw std::out_of_range( + "basic_string_view::copy: out of range. Index: " + + std::to_string(pos) + ", size: " + std::to_string(size())); + } + size_type copy_length = std::min(count, size_ - pos); + for (auto iter = begin() + pos, end = iter + copy_length; iter != end;) { + *(dest++) = *(iter++); + } + return copy_length; + } + + constexpr basic_string_view substr(size_type pos = 0, size_type count = npos) + const { +#if !defined( \ + __CUDA_ARCH__) // CUDA doesn't like std::out_of_range in device code + return (pos > size_) + ? (throw std::out_of_range( + "basic_string_view::substr parameter out of bounds. Index: " + + std::to_string(pos) + ", size: " + std::to_string(size())), + substr_()) + : substr_(pos, count); +#else + return substr_(pos, count); +#endif + } + + constexpr int compare(basic_string_view rhs) const noexcept { + // Write it iteratively. This is faster. + for (size_t i = 0, end = std::min(size(), rhs.size()); i < end; ++i) { + if (at_(i) < rhs.at_(i)) { + return -1; + } else if (at_(i) > rhs.at_(i)) { + return 1; + } + } + if (size() < rhs.size()) { + return -1; + } else if (size() > rhs.size()) { + return 1; + } + return 0; + } + + constexpr int compare(size_type pos1, size_type count1, basic_string_view v) + const { + return substr(pos1, count1).compare(v); + } + + constexpr int compare( + size_type pos1, + size_type count1, + basic_string_view v, + size_type pos2, + size_type count2) const { + return substr(pos1, count1).compare(v.substr(pos2, count2)); + } + + constexpr int compare(const_pointer s) const { + return compare(basic_string_view(s)); + } + + constexpr int compare(size_type pos1, size_type count1, const_pointer s) + const { + return substr(pos1, count1).compare(basic_string_view(s)); + } + + constexpr int compare( + size_type pos1, + size_type count1, + const_pointer s, + size_type count2) const { + return substr(pos1, count1).compare(basic_string_view(s, count2)); + } + + friend constexpr bool operator==( + basic_string_view lhs, + basic_string_view rhs) noexcept { + return lhs.equals_(rhs); + } + + friend constexpr bool operator!=( + basic_string_view lhs, + basic_string_view rhs) noexcept { + return !(lhs == rhs); + } + + friend constexpr bool operator<( + basic_string_view lhs, + basic_string_view rhs) noexcept { + return lhs.compare(rhs) < 0; + } + + friend constexpr bool operator>=( + basic_string_view lhs, + basic_string_view rhs) noexcept { + return !(lhs < rhs); + } + + friend constexpr bool operator>( + basic_string_view lhs, + basic_string_view rhs) noexcept { + return rhs < lhs; + } + + friend constexpr bool operator<=( + basic_string_view lhs, + basic_string_view rhs) noexcept { + return !(lhs > rhs); + } + + constexpr bool starts_with(basic_string_view prefix) const noexcept { + return (prefix.size() > size()) ? false + : prefix.equals_(substr_(0, prefix.size())); + } + + constexpr bool starts_with(CharT prefix) const noexcept { + return !empty() && prefix == front(); + } + + constexpr bool starts_with(const_pointer prefix) const { + return starts_with(basic_string_view(prefix)); + } + + constexpr bool ends_with(basic_string_view suffix) const noexcept { + return (suffix.size() > size()) + ? false + : suffix.equals_(substr_(size() - suffix.size(), suffix.size())); + } + + constexpr bool ends_with(CharT suffix) const noexcept { + return !empty() && suffix == back(); + } + + constexpr bool ends_with(const_pointer suffix) const { + return ends_with(basic_string_view(suffix)); + } + + constexpr size_type find(basic_string_view v, size_type pos = 0) + const noexcept { + if (v.empty()) { + return pos <= size() ? pos : npos; + } + + if (pos + v.size() <= size()) { + for (size_type cur = pos, end = size() - v.size(); cur <= end; ++cur) { + if (v.at_(0) == at_(cur) && + v.substr_(1).equals_(substr_(cur + 1, v.size() - 1))) { + return cur; + } + } + } + return npos; + } + + constexpr size_type find(CharT ch, size_type pos = 0) const noexcept { + return find_first_if_(pos, charIsEqual_{ch}); + } + + constexpr size_type find(const_pointer s, size_type pos, size_type count) + const { + return find(basic_string_view(s, count), pos); + } + + constexpr size_type find(const_pointer s, size_type pos = 0) const { + return find(basic_string_view(s), pos); + } + + constexpr size_type rfind(basic_string_view v, size_type pos = npos) + const noexcept { + // Write it iteratively. This is faster. + if (v.empty()) { + return pos <= size() ? pos : size(); + } + + if (v.size() <= size()) { + pos = std::min(size() - v.size(), pos); + do { + if (v.at_(0) == at_(pos) && + v.substr_(1).equals_(substr_(pos + 1, v.size() - 1))) { + return pos; + } + } while (pos-- > 0); + } + return npos; + } + + constexpr size_type rfind(CharT ch, size_type pos = npos) const noexcept { + return find_last_if_(pos, charIsEqual_{ch}); + } + + constexpr size_type rfind(const_pointer s, size_type pos, size_type count) + const { + return rfind(basic_string_view(s, count), pos); + } + + constexpr size_type rfind(const_pointer s, size_type pos = npos) const { + return rfind(basic_string_view(s), pos); + } + + constexpr size_type find_first_of(basic_string_view v, size_type pos = 0) + const noexcept { + return find_first_if_(pos, stringViewContainsChar_{v}); + } + + constexpr size_type find_first_of(CharT ch, size_type pos = 0) + const noexcept { + return find_first_if_(pos, charIsEqual_{ch}); + } + + constexpr size_type find_first_of( + const_pointer s, + size_type pos, + size_type count) const { + return find_first_of(basic_string_view(s, count), pos); + } + + constexpr size_type find_first_of(const_pointer s, size_type pos = 0) const { + return find_first_of(basic_string_view(s), pos); + } + + constexpr size_type find_last_of(basic_string_view v, size_type pos = npos) + const noexcept { + return find_last_if_(pos, stringViewContainsChar_{v}); + } + + constexpr size_type find_last_of(CharT ch, size_type pos = npos) + const noexcept { + return find_last_if_(pos, charIsEqual_{ch}); + } + + constexpr size_type find_last_of( + const_pointer s, + size_type pos, + size_type count) const { + return find_last_of(basic_string_view(s, count), pos); + } + + constexpr size_type find_last_of(const_pointer s, size_type pos = npos) + const { + return find_last_of(basic_string_view(s), pos); + } + + constexpr size_type find_first_not_of(basic_string_view v, size_type pos = 0) + const noexcept { + return find_first_if_(pos, stringViewDoesNotContainChar_{v}); + } + + constexpr size_type find_first_not_of(CharT ch, size_type pos = 0) + const noexcept { + return find_first_if_(pos, charIsNotEqual_{ch}); + } + + constexpr size_type find_first_not_of( + const_pointer s, + size_type pos, + size_type count) const { + return find_first_not_of(basic_string_view(s, count), pos); + } + + constexpr size_type find_first_not_of(const_pointer s, size_type pos = 0) + const { + return find_first_not_of(basic_string_view(s), pos); + } + + constexpr size_type find_last_not_of( + basic_string_view v, + size_type pos = npos) const noexcept { + return find_last_if_(pos, stringViewDoesNotContainChar_{v}); + } + + constexpr size_type find_last_not_of(CharT ch, size_type pos = npos) + const noexcept { + return find_last_if_(pos, charIsNotEqual_{ch}); + } + + constexpr size_type find_last_not_of( + const_pointer s, + size_type pos, + size_type count) const { + return find_last_not_of(basic_string_view(s, count), pos); + } + + constexpr size_type find_last_not_of(const_pointer s, size_type pos = npos) + const { + return find_last_not_of(basic_string_view(s), pos); + } + + private: + static constexpr size_type strlen_(const_pointer str) noexcept { + const_pointer current = str; + while (*current != '\0') { + ++current; + } + return current - str; + } + + constexpr const_reference at_(size_type pos) const noexcept { + return *(begin_ + pos); + } + + constexpr basic_string_view substr_(size_type pos = 0, size_type count = npos) + const { + return basic_string_view{begin_ + pos, std::min(count, size() - pos)}; + } + + template + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) + constexpr size_type find_first_if_(size_type pos, Condition&& condition) + const noexcept { + if (pos + 1 <= size()) { + for (size_type cur = pos; cur < size(); ++cur) { + if (condition(at_(cur))) { + return cur; + } + } + } + return npos; + } + + template + // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) + constexpr size_type find_last_if_(size_type pos, Condition&& condition) + const noexcept { + // Write it iteratively. This is faster. + if (!empty()) { + pos = std::min(size() - 1, pos); + do { + if (condition(at_(pos))) { + return pos; + } + } while (pos-- > 0); + } + return npos; + } + + constexpr bool equals_(basic_string_view rhs) const { + // We don't use string_view::compare() here but implement it manually + // because only looking at equality allows for more optimized code. +#if defined(__GNUC__) && !defined(__CUDACC__) + return size() == rhs.size() && + 0 == __builtin_memcmp(data(), rhs.data(), size()); +#else + if (size() != rhs.size()) { + return false; + } + // Yes, memcmp would be laster than this loop, but memcmp isn't constexpr + // and I didn't feel like implementing a constexpr memcmp variant. + // TODO At some point this should probably be done, including tricks + // like comparing one machine word instead of a byte per iteration. + for (typename basic_string_view::size_type pos = 0; pos < size(); + ++pos) { + if (at_(pos) != rhs.at_(pos)) { + return false; + } + } + return true; +#endif + } + + struct charIsEqual_ final { + CharT expected; + constexpr bool operator()(CharT actual) const noexcept { + return expected == actual; + } + }; + + struct charIsNotEqual_ final { + CharT expected; + constexpr bool operator()(CharT actual) const noexcept { + return expected != actual; + } + }; + + struct stringViewContainsChar_ final { + basic_string_view expected; + constexpr bool operator()(CharT ch) const noexcept { + return npos != expected.find(ch); + } + }; + + struct stringViewDoesNotContainChar_ final { + basic_string_view expected; + constexpr bool operator()(CharT ch) const noexcept { + return npos == expected.find(ch); + } + }; + + const_pointer begin_; + size_type size_{}; +}; + +template +inline std::basic_ostream& operator<<( + std::basic_ostream& stream, + basic_string_view sv) { + // The rules for operator<< are quite complex, so lets defer to the + // STL implementation. + using std_string_type = ::std::basic_string_view; + return stream << std_string_type(sv.data(), sv.size()); +} + +template +constexpr inline void swap( + basic_string_view& lhs, + basic_string_view& rhs) noexcept { + lhs.swap(rhs); +} +using string_view = std::string_view; +using c10_string_view = basic_string_view; + +// NOTE: In C++20, this function should be replaced by string_view.starts_with +constexpr bool starts_with( + const std::string_view s, + const std::string_view prefix) noexcept { + return (prefix.size() > s.size()) ? false + : prefix == s.substr(0, prefix.size()); +} + +// NOTE: In C++20, this function should be replaced by string_view.starts_with +constexpr bool starts_with( + const std::string_view s, + const char prefix) noexcept { + return !s.empty() && prefix == s.front(); +} + +// NOTE: In C++20, this function should be replaced by string_view.ends_with +constexpr bool ends_with( + const std::string_view s, + const std::string_view suffix) noexcept { + return (suffix.size() > s.size()) + ? false + : suffix == s.substr(s.size() - suffix.size(), suffix.size()); +} + +// NOTE: In C++20, this function should be replaced by string_view.ends_with +constexpr bool ends_with(const std::string_view s, const char prefix) noexcept { + return !s.empty() && prefix == s.back(); +} + +} // namespace c10 + +namespace std { +template +struct hash<::c10::basic_string_view> { + size_t operator()(::c10::basic_string_view x) const { + // The standard says that std::string_view hashing must do the same as + // std::string hashing but leaves the details of std::string hashing + // up to the implementer. So, to be conformant, we need to reuse and + // existing STL type's hash function. The std::string fallback is probably + // slow but the only way to be conformant. + + using std_string_type = ::std::basic_string_view; + return ::std::hash{}(std_string_type(x.data(), x.size())); + } +}; +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/strong_type.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/strong_type.h new file mode 100644 index 0000000000000000000000000000000000000000..eacb5ac194bf93b67545c9951c1983cc0defa64d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/strong_type.h @@ -0,0 +1,1669 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * strong_type C++14/17/20 strong typedef library + * + * Copyright (C) Björn Fahller + * + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * Project home: https://github.com/rollbear/strong_type + */ + +#ifndef ROLLBEAR_STRONG_TYPE_HPP_INCLUDED +#define ROLLBEAR_STRONG_TYPE_HPP_INCLUDED + +#include +#include +#include +#include +#include + +#ifndef STRONG_HAS_STD_FORMAT +#define STRONG_HAS_STD_FORMAT 0 +#endif + +#ifndef STRONG_HAS_FMT_FORMAT +#define STRONG_HAS_FMT_FORMAT 0 +#endif + +#if STRONG_HAS_STD_FORMAT +#include +#if !defined(__cpp_lib_format) || __cpp_lib_format < 201907 +#undef STRONG_HAS_STD_FORMAT +#define STRONG_HAS_STD_FORMAT 0 +#endif +#endif + +#if STRONG_HAS_FMT_FORMAT +#include +#endif + +namespace strong +{ + +namespace impl +{ + template + using WhenConstructible = std::enable_if_t>; +} + +template +using modifier = typename M::template modifier; + +struct uninitialized_t {}; +static constexpr uninitialized_t uninitialized{}; + +struct default_constructible +{ + template + class modifier + { + }; +}; + +namespace impl { + template + constexpr bool supports_default_construction(const ::strong::default_constructible::modifier* /*unused*/) + { + return true; + } +} + +template +class type : public modifier>... +{ +public: + template {}>> + explicit type(uninitialized_t /*unused*/) + noexcept + { + } + template (nullptr))> + constexpr + type() + noexcept(noexcept(T{})) + : val{} + { + } + + template >> + constexpr + explicit + type( + std::initializer_list us + ) + noexcept(noexcept(T{us})) + : val{us} + { + } + template && (sizeof...(U) > 0)>> + constexpr + explicit + type( + U&& ... u) + noexcept(std::is_nothrow_constructible_v) + : val(std::forward(u)...) + {} + + friend constexpr void swap(type& a, type& b) noexcept( + std::is_nothrow_move_constructible_v && + std::is_nothrow_move_assignable_v + ) + { + using std::swap; + swap(a.val, b.val); + } + + [[nodiscard]] + constexpr T& value_of() & noexcept { return val;} + [[nodiscard]] + constexpr const T& value_of() const & noexcept { return val;} + [[nodiscard]] + constexpr T&& value_of() && noexcept { return std::move(val);} + + [[nodiscard]] + friend constexpr T& value_of(type& t) noexcept { return t.val;} + [[nodiscard]] + friend constexpr const T& value_of(const type& t) noexcept { return t.val;} + [[nodiscard]] + friend constexpr T&& value_of(type&& t) noexcept { return std::move(t).val;} +private: + T val; +}; + +namespace impl { + template + constexpr bool is_strong_type_func(const strong::type* /*unused*/) { return true;} + constexpr bool is_strong_type_func(...) { return false;} + template + constexpr T underlying_type(strong::type*); + +} + +template +struct is_strong_type : std::integral_constant(nullptr))> {}; + +namespace impl { + template + using WhenStrongType = std::enable_if_t>::value>; + template + using WhenNotStrongType = std::enable_if_t>::value>; +} + +template ::value> +struct underlying_type +{ + using type = decltype(impl::underlying_type(static_cast(nullptr))); +}; + +template +struct underlying_type +{ + using type = T; +}; + +template +using underlying_type_t = typename underlying_type::type; + + +namespace impl { + template< + typename T, + typename = impl::WhenNotStrongType> + constexpr + T && + access(T &&t) + noexcept { + return std::forward(t); + } + template < + typename T, + typename = impl::WhenStrongType> + [[nodiscard]] + constexpr + auto + access(T&& t) + noexcept + -> decltype(value_of(std::forward(t))) + { + return value_of(std::forward(t)); + } + +} +struct equality +{ + template + class modifier; +}; + + +template +class equality::modifier<::strong::type> +{ + using type = ::strong::type; +public: + [[nodiscard]] + friend + constexpr + auto + operator==( + const type& lh, + const type& rh) + noexcept(noexcept(std::declval() == std::declval())) + -> decltype(std::declval() == std::declval()) + { + return value_of(lh) == value_of(rh); + } + + [[nodiscard]] + friend + constexpr + auto + operator!=( + const type& lh, + const type& rh) + noexcept(noexcept(std::declval() != std::declval())) + -> decltype(std::declval() != std::declval()) + { + return value_of(lh) != value_of(rh); + } +}; + +namespace impl +{ + template + class typed_equality + { + private: + using TT = underlying_type_t; + using OT = underlying_type_t; + public: + [[nodiscard]] + friend + constexpr + auto operator==(const T& lh, const Other& rh) + noexcept(noexcept(std::declval() == std::declval())) + -> decltype(std::declval() == std::declval()) + { + return value_of(lh) == impl::access(rh); + } + [[nodiscard]] + friend + constexpr + auto operator==(const Other& lh, const T& rh) + noexcept(noexcept(std::declval() == std::declval())) + -> decltype(std::declval() == std::declval()) + { + return impl::access(lh) == value_of(rh) ; + } + [[nodiscard]] + friend + constexpr + auto operator!=(const T& lh, const Other rh) + noexcept(noexcept(std::declval() != std::declval())) + -> decltype(std::declval() != std::declval()) + { + return value_of(lh) != impl::access(rh); + } + [[nodiscard]] + friend + constexpr + auto operator!=(const Other& lh, const T& rh) + noexcept(noexcept(std::declval() != std::declval())) + -> decltype(std::declval() != std::declval()) + { + return impl::access(lh) != value_of(rh) ; + } + }; +} +template +struct equality_with +{ + template + class modifier : public impl::typed_equality... + { + }; +}; + +namespace impl +{ + template + class typed_ordering + { + private: + using TT = underlying_type_t; + using OT = underlying_type_t; + public: + [[nodiscard]] + friend + constexpr + auto operator<(const T& lh, const Other& rh) + noexcept(noexcept(std::declval() < std::declval())) + -> decltype(std::declval() < std::declval()) + { + return value_of(lh) < impl::access(rh); + } + [[nodiscard]] + friend + constexpr + auto operator<(const Other& lh, const T& rh) + noexcept(noexcept(std::declval() < std::declval())) + -> decltype(std::declval() < std::declval()) + { + return impl::access(lh) < value_of(rh) ; + } + + [[nodiscard]] + friend + constexpr + auto operator<=(const T& lh, const Other& rh) + noexcept(noexcept(std::declval() <= std::declval())) + -> decltype(std::declval() <= std::declval()) + { + return value_of(lh) <= impl::access(rh); + } + [[nodiscard]] + friend + constexpr + auto operator<=(const Other& lh, const T& rh) + noexcept(noexcept(std::declval() <= std::declval())) + -> decltype(std::declval() <= std::declval()) + { + return impl::access(lh) <= value_of(rh) ; + } + + [[nodiscard]] + friend + constexpr + auto operator>(const T& lh, const Other& rh) + noexcept(noexcept(std::declval() > std::declval())) + -> decltype(std::declval() > std::declval()) + { + return value_of(lh) > impl::access(rh); + } + [[nodiscard]] + friend + constexpr + auto operator>(const Other& lh, const T& rh) + noexcept(noexcept(std::declval() > std::declval())) + -> decltype(std::declval() > std::declval()) + { + return impl::access(lh) > value_of(rh) ; + } + + [[nodiscard]] + friend + constexpr + auto operator>=(const T& lh, const Other& rh) + noexcept(noexcept(std::declval() >= std::declval())) + -> decltype(std::declval() >= std::declval()) + { + return value_of(lh) >= impl::access(rh); + } + [[nodiscard]] + friend + constexpr + auto operator>=(const Other& lh, const T& rh) + noexcept(noexcept(std::declval() >= std::declval())) + -> decltype(std::declval() >= std::declval()) + { + return impl::access(lh) >= value_of(rh) ; + } + }; +} + +template +struct ordered_with +{ + template + class modifier : public impl::typed_ordering... + { + }; +}; + +namespace impl +{ + template + struct require_copy_constructible + { + static constexpr bool value = std::is_copy_constructible_v>; + static_assert(value, "underlying type must be copy constructible"); + }; + template + struct require_move_constructible + { + static constexpr bool value = std::is_move_constructible_v>; + static_assert(value, "underlying type must be move constructible"); + }; + template + struct require_copy_assignable + { + static constexpr bool value = std::is_copy_assignable_v>; + static_assert(value, "underlying type must be copy assignable"); + }; + template + struct require_move_assignable + { + static constexpr bool value = std::is_move_assignable_v>; + static_assert(value, "underlying type must be move assignable"); + }; + + template struct valid_type; + template <> + struct valid_type {}; + + template + struct require_semiregular + : valid_type::value && + require_move_constructible::value && + require_copy_assignable::value && + require_move_assignable::value> + { + }; + +} +struct semiregular +{ + template + class modifier; +}; + +template +class semiregular::modifier<::strong::type> + : public default_constructible::modifier + , private impl::require_semiregular +{ +}; + +struct regular +{ + template + class modifier + : public semiregular::modifier + , public equality::modifier + { + }; +}; + +struct unique +{ + template + class modifier + : private impl::valid_type< + impl::require_move_constructible::value && + impl::require_move_assignable::value + > + { + public: + constexpr modifier() = default; + modifier(const modifier&) = delete; + constexpr modifier(modifier&&) = default; + modifier& operator=(const modifier&) = delete; + constexpr modifier& operator=(modifier&&) = default; + }; +}; +struct ordered +{ + template + class modifier; +}; + + +template +class ordered::modifier<::strong::type> +{ + using type = ::strong::type; +public: + [[nodiscard]] + friend + constexpr + auto + operator<( + const type& lh, + const type& rh) + noexcept(noexcept(std::declval() < std::declval())) + -> decltype(std::declval() < std::declval()) + { + return value_of(lh) < value_of(rh); + } + + [[nodiscard]] + friend + constexpr + auto + operator<=( + const type& lh, + const type& rh) + noexcept(noexcept(std::declval() <= std::declval())) + -> decltype(std::declval() <= std::declval()) + { + return value_of(lh) <= value_of(rh); + } + + [[nodiscard]] + friend + constexpr + auto + operator>( + const type& lh, + const type& rh) + noexcept(noexcept(std::declval() > std::declval())) + -> decltype(std::declval() > std::declval()) + { + return value_of(lh) > value_of(rh); + } + + [[nodiscard]] + friend + constexpr + + auto + operator>=( + const type& lh, + const type& rh) + noexcept(noexcept(std::declval() >= std::declval())) + -> decltype(std::declval() >= std::declval()) + { + return value_of(lh) >= value_of(rh); + } +}; + +struct ostreamable +{ + template + class modifier + { + public: + friend + std::ostream& + operator<<( + std::ostream &os, + const T &t) + { + return os << value_of(t); + } + }; +}; + +struct istreamable +{ + template + class modifier + { + public: + friend + std::istream& + operator>>( + std::istream &is, + T &t) + { + return is >> value_of(t); + } + }; +}; + +struct iostreamable +{ + template + class modifier + : public ostreamable::modifier + , public istreamable::modifier + { + }; +}; + +struct incrementable +{ + template + class modifier + { + public: + friend + constexpr + T& + operator++(T& t) + noexcept(noexcept(++std::declval().value_of())) + { + ++value_of(t); + return t; + } + + friend + constexpr + T + operator++(T& t, int) + { + auto copy = t; + ++t; + return copy; + } + }; +}; + +struct decrementable +{ + template + class modifier + { + public: + friend + constexpr + T& + operator--(T& t) + noexcept(noexcept(--std::declval().value_of())) + { + --value_of(t); + return t; + } + + friend + constexpr + T + operator--(T& t, int) + { + auto copy = t; + --t; + return copy; + } + }; +}; + +struct bicrementable +{ + template + class modifier + : public incrementable::modifier + , public decrementable::modifier + { + }; +}; + +struct boolean +{ + template + class modifier + { + public: + explicit constexpr operator bool() const + noexcept(noexcept(static_cast(value_of(std::declval())))) + { + const auto& self = static_cast(*this); + return static_cast(value_of(self)); + } + }; +}; + +struct hashable +{ + template + class modifier{}; +}; + +struct difference +{ + template + class modifier; +}; + +template +class difference::modifier<::strong::type> +: public ordered::modifier<::strong::type> +, public equality::modifier<::strong::type> +{ + using type = ::strong::type; +public: + friend + constexpr + type& operator+=(type& lh, const type& rh) + noexcept(noexcept(value_of(lh) += value_of(rh))) + { + value_of(lh) += value_of(rh); + return lh; + } + + friend + constexpr + type& operator-=(type& lh, const type& rh) + noexcept(noexcept(value_of(lh) -= value_of(rh))) + { + value_of(lh) -= value_of(rh); + return lh; + } + + friend + constexpr + type& operator*=(type& lh, const T& rh) + noexcept(noexcept(value_of(lh) *= rh)) + { + value_of(lh) *= rh; + return lh; + } + + friend + constexpr + type& operator/=(type& lh, const T& rh) + noexcept(noexcept(value_of(lh) /= rh)) + { + value_of(lh) /= rh; + return lh; + } + + template ()%= std::declval())> + friend + constexpr + type& operator%=(type& lh, const T& rh) + noexcept(noexcept(value_of(lh) %= rh)) + { + value_of(lh)%= rh; + return lh; + } + + friend + constexpr + type operator+(type lh, const type& rh) + { + lh += rh; + return lh; + } + + friend + constexpr + type operator-(type lh, const type& rh) + { + lh -= rh; + return lh; + } + + friend + constexpr + type operator*(type lh, const T& rh) + { + lh *= rh; + return lh; + } + + friend + constexpr + type operator*(const T& lh, type rh) + { + rh *= lh; + return rh; + } + + friend + constexpr + type operator/(type lh, const T& rh) + { + lh /= rh; + return lh; + } + + friend + constexpr + T operator/(const type& lh, const type& rh) + { + return value_of(lh) / value_of(rh); + } + + template () %= std::declval())> + friend + constexpr + type operator%(type lh, const T& rh) + noexcept(noexcept(lh%= rh)) + { + lh %= rh; + return lh; + } + + template () % std::declval())> + friend + constexpr + T operator%(type lh, type rh) + noexcept(noexcept(value_of(lh) % value_of(rh))) + { + return value_of(lh) % value_of(rh); + } +}; + +template +struct affine_point +{ + template + class modifier; +}; + +namespace impl +{ + template + using void_t = void; + + template + struct subtractable : std::false_type {}; + + template + struct subtractable() - std::declval())>> + : std::true_type {}; +} + + +template +template +class affine_point::modifier<::strong::type> +{ + using type = ::strong::type; + static_assert(impl::subtractable::value, "it must be possible to subtract instances of your underlying type"); + using base_diff_type = decltype(std::declval() - std::declval()); +public: + using difference = std::conditional_t{}, strong::type, D>; + static_assert(std::is_constructible_v ); + [[nodiscard]] + friend + constexpr + difference + operator-( + const type& lh, + const type& rh) + { + return difference(value_of(lh) - value_of(rh)); + } + + friend + constexpr + type& + operator+=( + type& lh, + const difference& d) + noexcept(noexcept(value_of(lh) += impl::access(d))) + { + value_of(lh) += impl::access(d); + return lh; + } + + friend + constexpr + type& + operator-=( + type& lh, + const difference& d) + noexcept(noexcept(value_of(lh) -= impl::access(d))) + { + value_of(lh) -= impl::access(d); + return lh; + } + + [[nodiscard]] + friend + constexpr + type + operator+( + type lh, + const difference& d) + { + return lh += d; + } + + [[nodiscard]] + friend + constexpr + type + operator+( + const difference& d, + type rh) + { + return rh+= d; + } + + [[nodiscard]] + friend + constexpr + type + operator-( + type lh, + const difference& d) + { + return lh -= d; + } +}; + + +struct pointer +{ + template + class modifier; +}; + +template +class pointer::modifier<::strong::type> +{ + using type = strong::type; +public: + template + [[nodiscard]] + friend + constexpr + auto + operator==( + const type& t, + std::nullptr_t) + noexcept(noexcept(std::declval() == nullptr)) + -> decltype(std::declval() == nullptr) + { + return value_of(t) == nullptr; + } + + template + [[nodiscard]] + friend + constexpr + auto + operator==( + std::nullptr_t, + const type& t) + noexcept(noexcept(nullptr == std::declval())) + -> decltype(nullptr == std::declval()) + { + return value_of(t) == nullptr; + } + + template + [[nodiscard]] + friend + constexpr + auto + operator!=( + const type& t, + std::nullptr_t) + noexcept(noexcept(std::declval() != nullptr)) + -> decltype(std::declval() != nullptr) + { + return value_of(t) != nullptr; + } + + template + [[nodiscard]] + friend + constexpr + auto + operator!=( + std::nullptr_t, + const type& t) + noexcept(noexcept(nullptr != std::declval())) + -> decltype(nullptr != std::declval()) + { + return value_of(t) != nullptr; + } + + [[nodiscard]] + constexpr + decltype(*std::declval()) + operator*() + const + { + auto& self = static_cast(*this); + return *value_of(self); + } + + [[nodiscard]] + constexpr + decltype(&(*std::declval())) operator->() const { return &operator*();} +}; + +struct arithmetic +{ + template + class modifier + { + public: + [[nodiscard]] + friend + constexpr + T + operator-( + const T &lh) + { + return T{-value_of(lh)}; + } + + friend + constexpr + T& + operator+=( + T &lh, + const T &rh) + noexcept(noexcept(value_of(lh) += value_of(rh))) + { + value_of(lh) += value_of(rh); + return lh; + } + + friend + constexpr + T& + operator-=( + T &lh, + const T &rh) + noexcept(noexcept(value_of(lh) -= value_of(rh))) + { + value_of(lh) -= value_of(rh); + return lh; + } + + friend + constexpr + T& + operator*=( + T &lh, + const T &rh) + noexcept(noexcept(value_of(lh) *= value_of(rh))) + { + value_of(lh) *= value_of(rh); + return lh; + } + + friend + constexpr + T& + operator/=( + T &lh, + const T &rh) + noexcept(noexcept(value_of(lh) /= value_of(rh))) + { + value_of(lh) /= value_of(rh); + return lh; + } + + template ()) % value_of(std::declval()))> + friend + constexpr + T& + operator%=( + T &lh, + const T &rh) + noexcept(noexcept(value_of(lh) %= value_of(rh))) + { + value_of(lh) %= value_of(rh); + return lh; + } + + [[nodiscard]] + friend + constexpr + T + operator+( + T lh, + const T &rh) + { + lh += rh; + return lh; + } + + [[nodiscard]] + friend + constexpr + T + operator-( + T lh, + const T &rh) + { + lh -= rh; + return lh; + } + + [[nodiscard]] + friend + constexpr + T + operator*( + T lh, + const T &rh) + { + lh *= rh; + return lh; + } + + [[nodiscard]] + friend + constexpr + T + operator/( + T lh, + const T &rh) + { + lh /= rh; + return lh; + } + + template ()) % value_of(std::declval()))> + [[nodiscard]] + friend + constexpr + T + operator%( + T lh, + const T &rh) + { + lh %= rh; + return lh; + } + + }; +}; + + +struct bitarithmetic +{ + template + class modifier + { + public: + friend + constexpr + T& + operator&=( + T &lh, + const T &rh) + noexcept(noexcept(value_of(lh) &= value_of(rh))) + { + value_of(lh) &= value_of(rh); + return lh; + } + + friend + constexpr + T& + operator|=( + T &lh, + const T &rh) + noexcept(noexcept(value_of(lh) |= value_of(rh))) + { + value_of(lh) |= value_of(rh); + return lh; + } + + friend + constexpr + T& + operator^=( + T &lh, + const T &rh) + noexcept(noexcept(value_of(lh) ^= value_of(rh))) + { + value_of(lh) ^= value_of(rh); + return lh; + } + + template + friend + constexpr + T& + operator<<=( + T &lh, + C c) + noexcept(noexcept(value_of(lh) <<= c)) + { + value_of(lh) <<= c; + return lh; + } + + template + friend + constexpr + T& + operator>>=( + T &lh, + C c) + noexcept(noexcept(value_of(lh) >>= c)) + { + value_of(lh) >>= c; + return lh; + } + + [[nodiscard]] + friend + constexpr + T + operator~( + const T &lh) + { + auto v = value_of(lh); + v = ~v; + return T(v); + } + + [[nodiscard]] + friend + constexpr + T + operator&( + T lh, + const T &rh) + { + lh &= rh; + return lh; + } + + [[nodiscard]] + friend + constexpr + T + operator|( + T lh, + const T &rh) + { + lh |= rh; + return lh; + } + + [[nodiscard]] + friend + constexpr + T + operator^( + T lh, + const T &rh) + { + lh ^= rh; + return lh; + } + + template + [[nodiscard]] + friend + constexpr + T + operator<<( + T lh, + C c) + { + lh <<= c; + return lh; + } + + template + [[nodiscard]] + friend + constexpr + T + operator>>( + T lh, + C c) + { + lh >>= c; + return lh; + } + }; +}; +template +struct indexed +{ + template + class modifier; +}; + +template <> +struct indexed { + template + class modifier; + + template + class modifier> { + using ref = T&; + using cref = const T&; + using rref = T&&; + using type = strong::type; + public: + template + [[nodiscard]] + auto + operator[]( + const I &i) + const & + noexcept(noexcept(std::declval()[impl::access(i)])) + -> decltype(std::declval()[impl::access(i)]) { + auto& self = static_cast(*this); + return value_of(self)[impl::access(i)]; + } + + template + [[nodiscard]] + auto + operator[]( + const I &i) + & + noexcept(noexcept(std::declval()[impl::access(i)])) + -> decltype(std::declval()[impl::access(i)]) { + auto& self = static_cast(*this); + return value_of(self)[impl::access(i)]; + } + + template + [[nodiscard]] + auto + operator[]( + const I &i) + && + noexcept(noexcept(std::declval()[impl::access(i)])) + -> decltype(std::declval()[impl::access(i)]) { + auto& self = static_cast(*this); + return value_of(std::move(self))[impl::access(i)]; + } + + template + [[nodiscard]] + auto + at( + const I &i) + const & + -> decltype(std::declval().at(impl::access(i))) { + auto& self = static_cast(*this); + return value_of(self).at(impl::access(i)); + } + + template + [[nodiscard]] + auto + at( + const I &i) + & + -> decltype(std::declval().at(impl::access(i))) { + auto& self = static_cast(*this); + return value_of(self).at(impl::access(i)); + } + + template + [[nodiscard]] + auto + at( + const I &i) + && + -> decltype(std::declval().at(impl::access(i))) { + auto& self = static_cast(*this); + return value_of(std::move(self)).at(impl::access(i)); + } + }; +}; + +template +template +class indexed::modifier> +{ + using type = ::strong::type; +public: + [[nodiscard]] + auto + operator[]( + const I& i) + const & + noexcept(noexcept(std::declval()[impl::access(i)])) + -> decltype(std::declval()[impl::access(i)]) + { + auto& self = static_cast(*this); + return value_of(self)[impl::access(i)]; + } + + [[nodiscard]] + auto + operator[]( + const I& i) + & + noexcept(noexcept(std::declval()[impl::access(i)])) + -> decltype(std::declval()[impl::access(i)]) + { + auto& self = static_cast(*this); + return value_of(self)[impl::access(i)]; + } + + [[nodiscard]] + auto + operator[]( + const I& i) + && + noexcept(noexcept(std::declval()[impl::access(i)])) + -> decltype(std::declval()[impl::access(i)]) + { + auto& self = static_cast(*this); + return value_of(std::move(self))[impl::access(i)]; + } + + template + [[nodiscard]] + auto + at( + const I& i) + const & + -> decltype(std::declval().at(impl::access(i))) + { + auto& self = static_cast(*this); + return value_of(self).at(impl::access(i)); + } + + template + [[nodiscard]] + auto + at( + const I& i) + & + -> decltype(std::declval().at(impl::access(i))) + { + auto& self = static_cast(*this); + return value_of(self).at(impl::access(i)); + } + + template + [[nodiscard]] + auto + at( + const I& i) + && + -> decltype(std::declval().at(impl::access(i))) + { + auto& self = static_cast(*this); + return value_of(std::move(self)).at(impl::access(i)); + } +}; + +class iterator +{ +public: + template >::iterator_category> + class modifier + : public pointer::modifier + , public equality::modifier + , public incrementable::modifier + { + public: + using difference_type = typename std::iterator_traits>::difference_type; + using value_type = typename std::iterator_traits>::value_type; + using pointer = typename std::iterator_traits>::value_type; + using reference = typename std::iterator_traits>::reference; + using iterator_category = typename std::iterator_traits>::iterator_category; + }; + + template + class modifier + : public modifier + , public decrementable::modifier + { + }; + template + class modifier + : public modifier + , public affine_point>::difference_type>::template modifier + , public indexed<>::modifier + , public ordered::modifier + { + }; +}; + +class range +{ +public: + template + class modifier; +}; + +template +class range::modifier> +{ + using type = ::strong::type; + using r_iterator = decltype(std::declval().begin()); + using r_const_iterator = decltype(std::declval().begin()); +public: + using iterator = ::strong::type; + using const_iterator = ::strong::type; + + iterator + begin() + noexcept(noexcept(std::declval().begin())) + { + auto& self = static_cast(*this); + return iterator{value_of(self).begin()}; + } + + iterator + end() + noexcept(noexcept(std::declval().end())) + { + auto& self = static_cast(*this); + return iterator{value_of(self).end()}; + } + + const_iterator + cbegin() + const + noexcept(noexcept(std::declval().begin())) + { + auto& self = static_cast(*this); + return const_iterator{value_of(self).begin()}; + } + + const_iterator + cend() + const + noexcept(noexcept(std::declval().end())) + { + auto& self = static_cast(*this); + return const_iterator{value_of(self).end()}; + } + + const_iterator + begin() + const + noexcept(noexcept(std::declval().begin())) + { + auto& self = static_cast(*this); + return const_iterator{value_of(self).begin()}; + } + + const_iterator + end() + const + noexcept(noexcept(std::declval().end())) + { + auto& self = static_cast(*this); + return const_iterator{value_of(self).end()}; + } +}; + +namespace impl { + + template + struct converter + { + constexpr explicit operator D() const + noexcept(noexcept(static_cast(std::declval&>()))) + { + auto& self = static_cast(*this); + return static_cast(value_of(self)); + } + }; + template + struct implicit_converter + { + constexpr operator D() const + noexcept(noexcept(static_cast(std::declval&>()))) + { + auto& self = static_cast(*this); + return static_cast(value_of(self)); + } + }; +} +template +struct convertible_to +{ + template + struct modifier : impl::converter... + { + }; +}; + +template +struct implicitly_convertible_to +{ + template + struct modifier : impl::implicit_converter... + { + }; + +}; + +struct formattable +{ + template + class modifier{}; +}; + +} + +namespace std { +template +struct hash<::strong::type> + : std::conditional_t< + std::is_base_of_v< + ::strong::hashable::modifier< + ::strong::type + >, + ::strong::type + >, + hash, + std::false_type> +{ + using type = ::strong::type; + decltype(auto) + operator()( + const ::strong::hashable::modifier& t) + const + noexcept(noexcept(std::declval>()(value_of(std::declval())))) + { + auto& tt = static_cast(t); + return hash::operator()(value_of(tt)); + } +}; + +#if STRONG_HAS_STD_FORMAT +template +struct formatter<::strong::type, Char, + std::enable_if_t< + std::is_base_of< + ::strong::formattable::modifier< + ::strong::type + >, + ::strong::type + >::value + >> + : formatter +{ + using type = ::strong::type; + template + constexpr + decltype(auto) + format(const ::strong::formattable::modifier& t, FormatContext& fc) + noexcept(noexcept(std::declval>().format(value_of(std::declval()), fc))) + { + const auto& tt = static_cast(t); + return formatter::format(value_of(tt), fc); + } +}; +#endif + +} + +#if STRONG_HAS_FMT_FORMAT +namespace fmt +{ +template +struct formatter<::strong::type, Char, + std::enable_if_t< + std::is_base_of< + ::strong::formattable::modifier< + ::strong::type + >, + ::strong::type + >::value + >> + : formatter +{ + using type = ::strong::type; + template + constexpr + decltype(auto) + format(const ::strong::formattable::modifier& t, FormatContext& fc) + noexcept(noexcept(std::declval>().format(value_of(std::declval()), fc))) + { + const auto& tt = static_cast(t); + return formatter::format(value_of(tt), fc); + } +}; +} +#endif +#endif //ROLLBEAR_STRONG_TYPE_HPP_INCLUDED + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/tempfile.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/tempfile.h new file mode 100644 index 0000000000000000000000000000000000000000..afcf4504c87a49112a6f4f21c6fe08f153c49a2a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/tempfile.h @@ -0,0 +1,94 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include + +namespace c10 { +struct C10_API TempFile { + TempFile(std::string_view name, int fd = -1) noexcept : fd(fd), name(name) {} + TempFile(const TempFile&) = delete; + TempFile(TempFile&& other) noexcept + : fd(other.fd), name(std::move(other.name)) { + other.fd = -1; + } + + TempFile& operator=(const TempFile&) = delete; + TempFile& operator=(TempFile&& other) noexcept { + fd = other.fd; + name = std::move(other.name); + other.fd = -1; + return *this; + } +#if defined(_WIN32) + bool open(); +#endif + + ~TempFile(); + + int fd; + + std::string name; +}; + +struct C10_API TempDir { + TempDir() = delete; + explicit TempDir(std::string_view name) noexcept : name(name) {} + TempDir(const TempDir&) = delete; + TempDir(TempDir&& other) noexcept : name(std::move(other.name)) { + other.name.clear(); + } + + TempDir& operator=(const TempDir&) = delete; + TempDir& operator=(TempDir&& other) noexcept { + name = std::move(other.name); + return *this; + } + + ~TempDir(); + + std::string name; +}; + +/// Attempts to return a temporary file or returns `nullopt` if an error +/// occurred. +/// +/// The file returned follows the pattern +/// `/`, where `` is the value of +/// the `"TMPDIR"`, `"TMP"`, `"TEMP"` or +/// `"TEMPDIR"` environment variable if any is set, or otherwise `/tmp`; +/// `` is the value supplied to this function, and +/// `` is a random sequence of numbers. +/// On Windows, `name_prefix` is ignored and `tmpnam_s` is used, +/// and no temporary file is opened. +C10_API std::optional try_make_tempfile( + std::string_view name_prefix = "torch-file-"); + +/// Like `try_make_tempfile`, but throws an exception if a temporary file could +/// not be returned. +C10_API TempFile make_tempfile(std::string_view name_prefix = "torch-file-"); + +/// Attempts to return a temporary directory or returns `nullopt` if an error +/// occurred. +/// +/// The directory returned follows the pattern +/// `//`, where `` is the value +/// of the `"TMPDIR"`, `"TMP"`, `"TEMP"` or +/// `"TEMPDIR"` environment variable if any is set, or otherwise `/tmp`; +/// `` is the value supplied to this function, and +/// `` is a random sequence of numbers. +/// On Windows, `name_prefix` is ignored. +C10_API std::optional try_make_tempdir( + std::string_view name_prefix = "torch-dir-"); + +/// Like `try_make_tempdir`, but throws an exception if a temporary directory +/// could not be returned. +C10_API TempDir make_tempdir(std::string_view name_prefix = "torch-dir-"); +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/thread_name.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/thread_name.h new file mode 100644 index 0000000000000000000000000000000000000000..5cda361bc8f17f673fb6735b76261b82d821f26d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/thread_name.h @@ -0,0 +1,18 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include + +namespace c10 { + +C10_API void setThreadName(std::string name); + +C10_API std::string getThreadName(); + +} // namespace c10 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/typeid.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/typeid.h new file mode 100644 index 0000000000000000000000000000000000000000..3f7da4264ad5339af2535aeb10863ef07c75515a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/typeid.h @@ -0,0 +1,720 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * TypeIdentifier is a small type containing an id. + * Types must be registered using CAFFE_DECLARE_KNOWN_TYPE() (in their header) + * and CAFFE_DEFINE_KNOWN_TYPE() (in their .cpp file) for them to have a type + * id. If a type is registered, you can also create an object containing meta + * data like constructor, destructor, stringified name, ... about the type by + * calling TypeMeta::Make. This returns a TypeMeta() object, which is + * basically just a pointer to the type information, so it's cheap to pass + * around. + */ + +// TODO: This file is still in the caffe2 namespace, despite living +// in the ATen directory. This is because the macro +// CAFFE_KNOWN_TYPE (and CAFFE_DECLARE_KNOWN_TYPE) defines a template +// specialization, which relies +// on the namespace of TypeMeta matching the namespace where the macro is +// called. This requires us to fix all of the call-sites, which I want to do +// later. So the namespace is not fixed at the moment. + +// Make at::Half a fundamental type. + +namespace c10::guts { +template <> +struct is_fundamental : std::true_type {}; +} // namespace c10::guts + +namespace caffe2 { + +/** + * A type id is a unique id for a given C++ type. + * You need to register your types using CAFFE_KNOWN_TYPE(MyType) to be able to + * use TypeIdentifier with custom types. This is for example used to store the + * dtype of tensors. + */ +class C10_API TypeIdentifier final + : public at::IdWrapper { + public: + friend std::ostream& operator<<(std::ostream& stream, TypeIdentifier typeId); + friend constexpr bool operator<(TypeIdentifier lhs, TypeIdentifier rhs); + + /** + * Returns the unique id for the given type T. The id is unique for the type T + * in the sense that for any two different types, their ids are different; for + * the same type T, the id remains the same over different calls of the + * function. However, this is not guaranteed over different runs, as the id + * is generated during run-time. Do NOT serialize the id for storage. + */ + template + static constexpr TypeIdentifier Get() noexcept { + return TypeIdentifier(c10::util::get_type_index()); + } + + static constexpr TypeIdentifier uninitialized() { + return TypeIdentifier(c10::util::type_index{0}); + } + + private: + constexpr explicit TypeIdentifier(c10::util::type_index id) : IdWrapper(id) {} +}; + +// Allow usage in std::map / std::set +// TODO Disallow this and rather use std::unordered_map/set everywhere +inline constexpr bool operator<(TypeIdentifier lhs, TypeIdentifier rhs) { + return lhs.underlyingId() < rhs.underlyingId(); +} + +inline std::ostream& operator<<( + std::ostream& stream, + caffe2::TypeIdentifier typeId) { + return stream << typeId.underlyingId(); +} + +} // namespace caffe2 + +namespace at { +using DataType = caffe2::TypeIdentifier; +} + +C10_DEFINE_HASH_FOR_IDWRAPPER(caffe2::TypeIdentifier) + +namespace caffe2 { + +namespace detail { + +// This struct holds the actual type information. There will be +// one allocated per type. TypeMeta objects will then point to the struct +// instance for the type they're configured for. +struct TypeMetaData final { + using New = void*(); + using PlacementNew = void(void*, size_t); + using Copy = void(const void*, void*, size_t); + using PlacementDelete = void(void*, size_t); + using Delete = void(void*); + + constexpr TypeMetaData() noexcept + : itemsize_(0), + new_(nullptr), + placementNew_(nullptr), + copy_(nullptr), + placementDelete_(nullptr), + delete_(nullptr), + id_(TypeIdentifier::uninitialized()), + name_("nullptr (uninitialized)") {} + + constexpr TypeMetaData( + size_t itemsize, + New* newFn, + PlacementNew* placementNew, + Copy* copy, + PlacementDelete* placementDelete, + Delete* deleteFn, + TypeIdentifier id, + std::string_view name) noexcept + : itemsize_(itemsize), + new_(newFn), + placementNew_(placementNew), + copy_(copy), + placementDelete_(placementDelete), + delete_(deleteFn), + id_(id), + name_(name) {} + + size_t itemsize_; + New* new_; + PlacementNew* placementNew_; + Copy* copy_; + PlacementDelete* placementDelete_; + Delete* delete_; + TypeIdentifier id_; + std::string_view name_; +}; + +// Mechanism for throwing errors which can't be prevented at compile time +// due to type erasure. E.g. somebody calling TypeMeta::copy() for +// non-copyable type. Right now just throws exception but is implemented +// in .cpp to manage dependencies +[[noreturn]] C10_API void _ThrowRuntimeTypeLogicError(const std::string& msg); + +/** + * Placement new function for the type. + */ +template +inline void _PlacementNew(void* ptr, size_t n) { + T* typed_ptr = static_cast(ptr); + for (const auto i : c10::irange(n)) { + new (typed_ptr + i) T; + } +} + +template +inline void _PlacementNewNotDefault(void* /*ptr*/, size_t /*n*/) { + _ThrowRuntimeTypeLogicError( + "Type " + std::string(c10::util::get_fully_qualified_type_name()) + + " is not default-constructible."); +} + +template < + typename T, + std::enable_if_t>* = nullptr> +inline constexpr TypeMetaData::PlacementNew* _PickPlacementNew() { + return (c10::guts::is_fundamental::value || std::is_pointer_v) + ? nullptr + : &_PlacementNew; +} + +template < + typename T, + std::enable_if_t>* = nullptr> +inline constexpr TypeMetaData::PlacementNew* _PickPlacementNew() { + static_assert( + !c10::guts::is_fundamental::value && !std::is_pointer_v, + "this should have picked the other SFINAE case"); + return &_PlacementNewNotDefault; +} + +template +inline void* _New() { + return new T; +} + +template +inline void* _NewNotDefault() { + _ThrowRuntimeTypeLogicError( + "Type " + std::string(c10::util::get_fully_qualified_type_name()) + + " is not default-constructible."); +} + +template < + typename T, + std::enable_if_t>* = nullptr> +inline constexpr TypeMetaData::New* _PickNew() { + return &_New; +} + +template < + typename T, + std::enable_if_t>* = nullptr> +inline constexpr TypeMetaData::New* _PickNew() { + return &_NewNotDefault; +} + +/** + * Typed copy function for classes. + */ +template +inline void _Copy(const void* src, void* dst, size_t n) { + const T* typed_src = static_cast(src); + T* typed_dst = static_cast(dst); + for (const auto i : c10::irange(n)) { + typed_dst[i] = typed_src[i]; + } +} + +/** + * A placeholder function for types that do not allow assignment. + */ +template +inline void _CopyNotAllowed(const void* /*src*/, void* /*dst*/, size_t /*n*/) { + _ThrowRuntimeTypeLogicError( + "Type " + std::string(c10::util::get_fully_qualified_type_name()) + + " does not allow assignment."); +} + +template >* = nullptr> +inline constexpr TypeMetaData::Copy* _PickCopy() { + return (c10::guts::is_fundamental::value || std::is_pointer_v) + ? nullptr + : &_Copy; +} + +template < + typename T, + std::enable_if_t>* = nullptr> +inline constexpr TypeMetaData::Copy* _PickCopy() { + static_assert( + !c10::guts::is_fundamental::value && !std::is_pointer_v, + "this should have picked the other SFINAE case"); + return &_CopyNotAllowed; +} + +/** + * Destructor for non-fundamental types. + */ +template +inline void _PlacementDelete(void* ptr, size_t n) { + T* typed_ptr = static_cast(ptr); + for (const auto i : c10::irange(n)) { + typed_ptr[i].~T(); + } +} + +template +inline constexpr TypeMetaData::PlacementDelete* _PickPlacementDelete() { + return (c10::guts::is_fundamental::value || std::is_pointer_v) + ? nullptr + : &_PlacementDelete; +} + +template +inline void _Delete(void* ptr) { + T* typed_ptr = static_cast(ptr); + delete typed_ptr; +} + +template +inline constexpr TypeMetaData::Delete* _PickDelete() noexcept { + return &_Delete; +} + +class _Uninitialized final {}; + +} // namespace detail + +// +// note: this is outside TypeMeta bc gcc seems to have trouble +// with scalarTypeItemSizes as a constexpr static member used by +// a public inline instance method +// + +// item sizes for TypeMeta::itemsize() fast path +static constexpr std::array scalarTypeItemSizes = { +#define SCALAR_TYPE_SIZE(T, name) sizeof(T), + AT_FORALL_SCALAR_TYPES_WITH_COMPLEX_AND_QINTS(SCALAR_TYPE_SIZE) +#undef SCALAR_TYPE_SIZE + 0, // Undefined +}; + +/** + * TypeMeta is a thin class that allows us to store the type of a container such + * as a blob, or the data type of a tensor, with a unique run-time id. It also + * stores some additional data such as the item size and the name of the type + * for run-time inspection. + */ +class C10_API TypeMeta final { + public: + using New = detail::TypeMetaData::New; + using PlacementNew = detail::TypeMetaData::PlacementNew; + using Copy = detail::TypeMetaData::Copy; + using PlacementDelete = detail::TypeMetaData::PlacementDelete; + using Delete = detail::TypeMetaData::Delete; + + /** Create a dummy TypeMeta object. To create a TypeMeta object for a specific + * type, use TypeMeta::Make(). + */ + TypeMeta() noexcept; + ~TypeMeta() = default; + + /** + * Copy constructor. + */ + TypeMeta(const TypeMeta& src) noexcept = default; + + /** + * Assignment operators. + */ + TypeMeta& operator=(const TypeMeta& src) noexcept = default; + + TypeMeta& operator=(TypeMeta&& src) noexcept = default; + TypeMeta(TypeMeta&& rhs) noexcept = default; + + inline TypeMeta& operator=(ScalarType scalar_type) noexcept { + index_ = static_cast(scalar_type); + return *this; + } + + private: + // TypeMeta can only be created by Make, making sure that we do not + // create incorrectly mixed up TypeMeta objects. + explicit TypeMeta(const uint16_t index) noexcept : index_(index) {} + + public: + /** + * Returns the type id. + */ + TypeIdentifier id() const noexcept { + return data().id_; + } + /** + * true if we represent some ScalarType type + */ + inline bool isScalarType() const noexcept { + return index_ < NumScalarTypes; + } + /** + * true if we represent ScalarType scalar_type + */ + inline bool isScalarType(ScalarType scalar_type) const noexcept { + return index_ == static_cast(scalar_type); + } + /** + * Returns the size of the item. + */ + inline size_t itemsize() const noexcept { + if (C10_LIKELY(isScalarType())) { + return scalarTypeItemSizes[index_]; + } + return data().itemsize_; + } + /** + * Returns the new function pointer for individual items. + */ + New* newFn() const noexcept { + return data().new_; + } + /** + * Returns the placement new function pointer for individual items. + */ + PlacementNew* placementNew() const noexcept { + return data().placementNew_; + } + /** + * Returns the typed copy function pointer for individual items. + */ + Copy* copy() const noexcept { + return data().copy_; + } + /** + * Returns the destructor function pointer for individual items. + */ + PlacementDelete* placementDelete() const noexcept { + return data().placementDelete_; + } + Delete* deleteFn() const noexcept { + return data().delete_; + } + /** + * Returns a printable name for the type. + */ + std::string_view name() const noexcept { + return data().name_; + } + + friend bool operator==(const TypeMeta& lhs, const TypeMeta& rhs) noexcept; + + template + bool Match() const noexcept { + return (*this == Make()); + } + + // Below are static functions that can be called by passing a specific type. + + template + static constexpr TypeIdentifier Id() noexcept { + return TypeIdentifier::Get(); + } + + template + static std::string_view TypeName() noexcept { + return c10::util::get_fully_qualified_type_name(); + } + + template + static constexpr size_t ItemSize() noexcept { + return sizeof(T); + } + + /** + * Returns a TypeMeta object that corresponds to the typename T. + */ + template + static TypeMeta Make() { + // The instance pointed to is declared here, but defined in a .cpp file. + // We need to silence the compiler warning about using an undefined + // variable template. '-Wpragmas' and '-Wunknown-warning-option' has to be + // disabled for compilers that don't know '-Wundefined-var-template' and + // would error at our attempt to disable it. +#ifndef _MSC_VER +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wunknown-warning-option" +#pragma GCC diagnostic ignored "-Wundefined-var-template" +#endif + return TypeMeta(_typeMetaData()); +#ifndef _MSC_VER +#pragma GCC diagnostic pop +#endif + } + + /** + * convert ScalarType enum values to TypeMeta handles + */ + static inline caffe2::TypeMeta fromScalarType(ScalarType scalar_type) { + const auto index = static_cast(scalar_type); + TORCH_INTERNAL_ASSERT_DEBUG_ONLY( + index < NumScalarTypes, + "Unrecognized Scalartype ", + scalar_type, + " (please report this error)"); + return TypeMeta(index); + } + + /** + * convert TypeMeta handles to ScalarType enum values + */ + inline ScalarType toScalarType() const { + if (C10_LIKELY(isScalarType())) { + return static_cast(index_); + } + error_unsupported_typemeta(*this); + } + + private: + [[noreturn]] static void error_unsupported_typemeta(caffe2::TypeMeta dtype); + + // hard limit number of registered types + // note: constexpr provokes Windows compilation error "member may not be + // initialized" static constexpr size_t MaxTypeIndex = 32; + // +#if defined C10_MOBILE +// The reason for this not to be UINT8_MAX is that the array +// initialization takes space which is proportional to the size of the array. +// The compiler seems to add code (or data padding) to initialize the array with +// empty elements. Please see +// https://github.com/pytorch/pytorch/pull/51881 for details. +// +#define MaxTypeIndex \ + (NumScalarTypes + 15 /* number of CAFFE_DEFINE_KNOWN_TYPE in typeid.cpp */ + \ + 1 /* 1 more for caffe2 tensor */) +#else +#define MaxTypeIndex UINT8_MAX +#endif + + // Protects type metadata allocation. + // NOLINTNEXTLINE(facebook-hte-NonPodStaticDeclaration) + static std::mutex& getTypeMetaDatasLock(); + static uint16_t nextTypeIndex; + + static detail::TypeMetaData* typeMetaDatas(); + + static uint16_t existingMetaDataIndexForType(TypeIdentifier identifier); + + public: +#ifdef __CUDACC__ + // NOTE [ TypeIdentifier::Get nvcc/clang discrepancy] + // nvcc and clang do not produce identical results for + // TypeIdentifier::Get, because TypeIdentifier::Get relies on + // __PRETTY_FUNCTION__ and they don't agree on the canonical names + // of types (e.g., nvcc normalizes to `short unsigned int`, but clang + // calls it `unsigned short`). Hide the implementation of this function + // from nvcc so that we always use clang (or whatever host C++ compiler) + // for TypeIdentifier::Get. + template + C10_EXPORT static uint16_t addTypeMetaData(); +#else + template + C10_EXPORT static uint16_t addTypeMetaData() { + const auto identifier = TypeIdentifier::Get(); + // Need to hold this for the rest of the function, protecting: + // 1) existingMetaDataIndexForType() + // 2) nextTypeIndex++ + // 3) the write into typeMetaDatas() + std::lock_guard lock(getTypeMetaDatasLock()); + // It may exist already if added in a different dynamic shared library. + const uint16_t existing_index = existingMetaDataIndexForType(identifier); + if (existing_index != MaxTypeIndex) { + return existing_index; + } + const uint16_t index = nextTypeIndex++; + TORCH_CHECK( + index <= MaxTypeIndex, + "Maximum number of CAFFE_KNOWN_TYPE declarations has been exceeded. ", + "Please report this issue."); + typeMetaDatas()[index] = detail::TypeMetaData{ + sizeof(T), + detail::_PickNew(), + detail::_PickPlacementNew(), + detail::_PickCopy(), + detail::_PickPlacementDelete(), + detail::_PickDelete(), + identifier, + c10::util::get_fully_qualified_type_name()}; + return index; + } +#endif + + private: + // specializations return indexes into typeMetaDataInstances() + template + C10_API static uint16_t _typeMetaData() noexcept; + + // + // TypeMeta just wraps this index + // + + uint16_t index_; + + inline const detail::TypeMetaData& data() const { + return typeMetaDatas()[index_]; + } +}; + +// specializations of TypeMeta::_typeMetaData for ScalarType types + +#define DEFINE_SCALAR_METADATA_INSTANCE(T, name) \ + template <> \ + constexpr uint16_t TypeMeta::_typeMetaData() noexcept { \ + return static_cast(ScalarType::name); \ + } +AT_FORALL_SCALAR_TYPES_WITH_COMPLEX_AND_QINTS(DEFINE_SCALAR_METADATA_INSTANCE) +#undef DEFINE_SCALAR_METADATA_INSTANCE + +template <> +C10_EXPORT constexpr uint16_t TypeMeta::_typeMetaData< + detail::_Uninitialized>() noexcept { + return static_cast(ScalarType::Undefined); +} + +inline TypeMeta::TypeMeta() noexcept + : index_(_typeMetaData()) {} + +inline bool operator==(const TypeMeta& lhs, const TypeMeta& rhs) noexcept { + return (lhs.index_ == rhs.index_); +} +inline bool operator!=(const TypeMeta& lhs, const TypeMeta& rhs) noexcept { + return !operator==(lhs, rhs); +} + +inline std::ostream& operator<<( + std::ostream& stream, + caffe2::TypeMeta typeMeta) { + return stream << typeMeta.name(); +} + +/** + * Register unique id for a type so it can be used in TypeMeta context, e.g. be + * used as a type for Blob or for Tensor elements. + * + * CAFFE_KNOWN_TYPE is deprecated; prefer CAFFE_DECLARE_KNOWN_TYPE and + * CAFFE_DEFINE_KNOWN_TYPE. + * + * CAFFE_KNOWN_TYPE does explicit instantiation of TypeIdentifier::Get + * template function and thus needs to be put in a single translation unit (.cpp + * file) for a given type T. Other translation units that use type T as a type + * of the caffe2::Blob or element type of caffe2::Tensor need to depend on the + * translation unit that contains CAFFE_KNOWN_TYPE declaration via regular + * linkage dependencies. + * + * NOTE: the macro needs to be invoked in ::caffe2 namespace + */ +// Implementation note: in MSVC, we will need to prepend the C10_API +// keyword in order to get things compiled properly. in Linux, gcc seems to +// create attribute ignored error for explicit template instantiations, see +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0537r0.html +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51930 +// and as a result, we define these two macros slightly differently. +#if defined(_MSC_VER) || defined(__clang__) +#define EXPORT_IF_NOT_GCC C10_EXPORT +#else +#define EXPORT_IF_NOT_GCC +#endif + +// CAFFE_KNOWN_TYPE is deprecated! Use CAFFE_DECLARE_KNOWN_TYPE and +// CAFFE_DEFINE_KNOWN_TYPE instead. +#define CAFFE_KNOWN_TYPE(T) \ + template uint16_t TypeMeta::addTypeMetaData(); \ + template <> \ + EXPORT_IF_NOT_GCC uint16_t TypeMeta::_typeMetaData() noexcept { \ + static const uint16_t index = addTypeMetaData(); \ + return index; \ + } + +#define CAFFE_DEFINE_KNOWN_TYPE(T, ident) \ + template uint16_t TypeMeta::addTypeMetaData(); \ + namespace detail { \ + EXPORT_IF_NOT_GCC const uint16_t ident##_metadata_index = \ + TypeMeta::addTypeMetaData(); \ + } // namespace detail + +// Unlike CAFFE_KNOWN_TYPE, CAFFE_DECLARE_KNOWN_TYPE avoids a function +// call to access _typeMetaData in the common case. +#define CAFFE_DECLARE_KNOWN_TYPE(T, ident) \ + extern template uint16_t TypeMeta::addTypeMetaData(); \ + namespace detail { \ + extern C10_API const uint16_t ident##_metadata_index; \ + } /* namespace detail */ \ + template <> \ + EXPORT_IF_NOT_GCC C10_ALWAYS_INLINE uint16_t \ + TypeMeta::_typeMetaData() noexcept { \ + return detail::ident##_metadata_index; \ + } + +#define CAFFE_KNOWN_TYPE_NOEXPORT(T) \ + template <> \ + uint16_t TypeMeta::_typeMetaData() noexcept { \ + static const uint16_t index = addTypeMetaData(); \ + return index; \ + } + +CAFFE_DECLARE_KNOWN_TYPE(std::string, std_string) +CAFFE_DECLARE_KNOWN_TYPE(char, char) +CAFFE_DECLARE_KNOWN_TYPE(std::unique_ptr, std_unique_ptr_std_mutex) +CAFFE_DECLARE_KNOWN_TYPE( + std::unique_ptr>, + std_unique_ptr_std_atomic_bool) +CAFFE_DECLARE_KNOWN_TYPE(std::vector, std_vector_int32_t) +CAFFE_DECLARE_KNOWN_TYPE(std::vector, std_vector_int64_t) +CAFFE_DECLARE_KNOWN_TYPE(std::vector, std_vector_unsigned_long) +CAFFE_DECLARE_KNOWN_TYPE(bool*, bool_ptr) +CAFFE_DECLARE_KNOWN_TYPE(char*, char_ptr) +CAFFE_DECLARE_KNOWN_TYPE(int*, int_ptr) + +// For some of the compilers, long is defined separately from int32_t and +// int64_t. As a result we will need to actually define them separately. +// It is recommended that one does NOT use long - use int32_t and int64_t +// explicitly. Explicit long type annotation may go away in the future. +// details: This hack works by defining a _guard_long_unique type, which is +// long iff the compiler has a separate long type and is a dummy type otherwise. +// we then allocate a type id to that _guard_long_unique. If the compiler has a +// separate long type, this allocates a type id for long. Otherwise, it +// allocates a type id for the dummy type, which doesn't matter. +namespace detail { +template +class _guard_long_unique_dummy final {}; +template +using _guard_long_unique = std::conditional_t< + std::is_same_v || std::is_same_v, + _guard_long_unique_dummy, + T>; +} // namespace detail + +CAFFE_DECLARE_KNOWN_TYPE( + detail::_guard_long_unique, + detail_guard_long_unique_long) +CAFFE_DECLARE_KNOWN_TYPE( + detail::_guard_long_unique>, + detail_guard_long_unique_std_vector_long) + +CAFFE_DECLARE_KNOWN_TYPE(float*, float_ptr) +CAFFE_DECLARE_KNOWN_TYPE(at::Half*, at_Half) + +} // namespace caffe2 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/win32-headers.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/win32-headers.h new file mode 100644 index 0000000000000000000000000000000000000000..f9eb55948a858c8551a52c81ece8eab8c862c324 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/win32-headers.h @@ -0,0 +1,65 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#ifndef NOKERNEL +#define NOKERNEL +#endif +#ifndef NOUSER +#define NOUSER +#endif +#ifndef NOSERVICE +#define NOSERVICE +#endif +#ifndef NOSOUND +#define NOSOUND +#endif +#ifndef NOMCX +#define NOMCX +#endif +#ifndef NOGDI +#define NOGDI +#endif +#ifndef NOMSG +#define NOMSG +#endif +#ifndef NOMB +#define NOMB +#endif +#ifndef NOCLIPBOARD +#define NOCLIPBOARD +#endif + +// dbghelp seems to require windows.h. +// clang-format off +#include +#include +// clang-format on + +#undef VOID +#undef DELETE +#undef IN +#undef THIS +#undef CONST +#undef NAN +#undef UNKNOWN +#undef NONE +#undef ANY +#undef IGNORE +#undef STRICT +#undef GetObject +#undef CreateSemaphore +#undef Yield +#undef RotateRight32 +#undef RotateLeft32 +#undef RotateRight64 +#undef RotateLeft64 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/PeerToPeerAccess.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/PeerToPeerAccess.h new file mode 100644 index 0000000000000000000000000000000000000000..9f227662a446845b4c1aa3e00bb299b494566e5c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/PeerToPeerAccess.h @@ -0,0 +1,23 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10::xpu { +namespace detail { +// Initialize the peer-to-peer access cache for XPU devices. +C10_XPU_API void init_p2p_access_cache(c10::DeviceIndex num_devices); +} // namespace detail + +// Query if peer-to-peer access is available between two devices. +C10_XPU_API bool get_p2p_access( + c10::DeviceIndex dev, + c10::DeviceIndex dev_to_access); + +} // namespace c10::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUCachingAllocator.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUCachingAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..2ae0904928db7f8721b679035eb69f66db731d85 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUCachingAllocator.h @@ -0,0 +1,142 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10::xpu::XPUCachingAllocator { + +class XPUAllocator : public DeviceAllocator { + public: + virtual void init(c10::DeviceIndex device_count) = 0; + virtual void* raw_alloc(size_t size) = 0; + virtual void raw_delete(void* ptr) = 0; +}; + +C10_XPU_API extern std::atomic allocator; + +struct AllocatorConfigInfo { + bool expandable_segments; + std::string last_allocator_settings; +}; + +struct SnapshotInfo { + std::vector segments; + std::vector> device_traces; + AllocatorConfigInfo config_metadata; +}; + +inline XPUAllocator* get() { + return allocator.load(); +} + +inline void init(c10::DeviceIndex device_count) { + get()->init(device_count); +} + +inline void emptyCache(MempoolId_t mempool_id = {0, 0}) { + get()->emptyCache(mempool_id); +} + +inline void resetPeakStats(DeviceIndex device) { + get()->resetPeakStats(device); +} + +inline void resetAccumulatedStats(DeviceIndex device) { + get()->resetAccumulatedStats(device); +} + +inline c10::CachingDeviceAllocator::DeviceStats getDeviceStats( + DeviceIndex device) { + return get()->getDeviceStats(device); +} + +inline void* raw_alloc(size_t size) { + return get()->raw_alloc(size); +} + +inline void raw_delete(void* ptr) { + get()->raw_delete(ptr); +} + +inline void recordStream(const DataPtr& dataPtr, XPUStream stream) { + get()->recordStream(dataPtr, stream); +} + +C10_XPU_API void enablePeerAccess( + c10::DeviceIndex dev, + c10::DeviceIndex dev_to_access); + +C10_XPU_API double getMemoryFraction(DeviceIndex device); + +C10_XPU_API void setMemoryFraction(double fraction, DeviceIndex device); + +C10_XPU_API void recordHistory( + bool enabled, + CachingDeviceAllocator::CreateContextFn context_recorder, + size_t alloc_trace_max_entries, + CachingDeviceAllocator::RecordContext when, + bool clearHistory, + const std::vector& skip_actions); + +C10_XPU_API SnapshotInfo snapshot(MempoolId_t mempool_id = {0, 0}); + +C10_XPU_API void createOrIncrefPool( + c10::DeviceIndex device, + c10::MempoolId_t mempool_id, + XPUAllocator* allocator = nullptr); + +C10_XPU_API void beginAllocateToPool( + c10::DeviceIndex device, + c10::MempoolId_t mempool_id, + std::function filter); + +C10_XPU_API void endAllocateToPool( + c10::DeviceIndex device, + c10::MempoolId_t mempool_id); + +C10_XPU_API void releasePool( + c10::DeviceIndex device, + c10::MempoolId_t mempool_id); + +C10_XPU_API int getPoolUseCount( + c10::DeviceIndex device, + c10::MempoolId_t mempool_id); + +} // namespace c10::xpu::XPUCachingAllocator + +namespace c10::xpu { + +using c10::CaptureId_t; +using c10::MempoolId_t; +struct C10_XPU_API MemPool { + MemPool( + XPUCachingAllocator::XPUAllocator* allocator = nullptr, + bool is_user_created = true, + bool use_on_oom = false); + MemPool(const MemPool&) = delete; + MemPool(MemPool&&) = default; + MemPool& operator=(const MemPool&) = delete; + MemPool& operator=(MemPool&&) = default; + ~MemPool(); + + MempoolId_t id(); + XPUCachingAllocator::XPUAllocator* allocator(); + int use_count(); + c10::DeviceIndex device(); + static MempoolId_t graph_pool_handle(bool is_user_created = true); + + private: + static std::atomic uid_; + static std::atomic uuid_; + XPUCachingAllocator::XPUAllocator* allocator_; + bool is_user_created_; + MempoolId_t id_; + c10::DeviceIndex device_; +}; +} // namespace c10::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUDeviceProp.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUDeviceProp.h new file mode 100644 index 0000000000000000000000000000000000000000..dcaed872ab21df9c5fe0e24e73439e50d94b3507 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUDeviceProp.h @@ -0,0 +1,222 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10::xpu { + +#define AT_FORALL_XPU_DEVICE_PROPERTIES(_) \ + /* the device name of this SYCL device. */ \ + _(name) \ + \ + /* the device type associated with the device. */ \ + _(device_type) \ + \ + /* the vendor of this SYCL device. */ \ + _(vendor) \ + \ + /* a backend-defined driver version as a std::string. */ \ + _(driver_version) \ + \ + /* the SYCL version as a std::string in the form . */ \ + _(version) \ + \ + /* true if the SYCL device is available. Otherwise, return false. */ \ + _(is_available) \ + \ + /* the maximum size in bytes of the arguments that can be passed to a \ + * kernel. */ \ + _(max_parameter_size) \ + \ + /* the number of parallel compute units available to the device. */ \ + _(max_compute_units) \ + \ + /* the maximum dimensions that specify the global and local work-item IDs \ + * used by the data parallel execution model. */ \ + _(max_work_item_dimensions) \ + \ + /* the maximum number of workitems that are permitted in a work-group \ + * executing a kernel on a single compute unit. */ \ + _(max_work_group_size) \ + \ + /* the maximum number of subgroups in a work-group for any kernel executed \ + * on the device. */ \ + _(max_num_sub_groups) \ + \ + /* a std::vector of size_t containing the set of sub-group sizes supported \ + * by the device. */ \ + _(sub_group_sizes) \ + \ + /* the maximum configured clock frequency of this SYCL device in MHz. */ \ + _(max_clock_frequency) \ + \ + /* the default compute device address space size specified as an unsigned \ + * integer value in bits. Must return either 32 or 64. */ \ + _(address_bits) \ + \ + /* the maximum size of memory object allocation in bytes. */ \ + _(max_mem_alloc_size) \ + \ + /* the minimum value in bits of the largest supported SYCL built-in data \ + * type if this SYCL device is not of device type \ + * sycl::info::device_type::custom. */ \ + _(mem_base_addr_align) \ + \ + /* a std::vector of info::fp_config describing the half/single/double \ + * precision floating-point capability of this SYCL device. */ \ + _(half_fp_config) \ + _(single_fp_config) \ + _(double_fp_config) \ + \ + /* the size of global device memory in bytes. */ \ + _(global_mem_size) \ + \ + /* the type of global memory cache supported. */ \ + _(global_mem_cache_type) \ + \ + /* the size of global memory cache in bytes. */ \ + _(global_mem_cache_size) \ + \ + /* the size of global memory cache line in bytes. */ \ + _(global_mem_cache_line_size) \ + \ + /* the type of local memory supported. */ \ + _(local_mem_type) \ + \ + /* the size of local memory arena in bytes. */ \ + _(local_mem_size) \ + \ + /* the maximum number of sub-devices that can be created when this device is \ + * partitioned. */ \ + _(partition_max_sub_devices) \ + \ + /* the resolution of device timer in nanoseconds. */ \ + _(profiling_timer_resolution) \ + \ + /* the preferred native vector width size for built-in scalar types that can \ + * be put into vectors. */ \ + _(preferred_vector_width_char) \ + _(preferred_vector_width_short) \ + _(preferred_vector_width_int) \ + _(preferred_vector_width_long) \ + _(preferred_vector_width_float) \ + _(preferred_vector_width_double) \ + _(preferred_vector_width_half) \ + \ + /* the native ISA vector width. The vector width is defined as the number of \ + * scalar elements that can be stored in the vector. */ \ + _(native_vector_width_char) \ + _(native_vector_width_short) \ + _(native_vector_width_int) \ + _(native_vector_width_long) \ + _(native_vector_width_float) \ + _(native_vector_width_double) \ + _(native_vector_width_half) + +#define AT_FORALL_XPU_EXT_DEVICE_PROPERTIES(_) \ + /* the number of EUs associated with the Intel GPU. */ \ + _(gpu_eu_count, gpu_eu_count, 512) \ + \ + /* the number of EUs in a subslice. */ \ + _(gpu_eu_count_per_subslice, gpu_eu_count_per_subslice, 8) \ + \ + /* the simd width of EU of GPU. */ \ + _(gpu_eu_simd_width, gpu_eu_simd_width, 8) \ + \ + /* the number of hardware threads per EU of GPU. */ \ + _(gpu_hw_threads_per_eu, gpu_hw_threads_per_eu, 8) \ + \ + /* the device identifier of the Intel GPU, also known as the product ID. */ \ + _(device_id, device_id, 0) \ + \ + /* the device descriptor for device Universal Unique ID, 16 bytes. */ \ + _(uuid, device_info_uuid, (std::array{})) \ + \ + /* the maximum clock rate of device's global memory in MHz. */ \ + _(memory_clock_rate, memory_clock_rate, 0) \ + \ + /* the maximum bus width between device and memory in bits. */ \ + _(memory_bus_width, memory_bus_width, 0) + +#define AT_FORALL_XPU_DEVICE_ASPECT(_) \ + /* sycl::half is supported on device. */ \ + _(fp16) \ + \ + /* double is supported on device. */ \ + _(fp64) \ + \ + /* 64-bit atomic operation is supported on device. */ \ + _(atomic64) + +#define AT_FORALL_XPU_EXP_CL_ASPECT(_) \ + /* conversion between single-precision 32-bit floating-point values and \ + * 16-bit bfloat16 values is supported on device. */ \ + _(bfloat16_conversions) \ + \ + /* specialized hardware to compute MMA is supported on device. */ \ + _(subgroup_matrix_multiply_accumulate) \ + \ + /* specialized hardware to compute MMA for 32-bit floating-point is \ + * supported on device. */ \ + _(subgroup_matrix_multiply_accumulate_tensor_float32) \ + \ + /* block read operations for efficient matrix multiplication is supported on \ + * device. */ \ + _(subgroup_2d_block_io) + +#define AT_FORALL_XPU_EXP_DEVICE_PROPERTIES(_) \ + /* the device architecture of this SYCL device. */ \ + _(architecture) + +#define _DEFINE_SYCL_PROP(ns, property, member) \ + ns::property::return_type member; + +#define DEFINE_DEVICE_PROP(property) \ + _DEFINE_SYCL_PROP(sycl::info::device, property, property) + +#define DEFINE_PLATFORM_PROP(property, member) \ + _DEFINE_SYCL_PROP(sycl::info::platform, property, member) + +#define DEFINE_EXT_DEVICE_PROP(property, ...) \ + _DEFINE_SYCL_PROP(sycl::ext::intel::info::device, property, property) + +#define DEFINE_DEVICE_ASPECT(member) bool has_##member; + +#define DEFINE_EXP_DEVICE_PROP(property) \ + _DEFINE_SYCL_PROP( \ + sycl::ext::oneapi::experimental::info::device, property, property) + +struct C10_XPU_API DeviceProp{ + AT_FORALL_XPU_DEVICE_PROPERTIES(DEFINE_DEVICE_PROP) + + // the platform name. + DEFINE_PLATFORM_PROP(name, platform_name) + + // ext properties. + AT_FORALL_XPU_EXT_DEVICE_PROPERTIES(DEFINE_EXT_DEVICE_PROP) + + // device aspects. + AT_FORALL_XPU_DEVICE_ASPECT(DEFINE_DEVICE_ASPECT) + + // experimental device aspects. + AT_FORALL_XPU_EXP_CL_ASPECT(DEFINE_DEVICE_ASPECT) + +#if SYCL_COMPILER_VERSION >= 20250000 + // experimental device properties. + AT_FORALL_XPU_EXP_DEVICE_PROPERTIES(DEFINE_EXP_DEVICE_PROP) +#endif +}; + +#undef _DEFINE_SYCL_PROP +#undef DEFINE_DEVICE_PROP +#undef DEFINE_PLATFORM_PROP +#undef DEFINE_EXT_DEVICE_PROP +#undef DEFINE_DEVICE_ASPECT +#undef DEFINE_EXP_DEVICE_PROP + +} // namespace c10::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUEvent.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..596fdfcc0ff06ccdb4395c3989e987836804eddc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUEvent.h @@ -0,0 +1,183 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include + +namespace c10::xpu { + +/* + * XPUEvent are movable not copyable wrappers around SYCL event. XPUEvent are + * constructed lazily when first recorded. It has a device, and this device is + * acquired from the first recording stream. Later streams that record the event + * must match the same device. + * + * Currently, XPUEvent does NOT support to export an inter-process event from + * another process via inter-process communication(IPC). So it means that + * inter-process communication for event handles between different processes is + * not available. This could impact some applications that rely on cross-process + * synchronization and communication. + */ +struct XPUEvent { + // Constructors + XPUEvent(bool enable_timing = false) noexcept + : enable_timing_{enable_timing} {} + + ~XPUEvent() { + if (isCreated()) { + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_deletion( + c10::kXPU, reinterpret_cast(event_.get())); + } + } + } + + C10_DISABLE_COPY_AND_ASSIGN(XPUEvent); + + XPUEvent(XPUEvent&& other) = default; + XPUEvent& operator=(XPUEvent&& other) = default; + + operator sycl::event&() const { + return event(); + } + + std::optional device() const { + if (isCreated()) { + return c10::Device(c10::kXPU, device_index_); + } else { + return std::nullopt; + } + } + + inline bool isCreated() const { + return (event_.get() != nullptr); + } + + DeviceIndex device_index() const { + return device_index_; + } + + sycl::event& event() const { + return *event_; + } + + bool query() const { + using namespace sycl::info; + if (!isCreated()) { + return true; + } + + return event().get_info() == + event_command_status::complete; + } + + void record() { + record(getCurrentXPUStream()); + } + + void recordOnce(const XPUStream& stream) { + if (!isCreated()) { + record(stream); + } + } + + void record(const XPUStream& stream) { + if (!isCreated()) { + device_index_ = stream.device_index(); + assignEvent(stream.queue()); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_creation( + c10::kXPU, reinterpret_cast(event_.get())); + } + } else { + TORCH_CHECK( + device_index_ == stream.device_index(), + "Event device ", + device_index_, + " does not match recording stream's device ", + stream.device_index(), + "."); + reassignEvent(stream.queue()); + } + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_record( + c10::kXPU, + reinterpret_cast(event_.get()), + reinterpret_cast(&stream.queue())); + } + } + + void block(const XPUStream& stream) { + if (isCreated()) { + std::vector event_list{event()}; + // Make this stream wait until event_ is completed. + stream.queue().ext_oneapi_submit_barrier(event_list); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_wait( + c10::kXPU, + reinterpret_cast(event_.get()), + reinterpret_cast(&stream.queue())); + } + } + } + + double elapsed_time(const XPUEvent& other) const { + TORCH_CHECK( + isCreated() && other.isCreated(), + "Both events must be recorded before calculating elapsed time."); + TORCH_CHECK( + query() && other.query(), + "Both events must be completed before calculating elapsed time."); + TORCH_CHECK( + enable_timing_ && other.enable_timing_, + "Both events must be created with argument 'enable_timing=True'."); + + using namespace sycl::info::event_profiling; + // Block until both of the recorded events are completed. + uint64_t end_time_ns = other.event().get_profiling_info(); + uint64_t start_time_ns = event().get_profiling_info(); + // Return the eplased time in milliseconds. + return 1e-6 * + (static_cast(end_time_ns) - static_cast(start_time_ns)); + } + + void synchronize() const { + if (isCreated()) { + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_synchronization( + c10::kXPU, reinterpret_cast(event_.get())); + } + event().wait_and_throw(); + } + } + + private: + void assignEvent(sycl::queue& queue) { + if (enable_timing_) { + event_ = std::make_unique( + sycl::ext::oneapi::experimental::submit_profiling_tag(queue)); + } else { + event_ = std::make_unique(queue.ext_oneapi_submit_barrier()); + } + } + + void reassignEvent(sycl::queue& queue) { + event_.reset(); + assignEvent(queue); + } + + bool enable_timing_ = false; + c10::DeviceIndex device_index_ = -1; + // Only need to track the last event, as events in an in-order queue are + // executed sequentially. + std::unique_ptr event_; +}; + +} // namespace c10::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUException.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUException.h new file mode 100644 index 0000000000000000000000000000000000000000..514299d6bb1eaa56874908ec5ac44badd30cac03 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUException.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +namespace c10::xpu { + +static inline sycl::async_handler asyncHandler = + [](const sycl::exception_list& el) { + if (el.size() == 0) { + return; + } + for (const auto& e : el) { + try { + std::rethrow_exception(e); + } catch (sycl::exception& e) { + TORCH_WARN("SYCL Exception: ", e.what()); + } + } + throw; + }; + +} // namespace c10::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUFunctions.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUFunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..e5017a054d32448a372290fcab2adfdea3e7fb36 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUFunctions.h @@ -0,0 +1,50 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +// The naming convention used here matches the naming convention of torch.xpu + +namespace c10::xpu { + +// Log a warning only once if no devices are detected. +C10_XPU_API DeviceIndex device_count(); + +// Throws an error if no devices are detected. +C10_XPU_API DeviceIndex device_count_ensure_non_zero(); + +C10_XPU_API DeviceIndex current_device(); + +C10_XPU_API void set_device(DeviceIndex device); + +C10_XPU_API DeviceIndex exchange_device(DeviceIndex device); + +C10_XPU_API DeviceIndex maybe_exchange_device(DeviceIndex to_device); + +C10_XPU_API sycl::device& get_raw_device(DeviceIndex device); + +C10_XPU_API sycl::context& get_device_context(); + +C10_XPU_API void get_device_properties( + DeviceProp* device_prop, + DeviceIndex device); + +C10_XPU_API DeviceIndex get_device_idx_from_pointer(void* ptr); + +static inline void check_device_index(DeviceIndex device_index) { + TORCH_CHECK( + device_index >= 0 && device_index < c10::xpu::device_count(), + "The device index is out of range. It must be in [0, ", + static_cast(c10::xpu::device_count()), + "), but got ", + static_cast(device_index), + "."); +} + +} // namespace c10::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUGraphsC10Utils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUGraphsC10Utils.h new file mode 100644 index 0000000000000000000000000000000000000000..437dda44bfc4826d05389b530a7cd54083ec8f08 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUGraphsC10Utils.h @@ -0,0 +1,47 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +// XPU Graphs utils used by c10 and aten. +using namespace sycl::ext::oneapi::experimental; +namespace c10::xpu { + +static_assert( + int8_t(queue_state::executing) == 0, + "unexpected int(queue_state::executing) value"); +static_assert( + int8_t(queue_state::recording) == 1, + "unexpected int(queue_state::recording) value"); + +enum class CaptureStatus : int8_t { + Executing = int8_t(queue_state::executing), + Recording = int8_t(queue_state::recording) +}; + +inline std::ostream& operator<<(std::ostream& os, CaptureStatus status) { + switch (status) { + case CaptureStatus::Executing: + os << "Executing"; + break; + case CaptureStatus::Recording: + os << "Recording"; + break; + default: + TORCH_INTERNAL_ASSERT( + false, "Unknown XPU graph CaptureStatus", int(status)); + } + return os; +} + +inline CaptureStatus currentStreamCaptureStatusMayInitCtx() { + auto state = c10::xpu::getCurrentXPUStream().queue().ext_oneapi_get_state(); + return CaptureStatus(state); +} + +} // namespace c10::xpu + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUMacros.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUMacros.h new file mode 100644 index 0000000000000000000000000000000000000000..43a42c2a6f8a47a2276268e58edc176ec5f6a781 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUMacros.h @@ -0,0 +1,38 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#ifndef C10_USING_CUSTOM_GENERATED_MACROS +#include +#endif + +// See c10/macros/Export.h for a detailed explanation of what the function +// of these macros are. We need one set of macros for every separate library +// we build. + +#ifdef _WIN32 +#if defined(C10_XPU_BUILD_SHARED_LIBS) +#define C10_XPU_EXPORT __declspec(dllexport) +#define C10_XPU_IMPORT __declspec(dllimport) +#else +#define C10_XPU_EXPORT +#define C10_XPU_IMPORT +#endif +#else // _WIN32 +#if defined(__GNUC__) +#define C10_XPU_EXPORT __attribute__((__visibility__("default"))) +#else // defined(__GNUC__) +#define C10_XPU_EXPORT +#endif // defined(__GNUC__) +#define C10_XPU_IMPORT C10_XPU_EXPORT +#endif // _WIN32 + +// This one is being used by libc10_xpu.so +#ifdef C10_XPU_BUILD_MAIN_LIB +#define C10_XPU_API C10_XPU_EXPORT +#else +#define C10_XPU_API C10_XPU_IMPORT +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUStream.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUStream.h new file mode 100644 index 0000000000000000000000000000000000000000..8715c12f024332c73bf0d8c30faf8c276cebaab9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUStream.h @@ -0,0 +1,222 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +namespace c10::xpu { + +/* + * Note [Stream Management] + * + * An XPUStream is an abstraction of an actual SYCL queue in which SYCL kernel + * can execute. Currently, there are several pools per device to manage SYCL + * queue, and a device's pool is lazily created. + * + * There are two pools per device. The first pool contains "normal priority" + * queues. The second pool is the "high priority" queues. There are 32 queues in + * per pool per device, and when a queue is requested one of these queues is + * returned round-robin. That is, the first queue requested is at index 0, the + * second at index 1... to index 31, then index 0 again. + * + * This means that if 33 queues are requested, the first and last queues + * requested are actually the same queue (under the covers) and kernels enqueued + * on them cannot run concurrently. + * + * It is safe to enqueue a kernel on the same queue from two different + * threads as the SYCL specification described. + */ + +static constexpr int max_compile_time_stream_priorities = 3; + +/* + * This serves as a wrapper around c10::Stream and acts as a representation for + * a SYCL queue, which allows asynchronous execution of XPU tasks. + */ +class C10_XPU_API XPUStream { + public: + enum Unchecked { UNCHECKED }; + + /// Construct a XPUStream from a Stream. This construction is checked, and + /// will raise an error if the Stream is not, in fact, a XPU stream. + explicit XPUStream(Stream stream) : stream_(stream) { + TORCH_CHECK(stream_.device_type() == DeviceType::XPU); + } + + /// Construct a XPUStream from a Stream with no error checking. + explicit XPUStream(Unchecked /*unused*/, Stream stream) : stream_(stream) {} + + bool operator==(const XPUStream& other) const noexcept { + return unwrap() == other.unwrap(); + } + + bool operator!=(const XPUStream& other) const noexcept { + return unwrap() != other.unwrap(); + } + + /// Implicit conversion to sycl::queue&. + operator sycl::queue&() const { + return queue(); + } + + /// Implicit conversion to sycl::queue*. + operator sycl::queue*() const { + return &queue(); + } + + /// Implicit conversion to Stream (a.k.a., forget that the stream is a + /// XPU stream). + operator Stream() const { + return unwrap(); + } + + /// Get the XPU device type that this stream is associated with. + DeviceType device_type() const { + return DeviceType::XPU; + } + + /// Get the XPU device index that this stream is associated with. + DeviceIndex device_index() const { + return stream_.device_index(); + } + + /// Get the full Device that this stream is associated with. The Device is + /// guaranteed to be a XPU device. + Device device() const { + return Device(DeviceType::XPU, device_index()); + } + + /// Return the stream ID corresponding to this particular stream. StreamId is + /// a int64_t representation generated by its type and index. + StreamId id() const { + return stream_.id(); + } + + /// Return true if all enqueued tasks in this stream have been completed, + /// otherwise return false. + bool query() const { + return queue().ext_oneapi_empty(); + } + + /// Performs a blocking wait for the completion of all enqueued tasks in this + /// stream. + void synchronize() const { + queue().wait_and_throw(); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_stream_synchronization( + c10::kXPU, reinterpret_cast(&queue())); + } + } + + bool is_capturing() const { + return queue().ext_oneapi_get_state() == + sycl::ext::oneapi::experimental::queue_state::recording; + } + + /// Return the priority that this stream is associated with. Lower numbers + /// represent higher priority. + int priority() const; + + /// Explicit conversion to sycl::queue&. + sycl::queue& queue() const; + + /// Explicit conversion to Stream. + Stream unwrap() const { + return stream_; + } + + /// Reversibly pack a XPUStream into a struct representation. The XPUStream + /// can be unpacked using unpack3(). + struct c10::StreamData3 pack3() const { + return stream_.pack3(); + } + + /// Unpack a XPUStream from the 3 fields generated by pack3(). + static XPUStream unpack3( + StreamId stream_id, + DeviceIndex device_index, + DeviceType device_type) { + return XPUStream(Stream::unpack3(stream_id, device_index, device_type)); + } + + /// Return the range of priority **supported by PyTorch**. + static std::tuple priority_range() { + // See Note [XPU Stream priorities] + return std::make_tuple(1, -max_compile_time_stream_priorities + 2); + } + + private: + Stream stream_; +}; + +/** + * Get a stream from the pool in a round-robin fashion. + * + * You can request a stream from the highest priority pool by setting + * isHighPriority to true for a specific device. + */ +C10_XPU_API XPUStream +getStreamFromPool(const bool isHighPriority = false, DeviceIndex device = -1); + +/** + * Get a stream from the pool in a round-robin fashion. + * + * You can request a stream by setting a priority value for a specific device. + * The priority number lower, the priority higher. + */ +C10_XPU_API XPUStream +getStreamFromPool(const int priority, DeviceIndex device = -1); + +/** + * Get an XPUStream from an external SYCL queue. + * + * This function allows interoperability with other libraries by enabling + * the use of an external SYCL queue that was not created by PyTorch. This + * can be useful for data exchange or other operations where integration + * with non-PyTorch queues is required. + * + * NOTE: It is the user's responsibility to ensure that the referenced SYCL + * queue remains alive while the corresponding XPUStream, or any c10::Stream + * derived from it, is in use. The different SYCL queue pointers will result in + * distinct XPUStream instances, even if the SYCL queues they dereference are + * equivalent. + */ +C10_XPU_API XPUStream +getStreamFromExternal(sycl::queue* ext_queue, DeviceIndex device_index); + +/** + * Get the current XPU stream, for the passed XPU device, or for the current + * device if no device index is passed. + */ +C10_XPU_API XPUStream getCurrentXPUStream(DeviceIndex device = -1); + +/** + * Set the current stream on the device of the passed in stream to be the passed + * in stream. + */ +C10_XPU_API void setCurrentXPUStream(XPUStream stream); + +C10_XPU_API std::ostream& operator<<(std::ostream& stream, const XPUStream& s); + +/** + * Block all reserved SYCL queues in the stream pools on the device, and wait + * for their synchronizations. + */ +C10_XPU_API void syncStreamsOnDevice(DeviceIndex device = -1); + +} // namespace c10::xpu + +namespace std { +template <> +struct hash { + size_t operator()(c10::xpu::XPUStream s) const noexcept { + return std::hash{}(s.unwrap()); + } +}; +} // namespace std + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/impl/XPUGuardImpl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/impl/XPUGuardImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..aac16f9d950f4d45770db793859fb6e0dd206b51 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/impl/XPUGuardImpl.h @@ -0,0 +1,258 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace c10::xpu::impl { + +struct XPUGuardImpl final : public c10::impl::DeviceGuardImplInterface { + static constexpr DeviceType static_type = kXPU; + + XPUGuardImpl() = default; + + explicit XPUGuardImpl(DeviceType t) { + TORCH_CHECK( + t == kXPU, "XPUGuardImpl initialized with non-XPU DeviceType: ", t); + } + + DeviceType type() const override { + return kXPU; + } + + Device exchangeDevice(Device d) const override { + TORCH_CHECK(d.is_xpu(), "Expected a XPU device, but got ", d); + const auto old_device_index = c10::xpu::exchange_device(d.index()); + return Device(kXPU, old_device_index); + } + + Device getDevice() const override { + const auto device = c10::xpu::current_device(); + return Device(kXPU, device); + } + + void setDevice(Device d) const override { + TORCH_CHECK(d.is_xpu(), "Expected a XPU device, but got ", d); + c10::xpu::set_device(d.index()); + } + + void uncheckedSetDevice(Device d) const noexcept override { + c10::xpu::set_device(d.index()); + } + + DeviceCapability getDeviceCapability(Device d) const override { + DeviceCapability cap; + cap.capability_data.capability_bits = (1ULL << kIndex_Byte) | + (1ULL << kIndex_Char) | (1ULL << kIndex_Short) | (1ULL << kIndex_Int) | + (1ULL << kIndex_Long) | (1ULL << kIndex_Float) | + (1ULL << kIndex_ComplexFloat) | (1ULL << kIndex_Bool) | + (1ULL << kIndex_Float8_e5m2) | (1ULL << kIndex_Float8_e4m3fn) | + (1ULL << kIndex_Float8_e5m2fnuz) | (1ULL << kIndex_Float8_e4m3fnuz) | + (1ULL << kIndex_Float8_e8m0fnu) | (1ULL << kIndex_UInt16) | + (1ULL << kIndex_UInt32) | (1ULL << kIndex_UInt64); + // BFloat16 may be emulated. We always assume BFloat16 is available; + // users can call is_bf16_supported() to check for native hardware support. + cap.capability_data.capability_bits |= (1ULL << kIndex_BFloat16); + auto& device = c10::xpu::get_raw_device(d.index()); + if (device.has(sycl::aspect::fp16)) { + cap.capability_data.capability_bits |= (1ULL << kIndex_Half); + cap.capability_data.capability_bits |= (1ULL << kIndex_ComplexHalf); + } + if (device.has(sycl::aspect::fp64)) { + cap.capability_data.capability_bits |= (1ULL << kIndex_Double); + cap.capability_data.capability_bits |= (1ULL << kIndex_ComplexDouble); + } + return cap; + } + + Stream getStream(Device d) const override { + return getCurrentXPUStream(d.index()).unwrap(); + } + + Stream getNewStream(Device d, int priority = 0) const override { + return getStreamFromPool(priority, d.index()); + } + + Stream getStreamFromGlobalPool(Device d, bool isHighPriority = false) + const override { + return getStreamFromPool(isHighPriority, d.index()); + } + + // NB: These do NOT set the current device + Stream exchangeStream(Stream s) const override { + const XPUStream stream(s); + const auto old_stream = getCurrentXPUStream(s.device().index()); + setCurrentXPUStream(stream); + return old_stream.unwrap(); + } + + void* getStreamNativeHandle(const Stream s) const override { + const XPUStream stream{s}; + return reinterpret_cast(&(stream.queue())); + } + + DeviceIndex deviceCount() const noexcept override { + return c10::xpu::device_count(); + } + + // Event-related functions + void destroyEvent(void* event, const DeviceIndex device_index) + const noexcept override { + if (!event) + return; + + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_deletion( + c10::kXPU, reinterpret_cast(event)); + } + + delete reinterpret_cast(event); + } + + void record( + void** event, + const Stream& stream, + const DeviceIndex device_index, + const EventFlag flag) const override { + TORCH_CHECK( + device_index == -1 || device_index == stream.device_index(), + "Event device index ", + device_index, + " does not match recording stream's device index ", + stream.device_index(), + "."); + + auto* xpu_event = reinterpret_cast(*event); + const XPUStream xpu_stream{stream}; + + // Delete the event previously recorded. + if (xpu_event) + delete xpu_event; +#if SYCL_COMPILER_VERSION >= 20250000 + if (flag == EventFlag::BACKEND_DEFAULT) { + // Use the profiling tag to record the event to enable timing feature. + xpu_event = + new sycl::event(sycl::ext::oneapi::experimental::submit_profiling_tag( + xpu_stream.queue())); + } else { + xpu_event = + new sycl::event(xpu_stream.queue().ext_oneapi_submit_barrier()); + } +#else + xpu_event = new sycl::event(xpu_stream.queue().ext_oneapi_submit_barrier()); +#endif + *event = reinterpret_cast(xpu_event); + + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_record( + c10::kXPU, + reinterpret_cast(xpu_event), + reinterpret_cast(&xpu_stream.queue())); + } + } + + void block(void* event, const Stream& stream) const override { + if (!event) + return; + auto* xpu_event = reinterpret_cast(event); + std::vector event_list{*xpu_event}; + const XPUStream xpu_stream(stream); + xpu_stream.queue().ext_oneapi_submit_barrier(event_list); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_wait( + c10::kXPU, + reinterpret_cast(xpu_event), + reinterpret_cast(&xpu_stream.queue())); + } + } + + bool queryEvent(void* event) const override { + using namespace sycl::info; + if (!event) + return true; + auto* xpu_event = reinterpret_cast(event); + return xpu_event->get_info() == + event_command_status::complete; + } + + double elapsedTime( + void* start_event, + void* end_event, + const DeviceIndex device_index) const override { +#if SYCL_COMPILER_VERSION < 20250000 + TORCH_CHECK_NOT_IMPLEMENTED( + false, + "elapsedTime requires PyTorch to be built with SYCL compiler version 2025.0.0 or newer."); +#endif + TORCH_CHECK( + start_event && end_event, + "Both events must be recorded before calculating elapsed time."); + auto* xpu_start_event = reinterpret_cast(start_event); + auto* xpu_end_event = reinterpret_cast(end_event); + + using namespace sycl::info::event_profiling; + // Block until both of the recorded events are completed. + uint64_t end_time_ns = xpu_end_event->get_profiling_info(); + uint64_t start_time_ns = xpu_start_event->get_profiling_info(); + // Return the eplased time in milliseconds. + return 1e-6 * + (static_cast(end_time_ns) - static_cast(start_time_ns)); + } + + // Stream-related functions + bool queryStream(const Stream& stream) const override { + const XPUStream xpu_stream{stream}; + return xpu_stream.query(); + } + + void synchronizeStream(const Stream& stream) const override { + const XPUStream xpu_stream{stream}; + xpu_stream.synchronize(); + } + + bool isStreamCapturing(const Stream& stream) const override { + const XPUStream xpu_stream{stream}; + return xpu_stream.is_capturing(); + } + + void synchronizeEvent(void* event) const override { + if (!event) + return; + auto* xpu_event = reinterpret_cast(event); + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_event_synchronization( + c10::kXPU, reinterpret_cast(xpu_event)); + } + xpu_event->wait_and_throw(); + } + + void synchronizeDevice(const c10::DeviceIndex device_index) const override { + const c10::impl::PyInterpreter* interp = c10::impl::GPUTrace::get_trace(); + if (C10_UNLIKELY(interp)) { + (*interp)->trace_gpu_device_synchronization(c10::kXPU); + } + c10::xpu::syncStreamsOnDevice(device_index); + } + + void recordDataPtrOnStream(const c10::DataPtr& data_ptr, const Stream& stream) + const override { + const XPUStream xpu_stream{stream}; + XPUCachingAllocator::recordStream(data_ptr, xpu_stream); + } +}; + +} // namespace c10::xpu::impl + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/test/impl/XPUTest.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/test/impl/XPUTest.h new file mode 100644 index 0000000000000000000000000000000000000000..336c8349121389fd6dc64732ef50977e1cb2e0d2 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/test/impl/XPUTest.h @@ -0,0 +1,26 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +#include + +static inline void initHostData(int* hostData, int numel) { + for (const auto i : c10::irange(numel)) { + hostData[i] = i; + } +} + +static inline void clearHostData(int* hostData, int numel) { + for (const auto i : c10::irange(numel)) { + hostData[i] = 0; + } +} + +static inline void validateHostData(int* hostData, int numel) { + for (const auto i : c10::irange(numel)) { + EXPECT_EQ(hostData[i], i); + } +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/common.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/common.h new file mode 100644 index 0000000000000000000000000000000000000000..f8de86b9ed8e3fc25a3e6efe20bc36f5b29336c0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/common.h @@ -0,0 +1,66 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef CAFFE2_CORE_COMMON_H_ +#define CAFFE2_CORE_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#endif + +#if defined(_MSC_VER) +#include +#else +#include +#endif + +// Macros used during the build of this caffe2 instance. This header file +// is automatically generated by the cmake script during build. +#include "caffe2/core/macros.h" + +#include + +namespace caffe2 { + +// Using statements for common classes that we refer to in caffe2 very often. +// Note that we only place it inside caffe2 so the global namespace is not +// polluted. +/* using override */ +using std::set; +using std::string; +using std::unique_ptr; +using std::vector; + +// Define alignment macro that is cross platform +#if (defined _MSC_VER && !defined NOMINMAX) +#define NOMINMAX +#endif + +using std::make_unique; + +#if defined(__ANDROID__) && !defined(__NDK_MAJOR__) +using ::round; +#else +using std::round; +#endif // defined(__ANDROID__) && !defined(__NDK_MAJOR__) + +// Returns which setting Caffe2 was configured and built with (exported from +// CMake) +TORCH_API const std::map& GetBuildOptions(); + +} // namespace caffe2 + +#endif // CAFFE2_CORE_COMMON_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/macros.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/macros.h new file mode 100644 index 0000000000000000000000000000000000000000..2e86ebe216d7d7bc2022375a7443040a56997c16 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/macros.h @@ -0,0 +1,77 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Automatically generated header file for caffe2 macros. These +// macros are used to build the Caffe2 binary, and if you are +// building a dependent library, they will need to be set as well +// for your program to link correctly. + +#pragma once + +#define CAFFE2_BUILD_SHARED_LIBS +/* #undef CAFFE2_FORCE_FALLBACK_CUDA_MPI */ +/* #undef CAFFE2_HAS_MKL_DNN */ +/* #undef CAFFE2_HAS_MKL_SGEMM_PACK */ +#define CAFFE2_PERF_WITH_AVX +#define CAFFE2_PERF_WITH_AVX2 +/* #undef CAFFE2_THREADPOOL_MAIN_IMBALANCE */ +/* #undef CAFFE2_THREADPOOL_STATS */ +/* #undef CAFFE2_USE_ACCELERATE */ +#define CAFFE2_USE_CUDNN +/* #undef CAFFE2_USE_EIGEN_FOR_BLAS */ +/* #undef CAFFE2_USE_FBCODE */ +/* #undef CAFFE2_USE_GOOGLE_GLOG */ +/* #undef CAFFE2_USE_LITE_PROTO */ +/* #undef CAFFE2_USE_MKL */ +#define USE_MKLDNN +/* #undef CAFFE2_USE_NVTX */ +/* #undef CAFFE2_USE_ITT */ + +#ifndef EIGEN_MPL2_ONLY +#define EIGEN_MPL2_ONLY +#endif + +// Useful build settings that are recorded in the compiled binary +// torch.__config__.show() +#define CAFFE2_BUILD_STRINGS { \ + {"TORCH_VERSION", "2.12.1"}, \ + {"CXX_COMPILER", "/cvmfs/soft.computecanada.ca/gentoo/2023/x86-64-v3/usr/x86_64-pc-linux-gnu/gcc-bin/12/c++"}, \ + {"CXX_FLAGS", " -fvisibility-inlines-hidden -DUSE_PTHREADPOOL -DNDEBUG -DUSE_KINETO -DLIBKINETO_NOROCTRACER -DLIBKINETO_NOXPUPTI=ON -DUSE_FBGEMM -DUSE_MSLK -DUSE_PYTORCH_QNNPACK -DUSE_XNNPACK -DSYMBOLICATE_MOBILE_DEBUG_HANDLE -O2 -fPIC -DC10_NODEPRECATED -Wall -Wextra -Werror=return-type -Werror=non-virtual-dtor -Werror=range-loop-construct -Werror=bool-operation -Wnarrowing -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-unused-parameter -Wno-strict-overflow -Wno-strict-aliasing -Wno-stringop-overflow -Wsuggest-override -Wno-psabi -Wno-error=old-style-cast -faligned-new -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math -Werror=format -Wno-stringop-overflow"}, \ + {"CUDA_FLAGS", " -DLIBCUDACXX_ENABLE_SIMPLIFIED_COMPLEX_OPERATIONS -Xfatbin -compress-all -DONNX_NAMESPACE=onnx_torch -gencode arch=compute_80,code=sm_80 -gencode arch=compute_90,code=sm_90 -gencode arch=compute_100,code=sm_100 -gencode arch=compute_100,code=compute_100 -Xcudafe --diag_suppress=cc_clobber_ignored,--diag_suppress=field_without_dll_interface,--diag_suppress=base_class_has_different_dll_interface,--diag_suppress=dll_interface_conflict_none_assumed,--diag_suppress=dll_interface_conflict_dllexport_assumed,--diag_suppress=bad_friend_decl --expt-relaxed-constexpr --expt-extended-lambda -Wno-deprecated-gpu-targets --expt-extended-lambda -DCUB_WRAPPED_NAMESPACE=at_cuda_detail -DDISABLE_CUSPARSE_DEPRECATED -DCUDA_HAS_FP16=1 -D__CUDA_NO_HALF_OPERATORS__ -D__CUDA_NO_HALF_CONVERSIONS__ -D__CUDA_NO_HALF2_OPERATORS__ -D__CUDA_NO_BFLOAT16_CONVERSIONS__ -DC10_NODEPRECATED"}, \ + {"BUILD_TYPE", "Release"}, \ + {"BLAS_INFO", "flexi"}, \ + {"LAPACK_INFO", "flexi"}, \ + {"USE_CUDA", "ON"}, \ + {"USE_ROCM", "OFF"}, \ + {"CUDA_VERSION", "13.2"}, \ + {"ROCM_VERSION", ""}, \ + {"USE_CUDNN", "ON"}, \ + {"COMMIT_SHA", "7269437d655783a26cba32aa88195b741ff496aa"}, \ + {"CUDNN_VERSION", "9.21.1"}, \ + {"USE_NCCL", "ON"}, \ + {"USE_MPI", "ON"}, \ + {"USE_GFLAGS", "OFF"}, \ + {"USE_GLOG", "OFF"}, \ + {"USE_GLOO", "ON"}, \ + {"USE_NNPACK", "ON"}, \ + {"USE_OPENMP", "ON"}, \ + {"FORCE_FALLBACK_CUDA_MPI", ""}, \ + {"HAS_MKL_DNN", ""}, \ + {"HAS_MKL_SGEMM_PACK", ""}, \ + {"PERF_WITH_AVX", "1"}, \ + {"PERF_WITH_AVX2", "1"}, \ + {"USE_ACCELERATE", ""}, \ + {"USE_EIGEN_FOR_BLAS", ""}, \ + {"USE_LITE_PROTO", ""}, \ + {"USE_MKL", ""}, \ + {"USE_MKLDNN", "ON"}, \ + {"USE_NVTX", ""}, \ + {"USE_ITT", ""}, \ + {"USE_ROCM_KERNEL_ASSERT", "OFF"}, \ + {"USE_CUSPARSELT", "ON"}, \ + {"USE_XPU", "OFF"}, \ + {"USE_XCCL", "OFF"}, \ + {"SYCL_COMPILER_VERSION", ""}, \ +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/timer.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/timer.h new file mode 100644 index 0000000000000000000000000000000000000000..54ff81fc25e27eb38cc23e497b692f321b71c6b4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/timer.h @@ -0,0 +1,53 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef CAFFE2_CORE_TIMER_H_ +#define CAFFE2_CORE_TIMER_H_ + +#include + +#include "caffe2/core/common.h" + +namespace caffe2 { + +/** + * @brief A simple timer object for measuring time. + * + * This is a minimal class around a std::chrono::high_resolution_clock that + * serves as a utility class for testing code. + */ +class Timer { + public: + typedef std::chrono::high_resolution_clock clock; + typedef std::chrono::nanoseconds ns; + Timer() { Start(); } + /** + * @brief Starts a timer. + */ + inline void Start() { start_time_ = clock::now(); } + inline float NanoSeconds() { + return static_cast( + std::chrono::duration_cast(clock::now() - start_time_).count()); + } + /** + * @brief Returns the elapsed time in milliseconds. + */ + inline float MilliSeconds() { return NanoSeconds() / 1000000.f; } + /** + * @brief Returns the elapsed time in microseconds. + */ + inline float MicroSeconds() { return NanoSeconds() / 1000.f; } + /** + * @brief Returns the elapsed time in seconds. + */ + inline float Seconds() { return NanoSeconds() / 1000000000.f; } + + protected: + std::chrono::time_point start_time_; + C10_DISABLE_COPY_AND_ASSIGN(Timer); +}; +} + +#endif // CAFFE2_CORE_TIMER_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/perfkernels/common.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/perfkernels/common.h new file mode 100644 index 0000000000000000000000000000000000000000..f927b1ac74631203bfb9ac4bf869d0e2fa7b0a7c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/perfkernels/common.h @@ -0,0 +1,145 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// !!!! PLEASE READ !!!! +// Minimize (transitively) included headers from _avx*.cc because some of the +// functions defined in the headers compiled with platform dependent compiler +// options can be reused by other translation units generating illegal +// instruction run-time error. + +// Common utilities for writing performance kernels and easy dispatching of +// different backends. +/* +The general workflow shall be as follows, say we want to +implement a functionality called void foo(int a, float b). + +In foo.h, do: + void foo(int a, float b); + +In foo_avx512.cc, do: + void foo__avx512(int a, float b) { + [actual avx512 implementation] + } + +In foo_avx2.cc, do: + void foo__avx2(int a, float b) { + [actual avx2 implementation] + } + +In foo_avx.cc, do: + void foo__avx(int a, float b) { + [actual avx implementation] + } + +In foo.cc, do: + // The base implementation should *always* be provided. + void foo__base(int a, float b) { + [base, possibly slow implementation] + } + decltype(foo__base) foo__avx512; + decltype(foo__base) foo__avx2; + decltype(foo__base) foo__avx; + void foo(int a, float b) { + // You should always order things by their preference, faster + // implementations earlier in the function. + AVX512_DO(foo, a, b); + AVX2_DO(foo, a, b); + AVX_DO(foo, a, b); + BASE_DO(foo, a, b); + } + +*/ +// Details: this functionality basically covers the cases for both build time +// and run time architecture support. +// +// During build time: +// The build system should provide flags CAFFE2_PERF_WITH_AVX512, +// CAFFE2_PERF_WITH_AVX2, and CAFFE2_PERF_WITH_AVX that corresponds to the +// __AVX512F__, __AVX512DQ__, __AVX512VL__, __AVX2__, and __AVX__ flags the +// compiler provides. Note that we do not use the compiler flags but rely on +// the build system flags, because the common files (like foo.cc above) will +// always be built without __AVX512F__, __AVX512DQ__, __AVX512VL__, __AVX2__ +// and __AVX__. +// During run time: +// we use cpuinfo to identify cpu support and run the proper functions. + +#pragma once +#if defined(CAFFE2_PERF_WITH_SVE) || defined(CAFFE2_PERF_WITH_AVX512) || \ + defined(CAFFE2_PERF_WITH_AVX2) || defined(CAFFE2_PERF_WITH_AVX) +#include +#endif + +// DO macros: these should be used in your entry function, similar to foo() +// above, that routes implementations based on CPU capability. + +#define BASE_DO(funcname, ...) return funcname##__base(__VA_ARGS__); + +#ifdef CAFFE2_PERF_WITH_SVE +#define SVE_DO(funcname, ...) \ + { \ + static const bool isDo = cpuinfo_initialize() && cpuinfo_has_arm_sve(); \ + if (isDo) { \ + return funcname##__sve(__VA_ARGS__); \ + } \ + } +#else // CAFFE2_PERF_WITH_SVE +#define SVE_DO(funcname, ...) +#endif // CAFFE2_PERF_WITH_SVE + +#ifdef CAFFE2_PERF_WITH_AVX512 +#define AVX512_DO(funcname, ...) \ + { \ + static const bool isDo = cpuinfo_initialize() && \ + cpuinfo_has_x86_avx512f() && cpuinfo_has_x86_avx512dq() && \ + cpuinfo_has_x86_avx512vl(); \ + if (isDo) { \ + return funcname##__avx512(__VA_ARGS__); \ + } \ + } +#else // CAFFE2_PERF_WITH_AVX512 +#define AVX512_DO(funcname, ...) +#endif // CAFFE2_PERF_WITH_AVX512 + +#ifdef CAFFE2_PERF_WITH_AVX2 +#define AVX2_DO(funcname, ...) \ + { \ + static const bool isDo = cpuinfo_initialize() && cpuinfo_has_x86_avx2(); \ + if (isDo) { \ + return funcname##__avx2(__VA_ARGS__); \ + } \ + } +#define AVX2_FMA_DO(funcname, ...) \ + { \ + static const bool isDo = cpuinfo_initialize() && cpuinfo_has_x86_avx2() && \ + cpuinfo_has_x86_fma3(); \ + if (isDo) { \ + return funcname##__avx2_fma(__VA_ARGS__); \ + } \ + } +#else // CAFFE2_PERF_WITH_AVX2 +#define AVX2_DO(funcname, ...) +#define AVX2_FMA_DO(funcname, ...) +#endif // CAFFE2_PERF_WITH_AVX2 + +#ifdef CAFFE2_PERF_WITH_AVX +#define AVX_DO(funcname, ...) \ + { \ + static const bool isDo = cpuinfo_initialize() && cpuinfo_has_x86_avx(); \ + if (isDo) { \ + return funcname##__avx(__VA_ARGS__); \ + } \ + } +#define AVX_F16C_DO(funcname, ...) \ + { \ + static const bool isDo = cpuinfo_initialize() && cpuinfo_has_x86_avx() && \ + cpuinfo_has_x86_f16c(); \ + if (isDo) { \ + return funcname##__avx_f16c(__VA_ARGS__); \ + } \ + } +#else // CAFFE2_PERF_WITH_AVX +#define AVX_DO(funcname, ...) +#define AVX_F16C_DO(funcname, ...) +#endif // CAFFE2_PERF_WITH_AVX + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/perfkernels/embedding_lookup_idx.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/perfkernels/embedding_lookup_idx.h new file mode 100644 index 0000000000000000000000000000000000000000..45eb7106de95e6ae73e4a99b020339aadb7fc527 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/perfkernels/embedding_lookup_idx.h @@ -0,0 +1,62 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace caffe2 { + +// clang-format off +/** + * Embedding lookup with reduction. + * + * `input` of size data_size * block_size + * `indices` of size index_size + * `offsets` of size output_size + * `weights` nullptr or array of size index_size + * `out` of size output_size * block_size + * + * Behavior is roughly equivalent to pseudocode: + * + * pos = 0 + * for (i = 0..output_size-1) + * for (k = 0..block_size-1) + * out[i*block_size + k] = 0 + * start_offset = offsets[i] + * end_offset = offsets[i+1] + * length = end_offset - start_offset + * for (j = start_offset..end_offset-1) + * for (k = 0..block_size-1) + * out[i*block_size + k] += input[indices[pos]*block_size + k] * + * (weights ? weights[IS_WEIGHT_POSITIONAL ? j - start_offset : pos] : 1.0) + * pos += 1 + * if (normalize_weights && length > 0) + * for (k = 0..block_size-1) + * out[i*block_size + k] /= length + * + * TODO: make this API also take "offsets" rather than "lengths" to match the + * API for PyTorch's EmbeddingBag + */ +// clang-format on +template < + typename IndexType, + typename InType, + typename OutType, + bool IS_WEIGHT_POSITIONAL = false> +void EmbeddingLookupIdx( + const std::int64_t block_size, + const std::int64_t output_size, + const std::int64_t index_size, + const std::int64_t data_size, + const InType* input, + const IndexType* indices, + const IndexType* offsets, + const float* weights, // optional, can be null for non-weighted sum + const float* scale_bias, // optional scale & bias params for uint8 input + bool normalize_by_lengths, + OutType* out); + +} // namespace caffe2 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/crc_alt.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/crc_alt.h new file mode 100644 index 0000000000000000000000000000000000000000..5586b37e59707104b1138b4f806200ded8466e87 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/crc_alt.h @@ -0,0 +1,1348 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +// ////////////////////////////////////////////////////////// +// Crc32.h +// Copyright (c) 2011-2019 Stephan Brumme. All rights reserved. +// Slicing-by-16 contributed by Bulat Ziganshin +// Tableless bytewise CRC contributed by Hagai Gold +// see http://create.stephan-brumme.com/disclaimer.html +// + +// if running on an embedded system, you might consider shrinking the +// big Crc32Lookup table by undefining these lines: +#define CRC32_USE_LOOKUP_TABLE_BYTE +#define CRC32_USE_LOOKUP_TABLE_SLICING_BY_4 +#define CRC32_USE_LOOKUP_TABLE_SLICING_BY_8 +#define CRC32_USE_LOOKUP_TABLE_SLICING_BY_16 +// - crc32_bitwise doesn't need it at all +// - crc32_halfbyte has its own small lookup table +// - crc32_1byte_tableless and crc32_1byte_tableless2 don't need it at all +// - crc32_1byte needs only Crc32Lookup[0] +// - crc32_4bytes needs only Crc32Lookup[0..3] +// - crc32_8bytes needs only Crc32Lookup[0..7] +// - crc32_4x8bytes needs only Crc32Lookup[0..7] +// - crc32_16bytes needs all of Crc32Lookup +// using the aforementioned #defines the table is automatically fitted to your needs + +// uint8_t, uint32_t, int32_t +#include +// size_t +#include + +// crc32_fast selects the fastest algorithm depending on flags (CRC32_USE_LOOKUP_...) +/// compute CRC32 using the fastest algorithm for large datasets on modern CPUs +uint32_t crc32_fast (const void* data, size_t length, uint32_t previousCrc32 = 0); + +/// merge two CRC32 such that result = crc32(dataB, lengthB, crc32(dataA, lengthA)) +uint32_t crc32_combine (uint32_t crcA, uint32_t crcB, size_t lengthB); + +/// compute CRC32 (bitwise algorithm) +uint32_t crc32_bitwise (const void* data, size_t length, uint32_t previousCrc32 = 0); +/// compute CRC32 (half-byte algorithm) +uint32_t crc32_halfbyte(const void* data, size_t length, uint32_t previousCrc32 = 0); + +#ifdef CRC32_USE_LOOKUP_TABLE_BYTE +/// compute CRC32 (standard algorithm) +uint32_t crc32_1byte (const void* data, size_t length, uint32_t previousCrc32 = 0); +#endif + +/// compute CRC32 (byte algorithm) without lookup tables +uint32_t crc32_1byte_tableless (const void* data, size_t length, uint32_t previousCrc32 = 0); +/// compute CRC32 (byte algorithm) without lookup tables +uint32_t crc32_1byte_tableless2(const void* data, size_t length, uint32_t previousCrc32 = 0); + +#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_4 +/// compute CRC32 (Slicing-by-4 algorithm) +uint32_t crc32_4bytes (const void* data, size_t length, uint32_t previousCrc32 = 0); +#endif + +#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_8 +/// compute CRC32 (Slicing-by-8 algorithm) +uint32_t crc32_8bytes (const void* data, size_t length, uint32_t previousCrc32 = 0); +/// compute CRC32 (Slicing-by-8 algorithm), unroll inner loop 4 times +uint32_t crc32_4x8bytes(const void* data, size_t length, uint32_t previousCrc32 = 0); +#endif + +#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_16 +/// compute CRC32 (Slicing-by-16 algorithm) +uint32_t crc32_16bytes (const void* data, size_t length, uint32_t previousCrc32 = 0); +/// compute CRC32 (Slicing-by-16 algorithm, prefetch upcoming data blocks) +uint32_t crc32_16bytes_prefetch(const void* data, size_t length, uint32_t previousCrc32 = 0, size_t prefetchAhead = 256); +#endif + +// ////////////////////////////////////////////////////////// +// Crc32.cpp +// Copyright (c) 2011-2019 Stephan Brumme. All rights reserved. +// Slicing-by-16 contributed by Bulat Ziganshin +// Tableless bytewise CRC contributed by Hagai Gold +// see http://create.stephan-brumme.com/disclaimer.html +// + +// if running on an embedded system, you might consider shrinking the +// big Crc32Lookup table: +// - crc32_bitwise doesn't need it at all +// - crc32_halfbyte has its own small lookup table +// - crc32_1byte needs only Crc32Lookup[0] +// - crc32_4bytes needs only Crc32Lookup[0..3] +// - crc32_8bytes needs only Crc32Lookup[0..7] +// - crc32_4x8bytes needs only Crc32Lookup[0..7] +// - crc32_16bytes needs all of Crc32Lookup + + +#ifndef __LITTLE_ENDIAN + #define __LITTLE_ENDIAN 1234 +#endif +#ifndef __BIG_ENDIAN + #define __BIG_ENDIAN 4321 +#endif + +// define endianness and some integer data types +#if defined(_MSC_VER) || defined(__MINGW32__) + // Windows always little endian + #define __BYTE_ORDER __LITTLE_ENDIAN + + // intrinsics / prefetching + #if defined(_M_ARM64) + #include + #else + #include + #endif + + #ifdef __MINGW32__ + #define PREFETCH(location) __builtin_prefetch(location) + #else + #if defined(_M_ARM64) + #define PREFETCH(location) __prefetch(location) + #else + #define PREFETCH(location) _mm_prefetch(location, _MM_HINT_T0) + #endif + #endif +#elif defined(__APPLE__) + #include + #if TARGET_IPHONE_SIMULATOR + #define __BYTE_ORDER __LITTLE_ENDIAN + #elif TARGET_OS_IPHONE + #define __BYTE_ORDER __LITTLE_ENDIAN + #elif TARGET_OS_MAC + #include + #if defined(__BIG_ENDIAN__) + #define __BYTE_ORDER __BIG_ENDIAN + #endif + #if defined(__LITTLE_ENDIAN__) + #define __BYTE_ORDER __LITTLE_ENDIAN + #endif + #else + # error "Unknown Apple platform" + #endif +#elif defined(__ARMEB__) + #define __BYTE_ORDER __BIG_ENDIAN +#elif (defined(__BYTE_ORDER__) and !defined(__BYTE_ORDER)) + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define __BYTE_ORDER __BIG_ENDIAN + #else + #define __BYTE_ORDER __LITTLE_ENDIAN + #endif +#else + // defines __BYTE_ORDER as __LITTLE_ENDIAN or __BIG_ENDIAN + #include +#endif + +// intrinsics / prefetching +#ifdef __GNUC__ + #define PREFETCH(location) __builtin_prefetch(location) +#else +#ifndef PREFETCH + // no prefetching + #define PREFETCH(location) ; +#endif +#endif + +// abort if byte order is undefined +#ifndef __BYTE_ORDER +#error undefined byte order, compile with -D__BYTE_ORDER=1234 (if little endian) or -D__BYTE_ORDER=4321 (big endian) +#endif + + +namespace +{ + /// zlib's CRC32 polynomial + const uint32_t Polynomial = 0xEDB88320; + + /// swap endianness + static inline uint32_t swap(uint32_t x) + { + #if defined(__GNUC__) || defined(__clang__) + return __builtin_bswap32(x); + #else + return (x >> 24) | + ((x >> 8) & 0x0000FF00) | + ((x << 8) & 0x00FF0000) | + (x << 24); + #endif + } + + /// Slicing-By-16 + #ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_16 + const size_t MaxSlice = 16; + #elif defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_8) + const size_t MaxSlice = 8; + #elif defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_4) + const size_t MaxSlice = 4; + #elif defined(CRC32_USE_LOOKUP_TABLE_BYTE) + const size_t MaxSlice = 1; + #else + #define NO_LUT // don't need Crc32Lookup at all + #endif + +} // anonymous namespace + +#ifndef NO_LUT +/// forward declaration, table is at the end of this file +extern const uint32_t Crc32Lookup[MaxSlice][256]; // extern is needed to keep compiler happy +#endif + + +/// compute CRC32 (bitwise algorithm) +uint32_t crc32_bitwise(const void* data, size_t length, uint32_t previousCrc32) +{ + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint8_t* current = (const uint8_t*) data; + + while (length-- != 0) + { + crc ^= *current++; + + for (int j = 0; j < 8; j++) + { + // branch-free + crc = (crc >> 1) ^ (-int32_t(crc & 1) & Polynomial); + + // branching, much slower: + //if (crc & 1) + // crc = (crc >> 1) ^ Polynomial; + //else + // crc = crc >> 1; + } + } + + return ~crc; // same as crc ^ 0xFFFFFFFF +} + + +/// compute CRC32 (half-byte algorithm) +uint32_t crc32_halfbyte(const void* data, size_t length, uint32_t previousCrc32) +{ + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint8_t* current = (const uint8_t*) data; + + /// look-up table for half-byte, same as crc32Lookup[0][16*i] + static const uint32_t Crc32Lookup16[16] = + { + 0x00000000,0x1DB71064,0x3B6E20C8,0x26D930AC,0x76DC4190,0x6B6B51F4,0x4DB26158,0x5005713C, + 0xEDB88320,0xF00F9344,0xD6D6A3E8,0xCB61B38C,0x9B64C2B0,0x86D3D2D4,0xA00AE278,0xBDBDF21C + }; + + while (length-- != 0) + { + crc = Crc32Lookup16[(crc ^ *current ) & 0x0F] ^ (crc >> 4); + crc = Crc32Lookup16[(crc ^ (*current >> 4)) & 0x0F] ^ (crc >> 4); + current++; + } + + return ~crc; // same as crc ^ 0xFFFFFFFF +} + + +#ifdef CRC32_USE_LOOKUP_TABLE_BYTE +/// compute CRC32 (standard algorithm) +uint32_t crc32_1byte(const void* data, size_t length, uint32_t previousCrc32) +{ + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint8_t* current = (const uint8_t*) data; + + while (length-- != 0) + crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *current++]; + + return ~crc; // same as crc ^ 0xFFFFFFFF +} +#endif + + +/// compute CRC32 (byte algorithm) without lookup tables +uint32_t crc32_1byte_tableless(const void* data, size_t length, uint32_t previousCrc32) +{ + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint8_t* current = (const uint8_t*) data; + + while (length-- != 0) + { + uint8_t s = uint8_t(crc) ^ *current++; + + // Hagai Gold made me aware of this table-less algorithm and send me code + + // polynomial 0xEDB88320 can be written in binary as 11101101101110001000001100100000b + // reverse the bits (or just assume bit 0 is the first one) + // and we have bits set at position 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 + // => those are the shift offsets: + //crc = (crc >> 8) ^ + // t ^ + // (t >> 1) ^ (t >> 2) ^ (t >> 4) ^ (t >> 5) ^ // == y + // (t >> 7) ^ (t >> 8) ^ (t >> 10) ^ (t >> 11) ^ // == y >> 6 + // (t >> 12) ^ (t >> 16) ^ // == z + // (t >> 22) ^ (t >> 26) ^ // == z >> 10 + // (t >> 23); + + // the fastest I can come up with: + uint32_t low = (s ^ (s << 6)) & 0xFF; + uint32_t a = (low * ((1 << 23) + (1 << 14) + (1 << 2))); + crc = (crc >> 8) ^ + (low * ((1 << 24) + (1 << 16) + (1 << 8))) ^ + a ^ + (a >> 1) ^ + (low * ((1 << 20) + (1 << 12) )) ^ + (low << 19) ^ + (low << 17) ^ + (low >> 2); + + // Hagai's code: + /*uint32_t t = (s ^ (s << 6)) << 24; + // some temporaries to optimize XOR + uint32_t x = (t >> 1) ^ (t >> 2); + uint32_t y = x ^ (x >> 3); + uint32_t z = (t >> 12) ^ (t >> 16); + crc = (crc >> 8) ^ + t ^ (t >> 23) ^ + y ^ (y >> 6) ^ + z ^ (z >> 10);*/ + } + + return ~crc; // same as crc ^ 0xFFFFFFFF +} + + +/// compute CRC32 (byte algorithm) without lookup tables +uint32_t crc32_1byte_tableless2(const void* data, size_t length, uint32_t previousCrc32) +{ + int32_t crc = ~previousCrc32; // note: signed integer, right shift distributes sign bit into lower bits + const uint8_t* current = (const uint8_t*) data; + + while (length-- != 0) + { + crc = crc ^ *current++; + + uint32_t c = (((crc << 31) >> 31) & ((Polynomial >> 7) ^ (Polynomial >> 1))) ^ + (((crc << 30) >> 31) & ((Polynomial >> 6) ^ Polynomial)) ^ + (((crc << 29) >> 31) & (Polynomial >> 5)) ^ + (((crc << 28) >> 31) & (Polynomial >> 4)) ^ + (((crc << 27) >> 31) & (Polynomial >> 3)) ^ + (((crc << 26) >> 31) & (Polynomial >> 2)) ^ + (((crc << 25) >> 31) & (Polynomial >> 1)) ^ + (((crc << 24) >> 31) & Polynomial); + + crc = ((uint32_t)crc >> 8) ^ c; // convert to unsigned integer before right shift + } + + return ~crc; // same as crc ^ 0xFFFFFFFF +} + + +#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_4 +/// compute CRC32 (Slicing-by-4 algorithm) +uint32_t crc32_4bytes(const void* data, size_t length, uint32_t previousCrc32) +{ + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint32_t* current = (const uint32_t*) data; + + // process four bytes at once (Slicing-by-4) + while (length >= 4) + { +#if __BYTE_ORDER == __BIG_ENDIAN + uint32_t one = *current++ ^ swap(crc); + crc = Crc32Lookup[0][ one & 0xFF] ^ + Crc32Lookup[1][(one>> 8) & 0xFF] ^ + Crc32Lookup[2][(one>>16) & 0xFF] ^ + Crc32Lookup[3][(one>>24) & 0xFF]; +#else + uint32_t one = *current++ ^ crc; + crc = Crc32Lookup[0][(one>>24) & 0xFF] ^ + Crc32Lookup[1][(one>>16) & 0xFF] ^ + Crc32Lookup[2][(one>> 8) & 0xFF] ^ + Crc32Lookup[3][ one & 0xFF]; +#endif + + length -= 4; + } + + const uint8_t* currentChar = (const uint8_t*) current; + // remaining 1 to 3 bytes (standard algorithm) + while (length-- != 0) + crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; + + return ~crc; // same as crc ^ 0xFFFFFFFF +} +#endif + + +#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_8 +/// compute CRC32 (Slicing-by-8 algorithm) +uint32_t crc32_8bytes(const void* data, size_t length, uint32_t previousCrc32) +{ + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint32_t* current = (const uint32_t*) data; + + // process eight bytes at once (Slicing-by-8) + while (length >= 8) + { +#if __BYTE_ORDER == __BIG_ENDIAN + uint32_t one = *current++ ^ swap(crc); + uint32_t two = *current++; + crc = Crc32Lookup[0][ two & 0xFF] ^ + Crc32Lookup[1][(two>> 8) & 0xFF] ^ + Crc32Lookup[2][(two>>16) & 0xFF] ^ + Crc32Lookup[3][(two>>24) & 0xFF] ^ + Crc32Lookup[4][ one & 0xFF] ^ + Crc32Lookup[5][(one>> 8) & 0xFF] ^ + Crc32Lookup[6][(one>>16) & 0xFF] ^ + Crc32Lookup[7][(one>>24) & 0xFF]; +#else + uint32_t one = *current++ ^ crc; + uint32_t two = *current++; + crc = Crc32Lookup[0][(two>>24) & 0xFF] ^ + Crc32Lookup[1][(two>>16) & 0xFF] ^ + Crc32Lookup[2][(two>> 8) & 0xFF] ^ + Crc32Lookup[3][ two & 0xFF] ^ + Crc32Lookup[4][(one>>24) & 0xFF] ^ + Crc32Lookup[5][(one>>16) & 0xFF] ^ + Crc32Lookup[6][(one>> 8) & 0xFF] ^ + Crc32Lookup[7][ one & 0xFF]; +#endif + + length -= 8; + } + + const uint8_t* currentChar = (const uint8_t*) current; + // remaining 1 to 7 bytes (standard algorithm) + while (length-- != 0) + crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; + + return ~crc; // same as crc ^ 0xFFFFFFFF +} + + +/// compute CRC32 (Slicing-by-8 algorithm), unroll inner loop 4 times +uint32_t crc32_4x8bytes(const void* data, size_t length, uint32_t previousCrc32) +{ + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint32_t* current = (const uint32_t*) data; + + // enabling optimization (at least -O2) automatically unrolls the inner for-loop + const size_t Unroll = 4; + const size_t BytesAtOnce = 8 * Unroll; + + // process 4x eight bytes at once (Slicing-by-8) + while (length >= BytesAtOnce) + { + for (size_t unrolling = 0; unrolling < Unroll; unrolling++) + { +#if __BYTE_ORDER == __BIG_ENDIAN + uint32_t one = *current++ ^ swap(crc); + uint32_t two = *current++; + crc = Crc32Lookup[0][ two & 0xFF] ^ + Crc32Lookup[1][(two>> 8) & 0xFF] ^ + Crc32Lookup[2][(two>>16) & 0xFF] ^ + Crc32Lookup[3][(two>>24) & 0xFF] ^ + Crc32Lookup[4][ one & 0xFF] ^ + Crc32Lookup[5][(one>> 8) & 0xFF] ^ + Crc32Lookup[6][(one>>16) & 0xFF] ^ + Crc32Lookup[7][(one>>24) & 0xFF]; +#else + uint32_t one = *current++ ^ crc; + uint32_t two = *current++; + crc = Crc32Lookup[0][(two>>24) & 0xFF] ^ + Crc32Lookup[1][(two>>16) & 0xFF] ^ + Crc32Lookup[2][(two>> 8) & 0xFF] ^ + Crc32Lookup[3][ two & 0xFF] ^ + Crc32Lookup[4][(one>>24) & 0xFF] ^ + Crc32Lookup[5][(one>>16) & 0xFF] ^ + Crc32Lookup[6][(one>> 8) & 0xFF] ^ + Crc32Lookup[7][ one & 0xFF]; +#endif + + } + + length -= BytesAtOnce; + } + + const uint8_t* currentChar = (const uint8_t*) current; + // remaining 1 to 31 bytes (standard algorithm) + while (length-- != 0) + crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; + + return ~crc; // same as crc ^ 0xFFFFFFFF +} +#endif // CRC32_USE_LOOKUP_TABLE_SLICING_BY_8 + + +#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_16 +/// compute CRC32 (Slicing-by-16 algorithm) +uint32_t crc32_16bytes(const void* data, size_t length, uint32_t previousCrc32) +{ + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint32_t* current = (const uint32_t*) data; + + // enabling optimization (at least -O2) automatically unrolls the inner for-loop + const size_t Unroll = 4; + const size_t BytesAtOnce = 16 * Unroll; + + while (length >= BytesAtOnce) + { + for (size_t unrolling = 0; unrolling < Unroll; unrolling++) + { +#if __BYTE_ORDER == __BIG_ENDIAN + uint32_t one = *current++ ^ swap(crc); + uint32_t two = *current++; + uint32_t three = *current++; + uint32_t four = *current++; + crc = Crc32Lookup[ 0][ four & 0xFF] ^ + Crc32Lookup[ 1][(four >> 8) & 0xFF] ^ + Crc32Lookup[ 2][(four >> 16) & 0xFF] ^ + Crc32Lookup[ 3][(four >> 24) & 0xFF] ^ + Crc32Lookup[ 4][ three & 0xFF] ^ + Crc32Lookup[ 5][(three >> 8) & 0xFF] ^ + Crc32Lookup[ 6][(three >> 16) & 0xFF] ^ + Crc32Lookup[ 7][(three >> 24) & 0xFF] ^ + Crc32Lookup[ 8][ two & 0xFF] ^ + Crc32Lookup[ 9][(two >> 8) & 0xFF] ^ + Crc32Lookup[10][(two >> 16) & 0xFF] ^ + Crc32Lookup[11][(two >> 24) & 0xFF] ^ + Crc32Lookup[12][ one & 0xFF] ^ + Crc32Lookup[13][(one >> 8) & 0xFF] ^ + Crc32Lookup[14][(one >> 16) & 0xFF] ^ + Crc32Lookup[15][(one >> 24) & 0xFF]; +#else + uint32_t one = *current++ ^ crc; + uint32_t two = *current++; + uint32_t three = *current++; + uint32_t four = *current++; + crc = Crc32Lookup[ 0][(four >> 24) & 0xFF] ^ + Crc32Lookup[ 1][(four >> 16) & 0xFF] ^ + Crc32Lookup[ 2][(four >> 8) & 0xFF] ^ + Crc32Lookup[ 3][ four & 0xFF] ^ + Crc32Lookup[ 4][(three >> 24) & 0xFF] ^ + Crc32Lookup[ 5][(three >> 16) & 0xFF] ^ + Crc32Lookup[ 6][(three >> 8) & 0xFF] ^ + Crc32Lookup[ 7][ three & 0xFF] ^ + Crc32Lookup[ 8][(two >> 24) & 0xFF] ^ + Crc32Lookup[ 9][(two >> 16) & 0xFF] ^ + Crc32Lookup[10][(two >> 8) & 0xFF] ^ + Crc32Lookup[11][ two & 0xFF] ^ + Crc32Lookup[12][(one >> 24) & 0xFF] ^ + Crc32Lookup[13][(one >> 16) & 0xFF] ^ + Crc32Lookup[14][(one >> 8) & 0xFF] ^ + Crc32Lookup[15][ one & 0xFF]; +#endif + } + + length -= BytesAtOnce; + } + + const uint8_t* currentChar = (const uint8_t*) current; + // remaining 1 to 63 bytes (standard algorithm) + while (length-- != 0) + crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; + + return ~crc; // same as crc ^ 0xFFFFFFFF +} + + +/// compute CRC32 (Slicing-by-16 algorithm, prefetch upcoming data blocks) +uint32_t crc32_16bytes_prefetch(const void* data, size_t length, uint32_t previousCrc32, size_t prefetchAhead) +{ + // CRC code is identical to crc32_16bytes (including unrolling), only added prefetching + // 256 bytes look-ahead seems to be the sweet spot on Core i7 CPUs + + uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF + const uint32_t* current = (const uint32_t*) data; + + // enabling optimization (at least -O2) automatically unrolls the for-loop + const size_t Unroll = 4; + const size_t BytesAtOnce = 16 * Unroll; + + while (length >= BytesAtOnce + prefetchAhead) + { + PREFETCH(((const char*) current) + prefetchAhead); + + for (size_t unrolling = 0; unrolling < Unroll; unrolling++) + { +#if __BYTE_ORDER == __BIG_ENDIAN + uint32_t one = *current++ ^ swap(crc); + uint32_t two = *current++; + uint32_t three = *current++; + uint32_t four = *current++; + crc = Crc32Lookup[ 0][ four & 0xFF] ^ + Crc32Lookup[ 1][(four >> 8) & 0xFF] ^ + Crc32Lookup[ 2][(four >> 16) & 0xFF] ^ + Crc32Lookup[ 3][(four >> 24) & 0xFF] ^ + Crc32Lookup[ 4][ three & 0xFF] ^ + Crc32Lookup[ 5][(three >> 8) & 0xFF] ^ + Crc32Lookup[ 6][(three >> 16) & 0xFF] ^ + Crc32Lookup[ 7][(three >> 24) & 0xFF] ^ + Crc32Lookup[ 8][ two & 0xFF] ^ + Crc32Lookup[ 9][(two >> 8) & 0xFF] ^ + Crc32Lookup[10][(two >> 16) & 0xFF] ^ + Crc32Lookup[11][(two >> 24) & 0xFF] ^ + Crc32Lookup[12][ one & 0xFF] ^ + Crc32Lookup[13][(one >> 8) & 0xFF] ^ + Crc32Lookup[14][(one >> 16) & 0xFF] ^ + Crc32Lookup[15][(one >> 24) & 0xFF]; +#else + uint32_t one = *current++ ^ crc; + uint32_t two = *current++; + uint32_t three = *current++; + uint32_t four = *current++; + crc = Crc32Lookup[ 0][(four >> 24) & 0xFF] ^ + Crc32Lookup[ 1][(four >> 16) & 0xFF] ^ + Crc32Lookup[ 2][(four >> 8) & 0xFF] ^ + Crc32Lookup[ 3][ four & 0xFF] ^ + Crc32Lookup[ 4][(three >> 24) & 0xFF] ^ + Crc32Lookup[ 5][(three >> 16) & 0xFF] ^ + Crc32Lookup[ 6][(three >> 8) & 0xFF] ^ + Crc32Lookup[ 7][ three & 0xFF] ^ + Crc32Lookup[ 8][(two >> 24) & 0xFF] ^ + Crc32Lookup[ 9][(two >> 16) & 0xFF] ^ + Crc32Lookup[10][(two >> 8) & 0xFF] ^ + Crc32Lookup[11][ two & 0xFF] ^ + Crc32Lookup[12][(one >> 24) & 0xFF] ^ + Crc32Lookup[13][(one >> 16) & 0xFF] ^ + Crc32Lookup[14][(one >> 8) & 0xFF] ^ + Crc32Lookup[15][ one & 0xFF]; +#endif + } + + length -= BytesAtOnce; + } + + const uint8_t* currentChar = (const uint8_t*) current; + // remaining 1 to 63 bytes (standard algorithm) + while (length-- != 0) + crc = (crc >> 8) ^ Crc32Lookup[0][(crc & 0xFF) ^ *currentChar++]; + + return ~crc; // same as crc ^ 0xFFFFFFFF +} +#endif + + +/// compute CRC32 using the fastest algorithm for large datasets on modern CPUs +uint32_t crc32_fast(const void* data, size_t length, uint32_t previousCrc32) +{ +#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_16 + return crc32_16bytes (data, length, previousCrc32); +#elif defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_8) + return crc32_8bytes (data, length, previousCrc32); +#elif defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_4) + return crc32_4bytes (data, length, previousCrc32); +#elif defined(CRC32_USE_LOOKUP_TABLE_BYTE) + return crc32_1byte (data, length, previousCrc32); +#else + return crc32_halfbyte(data, length, previousCrc32); +#endif +} + + +/// merge two CRC32 such that result = crc32(dataB, lengthB, crc32(dataA, lengthA)) +uint32_t crc32_combine(uint32_t crcA, uint32_t crcB, size_t lengthB) +{ + // based on Mark Adler's crc_combine from + // https://github.com/madler/pigz/blob/master/pigz.c + + // main idea: + // - if you have two equally-sized blocks A and B, + // then you can create a block C = A ^ B + // which has the property crc(C) = crc(A) ^ crc(B) + // - if you append length(B) zeros to A and call it A' (think of it as AAAA000) + // and prepend length(A) zeros to B and call it B' (think of it as 0000BBB) + // then exists a C' = A' ^ B' + // - remember: if you XOR something with zero, it remains unchanged: X ^ 0 = X + // - that means C' = A concat B so that crc(A concat B) = crc(C') = crc(A') ^ crc(B') + // - the trick is to compute crc(A') based on crc(A) + // and crc(B') based on crc(B) + // - since B' starts with many zeros, the crc of those initial zeros is still zero + // - that means crc(B') = crc(B) + // - unfortunately the trailing zeros of A' change the crc, so usually crc(A') != crc(A) + // - the following code is a fast algorithm to compute crc(A') + // - starting with crc(A) and appending length(B) zeros, needing just log2(length(B)) iterations + // - the details are explained by the original author at + // https://stackoverflow.com/questions/23122312/crc-calculation-of-a-mostly-static-data-stream/23126768 + // + // notes: + // - I squeezed everything into one function to keep global namespace clean (original code two helper functions) + // - most original comments are still in place, I added comments where these helper functions where made inline code + // - performance-wise there isn't any differenze to the original zlib/pigz code + + // degenerated case + if (lengthB == 0) + return crcA; + + /// CRC32 => 32 bits + const uint32_t CrcBits = 32; + + uint32_t odd [CrcBits]; // odd-power-of-two zeros operator + uint32_t even[CrcBits]; // even-power-of-two zeros operator + + // put operator for one zero bit in odd + odd[0] = Polynomial; // CRC-32 polynomial + for (uint32_t i = 1; i < CrcBits; i++) + odd[i] = 1 << (i - 1); + + // put operator for two zero bits in even + // same as gf2_matrix_square(even, odd); + for (uint32_t i = 0; i < CrcBits; i++) + { + uint32_t vec = odd[i]; + even[i] = 0; + for (int j = 0; vec != 0; j++, vec >>= 1) + if (vec & 1) + even[i] ^= odd[j]; + } + // put operator for four zero bits in odd + // same as gf2_matrix_square(odd, even); + for (uint32_t i = 0; i < CrcBits; i++) + { + uint32_t vec = even[i]; + odd[i] = 0; + for (int j = 0; vec != 0; j++, vec >>= 1) + if (vec & 1) + odd[i] ^= even[j]; + } + + // the following loop becomes much shorter if I keep swapping even and odd + uint32_t* a = even; + uint32_t* b = odd; + // apply secondLength zeros to firstCrc32 + for (; lengthB > 0; lengthB >>= 1) + { + // same as gf2_matrix_square(a, b); + for (uint32_t i = 0; i < CrcBits; i++) + { + uint32_t vec = b[i]; + a[i] = 0; + for (int j = 0; vec != 0; j++, vec >>= 1) + if (vec & 1) + a[i] ^= b[j]; + } + + // apply zeros operator for this bit + if (lengthB & 1) + { + // same as firstCrc32 = gf2_matrix_times(a, firstCrc32); + uint32_t sum = 0; + for (int i = 0; crcA != 0; i++, crcA >>= 1) + if (crcA & 1) + sum ^= a[i]; + crcA = sum; + } + + // switch even and odd + uint32_t* t = a; a = b; b = t; + } + + // return combined crc + return crcA ^ crcB; +} + + +// ////////////////////////////////////////////////////////// +// constants + + +#ifndef NO_LUT +/// look-up table, already declared above +const uint32_t Crc32Lookup[MaxSlice][256] = +{ + //// same algorithm as crc32_bitwise + //for (int i = 0; i <= 0xFF; i++) + //{ + // uint32_t crc = i; + // for (int j = 0; j < 8; j++) + // crc = (crc >> 1) ^ ((crc & 1) * Polynomial); + // Crc32Lookup[0][i] = crc; + //} + //// ... and the following slicing-by-8 algorithm (from Intel): + //// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf + //// http://sourceforge.net/projects/slicing-by-8/ + //for (int slice = 1; slice < MaxSlice; slice++) + // Crc32Lookup[slice][i] = (Crc32Lookup[slice - 1][i] >> 8) ^ Crc32Lookup[0][Crc32Lookup[slice - 1][i] & 0xFF]; + { + // note: the first number of every second row corresponds to the half-byte look-up table ! + 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3, + 0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91, + 0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7, + 0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5, + 0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B, + 0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59, + 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F, + 0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D, + 0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433, + 0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01, + 0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457, + 0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65, + 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB, + 0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9, + 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F, + 0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD, + 0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683, + 0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1, + 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7, + 0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5, + 0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, + 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79, + 0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F, + 0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D, + 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713, + 0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21, + 0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777, + 0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45, + 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB, + 0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9, + 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF, + 0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D, + } + +#if defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_4) || defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_8) || defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_16) + // beyond this point only relevant for Slicing-by-4, Slicing-by-8 and Slicing-by-16 + ,{ + 0x00000000,0x191B3141,0x32366282,0x2B2D53C3,0x646CC504,0x7D77F445,0x565AA786,0x4F4196C7, + 0xC8D98A08,0xD1C2BB49,0xFAEFE88A,0xE3F4D9CB,0xACB54F0C,0xB5AE7E4D,0x9E832D8E,0x87981CCF, + 0x4AC21251,0x53D92310,0x78F470D3,0x61EF4192,0x2EAED755,0x37B5E614,0x1C98B5D7,0x05838496, + 0x821B9859,0x9B00A918,0xB02DFADB,0xA936CB9A,0xE6775D5D,0xFF6C6C1C,0xD4413FDF,0xCD5A0E9E, + 0x958424A2,0x8C9F15E3,0xA7B24620,0xBEA97761,0xF1E8E1A6,0xE8F3D0E7,0xC3DE8324,0xDAC5B265, + 0x5D5DAEAA,0x44469FEB,0x6F6BCC28,0x7670FD69,0x39316BAE,0x202A5AEF,0x0B07092C,0x121C386D, + 0xDF4636F3,0xC65D07B2,0xED705471,0xF46B6530,0xBB2AF3F7,0xA231C2B6,0x891C9175,0x9007A034, + 0x179FBCFB,0x0E848DBA,0x25A9DE79,0x3CB2EF38,0x73F379FF,0x6AE848BE,0x41C51B7D,0x58DE2A3C, + 0xF0794F05,0xE9627E44,0xC24F2D87,0xDB541CC6,0x94158A01,0x8D0EBB40,0xA623E883,0xBF38D9C2, + 0x38A0C50D,0x21BBF44C,0x0A96A78F,0x138D96CE,0x5CCC0009,0x45D73148,0x6EFA628B,0x77E153CA, + 0xBABB5D54,0xA3A06C15,0x888D3FD6,0x91960E97,0xDED79850,0xC7CCA911,0xECE1FAD2,0xF5FACB93, + 0x7262D75C,0x6B79E61D,0x4054B5DE,0x594F849F,0x160E1258,0x0F152319,0x243870DA,0x3D23419B, + 0x65FD6BA7,0x7CE65AE6,0x57CB0925,0x4ED03864,0x0191AEA3,0x188A9FE2,0x33A7CC21,0x2ABCFD60, + 0xAD24E1AF,0xB43FD0EE,0x9F12832D,0x8609B26C,0xC94824AB,0xD05315EA,0xFB7E4629,0xE2657768, + 0x2F3F79F6,0x362448B7,0x1D091B74,0x04122A35,0x4B53BCF2,0x52488DB3,0x7965DE70,0x607EEF31, + 0xE7E6F3FE,0xFEFDC2BF,0xD5D0917C,0xCCCBA03D,0x838A36FA,0x9A9107BB,0xB1BC5478,0xA8A76539, + 0x3B83984B,0x2298A90A,0x09B5FAC9,0x10AECB88,0x5FEF5D4F,0x46F46C0E,0x6DD93FCD,0x74C20E8C, + 0xF35A1243,0xEA412302,0xC16C70C1,0xD8774180,0x9736D747,0x8E2DE606,0xA500B5C5,0xBC1B8484, + 0x71418A1A,0x685ABB5B,0x4377E898,0x5A6CD9D9,0x152D4F1E,0x0C367E5F,0x271B2D9C,0x3E001CDD, + 0xB9980012,0xA0833153,0x8BAE6290,0x92B553D1,0xDDF4C516,0xC4EFF457,0xEFC2A794,0xF6D996D5, + 0xAE07BCE9,0xB71C8DA8,0x9C31DE6B,0x852AEF2A,0xCA6B79ED,0xD37048AC,0xF85D1B6F,0xE1462A2E, + 0x66DE36E1,0x7FC507A0,0x54E85463,0x4DF36522,0x02B2F3E5,0x1BA9C2A4,0x30849167,0x299FA026, + 0xE4C5AEB8,0xFDDE9FF9,0xD6F3CC3A,0xCFE8FD7B,0x80A96BBC,0x99B25AFD,0xB29F093E,0xAB84387F, + 0x2C1C24B0,0x350715F1,0x1E2A4632,0x07317773,0x4870E1B4,0x516BD0F5,0x7A468336,0x635DB277, + 0xCBFAD74E,0xD2E1E60F,0xF9CCB5CC,0xE0D7848D,0xAF96124A,0xB68D230B,0x9DA070C8,0x84BB4189, + 0x03235D46,0x1A386C07,0x31153FC4,0x280E0E85,0x674F9842,0x7E54A903,0x5579FAC0,0x4C62CB81, + 0x8138C51F,0x9823F45E,0xB30EA79D,0xAA1596DC,0xE554001B,0xFC4F315A,0xD7626299,0xCE7953D8, + 0x49E14F17,0x50FA7E56,0x7BD72D95,0x62CC1CD4,0x2D8D8A13,0x3496BB52,0x1FBBE891,0x06A0D9D0, + 0x5E7EF3EC,0x4765C2AD,0x6C48916E,0x7553A02F,0x3A1236E8,0x230907A9,0x0824546A,0x113F652B, + 0x96A779E4,0x8FBC48A5,0xA4911B66,0xBD8A2A27,0xF2CBBCE0,0xEBD08DA1,0xC0FDDE62,0xD9E6EF23, + 0x14BCE1BD,0x0DA7D0FC,0x268A833F,0x3F91B27E,0x70D024B9,0x69CB15F8,0x42E6463B,0x5BFD777A, + 0xDC656BB5,0xC57E5AF4,0xEE530937,0xF7483876,0xB809AEB1,0xA1129FF0,0x8A3FCC33,0x9324FD72, + }, + + { + 0x00000000,0x01C26A37,0x0384D46E,0x0246BE59,0x0709A8DC,0x06CBC2EB,0x048D7CB2,0x054F1685, + 0x0E1351B8,0x0FD13B8F,0x0D9785D6,0x0C55EFE1,0x091AF964,0x08D89353,0x0A9E2D0A,0x0B5C473D, + 0x1C26A370,0x1DE4C947,0x1FA2771E,0x1E601D29,0x1B2F0BAC,0x1AED619B,0x18ABDFC2,0x1969B5F5, + 0x1235F2C8,0x13F798FF,0x11B126A6,0x10734C91,0x153C5A14,0x14FE3023,0x16B88E7A,0x177AE44D, + 0x384D46E0,0x398F2CD7,0x3BC9928E,0x3A0BF8B9,0x3F44EE3C,0x3E86840B,0x3CC03A52,0x3D025065, + 0x365E1758,0x379C7D6F,0x35DAC336,0x3418A901,0x3157BF84,0x3095D5B3,0x32D36BEA,0x331101DD, + 0x246BE590,0x25A98FA7,0x27EF31FE,0x262D5BC9,0x23624D4C,0x22A0277B,0x20E69922,0x2124F315, + 0x2A78B428,0x2BBADE1F,0x29FC6046,0x283E0A71,0x2D711CF4,0x2CB376C3,0x2EF5C89A,0x2F37A2AD, + 0x709A8DC0,0x7158E7F7,0x731E59AE,0x72DC3399,0x7793251C,0x76514F2B,0x7417F172,0x75D59B45, + 0x7E89DC78,0x7F4BB64F,0x7D0D0816,0x7CCF6221,0x798074A4,0x78421E93,0x7A04A0CA,0x7BC6CAFD, + 0x6CBC2EB0,0x6D7E4487,0x6F38FADE,0x6EFA90E9,0x6BB5866C,0x6A77EC5B,0x68315202,0x69F33835, + 0x62AF7F08,0x636D153F,0x612BAB66,0x60E9C151,0x65A6D7D4,0x6464BDE3,0x662203BA,0x67E0698D, + 0x48D7CB20,0x4915A117,0x4B531F4E,0x4A917579,0x4FDE63FC,0x4E1C09CB,0x4C5AB792,0x4D98DDA5, + 0x46C49A98,0x4706F0AF,0x45404EF6,0x448224C1,0x41CD3244,0x400F5873,0x4249E62A,0x438B8C1D, + 0x54F16850,0x55330267,0x5775BC3E,0x56B7D609,0x53F8C08C,0x523AAABB,0x507C14E2,0x51BE7ED5, + 0x5AE239E8,0x5B2053DF,0x5966ED86,0x58A487B1,0x5DEB9134,0x5C29FB03,0x5E6F455A,0x5FAD2F6D, + 0xE1351B80,0xE0F771B7,0xE2B1CFEE,0xE373A5D9,0xE63CB35C,0xE7FED96B,0xE5B86732,0xE47A0D05, + 0xEF264A38,0xEEE4200F,0xECA29E56,0xED60F461,0xE82FE2E4,0xE9ED88D3,0xEBAB368A,0xEA695CBD, + 0xFD13B8F0,0xFCD1D2C7,0xFE976C9E,0xFF5506A9,0xFA1A102C,0xFBD87A1B,0xF99EC442,0xF85CAE75, + 0xF300E948,0xF2C2837F,0xF0843D26,0xF1465711,0xF4094194,0xF5CB2BA3,0xF78D95FA,0xF64FFFCD, + 0xD9785D60,0xD8BA3757,0xDAFC890E,0xDB3EE339,0xDE71F5BC,0xDFB39F8B,0xDDF521D2,0xDC374BE5, + 0xD76B0CD8,0xD6A966EF,0xD4EFD8B6,0xD52DB281,0xD062A404,0xD1A0CE33,0xD3E6706A,0xD2241A5D, + 0xC55EFE10,0xC49C9427,0xC6DA2A7E,0xC7184049,0xC25756CC,0xC3953CFB,0xC1D382A2,0xC011E895, + 0xCB4DAFA8,0xCA8FC59F,0xC8C97BC6,0xC90B11F1,0xCC440774,0xCD866D43,0xCFC0D31A,0xCE02B92D, + 0x91AF9640,0x906DFC77,0x922B422E,0x93E92819,0x96A63E9C,0x976454AB,0x9522EAF2,0x94E080C5, + 0x9FBCC7F8,0x9E7EADCF,0x9C381396,0x9DFA79A1,0x98B56F24,0x99770513,0x9B31BB4A,0x9AF3D17D, + 0x8D893530,0x8C4B5F07,0x8E0DE15E,0x8FCF8B69,0x8A809DEC,0x8B42F7DB,0x89044982,0x88C623B5, + 0x839A6488,0x82580EBF,0x801EB0E6,0x81DCDAD1,0x8493CC54,0x8551A663,0x8717183A,0x86D5720D, + 0xA9E2D0A0,0xA820BA97,0xAA6604CE,0xABA46EF9,0xAEEB787C,0xAF29124B,0xAD6FAC12,0xACADC625, + 0xA7F18118,0xA633EB2F,0xA4755576,0xA5B73F41,0xA0F829C4,0xA13A43F3,0xA37CFDAA,0xA2BE979D, + 0xB5C473D0,0xB40619E7,0xB640A7BE,0xB782CD89,0xB2CDDB0C,0xB30FB13B,0xB1490F62,0xB08B6555, + 0xBBD72268,0xBA15485F,0xB853F606,0xB9919C31,0xBCDE8AB4,0xBD1CE083,0xBF5A5EDA,0xBE9834ED, + }, + + { + 0x00000000,0xB8BC6765,0xAA09C88B,0x12B5AFEE,0x8F629757,0x37DEF032,0x256B5FDC,0x9DD738B9, + 0xC5B428EF,0x7D084F8A,0x6FBDE064,0xD7018701,0x4AD6BFB8,0xF26AD8DD,0xE0DF7733,0x58631056, + 0x5019579F,0xE8A530FA,0xFA109F14,0x42ACF871,0xDF7BC0C8,0x67C7A7AD,0x75720843,0xCDCE6F26, + 0x95AD7F70,0x2D111815,0x3FA4B7FB,0x8718D09E,0x1ACFE827,0xA2738F42,0xB0C620AC,0x087A47C9, + 0xA032AF3E,0x188EC85B,0x0A3B67B5,0xB28700D0,0x2F503869,0x97EC5F0C,0x8559F0E2,0x3DE59787, + 0x658687D1,0xDD3AE0B4,0xCF8F4F5A,0x7733283F,0xEAE41086,0x525877E3,0x40EDD80D,0xF851BF68, + 0xF02BF8A1,0x48979FC4,0x5A22302A,0xE29E574F,0x7F496FF6,0xC7F50893,0xD540A77D,0x6DFCC018, + 0x359FD04E,0x8D23B72B,0x9F9618C5,0x272A7FA0,0xBAFD4719,0x0241207C,0x10F48F92,0xA848E8F7, + 0x9B14583D,0x23A83F58,0x311D90B6,0x89A1F7D3,0x1476CF6A,0xACCAA80F,0xBE7F07E1,0x06C36084, + 0x5EA070D2,0xE61C17B7,0xF4A9B859,0x4C15DF3C,0xD1C2E785,0x697E80E0,0x7BCB2F0E,0xC377486B, + 0xCB0D0FA2,0x73B168C7,0x6104C729,0xD9B8A04C,0x446F98F5,0xFCD3FF90,0xEE66507E,0x56DA371B, + 0x0EB9274D,0xB6054028,0xA4B0EFC6,0x1C0C88A3,0x81DBB01A,0x3967D77F,0x2BD27891,0x936E1FF4, + 0x3B26F703,0x839A9066,0x912F3F88,0x299358ED,0xB4446054,0x0CF80731,0x1E4DA8DF,0xA6F1CFBA, + 0xFE92DFEC,0x462EB889,0x549B1767,0xEC277002,0x71F048BB,0xC94C2FDE,0xDBF98030,0x6345E755, + 0x6B3FA09C,0xD383C7F9,0xC1366817,0x798A0F72,0xE45D37CB,0x5CE150AE,0x4E54FF40,0xF6E89825, + 0xAE8B8873,0x1637EF16,0x048240F8,0xBC3E279D,0x21E91F24,0x99557841,0x8BE0D7AF,0x335CB0CA, + 0xED59B63B,0x55E5D15E,0x47507EB0,0xFFEC19D5,0x623B216C,0xDA874609,0xC832E9E7,0x708E8E82, + 0x28ED9ED4,0x9051F9B1,0x82E4565F,0x3A58313A,0xA78F0983,0x1F336EE6,0x0D86C108,0xB53AA66D, + 0xBD40E1A4,0x05FC86C1,0x1749292F,0xAFF54E4A,0x322276F3,0x8A9E1196,0x982BBE78,0x2097D91D, + 0x78F4C94B,0xC048AE2E,0xD2FD01C0,0x6A4166A5,0xF7965E1C,0x4F2A3979,0x5D9F9697,0xE523F1F2, + 0x4D6B1905,0xF5D77E60,0xE762D18E,0x5FDEB6EB,0xC2098E52,0x7AB5E937,0x680046D9,0xD0BC21BC, + 0x88DF31EA,0x3063568F,0x22D6F961,0x9A6A9E04,0x07BDA6BD,0xBF01C1D8,0xADB46E36,0x15080953, + 0x1D724E9A,0xA5CE29FF,0xB77B8611,0x0FC7E174,0x9210D9CD,0x2AACBEA8,0x38191146,0x80A57623, + 0xD8C66675,0x607A0110,0x72CFAEFE,0xCA73C99B,0x57A4F122,0xEF189647,0xFDAD39A9,0x45115ECC, + 0x764DEE06,0xCEF18963,0xDC44268D,0x64F841E8,0xF92F7951,0x41931E34,0x5326B1DA,0xEB9AD6BF, + 0xB3F9C6E9,0x0B45A18C,0x19F00E62,0xA14C6907,0x3C9B51BE,0x842736DB,0x96929935,0x2E2EFE50, + 0x2654B999,0x9EE8DEFC,0x8C5D7112,0x34E11677,0xA9362ECE,0x118A49AB,0x033FE645,0xBB838120, + 0xE3E09176,0x5B5CF613,0x49E959FD,0xF1553E98,0x6C820621,0xD43E6144,0xC68BCEAA,0x7E37A9CF, + 0xD67F4138,0x6EC3265D,0x7C7689B3,0xC4CAEED6,0x591DD66F,0xE1A1B10A,0xF3141EE4,0x4BA87981, + 0x13CB69D7,0xAB770EB2,0xB9C2A15C,0x017EC639,0x9CA9FE80,0x241599E5,0x36A0360B,0x8E1C516E, + 0x866616A7,0x3EDA71C2,0x2C6FDE2C,0x94D3B949,0x090481F0,0xB1B8E695,0xA30D497B,0x1BB12E1E, + 0x43D23E48,0xFB6E592D,0xE9DBF6C3,0x516791A6,0xCCB0A91F,0x740CCE7A,0x66B96194,0xDE0506F1, + } +#endif // defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_4) || defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_8) || defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_16) +#if defined (CRC32_USE_LOOKUP_TABLE_SLICING_BY_8) || defined(CRC32_USE_LOOKUP_TABLE_SLICING_BY_16) + // beyond this point only relevant for Slicing-by-8 and Slicing-by-16 + ,{ + 0x00000000,0x3D6029B0,0x7AC05360,0x47A07AD0,0xF580A6C0,0xC8E08F70,0x8F40F5A0,0xB220DC10, + 0x30704BC1,0x0D106271,0x4AB018A1,0x77D03111,0xC5F0ED01,0xF890C4B1,0xBF30BE61,0x825097D1, + 0x60E09782,0x5D80BE32,0x1A20C4E2,0x2740ED52,0x95603142,0xA80018F2,0xEFA06222,0xD2C04B92, + 0x5090DC43,0x6DF0F5F3,0x2A508F23,0x1730A693,0xA5107A83,0x98705333,0xDFD029E3,0xE2B00053, + 0xC1C12F04,0xFCA106B4,0xBB017C64,0x866155D4,0x344189C4,0x0921A074,0x4E81DAA4,0x73E1F314, + 0xF1B164C5,0xCCD14D75,0x8B7137A5,0xB6111E15,0x0431C205,0x3951EBB5,0x7EF19165,0x4391B8D5, + 0xA121B886,0x9C419136,0xDBE1EBE6,0xE681C256,0x54A11E46,0x69C137F6,0x2E614D26,0x13016496, + 0x9151F347,0xAC31DAF7,0xEB91A027,0xD6F18997,0x64D15587,0x59B17C37,0x1E1106E7,0x23712F57, + 0x58F35849,0x659371F9,0x22330B29,0x1F532299,0xAD73FE89,0x9013D739,0xD7B3ADE9,0xEAD38459, + 0x68831388,0x55E33A38,0x124340E8,0x2F236958,0x9D03B548,0xA0639CF8,0xE7C3E628,0xDAA3CF98, + 0x3813CFCB,0x0573E67B,0x42D39CAB,0x7FB3B51B,0xCD93690B,0xF0F340BB,0xB7533A6B,0x8A3313DB, + 0x0863840A,0x3503ADBA,0x72A3D76A,0x4FC3FEDA,0xFDE322CA,0xC0830B7A,0x872371AA,0xBA43581A, + 0x9932774D,0xA4525EFD,0xE3F2242D,0xDE920D9D,0x6CB2D18D,0x51D2F83D,0x167282ED,0x2B12AB5D, + 0xA9423C8C,0x9422153C,0xD3826FEC,0xEEE2465C,0x5CC29A4C,0x61A2B3FC,0x2602C92C,0x1B62E09C, + 0xF9D2E0CF,0xC4B2C97F,0x8312B3AF,0xBE729A1F,0x0C52460F,0x31326FBF,0x7692156F,0x4BF23CDF, + 0xC9A2AB0E,0xF4C282BE,0xB362F86E,0x8E02D1DE,0x3C220DCE,0x0142247E,0x46E25EAE,0x7B82771E, + 0xB1E6B092,0x8C869922,0xCB26E3F2,0xF646CA42,0x44661652,0x79063FE2,0x3EA64532,0x03C66C82, + 0x8196FB53,0xBCF6D2E3,0xFB56A833,0xC6368183,0x74165D93,0x49767423,0x0ED60EF3,0x33B62743, + 0xD1062710,0xEC660EA0,0xABC67470,0x96A65DC0,0x248681D0,0x19E6A860,0x5E46D2B0,0x6326FB00, + 0xE1766CD1,0xDC164561,0x9BB63FB1,0xA6D61601,0x14F6CA11,0x2996E3A1,0x6E369971,0x5356B0C1, + 0x70279F96,0x4D47B626,0x0AE7CCF6,0x3787E546,0x85A73956,0xB8C710E6,0xFF676A36,0xC2074386, + 0x4057D457,0x7D37FDE7,0x3A978737,0x07F7AE87,0xB5D77297,0x88B75B27,0xCF1721F7,0xF2770847, + 0x10C70814,0x2DA721A4,0x6A075B74,0x576772C4,0xE547AED4,0xD8278764,0x9F87FDB4,0xA2E7D404, + 0x20B743D5,0x1DD76A65,0x5A7710B5,0x67173905,0xD537E515,0xE857CCA5,0xAFF7B675,0x92979FC5, + 0xE915E8DB,0xD475C16B,0x93D5BBBB,0xAEB5920B,0x1C954E1B,0x21F567AB,0x66551D7B,0x5B3534CB, + 0xD965A31A,0xE4058AAA,0xA3A5F07A,0x9EC5D9CA,0x2CE505DA,0x11852C6A,0x562556BA,0x6B457F0A, + 0x89F57F59,0xB49556E9,0xF3352C39,0xCE550589,0x7C75D999,0x4115F029,0x06B58AF9,0x3BD5A349, + 0xB9853498,0x84E51D28,0xC34567F8,0xFE254E48,0x4C059258,0x7165BBE8,0x36C5C138,0x0BA5E888, + 0x28D4C7DF,0x15B4EE6F,0x521494BF,0x6F74BD0F,0xDD54611F,0xE03448AF,0xA794327F,0x9AF41BCF, + 0x18A48C1E,0x25C4A5AE,0x6264DF7E,0x5F04F6CE,0xED242ADE,0xD044036E,0x97E479BE,0xAA84500E, + 0x4834505D,0x755479ED,0x32F4033D,0x0F942A8D,0xBDB4F69D,0x80D4DF2D,0xC774A5FD,0xFA148C4D, + 0x78441B9C,0x4524322C,0x028448FC,0x3FE4614C,0x8DC4BD5C,0xB0A494EC,0xF704EE3C,0xCA64C78C, + }, + + { + 0x00000000,0xCB5CD3A5,0x4DC8A10B,0x869472AE,0x9B914216,0x50CD91B3,0xD659E31D,0x1D0530B8, + 0xEC53826D,0x270F51C8,0xA19B2366,0x6AC7F0C3,0x77C2C07B,0xBC9E13DE,0x3A0A6170,0xF156B2D5, + 0x03D6029B,0xC88AD13E,0x4E1EA390,0x85427035,0x9847408D,0x531B9328,0xD58FE186,0x1ED33223, + 0xEF8580F6,0x24D95353,0xA24D21FD,0x6911F258,0x7414C2E0,0xBF481145,0x39DC63EB,0xF280B04E, + 0x07AC0536,0xCCF0D693,0x4A64A43D,0x81387798,0x9C3D4720,0x57619485,0xD1F5E62B,0x1AA9358E, + 0xEBFF875B,0x20A354FE,0xA6372650,0x6D6BF5F5,0x706EC54D,0xBB3216E8,0x3DA66446,0xF6FAB7E3, + 0x047A07AD,0xCF26D408,0x49B2A6A6,0x82EE7503,0x9FEB45BB,0x54B7961E,0xD223E4B0,0x197F3715, + 0xE82985C0,0x23755665,0xA5E124CB,0x6EBDF76E,0x73B8C7D6,0xB8E41473,0x3E7066DD,0xF52CB578, + 0x0F580A6C,0xC404D9C9,0x4290AB67,0x89CC78C2,0x94C9487A,0x5F959BDF,0xD901E971,0x125D3AD4, + 0xE30B8801,0x28575BA4,0xAEC3290A,0x659FFAAF,0x789ACA17,0xB3C619B2,0x35526B1C,0xFE0EB8B9, + 0x0C8E08F7,0xC7D2DB52,0x4146A9FC,0x8A1A7A59,0x971F4AE1,0x5C439944,0xDAD7EBEA,0x118B384F, + 0xE0DD8A9A,0x2B81593F,0xAD152B91,0x6649F834,0x7B4CC88C,0xB0101B29,0x36846987,0xFDD8BA22, + 0x08F40F5A,0xC3A8DCFF,0x453CAE51,0x8E607DF4,0x93654D4C,0x58399EE9,0xDEADEC47,0x15F13FE2, + 0xE4A78D37,0x2FFB5E92,0xA96F2C3C,0x6233FF99,0x7F36CF21,0xB46A1C84,0x32FE6E2A,0xF9A2BD8F, + 0x0B220DC1,0xC07EDE64,0x46EAACCA,0x8DB67F6F,0x90B34FD7,0x5BEF9C72,0xDD7BEEDC,0x16273D79, + 0xE7718FAC,0x2C2D5C09,0xAAB92EA7,0x61E5FD02,0x7CE0CDBA,0xB7BC1E1F,0x31286CB1,0xFA74BF14, + 0x1EB014D8,0xD5ECC77D,0x5378B5D3,0x98246676,0x852156CE,0x4E7D856B,0xC8E9F7C5,0x03B52460, + 0xF2E396B5,0x39BF4510,0xBF2B37BE,0x7477E41B,0x6972D4A3,0xA22E0706,0x24BA75A8,0xEFE6A60D, + 0x1D661643,0xD63AC5E6,0x50AEB748,0x9BF264ED,0x86F75455,0x4DAB87F0,0xCB3FF55E,0x006326FB, + 0xF135942E,0x3A69478B,0xBCFD3525,0x77A1E680,0x6AA4D638,0xA1F8059D,0x276C7733,0xEC30A496, + 0x191C11EE,0xD240C24B,0x54D4B0E5,0x9F886340,0x828D53F8,0x49D1805D,0xCF45F2F3,0x04192156, + 0xF54F9383,0x3E134026,0xB8873288,0x73DBE12D,0x6EDED195,0xA5820230,0x2316709E,0xE84AA33B, + 0x1ACA1375,0xD196C0D0,0x5702B27E,0x9C5E61DB,0x815B5163,0x4A0782C6,0xCC93F068,0x07CF23CD, + 0xF6999118,0x3DC542BD,0xBB513013,0x700DE3B6,0x6D08D30E,0xA65400AB,0x20C07205,0xEB9CA1A0, + 0x11E81EB4,0xDAB4CD11,0x5C20BFBF,0x977C6C1A,0x8A795CA2,0x41258F07,0xC7B1FDA9,0x0CED2E0C, + 0xFDBB9CD9,0x36E74F7C,0xB0733DD2,0x7B2FEE77,0x662ADECF,0xAD760D6A,0x2BE27FC4,0xE0BEAC61, + 0x123E1C2F,0xD962CF8A,0x5FF6BD24,0x94AA6E81,0x89AF5E39,0x42F38D9C,0xC467FF32,0x0F3B2C97, + 0xFE6D9E42,0x35314DE7,0xB3A53F49,0x78F9ECEC,0x65FCDC54,0xAEA00FF1,0x28347D5F,0xE368AEFA, + 0x16441B82,0xDD18C827,0x5B8CBA89,0x90D0692C,0x8DD55994,0x46898A31,0xC01DF89F,0x0B412B3A, + 0xFA1799EF,0x314B4A4A,0xB7DF38E4,0x7C83EB41,0x6186DBF9,0xAADA085C,0x2C4E7AF2,0xE712A957, + 0x15921919,0xDECECABC,0x585AB812,0x93066BB7,0x8E035B0F,0x455F88AA,0xC3CBFA04,0x089729A1, + 0xF9C19B74,0x329D48D1,0xB4093A7F,0x7F55E9DA,0x6250D962,0xA90C0AC7,0x2F987869,0xE4C4ABCC, + }, + + { + 0x00000000,0xA6770BB4,0x979F1129,0x31E81A9D,0xF44F2413,0x52382FA7,0x63D0353A,0xC5A73E8E, + 0x33EF4E67,0x959845D3,0xA4705F4E,0x020754FA,0xC7A06A74,0x61D761C0,0x503F7B5D,0xF64870E9, + 0x67DE9CCE,0xC1A9977A,0xF0418DE7,0x56368653,0x9391B8DD,0x35E6B369,0x040EA9F4,0xA279A240, + 0x5431D2A9,0xF246D91D,0xC3AEC380,0x65D9C834,0xA07EF6BA,0x0609FD0E,0x37E1E793,0x9196EC27, + 0xCFBD399C,0x69CA3228,0x582228B5,0xFE552301,0x3BF21D8F,0x9D85163B,0xAC6D0CA6,0x0A1A0712, + 0xFC5277FB,0x5A257C4F,0x6BCD66D2,0xCDBA6D66,0x081D53E8,0xAE6A585C,0x9F8242C1,0x39F54975, + 0xA863A552,0x0E14AEE6,0x3FFCB47B,0x998BBFCF,0x5C2C8141,0xFA5B8AF5,0xCBB39068,0x6DC49BDC, + 0x9B8CEB35,0x3DFBE081,0x0C13FA1C,0xAA64F1A8,0x6FC3CF26,0xC9B4C492,0xF85CDE0F,0x5E2BD5BB, + 0x440B7579,0xE27C7ECD,0xD3946450,0x75E36FE4,0xB044516A,0x16335ADE,0x27DB4043,0x81AC4BF7, + 0x77E43B1E,0xD19330AA,0xE07B2A37,0x460C2183,0x83AB1F0D,0x25DC14B9,0x14340E24,0xB2430590, + 0x23D5E9B7,0x85A2E203,0xB44AF89E,0x123DF32A,0xD79ACDA4,0x71EDC610,0x4005DC8D,0xE672D739, + 0x103AA7D0,0xB64DAC64,0x87A5B6F9,0x21D2BD4D,0xE47583C3,0x42028877,0x73EA92EA,0xD59D995E, + 0x8BB64CE5,0x2DC14751,0x1C295DCC,0xBA5E5678,0x7FF968F6,0xD98E6342,0xE86679DF,0x4E11726B, + 0xB8590282,0x1E2E0936,0x2FC613AB,0x89B1181F,0x4C162691,0xEA612D25,0xDB8937B8,0x7DFE3C0C, + 0xEC68D02B,0x4A1FDB9F,0x7BF7C102,0xDD80CAB6,0x1827F438,0xBE50FF8C,0x8FB8E511,0x29CFEEA5, + 0xDF879E4C,0x79F095F8,0x48188F65,0xEE6F84D1,0x2BC8BA5F,0x8DBFB1EB,0xBC57AB76,0x1A20A0C2, + 0x8816EAF2,0x2E61E146,0x1F89FBDB,0xB9FEF06F,0x7C59CEE1,0xDA2EC555,0xEBC6DFC8,0x4DB1D47C, + 0xBBF9A495,0x1D8EAF21,0x2C66B5BC,0x8A11BE08,0x4FB68086,0xE9C18B32,0xD82991AF,0x7E5E9A1B, + 0xEFC8763C,0x49BF7D88,0x78576715,0xDE206CA1,0x1B87522F,0xBDF0599B,0x8C184306,0x2A6F48B2, + 0xDC27385B,0x7A5033EF,0x4BB82972,0xEDCF22C6,0x28681C48,0x8E1F17FC,0xBFF70D61,0x198006D5, + 0x47ABD36E,0xE1DCD8DA,0xD034C247,0x7643C9F3,0xB3E4F77D,0x1593FCC9,0x247BE654,0x820CEDE0, + 0x74449D09,0xD23396BD,0xE3DB8C20,0x45AC8794,0x800BB91A,0x267CB2AE,0x1794A833,0xB1E3A387, + 0x20754FA0,0x86024414,0xB7EA5E89,0x119D553D,0xD43A6BB3,0x724D6007,0x43A57A9A,0xE5D2712E, + 0x139A01C7,0xB5ED0A73,0x840510EE,0x22721B5A,0xE7D525D4,0x41A22E60,0x704A34FD,0xD63D3F49, + 0xCC1D9F8B,0x6A6A943F,0x5B828EA2,0xFDF58516,0x3852BB98,0x9E25B02C,0xAFCDAAB1,0x09BAA105, + 0xFFF2D1EC,0x5985DA58,0x686DC0C5,0xCE1ACB71,0x0BBDF5FF,0xADCAFE4B,0x9C22E4D6,0x3A55EF62, + 0xABC30345,0x0DB408F1,0x3C5C126C,0x9A2B19D8,0x5F8C2756,0xF9FB2CE2,0xC813367F,0x6E643DCB, + 0x982C4D22,0x3E5B4696,0x0FB35C0B,0xA9C457BF,0x6C636931,0xCA146285,0xFBFC7818,0x5D8B73AC, + 0x03A0A617,0xA5D7ADA3,0x943FB73E,0x3248BC8A,0xF7EF8204,0x519889B0,0x6070932D,0xC6079899, + 0x304FE870,0x9638E3C4,0xA7D0F959,0x01A7F2ED,0xC400CC63,0x6277C7D7,0x539FDD4A,0xF5E8D6FE, + 0x647E3AD9,0xC209316D,0xF3E12BF0,0x55962044,0x90311ECA,0x3646157E,0x07AE0FE3,0xA1D90457, + 0x579174BE,0xF1E67F0A,0xC00E6597,0x66796E23,0xA3DE50AD,0x05A95B19,0x34414184,0x92364A30, + }, + + { + 0x00000000,0xCCAA009E,0x4225077D,0x8E8F07E3,0x844A0EFA,0x48E00E64,0xC66F0987,0x0AC50919, + 0xD3E51BB5,0x1F4F1B2B,0x91C01CC8,0x5D6A1C56,0x57AF154F,0x9B0515D1,0x158A1232,0xD92012AC, + 0x7CBB312B,0xB01131B5,0x3E9E3656,0xF23436C8,0xF8F13FD1,0x345B3F4F,0xBAD438AC,0x767E3832, + 0xAF5E2A9E,0x63F42A00,0xED7B2DE3,0x21D12D7D,0x2B142464,0xE7BE24FA,0x69312319,0xA59B2387, + 0xF9766256,0x35DC62C8,0xBB53652B,0x77F965B5,0x7D3C6CAC,0xB1966C32,0x3F196BD1,0xF3B36B4F, + 0x2A9379E3,0xE639797D,0x68B67E9E,0xA41C7E00,0xAED97719,0x62737787,0xECFC7064,0x205670FA, + 0x85CD537D,0x496753E3,0xC7E85400,0x0B42549E,0x01875D87,0xCD2D5D19,0x43A25AFA,0x8F085A64, + 0x562848C8,0x9A824856,0x140D4FB5,0xD8A74F2B,0xD2624632,0x1EC846AC,0x9047414F,0x5CED41D1, + 0x299DC2ED,0xE537C273,0x6BB8C590,0xA712C50E,0xADD7CC17,0x617DCC89,0xEFF2CB6A,0x2358CBF4, + 0xFA78D958,0x36D2D9C6,0xB85DDE25,0x74F7DEBB,0x7E32D7A2,0xB298D73C,0x3C17D0DF,0xF0BDD041, + 0x5526F3C6,0x998CF358,0x1703F4BB,0xDBA9F425,0xD16CFD3C,0x1DC6FDA2,0x9349FA41,0x5FE3FADF, + 0x86C3E873,0x4A69E8ED,0xC4E6EF0E,0x084CEF90,0x0289E689,0xCE23E617,0x40ACE1F4,0x8C06E16A, + 0xD0EBA0BB,0x1C41A025,0x92CEA7C6,0x5E64A758,0x54A1AE41,0x980BAEDF,0x1684A93C,0xDA2EA9A2, + 0x030EBB0E,0xCFA4BB90,0x412BBC73,0x8D81BCED,0x8744B5F4,0x4BEEB56A,0xC561B289,0x09CBB217, + 0xAC509190,0x60FA910E,0xEE7596ED,0x22DF9673,0x281A9F6A,0xE4B09FF4,0x6A3F9817,0xA6959889, + 0x7FB58A25,0xB31F8ABB,0x3D908D58,0xF13A8DC6,0xFBFF84DF,0x37558441,0xB9DA83A2,0x7570833C, + 0x533B85DA,0x9F918544,0x111E82A7,0xDDB48239,0xD7718B20,0x1BDB8BBE,0x95548C5D,0x59FE8CC3, + 0x80DE9E6F,0x4C749EF1,0xC2FB9912,0x0E51998C,0x04949095,0xC83E900B,0x46B197E8,0x8A1B9776, + 0x2F80B4F1,0xE32AB46F,0x6DA5B38C,0xA10FB312,0xABCABA0B,0x6760BA95,0xE9EFBD76,0x2545BDE8, + 0xFC65AF44,0x30CFAFDA,0xBE40A839,0x72EAA8A7,0x782FA1BE,0xB485A120,0x3A0AA6C3,0xF6A0A65D, + 0xAA4DE78C,0x66E7E712,0xE868E0F1,0x24C2E06F,0x2E07E976,0xE2ADE9E8,0x6C22EE0B,0xA088EE95, + 0x79A8FC39,0xB502FCA7,0x3B8DFB44,0xF727FBDA,0xFDE2F2C3,0x3148F25D,0xBFC7F5BE,0x736DF520, + 0xD6F6D6A7,0x1A5CD639,0x94D3D1DA,0x5879D144,0x52BCD85D,0x9E16D8C3,0x1099DF20,0xDC33DFBE, + 0x0513CD12,0xC9B9CD8C,0x4736CA6F,0x8B9CCAF1,0x8159C3E8,0x4DF3C376,0xC37CC495,0x0FD6C40B, + 0x7AA64737,0xB60C47A9,0x3883404A,0xF42940D4,0xFEEC49CD,0x32464953,0xBCC94EB0,0x70634E2E, + 0xA9435C82,0x65E95C1C,0xEB665BFF,0x27CC5B61,0x2D095278,0xE1A352E6,0x6F2C5505,0xA386559B, + 0x061D761C,0xCAB77682,0x44387161,0x889271FF,0x825778E6,0x4EFD7878,0xC0727F9B,0x0CD87F05, + 0xD5F86DA9,0x19526D37,0x97DD6AD4,0x5B776A4A,0x51B26353,0x9D1863CD,0x1397642E,0xDF3D64B0, + 0x83D02561,0x4F7A25FF,0xC1F5221C,0x0D5F2282,0x079A2B9B,0xCB302B05,0x45BF2CE6,0x89152C78, + 0x50353ED4,0x9C9F3E4A,0x121039A9,0xDEBA3937,0xD47F302E,0x18D530B0,0x965A3753,0x5AF037CD, + 0xFF6B144A,0x33C114D4,0xBD4E1337,0x71E413A9,0x7B211AB0,0xB78B1A2E,0x39041DCD,0xF5AE1D53, + 0x2C8E0FFF,0xE0240F61,0x6EAB0882,0xA201081C,0xA8C40105,0x646E019B,0xEAE10678,0x264B06E6, + } +#endif // CRC32_USE_LOOKUP_TABLE_SLICING_BY_8 || CRC32_USE_LOOKUP_TABLE_SLICING_BY_16 +#ifdef CRC32_USE_LOOKUP_TABLE_SLICING_BY_16 + // beyond this point only relevant for Slicing-by-16 + ,{ + 0x00000000,0x177B1443,0x2EF62886,0x398D3CC5,0x5DEC510C,0x4A97454F,0x731A798A,0x64616DC9, + 0xBBD8A218,0xACA3B65B,0x952E8A9E,0x82559EDD,0xE634F314,0xF14FE757,0xC8C2DB92,0xDFB9CFD1, + 0xACC04271,0xBBBB5632,0x82366AF7,0x954D7EB4,0xF12C137D,0xE657073E,0xDFDA3BFB,0xC8A12FB8, + 0x1718E069,0x0063F42A,0x39EEC8EF,0x2E95DCAC,0x4AF4B165,0x5D8FA526,0x640299E3,0x73798DA0, + 0x82F182A3,0x958A96E0,0xAC07AA25,0xBB7CBE66,0xDF1DD3AF,0xC866C7EC,0xF1EBFB29,0xE690EF6A, + 0x392920BB,0x2E5234F8,0x17DF083D,0x00A41C7E,0x64C571B7,0x73BE65F4,0x4A335931,0x5D484D72, + 0x2E31C0D2,0x394AD491,0x00C7E854,0x17BCFC17,0x73DD91DE,0x64A6859D,0x5D2BB958,0x4A50AD1B, + 0x95E962CA,0x82927689,0xBB1F4A4C,0xAC645E0F,0xC80533C6,0xDF7E2785,0xE6F31B40,0xF1880F03, + 0xDE920307,0xC9E91744,0xF0642B81,0xE71F3FC2,0x837E520B,0x94054648,0xAD887A8D,0xBAF36ECE, + 0x654AA11F,0x7231B55C,0x4BBC8999,0x5CC79DDA,0x38A6F013,0x2FDDE450,0x1650D895,0x012BCCD6, + 0x72524176,0x65295535,0x5CA469F0,0x4BDF7DB3,0x2FBE107A,0x38C50439,0x014838FC,0x16332CBF, + 0xC98AE36E,0xDEF1F72D,0xE77CCBE8,0xF007DFAB,0x9466B262,0x831DA621,0xBA909AE4,0xADEB8EA7, + 0x5C6381A4,0x4B1895E7,0x7295A922,0x65EEBD61,0x018FD0A8,0x16F4C4EB,0x2F79F82E,0x3802EC6D, + 0xE7BB23BC,0xF0C037FF,0xC94D0B3A,0xDE361F79,0xBA5772B0,0xAD2C66F3,0x94A15A36,0x83DA4E75, + 0xF0A3C3D5,0xE7D8D796,0xDE55EB53,0xC92EFF10,0xAD4F92D9,0xBA34869A,0x83B9BA5F,0x94C2AE1C, + 0x4B7B61CD,0x5C00758E,0x658D494B,0x72F65D08,0x169730C1,0x01EC2482,0x38611847,0x2F1A0C04, + 0x6655004F,0x712E140C,0x48A328C9,0x5FD83C8A,0x3BB95143,0x2CC24500,0x154F79C5,0x02346D86, + 0xDD8DA257,0xCAF6B614,0xF37B8AD1,0xE4009E92,0x8061F35B,0x971AE718,0xAE97DBDD,0xB9ECCF9E, + 0xCA95423E,0xDDEE567D,0xE4636AB8,0xF3187EFB,0x97791332,0x80020771,0xB98F3BB4,0xAEF42FF7, + 0x714DE026,0x6636F465,0x5FBBC8A0,0x48C0DCE3,0x2CA1B12A,0x3BDAA569,0x025799AC,0x152C8DEF, + 0xE4A482EC,0xF3DF96AF,0xCA52AA6A,0xDD29BE29,0xB948D3E0,0xAE33C7A3,0x97BEFB66,0x80C5EF25, + 0x5F7C20F4,0x480734B7,0x718A0872,0x66F11C31,0x029071F8,0x15EB65BB,0x2C66597E,0x3B1D4D3D, + 0x4864C09D,0x5F1FD4DE,0x6692E81B,0x71E9FC58,0x15889191,0x02F385D2,0x3B7EB917,0x2C05AD54, + 0xF3BC6285,0xE4C776C6,0xDD4A4A03,0xCA315E40,0xAE503389,0xB92B27CA,0x80A61B0F,0x97DD0F4C, + 0xB8C70348,0xAFBC170B,0x96312BCE,0x814A3F8D,0xE52B5244,0xF2504607,0xCBDD7AC2,0xDCA66E81, + 0x031FA150,0x1464B513,0x2DE989D6,0x3A929D95,0x5EF3F05C,0x4988E41F,0x7005D8DA,0x677ECC99, + 0x14074139,0x037C557A,0x3AF169BF,0x2D8A7DFC,0x49EB1035,0x5E900476,0x671D38B3,0x70662CF0, + 0xAFDFE321,0xB8A4F762,0x8129CBA7,0x9652DFE4,0xF233B22D,0xE548A66E,0xDCC59AAB,0xCBBE8EE8, + 0x3A3681EB,0x2D4D95A8,0x14C0A96D,0x03BBBD2E,0x67DAD0E7,0x70A1C4A4,0x492CF861,0x5E57EC22, + 0x81EE23F3,0x969537B0,0xAF180B75,0xB8631F36,0xDC0272FF,0xCB7966BC,0xF2F45A79,0xE58F4E3A, + 0x96F6C39A,0x818DD7D9,0xB800EB1C,0xAF7BFF5F,0xCB1A9296,0xDC6186D5,0xE5ECBA10,0xF297AE53, + 0x2D2E6182,0x3A5575C1,0x03D84904,0x14A35D47,0x70C2308E,0x67B924CD,0x5E341808,0x494F0C4B, + }, + + { + 0x00000000,0xEFC26B3E,0x04F5D03D,0xEB37BB03,0x09EBA07A,0xE629CB44,0x0D1E7047,0xE2DC1B79, + 0x13D740F4,0xFC152BCA,0x172290C9,0xF8E0FBF7,0x1A3CE08E,0xF5FE8BB0,0x1EC930B3,0xF10B5B8D, + 0x27AE81E8,0xC86CEAD6,0x235B51D5,0xCC993AEB,0x2E452192,0xC1874AAC,0x2AB0F1AF,0xC5729A91, + 0x3479C11C,0xDBBBAA22,0x308C1121,0xDF4E7A1F,0x3D926166,0xD2500A58,0x3967B15B,0xD6A5DA65, + 0x4F5D03D0,0xA09F68EE,0x4BA8D3ED,0xA46AB8D3,0x46B6A3AA,0xA974C894,0x42437397,0xAD8118A9, + 0x5C8A4324,0xB348281A,0x587F9319,0xB7BDF827,0x5561E35E,0xBAA38860,0x51943363,0xBE56585D, + 0x68F38238,0x8731E906,0x6C065205,0x83C4393B,0x61182242,0x8EDA497C,0x65EDF27F,0x8A2F9941, + 0x7B24C2CC,0x94E6A9F2,0x7FD112F1,0x901379CF,0x72CF62B6,0x9D0D0988,0x763AB28B,0x99F8D9B5, + 0x9EBA07A0,0x71786C9E,0x9A4FD79D,0x758DBCA3,0x9751A7DA,0x7893CCE4,0x93A477E7,0x7C661CD9, + 0x8D6D4754,0x62AF2C6A,0x89989769,0x665AFC57,0x8486E72E,0x6B448C10,0x80733713,0x6FB15C2D, + 0xB9148648,0x56D6ED76,0xBDE15675,0x52233D4B,0xB0FF2632,0x5F3D4D0C,0xB40AF60F,0x5BC89D31, + 0xAAC3C6BC,0x4501AD82,0xAE361681,0x41F47DBF,0xA32866C6,0x4CEA0DF8,0xA7DDB6FB,0x481FDDC5, + 0xD1E70470,0x3E256F4E,0xD512D44D,0x3AD0BF73,0xD80CA40A,0x37CECF34,0xDCF97437,0x333B1F09, + 0xC2304484,0x2DF22FBA,0xC6C594B9,0x2907FF87,0xCBDBE4FE,0x24198FC0,0xCF2E34C3,0x20EC5FFD, + 0xF6498598,0x198BEEA6,0xF2BC55A5,0x1D7E3E9B,0xFFA225E2,0x10604EDC,0xFB57F5DF,0x14959EE1, + 0xE59EC56C,0x0A5CAE52,0xE16B1551,0x0EA97E6F,0xEC756516,0x03B70E28,0xE880B52B,0x0742DE15, + 0xE6050901,0x09C7623F,0xE2F0D93C,0x0D32B202,0xEFEEA97B,0x002CC245,0xEB1B7946,0x04D91278, + 0xF5D249F5,0x1A1022CB,0xF12799C8,0x1EE5F2F6,0xFC39E98F,0x13FB82B1,0xF8CC39B2,0x170E528C, + 0xC1AB88E9,0x2E69E3D7,0xC55E58D4,0x2A9C33EA,0xC8402893,0x278243AD,0xCCB5F8AE,0x23779390, + 0xD27CC81D,0x3DBEA323,0xD6891820,0x394B731E,0xDB976867,0x34550359,0xDF62B85A,0x30A0D364, + 0xA9580AD1,0x469A61EF,0xADADDAEC,0x426FB1D2,0xA0B3AAAB,0x4F71C195,0xA4467A96,0x4B8411A8, + 0xBA8F4A25,0x554D211B,0xBE7A9A18,0x51B8F126,0xB364EA5F,0x5CA68161,0xB7913A62,0x5853515C, + 0x8EF68B39,0x6134E007,0x8A035B04,0x65C1303A,0x871D2B43,0x68DF407D,0x83E8FB7E,0x6C2A9040, + 0x9D21CBCD,0x72E3A0F3,0x99D41BF0,0x761670CE,0x94CA6BB7,0x7B080089,0x903FBB8A,0x7FFDD0B4, + 0x78BF0EA1,0x977D659F,0x7C4ADE9C,0x9388B5A2,0x7154AEDB,0x9E96C5E5,0x75A17EE6,0x9A6315D8, + 0x6B684E55,0x84AA256B,0x6F9D9E68,0x805FF556,0x6283EE2F,0x8D418511,0x66763E12,0x89B4552C, + 0x5F118F49,0xB0D3E477,0x5BE45F74,0xB426344A,0x56FA2F33,0xB938440D,0x520FFF0E,0xBDCD9430, + 0x4CC6CFBD,0xA304A483,0x48331F80,0xA7F174BE,0x452D6FC7,0xAAEF04F9,0x41D8BFFA,0xAE1AD4C4, + 0x37E20D71,0xD820664F,0x3317DD4C,0xDCD5B672,0x3E09AD0B,0xD1CBC635,0x3AFC7D36,0xD53E1608, + 0x24354D85,0xCBF726BB,0x20C09DB8,0xCF02F686,0x2DDEEDFF,0xC21C86C1,0x292B3DC2,0xC6E956FC, + 0x104C8C99,0xFF8EE7A7,0x14B95CA4,0xFB7B379A,0x19A72CE3,0xF66547DD,0x1D52FCDE,0xF29097E0, + 0x039BCC6D,0xEC59A753,0x076E1C50,0xE8AC776E,0x0A706C17,0xE5B20729,0x0E85BC2A,0xE147D714, + }, + + { + 0x00000000,0xC18EDFC0,0x586CB9C1,0x99E26601,0xB0D97382,0x7157AC42,0xE8B5CA43,0x293B1583, + 0xBAC3E145,0x7B4D3E85,0xE2AF5884,0x23218744,0x0A1A92C7,0xCB944D07,0x52762B06,0x93F8F4C6, + 0xAEF6C4CB,0x6F781B0B,0xF69A7D0A,0x3714A2CA,0x1E2FB749,0xDFA16889,0x46430E88,0x87CDD148, + 0x1435258E,0xD5BBFA4E,0x4C599C4F,0x8DD7438F,0xA4EC560C,0x656289CC,0xFC80EFCD,0x3D0E300D, + 0x869C8FD7,0x47125017,0xDEF03616,0x1F7EE9D6,0x3645FC55,0xF7CB2395,0x6E294594,0xAFA79A54, + 0x3C5F6E92,0xFDD1B152,0x6433D753,0xA5BD0893,0x8C861D10,0x4D08C2D0,0xD4EAA4D1,0x15647B11, + 0x286A4B1C,0xE9E494DC,0x7006F2DD,0xB1882D1D,0x98B3389E,0x593DE75E,0xC0DF815F,0x01515E9F, + 0x92A9AA59,0x53277599,0xCAC51398,0x0B4BCC58,0x2270D9DB,0xE3FE061B,0x7A1C601A,0xBB92BFDA, + 0xD64819EF,0x17C6C62F,0x8E24A02E,0x4FAA7FEE,0x66916A6D,0xA71FB5AD,0x3EFDD3AC,0xFF730C6C, + 0x6C8BF8AA,0xAD05276A,0x34E7416B,0xF5699EAB,0xDC528B28,0x1DDC54E8,0x843E32E9,0x45B0ED29, + 0x78BEDD24,0xB93002E4,0x20D264E5,0xE15CBB25,0xC867AEA6,0x09E97166,0x900B1767,0x5185C8A7, + 0xC27D3C61,0x03F3E3A1,0x9A1185A0,0x5B9F5A60,0x72A44FE3,0xB32A9023,0x2AC8F622,0xEB4629E2, + 0x50D49638,0x915A49F8,0x08B82FF9,0xC936F039,0xE00DE5BA,0x21833A7A,0xB8615C7B,0x79EF83BB, + 0xEA17777D,0x2B99A8BD,0xB27BCEBC,0x73F5117C,0x5ACE04FF,0x9B40DB3F,0x02A2BD3E,0xC32C62FE, + 0xFE2252F3,0x3FAC8D33,0xA64EEB32,0x67C034F2,0x4EFB2171,0x8F75FEB1,0x169798B0,0xD7194770, + 0x44E1B3B6,0x856F6C76,0x1C8D0A77,0xDD03D5B7,0xF438C034,0x35B61FF4,0xAC5479F5,0x6DDAA635, + 0x77E1359F,0xB66FEA5F,0x2F8D8C5E,0xEE03539E,0xC738461D,0x06B699DD,0x9F54FFDC,0x5EDA201C, + 0xCD22D4DA,0x0CAC0B1A,0x954E6D1B,0x54C0B2DB,0x7DFBA758,0xBC757898,0x25971E99,0xE419C159, + 0xD917F154,0x18992E94,0x817B4895,0x40F59755,0x69CE82D6,0xA8405D16,0x31A23B17,0xF02CE4D7, + 0x63D41011,0xA25ACFD1,0x3BB8A9D0,0xFA367610,0xD30D6393,0x1283BC53,0x8B61DA52,0x4AEF0592, + 0xF17DBA48,0x30F36588,0xA9110389,0x689FDC49,0x41A4C9CA,0x802A160A,0x19C8700B,0xD846AFCB, + 0x4BBE5B0D,0x8A3084CD,0x13D2E2CC,0xD25C3D0C,0xFB67288F,0x3AE9F74F,0xA30B914E,0x62854E8E, + 0x5F8B7E83,0x9E05A143,0x07E7C742,0xC6691882,0xEF520D01,0x2EDCD2C1,0xB73EB4C0,0x76B06B00, + 0xE5489FC6,0x24C64006,0xBD242607,0x7CAAF9C7,0x5591EC44,0x941F3384,0x0DFD5585,0xCC738A45, + 0xA1A92C70,0x6027F3B0,0xF9C595B1,0x384B4A71,0x11705FF2,0xD0FE8032,0x491CE633,0x889239F3, + 0x1B6ACD35,0xDAE412F5,0x430674F4,0x8288AB34,0xABB3BEB7,0x6A3D6177,0xF3DF0776,0x3251D8B6, + 0x0F5FE8BB,0xCED1377B,0x5733517A,0x96BD8EBA,0xBF869B39,0x7E0844F9,0xE7EA22F8,0x2664FD38, + 0xB59C09FE,0x7412D63E,0xEDF0B03F,0x2C7E6FFF,0x05457A7C,0xC4CBA5BC,0x5D29C3BD,0x9CA71C7D, + 0x2735A3A7,0xE6BB7C67,0x7F591A66,0xBED7C5A6,0x97ECD025,0x56620FE5,0xCF8069E4,0x0E0EB624, + 0x9DF642E2,0x5C789D22,0xC59AFB23,0x041424E3,0x2D2F3160,0xECA1EEA0,0x754388A1,0xB4CD5761, + 0x89C3676C,0x484DB8AC,0xD1AFDEAD,0x1021016D,0x391A14EE,0xF894CB2E,0x6176AD2F,0xA0F872EF, + 0x33008629,0xF28E59E9,0x6B6C3FE8,0xAAE2E028,0x83D9F5AB,0x42572A6B,0xDBB54C6A,0x1A3B93AA, + }, + + { + 0x00000000,0x9BA54C6F,0xEC3B9E9F,0x779ED2F0,0x03063B7F,0x98A37710,0xEF3DA5E0,0x7498E98F, + 0x060C76FE,0x9DA93A91,0xEA37E861,0x7192A40E,0x050A4D81,0x9EAF01EE,0xE931D31E,0x72949F71, + 0x0C18EDFC,0x97BDA193,0xE0237363,0x7B863F0C,0x0F1ED683,0x94BB9AEC,0xE325481C,0x78800473, + 0x0A149B02,0x91B1D76D,0xE62F059D,0x7D8A49F2,0x0912A07D,0x92B7EC12,0xE5293EE2,0x7E8C728D, + 0x1831DBF8,0x83949797,0xF40A4567,0x6FAF0908,0x1B37E087,0x8092ACE8,0xF70C7E18,0x6CA93277, + 0x1E3DAD06,0x8598E169,0xF2063399,0x69A37FF6,0x1D3B9679,0x869EDA16,0xF10008E6,0x6AA54489, + 0x14293604,0x8F8C7A6B,0xF812A89B,0x63B7E4F4,0x172F0D7B,0x8C8A4114,0xFB1493E4,0x60B1DF8B, + 0x122540FA,0x89800C95,0xFE1EDE65,0x65BB920A,0x11237B85,0x8A8637EA,0xFD18E51A,0x66BDA975, + 0x3063B7F0,0xABC6FB9F,0xDC58296F,0x47FD6500,0x33658C8F,0xA8C0C0E0,0xDF5E1210,0x44FB5E7F, + 0x366FC10E,0xADCA8D61,0xDA545F91,0x41F113FE,0x3569FA71,0xAECCB61E,0xD95264EE,0x42F72881, + 0x3C7B5A0C,0xA7DE1663,0xD040C493,0x4BE588FC,0x3F7D6173,0xA4D82D1C,0xD346FFEC,0x48E3B383, + 0x3A772CF2,0xA1D2609D,0xD64CB26D,0x4DE9FE02,0x3971178D,0xA2D45BE2,0xD54A8912,0x4EEFC57D, + 0x28526C08,0xB3F72067,0xC469F297,0x5FCCBEF8,0x2B545777,0xB0F11B18,0xC76FC9E8,0x5CCA8587, + 0x2E5E1AF6,0xB5FB5699,0xC2658469,0x59C0C806,0x2D582189,0xB6FD6DE6,0xC163BF16,0x5AC6F379, + 0x244A81F4,0xBFEFCD9B,0xC8711F6B,0x53D45304,0x274CBA8B,0xBCE9F6E4,0xCB772414,0x50D2687B, + 0x2246F70A,0xB9E3BB65,0xCE7D6995,0x55D825FA,0x2140CC75,0xBAE5801A,0xCD7B52EA,0x56DE1E85, + 0x60C76FE0,0xFB62238F,0x8CFCF17F,0x1759BD10,0x63C1549F,0xF86418F0,0x8FFACA00,0x145F866F, + 0x66CB191E,0xFD6E5571,0x8AF08781,0x1155CBEE,0x65CD2261,0xFE686E0E,0x89F6BCFE,0x1253F091, + 0x6CDF821C,0xF77ACE73,0x80E41C83,0x1B4150EC,0x6FD9B963,0xF47CF50C,0x83E227FC,0x18476B93, + 0x6AD3F4E2,0xF176B88D,0x86E86A7D,0x1D4D2612,0x69D5CF9D,0xF27083F2,0x85EE5102,0x1E4B1D6D, + 0x78F6B418,0xE353F877,0x94CD2A87,0x0F6866E8,0x7BF08F67,0xE055C308,0x97CB11F8,0x0C6E5D97, + 0x7EFAC2E6,0xE55F8E89,0x92C15C79,0x09641016,0x7DFCF999,0xE659B5F6,0x91C76706,0x0A622B69, + 0x74EE59E4,0xEF4B158B,0x98D5C77B,0x03708B14,0x77E8629B,0xEC4D2EF4,0x9BD3FC04,0x0076B06B, + 0x72E22F1A,0xE9476375,0x9ED9B185,0x057CFDEA,0x71E41465,0xEA41580A,0x9DDF8AFA,0x067AC695, + 0x50A4D810,0xCB01947F,0xBC9F468F,0x273A0AE0,0x53A2E36F,0xC807AF00,0xBF997DF0,0x243C319F, + 0x56A8AEEE,0xCD0DE281,0xBA933071,0x21367C1E,0x55AE9591,0xCE0BD9FE,0xB9950B0E,0x22304761, + 0x5CBC35EC,0xC7197983,0xB087AB73,0x2B22E71C,0x5FBA0E93,0xC41F42FC,0xB381900C,0x2824DC63, + 0x5AB04312,0xC1150F7D,0xB68BDD8D,0x2D2E91E2,0x59B6786D,0xC2133402,0xB58DE6F2,0x2E28AA9D, + 0x489503E8,0xD3304F87,0xA4AE9D77,0x3F0BD118,0x4B933897,0xD03674F8,0xA7A8A608,0x3C0DEA67, + 0x4E997516,0xD53C3979,0xA2A2EB89,0x3907A7E6,0x4D9F4E69,0xD63A0206,0xA1A4D0F6,0x3A019C99, + 0x448DEE14,0xDF28A27B,0xA8B6708B,0x33133CE4,0x478BD56B,0xDC2E9904,0xABB04BF4,0x3015079B, + 0x428198EA,0xD924D485,0xAEBA0675,0x351F4A1A,0x4187A395,0xDA22EFFA,0xADBC3D0A,0x36197165, + }, + + { + 0x00000000,0xDD96D985,0x605CB54B,0xBDCA6CCE,0xC0B96A96,0x1D2FB313,0xA0E5DFDD,0x7D730658, + 0x5A03D36D,0x87950AE8,0x3A5F6626,0xE7C9BFA3,0x9ABAB9FB,0x472C607E,0xFAE60CB0,0x2770D535, + 0xB407A6DA,0x69917F5F,0xD45B1391,0x09CDCA14,0x74BECC4C,0xA92815C9,0x14E27907,0xC974A082, + 0xEE0475B7,0x3392AC32,0x8E58C0FC,0x53CE1979,0x2EBD1F21,0xF32BC6A4,0x4EE1AA6A,0x937773EF, + 0xB37E4BF5,0x6EE89270,0xD322FEBE,0x0EB4273B,0x73C72163,0xAE51F8E6,0x139B9428,0xCE0D4DAD, + 0xE97D9898,0x34EB411D,0x89212DD3,0x54B7F456,0x29C4F20E,0xF4522B8B,0x49984745,0x940E9EC0, + 0x0779ED2F,0xDAEF34AA,0x67255864,0xBAB381E1,0xC7C087B9,0x1A565E3C,0xA79C32F2,0x7A0AEB77, + 0x5D7A3E42,0x80ECE7C7,0x3D268B09,0xE0B0528C,0x9DC354D4,0x40558D51,0xFD9FE19F,0x2009381A, + 0xBD8D91AB,0x601B482E,0xDDD124E0,0x0047FD65,0x7D34FB3D,0xA0A222B8,0x1D684E76,0xC0FE97F3, + 0xE78E42C6,0x3A189B43,0x87D2F78D,0x5A442E08,0x27372850,0xFAA1F1D5,0x476B9D1B,0x9AFD449E, + 0x098A3771,0xD41CEEF4,0x69D6823A,0xB4405BBF,0xC9335DE7,0x14A58462,0xA96FE8AC,0x74F93129, + 0x5389E41C,0x8E1F3D99,0x33D55157,0xEE4388D2,0x93308E8A,0x4EA6570F,0xF36C3BC1,0x2EFAE244, + 0x0EF3DA5E,0xD36503DB,0x6EAF6F15,0xB339B690,0xCE4AB0C8,0x13DC694D,0xAE160583,0x7380DC06, + 0x54F00933,0x8966D0B6,0x34ACBC78,0xE93A65FD,0x944963A5,0x49DFBA20,0xF415D6EE,0x29830F6B, + 0xBAF47C84,0x6762A501,0xDAA8C9CF,0x073E104A,0x7A4D1612,0xA7DBCF97,0x1A11A359,0xC7877ADC, + 0xE0F7AFE9,0x3D61766C,0x80AB1AA2,0x5D3DC327,0x204EC57F,0xFDD81CFA,0x40127034,0x9D84A9B1, + 0xA06A2517,0x7DFCFC92,0xC036905C,0x1DA049D9,0x60D34F81,0xBD459604,0x008FFACA,0xDD19234F, + 0xFA69F67A,0x27FF2FFF,0x9A354331,0x47A39AB4,0x3AD09CEC,0xE7464569,0x5A8C29A7,0x871AF022, + 0x146D83CD,0xC9FB5A48,0x74313686,0xA9A7EF03,0xD4D4E95B,0x094230DE,0xB4885C10,0x691E8595, + 0x4E6E50A0,0x93F88925,0x2E32E5EB,0xF3A43C6E,0x8ED73A36,0x5341E3B3,0xEE8B8F7D,0x331D56F8, + 0x13146EE2,0xCE82B767,0x7348DBA9,0xAEDE022C,0xD3AD0474,0x0E3BDDF1,0xB3F1B13F,0x6E6768BA, + 0x4917BD8F,0x9481640A,0x294B08C4,0xF4DDD141,0x89AED719,0x54380E9C,0xE9F26252,0x3464BBD7, + 0xA713C838,0x7A8511BD,0xC74F7D73,0x1AD9A4F6,0x67AAA2AE,0xBA3C7B2B,0x07F617E5,0xDA60CE60, + 0xFD101B55,0x2086C2D0,0x9D4CAE1E,0x40DA779B,0x3DA971C3,0xE03FA846,0x5DF5C488,0x80631D0D, + 0x1DE7B4BC,0xC0716D39,0x7DBB01F7,0xA02DD872,0xDD5EDE2A,0x00C807AF,0xBD026B61,0x6094B2E4, + 0x47E467D1,0x9A72BE54,0x27B8D29A,0xFA2E0B1F,0x875D0D47,0x5ACBD4C2,0xE701B80C,0x3A976189, + 0xA9E01266,0x7476CBE3,0xC9BCA72D,0x142A7EA8,0x695978F0,0xB4CFA175,0x0905CDBB,0xD493143E, + 0xF3E3C10B,0x2E75188E,0x93BF7440,0x4E29ADC5,0x335AAB9D,0xEECC7218,0x53061ED6,0x8E90C753, + 0xAE99FF49,0x730F26CC,0xCEC54A02,0x13539387,0x6E2095DF,0xB3B64C5A,0x0E7C2094,0xD3EAF911, + 0xF49A2C24,0x290CF5A1,0x94C6996F,0x495040EA,0x342346B2,0xE9B59F37,0x547FF3F9,0x89E92A7C, + 0x1A9E5993,0xC7088016,0x7AC2ECD8,0xA754355D,0xDA273305,0x07B1EA80,0xBA7B864E,0x67ED5FCB, + 0x409D8AFE,0x9D0B537B,0x20C13FB5,0xFD57E630,0x8024E068,0x5DB239ED,0xE0785523,0x3DEE8CA6, + }, + + { + 0x00000000,0x9D0FE176,0xE16EC4AD,0x7C6125DB,0x19AC8F1B,0x84A36E6D,0xF8C24BB6,0x65CDAAC0, + 0x33591E36,0xAE56FF40,0xD237DA9B,0x4F383BED,0x2AF5912D,0xB7FA705B,0xCB9B5580,0x5694B4F6, + 0x66B23C6C,0xFBBDDD1A,0x87DCF8C1,0x1AD319B7,0x7F1EB377,0xE2115201,0x9E7077DA,0x037F96AC, + 0x55EB225A,0xC8E4C32C,0xB485E6F7,0x298A0781,0x4C47AD41,0xD1484C37,0xAD2969EC,0x3026889A, + 0xCD6478D8,0x506B99AE,0x2C0ABC75,0xB1055D03,0xD4C8F7C3,0x49C716B5,0x35A6336E,0xA8A9D218, + 0xFE3D66EE,0x63328798,0x1F53A243,0x825C4335,0xE791E9F5,0x7A9E0883,0x06FF2D58,0x9BF0CC2E, + 0xABD644B4,0x36D9A5C2,0x4AB88019,0xD7B7616F,0xB27ACBAF,0x2F752AD9,0x53140F02,0xCE1BEE74, + 0x988F5A82,0x0580BBF4,0x79E19E2F,0xE4EE7F59,0x8123D599,0x1C2C34EF,0x604D1134,0xFD42F042, + 0x41B9F7F1,0xDCB61687,0xA0D7335C,0x3DD8D22A,0x581578EA,0xC51A999C,0xB97BBC47,0x24745D31, + 0x72E0E9C7,0xEFEF08B1,0x938E2D6A,0x0E81CC1C,0x6B4C66DC,0xF64387AA,0x8A22A271,0x172D4307, + 0x270BCB9D,0xBA042AEB,0xC6650F30,0x5B6AEE46,0x3EA74486,0xA3A8A5F0,0xDFC9802B,0x42C6615D, + 0x1452D5AB,0x895D34DD,0xF53C1106,0x6833F070,0x0DFE5AB0,0x90F1BBC6,0xEC909E1D,0x719F7F6B, + 0x8CDD8F29,0x11D26E5F,0x6DB34B84,0xF0BCAAF2,0x95710032,0x087EE144,0x741FC49F,0xE91025E9, + 0xBF84911F,0x228B7069,0x5EEA55B2,0xC3E5B4C4,0xA6281E04,0x3B27FF72,0x4746DAA9,0xDA493BDF, + 0xEA6FB345,0x77605233,0x0B0177E8,0x960E969E,0xF3C33C5E,0x6ECCDD28,0x12ADF8F3,0x8FA21985, + 0xD936AD73,0x44394C05,0x385869DE,0xA55788A8,0xC09A2268,0x5D95C31E,0x21F4E6C5,0xBCFB07B3, + 0x8373EFE2,0x1E7C0E94,0x621D2B4F,0xFF12CA39,0x9ADF60F9,0x07D0818F,0x7BB1A454,0xE6BE4522, + 0xB02AF1D4,0x2D2510A2,0x51443579,0xCC4BD40F,0xA9867ECF,0x34899FB9,0x48E8BA62,0xD5E75B14, + 0xE5C1D38E,0x78CE32F8,0x04AF1723,0x99A0F655,0xFC6D5C95,0x6162BDE3,0x1D039838,0x800C794E, + 0xD698CDB8,0x4B972CCE,0x37F60915,0xAAF9E863,0xCF3442A3,0x523BA3D5,0x2E5A860E,0xB3556778, + 0x4E17973A,0xD318764C,0xAF795397,0x3276B2E1,0x57BB1821,0xCAB4F957,0xB6D5DC8C,0x2BDA3DFA, + 0x7D4E890C,0xE041687A,0x9C204DA1,0x012FACD7,0x64E20617,0xF9EDE761,0x858CC2BA,0x188323CC, + 0x28A5AB56,0xB5AA4A20,0xC9CB6FFB,0x54C48E8D,0x3109244D,0xAC06C53B,0xD067E0E0,0x4D680196, + 0x1BFCB560,0x86F35416,0xFA9271CD,0x679D90BB,0x02503A7B,0x9F5FDB0D,0xE33EFED6,0x7E311FA0, + 0xC2CA1813,0x5FC5F965,0x23A4DCBE,0xBEAB3DC8,0xDB669708,0x4669767E,0x3A0853A5,0xA707B2D3, + 0xF1930625,0x6C9CE753,0x10FDC288,0x8DF223FE,0xE83F893E,0x75306848,0x09514D93,0x945EACE5, + 0xA478247F,0x3977C509,0x4516E0D2,0xD81901A4,0xBDD4AB64,0x20DB4A12,0x5CBA6FC9,0xC1B58EBF, + 0x97213A49,0x0A2EDB3F,0x764FFEE4,0xEB401F92,0x8E8DB552,0x13825424,0x6FE371FF,0xF2EC9089, + 0x0FAE60CB,0x92A181BD,0xEEC0A466,0x73CF4510,0x1602EFD0,0x8B0D0EA6,0xF76C2B7D,0x6A63CA0B, + 0x3CF77EFD,0xA1F89F8B,0xDD99BA50,0x40965B26,0x255BF1E6,0xB8541090,0xC435354B,0x593AD43D, + 0x691C5CA7,0xF413BDD1,0x8872980A,0x157D797C,0x70B0D3BC,0xEDBF32CA,0x91DE1711,0x0CD1F667, + 0x5A454291,0xC74AA3E7,0xBB2B863C,0x2624674A,0x43E9CD8A,0xDEE62CFC,0xA2870927,0x3F88E851, + }, + + { + 0x00000000,0xB9FBDBE8,0xA886B191,0x117D6A79,0x8A7C6563,0x3387BE8B,0x22FAD4F2,0x9B010F1A, + 0xCF89CC87,0x7672176F,0x670F7D16,0xDEF4A6FE,0x45F5A9E4,0xFC0E720C,0xED731875,0x5488C39D, + 0x44629F4F,0xFD9944A7,0xECE42EDE,0x551FF536,0xCE1EFA2C,0x77E521C4,0x66984BBD,0xDF639055, + 0x8BEB53C8,0x32108820,0x236DE259,0x9A9639B1,0x019736AB,0xB86CED43,0xA911873A,0x10EA5CD2, + 0x88C53E9E,0x313EE576,0x20438F0F,0x99B854E7,0x02B95BFD,0xBB428015,0xAA3FEA6C,0x13C43184, + 0x474CF219,0xFEB729F1,0xEFCA4388,0x56319860,0xCD30977A,0x74CB4C92,0x65B626EB,0xDC4DFD03, + 0xCCA7A1D1,0x755C7A39,0x64211040,0xDDDACBA8,0x46DBC4B2,0xFF201F5A,0xEE5D7523,0x57A6AECB, + 0x032E6D56,0xBAD5B6BE,0xABA8DCC7,0x1253072F,0x89520835,0x30A9D3DD,0x21D4B9A4,0x982F624C, + 0xCAFB7B7D,0x7300A095,0x627DCAEC,0xDB861104,0x40871E1E,0xF97CC5F6,0xE801AF8F,0x51FA7467, + 0x0572B7FA,0xBC896C12,0xADF4066B,0x140FDD83,0x8F0ED299,0x36F50971,0x27886308,0x9E73B8E0, + 0x8E99E432,0x37623FDA,0x261F55A3,0x9FE48E4B,0x04E58151,0xBD1E5AB9,0xAC6330C0,0x1598EB28, + 0x411028B5,0xF8EBF35D,0xE9969924,0x506D42CC,0xCB6C4DD6,0x7297963E,0x63EAFC47,0xDA1127AF, + 0x423E45E3,0xFBC59E0B,0xEAB8F472,0x53432F9A,0xC8422080,0x71B9FB68,0x60C49111,0xD93F4AF9, + 0x8DB78964,0x344C528C,0x253138F5,0x9CCAE31D,0x07CBEC07,0xBE3037EF,0xAF4D5D96,0x16B6867E, + 0x065CDAAC,0xBFA70144,0xAEDA6B3D,0x1721B0D5,0x8C20BFCF,0x35DB6427,0x24A60E5E,0x9D5DD5B6, + 0xC9D5162B,0x702ECDC3,0x6153A7BA,0xD8A87C52,0x43A97348,0xFA52A8A0,0xEB2FC2D9,0x52D41931, + 0x4E87F0BB,0xF77C2B53,0xE601412A,0x5FFA9AC2,0xC4FB95D8,0x7D004E30,0x6C7D2449,0xD586FFA1, + 0x810E3C3C,0x38F5E7D4,0x29888DAD,0x90735645,0x0B72595F,0xB28982B7,0xA3F4E8CE,0x1A0F3326, + 0x0AE56FF4,0xB31EB41C,0xA263DE65,0x1B98058D,0x80990A97,0x3962D17F,0x281FBB06,0x91E460EE, + 0xC56CA373,0x7C97789B,0x6DEA12E2,0xD411C90A,0x4F10C610,0xF6EB1DF8,0xE7967781,0x5E6DAC69, + 0xC642CE25,0x7FB915CD,0x6EC47FB4,0xD73FA45C,0x4C3EAB46,0xF5C570AE,0xE4B81AD7,0x5D43C13F, + 0x09CB02A2,0xB030D94A,0xA14DB333,0x18B668DB,0x83B767C1,0x3A4CBC29,0x2B31D650,0x92CA0DB8, + 0x8220516A,0x3BDB8A82,0x2AA6E0FB,0x935D3B13,0x085C3409,0xB1A7EFE1,0xA0DA8598,0x19215E70, + 0x4DA99DED,0xF4524605,0xE52F2C7C,0x5CD4F794,0xC7D5F88E,0x7E2E2366,0x6F53491F,0xD6A892F7, + 0x847C8BC6,0x3D87502E,0x2CFA3A57,0x9501E1BF,0x0E00EEA5,0xB7FB354D,0xA6865F34,0x1F7D84DC, + 0x4BF54741,0xF20E9CA9,0xE373F6D0,0x5A882D38,0xC1892222,0x7872F9CA,0x690F93B3,0xD0F4485B, + 0xC01E1489,0x79E5CF61,0x6898A518,0xD1637EF0,0x4A6271EA,0xF399AA02,0xE2E4C07B,0x5B1F1B93, + 0x0F97D80E,0xB66C03E6,0xA711699F,0x1EEAB277,0x85EBBD6D,0x3C106685,0x2D6D0CFC,0x9496D714, + 0x0CB9B558,0xB5426EB0,0xA43F04C9,0x1DC4DF21,0x86C5D03B,0x3F3E0BD3,0x2E4361AA,0x97B8BA42, + 0xC33079DF,0x7ACBA237,0x6BB6C84E,0xD24D13A6,0x494C1CBC,0xF0B7C754,0xE1CAAD2D,0x583176C5, + 0x48DB2A17,0xF120F1FF,0xE05D9B86,0x59A6406E,0xC2A74F74,0x7B5C949C,0x6A21FEE5,0xD3DA250D, + 0x8752E690,0x3EA93D78,0x2FD45701,0x962F8CE9,0x0D2E83F3,0xB4D5581B,0xA5A83262,0x1C53E98A, + }, + + { + 0x00000000,0xAE689191,0x87A02563,0x29C8B4F2,0xD4314C87,0x7A59DD16,0x539169E4,0xFDF9F875, + 0x73139F4F,0xDD7B0EDE,0xF4B3BA2C,0x5ADB2BBD,0xA722D3C8,0x094A4259,0x2082F6AB,0x8EEA673A, + 0xE6273E9E,0x484FAF0F,0x61871BFD,0xCFEF8A6C,0x32167219,0x9C7EE388,0xB5B6577A,0x1BDEC6EB, + 0x9534A1D1,0x3B5C3040,0x129484B2,0xBCFC1523,0x4105ED56,0xEF6D7CC7,0xC6A5C835,0x68CD59A4, + 0x173F7B7D,0xB957EAEC,0x909F5E1E,0x3EF7CF8F,0xC30E37FA,0x6D66A66B,0x44AE1299,0xEAC68308, + 0x642CE432,0xCA4475A3,0xE38CC151,0x4DE450C0,0xB01DA8B5,0x1E753924,0x37BD8DD6,0x99D51C47, + 0xF11845E3,0x5F70D472,0x76B86080,0xD8D0F111,0x25290964,0x8B4198F5,0xA2892C07,0x0CE1BD96, + 0x820BDAAC,0x2C634B3D,0x05ABFFCF,0xABC36E5E,0x563A962B,0xF85207BA,0xD19AB348,0x7FF222D9, + 0x2E7EF6FA,0x8016676B,0xA9DED399,0x07B64208,0xFA4FBA7D,0x54272BEC,0x7DEF9F1E,0xD3870E8F, + 0x5D6D69B5,0xF305F824,0xDACD4CD6,0x74A5DD47,0x895C2532,0x2734B4A3,0x0EFC0051,0xA09491C0, + 0xC859C864,0x663159F5,0x4FF9ED07,0xE1917C96,0x1C6884E3,0xB2001572,0x9BC8A180,0x35A03011, + 0xBB4A572B,0x1522C6BA,0x3CEA7248,0x9282E3D9,0x6F7B1BAC,0xC1138A3D,0xE8DB3ECF,0x46B3AF5E, + 0x39418D87,0x97291C16,0xBEE1A8E4,0x10893975,0xED70C100,0x43185091,0x6AD0E463,0xC4B875F2, + 0x4A5212C8,0xE43A8359,0xCDF237AB,0x639AA63A,0x9E635E4F,0x300BCFDE,0x19C37B2C,0xB7ABEABD, + 0xDF66B319,0x710E2288,0x58C6967A,0xF6AE07EB,0x0B57FF9E,0xA53F6E0F,0x8CF7DAFD,0x229F4B6C, + 0xAC752C56,0x021DBDC7,0x2BD50935,0x85BD98A4,0x784460D1,0xD62CF140,0xFFE445B2,0x518CD423, + 0x5CFDEDF4,0xF2957C65,0xDB5DC897,0x75355906,0x88CCA173,0x26A430E2,0x0F6C8410,0xA1041581, + 0x2FEE72BB,0x8186E32A,0xA84E57D8,0x0626C649,0xFBDF3E3C,0x55B7AFAD,0x7C7F1B5F,0xD2178ACE, + 0xBADAD36A,0x14B242FB,0x3D7AF609,0x93126798,0x6EEB9FED,0xC0830E7C,0xE94BBA8E,0x47232B1F, + 0xC9C94C25,0x67A1DDB4,0x4E696946,0xE001F8D7,0x1DF800A2,0xB3909133,0x9A5825C1,0x3430B450, + 0x4BC29689,0xE5AA0718,0xCC62B3EA,0x620A227B,0x9FF3DA0E,0x319B4B9F,0x1853FF6D,0xB63B6EFC, + 0x38D109C6,0x96B99857,0xBF712CA5,0x1119BD34,0xECE04541,0x4288D4D0,0x6B406022,0xC528F1B3, + 0xADE5A817,0x038D3986,0x2A458D74,0x842D1CE5,0x79D4E490,0xD7BC7501,0xFE74C1F3,0x501C5062, + 0xDEF63758,0x709EA6C9,0x5956123B,0xF73E83AA,0x0AC77BDF,0xA4AFEA4E,0x8D675EBC,0x230FCF2D, + 0x72831B0E,0xDCEB8A9F,0xF5233E6D,0x5B4BAFFC,0xA6B25789,0x08DAC618,0x211272EA,0x8F7AE37B, + 0x01908441,0xAFF815D0,0x8630A122,0x285830B3,0xD5A1C8C6,0x7BC95957,0x5201EDA5,0xFC697C34, + 0x94A42590,0x3ACCB401,0x130400F3,0xBD6C9162,0x40956917,0xEEFDF886,0xC7354C74,0x695DDDE5, + 0xE7B7BADF,0x49DF2B4E,0x60179FBC,0xCE7F0E2D,0x3386F658,0x9DEE67C9,0xB426D33B,0x1A4E42AA, + 0x65BC6073,0xCBD4F1E2,0xE21C4510,0x4C74D481,0xB18D2CF4,0x1FE5BD65,0x362D0997,0x98459806, + 0x16AFFF3C,0xB8C76EAD,0x910FDA5F,0x3F674BCE,0xC29EB3BB,0x6CF6222A,0x453E96D8,0xEB560749, + 0x839B5EED,0x2DF3CF7C,0x043B7B8E,0xAA53EA1F,0x57AA126A,0xF9C283FB,0xD00A3709,0x7E62A698, + 0xF088C1A2,0x5EE05033,0x7728E4C1,0xD9407550,0x24B98D25,0x8AD11CB4,0xA319A846,0x0D7139D7, + } +#endif // CRC32_USE_LOOKUP_TABLE_SLICING_BY_16 +}; +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/file_adapter.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/file_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..4bf472737e0186c2e244dd502f319e88956bdfcc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/file_adapter.h @@ -0,0 +1,40 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +#include "caffe2/serialize/istream_adapter.h" +#include "caffe2/serialize/read_adapter_interface.h" + + +namespace caffe2::serialize { + +class TORCH_API FileAdapter final : public ReadAdapterInterface { + public: + C10_DISABLE_COPY_AND_ASSIGN(FileAdapter); + explicit FileAdapter(const std::string& file_name); + size_t size() const override; + size_t read(uint64_t pos, void* buf, size_t n, const char* what = "") + const override; + ~FileAdapter() override; + + private: + // An RAII Wrapper for a FILE pointer. Closes on destruction. + struct RAIIFile { + FILE* fp_; + explicit RAIIFile(const std::string& file_name); + ~RAIIFile(); + }; + + RAIIFile file_; + // The size of the opened file in bytes + uint64_t size_; +}; + +} // namespace caffe2::serialize + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/in_memory_adapter.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/in_memory_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..394898e5ed08ec4c62c8868ae12cf846ad7bf22f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/in_memory_adapter.h @@ -0,0 +1,35 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include +#include + +namespace caffe2 { +namespace serialize { + +class MemoryReadAdapter final : public caffe2::serialize::ReadAdapterInterface { + public: + explicit MemoryReadAdapter(const void* data, off_t size) + : data_(data), size_(size) {} + + size_t size() const override { + return size_; + } + + size_t read(uint64_t pos, void* buf, size_t n, const char* what = "") + const override { + (void)what; + memcpy(buf, (int8_t*)(data_) + pos, n); + return n; + } + + private: + const void* data_; + off_t size_; +}; + +} // namespace serialize +} // namespace caffe2 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/inline_container.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/inline_container.h new file mode 100644 index 0000000000000000000000000000000000000000..0a87f511f071f571c93a2c663b96c9982d022618 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/inline_container.h @@ -0,0 +1,314 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "caffe2/serialize/istream_adapter.h" +#include "caffe2/serialize/read_adapter_interface.h" +#include "caffe2/serialize/versions.h" + +extern "C" { +typedef struct mz_zip_archive mz_zip_archive; +} + +// PyTorch containers are a special zip archive with the following layout +// archive_name.zip contains: +// archive_name/ +// version # a file with a single decimal number written in ascii, +// # used to establish the version of the archive format +// model.json # overall model description, this is a json output of +// # ModelDef from torch.proto +// # the following names are by convention only, model.json will +// # refer to these files by full names +// tensors/ +// 0 # flat storage for tensor data, meta-data about shapes, etc. is +// # in model.json +// 1 +// ... +// # code entries will only exist for modules that have methods attached +// code/ +// archive_name.py # serialized torch script code (python syntax, using +// PythonPrint) archive_name_my_submodule.py # submodules have separate +// files +// +// The PyTorchStreamWriter also ensures additional useful properties for these +// files +// 1. All files are stored uncompressed. +// 2. All files in the archive are aligned to 64 byte boundaries such that +// it is possible to mmap the entire file and get an aligned pointer to +// tensor data. +// 3. We universally write in ZIP64 format for consistency. + +// The PyTorchStreamReader also provides additional properties: +// 1. It can read zip files that are created with common +// zip tools. This means that even though our writer doesn't compress files, +// the reader can still read files that were compressed. +// 2. It provides a getRecordOffset function which returns the offset into the +// raw file where file data lives. If the file was written with +// PyTorchStreamWriter it is guaranteed to be 64 byte aligned. + +// PyTorchReader/Writer handle checking the version number on the archive format +// and ensure that all files are written to a archive_name directory so they +// unzip cleanly. + +// When developing this format we want to pay particular attention to the +// following use cases: +// +// -- Reading -- +// 1) Reading with full random access +// a) Reading with file api's such as fread() +// b) mmaping the file and jumping around the mapped region +// 2) Reading with 1-pass sequential access +// -> A reader will need to build up a data structure of parsed structures +// as it reads +// +// -- Writing -- +// 1) Writing with full random access +// 2) Writing with 1-pass sequential access +// -> We must take care not to require updating values that have already +// been written. We place the variable-length index at the end and do +// not put any index into the header to fulfill this constraint. + +// The model.json, which contains all the metadata information, +// should be written as the last file. One reason is that the size of tensor +// data is usually stable. As long as the shape and type of the tensor do not +// change, the size of the data won't change. On the other sied, the size of the +// serialized model is likely to change, so we store it as the last record, and +// we don't need to move previous records when updating the model data. + +// The zip format is sufficiently flexible to handle the above use-case. +// it puts its central directory at the end of the archive and we write +// model.json as the last file when writing after we have accumulated all +// other information. + + +namespace caffe2::serialize { + +static constexpr const char* kSerializationIdRecordName = + ".data/serialization_id"; + +struct MzZipReaderIterWrapper; + +class TORCH_API ChunkRecordIterator { + public: + ~ChunkRecordIterator(); + + // Read at most `chunkSize` into `buf`. Return the number of actual bytes + // read. + size_t next(void* buf); + size_t recordSize() const { + return recordSize_; + } + + private: + ChunkRecordIterator( + size_t recordSize, + size_t chunkSize, + std::unique_ptr iter); + + const size_t recordSize_; + const size_t chunkSize_; + size_t offset_; + std::unique_ptr iter_; + + friend class PyTorchStreamReader; +}; + +class TORCH_API PyTorchStreamReader final { + public: + explicit PyTorchStreamReader(const std::string& file_name); + explicit PyTorchStreamReader(std::istream* in); + explicit PyTorchStreamReader(std::shared_ptr in); + + // return dataptr, size + // set allocator to override default cpu allocator + std::tuple getRecord( + const std::string& name, + std::optional allocator = std::nullopt); + // multi-thread getRecord + std::tuple getRecord( + const std::string& name, + std::vector>& additionalReaders, + std::optional allocator = std::nullopt); + // inplace memory writing + size_t getRecord(const std::string& name, void* dst, size_t n); + // inplace memory writing, multi-threads. + // When additionalReaders is empty, the default behavior is call + // getRecord(name, dst, n) with default reader This approach can be used for + // reading large tensors. + size_t getRecord( + const std::string& name, + void* dst, + size_t n, + std::vector>& additionalReaders); + size_t getRecord( + const std::string& name, + void* dst, + size_t n, + size_t chunk_size, + void* buf, + const std::function& memcpy_func = + nullptr); + + // Concurrent reading records with multiple readers. + // additionalReaders are additional clients to access the underlying record at + // different offsets and write to different trunks of buffers. If the overall + // size of the tensor is 10, and size of additionalReader is 2. The default + // thread will read [0,4), the additional reader will read [4,8). The default + // reader will read [8,10). The default reader will write to buffer[0,4), the + // additional reader will write to buffer[4,8), the additional reader will + // write to buffer[8,10). When additionalReaders is empty, the default + // behavior is call getRecord(name) with default reader This approach can be + // used for reading large tensors. + size_t getRecordMultiReaders( + const std::string& name, + std::vector>& additionalReaders, + void* dst, + size_t n); + + size_t getRecordSize(const std::string& name); + size_t getRecordHeaderOffset(const std::string& name); + size_t getRecordOffset(const std::string& name); + size_t getRecordOffsetNoRead( + size_t cursor, + std::string filename, + size_t size, + uint64_t alignment); + bool hasRecord(const std::string& name); + std::vector getAllRecords(); + + ChunkRecordIterator createChunkReaderIter( + const std::string& name, + const size_t recordSize, + const size_t chunkSize); + + ~PyTorchStreamReader(); + uint64_t version() const { + return version_; + } + const std::string& serializationId() { + return serialization_id_; + } + + void setShouldLoadDebugSymbol(bool should_load_debug_symbol) { + load_debug_symbol_ = should_load_debug_symbol; + } + void setAdditionalReaderSizeThreshold(const size_t& size) { + additional_reader_size_threshold_ = size; + } + + private: + void init(); + size_t read(uint64_t pos, char* buf, size_t n); + void valid(const char* what, const char* info = ""); + size_t getRecordID(const std::string& name); + + friend size_t + istream_read_func(void* pOpaque, uint64_t file_ofs, void* pBuf, size_t n); + std::unique_ptr ar_; + std::string archive_name_; + std::string archive_name_plus_slash_; + std::shared_ptr in_; + int64_t version_; + std::mutex reader_lock_; + bool load_debug_symbol_ = true; + std::string serialization_id_; + size_t additional_reader_size_threshold_; +}; + +class TORCH_API PyTorchStreamWriter final { + public: + explicit PyTorchStreamWriter( + const std::string& archive_name, + bool compute_crc32 = true, + uint64_t alignment = 64); + explicit PyTorchStreamWriter( + const std::function writer_func, + bool compute_crc32 = true, + uint64_t alignment = 64); + + void setMinVersion(const uint64_t version); + + void writeRecord( + const std::string& name, + const void* data, + size_t size, + bool compress = false); + void writeEndOfFile(); + + const std::unordered_set& getAllWrittenRecords(); + + bool finalized() const { + return finalized_; + } + + const std::string& archiveName() { + return archive_name_; + } + + const std::string& serializationId() { + return serialization_id_; + } + + ~PyTorchStreamWriter(); + + private: + void setup(const std::string& file_name); + void valid(const char* what, const char* info = ""); + void writeSerializationId(); + size_t current_pos_ = 0; + std::unordered_set files_written_; + std::unique_ptr ar_; + std::string archive_name_; + std::string archive_name_plus_slash_; + std::string padding_; + std::ofstream file_stream_; + std::function writer_func_; + uint64_t combined_uncomp_crc32_ = 0; + std::string serialization_id_; + bool compute_crc32_; + uint64_t alignment_; + + // This number will be updated when the model has operators + // that have valid upgraders. + uint64_t version_ = kMinProducedFileFormatVersion; + bool finalized_ = false; + bool err_seen_ = false; + friend size_t ostream_write_func( + void* pOpaque, + uint64_t file_ofs, + const void* pBuf, + size_t n); +}; + +namespace detail { + +// Returns a record to be appended to the local user extra data entry in order +// to make data beginning aligned at kFieldAlignment bytes boundary. +size_t getPadding( + size_t cursor, + size_t filename_size, + size_t size, + std::string& padding_buf, + uint64_t alignment); + +std::tuple +getOffset(size_t cursor, size_t filename_size, size_t size, uint64_t alignment); + +} // namespace detail + +} // namespace caffe2::serialize + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/istream_adapter.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/istream_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..8155b2f20c7767e6372c92625d00b678c051ca53 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/istream_adapter.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#include "c10/macros/Macros.h" +#include "caffe2/serialize/read_adapter_interface.h" + + +namespace caffe2::serialize { + +// this is a reader implemented by std::istream +class TORCH_API IStreamAdapter final : public ReadAdapterInterface { + public: + C10_DISABLE_COPY_AND_ASSIGN(IStreamAdapter); + explicit IStreamAdapter(std::istream* istream); + size_t size() const override; + size_t read(uint64_t pos, void* buf, size_t n, const char* what = "") + const override; + ~IStreamAdapter() override; + + private: + std::istream* istream_; + void validate(const char* what) const; +}; + +} // namespace caffe2::serialize + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/read_adapter_interface.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/read_adapter_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..78014a8788465fc7f748f024937be8b5bbd49e42 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/read_adapter_interface.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include + +#include "c10/macros/Macros.h" + + +namespace caffe2::serialize { + +// this is the interface for the (file/stream/memory) reader in +// PyTorchStreamReader. with this interface, we can extend the support +// besides standard istream +class TORCH_API ReadAdapterInterface { + public: + virtual size_t size() const = 0; + virtual size_t read(uint64_t pos, void* buf, size_t n, const char* what = "") + const = 0; + virtual ~ReadAdapterInterface(); +}; + +} // namespace caffe2::serialize + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/versions.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/versions.h new file mode 100644 index 0000000000000000000000000000000000000000..ce96250ba9f184955b77e829ded09ba2e5517843 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/versions.h @@ -0,0 +1,137 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#include + + +namespace caffe2::serialize { + +constexpr uint64_t kMinSupportedFileFormatVersion = 0x1L; + +constexpr uint64_t kMaxSupportedFileFormatVersion = 0xAL; + +// Versions (i.e. why was the version number bumped?) + +// Note [Dynamic Versions and torch.jit.save vs. torch.save] +// +// Our versioning scheme has a "produced file format version" which +// describes how an archive is to be read. The version written in an archive +// is at least this current produced file format version, but may be greater +// if it includes certain symbols. We refer to these conditional versions +// as "dynamic," since they are identified at runtime. +// +// Dynamic versioning is useful when an operator's semantics are updated. +// When using torch.jit.save we want those semantics to be preserved. If +// we bumped the produced file format version on every change, however, +// then older versions of PyTorch couldn't read even simple archives, like +// a single tensor, from newer versions of PyTorch. Instead, we +// assign dynamic versions to these changes that override the +// produced file format version as needed. That is, when the semantics +// of torch.div changed it was assigned dynamic version 4, and when +// torch.jit.saving modules that use torch.div those archives also have +// (at least) version 4. This prevents earlier versions of PyTorch +// from accidentally performing the wrong kind of division. Modules +// that don't use torch.div or other operators with dynamic versions +// can write the produced file format version, and these programs will +// run as expected on earlier versions of PyTorch. +// +// While torch.jit.save attempts to preserve operator semantics, +// torch.save does not. torch.save is analogous to pickling Python, so +// a function that uses torch.div will have different behavior if torch.saved +// and torch.loaded across PyTorch versions. From a technical perspective, +// torch.save ignores dynamic versioning. + +// 1. Initial version +// 2. Removed op_version_set version numbers +// 3. Added type tags to pickle serialization of container types +// 4. (Dynamic) Stopped integer division using torch.div +// (a versioned symbol preserves the historic behavior of versions 1--3) +// 5. (Dynamic) Stops torch.full inferring a floating point dtype +// when given bool or integer fill values. +// 6. Write version string to `./data/version` instead of `version`. + +// [12/15/2021] +// kProducedFileFormatVersion is set to 7 from 3 due to a different +// interpretation of what file format version is. +// Whenever there is new upgrader introduced, +// this number should be bumped. +// The reasons that version is bumped in the past: +// 1. aten::div is changed at version 4 +// 2. aten::full is changed at version 5 +// 3. torch.package uses version 6 +// 4. Introduce new upgrader design and set the version number to 7 +// mark this change +// -------------------------------------------------- +// We describe new operator version bump reasons here: +// 1) [01/24/2022] +// We bump the version number to 8 to update aten::linspace +// and aten::linspace.out to error out when steps is not +// provided. (see: https://github.com/pytorch/pytorch/issues/55951) +// 2) [01/30/2022] +// Bump the version number to 9 to update aten::logspace and +// and aten::logspace.out to error out when steps is not +// provided. (see: https://github.com/pytorch/pytorch/issues/55951) +// 3) [02/11/2022] +// Bump the version number to 10 to update aten::gelu and +// and aten::gelu.out to support the new approximate kwarg. +// (see: https://github.com/pytorch/pytorch/pull/61439) +constexpr uint64_t kProducedFileFormatVersion = 0xAL; + +// Absolute minimum version we will write packages. This +// means that every package from now on will always be +// greater than this number. +constexpr uint64_t kMinProducedFileFormatVersion = 0x3L; + +// The version we write when the archive contains bytecode. +// It must be higher or eq to kProducedFileFormatVersion. +// Because torchscript changes is likely introduce bytecode change. +// If kProducedFileFormatVersion is increased, kProducedBytecodeVersion +// should be increased too. The relationship is: +// kMaxSupportedFileFormatVersion >= (most likely ==) kProducedBytecodeVersion +// >= kProducedFileFormatVersion +// If a format change is forward compatible (still readable by older +// executables), we will not increment the version number, to minimize the +// risk of breaking existing clients. TODO: A better way would be to allow +// the caller that creates a model to specify a maximum version that its +// clients can accept. +// Versions: +// 0x1L: Initial version +// 0x2L: (Comment missing) +// 0x3L: (Comment missing) +// 0x4L: (update) Added schema to function tuple. Forward-compatible change. +// 0x5L: (update) Update bytecode is sharing constant tensor files from +// torchscript, and only serialize extra tensors that are not in the +// torchscript constant table. Also update tensor storage schema adapting to +// the unify format, the root key of tensor storage is updated from {index} to +// {the_pointer_value_the_tensor.storage}, for example: +// `140245072983168.storage` Forward-compatibility change. +// 0x6L: Implicit opereator versioning using number of specified argument. +// Refer to the summary of https://github.com/pytorch/pytorch/pull/56845 for +// details. +// 0x7L: Enable support for operators with default arguments plus out +// arguments. Refer. See https://github.com/pytorch/pytorch/pull/63651 for +// details. +// 0x8L: Emit promoted operators as instructions. See +// https://github.com/pytorch/pytorch/pull/71662 for details. +// 0x9L: Change serialization format from pickle to format This version is to +// serve migration. v8 pickle and v9 flatbuffer are the same. Refer to the +// summary of https://github.com/pytorch/pytorch/pull/75201 for more details. +constexpr uint64_t kProducedBytecodeVersion = 0x8L; + +// static_assert( +// kProducedBytecodeVersion >= kProducedFileFormatVersion, +// "kProducedBytecodeVersion must be higher or equal to +// kProducedFileFormatVersion."); + +// Introduce kMinSupportedBytecodeVersion and kMaxSupportedBytecodeVersion +// for limited backward/forward compatibility support of bytecode. If +// kMinSupportedBytecodeVersion <= model_version <= kMaxSupportedBytecodeVersion +// (in loader), we should support this model_version. For example, we provide a +// wrapper to handle an updated operator. +constexpr uint64_t kMinSupportedBytecodeVersion = 0x4L; +constexpr uint64_t kMaxSupportedBytecodeVersion = 0x9L; + +} // namespace caffe2::serialize + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/fixed_divisor.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/fixed_divisor.h new file mode 100644 index 0000000000000000000000000000000000000000..8041a2723c8603b05b26956126e37eff436ac905 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/fixed_divisor.h @@ -0,0 +1,137 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef CAFFE2_UTILS_FIXED_DIVISOR_H_ +#define CAFFE2_UTILS_FIXED_DIVISOR_H_ + +#include +#include +#include + +// See Note [hip-clang differences to hcc] + +#if defined(__CUDA_ARCH__) || defined(__HIP_ARCH__) || defined(__HIP__) || \ + (defined(__clang__) && defined(__CUDA__)) +#define FIXED_DIVISOR_DECL inline __host__ __device__ +#else +#define FIXED_DIVISOR_DECL inline +#endif + +namespace caffe2 { + +// Utility class for quickly calculating quotients and remainders for +// a known integer divisor +template +class FixedDivisor {}; + +// Works for any positive divisor, 1 to INT_MAX. One 64-bit +// multiplication and one 64-bit shift is used to calculate the +// result. +template <> +class FixedDivisor { + public: + FixedDivisor() = default; + + explicit FixedDivisor(const std::int32_t d) : d_(d) { +#if !defined(USE_ROCM) + CalcSignedMagic(); +#endif // USE_ROCM + } + + FIXED_DIVISOR_DECL std::int32_t d() const { + return d_; + } + +#if !defined(USE_ROCM) + FIXED_DIVISOR_DECL std::uint64_t magic() const { + return magic_; + } + + FIXED_DIVISOR_DECL int shift() const { + return shift_; + } +#endif // USE_ROCM + + /// Calculates `q = n / d`. + FIXED_DIVISOR_DECL std::int32_t Div(const std::int32_t n) const { +#if defined(USE_ROCM) + return n / d_; +#else // USE_ROCM + // In lieu of a mulhi instruction being available, perform the + // work in uint64 + return (int32_t)((magic_ * (uint64_t)n) >> shift_); +#endif // USE_ROCM + } + + /// Calculates `r = n % d`. + FIXED_DIVISOR_DECL std::int32_t Mod(const std::int32_t n) const { + return n - d_ * Div(n); + } + + /// Calculates `q = n / d` and `r = n % d` together. + FIXED_DIVISOR_DECL void + DivMod(const std::int32_t n, std::int32_t* q, int32_t* r) const { + *q = Div(n); + *r = n - d_ * *q; + } + + private: +#if !defined(USE_ROCM) + // Calculates magic multiplicative value and shift amount for calculating `q = + // n / d` for signed 32-bit integers. + // Implementation taken from Hacker's Delight section 10. + void CalcSignedMagic() { + if (d_ == 1) { + magic_ = UINT64_C(0x1) << 32; + shift_ = 32; + return; + } + + const std::uint32_t two31 = UINT32_C(0x80000000); + const std::uint32_t ad = std::abs(d_); + const std::uint32_t t = two31 + ((uint32_t)d_ >> 31); + const std::uint32_t anc = t - 1 - t % ad; // Absolute value of nc. + std::uint32_t p = 31; // Init. p. + std::uint32_t q1 = two31 / anc; // Init. q1 = 2**p/|nc|. + std::uint32_t r1 = two31 - q1 * anc; // Init. r1 = rem(2**p, |nc|). + std::uint32_t q2 = two31 / ad; // Init. q2 = 2**p/|d|. + std::uint32_t r2 = two31 - q2 * ad; // Init. r2 = rem(2**p, |d|). + std::uint32_t delta = 0; + do { + ++p; + q1 <<= 1; // Update q1 = 2**p/|nc|. + r1 <<= 1; // Update r1 = rem(2**p, |nc|). + if (r1 >= anc) { // (Must be an unsigned + ++q1; // comparison here). + r1 -= anc; + } + q2 <<= 1; // Update q2 = 2**p/|d|. + r2 <<= 1; // Update r2 = rem(2**p, |d|). + if (r2 >= ad) { // (Must be an unsigned + ++q2; // comparison here). + r2 -= ad; + } + delta = ad - r2; + } while (q1 < delta || (q1 == delta && r1 == 0)); + std::int32_t magic = q2 + 1; + if (d_ < 0) { + magic = -magic; + } + shift_ = p; + magic_ = (std::uint64_t)(std::uint32_t)magic; + } +#endif // USE_ROCM + + std::int32_t d_ = 1; + +#if !defined(USE_ROCM) + std::uint64_t magic_; + int shift_; +#endif // USE_ROCM +}; + +} // namespace caffe2 + +#endif // CAFFE2_UTILS_FIXED_DIVISOR_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/proto_wrap.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/proto_wrap.h new file mode 100644 index 0000000000000000000000000000000000000000..29b58072e159b1ca826fc4b6d8631e7590943969 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/proto_wrap.h @@ -0,0 +1,42 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef CAFFE2_UTILS_PROTO_WRAP_H_ +#define CAFFE2_UTILS_PROTO_WRAP_H_ + +#include + +namespace caffe2 { + +// A wrapper function to shut down protobuf library (this is needed in ASAN +// testing and valgrind cases to avoid protobuf appearing to "leak" memory). +TORCH_API void ShutdownProtobufLibrary(); + +// Caffe2 wrapper functions for protobuf's GetEmptyStringAlreadyInited() +// function used to avoid duplicated global variable in the case when protobuf +// is built with hidden visibility. +TORCH_API const ::std::string& GetEmptyStringAlreadyInited(); +} // namespace caffe2 + +namespace ONNX_NAMESPACE { + +// ONNX wrapper functions for protobuf's GetEmptyStringAlreadyInited() function +// used to avoid duplicated global variable in the case when protobuf +// is built with hidden visibility. +TORCH_API const ::std::string& GetEmptyStringAlreadyInited(); + +} // namespace ONNX_NAMESPACE + +namespace torch { + +// Caffe2 wrapper functions for protobuf's GetEmptyStringAlreadyInited() +// function used to avoid duplicated global variable in the case when protobuf +// is built with hidden visibility. +TORCH_API const ::std::string& GetEmptyStringAlreadyInited(); + +void ShutdownProtobufLibrary(); + +} // namespace torch +#endif // CAFFE2_UTILS_PROTO_WRAP_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/string_utils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/string_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..f8d2d49efdb0ca402a6e6b60c0c6de7db9249684 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/string_utils.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include + +#include + +namespace caffe2 { + +TORCH_API std::vector +split(char separator, const std::string& string, bool ignore_empty = false); + +TORCH_API std::string trim(const std::string& str); + +TORCH_API size_t editDistance( + const std::string& s1, + const std::string& s2, + size_t max_distance = 0); + +TORCH_API inline bool StartsWith( + const std::string& str, + const std::string& prefix) { + return str.length() >= prefix.length() && + std::mismatch(prefix.begin(), prefix.end(), str.begin()).first == + prefix.end(); +} + +TORCH_API inline bool EndsWith( + const std::string& full, + const std::string& ending) { + if (full.length() >= ending.length()) { + return ( + 0 == + full.compare(full.length() - ending.length(), ending.length(), ending)); + } else { + return false; + } +} + +TORCH_API int32_t editDistanceHelper( + const char* s1, + size_t s1_len, + const char* s2, + size_t s2_len, + std::vector& current, + std::vector& previous, + std::vector& previous1, + size_t max_distance); +} // namespace caffe2 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/ThreadPool.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/ThreadPool.h new file mode 100644 index 0000000000000000000000000000000000000000..a3769ec59ebdc60be60a685779aa4c3903e0f721 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/ThreadPool.h @@ -0,0 +1,84 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef CAFFE2_UTILS_THREADPOOL_H_ +#define CAFFE2_UTILS_THREADPOOL_H_ + +#include "ThreadPoolCommon.h" + +#include +#include +#include +#include +#include + +#include "c10/util/Flags.h" +#include "caffe2/core/common.h" + +// +// A work-stealing threadpool loosely based off of pthreadpool +// + +namespace caffe2 { + +struct Task; +class WorkersPool; + +constexpr size_t kCacheLineSize = 64; + +// A threadpool with the given number of threads. +// NOTE: the kCacheLineSize alignment is present only for cache +// performance, and is not strictly enforced (for example, when +// the object is created on the heap). Thus, in order to avoid +// misaligned intrinsics, no SSE instructions shall be involved in +// the ThreadPool implementation. +// Note: alignas is disabled because some compilers do not deal with +// TORCH_API and alignas annotations at the same time. +class TORCH_API /*alignas(kCacheLineSize)*/ ThreadPool { + public: + static ThreadPool* createThreadPool(int numThreads); + static std::unique_ptr defaultThreadPool(); + virtual ~ThreadPool() = default; + // Returns the number of threads currently in use + virtual int getNumThreads() const = 0; + virtual void setNumThreads(size_t numThreads) = 0; + + // Sets the minimum work size (range) for which to invoke the + // threadpool; work sizes smaller than this will just be run on the + // main (calling) thread + void setMinWorkSize(size_t size) { + std::lock_guard guard(executionMutex_); + minWorkSize_ = size; + } + + size_t getMinWorkSize() const { + return minWorkSize_; + } + virtual void run(const std::function& fn, size_t range) = 0; + + // Run an arbitrary function in a thread-safe manner accessing the Workers + // Pool + virtual void withPool(const std::function& fn) = 0; + + protected: + static size_t defaultNumThreads_; + mutable std::mutex executionMutex_; + size_t minWorkSize_; +}; + +size_t getDefaultNumThreads(); +} // namespace caffe2 + +C10_DECLARE_bool(caffe2_threadpool_force_inline); + +// Whether or not threadpool caps apply to Android +C10_DECLARE_int(caffe2_threadpool_android_cap); + +// Whether or not threadpool caps apply to iOS and MacOS +C10_DECLARE_int(caffe2_threadpool_ios_cap); +C10_DECLARE_int(caffe2_threadpool_macos_cap); + +C10_DECLARE_int(pthreadpool_size); +#endif // CAFFE2_UTILS_THREADPOOL_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/ThreadPoolCommon.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/ThreadPoolCommon.h new file mode 100644 index 0000000000000000000000000000000000000000..0bd04aa595c383ea8c1e0cb833e81e5478bc879b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/ThreadPoolCommon.h @@ -0,0 +1,25 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef CAFFE2_UTILS_THREADPOOL_COMMON_H_ +#define CAFFE2_UTILS_THREADPOOL_COMMON_H_ + +#ifdef __APPLE__ +#include +#endif + +// caffe2 depends upon NNPACK, which depends upon this threadpool, so +// unfortunately we can't reference core/common.h here + +// This is copied from core/common.h's definition of C10_MOBILE +// Define enabled when building for iOS or Android devices +#if defined(__ANDROID__) +#define C10_ANDROID 1 +#elif (defined(__APPLE__) && \ + (TARGET_IPHONE_SIMULATOR || TARGET_OS_SIMULATOR || TARGET_OS_IPHONE)) +#define C10_IOS 1 +#endif // ANDROID / IOS + +#endif // CAFFE2_UTILS_THREADPOOL_COMMON_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/WorkersPool.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/WorkersPool.h new file mode 100644 index 0000000000000000000000000000000000000000..a4adbac9b3c1b3a9672b511cb24dda1c48a4622e --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/WorkersPool.h @@ -0,0 +1,383 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include +#include "c10/util/thread_name.h" +#include +#include + +#if defined(_MSC_VER) +#include +#endif + +namespace caffe2 { + +// Uses code derived from gemmlowp, +// https://github.com/google/gemmlowp/blob/6c91e1ed0c2eff1182d804310b92911fe9c18019/internal/multi_thread_gemm.h +// Changes: +// - allocation-free execute() +// - Use RAII where possible. +// - Run the first task on the main thread (since that is the largest task). +// - removed custom allocator. +// - Removed some ifdef's +// - cache-line align Worker. +// - use std::atomic instead of volatile and custom barriers. +// - use std::mutex/std::condition_variable instead of raw pthreads. + +constexpr size_t kGEMMLOWPCacheLineSize = 64; + +template +struct AllocAligned { + // Allocate a T aligned at an `align` byte address + template + static T* alloc(Args&&... args) { + void* p = nullptr; + +#if defined(__ANDROID__) + p = memalign(kGEMMLOWPCacheLineSize, sizeof(T)); +#elif defined(_MSC_VER) + p = _aligned_malloc(sizeof(T), kGEMMLOWPCacheLineSize); +#else + auto res = posix_memalign(&p, kGEMMLOWPCacheLineSize, sizeof(T)); + (void)res; +#endif + + if (p) { + return new (p) T(std::forward(args)...); + } + + return nullptr; + } + + // Free a T previously allocated via AllocAligned::alloc() + static void release(T* p) { + if (p) { + p->~T(); +#if defined(_MSC_VER) + _aligned_free((void*)p); +#else + free((void*)p); +#endif + } + } +}; + +// Deleter object for unique_ptr for an aligned object +template +struct AlignedDeleter { + void operator()(T* p) const { AllocAligned::release(p); } +}; + +// make_unique that guarantees alignment +template +struct MakeAligned { + template + static std::unique_ptr> make(Args&&... args) { + return std::unique_ptr>( + AllocAligned::alloc(std::forward(args)...)); + } +}; + +const int kMaxBusyWaitNOPs = 32 * 1000 * 1000; + +#if defined(_MSC_VER) +#define GEMMLOWP_NOP __nop(); +#else +#define GEMMLOWP_NOP "nop\n" +#endif + +#define GEMMLOWP_STRING_CONCAT_4(X) X X X X +#define GEMMLOWP_NOP4 GEMMLOWP_STRING_CONCAT_4(GEMMLOWP_NOP) +#define GEMMLOWP_NOP16 GEMMLOWP_STRING_CONCAT_4(GEMMLOWP_NOP4) +#define GEMMLOWP_NOP64 GEMMLOWP_STRING_CONCAT_4(GEMMLOWP_NOP16) + +inline int Do256NOPs() { +#if defined(_MSC_VER) + GEMMLOWP_NOP64; +#else + asm volatile(GEMMLOWP_NOP64); +#endif + return 64; +} + +#undef GEMMLOWP_STRING_CONCAT_4 +#undef GEMMLOWP_NOP256 +#undef GEMMLOWP_NOP64 +#undef GEMMLOWP_NOP16 +#undef GEMMLOWP_NOP4 +#undef GEMMLOWP_NOP + +// Waits until *var != initial_value. +// +// Returns the new value of *var. The guarantee here is that +// the return value is different from initial_value, and that that +// new value has been taken by *var at some point during the +// execution of this function. There is no guarantee that this is +// still the value of *var when this function returns, since *var is +// not assumed to be guarded by any lock. +// +// First does some busy-waiting for a fixed number of no-op cycles, +// then falls back to passive waiting for the given condvar, guarded +// by the given mutex. +// +// The idea of doing some initial busy-waiting is to help get +// better and more consistent multithreading benefits for small GEMM sizes. +// Busy-waiting help ensuring that if we need to wake up soon after having +// started waiting, then we can wake up quickly (as opposed to, say, +// having to wait to be scheduled again by the OS). On the other hand, +// we must still eventually revert to passive waiting for longer waits +// (e.g. worker threads having finished a GEMM and waiting until the next GEMM) +// so as to avoid permanently spinning. +// +template +T WaitForVariableChange(std::atomic* var, + T initial_value, + std::condition_variable* cond, + std::mutex* mutex) { + // If we are on a platform that supports it, spin for some time. + { + int nops = 0; + // First, trivial case where the variable already changed value. + T new_value = var->load(std::memory_order_relaxed); + if (new_value != initial_value) { + std::atomic_thread_fence(std::memory_order_acquire); + return new_value; + } + // Then try busy-waiting. + while (nops < kMaxBusyWaitNOPs) { + nops += Do256NOPs(); + new_value = var->load(std::memory_order_relaxed); + if (new_value != initial_value) { + std::atomic_thread_fence(std::memory_order_acquire); + return new_value; + } + } + } + + // Finally, do real passive waiting. + { + std::unique_lock g(*mutex); + T new_value = var->load(std::memory_order_relaxed); + // Handle spurious wakeups. + cond->wait(g, [&]() { + new_value = var->load(std::memory_order_relaxed); + return new_value != initial_value; + }); + TORCH_DCHECK_NE(static_cast(new_value), static_cast(initial_value)); + return new_value; + } +} + +// A BlockingCounter lets one thread to wait for N events to occur. +// This is how the master thread waits for all the worker threads +// to have finished working. +class BlockingCounter { + public: + // Sets/resets the counter; initial_count is the number of + // decrementing events that the Wait() call will be waiting for. + void Reset(std::size_t initial_count) { + std::lock_guard g(mutex_); + TORCH_DCHECK_EQ(count_, 0); + count_ = initial_count; + } + + // Decrements the counter; if the counter hits zero, signals + // the thread that was waiting for that, and returns true. + // Otherwise (if the decremented count is still nonzero), + // returns false. + bool DecrementCount() { + const auto count_value = count_.fetch_sub(1, std::memory_order_relaxed) - 1; + if (count_value == 0) { + std::lock_guard g(mutex_); + cond_.notify_one(); + } + bool retval = count_value == 0; + return retval; + } + + // Waits for the N other threads (N having been set by Reset()) + // to hit the BlockingCounter. + void Wait() { + while (size_t count_value = count_.load(std::memory_order_relaxed)) { + WaitForVariableChange(&count_, count_value, &cond_, &mutex_); + } + } + + private: + std::condition_variable cond_; + std::mutex mutex_; + std::atomic count_{0}; +}; + +// A workload for a worker. +struct Task { + Task() = default; + virtual ~Task() = default; + virtual void Run() = 0; +}; + +// A worker thread. +class alignas(kGEMMLOWPCacheLineSize) Worker { + public: + enum class State : uint8_t { + ThreadStartup, // The initial state before the thread main loop runs. + Ready, // Is not working, has not yet received new work to do. + HasWork, // Has work to do. + ExitAsSoonAsPossible // Should exit at earliest convenience. + }; + + explicit Worker(BlockingCounter* counter_to_decrement_when_ready) + : task_(nullptr), + state_(State::ThreadStartup), + counter_to_decrement_when_ready_(counter_to_decrement_when_ready) { + thread_ = std::make_unique([this]() { + c10::setThreadName("pt_thread_pool"); + this->ThreadFunc(); + }); + } + + ~Worker() { + ChangeState(State::ExitAsSoonAsPossible); + thread_->join(); + } + + // Changes State; may be called from either the worker thread + // or the master thread; however, not all state transitions are legal, + // which is guarded by assertions. + void ChangeState(State new_state) { + std::lock_guard g(state_mutex_); + DCHECK(new_state != state_.load(std::memory_order_relaxed)); + switch (state_.load(std::memory_order_relaxed)) { + case State::ThreadStartup: + DCHECK(new_state == State::Ready); + break; + case State::Ready: + DCHECK(new_state == State::HasWork || new_state == State::ExitAsSoonAsPossible); + break; + case State::HasWork: + DCHECK(new_state == State::Ready || new_state == State::ExitAsSoonAsPossible); + break; + case State::ExitAsSoonAsPossible: + default: + abort(); + } + state_.store(new_state, std::memory_order_relaxed); + state_cond_.notify_one(); + if (new_state == State::Ready) { + counter_to_decrement_when_ready_->DecrementCount(); + } + } + + // Thread entry point. + void ThreadFunc() { + c10::setThreadName("CaffeWorkersPool"); + ChangeState(State::Ready); + + // Thread main loop + while (true) { + // Get a state to act on + // In the 'Ready' state, we have nothing to do but to wait until + // we switch to another state. + State state_to_act_upon = + WaitForVariableChange(&state_, State::Ready, &state_cond_, &state_mutex_); + + // We now have a state to act on, so act. + switch (state_to_act_upon) { + case State::HasWork: + // Got work to do! So do it, and then revert to 'Ready' state. + DCHECK(task_.load()); + (*task_).Run(); + task_ = nullptr; + ChangeState(State::Ready); + break; + case State::ExitAsSoonAsPossible: + return; + case State::Ready: + case State::ThreadStartup: + default: + abort(); + } + } + } + + static void* ThreadFunc(void* arg) { + static_cast(arg)->ThreadFunc(); + return nullptr; + } + + // Called by the master thread to give this worker work to do. + // It is only legal to call this if the worker + void StartWork(Task* task) { + DCHECK(!task_.load()); + task_ = task; + DCHECK(state_.load(std::memory_order_acquire) == State::Ready); + ChangeState(State::HasWork); + } + + private: + // The underlying thread. + std::unique_ptr thread_; + + // The task to be worked on. + std::atomic task_; + + // The condition variable and mutex guarding state changes. + std::condition_variable state_cond_; + std::mutex state_mutex_; + + // The state enum tells if we're currently working, waiting for work, etc. + std::atomic state_; + + // pointer to the master's thread BlockingCounter object, to notify the + // master thread of when this worker switches to the 'Ready' state. + BlockingCounter* const counter_to_decrement_when_ready_; +}; + +class WorkersPool { + public: + WorkersPool() = default; + + void Execute(const std::vector>& tasks) { + CAFFE_ENFORCE_GE(tasks.size(), 1); + // One of the tasks will be run on the current thread. + int workers_count = tasks.size() - 1; + CreateWorkers(workers_count); + TORCH_DCHECK_LE(workers_count, (int)workers_.size()); + counter_to_decrement_when_ready_.Reset(workers_count); + for (const auto task : c10::irange(1, tasks.size())) { + workers_[task - 1]->StartWork(tasks[task].get()); + } + // Execute the remaining workload immediately on the current thread. + auto& task = tasks.front(); + task->Run(); + // Wait for the workers submitted above to finish. + counter_to_decrement_when_ready_.Wait(); + } + + private: + // Ensures that the pool has at least the given count of workers. + // If any new worker has to be created, this function waits for it to + // be ready. + void CreateWorkers(std::size_t workers_count) { + if (workers_.size() >= workers_count) { + return; + } + counter_to_decrement_when_ready_.Reset(workers_count - workers_.size()); + while (workers_.size() < workers_count) { + workers_.push_back(MakeAligned::make(&counter_to_decrement_when_ready_)); + } + counter_to_decrement_when_ready_.Wait(); + } + + C10_DISABLE_COPY_AND_ASSIGN(WorkersPool); + std::vector>> workers_; + // The BlockingCounter used to wait for the workers. + BlockingCounter counter_to_decrement_when_ready_; +}; +} // namespace caffe2 + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/pthreadpool-cpp.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/pthreadpool-cpp.h new file mode 100644 index 0000000000000000000000000000000000000000..cb9a01d3bd2ec1bc12d5290b965f18d9bb0cbfb4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/pthreadpool-cpp.h @@ -0,0 +1,60 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#ifdef USE_PTHREADPOOL + +#ifdef USE_INTERNAL_PTHREADPOOL_IMPL +#include +#else +#include +#endif + +#include +#include +#include + +namespace caffe2 { + +class PThreadPool final { + public: + explicit PThreadPool(size_t thread_count); + ~PThreadPool() = default; + + PThreadPool(const PThreadPool&) = delete; + PThreadPool& operator=(const PThreadPool&) = delete; + + PThreadPool(PThreadPool&&) = delete; + PThreadPool& operator=(PThreadPool&&) = delete; + + size_t get_thread_count() const; + void set_thread_count(size_t thread_count); + + // Run, in parallel, function fn(task_id) over task_id in range [0, range). + // This function is blocking. All input is processed by the time it returns. + void run(const std::function& fn, size_t range); + + private: + friend pthreadpool_t pthreadpool_(); + + private: + mutable std::mutex mutex_; + std::unique_ptr threadpool_; +}; + +// Return a singleton instance of PThreadPool for ATen/TH multithreading. +PThreadPool* pthreadpool(); +PThreadPool* pthreadpool(size_t thread_count); + +// Exposes the underlying implementation of PThreadPool. +// Only for use in external libraries so as to unify threading across +// internal (i.e. ATen, etc.) and external (e.g. NNPACK, QNNPACK, XNNPACK) +// use cases. +pthreadpool_t pthreadpool_(); + +} // namespace caffe2 + +#endif /* USE_PTHREADPOOL */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/pthreadpool.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/pthreadpool.h new file mode 100644 index 0000000000000000000000000000000000000000..ff7ff896b589dff1f51abd155e685fe2ee231750 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/pthreadpool.h @@ -0,0 +1,198 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// pthreadpool header from https://github.com/Maratyszcza/pthreadpool +// for NNPACK +#ifndef CAFFE2_UTILS_PTHREADPOOL_H_ +#define CAFFE2_UTILS_PTHREADPOOL_H_ + +#include "ThreadPoolCommon.h" + +#include // for size_t +#include // for uint32_t + +#if defined(USE_PTHREADPOOL) +// This is a hack. +// Mainly introduced here because +// 1. NNPACK can be compiled to use internal legacy threadpool implementation because much of C2 depends on that. +// 2. Then if we want to use NNPACK in PyTorch, which uses new pthreadpool, then we will supply new pthreadpool pointer +// to NNPACK. This will not work if NNPACK is compiled with internal legacy threadpool. Thus this guard +// along with changes in pthreadpool_impl.cc allows us to override that behavior. +// It enables us to use NNPACK from pytorch using `caffe2::pthreadpool_()` +namespace caffe2 { +class WithCastToNewThreadPool { + public: + explicit WithCastToNewThreadPool(bool use_new_threadpool); + ~WithCastToNewThreadPool(); + private: + bool use_new_threadpool_; +}; +} +#endif + +typedef struct pthreadpool* legacy_pthreadpool_t; + +typedef void (*legacy_pthreadpool_function_1d_t)(void*, size_t); +typedef void (*legacy_pthreadpool_function_1d_tiled_t)(void*, size_t, size_t); +typedef void (*legacy_pthreadpool_function_2d_t)(void*, size_t, size_t); +typedef void (*legacy_pthreadpool_function_2d_tiled_t)(void*, size_t, size_t, size_t, size_t); +typedef void (*legacy_pthreadpool_function_3d_tiled_t)( + void*, + size_t, + size_t, + size_t, + size_t, + size_t, + size_t); +typedef void (*legacy_pthreadpool_function_4d_tiled_t)( + void*, + size_t, + size_t, + size_t, + size_t, + size_t, + size_t, + size_t, + size_t); + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Creates a thread pool with the specified number of threads. + * + * @param[in] threads_count The number of threads in the thread pool. + * A value of 0 has special interpretation: it creates a thread for each + * processor core available in the system. + * + * @returns A pointer to an opaque thread pool object. + * On error the function returns NULL and sets errno accordingly. + */ + +// Returns internal threadpool impl. +legacy_pthreadpool_t legacy_pthreadpool_create(size_t threads_count); + +/** + * Queries the number of threads in a thread pool. + * + * @param[in] threadpool The thread pool to query. + * + * @returns The number of threads in the thread pool. + */ +size_t legacy_pthreadpool_get_threads_count(legacy_pthreadpool_t threadpool); + +/** + * Processes items in parallel using threads from a thread pool. + * + * When the call returns, all items have been processed and the thread pool is + * ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param[in] threadpool The thread pool to use for parallelisation. + * @param[in] function The function to call for each item. + * @param[in] argument The first argument passed to the @a function. + * @param[in] items The number of items to process. The @a function + * will be called once for each item. + */ +void legacy_pthreadpool_compute_1d( + legacy_pthreadpool_t threadpool, + legacy_pthreadpool_function_1d_t function, + void* argument, + size_t range); + +void legacy_pthreadpool_parallelize_1d( + legacy_pthreadpool_t threadpool, + legacy_pthreadpool_function_1d_t function, + void* argument, + size_t range, + uint32_t flags); + +void legacy_pthreadpool_compute_1d_tiled( + legacy_pthreadpool_t threadpool, + legacy_pthreadpool_function_1d_tiled_t function, + void* argument, + size_t range, + size_t tile); + +void legacy_pthreadpool_compute_2d( + legacy_pthreadpool_t threadpool, + legacy_pthreadpool_function_2d_t function, + void* argument, + size_t range_i, + size_t range_j); + +void legacy_pthreadpool_compute_2d_tiled( + legacy_pthreadpool_t threadpool, + legacy_pthreadpool_function_2d_tiled_t function, + void* argument, + size_t range_i, + size_t range_j, + size_t tile_i, + size_t tile_j); + +void legacy_pthreadpool_compute_3d_tiled( + legacy_pthreadpool_t threadpool, + legacy_pthreadpool_function_3d_tiled_t function, + void* argument, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_i, + size_t tile_j, + size_t tile_k); + +void legacy_pthreadpool_compute_4d_tiled( + legacy_pthreadpool_t threadpool, + legacy_pthreadpool_function_4d_tiled_t function, + void* argument, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t tile_i, + size_t tile_j, + size_t tile_k, + size_t tile_l); + +/** + * Terminates threads in the thread pool and releases associated resources. + * + * @warning Accessing the thread pool after a call to this function constitutes + * undefined behaviour and may cause data corruption. + * + * @param[in,out] threadpool The thread pool to destroy. + */ +void legacy_pthreadpool_destroy(legacy_pthreadpool_t threadpool); + +#ifdef USE_INTERNAL_PTHREADPOOL_IMPL + +#define pthreadpool_t legacy_pthreadpool_t +#define pthreadpool_function_1d_t legacy_pthreadpool_function_1d_t +#define pthreadpool_function_1d_tiled_t legacy_pthreadpool_function_1d_tiled_t +#define pthreadpool_function_2d_t legacy_pthreadpool_function_2d_t +#define pthreadpool_function_2d_tiled_t legacy_pthreadpool_function_2d_tiled_t +#define pthreadpool_function_3d_tiled_t legacy_pthreadpool_function_3d_tiled_t +#define pthreadpool_function_4d_tiled_t legacy_pthreadpool_function_4d_tiled_t +#define pthreadpool_create legacy_pthreadpool_create +#define pthreadpool_destroy legacy_pthreadpool_destroy +#define pthreadpool_get_threads_count legacy_pthreadpool_get_threads_count +#define pthreadpool_compute_1d legacy_pthreadpool_compute_1d +#define pthreadpool_parallelize_1d legacy_pthreadpool_parallelize_1d +#define pthreadpool_compute_1d_tiled legacy_pthreadpool_compute_1d_tiled +#define pthreadpool_compute_2d legacy_pthreadpool_compute_2d +#define pthreadpool_compute_2d_tiled legacy_pthreadpool_compute_2d_tiled +#define pthreadpool_compute_3d_tiled legacy_pthreadpool_compute_3d_tiled +#define pthreadpool_compute_4d_tiled legacy_pthreadpool_compute_4d_tiled + +#endif /* USE_INTERNAL_PTHREADPOOL_IMPL */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // CAFFE2_UTILS_PTHREADPOOL_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/thread_pool_guard.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/thread_pool_guard.h new file mode 100644 index 0000000000000000000000000000000000000000..cb76646e6f61bdc1540bacd7dcbf88b4aa09b5f4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/thread_pool_guard.h @@ -0,0 +1,28 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +namespace caffe2 { + +// A RAII, thread local (!) guard that enables or disables grad mode upon +// construction, and sets it back to the original value upon destruction. +struct TORCH_API _NoPThreadPoolGuard { + static bool is_enabled(); + static void set_enabled(bool enabled); + + _NoPThreadPoolGuard(): prev_mode_(_NoPThreadPoolGuard::is_enabled()) { + _NoPThreadPoolGuard::set_enabled(true); + } + ~_NoPThreadPoolGuard() { + _NoPThreadPoolGuard::set_enabled(prev_mode_); + } + private: + bool prev_mode_; +}; + +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/clog.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/clog.h new file mode 100644 index 0000000000000000000000000000000000000000..e12d3ecc0efbfbcfd577d5a6cef63b65587e5014 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/clog.h @@ -0,0 +1,128 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +#define CLOG_NONE 0 +#define CLOG_FATAL 1 +#define CLOG_ERROR 2 +#define CLOG_WARNING 3 +#define CLOG_INFO 4 +#define CLOG_DEBUG 5 + +#ifndef CLOG_VISIBILITY +#if defined(__ELF__) +#define CLOG_VISIBILITY __attribute__((__visibility__("internal"))) +#elif defined(__MACH__) +#define CLOG_VISIBILITY __attribute__((__visibility__("hidden"))) +#else +#define CLOG_VISIBILITY +#endif +#endif + +#ifndef CLOG_ARGUMENTS_FORMAT +#if defined(__GNUC__) +#define CLOG_ARGUMENTS_FORMAT __attribute__((__format__(__printf__, 1, 2))) +#else +#define CLOG_ARGUMENTS_FORMAT +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +CLOG_VISIBILITY void clog_vlog_debug( + const char* module, + const char* format, + va_list args); +CLOG_VISIBILITY void clog_vlog_info( + const char* module, + const char* format, + va_list args); +CLOG_VISIBILITY void clog_vlog_warning( + const char* module, + const char* format, + va_list args); +CLOG_VISIBILITY void clog_vlog_error( + const char* module, + const char* format, + va_list args); +CLOG_VISIBILITY void clog_vlog_fatal( + const char* module, + const char* format, + va_list args); + +#define CLOG_DEFINE_LOG_DEBUG(log_debug_function_name, module, level) \ + CLOG_ARGUMENTS_FORMAT \ + inline static void log_debug_function_name(const char* format, ...) { \ + if (level >= CLOG_DEBUG) { \ + va_list args; \ + va_start(args, format); \ + clog_vlog_debug(module, format, args); \ + va_end(args); \ + } \ + } + +#define CLOG_DEFINE_LOG_INFO(log_info_function_name, module, level) \ + CLOG_ARGUMENTS_FORMAT \ + inline static void log_info_function_name(const char* format, ...) { \ + if (level >= CLOG_INFO) { \ + va_list args; \ + va_start(args, format); \ + clog_vlog_info(module, format, args); \ + va_end(args); \ + } \ + } + +#define CLOG_DEFINE_LOG_WARNING(log_warning_function_name, module, level) \ + CLOG_ARGUMENTS_FORMAT \ + inline static void log_warning_function_name(const char* format, ...) { \ + if (level >= CLOG_WARNING) { \ + va_list args; \ + va_start(args, format); \ + clog_vlog_warning(module, format, args); \ + va_end(args); \ + } \ + } + +#define CLOG_DEFINE_LOG_ERROR(log_error_function_name, module, level) \ + CLOG_ARGUMENTS_FORMAT \ + inline static void log_error_function_name(const char* format, ...) { \ + if (level >= CLOG_ERROR) { \ + va_list args; \ + va_start(args, format); \ + clog_vlog_error(module, format, args); \ + va_end(args); \ + } \ + } + +#define CLOG_DEFINE_LOG_FATAL(log_fatal_function_name, module, level) \ + CLOG_ARGUMENTS_FORMAT \ + inline static void log_fatal_function_name(const char* format, ...) { \ + if (level >= CLOG_FATAL) { \ + va_list args; \ + va_start(args, format); \ + clog_vlog_fatal(module, format, args); \ + va_end(args); \ + } \ + abort(); \ + } + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/cpuinfo.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/cpuinfo.h new file mode 100644 index 0000000000000000000000000000000000000000..3b2429f42848c6d971003d3f24a0a00eda806ade --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/cpuinfo.h @@ -0,0 +1,2366 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#ifndef CPUINFO_H +#define CPUINFO_H + +#ifndef __cplusplus +#include +#endif + +#ifdef __APPLE__ +#include +#endif + +#include + +/* Identify architecture and define corresponding macro */ + +#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) +#define CPUINFO_ARCH_X86 1 +#endif + +#if defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) +#define CPUINFO_ARCH_X86_64 1 +#endif + +#if defined(__arm__) || defined(_M_ARM) +#define CPUINFO_ARCH_ARM 1 +#endif + +#if defined(__aarch64__) || defined(_M_ARM64) +#define CPUINFO_ARCH_ARM64 1 +#endif + +#if defined(__PPC64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) +#define CPUINFO_ARCH_PPC64 1 +#endif + +#if defined(__asmjs__) +#define CPUINFO_ARCH_ASMJS 1 +#endif + +#if defined(__wasm__) +#if defined(__wasm_simd128__) +#define CPUINFO_ARCH_WASMSIMD 1 +#else +#define CPUINFO_ARCH_WASM 1 +#endif +#endif + +#if defined(__riscv) +#if (__riscv_xlen == 32) +#define CPUINFO_ARCH_RISCV32 1 +#elif (__riscv_xlen == 64) +#define CPUINFO_ARCH_RISCV64 1 +#endif +#endif + +/* Define other architecture-specific macros as 0 */ + +#ifndef CPUINFO_ARCH_X86 +#define CPUINFO_ARCH_X86 0 +#endif + +#ifndef CPUINFO_ARCH_X86_64 +#define CPUINFO_ARCH_X86_64 0 +#endif + +#ifndef CPUINFO_ARCH_ARM +#define CPUINFO_ARCH_ARM 0 +#endif + +#ifndef CPUINFO_ARCH_ARM64 +#define CPUINFO_ARCH_ARM64 0 +#endif + +#ifndef CPUINFO_ARCH_PPC64 +#define CPUINFO_ARCH_PPC64 0 +#endif + +#ifndef CPUINFO_ARCH_ASMJS +#define CPUINFO_ARCH_ASMJS 0 +#endif + +#ifndef CPUINFO_ARCH_WASM +#define CPUINFO_ARCH_WASM 0 +#endif + +#ifndef CPUINFO_ARCH_WASMSIMD +#define CPUINFO_ARCH_WASMSIMD 0 +#endif + +#ifndef CPUINFO_ARCH_RISCV32 +#define CPUINFO_ARCH_RISCV32 0 +#endif + +#ifndef CPUINFO_ARCH_RISCV64 +#define CPUINFO_ARCH_RISCV64 0 +#endif + +#if CPUINFO_ARCH_X86 && defined(_MSC_VER) +#define CPUINFO_ABI __cdecl +#elif CPUINFO_ARCH_X86 && defined(__GNUC__) +#define CPUINFO_ABI __attribute__((__cdecl__)) +#else +#define CPUINFO_ABI +#endif + +#define CPUINFO_CACHE_UNIFIED 0x00000001 +#define CPUINFO_CACHE_INCLUSIVE 0x00000002 +#define CPUINFO_CACHE_COMPLEX_INDEXING 0x00000004 + +struct cpuinfo_cache { + /** Cache size in bytes */ + uint32_t size; + /** Number of ways of associativity */ + uint32_t associativity; + /** Number of sets */ + uint32_t sets; + /** Number of partitions */ + uint32_t partitions; + /** Line size in bytes */ + uint32_t line_size; + /** + * Binary characteristics of the cache (unified cache, inclusive cache, + * cache with complex indexing). + * + * @see CPUINFO_CACHE_UNIFIED, CPUINFO_CACHE_INCLUSIVE, + * CPUINFO_CACHE_COMPLEX_INDEXING + */ + uint32_t flags; + /** Index of the first logical processor that shares this cache */ + uint32_t processor_start; + /** Number of logical processors that share this cache */ + uint32_t processor_count; +}; + +struct cpuinfo_trace_cache { + uint32_t uops; + uint32_t associativity; +}; + +#define CPUINFO_PAGE_SIZE_4KB 0x1000 +#define CPUINFO_PAGE_SIZE_1MB 0x100000 +#define CPUINFO_PAGE_SIZE_2MB 0x200000 +#define CPUINFO_PAGE_SIZE_4MB 0x400000 +#define CPUINFO_PAGE_SIZE_16MB 0x1000000 +#define CPUINFO_PAGE_SIZE_1GB 0x40000000 + +struct cpuinfo_tlb { + uint32_t entries; + uint32_t associativity; + uint64_t pages; +}; + +/** Vendor of processor core design */ +enum cpuinfo_vendor { + /** Processor vendor is not known to the library, or the library failed + to get vendor information from the OS. */ + cpuinfo_vendor_unknown = 0, + + /* Active vendors of modern CPUs */ + + /** + * Intel Corporation. Vendor of x86, x86-64, IA64, and ARM processor + * microarchitectures. + * + * Sold its ARM design subsidiary in 2006. The last ARM processor design + * was released in 2004. + */ + cpuinfo_vendor_intel = 1, + /** Advanced Micro Devices, Inc. Vendor of x86 and x86-64 processor + microarchitectures. */ + cpuinfo_vendor_amd = 2, + /** ARM Holdings plc. Vendor of ARM and ARM64 processor + microarchitectures. */ + cpuinfo_vendor_arm = 3, + /** Qualcomm Incorporated. Vendor of ARM and ARM64 processor + microarchitectures. */ + cpuinfo_vendor_qualcomm = 4, + /** Apple Inc. Vendor of ARM and ARM64 processor microarchitectures. */ + cpuinfo_vendor_apple = 5, + /** Samsung Electronics Co., Ltd. Vendir if ARM64 processor + microarchitectures. */ + cpuinfo_vendor_samsung = 6, + /** Nvidia Corporation. Vendor of ARM64-compatible processor + microarchitectures. */ + cpuinfo_vendor_nvidia = 7, + /** MIPS Technologies, Inc. Vendor of MIPS processor microarchitectures. + */ + cpuinfo_vendor_mips = 8, + /** International Business Machines Corporation. Vendor of PowerPC + processor microarchitectures. */ + cpuinfo_vendor_ibm = 9, + /** Ingenic Semiconductor. Vendor of MIPS processor microarchitectures. + */ + cpuinfo_vendor_ingenic = 10, + /** + * VIA Technologies, Inc. Vendor of x86 and x86-64 processor + * microarchitectures. + * + * Processors are designed by Centaur Technology, a subsidiary of VIA + * Technologies. + */ + cpuinfo_vendor_via = 11, + /** Cavium, Inc. Vendor of ARM64 processor microarchitectures. */ + cpuinfo_vendor_cavium = 12, + /** Broadcom, Inc. Vendor of ARM processor microarchitectures. */ + cpuinfo_vendor_broadcom = 13, + /** Applied Micro Circuits Corporation (APM). Vendor of ARM64 processor + microarchitectures. */ + cpuinfo_vendor_apm = 14, + /** + * Huawei Technologies Co., Ltd. Vendor of ARM64 processor + * microarchitectures. + * + * Processors are designed by HiSilicon, a subsidiary of Huawei. + */ + cpuinfo_vendor_huawei = 15, + /** + * Hygon (Chengdu Haiguang Integrated Circuit Design Co., Ltd), Vendor + * of x86-64 processor microarchitectures. + * + * Processors are variants of AMD cores. + */ + cpuinfo_vendor_hygon = 16, + /** SiFive, Inc. Vendor of RISC-V processor microarchitectures. */ + cpuinfo_vendor_sifive = 17, + + /* Active vendors of embedded CPUs */ + + /** Texas Instruments Inc. Vendor of ARM processor microarchitectures. + */ + cpuinfo_vendor_texas_instruments = 30, + /** Marvell Technology Group Ltd. Vendor of ARM processor + * microarchitectures. + */ + cpuinfo_vendor_marvell = 31, + /** RDC Semiconductor Co., Ltd. Vendor of x86 processor + microarchitectures. */ + cpuinfo_vendor_rdc = 32, + /** DM&P Electronics Inc. Vendor of x86 processor microarchitectures. */ + cpuinfo_vendor_dmp = 33, + /** Motorola, Inc. Vendor of PowerPC and ARM processor + microarchitectures. */ + cpuinfo_vendor_motorola = 34, + + /* Defunct CPU vendors */ + + /** + * Transmeta Corporation. Vendor of x86 processor microarchitectures. + * + * Now defunct. The last processor design was released in 2004. + * Transmeta processors implemented VLIW ISA and used binary translation + * to execute x86 code. + */ + cpuinfo_vendor_transmeta = 50, + /** + * Cyrix Corporation. Vendor of x86 processor microarchitectures. + * + * Now defunct. The last processor design was released in 1996. + */ + cpuinfo_vendor_cyrix = 51, + /** + * Rise Technology. Vendor of x86 processor microarchitectures. + * + * Now defunct. The last processor design was released in 1999. + */ + cpuinfo_vendor_rise = 52, + /** + * National Semiconductor. Vendor of x86 processor microarchitectures. + * + * Sold its x86 design subsidiary in 1999. The last processor design was + * released in 1998. + */ + cpuinfo_vendor_nsc = 53, + /** + * Silicon Integrated Systems. Vendor of x86 processor + * microarchitectures. + * + * Sold its x86 design subsidiary in 2001. The last processor design was + * released in 2001. + */ + cpuinfo_vendor_sis = 54, + /** + * NexGen. Vendor of x86 processor microarchitectures. + * + * Now defunct. The last processor design was released in 1994. + * NexGen designed the first x86 microarchitecture which decomposed x86 + * instructions into simple microoperations. + */ + cpuinfo_vendor_nexgen = 55, + /** + * United Microelectronics Corporation. Vendor of x86 processor + * microarchitectures. + * + * Ceased x86 in the early 1990s. The last processor design was released + * in 1991. Designed U5C and U5D processors. Both are 486 level. + */ + cpuinfo_vendor_umc = 56, + /** + * Digital Equipment Corporation. Vendor of ARM processor + * microarchitecture. + * + * Sold its ARM designs in 1997. The last processor design was released + * in 1997. + */ + cpuinfo_vendor_dec = 57, +}; + +/** + * Processor microarchitecture + * + * Processors with different microarchitectures often have different instruction + * performance characteristics, and may have dramatically different pipeline + * organization. + */ +enum cpuinfo_uarch { + /** Microarchitecture is unknown, or the library failed to get + information about the microarchitecture from OS */ + cpuinfo_uarch_unknown = 0, + + /** Pentium and Pentium MMX microarchitecture. */ + cpuinfo_uarch_p5 = 0x00100100, + /** Intel Quark microarchitecture. */ + cpuinfo_uarch_quark = 0x00100101, + + /** Pentium Pro, Pentium II, and Pentium III. */ + cpuinfo_uarch_p6 = 0x00100200, + /** Pentium M. */ + cpuinfo_uarch_dothan = 0x00100201, + /** Intel Core microarchitecture. */ + cpuinfo_uarch_yonah = 0x00100202, + /** Intel Core 2 microarchitecture on 65 nm process. */ + cpuinfo_uarch_conroe = 0x00100203, + /** Intel Core 2 microarchitecture on 45 nm process. */ + cpuinfo_uarch_penryn = 0x00100204, + /** Intel Nehalem and Westmere microarchitectures (Core i3/i5/i7 1st + gen). */ + cpuinfo_uarch_nehalem = 0x00100205, + /** Intel Sandy Bridge microarchitecture (Core i3/i5/i7 2nd gen). */ + cpuinfo_uarch_sandy_bridge = 0x00100206, + /** Intel Ivy Bridge microarchitecture (Core i3/i5/i7 3rd gen). */ + cpuinfo_uarch_ivy_bridge = 0x00100207, + /** Intel Haswell microarchitecture (Core i3/i5/i7 4th gen). */ + cpuinfo_uarch_haswell = 0x00100208, + /** Intel Broadwell microarchitecture. */ + cpuinfo_uarch_broadwell = 0x00100209, + /** Intel Sky Lake microarchitecture (14 nm, including + Kaby/Coffee/Whiskey/Amber/Comet/Cascade/Cooper Lake). */ + cpuinfo_uarch_sky_lake = 0x0010020A, + /** DEPRECATED (Intel Kaby Lake microarchitecture). */ + cpuinfo_uarch_kaby_lake = 0x0010020A, + /** Intel Palm Cove microarchitecture (10 nm, Cannon Lake). */ + cpuinfo_uarch_palm_cove = 0x0010020B, + /** Intel Sunny Cove microarchitecture (10 nm, Ice Lake). */ + cpuinfo_uarch_sunny_cove = 0x0010020C, + /** Intel Willow Cove microarchitecture (10 nm, Tiger Lake). */ + cpuinfo_uarch_willow_cove = 0x0010020D, + + /** Pentium 4 with Willamette, Northwood, or Foster cores. */ + cpuinfo_uarch_willamette = 0x00100300, + /** Pentium 4 with Prescott and later cores. */ + cpuinfo_uarch_prescott = 0x00100301, + + /** Intel Atom on 45 nm process. */ + cpuinfo_uarch_bonnell = 0x00100400, + /** Intel Atom on 32 nm process. */ + cpuinfo_uarch_saltwell = 0x00100401, + /** Intel Silvermont microarchitecture (22 nm out-of-order Atom). */ + cpuinfo_uarch_silvermont = 0x00100402, + /** Intel Airmont microarchitecture (14 nm out-of-order Atom). */ + cpuinfo_uarch_airmont = 0x00100403, + /** Intel Goldmont microarchitecture (Denverton, Apollo Lake). */ + cpuinfo_uarch_goldmont = 0x00100404, + /** Intel Goldmont Plus microarchitecture (Gemini Lake). */ + cpuinfo_uarch_goldmont_plus = 0x00100405, + /** Intel Airmont microarchitecture (10 nm out-of-order Atom). */ + cpuinfo_uarch_tremont = 0x00100406, + /** Intel Gracemont microarchitecture (AlderLake N). */ + cpuinfo_uarch_gracemont = 0x00100407, + /** Intel Crestmont microarchitecture (Sierra Forest). */ + cpuinfo_uarch_crestmont = 0x00100408, + /** Intel Darkmont microarchitecture (e-core used in Clearwater Forest). */ + cpuinfo_uarch_darkmont = 0x00100409, + + /** Intel Knights Ferry HPC boards. */ + cpuinfo_uarch_knights_ferry = 0x00100500, + /** Intel Knights Corner HPC boards (aka Xeon Phi). */ + cpuinfo_uarch_knights_corner = 0x00100501, + /** Intel Knights Landing microarchitecture (second-gen MIC). */ + cpuinfo_uarch_knights_landing = 0x00100502, + /** Intel Knights Hill microarchitecture (third-gen MIC). */ + cpuinfo_uarch_knights_hill = 0x00100503, + /** Intel Knights Mill Xeon Phi. */ + cpuinfo_uarch_knights_mill = 0x00100504, + + /** Intel/Marvell XScale series. */ + cpuinfo_uarch_xscale = 0x00100600, + + /** AMD K5. */ + cpuinfo_uarch_k5 = 0x00200100, + /** AMD K6 and alike. */ + cpuinfo_uarch_k6 = 0x00200101, + /** AMD Athlon and Duron. */ + cpuinfo_uarch_k7 = 0x00200102, + /** AMD Athlon 64, Opteron 64. */ + cpuinfo_uarch_k8 = 0x00200103, + /** AMD Family 10h (Barcelona, Istambul, Magny-Cours). */ + cpuinfo_uarch_k10 = 0x00200104, + /** + * AMD Bulldozer microarchitecture + * Zambezi FX-series CPUs, Zurich, Valencia and Interlagos Opteron CPUs. + */ + cpuinfo_uarch_bulldozer = 0x00200105, + /** + * AMD Piledriver microarchitecture + * Vishera FX-series CPUs, Trinity and Richland APUs, Delhi, Seoul, Abu + * Dhabi Opteron CPUs. + */ + cpuinfo_uarch_piledriver = 0x00200106, + /** AMD Steamroller microarchitecture (Kaveri APUs). */ + cpuinfo_uarch_steamroller = 0x00200107, + /** AMD Excavator microarchitecture (Carizzo APUs). */ + cpuinfo_uarch_excavator = 0x00200108, + /** AMD Zen microarchitecture (12/14 nm Ryzen and EPYC CPUs). */ + cpuinfo_uarch_zen = 0x00200109, + /** AMD Zen 2 microarchitecture (7 nm Ryzen and EPYC CPUs). */ + cpuinfo_uarch_zen2 = 0x0020010A, + /** AMD Zen 3 microarchitecture. */ + cpuinfo_uarch_zen3 = 0x0020010B, + /** AMD Zen 4 microarchitecture. */ + cpuinfo_uarch_zen4 = 0x0020010C, + /** AMD Zen 5 microarchitecture. */ + cpuinfo_uarch_zen5 = 0x0020010D, + + /** NSC Geode and AMD Geode GX and LX. */ + cpuinfo_uarch_geode = 0x00200200, + /** AMD Bobcat mobile microarchitecture. */ + cpuinfo_uarch_bobcat = 0x00200201, + /** AMD Jaguar mobile microarchitecture. */ + cpuinfo_uarch_jaguar = 0x00200202, + /** AMD Puma mobile microarchitecture. */ + cpuinfo_uarch_puma = 0x00200203, + + /** ARM7 series. */ + cpuinfo_uarch_arm7 = 0x00300100, + /** ARM9 series. */ + cpuinfo_uarch_arm9 = 0x00300101, + /** ARM 1136, ARM 1156, ARM 1176, or ARM 11MPCore. */ + cpuinfo_uarch_arm11 = 0x00300102, + + /** ARM Cortex-A5. */ + cpuinfo_uarch_cortex_a5 = 0x00300205, + /** ARM Cortex-A7. */ + cpuinfo_uarch_cortex_a7 = 0x00300207, + /** ARM Cortex-A8. */ + cpuinfo_uarch_cortex_a8 = 0x00300208, + /** ARM Cortex-A9. */ + cpuinfo_uarch_cortex_a9 = 0x00300209, + /** ARM Cortex-A12. */ + cpuinfo_uarch_cortex_a12 = 0x00300212, + /** ARM Cortex-A15. */ + cpuinfo_uarch_cortex_a15 = 0x00300215, + /** ARM Cortex-A17. */ + cpuinfo_uarch_cortex_a17 = 0x00300217, + + /** ARM Cortex-A32. */ + cpuinfo_uarch_cortex_a32 = 0x00300332, + /** ARM Cortex-A35. */ + cpuinfo_uarch_cortex_a35 = 0x00300335, + /** ARM Cortex-A53. */ + cpuinfo_uarch_cortex_a53 = 0x00300353, + /** ARM Cortex-A55 revision 0 (restricted dual-issue capabilities + compared to revision 1+). */ + cpuinfo_uarch_cortex_a55r0 = 0x00300354, + /** ARM Cortex-A55. */ + cpuinfo_uarch_cortex_a55 = 0x00300355, + /** ARM Cortex-A57. */ + cpuinfo_uarch_cortex_a57 = 0x00300357, + /** ARM Cortex-A65. */ + cpuinfo_uarch_cortex_a65 = 0x00300365, + /** ARM Cortex-A72. */ + cpuinfo_uarch_cortex_a72 = 0x00300372, + /** ARM Cortex-A73. */ + cpuinfo_uarch_cortex_a73 = 0x00300373, + /** ARM Cortex-A75. */ + cpuinfo_uarch_cortex_a75 = 0x00300375, + /** ARM Cortex-A76. */ + cpuinfo_uarch_cortex_a76 = 0x00300376, + /** ARM Cortex-A77. */ + cpuinfo_uarch_cortex_a77 = 0x00300377, + /** ARM Cortex-A78. */ + cpuinfo_uarch_cortex_a78 = 0x00300378, + + /** ARM Neoverse N1. */ + cpuinfo_uarch_neoverse_n1 = 0x00300400, + /** ARM Neoverse E1. */ + cpuinfo_uarch_neoverse_e1 = 0x00300401, + /** ARM Neoverse V1. */ + cpuinfo_uarch_neoverse_v1 = 0x00300402, + /** ARM Neoverse N2. */ + cpuinfo_uarch_neoverse_n2 = 0x00300403, + /** ARM Neoverse V2. */ + cpuinfo_uarch_neoverse_v2 = 0x00300404, + + /** ARM Cortex-X1. */ + cpuinfo_uarch_cortex_x1 = 0x00300501, + /** ARM Cortex-X2. */ + cpuinfo_uarch_cortex_x2 = 0x00300502, + /** ARM Cortex-X3. */ + cpuinfo_uarch_cortex_x3 = 0x00300503, + /** ARM Cortex-X4. */ + cpuinfo_uarch_cortex_x4 = 0x00300504, + /** ARM Cortex-X925. */ + cpuinfo_uarch_cortex_x925 = 0x00300505, + + /** ARM Cortex-A510. */ + cpuinfo_uarch_cortex_a510 = 0x00300551, + /** ARM Cortex-A520. */ + cpuinfo_uarch_cortex_a520 = 0x00300552, + /** ARM Cortex-A710. */ + cpuinfo_uarch_cortex_a710 = 0x00300571, + /** ARM Cortex-A715. */ + cpuinfo_uarch_cortex_a715 = 0x00300572, + /** ARM Cortex-A720. */ + cpuinfo_uarch_cortex_a720 = 0x00300573, + /** ARM Cortex-A725. */ + cpuinfo_uarch_cortex_a725 = 0x00300574, + + /** Qualcomm Scorpion. */ + cpuinfo_uarch_scorpion = 0x00400100, + /** Qualcomm Krait. */ + cpuinfo_uarch_krait = 0x00400101, + /** Qualcomm Kryo. */ + cpuinfo_uarch_kryo = 0x00400102, + /** Qualcomm Falkor. */ + cpuinfo_uarch_falkor = 0x00400103, + /** Qualcomm Saphira. */ + cpuinfo_uarch_saphira = 0x00400104, + /** Qualcomm Oryon. */ + cpuinfo_uarch_oryon = 0x00400105, + + /** Nvidia Denver. */ + cpuinfo_uarch_denver = 0x00500100, + /** Nvidia Denver 2. */ + cpuinfo_uarch_denver2 = 0x00500101, + /** Nvidia Carmel. */ + cpuinfo_uarch_carmel = 0x00500102, + + /** Samsung Exynos M1 (Exynos 8890 big cores). */ + cpuinfo_uarch_exynos_m1 = 0x00600100, + /** Samsung Exynos M2 (Exynos 8895 big cores). */ + cpuinfo_uarch_exynos_m2 = 0x00600101, + /** Samsung Exynos M3 (Exynos 9810 big cores). */ + cpuinfo_uarch_exynos_m3 = 0x00600102, + /** Samsung Exynos M4 (Exynos 9820 big cores). */ + cpuinfo_uarch_exynos_m4 = 0x00600103, + /** Samsung Exynos M5 (Exynos 9830 big cores). */ + cpuinfo_uarch_exynos_m5 = 0x00600104, + + /* Deprecated synonym for Cortex-A76 */ + cpuinfo_uarch_cortex_a76ae = 0x00300376, + /* Deprecated names for Exynos. */ + cpuinfo_uarch_mongoose_m1 = 0x00600100, + cpuinfo_uarch_mongoose_m2 = 0x00600101, + cpuinfo_uarch_meerkat_m3 = 0x00600102, + cpuinfo_uarch_meerkat_m4 = 0x00600103, + + /** Apple A6 and A6X processors. */ + cpuinfo_uarch_swift = 0x00700100, + /** Apple A7 processor. */ + cpuinfo_uarch_cyclone = 0x00700101, + /** Apple A8 and A8X processor. */ + cpuinfo_uarch_typhoon = 0x00700102, + /** Apple A9 and A9X processor. */ + cpuinfo_uarch_twister = 0x00700103, + /** Apple A10 and A10X processor. */ + cpuinfo_uarch_hurricane = 0x00700104, + /** Apple A11 processor (big cores). */ + cpuinfo_uarch_monsoon = 0x00700105, + /** Apple A11 processor (little cores). */ + cpuinfo_uarch_mistral = 0x00700106, + /** Apple A12 processor (big cores). */ + cpuinfo_uarch_vortex = 0x00700107, + /** Apple A12 processor (little cores). */ + cpuinfo_uarch_tempest = 0x00700108, + /** Apple A13 processor (big cores). */ + cpuinfo_uarch_lightning = 0x00700109, + /** Apple A13 processor (little cores). */ + cpuinfo_uarch_thunder = 0x0070010A, + /** Apple A14 / M1 processor (big cores). */ + cpuinfo_uarch_firestorm = 0x0070010B, + /** Apple A14 / M1 processor (little cores). */ + cpuinfo_uarch_icestorm = 0x0070010C, + /** Apple A15 / M2 processor (big cores). */ + cpuinfo_uarch_avalanche = 0x0070010D, + /** Apple A15 / M2 processor (little cores). */ + cpuinfo_uarch_blizzard = 0x0070010E, + /** Apple A16 processor (big cores). */ + cpuinfo_uarch_everest = 0x00700200, + /** Apple A16 processor (little cores). */ + cpuinfo_uarch_sawtooth = 0x00700201, + /** Apple A17 processor (big cores). */ + cpuinfo_uarch_coll_everest = 0x00700202, + /** Apple A17 processor (little cores). */ + cpuinfo_uarch_coll_sawtooth = 0x00700203, + /** Apple A18 processor (big cores). */ + cpuinfo_uarch_tupai_everest = 0x00700204, + /** Apple A18 processor (little cores). */ + cpuinfo_uarch_tupai_sawtooth = 0x00700205, + /** Apple A18 pro processor (big cores). */ + cpuinfo_uarch_tahiti_everest = 0x00700206, + /** Apple A18 pro processor (little cores). */ + cpuinfo_uarch_tahiti_sawtooth = 0x00700207, + + /** Cavium ThunderX. */ + cpuinfo_uarch_thunderx = 0x00800100, + /** Cavium ThunderX2 (originally Broadcom Vulkan). */ + cpuinfo_uarch_thunderx2 = 0x00800200, + + /** Marvell PJ4. */ + cpuinfo_uarch_pj4 = 0x00900100, + + /** Broadcom Brahma B15. */ + cpuinfo_uarch_brahma_b15 = 0x00A00100, + /** Broadcom Brahma B53. */ + cpuinfo_uarch_brahma_b53 = 0x00A00101, + + /** Applied Micro X-Gene. */ + cpuinfo_uarch_xgene = 0x00B00100, + + /* Hygon Dhyana (a modification of AMD Zen for Chinese market). */ + cpuinfo_uarch_dhyana = 0x01000100, + + /** HiSilicon TaiShan v110 (Huawei Kunpeng 920 series processors). */ + cpuinfo_uarch_taishan_v110 = 0x00C00100, +}; + +struct cpuinfo_processor { + /** SMT (hyperthread) ID within a core */ + uint32_t smt_id; + /** Core containing this logical processor */ + const struct cpuinfo_core* core; + /** Cluster of cores containing this logical processor */ + const struct cpuinfo_cluster* cluster; + /** Physical package containing this logical processor */ + const struct cpuinfo_package* package; +#if defined(__linux__) + /** + * Linux-specific ID for the logical processor: + * - Linux kernel exposes information about this logical processor in + * /sys/devices/system/cpu/cpu/ + * - Bit in the cpu_set_t identifies this logical processor + */ + int linux_id; +#endif +#if defined(_WIN32) || defined(__CYGWIN__) + /** Windows-specific ID for the group containing the logical processor. + */ + uint16_t windows_group_id; + /** + * Windows-specific ID of the logical processor within its group: + * - Bit in the KAFFINITY mask identifies this + * logical processor within its group. + */ + uint16_t windows_processor_id; +#endif +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + /** APIC ID (unique x86-specific ID of the logical processor) */ + uint32_t apic_id; +#endif + struct { + /** Level 1 instruction cache */ + const struct cpuinfo_cache* l1i; + /** Level 1 data cache */ + const struct cpuinfo_cache* l1d; + /** Level 2 unified or data cache */ + const struct cpuinfo_cache* l2; + /** Level 3 unified or data cache */ + const struct cpuinfo_cache* l3; + /** Level 4 unified or data cache */ + const struct cpuinfo_cache* l4; + } cache; +}; + +struct cpuinfo_core { + /** Index of the first logical processor on this core. */ + uint32_t processor_start; + /** Number of logical processors on this core */ + uint32_t processor_count; + /** Core ID within a package */ + uint32_t core_id; + /** Cluster containing this core */ + const struct cpuinfo_cluster* cluster; + /** Physical package containing this core. */ + const struct cpuinfo_package* package; + /** Vendor of the CPU microarchitecture for this core */ + enum cpuinfo_vendor vendor; + /** CPU microarchitecture for this core */ + enum cpuinfo_uarch uarch; +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + /** Value of CPUID leaf 1 EAX register for this core */ + uint32_t cpuid; +#elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + /** Value of Main ID Register (MIDR) for this core */ + uint32_t midr; +#endif + /** Clock rate (non-Turbo) of the core, in Hz */ + uint64_t frequency; +}; + +struct cpuinfo_cluster { + /** Index of the first logical processor in the cluster */ + uint32_t processor_start; + /** Number of logical processors in the cluster */ + uint32_t processor_count; + /** Index of the first core in the cluster */ + uint32_t core_start; + /** Number of cores on the cluster */ + uint32_t core_count; + /** Cluster ID within a package */ + uint32_t cluster_id; + /** Physical package containing the cluster */ + const struct cpuinfo_package* package; + /** CPU microarchitecture vendor of the cores in the cluster */ + enum cpuinfo_vendor vendor; + /** CPU microarchitecture of the cores in the cluster */ + enum cpuinfo_uarch uarch; +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + /** Value of CPUID leaf 1 EAX register of the cores in the cluster */ + uint32_t cpuid; +#elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + /** Value of Main ID Register (MIDR) of the cores in the cluster */ + uint32_t midr; +#endif + /** Clock rate (non-Turbo) of the cores in the cluster, in Hz */ + uint64_t frequency; +}; + +#define CPUINFO_PACKAGE_NAME_MAX 64 + +struct cpuinfo_package { + /** SoC or processor chip model name */ + char name[CPUINFO_PACKAGE_NAME_MAX]; + /** Index of the first logical processor on this physical package */ + uint32_t processor_start; + /** Number of logical processors on this physical package */ + uint32_t processor_count; + /** Index of the first core on this physical package */ + uint32_t core_start; + /** Number of cores on this physical package */ + uint32_t core_count; + /** Index of the first cluster of cores on this physical package */ + uint32_t cluster_start; + /** Number of clusters of cores on this physical package */ + uint32_t cluster_count; +}; + +struct cpuinfo_uarch_info { + /** Type of CPU microarchitecture */ + enum cpuinfo_uarch uarch; +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + /** Value of CPUID leaf 1 EAX register for the microarchitecture */ + uint32_t cpuid; +#elif CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + /** Value of Main ID Register (MIDR) for the microarchitecture */ + uint32_t midr; +#endif + /** Number of logical processors with the microarchitecture */ + uint32_t processor_count; + /** Number of cores with the microarchitecture */ + uint32_t core_count; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +bool CPUINFO_ABI cpuinfo_initialize(void); + +void CPUINFO_ABI cpuinfo_deinitialize(void); + +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 +/* This structure is not a part of stable API. Use cpuinfo_has_x86_* functions + * instead. */ +struct cpuinfo_x86_isa { +#if CPUINFO_ARCH_X86 + bool rdtsc; +#endif + bool rdtscp; + bool rdpid; + bool sysenter; +#if CPUINFO_ARCH_X86 + bool syscall; +#endif + bool msr; + bool clzero; + bool clflush; + bool clflushopt; + bool mwait; + bool mwaitx; +#if CPUINFO_ARCH_X86 + bool emmx; +#endif + bool fxsave; + bool xsave; +#if CPUINFO_ARCH_X86 + bool fpu; + bool mmx; + bool mmx_plus; +#endif + bool three_d_now; + bool three_d_now_plus; +#if CPUINFO_ARCH_X86 + bool three_d_now_geode; +#endif + bool prefetch; + bool prefetchw; + bool prefetchwt1; +#if CPUINFO_ARCH_X86 + bool daz; + bool sse; + bool sse2; +#endif + bool sse3; + bool ssse3; + bool sse4_1; + bool sse4_2; + bool sse4a; + bool misaligned_sse; + bool avx; + bool avxvnni; + bool fma3; + bool fma4; + bool xop; + bool f16c; + bool avx2; + bool avx512f; + bool avx512pf; + bool avx512er; + bool avx512cd; + bool avx512dq; + bool avx512bw; + bool avx512vl; + bool avx512ifma; + bool avx512vbmi; + bool avx512vbmi2; + bool avx512bitalg; + bool avx512vpopcntdq; + bool avx512vnni; + bool avx512bf16; + bool avx512fp16; + bool avx512vp2intersect; + bool avx512_4vnniw; + bool avx512_4fmaps; + bool avx10_1; + bool avx10_2; + bool amx_bf16; + bool amx_tile; + bool amx_int8; + bool amx_fp16; + bool avx_vnni_int8; + bool avx_vnni_int16; + bool avx_ne_convert; + bool hle; + bool rtm; + bool xtest; + bool mpx; +#if CPUINFO_ARCH_X86 + bool cmov; + bool cmpxchg8b; +#endif + bool cmpxchg16b; + bool clwb; + bool movbe; +#if CPUINFO_ARCH_X86_64 + bool lahf_sahf; +#endif + bool fs_gs_base; + bool lzcnt; + bool popcnt; + bool tbm; + bool bmi; + bool bmi2; + bool adx; + bool aes; + bool vaes; + bool pclmulqdq; + bool vpclmulqdq; + bool gfni; + bool rdrand; + bool rdseed; + bool sha; + bool rng; + bool ace; + bool ace2; + bool phe; + bool pmm; + bool lwp; +}; + +extern struct cpuinfo_x86_isa cpuinfo_isa; +#endif + +static inline bool cpuinfo_has_x86_rdtsc(void) { +#if CPUINFO_ARCH_X86_64 + return true; +#elif CPUINFO_ARCH_X86 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.rdtsc; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_rdtscp(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.rdtscp; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_rdpid(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.rdpid; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_clzero(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.clzero; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_mwait(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.mwait; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_mwaitx(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.mwaitx; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_fxsave(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.fxsave; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_xsave(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.xsave; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_fpu(void) { +#if CPUINFO_ARCH_X86_64 + return true; +#elif CPUINFO_ARCH_X86 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.fpu; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_mmx(void) { +#if CPUINFO_ARCH_X86_64 + return true; +#elif CPUINFO_ARCH_X86 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.mmx; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_mmx_plus(void) { +#if CPUINFO_ARCH_X86_64 + return true; +#elif CPUINFO_ARCH_X86 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.mmx_plus; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_3dnow(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.three_d_now; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_3dnow_plus(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.three_d_now_plus; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_3dnow_geode(void) { +#if CPUINFO_ARCH_X86_64 + return false; +#elif CPUINFO_ARCH_X86 +#if defined(__ANDROID__) + return false; +#else + return cpuinfo_isa.three_d_now_geode; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_prefetch(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.prefetch; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_prefetchw(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.prefetchw; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_prefetchwt1(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.prefetchwt1; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_daz(void) { +#if CPUINFO_ARCH_X86_64 + return true; +#elif CPUINFO_ARCH_X86 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.daz; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_sse(void) { +#if CPUINFO_ARCH_X86_64 + return true; +#elif CPUINFO_ARCH_X86 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.sse; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_sse2(void) { +#if CPUINFO_ARCH_X86_64 + return true; +#elif CPUINFO_ARCH_X86 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.sse2; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_sse3(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.sse3; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_ssse3(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.ssse3; +#endif +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_sse4_1(void) { +#if CPUINFO_ARCH_X86_64 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.sse4_1; +#endif +#elif CPUINFO_ARCH_X86 + return cpuinfo_isa.sse4_1; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_sse4_2(void) { +#if CPUINFO_ARCH_X86_64 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.sse4_2; +#endif +#elif CPUINFO_ARCH_X86 + return cpuinfo_isa.sse4_2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_sse4a(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.sse4a; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_misaligned_sse(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.misaligned_sse; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avxvnni(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avxvnni; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_fma3(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.fma3; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_fma4(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.fma4; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_xop(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.xop; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_f16c(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.f16c; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx2(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512f(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512f; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512pf(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512pf; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512er(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512er; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512cd(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512cd; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512dq(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512dq; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512bw(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512bw; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512vl(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512vl; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512ifma(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512ifma; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512vbmi(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512vbmi; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512vbmi2(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512vbmi2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512bitalg(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512bitalg; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512vpopcntdq(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512vpopcntdq; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512vnni(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512vnni; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512bf16(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512bf16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512fp16(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512fp16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512vp2intersect(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512vp2intersect; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512_4vnniw(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512_4vnniw; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx512_4fmaps(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx512_4fmaps; +#else + return false; +#endif +} + +/* [NOTE] Intel Advanced Matrix Extensions (AMX) detection + * + * I. AMX is a new extensions to the x86 ISA to work on matrices, consists of + * 1) 2-dimentional registers (tiles), hold sub-matrices from larger matrices in memory + * 2) Accelerator called Tile Matrix Multiply (TMUL), contains instructions operating on tiles + * + * II. Platforms that supports AMX: + * +-----------------+-----+----------+----------+----------+----------+ + * | Platforms | Gen | amx-bf16 | amx-tile | amx-int8 | amx-fp16 | + * +-----------------+-----+----------+----------+----------+----------+ + * | Sapphire Rapids | 4th | YES | YES | YES | NO | + * +-----------------+-----+----------+----------+----------+----------+ + * | Emerald Rapids | 5th | YES | YES | YES | NO | + * +-----------------+-----+----------+----------+----------+----------+ + * | Granite Rapids | 6th | YES | YES | YES | YES | + * +-----------------+-----+----------+----------+----------+----------+ + * + * Reference: https://www.intel.com/content/www/us/en/products/docs + * /accelerator-engines/advanced-matrix-extensions/overview.html + */ +static inline bool cpuinfo_has_x86_amx_bf16(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.amx_bf16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_amx_tile(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.amx_tile; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_amx_int8(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.amx_int8; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_amx_fp16(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.amx_fp16; +#else + return false; +#endif +} + +/* + * Intel AVX Vector Neural Network Instructions (VNNI) INT8 + * Supported Platfroms: Sierra Forest, Arrow Lake, Lunar Lake + */ +static inline bool cpuinfo_has_x86_avx_vnni_int8(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx_vnni_int8; +#else + return false; +#endif +} + +/* + * Intel AVX Vector Neural Network Instructions (VNNI) INT16 + * Supported Platfroms: Arrow Lake, Lunar Lake + */ +static inline bool cpuinfo_has_x86_avx_vnni_int16(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx_vnni_int16; +#else + return false; +#endif +} + +/* + * A new set of instructions, which can convert low precision floating point + * like BF16/FP16 to high precision floating point FP32, as well as convert FP32 + * elements to BF16. This instruction allows the platform to have improved AI + * capabilities and better compatibility. + * + * Supported Platforms: Sierra Forest, Arrow Lake, Lunar Lake + */ +static inline bool cpuinfo_has_x86_avx_ne_convert(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx_ne_convert; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx10_1(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx10_1; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_avx10_2(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.avx10_2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_hle(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.hle; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_rtm(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.rtm; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_xtest(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.xtest; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_mpx(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.mpx; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_cmov(void) { +#if CPUINFO_ARCH_X86_64 + return true; +#elif CPUINFO_ARCH_X86 + return cpuinfo_isa.cmov; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_cmpxchg8b(void) { +#if CPUINFO_ARCH_X86_64 + return true; +#elif CPUINFO_ARCH_X86 + return cpuinfo_isa.cmpxchg8b; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_cmpxchg16b(void) { +#if CPUINFO_ARCH_X86_64 + return cpuinfo_isa.cmpxchg16b; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_clwb(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.clwb; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_movbe(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.movbe; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_lahf_sahf(void) { +#if CPUINFO_ARCH_X86 + return true; +#elif CPUINFO_ARCH_X86_64 + return cpuinfo_isa.lahf_sahf; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_lzcnt(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.lzcnt; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_popcnt(void) { +#if CPUINFO_ARCH_X86_64 +#if defined(__ANDROID__) + return true; +#else + return cpuinfo_isa.popcnt; +#endif +#elif CPUINFO_ARCH_X86 + return cpuinfo_isa.popcnt; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_tbm(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.tbm; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_bmi(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.bmi; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_bmi2(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.bmi2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_adx(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.adx; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_aes(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.aes; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_vaes(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.vaes; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_pclmulqdq(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.pclmulqdq; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_vpclmulqdq(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.vpclmulqdq; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_gfni(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.gfni; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_rdrand(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.rdrand; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_rdseed(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.rdseed; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_sha(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.sha; +#else + return false; +#endif +} + +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 +/* This structure is not a part of stable API. Use cpuinfo_has_arm_* functions + * instead. */ +struct cpuinfo_arm_isa { +#if CPUINFO_ARCH_ARM + bool thumb; + bool thumb2; + bool thumbee; + bool jazelle; + bool armv5e; + bool armv6; + bool armv6k; + bool armv7; + bool armv7mp; + bool armv8; + bool idiv; + + bool vfpv2; + bool vfpv3; + bool d32; + bool fp16; + bool fma; + + bool wmmx; + bool wmmx2; + bool neon; +#endif +#if CPUINFO_ARCH_ARM64 + bool atomics; + bool bf16; + bool sve; + bool sve2; + bool i8mm; + bool sme; + bool sme2; + bool sme2p1; + bool sme_i16i32; + bool sme_bi32i32; + bool sme_b16b16; + bool sme_f16f16; + uint32_t svelen; + uint32_t smelen; +#endif + bool rdm; + bool fp16arith; + bool dot; + bool jscvt; + bool fcma; + bool fhm; + + bool aes; + bool sha1; + bool sha2; + bool pmull; + bool crc32; +}; + +extern struct cpuinfo_arm_isa cpuinfo_isa; +#endif + +static inline bool cpuinfo_has_arm_thumb(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.thumb; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_thumb2(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.thumb2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_v5e(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.armv5e; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_v6(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.armv6; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_v6k(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.armv6k; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_v7(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.armv7; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_v7mp(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.armv7mp; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_v8(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.armv8; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_idiv(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.idiv; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_vfpv2(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.vfpv2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_vfpv3(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.vfpv3; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_vfpv3_d32(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.vfpv3 && cpuinfo_isa.d32; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_vfpv3_fp16(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.vfpv3 && cpuinfo_isa.fp16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_vfpv3_fp16_d32(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.vfpv3 && cpuinfo_isa.fp16 && cpuinfo_isa.d32; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_vfpv4(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.vfpv3 && cpuinfo_isa.fma; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_vfpv4_d32(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.vfpv3 && cpuinfo_isa.fma && cpuinfo_isa.d32; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_fp16_arith(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.fp16arith; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_bf16(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.bf16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_wmmx(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.wmmx; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_wmmx2(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.wmmx2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_neon(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.neon; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_neon_fp16(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.neon && cpuinfo_isa.fp16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_neon_fma(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.neon && cpuinfo_isa.fma; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_neon_v8(void) { +#if CPUINFO_ARCH_ARM64 + return true; +#elif CPUINFO_ARCH_ARM + return cpuinfo_isa.neon && cpuinfo_isa.armv8; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_atomics(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.atomics; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_neon_rdm(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.rdm; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_neon_fp16_arith(void) { +#if CPUINFO_ARCH_ARM + return cpuinfo_isa.neon && cpuinfo_isa.fp16arith; +#elif CPUINFO_ARCH_ARM64 + return cpuinfo_isa.fp16arith; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_fhm(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.fhm; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_neon_dot(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.dot; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_neon_bf16(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.bf16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_jscvt(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.jscvt; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_fcma(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.fcma; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_i8mm(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.i8mm; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_aes(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.aes; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sha1(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sha1; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sha2(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sha2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_pmull(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.pmull; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_crc32(void) { +#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 + return cpuinfo_isa.crc32; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sve(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sve; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sve_bf16(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sve && cpuinfo_isa.bf16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sve2(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sve2; +#else + return false; +#endif +} + +// Function to get the max SVE vector length on ARM CPU's which support SVE. +static inline uint32_t cpuinfo_get_max_arm_sve_length(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.svelen * 8; // bytes * 8 = bit length(vector length) +#else + return 0; +#endif +} + +// Function to get the max SME vector length on ARM CPU's which support SME. +static inline uint32_t cpuinfo_get_max_arm_sme_length(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.smelen * 8; // bytes * 8 = bit length(vector length) +#else + return 0; +#endif +} + +static inline bool cpuinfo_has_arm_sme(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme2(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme2; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme2p1(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme2p1; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme_i16i32(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme_i16i32; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme_bi32i32(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme_bi32i32; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme_b16b16(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme_b16b16; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_arm_sme_f16f16(void) { +#if CPUINFO_ARCH_ARM64 + return cpuinfo_isa.sme_f16f16; +#else + return false; +#endif +} + +#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 +/* This structure is not a part of stable API. Use cpuinfo_has_riscv_* functions + * instead. */ +struct cpuinfo_riscv_isa { + /** + * Keep fields in line with the canonical order as defined by + * Section 27.11 Subset Naming Convention. + */ + /* RV32I/64I/128I Base ISA. */ + bool i; +#if CPUINFO_ARCH_RISCV32 + /* RV32E Base ISA. */ + bool e; +#endif + /* Integer Multiply/Divide Extension. */ + bool m; + /* Atomic Extension. */ + bool a; + /* Single-Precision Floating-Point Extension. */ + bool f; + /* Double-Precision Floating-Point Extension. */ + bool d; + /* Compressed Extension. */ + bool c; + /* Vector Extension. */ + bool v; +}; + +extern struct cpuinfo_riscv_isa cpuinfo_isa; +#endif + +static inline bool cpuinfo_has_riscv_i(void) { +#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 + return cpuinfo_isa.i; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_riscv_e(void) { +#if CPUINFO_ARCH_RISCV32 + return cpuinfo_isa.e; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_riscv_m(void) { +#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 + return cpuinfo_isa.m; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_riscv_a(void) { +#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 + return cpuinfo_isa.a; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_riscv_f(void) { +#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 + return cpuinfo_isa.f; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_riscv_d(void) { +#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 + return cpuinfo_isa.d; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_riscv_g(void) { + // The 'G' extension is simply shorthand for 'IMAFD'. + return cpuinfo_has_riscv_i() && cpuinfo_has_riscv_m() && cpuinfo_has_riscv_a() && cpuinfo_has_riscv_f() && + cpuinfo_has_riscv_d(); +} + +static inline bool cpuinfo_has_riscv_c(void) { +#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 + return cpuinfo_isa.c; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_riscv_v(void) { +#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 + return cpuinfo_isa.v; +#else + return false; +#endif +} + +const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processors(void); +const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_cores(void); +const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_clusters(void); +const struct cpuinfo_package* CPUINFO_ABI cpuinfo_get_packages(void); +const struct cpuinfo_uarch_info* CPUINFO_ABI cpuinfo_get_uarchs(void); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_caches(void); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_caches(void); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_caches(void); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_caches(void); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_caches(void); + +const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_processor(uint32_t index); +const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_core(uint32_t index); +const struct cpuinfo_cluster* CPUINFO_ABI cpuinfo_get_cluster(uint32_t index); +const struct cpuinfo_package* CPUINFO_ABI cpuinfo_get_package(uint32_t index); +const struct cpuinfo_uarch_info* CPUINFO_ABI cpuinfo_get_uarch(uint32_t index); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_cache(uint32_t index); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_cache(uint32_t index); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_cache(uint32_t index); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_cache(uint32_t index); +const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_cache(uint32_t index); + +uint32_t CPUINFO_ABI cpuinfo_get_processors_count(void); +uint32_t CPUINFO_ABI cpuinfo_get_cores_count(void); +uint32_t CPUINFO_ABI cpuinfo_get_clusters_count(void); +uint32_t CPUINFO_ABI cpuinfo_get_packages_count(void); +uint32_t CPUINFO_ABI cpuinfo_get_uarchs_count(void); +uint32_t CPUINFO_ABI cpuinfo_get_l1i_caches_count(void); +uint32_t CPUINFO_ABI cpuinfo_get_l1d_caches_count(void); +uint32_t CPUINFO_ABI cpuinfo_get_l2_caches_count(void); +uint32_t CPUINFO_ABI cpuinfo_get_l3_caches_count(void); +uint32_t CPUINFO_ABI cpuinfo_get_l4_caches_count(void); + +/** + * Returns upper bound on cache size. + */ +uint32_t CPUINFO_ABI cpuinfo_get_max_cache_size(void); + +/** + * Identify the logical processor that executes the current thread. + * + * There is no guarantee that the thread will stay on the same logical processor + * for any time. Callers should treat the result as only a hint, and be prepared + * to handle NULL return value. + */ +const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_current_processor(void); + +/** + * Identify the core that executes the current thread. + * + * There is no guarantee that the thread will stay on the same core for any + * time. Callers should treat the result as only a hint, and be prepared to + * handle NULL return value. + */ +const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_current_core(void); + +/** + * Identify the microarchitecture index of the core that executes the current + * thread. If the system does not support such identification, the function + * returns 0. + * + * There is no guarantee that the thread will stay on the same type of core for + * any time. Callers should treat the result as only a hint. + */ +uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index(void); + +/** + * Identify the microarchitecture index of the core that executes the current + * thread. If the system does not support such identification, the function + * returns the user-specified default value. + * + * There is no guarantee that the thread will stay on the same type of core for + * any time. Callers should treat the result as only a hint. + */ +uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index_with_default(uint32_t default_uarch_index); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CPUINFO_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.h new file mode 100644 index 0000000000000000000000000000000000000000..2f23ccc356d39007d0e1526a1915c9f263b353ca --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_H +#define DNNL_H + +#include "oneapi/dnnl/dnnl.h" + +#endif /* DNNL_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cfeaa7ae8104ef4ee187593e8293d4fb332a1d7f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.hpp @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_HPP +#define DNNL_HPP + +#include "oneapi/dnnl/dnnl.hpp" + +#endif /* DNNL_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_config.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_config.h new file mode 100644 index 0000000000000000000000000000000000000000..9ed9094b2e8de55cbe29f97203b0a038017bd4e9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_config.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_CONFIG_H +#define DNNL_CONFIG_H + +#include "oneapi/dnnl/dnnl_config.h" + +#endif /* DNNL_CONFIG_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_debug.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..7542b65d3a82845d45550ac22c352532b0e65161 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_debug.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_DEBUG_H +#define DNNL_DEBUG_H + +#include "oneapi/dnnl/dnnl_debug.h" + +#endif /* DNNL_DEBUG_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.h new file mode 100644 index 0000000000000000000000000000000000000000..f7c5cdc04199555228ba220445acc0a6f427c77c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_OCL_H +#define DNNL_OCL_H + +#include "oneapi/dnnl/dnnl_ocl.h" + +#endif /* DNNL_OCL_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..55e02e842d8b1dde9b932d7bc0b22b39a21df014 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.hpp @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_OCL_HPP +#define DNNL_OCL_HPP + +#include "oneapi/dnnl/dnnl_ocl.hpp" + +#endif /* DNNL_OCL_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.h new file mode 100644 index 0000000000000000000000000000000000000000..3017d8ce576b0fe44ba275810cf7021f4df649a7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_SYCL_H +#define DNNL_SYCL_H + +#include "oneapi/dnnl/dnnl_sycl.h" + +#endif /* DNNL_SYCL_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6001dea399240f83e06f38956fb5aee7355264d6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.hpp @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_SYCL_HPP +#define DNNL_SYCL_HPP + +#include "oneapi/dnnl/dnnl_sycl.hpp" + +#endif /* DNNL_SYCL_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl_types.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl_types.h new file mode 100644 index 0000000000000000000000000000000000000000..ede1cdcb3bec776331b64fb27724c72ead100d19 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl_types.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_SYCL_TYPES_H +#define DNNL_SYCL_TYPES_H + +#include "oneapi/dnnl/dnnl_sycl_types.h" + +#endif /* DNNL_SYCL_TYPES_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.h new file mode 100644 index 0000000000000000000000000000000000000000..56427210e54c1516fa2453519965945042a5798c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_THREADPOOL_H +#define DNNL_THREADPOOL_H + +#include "oneapi/dnnl/dnnl_threadpool.h" + +#endif /* DNNL_THREADPOOL_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.hpp new file mode 100644 index 0000000000000000000000000000000000000000..436afe2c58752f61287a888ef0b2af1eff290bdd --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.hpp @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_THREADPOOL_HPP +#define DNNL_THREADPOOL_HPP + +#include "oneapi/dnnl/dnnl_threadpool.hpp" + +#endif /* DNNL_THREADPOOL_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool_iface.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool_iface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..beead174e90480e97efc996ba20e0c4330e061fa --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool_iface.hpp @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_THREADPOOL_IFACE_HPP +#define DNNL_THREADPOOL_IFACE_HPP + +#include "oneapi/dnnl/dnnl_threadpool_iface.hpp" + +#endif /* DNNL_THREADPOOL_IFACE_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_types.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_types.h new file mode 100644 index 0000000000000000000000000000000000000000..35e54d4a3ae678a1674bbadb42c72c5352238743 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_types.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_TYPES_H +#define DNNL_TYPES_H + +#include "oneapi/dnnl/dnnl_types.h" + +#endif /* DNNL_TYPES_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_version.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_version.h new file mode 100644 index 0000000000000000000000000000000000000000..6a58705775014639fed51001a5069bbf7b2b7efe --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_version.h @@ -0,0 +1,27 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef DNNL_VERSION_H +#define DNNL_VERSION_H + +#include "oneapi/dnnl/dnnl_version.h" + +#endif /* DNNL_VERSION_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/ConvUtils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/ConvUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..e02f7219333029289853acf1883b29b840da4198 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/ConvUtils.h @@ -0,0 +1,195 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +namespace fbgemm { + +template +constexpr std::enable_if_t> +array_of_ones() { + return std::array{{Vals...}}; +} + +template +constexpr std::enable_if_t> +array_of_ones() { + return array_of_ones(); +} + +template +constexpr std::enable_if_t> +array_of_zeroes() { + return std::array{{Vals...}}; +} + +template +constexpr std::enable_if_t> +array_of_zeroes() { + return array_of_zeroes(); +} + +/** + * @brief A struct to conveniently store all convolution parameters. + */ +template +struct conv_param_t { + int MB; ///< Mini Batch size + int IC; ///< Number of Input Channels + int OC; ///< Number of Output Channels + std::array IN_DIM; ///< Input Image Dimension + int G; ///< Number of Groups + std::array K; ///< Filter (Kernel) dimensions + std::array stride; //< Strides + std::array + pad; //< Padding (first SPATIAL_DIM is for prev/top/left padding, second + // SPATIAL_DIM is for next/bottom/right padding) + std::array dilation; //< Kernel dilation + + // The following are derived parameters + std::array OUT_DIM; //< Output Image Dimension + std::array IN_DIMP; //< Input Image Dimension Padded + + // The following is for tranposed convolution + std::array + output_pad; //< Padding (next/bottom/right padding in output buffer) + bool transposed; + + /** + * @brief Constructor for initializing the convolution parameters. + */ + conv_param_t( + int mb, + int ic, + int oc, + std::array in_dim, + int g, + std::array k, + std::array strd, + std::array pd, + std::array dilations = array_of_ones(), + std::array otpt_pd = array_of_zeroes(), + bool transposed = false) + : MB(mb), + IC(ic), + OC(oc), + IN_DIM(in_dim), + G(g), + K(k), + stride(strd), + pad(pd), + dilation(dilations), + output_pad(otpt_pd), + transposed(transposed) { + if (ic % g != 0) { + throw std::runtime_error( + "groups = " + std::to_string(g) + + " does not divide number of input channels = " + std::to_string(ic)); + } + if (oc % g != 0) { + throw std::runtime_error( + "groups = " + std::to_string(g) + + " does not divide number of output channels = " + std::to_string(oc)); + } + + for (int d = 0; d < SPATIAL_DIM; ++d) { + if (transposed) { + this->IN_DIMP[d] = this->IN_DIM[d] + + (this->dilation[d] * (this->K[d] - 1) - this->pad[d]) + + (this->dilation[d] * (this->K[d] - 1) - this->pad[SPATIAL_DIM + d]); + this->OUT_DIM[d] = (this->IN_DIM[d] - 1) * this->stride[d] - + this->pad[d] - this->pad[SPATIAL_DIM + d] + + this->dilation[d] * (this->K[d] - 1) + output_pad[d] + 1; + } else { + IN_DIMP[d] = IN_DIM[d] + pad[d] + pad[SPATIAL_DIM + d]; + OUT_DIM[d] = + (IN_DIMP[d] - dilation[d] * (K[d] - 1) - 1) / stride[d] + 1; + } + } + } + + /** + * @brief Helper function to get convolution parameters as string. + */ + std::string toString() const { + std::string dim_string[3] = {"T", "H", "W"}; + + std::string out; + out += "MB:" + std::to_string(MB) + ", "; + out += "IC:" + std::to_string(IC) + ", "; + out += "OC:" + std::to_string(OC) + ", "; + if constexpr (SPATIAL_DIM <= 3) { + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "I" + dim_string[3 - SPATIAL_DIM + d] + ":" + + std::to_string(IN_DIM[d]) + ", "; + } + } else { + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "I" + std::to_string(d) + ":" + std::to_string(IN_DIM[d]) + ", "; + } + } + out += "G:" + std::to_string(G) + ", "; + if constexpr (SPATIAL_DIM <= 3) { + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "K" + dim_string[3 - SPATIAL_DIM + d] + ":" + + std::to_string(K[d]) + ", "; + } + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "stride_" + dim_string[3 - SPATIAL_DIM + d] + ":" + + std::to_string(stride[d]) + ", "; + } + for (int d = 0; d < SPATIAL_DIM * 2; ++d) { + out += "pad_" + dim_string[3 - SPATIAL_DIM + (d % SPATIAL_DIM)] + ":" + + std::to_string(pad[d]) + ", "; + } + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "dilation_" + dim_string[3 - SPATIAL_DIM + d] + ":" + + std::to_string(dilation[d]); + if (d < SPATIAL_DIM - 1) { + out += ", "; + } + } + } else { + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "K" + std::to_string(d) + ":" + std::to_string(K[d]) + ", "; + } + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "stride_" + std::to_string(d) + ":" + std::to_string(stride[d]) + + ", "; + } + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "pad_" + std::to_string(d) + ":" + std::to_string(pad[d]); + if (d < SPATIAL_DIM * 2 - 1) { + out += ", "; + } + } + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "dilation_" + std::to_string(d) + ":" + + std::to_string(dilation[d]) + ", "; + } + } + if (transposed) { + for (int d = 0; d < SPATIAL_DIM; ++d) { + out += "output_padding_" + std::to_string(d) + ":" + + std::to_string(output_pad[d]) + ", "; + } + } + return out; + } +}; +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Fbgemm.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Fbgemm.h new file mode 100644 index 0000000000000000000000000000000000000000..518d014dd8bdf904cb561071de323cce8d2517eb --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Fbgemm.h @@ -0,0 +1,1515 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +/** + * Top level include file for FBGEMM. + */ +#include +#include +#include "./ConvUtils.h" // @manual +#include "./FbgemmBuild.h" // @manual +#include "./FbgemmEmbedding.h" // @manual +#include "./FbgemmI8DepthwiseAvx2.h" // @manual +#include "./FbgemmI8DirectconvAvx2.h" // @manual +#include "./FbgemmI8Spmdm.h" // @manual +#include "./FloatConversion.h" // @manual +#include "./QuantUtilsAvx2.h" // @manual +#include "./Types.h" // @manual +#include "./Utils.h" // @manual + +// Turning on this option will print out time breakdown of each stage (e.g., +// input packing, the main GEMM kernel, each output processing pipeline). +// Please note that currently this option won't report accurate timing if +// multiple threads are used. +// #define FBGEMM_MEASURE_TIME_BREAKDOWN + +#ifdef FBGEMM_MEASURE_TIME_BREAKDOWN +#include +#include +extern double packing_time; +extern double computing_time; +extern double kernel_time; +extern double postprocessing_time; +extern double run_time; +#endif + +namespace fbgemm { + +/** + * @brief Templatized struct for packing parameters for A and B matrices. + * + * @tparam T input type + * @tparam accT the type used for accumulation + * @tparam instSet anyarch/avx2/avx512 + * @tparam int8Type an auxiliary template parameter to specialize for 8-bit + * input types. + */ +template < + typename T, + typename accT, + inst_set_t instSet, + typename int8Type = void> +struct PackingTraits; + +// type specialized implementation in an include file +#include "./PackingTraits-inl.h" // @manual + +/** + * @brief Base class for packing matrices for higher GEMM performance. + * + * Matrix is tiled into blockRows() * blockCols() blocks. + * Each block is with size blockRowSize() * blockColSize(). + * This class is designed using CRTP + * (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) + * + * @tparam PT actual packing type, e.g., PackAWithRowOffset + */ +template +class PackMatrix { + public: + PackMatrix() = delete; // no default constructor + PackMatrix(const PackMatrix&) = delete; // no copy + PackMatrix& operator=(const PackMatrix&) = delete; // no copy + PackMatrix(PackMatrix&&) = delete; // no move + PackMatrix& operator=(PackMatrix&& rhs) noexcept = delete; // no move + + /** + * @param rows total number of rows in the matrix + * (packed rows can be less than rows). + * @param cols total number of columns in the matrix + * @param pmat A buffer to contain the packed matrix. + * If nullptr, a buffer owned by PackMatrix will be allocated + * internally to contain the packed matrix. + * For non-constant matrices like activation matrices, the client + * code may want to pass a pre-allocated pmat to avoid the + * overhead of internal memory allocation everytime a PackMatrix + * is constructed. The client code can query how big patm should + * be with packedBufferSize function. + * @param groups when groups > 1, we compute groups number of GEMMs each + * multiplies A.rows by A.cols/A.groups matrix with + * B.rows/B.groups by B.cols matrix (in conventional BLAS + * terminology, this is a batched GEMM but we use the name group + * to follow deep learning terminology). The result matrix has + * dimension A.rows by B.cols*B.groups . + * A.groups must be same as B.groups, A.groups must divide + * A.cols, and B.groups must divide B.rows and C.cols. + */ + PackMatrix( + std::int32_t rows, + std::int32_t cols, + inpType* pmat, + int groups = 1, + const BlockingFactors* params = nullptr); + + /** + * @return true usually when the matrix is constant matrix (e.g., weight + * matrices) that can be prepacked + */ + bool isPrePacked() const { + return static_cast(this)->isPrePacked(); + } + + /** + * @return true if this is the first input matrix in GEMM (i.e., A in C = A * + * B) + */ + static bool isA() { + return PT::isA(); + } + + /** + * @brief The size of the buffer used for packing (The size is in number of + * elements). + * + * rows and cols are only used for fully packing, i.e., for B matrix. The + * client code can use this function to query how big the buffer used for + * packing should be. + */ + static int packedBufferSize( + int rows = 0, + int cols = 0, + const BlockingFactors* params = nullptr); + + FBGEMM_PUSH_WARNING_AND_DISABLE("-Wpragmas") + FBGEMM_PUSH_WARNING_AND_DISABLE("-Winfinite-recursion") + /** + * @return Pointer to a buffer containing row offset results. Some packing + * objects fuse row offset computation for later requantization step. + */ + std::int32_t* getRowOffsetBuffer() const { + return static_cast(this)->getRowOffsetBuffer(); + } + /** + * @brief When k loop is also tiled/blocked, this function is used to check if + * have executed computations for the last k block so that we can perform + * post-GEMM operations. + */ + bool isThisLastKBlock(int block_id) const { + return static_cast(this)->isThisLastKBlock(block_id); + } + FBGEMM_POP_WARNING + FBGEMM_POP_WARNING + + /** + * @brief Actual packing of a block of the source matrix in pmat buffer. + */ + void pack(const block_type_t& block) { +#if defined(FBGEMM_FBCODE) || !defined(__aarch64__) + static_cast(this)->pack(block); +#else + throw std::runtime_error("PackMatrix::pack() not implemented for aarch64"); +#endif // __aarch64__ + } + + std::int32_t numRows() const { + return nrows_; + } + + std::int32_t numCols() const { + return ncols_; + } + + /** + * @return The number of rows in each block + */ + std::int32_t blockRowSize() const { + return brow_; + } + + /** + * @return The number of columns in each block + */ + std::int32_t blockColSize() const { + return bcol_; + } + + /** + * @return The number of blocks along rows + */ + std::int32_t blockRows() const { + return nbrow_; + } + + /** + * @return The number of blocks along columns + */ + std::int32_t blockCols() const { + return nbcol_; + } + + /** + * @return The number of the rows in the currently packed block of a matrix. + * For pre-packed (i.e., fully-packed), it's equal to the total number + * of rows. + */ + std::int32_t numPackedRows() const { + return packedBlock_.row_size; + } + + /** + * @return The number of columns in the currently packed block of a matrix. + * For pre-packed (i.e., fully-packed), it's equal to the number of + * columns. + */ + std::int32_t numPackedCols() const { + return packedBlock_.col_size; + } + + /** + * @return The first row of the block we're working on. + */ + std::int32_t packedRowStart() const { + return packedBlock_.row_start; + } + + /** + * @return The first column of the block we're working on. + */ + std::int32_t packedColStart() const { + return packedBlock_.col_start; + } + + /** + * @return The beginning of (rowBlockNum, colBlockNum)th block + */ + inpType* getBuf(std::int32_t rowBlockNum = 0, std::int32_t colBlockNum = 0) { + return buf_ + blockRowSize() * blockColSize() * rowBlockNum + + blockRowSize() * blockColSize() * blockCols() * colBlockNum; + } + + /** + * @brief Print the packed block. + */ + void printPackedMatrix(const std::string& name) { + static_cast(this)->printPackedMatrix(name); + } + + /** + * @return The number of rows in the last row block. + */ + std::int32_t lastBrow() const { + return last_brow_; + } + + /** + * @return The number of columns in the last column block. + */ + std::int32_t lastBcol() const { + return last_bcol_; + } + + int numGroups() const { + return G_; + } + + /** + * @return True if the last column block has fewer columns than the block + * size. + */ + bool isThereColRemainder() const { + return last_bcol_ != blockColSize(); + } + + virtual ~PackMatrix() { + if (bufAllocatedHere_) { + fbgemmAlignedFree(buf_); + } + } + + protected: + /** + * Set which block we're packing + */ + void packedBlock(const block_type_t& block) { + packedBlock_ = block; + nbrow_ = (numPackedRows() + blockRowSize() - 1) / blockRowSize(); + nbcol_ = (numPackedCols() + blockColSize() - 1) / blockColSize(); + + last_brow_ = ((numPackedRows() % blockRowSize()) == 0) + ? blockRowSize() + : (numPackedRows() % blockRowSize()); + last_bcol_ = ((numPackedCols() % blockColSize()) == 0) + ? blockColSize() + : (numPackedCols() % blockColSize()); + } + + inpType* buf_; + std::int32_t brow_; ///< the number of rows in each block + std::int32_t bcol_; ///< the number of columns in each block + std::int32_t nbrow_; ///< the number of blocks along rows + std::int32_t nbcol_; ///< the number of blocks along columns + bool bufAllocatedHere_{false}; + const BlockingFactors* + blocking_params; ///< MCB, KCB, NCB, MR, NR, NR_MIN, ROW_INTERLEAVE; + + private: + std::int32_t nrows_, ncols_; + int G_; + block_type_t packedBlock_; ///< The block in the source matrix just packed + std::int32_t last_brow_, last_bcol_; +}; + +/** + * @brief Matrix packed for the first input matrix in GEMM (usually + * activation). The source matrix is already quantized. Default + * accumulation type is int32. + */ +template +class FBGEMM_API PackAMatrix final + : public PackMatrix, T, accT> { + public: + using This = PackAMatrix; + using BaseType = PackMatrix; + using inpType = T; + using accType = accT; + + PackAMatrix() = delete; // no default constructor + + PackAMatrix( + matrix_op_t trans, + std::int32_t nRow, + std::int32_t nCol, + const inpType* smat, + std::int32_t ld, + inpType* pmat = nullptr, + int groups = 1, + const BlockingFactors* params = nullptr); + + /** + * Activation matrices are not constant so cannot amortize the cost of + * pre-packing. + */ + bool isPrePacked() const { + return false; + } + + /** + * @return True if this is used as A matrix. + */ + static constexpr bool isA() { + return true; + } + + /** + * @return A pointer to the row offset buffer. There is no row offset buffer + * calculations with this packing class, hence, it returns nullptr. + */ + std::int32_t* getRowOffsetBuffer() const { + return nullptr; + } + + /** + * @return Offset of the element in the packed matrix that was at (i, j) in + * the source matrix. + */ + std::int32_t addr(std::int32_t i, std::int32_t j) const; + + /** + * @brief Packs a block of source matrix into pmat buffer. + */ + void pack(const block_type_t& block); + + /** + * @brief Print the packed block. + */ + void printPackedMatrix(const std::string& name); + + private: + matrix_op_t trans_; + const T* smat_; + std::int32_t ld_; + std::int32_t row_interleave_B_; +}; + +/** + * @brief Matrix packed for the second input matrix in GEMM (usually weight). + * The source matrix is already quantized. Default accumulation + * type is int32. + */ +template +class FBGEMM_API PackBMatrix final + : public PackMatrix, T, accT> { + public: + using This = PackBMatrix; + using BaseType = PackMatrix; + using inpType = T; + using accType = accT; + + PackBMatrix() = delete; // no default constructor + + /** + * @param groups if > 1 and trans == NoTranspose, smat is nRow x nCol with + * groups are vertically concatenated: each group is + * (nRow / groups) x nCol . + * if > 1 and trans == Transpose, smat is (nCol * groups) x + * (nRow / groups) with groups are horizontally concatenated: + * each group is nCol x (nRow / groups) . Each group is + * transposed and vertically concatenated to match with the + * NoTranspose case. + */ + PackBMatrix( + matrix_op_t trans, + std::int32_t nRow, + std::int32_t nCol, + const inpType* smat, + std::int32_t ld, + inpType* pmat = nullptr, + int groups = 1, + const BlockingFactors* params = nullptr); + + /** + * Weight matrices are usually constant so worth pre-packing. + */ + bool isPrePacked() const { + return true; + } + + /** + * @return True if to be used as A matrix, False otherwise. + */ + static constexpr bool isA() { + return false; + } + + /** + * @brief When k loop is also tiled/blocked, this function is used to check if + * have executed computations for the last k block so that we can perform + * post-GEMM operations. + */ + bool isThisLastKBlock(int block_id) const { + return (BaseType::blockRows() - 1) == block_id; + } + + /** + * @return Offset of the element in the packed matrix that was at (i, j) in + * the source matrix. + */ + std::int32_t addr(std::int32_t i, std::int32_t j) const; + + /** + * @brief Packs a block of source matrix into pmat buffer. The blocking + * parameters are needed to compute the buffer size of each group. + * It will use default blocking parameters if params is not provided. + */ + void pack(const block_type_t& block, const BlockingFactors* params = nullptr); + + /** + * @brief Print the packed block. + */ + void printPackedMatrix( + const std::string& name, + const BlockingFactors* params = nullptr); + + /** + * @return true if meta information like matrix shape is the same. + */ + bool metaEquals(const PackBMatrix& that) const; + /** + * @return true if matrices are the same. + */ + bool equals(const PackBMatrix& that) const; + + /** + * @brief Unpack pmat buffer to the origin_buf (Used for the serialization to + * recover weight matrix). + */ + void unpack(T* origin_buf, const BlockingFactors* params = nullptr); + + ~PackBMatrix() override = default; + + private: + matrix_op_t trans_; + const T* smat_; + std::int32_t ld_; + std::int32_t row_interleave_; + + /** + * @brief Internal function performing both pack & unpack + */ + void pack_unpack_( + const block_type_t& block, + T* unpack_buf, + T* pack_buf, + bool ispack, + const BlockingFactors* params = nullptr); +}; + +/** + * @brief Matrix packed for direct group convolution. + * The source matrix is already quantized. Default accumulation + * type is int32. + */ +template +class FBGEMM_API PackWeightMatrixForGConv { + public: + using This = PackWeightMatrixForGConv; + using inpType = T; + using accType = accT; + + PackWeightMatrixForGConv() = delete; // no default constructor + PackWeightMatrixForGConv(const PackWeightMatrixForGConv&) = delete; // no copy + PackWeightMatrixForGConv& operator=(const PackWeightMatrixForGConv&) = + delete; // no copy + + PackWeightMatrixForGConv(PackWeightMatrixForGConv&&) = delete; // no move + PackWeightMatrixForGConv& operator=(PackWeightMatrixForGConv&&) = + delete; // no move + + /** + * @param pmat if nullptr, a buffer is allocated and owned by this class. + */ + PackWeightMatrixForGConv( + matrix_op_t trans, + const conv_param_t& conv_param, + const inpType* sdata, + inpType* pdata = nullptr); + + /** + * Number of groups we work at a time to fill the full simd width + * e.g., IC_PER_G = 4 and OC_PER_G = 4, we work on two groups at a time + * to fill the avx2 width of 256 bits. + */ + static int numOfGroupsTogether(const conv_param_t& conv_param); + + /** + * @brief Packs a block of source matrix into pmat buffer. + */ + void pack(); + + /** + * @brief Unpacks a pmat buffer into source matrix. + */ + void unpack(T* origin_buf); + + /** + * @brief Return packed data + */ + inpType* getBuf() { + return pdata_; + } + + ~PackWeightMatrixForGConv() { + if (bufAllocatedHere_) { + fbgemmAlignedFree(pdata_); + } + } + + private: + matrix_op_t trans_; + const conv_param_t conv_param_; + const T* sdata_; + T* pdata_; + bool bufAllocatedHere_{false}; + // Number of groups we work at a time to fill the full simd width + int GTogether_; + + /** + * @brief Internal function performing both pack & unpack + */ + void pack_unpack_(const T* src, T* dst, bool ispack); + + /** + * @brief Get the index of the unpacked data + */ + int unpacked_index_(int t, int r, int s, int k, int g, int c, bool tr); + + /** + * @brief Get the index of the packed data + */ + int packed_index_(int t, int r, int s, int k, int g, int c); +}; + +/** + * @brief A container class to keep packed weight tensor for convolution. + * The source tensor should already be quantized. + * + * @tparam SPATIAL_DIM is equal to 2 for 2D convolutions and 3 for 3D + * convolutions. Default value is 2. + * @tparam T is the datatype for source tensor. Default value is int8. + * @tparam accT is the datatype to accumulate into. Default value is int32. + */ +template < + int SPATIAL_DIM = 2, + typename T = std::int8_t, + typename accT = std::int32_t> +class FBGEMM_API PackWeightsForConv { + public: + using This = PackWeightsForConv; + using inpType = T; + using accType = accT; + + PackWeightsForConv() = delete; // no default constructor + + PackWeightsForConv( + const conv_param_t& conv_param, + const inpType* sdata, + const BlockingFactors* blocking_params = nullptr); + + std::shared_ptr> getPackedWForIm2col() { + return W_im2col_packed_; + } + +#if defined(FBGEMM_FBCODE) || !defined(__aarch64__) + std::shared_ptr getPackedWForDepthwise() { + return W_dw_packed_; + } +#endif // __aarch64__ + + std::shared_ptr getPackedWForDirectconv() { + return W_dc_packed_; + } + + std::shared_ptr> + getPackedWForGroupwise() { + return W_gconv_packed_; + } + + std::shared_ptr> getPackedWForPointwise() { + return W_pointwise_packed_; + } + + int inputChannels() { + return conv_param_.IC; + } + + int outputChannels() { + return conv_param_.OC; + } + + std::array kernelDims() { + return conv_param_.K; + } + + int groups() { + return conv_param_.G; + } + + /** + * @brief Returns true if the packed weights would work for the given + * convolution parameters, and false otherwise + */ + bool isPackingCompliant(const conv_param_t& conv_p); + + /** + * @brief Returns a string of mismatching parameters + */ + std::string mismatchingParams(const conv_param_t& conv_p); + + /** + * @brief Unpack packed matric into origin_buf (Used for the serialization to + * recover weight matrix). + */ + void unpack(T* origin_buf); + + private: + const conv_param_t conv_param_; + // Packed weights if we use im2col based convolution implementation + std::shared_ptr> W_im2col_packed_; +#if defined(FBGEMM_FBCODE) || !defined(__aarch64__) + // Packed weights if we use depthwise convolution implementation + std::shared_ptr W_dw_packed_; +#endif // __aarch64__ + // Packed weights if we use direct convolution implementation + std::shared_ptr W_dc_packed_; + // Packed weights if we use groupwise (small channels per group) convolution + // implementation + std::shared_ptr> + W_gconv_packed_; + // Packed weights if we use direct gemm for pointwise convolution + std::shared_ptr> W_pointwise_packed_; +}; + +/** + * @brief Matrix packed for the first input matrix in GEMM (usually activation), + * and row offsets used for requantization is computed during packing. + * Im2col is fused with packing here. The source matrix is already + * quantized. + */ +template +class FBGEMM_API PackAWithIm2Col + : public PackMatrix, T, accT> { + public: + using This = PackAWithIm2Col; + using BaseType = PackMatrix; + using inpType = T; + using accType = accT; + + PackAWithIm2Col() = delete; // no default constructor + /** + * @param zero_pt the quantized value that maps to 0.0f floating-point number. + * @param row_offset If nullptr, this constructor internally allocates a + * buffer and owns it. Otherwise, this class doesn't own + * the buffer. The buffer will be populated when pack + * function is called. + * @param b_symmetric if true we skip row offset computation + */ + PackAWithIm2Col( + const conv_param_t& conv_param, + const T* sdata, + inpType* pmat = nullptr, + std::int32_t a_zero_pt = 0, + std::int32_t* row_offset = nullptr, + bool b_symmetric = false, + const BlockingFactors* params = nullptr); + + PackAWithIm2Col(const PackAWithIm2Col&) = delete; + PackAWithIm2Col(PackAWithIm2Col&&) = delete; + PackAWithIm2Col& operator=(const PackAWithIm2Col&) = delete; + PackAWithIm2Col& operator=(PackAWithIm2Col&&) = delete; + + /** + * Activation matrices are not constant so cannot amortize the cost of + * pre-packing. + */ + bool isPrePacked() const { + return false; + } + + /** + * @return True if this is used as A matrix. + */ + static constexpr bool isA() { + return true; + } + + /** + * @brief Packs a block of source matrix into pmat buffer. + */ + void pack(const block_type_t& block); + + /** + * @return A pointer to the row offset buffer. + */ + std::int32_t* getRowOffsetBuffer() const { + return row_offset_; + } + + /** + * @brief Print the packed block. + */ + void printPackedMatrix(const std::string& name); + + /** + * @return Size of row offset buffer in number of elements + */ + static int rowOffsetBufferSize(const BlockingFactors* params = nullptr); + + ~PackAWithIm2Col() override { + if (rowOffsetAllocatedHere) { + fbgemmAlignedFree(row_offset_); + } + } + + private: + const conv_param_t conv_p_; + const T* sdata_; + std::int32_t a_zero_pt_; + std::int32_t* row_offset_{nullptr}; + bool rowOffsetAllocatedHere{false}; + std::int32_t row_interleave_B_; +}; + +/** + * @brief Matrix packed for the first input matrix in GEMM (usually activation), + * and row offsets used for requantization is computed during packing. + * The source matrix is already quantized. + */ +template +class FBGEMM_API PackAWithRowOffset final + : public PackMatrix, T, accT> { + public: + using This = PackAWithRowOffset; + using BaseType = PackMatrix; + using inpType = T; + using accType = accT; + + PackAWithRowOffset() = delete; // no default constructor + /** + * @param row_offset If nullptr, this constructor internally allocates a + * buffer and owns it. Otherwise, this class doesn't own + * the buffer. The buffer will be populated when pack + * function is called. + */ + PackAWithRowOffset( + matrix_op_t trans, + std::uint32_t nRow, + std::uint32_t nCol, + const T* smat, + std::uint32_t ld, + inpType* pmat = nullptr, + int groups = 1, + std::int32_t* row_offset = nullptr, + const BlockingFactors* params = nullptr); + + PackAWithRowOffset(const PackAWithRowOffset&) = delete; + PackAWithRowOffset(PackAWithRowOffset&&) = delete; + PackAWithRowOffset& operator=(const PackAWithRowOffset&) = delete; + PackAWithRowOffset& operator=(PackAWithRowOffset&&) = delete; + + /** + * Activation matrices are not constant so cannot amortize the cost of + * pre-packing. + */ + bool isPrePacked() const { + return false; + } + + /** + * @return True if this is used as A matrix. + */ + static constexpr bool isA() { + return true; + } + + /** + * @return Offset of the element in the packed matrix that was at (i, j) in + * the source matrix + */ + std::int32_t addr(std::int32_t i, std::int32_t j) const; + + /** + * @brief Packs a block of source matrix into pmat buffer. + */ + void pack(const block_type_t& block); + + /** + * @return A pointer to the row offset buffer. + */ + std::int32_t* getRowOffsetBuffer() const { + return row_offset_; + } + + /** + * @brief Print the packed block. + */ + void printPackedMatrix(const std::string& name); + + /** + * @return size of row offset buffer in number of elements + */ + static int rowOffsetBufferSize(const BlockingFactors* params = nullptr); + + ~PackAWithRowOffset() override { + if (rowOffsetAllocatedHere) { + fbgemmAlignedFree(row_offset_); + } + } + + private: + matrix_op_t trans_; + const T* smat_; + std::uint32_t ld_; + std::int32_t* row_offset_{nullptr}; + bool rowOffsetAllocatedHere{false}; + std::int32_t row_interleave_B_; +}; + +/** + * @brief Matrix packed for the first input matrix in GEMM (usually activation), + * and row offsets used for requantization is computed during packing. + * The source matrix is in fp32 and quantized during packing. + */ +template +class FBGEMM_API PackAWithQuantRowOffset final + : public PackMatrix, T, accT> { + public: + using This = PackAWithQuantRowOffset; + using BaseType = PackMatrix; + using inpType = T; + using accType = accT; + + PackAWithQuantRowOffset() = delete; // no default constructor + /** + * @param row_offset If nullptr, this constructor internally allocates a + * buffer and owns it. Otherwise, this class doesn't own + * the buffer. The buffer will be populated when pack + * function is called. + */ + PackAWithQuantRowOffset( + matrix_op_t trans, + std::int32_t nRow, + std::int32_t nCol, + const float* smat, + std::int32_t ld, + inpType* pmat = nullptr, + float scale = 1.0f, + std::int32_t zero_pt = 0, + int groups = 1, + std::int32_t* row_offset = nullptr, + const BlockingFactors* params = nullptr); + PackAWithQuantRowOffset(const PackAWithQuantRowOffset&) = delete; + PackAWithQuantRowOffset(PackAWithQuantRowOffset&&) = delete; + PackAWithQuantRowOffset& operator=(const PackAWithQuantRowOffset&) = delete; + PackAWithQuantRowOffset& operator=(PackAWithQuantRowOffset&&) = delete; + + /** + * Activation matrices are not constant so cannot amortize the cost of + * pre-packing. + */ + bool isPrePacked() const { + return false; + } + + /** + * @return True if this is used as A matrix. + */ + static constexpr bool isA() { + return true; + } + + /** + * @return offset of the element in the packed matrix that was at (i, j) in + * the source matrix + */ + std::int32_t addr(std::int32_t i, std::int32_t j) const; + + /** + * @brief Packs a block of source matrix into pmat buffer. + */ + void pack(const block_type_t& block); + + /** + * @return A pointer to the row offset buffer. + */ + std::int32_t* getRowOffsetBuffer() const { + return row_offset_; + } + + /** + * @brief Print the packed block. + */ + void printPackedMatrix(const std::string& name); + + /** + * @return Size of row offset buffer in number of elements + */ + static int rowOffsetBufferSize(const BlockingFactors* params = nullptr); + + ~PackAWithQuantRowOffset() override { + if (rowOffsetAllocatedHere) { + fbgemmAlignedFree(row_offset_); + } + } + + private: + matrix_op_t trans_; + const float* smat_; + std::int32_t ld_; + float scale_; + std::int32_t zero_pt_; + std::int32_t* row_offset_{nullptr}; + bool rowOffsetAllocatedHere{false}; + std::int32_t row_interleave_B_; +}; + +/* + * + * Post Processing of outputs + * + */ + +/** + * @brief Does nothing. NoOp. Used as the last operation in the output + * processing pipeline. + * + */ +template +class FBGEMM_API DoNothing { + public: + using outType = outT; + using inpType = inT; + DoNothing() = default; + template + int f( + outType* /* unused */, + inpType* /* unused */, + const block_type_t& /* unused */, + int /* unused */, + int /* unused */) const { + return 0; + } +}; + +/** + * @brief Copy data pointed by inp ptr to out ptr when + * inp ptr and out ptr are not the same. + * inp buffer: row and column start points: (0, 0) + * output buffer: row and column start points: + * (block.row_start, block.col_start) + * + * This is the output processing stage that should passed when there is no + * requantization and output is required in the same format as internal buffer + * used for accumulation. + */ +template < + typename outT = std::int32_t, + typename inT = std::int32_t, + typename nextOPType = DoNothing> +class FBGEMM_API memCopy { + public: + using outType = outT; + using inpType = inT; + explicit memCopy(nextOPType& nextop) : nextop_(nextop) {} + template + inline int f( + outType* out, + inpType* inp, + const block_type_t& block, + int ld_out, + int ld_in) const; + + private: + nextOPType& nextop_; +}; + +/** + * @brief Perform scaling on accumulated data. + */ +template < + typename outT = std::int32_t, + typename inT = std::int32_t, + typename nextOPType = DoNothing> +class ScaleOP { + public: + using outType = outT; + using inpType = inT; + explicit ScaleOP(inpType scalingFactor) : scalingFactor_(scalingFactor) {} + + template + inline int f( + outType* out, + inpType* inp, + const block_type_t& block, + int ld_out, + int ld_in) const; + + private: + inpType scalingFactor_; +}; + +/** + * @brief Perform Relu on accumulated data. + */ +template < + typename outT = std::int32_t, + typename inT = std::int32_t, + typename nextOPType = DoNothing> +class ReluOutput { + public: + using outType = outT; + using inpType = inT; + explicit ReluOutput(inpType zero_pt) : zero_pt_(zero_pt) {} + + template + inline int f( + outType* out, + inpType* inp, + const block_type_t& block, + int ld_out, + int ld_in) const; + + private: + inpType zero_pt_; +}; + +/** + * @brief Perform Dense-Matrix * Sparse-Matrix as a part the of output + * processing pipeline. + * + * SPMDM (SParse Matrix times Dense Matrix) inplace on the 32-bit input buffer + * (inp). After modifying the input buffer, pass it to the next op. + * When groups > 1, each group is numRows() x (numCols()/groups) matrix. + */ +template < + typename outT = std::int32_t, + typename inT = std::int32_t, + typename nextOPType = DoNothing> +class FBGEMM_API DoSpmdmOnInpBuffer { + public: + using outType = outT; + using inpType = inT; + DoSpmdmOnInpBuffer( + nextOPType& nextop, + const std::uint8_t* A, + int lda, + const CompressedSparseColumn& B_csc, + int groups = 1) + : nextop_(nextop), A_(A), lda_(lda), B_csc_(B_csc), groups_(groups) {} + + template + inline int f( + outT* out, + inT* inp, + const block_type_t& block, + int ld_out, + int ld_in) const; + + private: + nextOPType& nextop_; + const std::uint8_t* A_; + const int lda_; + const CompressedSparseColumn& B_csc_; + const int groups_; +}; + +/** + * @brief Perform Dense-Matrix * Sparse-Matrix as a part the of output + * processing pipeline. + * + * SPMDM (SParse Matrix times Dense Matrix) inplace on the 32-bit input buffer + * (inp). After modifying the input buffer, pass it to the next op. + * When groups > 1, each group is numRows() x (numCols()/groups) matrix. + */ +template < + typename outT = std::int32_t, + typename inT = std::int32_t, + typename nextOPType = DoNothing> +class FBGEMM_API DoSConvOnInpBuffer { + public: + using outType = outT; + using inpType = inT; + DoSConvOnInpBuffer( + nextOPType& nextop, + const std::uint8_t* A, + const conv_param_t<>& conv_p, + std::int32_t A_zero_point, + const CompressedSparseColumn& B_csc) + : nextop_(nextop), + A_(A), + conv_p_(conv_p), + A_zero_point_(A_zero_point), + B_csc_(B_csc) {} + + template + inline int f( + outT* out, + inT* inp, + const block_type_t& block, + int ld_out, + int ld_in) const; + + private: + nextOPType& nextop_; + const std::uint8_t* A_; + const conv_param_t<> conv_p_; + const std::int32_t A_zero_point_; + const CompressedSparseColumn& B_csc_; +}; + +/** + * @brief Requantize values in inp buffer and write to out buffer. + * pass the out buffer to next op for further processing. + */ +template < + bool FUSE_RELU, + QuantizationGranularity Q_GRAN = QuantizationGranularity::TENSOR, + typename BIAS_TYPE = std::int32_t, + typename outT = std::uint8_t, + typename inT = std::int32_t, + typename nextOPType = DoNothing> +class FBGEMM_API ReQuantizeOutput { + public: + static constexpr int RELU_FUSED = FUSE_RELU; + static constexpr QuantizationGranularity QGRANType = Q_GRAN; + using BIAS_T = BIAS_TYPE; + using outType = outT; + using inpType = inT; + /** + * @param C_multiplier The length of this array is + * 1 when Q_GRAN == QuantizationGranularity::TENSOR, + * groups when Q_GRAN == QuantizationGranularity::GROUP, + * nCol if Q_GRAN == QuantizationGranularity::OUT_CHANNEL + * @param Bq_zero_point The length of this array should be the same as + * C_multiplier. + * @param row_offsets Typically, this should've been computed by a + * PackAMatrix and should be obtained by + * PackMatrix::getRowOffsetBuffer(). + * If Bq_zero_point == 0 (symmetric quantization of B + * matrix), we can pass nullptr. + * @param col_offsets This should be pre-computed for example using + * col_offsets_with_zero_pt_s8acc32_ref. + * The length should be nCol. + * See PackedRequantizeTest.cc for an example. + * TODO: if Aq_zero_point == 0, allow passing nullptr. + * @param bias can be nullptr otherwise the length should be nCol + * @param act_times_w_scale activation_scale * weight_scale. This is only + * used if bias is unquantized (i.e., float). + */ + ReQuantizeOutput( + nextOPType& nextop, + const float* C_multiplier, + std::int32_t C_zero_point, + std::int32_t Aq_zero_point, + const std::int32_t* Bq_zero_point, + const std::int32_t* row_offsets, + const std::int32_t* col_offsets, + const BIAS_T* bias, + std::uint32_t nCol, + int groups = 1, + const float* act_times_w_scale = nullptr) + : nextop_(nextop), + C_multiplier_(C_multiplier), + C_zero_point_(C_zero_point), + Aq_zero_point_(Aq_zero_point), + Bq_zero_point_(Bq_zero_point), + q_row_offsets_(row_offsets), + q_col_offsets_(col_offsets), + bias_(bias), + ncols_(nCol), + groups_(groups), + act_times_w_scale_(act_times_w_scale) {} + + template + inline int f( + outT* out, + const inT* inp, + const block_type_t& block, + int ld_out, + int ld_in) const; + + const float* getCMultiplier() const { + return C_multiplier_; + } + std::int32_t getAZeroPoint() const { + return Aq_zero_point_; + } + std::int32_t getCZeroPoint() const { + return C_zero_point_; + } + const std::int32_t* getBZeroPoint() const { + return Bq_zero_point_; + } + const std::int32_t* getRowOffsets() const { + return q_row_offsets_; + } + const std::int32_t* getColOffsets() const { + return q_col_offsets_; + } + const BIAS_T* getBias() const { + return bias_; + } + std::uint32_t getNCols() const { + return ncols_; + } + const float* getActWScale() const { + return act_times_w_scale_; + } + + void setRowOffsets(const std::int32_t* row_offsets) { + q_row_offsets_ = row_offsets; + } + + private: + nextOPType& nextop_; + const float* C_multiplier_; + std::int32_t C_zero_point_; + std::int32_t Aq_zero_point_; + const std::int32_t* Bq_zero_point_; + const std::int32_t* q_row_offsets_; + const std::int32_t* q_col_offsets_; + const BIAS_T* bias_; + std::uint32_t ncols_; + int groups_; + const float* act_times_w_scale_; +}; + +/** + * @brief Requantize to convert accumulated data to be used as float, i.e., the + * output would be used as float. + */ +template < + bool FUSE_RELU, + QuantizationGranularity Q_GRAN = QuantizationGranularity::TENSOR, + typename outT = float, + typename inT = std::int32_t, + typename nextOPType = DoNothing> +class FBGEMM_API ReQuantizeForFloat { + public: + using outType = outT; + using inpType = inT; + /** + * @param Bq_scale The length of this array is + * 1 when Q_GRAN == QuantizationGranularity::TENSOR, + * groups when Q_GRAN == QuantizationGranularity::GROUP, + * nCol if Q_GRAN == QuantizationGranularity::OUT_CHANNEL + * @param Bq_zero_point The length of this array should be the same as + * Bq_scale. + * @param row_offsets Typically, this should've been computed by a + * PackAMatrix and should be obtained by + * PackMatrix::getRowOffsetBuffer(). + * If Bq_zero_point == 0 (symmetric quantization of B + * matrix), we can pass nullptr. + * @param col_offsets This should be pre-computed for example using + * col_offsets_with_zero_pt_s8acc32_ref. + * The length should be nCol. + * See PackedRequantizeTest.cc for an example. + * TODO: if Aq_zero_point == 0, allow passing nullptr. + * @param bias can be nullptr otherwise the length should be nCol + */ + ReQuantizeForFloat( + nextOPType& nextop, + float Aq_scale, + const float* Bq_scale, + std::int32_t Aq_zero_point, + const std::int32_t* Bq_zero_point, + const std::int32_t* row_offsets, + const std::int32_t* col_offsets, + const float* bias, + std::uint32_t nCol, + int groups = 1) + : nextop_(nextop), + Aq_scale_(Aq_scale), + Bq_scale_(Bq_scale), + Aq_zero_point_(Aq_zero_point), + Bq_zero_point_(Bq_zero_point), + q_row_offsets_(row_offsets), + q_col_offsets_(col_offsets), + bias_(bias), + ncols_(nCol), + groups_(groups) {} + + template + inline int f( + outT* out, + inT* inp, + const block_type_t& block, + int ld_out, + int ld_in) const; + + private: + nextOPType& nextop_; + float Aq_scale_; + const float* Bq_scale_; + std::int32_t Aq_zero_point_; + const std::int32_t* Bq_zero_point_; + const std::int32_t* q_row_offsets_; + const std::int32_t* q_col_offsets_; + const float* bias_; + std::uint32_t ncols_; + int groups_; +}; + +// type specialized implementation in an include file +#include "./OutputProcessing-inl.h" // @manual + +/* + * + * ####### GEMM related functions ####### + * + */ + +/** + * Matrix B must be prepacked. For matrix A, packA.pack function is called to + * pack it. + * + * @tparam packingAMatrix processing of A matrix while packing, + * e.g., PackAWithQuantRowOffset + * + * @tparam packingBMatrix processing of B matrix while packing, + * e.g., pre-multiply by alpha + * @tparam cT data type of C matrix + * @tparam processOutputType further processing of outputs, e.g., Relu + */ +template < + typename packingAMatrix, + typename packingBMatrix, + typename cT, + typename processOutputType> +FBGEMM_API void fbgemmPacked( + PackMatrix< + packingAMatrix, + typename packingAMatrix::inpType, + typename packingAMatrix::accType>& packA, + PackMatrix< + packingBMatrix, + typename packingBMatrix::inpType, + typename packingBMatrix::accType>& packB, + cT* C, + std::int32_t* C_buffer, + std::uint32_t ldc, + const processOutputType& outProcess, + int thread_id, + int num_threads, + const BlockingFactors* blocking_params = nullptr); + +/** + * @brief Perform small-channels-per-group groupwise convolution + * Note: Currently threading is not supported. This function does + * nothing for thread_ids > 0, i.e., returns early. + * + * @param rowOffsetBuf nullptr if B uses symmetric quantization + * Note: Currently threading is not supported. This function does + * nothing for thread_ids > 0, i.e., returns early. + */ +template < + typename packed_W, + typename outType, + bool FUSE_RELU, + QuantizationGranularity Q_GRAN, + int SPATIAL_DIM = 2, + typename BIAS_TYPE = std::int32_t> +FBGEMM_API void fbgemmGroupwiseConv( + const conv_param_t& conv_param, + const std::uint8_t* activations, + std::int32_t a_zero_point, + std::int32_t* rowOffsetBuf, + packed_W& packed_weights, + outType* out, + std::int32_t* outBuffer, + const ReQuantizeOutput& outProcess, + int thread_id, + int num_threads); + +template < + int SPATIAL_DIM, + QuantizationGranularity Q_GRAN, + bool FUSE_RELU, + typename BIAS_TYPE = std::int32_t> +FBGEMM_API void fbgemmDirectConv( + const conv_param_t& conv_p, + const uint8_t* Aint8, + PackedDirectConvMatrix& Bint8_tr, + uint8_t* C, + int32_t* C_buffer, + const ReQuantizeOutput& outProcess, + const BIAS_TYPE* bias, + int thread_id, + int num_threads); + +/** + * @return Size of row offset buffer in number of elements needed for + * fbgemmGroupwiseConv + */ +template +FBGEMM_API int rowOffsetBufferSizeGConv( + const conv_param_t& conv_param); + +/** + * @brief Is this depthwise convolution optimized? + */ +template +bool takeDepthWiseFastPath(const conv_param_t& conv_p); + +/** + * @brief Is this groupwise convolution supported? + */ +template +FBGEMM_API bool fbgemmOptimizedGConv(const conv_param_t& conv_p); + +/** + * @brief Is this convolution a direct matrix-matrix multiplication, i.e., 1x1 + * (aka pointwise) with right paddings etc.? + */ +template +FBGEMM_API bool takePointWiseFastPath(const conv_param_t& conv_p); + +/** + * @brief Are we running on a fbgemm supported cpu? + */ +FBGEMM_API bool fbgemmSupportedCPU(); + +/** + * @brief Performs convolution using fastest path available. + * + * @tparam SPATIAL_DIM It's 2 for 2D convolutions and 3 for 3D convolutions. + */ +template < + typename processOutputType, + int SPATIAL_DIM = 2, + typename ACC_T = std::int32_t> +FBGEMM_API int fbgemmConv( + const conv_param_t& conv_p, + const std::uint8_t* activations, + PackWeightsForConv& packed_weights, + typename processOutputType::outType* out, + std::int32_t* outBuffer, + processOutputType& outProcess, + int thread_id, + int num_threads, + const BlockingFactors* blocking_params = nullptr); + +/** + * @brief Returns which fast path to take + * + * @tparam SPATIAL_DIM It's 2 for 2D convolutions and 3 for 3D convolutions. + * + * @return optimized_conv_t::depthwise, optimized_conv_t::groupwise or + * optimized_conv_t::im2col + * + */ +template +FBGEMM_API optimized_conv_t +ConvFastPath(const conv_param_t& conv_p); +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmBuild.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmBuild.h new file mode 100644 index 0000000000000000000000000000000000000000..f413d17980a5b8fcc3ea3e4f98b6ec81a98512c5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmBuild.h @@ -0,0 +1,116 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +// For details about dllexport/dllimport, checkout the following SO question +// https://stackoverflow.com/questions/57999/what-is-the-difference-between-dllexport-and-dllimport +#if !defined(FBGEMM_API) +#if defined(FBGEMM_STATIC) +#define FBGEMM_API +#define FBGEMM_ENUM_CLASS_API +#elif defined _WIN32 || defined __CYGWIN__ +#if (__GNUC__ || __clang__) && !(__MINGW64__ || __MINGW32__) +#if defined(FBGEMM_EXPORTS) +#define FBGEMM_API __attribute__((__dllexport__)) +#else +#define FBGEMM_API __attribute__((__dllimport__)) +#endif +#else +#if defined(FBGEMM_EXPORTS) +#define FBGEMM_API __declspec(dllexport) +#else +#define FBGEMM_API __declspec(dllimport) +#endif +#endif +#define FBGEMM_ENUM_CLASS_API +#else +#if __clang__ || __GNUC__ || __INTEL_COMPILER +#define FBGEMM_API __attribute__((__visibility__("default"))) +#else +#define FBGEMM_API +#endif +// Currently, enum classes need to be declaredly explicitly for shared build on +// macos +#if __clang__ +#define FBGEMM_ENUM_CLASS_API __attribute__((__visibility__("default"))) +#else +#define FBGEMM_ENUM_CLASS_API +#endif +#endif +#endif + +// Use this to indicate to not inline functions +#if __clang__ || __GNUC__ || __INTEL_COMPILER +#define NOINLINE __attribute__((noinline)) +#elif _MSC_VER +#define NOINLINE __declspec(noinline) +#else +#define NOINLINE +#endif + +// Use this to indicate always inline functions +#if __clang__ || __GNUC__ || __INTEL_COMPILER +#define ALWAYS_INLINE inline __attribute__((__always_inline__)) +#elif _MSC_VER +// commenting out because __forceinline takes too long time in MSVC +#define ALWAYS_INLINE // __forceinline +#else +#define ALWAYS_INLINE inline +#endif + +// Use the C++11 keyword "alignas" if you can +#if _MSC_VER +#define ALIGNAS(byte_alignment) __declspec(align(byte_alignment)) +#else +#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) +#endif + +// Sanitizers annotations +#if defined(__has_attribute) +#if __has_attribute(no_sanitize) +#define NO_SANITIZE(what) __attribute__((no_sanitize(what))) +#endif +#endif +#if !defined(NO_SANITIZE) +#define NO_SANITIZE(what) +#endif + +// Ignore __builtin_assume() when not supported by compiler. +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif +#if !__has_builtin(__builtin_assume) +#define __builtin_assume(x) (static_cast(0)) +#endif + +// Macro for silencing warnings +#if __clang__ || __GNUC__ +// clang-format off +#define FBGEMM_PUSH_WARNING _Pragma("GCC diagnostic push") +#define FBGEMM_DISABLE_WARNING_INTERNAL2(warningName) #warningName +#define FBGEMM_DISABLE_WARNING(warningName) \ + _Pragma( \ + FBGEMM_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored warningName)) +#define FBGEMM_PUSH_WARNING_AND_DISABLE(warningName) \ + _Pragma("GCC diagnostic push") \ + _Pragma( \ + FBGEMM_DISABLE_WARNING_INTERNAL2(GCC diagnostic ignored warningName)) +#define FBGEMM_POP_WARNING _Pragma("GCC diagnostic pop") +// clang-format on +#else +#define FBGEMM_PUSH_WARNING +#define FBGEMM_DISABLE_WARNING(NAME) +#define FBGEMM_PUSH_WARNING_AND_DISABLE(NAME) +#define FBGEMM_POP_WARNING +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmConvert.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmConvert.h new file mode 100644 index 0000000000000000000000000000000000000000..6574dfc305700356f3ea6d16be69512c45208212 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmConvert.h @@ -0,0 +1,205 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include "fbgemm/FbgemmBuild.h" +#include "fbgemm/Types.h" + +namespace fbgemm { + +/** + * @ Transform all entries in a matrix from fp32 to bfloat16: reference + * implementation. + * + */ +FBGEMM_API void +FloatToBfloat16_ref(const float* src, bfloat16* dst, size_t size); + +/** + * @ Transform all entries in a matrix from bfloat16 to fp32: reference + * implementation. + * + */ +FBGEMM_API void +Bfloat16ToFloat_ref(const bfloat16* src, float* dst, size_t size); + +/** + * @ Transform all entries in a matrix from fp32 to bfloat16: simd + * implementation. + * + */ +FBGEMM_API void +FloatToBfloat16_simd(const float* src, bfloat16* dst, size_t size); + +/** + * @ Transform all entries in a matrix from bfloat16 to fp32: simd + * implementation. + * + */ +FBGEMM_API void +Bfloat16ToFloat_simd(const bfloat16* src, float* dst, size_t size); + +#if !defined(__aarch64__) +/** + * @brief AVX2 implementation to convert fp32 numbers to bf16 numbers. + * + */ +FBGEMM_API void +FloatToBfloat16_avx2(const float* src, bfloat16* dst, size_t size); + +/** + * @brief AVX512 implementation to convert fp32 numbers to bf16 numbers. + * + */ +FBGEMM_API void +FloatToBfloat16_avx512(const float* src, bfloat16* dst, size_t size); + +/** + * @brief AVX2 implementation to convert bf16 numbers to fp32 numbers. + * + */ +FBGEMM_API void +Bfloat16ToFloat_avx2(const bfloat16* src, float* dst, size_t size); + +/** + * @brief AVX512 implementation to convert bf16 numbers to fp32 numbers. + * + */ +FBGEMM_API void +Bfloat16ToFloat_avx512(const bfloat16* src, float* dst, size_t size); +#endif + +/** + * @ Transform all entries in a matrix from fp32 to float16: reference + * implementation. + * + * @param do_clip if true we saturate to fp16 min and max instead of generating + * infinities. + */ +FBGEMM_API void FloatToFloat16_ref( + const float* src, + float16* dst, + size_t size, + bool do_clip = false); + +/** + * @ Transform all entries in a matrix from float16 to fp32: reference + * implementation. + * + */ +FBGEMM_API void Float16ToFloat_ref(const float16* src, float* dst, size_t size); + +/** + * @ Transform all entries in a matrix from fp32 to float16: simd + * implementation. + * + * @param do_clip if true we saturate to fp16 min and max instead of generating + * infinities. + */ +FBGEMM_API void FloatToFloat16_simd( + const float* src, + float16* dst, + size_t size, + bool do_clip = false); + +/** + * @ Transform all entries in a matrix from float16 to fp32: simd + * implementation. + * + */ +FBGEMM_API void +Float16ToFloat_simd(const float16* src, float* dst, size_t size); + +/** + * @brief AVX2 implementation to convert fp32 numbers to fp16 numbers. + * + */ +#if !defined(__aarch64__) +FBGEMM_API void FloatToFloat16_avx2( + const float* src, + float16* dst, + size_t size, + bool do_clip = false); + +/** + * @brief AVX512 implementation to convert fp32 numbers to fp16 numbers. + * + */ +FBGEMM_API void FloatToFloat16_avx512( + const float* src, + float16* dst, + size_t size, + bool do_clip = false); +#endif + +/** + * @brief SVE2 implementation to convert fp32 numbers to fp16 numbers. + * + */ +FBGEMM_API void FloatToFloat16_sve2( + const float* src, + float16* dst, + size_t size, + bool do_clip = false); + +#if !defined(__aarch64__) +/** + * @brief AVX2 implementation to convert fp16 numbers to fp32 numbers. + * + */ +FBGEMM_API void +Float16ToFloat_avx2(const float16* src, float* dst, size_t size); + +/** + * @brief AVX512 implementation to convert fp16 numbers to fp32 numbers. + * + */ +FBGEMM_API void +Float16ToFloat_avx512(const float16* src, float* dst, size_t size); +#endif + +/** + * @brief Transform all entries in a matrix from fp32 to float16 and back to + * fp32. + */ +FBGEMM_API void RoundToFloat16( + const float* input, + float* output, + size_t size, + bool clamp = false, + bool clamp_denorms = false); + +/** + * @brief Quantize float32 to float8. The code is a copy of float_to_hfp8() in + * fbgemm_gpu/quantize_ops_utils.h + */ +FBGEMM_API void FloatToFloat8_ref( + float input, + uint8_t* output, + int exponent_bits, + int exponent_bias); + +/** + * @brief Dequantize float8 to float32. The code is a copy of hf8_to_float() in + * fbgemm_gpu/quantize_ops_utils.h + */ +FBGEMM_API void Float8ToFloat_ref( + uint8_t input, + float* output, + int exponent_bits, + int exponent_bias); + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmEmbedding.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmEmbedding.h new file mode 100644 index 0000000000000000000000000000000000000000..0da43d39fbdfd5d0df2958cc1f6d0b5fe5ff4cdb --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmEmbedding.h @@ -0,0 +1,383 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once +#include +#include + +#include "fbgemm/FbgemmBuild.h" + +namespace fbgemm { + +template < + typename InType, + typename IndexType, + typename OffsetType = std::int32_t, + typename OutType = float> +class EmbeddingSpMDMKernelSignature { + public: + /** + * Behavior is as the follow pseudocode + * (when use_offsets == true, lengths[i] == offsets[i + 1] - offsets[i]) + * (when is_weight_positional == true, use weights[j - offsets[i]] instead of + * weights[j]) + * + * for i in range(output_size): + * out[i * block_size : (i + 1) * block_size] = 0 + * for j in range(offsets[i], offsets[i + 1]): + * for k in range(block_size): + * out[i * block_size + k] += input[indices[j] * block_size + k] * + * weights ? weights[j] : 1; + * if normalize_weights and lengths[i] > 0: + * out[i * block_size : (i + 1) * block_size] /= lengths[i] + * + * @param data_size the number of rows in embedding table + */ + using Type = std::function; +}; + +/** + * @tparam InType can be float, float16, or uint8_t + * @tparam IndexType can be int32_t or int64_t + * @tparam IndexType can be int32_t or int64_t + * + * @param use_offsets If true, the generated code assumes we will pass offsets + * instead of lengths that confirms PyTorch EmbeddingBag + * interface. In this case, the length of offsets array + * should be output_size + 1 and offsets[output_size] should + * be index_size. + * If false, the generate code assumes we will pass lengths + * that confirms Caffe2 SparseLengthsSum interface. + */ +template < + typename InType, + typename IndexType, + typename OffsetType = std::int32_t, + typename OutType = float, + bool THREAD_LOCAL = false> +FBGEMM_API typename EmbeddingSpMDMKernelSignature< + InType, + IndexType, + OffsetType, + OutType>::Type +GenerateEmbeddingSpMDM( + const std::int64_t block_size, + bool has_weight, + bool normalize_by_lengths, + int prefetch = 16, + bool is_weight_positional = false, + bool use_offsets = true, + bool is_bf16_out = false, + bool is_bf16_in = false); + +/** + * @param output_stride If -1, output_stride is same as block_size + * @param input_stride If -1, input_stride is same as block_size + * @param scale_bias_last if false, scale and bias appear at the beginning + * of each row and are in fp16 for table batched embedding (TBE) + * in FBGEMM_GPU. If false, it can also take -1 indices (output from + * pruned embedding id mapping) + */ +template < + typename InType, + typename IndexType, + typename OffsetType = std::int32_t, + typename OutType = float, + bool THREAD_LOCAL = false> +FBGEMM_API typename EmbeddingSpMDMKernelSignature< + InType, + IndexType, + OffsetType, + OutType>::Type +GenerateEmbeddingSpMDMWithStrides( + const std::int64_t block_size, + bool has_weight, + bool normalize_by_lengths, + int prefetch = 16, + bool is_weight_positional = false, + bool use_offsets = true, + std::int64_t output_stride = -1, + std::int64_t input_stride = -1, + bool scale_bias_last = true, + bool no_bag = false, + bool is_bf16_out = false, + bool is_bf16_in = false); + +/** + * @tparam IndexType can be int32_t or int64_t + * @tparam OffsetType can be int32_t or int64_t + * @param bit_rate can be 2 or 4 + */ +template < + typename IndexType, + typename OffsetType = std::int32_t, + typename OutType = float> +FBGEMM_API typename EmbeddingSpMDMKernelSignature< + std::uint8_t, + IndexType, + OffsetType, + OutType>::Type +GenerateEmbeddingSpMDMNBit( + int bit_rate, + const std::int64_t block_size, + bool has_weight, + bool normalize_by_lengths, + int prefetch = 16, + bool is_weight_positional = false, + bool use_offsets = true); + +/** + * @param output_stride If -1, output_stride is same as block_size + * @param input_stride in Bytes. If -1, input_stride is same as + * block_size / num_elem_per_byte + 2 * sizeof(float16) + * @param scale_bias_last if false, scale and bias appear at the beginning + * of each row and are in fp16 for table batched embedding (TBE) + * in FBGEMM_GPU. If false, it can also take -1 indices (output from + * pruned embedding id mapping) + */ +template < + typename IndexType, + typename OffsetType = std::int32_t, + typename OutType = float, + bool THREAD_LOCAL = false> +FBGEMM_API typename EmbeddingSpMDMKernelSignature< + std::uint8_t, + IndexType, + OffsetType, + OutType>::Type +GenerateEmbeddingSpMDMNBitWithStrides( + const int input_bit_rate, + const std::int64_t block_size, + bool has_weight, + bool normalize_by_lengths, + int prefetch = 16, + bool is_weight_positional = false, + bool use_offsets = true, + std::int64_t output_stride = -1, + std::int64_t input_stride = -1, + bool scale_bias_last = true, + const bool is_bf16_out = false, + const bool no_bag = false, + int output_bit_rate = -1); + +/** + * @param output_stride If -1, output_stride is same as block_size + * @param input_stride in Bytes. If -1, input_stride is same as + * block_size / num_elem_per_byte + 2 * sizeof(float16) + * @param exponent_bits is the number of exponent bits in the FP8 encode + * (normally 4 or 5) + * @param exponent_bias is subtracted from the exponent to obtain the actual + * exponent for the floating-point number + */ +template < + typename IndexType, + typename OffsetType = std::int32_t, + typename OutType = float> +FBGEMM_API typename EmbeddingSpMDMKernelSignature< + std::uint8_t, + IndexType, + OffsetType, + OutType>::Type +GenerateEmbeddingSpMDMFP8WithStrides( + const std::int64_t block_size, + bool normalize_by_lengths, + bool is_weight_positional = false, + bool use_offsets = true, + std::int64_t output_stride = -1, + std::int64_t input_stride = -1, + int exponent_bits = 4, + int exponent_bias = 7, + bool is_bf16_out = false); + +template < + typename InType, + typename IndexType, + typename OffsetType = std::int32_t> +class EmbeddingSpMDMRowWiseSparseKernelSignature { + public: + using Type = std::function; +}; + +/** + * @tparam InType can be float, float16, or uint8_t + * @tparam IndexType can be int32_t or int64_t + * @tparam OffsetType can be int32_t or int64_t + */ +template < + typename InType, + typename IndexType, + typename OffsetType = std::int32_t> +FBGEMM_API typename EmbeddingSpMDMRowWiseSparseKernelSignature< + InType, + IndexType, + OffsetType>::Type +GenerateEmbeddingSpMDMRowWiseSparse( + const std::int64_t block_size, + bool has_weight, + bool normalize_by_lengths, + int prefetch = 16, + bool is_weight_positional = false, + bool use_offsets = true); + +/** + * @tparam IndexType can be int32_t or int64_t + * @tparam OffsetType can be int32_t or int64_t + * @param bit_rate can be 2 or 4 + */ +template +FBGEMM_API typename EmbeddingSpMDMRowWiseSparseKernelSignature< + std::uint8_t, + IndexType, + OffsetType>::Type +GenerateEmbeddingSpMDMNBitRowWiseSparse( + int bit_rate, + const std::int64_t block_size, + bool has_weight, + bool normalize_by_lengths, + int prefetch = 16, + bool is_weight_positional = false, + bool use_offsets = true); + +/** + * @return The number of rows processed. If smaller than num_rows, an error + * must have happened at the last row processed. + */ +template +class SparseAdaGradSignature { + public: + using Type = std::function; // frequency adjust happens only after +}; + +template +FBGEMM_API typename SparseAdaGradSignature::Type +GenerateSparseAdaGrad( + int block_size, // number of parameters per row + bool rowwise = false, + int prefetch = 16, + bool use_weight_decay = false); + +// RowWiseSparseAdaGrad fused with SLS gradient +// Weights can be either float or float16 +template < + typename IndexType, + typename OffsetType = std::int32_t, + typename DataType = float> +class RowWiseSparseAdaGradFusedSignature { + public: + using Type = std::function; +}; + +/** + * @param grad_stride If -1, grad_stride is same as block size + */ +template < + typename IndexType, + typename OffsetType = std::int32_t, + typename DataType = float> +FBGEMM_API typename RowWiseSparseAdaGradFusedSignature< + IndexType, + OffsetType, + DataType>::Type +GenerateRowWiseSparseAdaGradFused( + int block_size, // number of parameters per row + int prefetch = 16, + bool use_offsets = true, + bool use_stochastic_rounding = true, + int grad_stride = -1); + +namespace internal { +// Specialization for block size 1 internally called by GenerateEmbeddingSpMDM +template +FBGEMM_API bool EmbeddingSpMDMBlockSize1_( + const std::int64_t output_size, + const std::int64_t index_size, + const std::int64_t data_size, // the number of rows in input + const InType* input, + const IndexType* indices, + const OffsetType* offsets_or_lengths, + const float* weights, // optional, can be null for non-weighted sum + bool normalize_by_lengths, + float* out, + bool is_weight_positional = false, + bool use_offsets = true, + bool is_bf16 = false); + +#if !defined(__aarch64__) +template +void compressed_indices_remap_avx512( + std::int32_t offsets_numel, + const IndexType* indices, + const int32_t* compressed_indices_mapping, + const IndexType* offsets, + const float* weights, // optional, can be null, + IndexType* out_indices, + IndexType* out_offsets, + float* out_weights); +#endif + +} // namespace internal + +template +FBGEMM_API void compressed_indices_remap( + std::int32_t offsets_numel, + const IndexType* indices, + const int32_t* compressed_indices_mapping, + const IndexType* offsets, + const float* weights, // optional, can be null, + IndexType* out_indices, + IndexType* out_offsets, + float* out_weights); + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP16.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP16.h new file mode 100644 index 0000000000000000000000000000000000000000..254142290ef03e8aeb5ee40c28443af6f737a6bb --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP16.h @@ -0,0 +1,60 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +// WARNING: this is a legacy fp16 fbgemm implementation and will soon be +// upgraded to match with new fbgemm interface. + +#include + +#include "./FbgemmPackMatrixB.h" // @manual +#include "./FloatConversion.h" // @manual +#include "./Types.h" // @manual +#include "./Utils.h" // @manual + +namespace fbgemm { + +template <> +struct TypeConverter { + float16 operator()(float src) const { + constexpr float FP16_MAX = 65504.f; + const float fp16 = std::max(-FP16_MAX, std::min(src, FP16_MAX)); + return cpu_float2half(fp16); + } +}; + +using PackedGemmMatrixFP16 = PackedGemmMatrixB; + +template +FBGEMM_API void cblas_gemm_compute( + const matrix_op_t transa, + const int m, + const float* A, + const PackedGemmMatrixB& Bp, + const float beta, + float* C, + int thread_id = 0, + int num_threads = 1); + +extern template void cblas_gemm_compute( + const matrix_op_t transa, + const int m, + const float* A, + const PackedGemmMatrixFP16& Bp, + const float beta, + float* C, + int thread_id, + int num_threads); + +}; // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP32.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP32.h new file mode 100644 index 0000000000000000000000000000000000000000..91c0c4c7ce6bb8e062391b1b612dfc86720d2ef0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP32.h @@ -0,0 +1,54 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#pragma once + +// WARNING: this is a legacy fp16 fbgemm implementation and will soon be +// upgraded to match with new fbgemm interface. + +#include + +#include "fbgemm/FbgemmFPCommon.h" +#include "fbgemm/FbgemmPackMatrixB.h" +#include "fbgemm/Utils.h" + +namespace fbgemm { +template <> +struct TypeConverter { + float operator()(float src) const { + return src; + } +}; + +using GemmParamsFP32 = GemmParams; +using PackedGemmMatrixFP32 = PackedGemmMatrixB; + +template +void cblas_gemm_compute( + const matrix_op_t transa, + const int m, + const float* A, + const PackedGemmMatrixB& Bp, + const float beta, + float* C, + int thread_id = 0, + int num_threads = 1); + +extern template void cblas_gemm_compute( + const matrix_op_t transa, + const int m, + const float* A, + const PackedGemmMatrixFP32& Bp, + const float beta, + float* C, + int thread_id, + int num_threads); + +template <> +const isa_descriptor& getIsaHandlers(inst_set_t isa); + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFPCommon.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFPCommon.h new file mode 100644 index 0000000000000000000000000000000000000000..e4fd09a18f70ab177229aad256043b955dea884d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFPCommon.h @@ -0,0 +1,319 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include + +#if defined(FBGEMM_FP16_FALLBACK_TO_REF_KERNEL) || \ + defined(FBGEMM_FP32_FALLBACK_TO_REF_KERNEL) +#if defined(__APPLE__) && defined(__aarch64__) +#define FBGEMM_USE_REF_KERNEL +#endif +#endif + +namespace fbgemm { + +using partition_array_t = std::array, 2>, 121>; +extern partition_array_t partition_avx2; +extern partition_array_t partition_avx512; +extern partition_array_t partition_sve128; +#ifdef FBGEMM_ENABLE_KLEIDIAI +extern partition_array_t partition_neon; +#endif + +template +struct GemmParams { + uint64_t k; + float* A; + const T* B; + float beta; + float* C; + uint64_t ldc; + uint64_t b_block_cols; + uint64_t b_block_size; +}; + +template <> +struct GemmParams { + uint64_t k; + float* A; + const float16* B; + float beta; + float* C; + uint64_t ldc; + uint64_t b_block_cols; +#ifdef FBGEMM_ENABLE_KLEIDIAI + uint64_t lda; +#else + uint64_t b_block_size; +#endif +}; + +template <> +struct GemmParams { + uint64_t k; + float* A; + const float* B; + float beta; + float* C; + uint64_t ldc; + uint64_t b_block_cols; +#ifdef FBGEMM_ENABLE_KLEIDIAI + uint64_t lda; +#else + uint64_t b_block_size; +#endif +}; + +template +using funcptr_t = void (*)(GemmParams*); +template +using kernel_array_t = std::array, 15>; +template +using isa_descriptor = std::tuple, partition_array_t>; + +template +extern const isa_descriptor& getIsaHandlers(inst_set_t isa); + +void PackA(int nrow, int ncol, const float* from, int ldim, float* to); + +// define fp16/fp32 kernels using a reference C implementation +#if defined(FBGEMM_FP16_FALLBACK_TO_REF_KERNEL) || \ + defined(FBGEMM_FP32_FALLBACK_TO_REF_KERNEL) +template +FBGEMM_API void ref_kernel( + int kernel_nrows, + GemmParams* gp, + const float* C_base, + int m_total, + int n_total, + int vlen); +#endif + +template +FBGEMM_API void cblas_gemm_compute( + const matrix_op_t transa, + const int m, + const float* A, + const PackedGemmMatrixB& Bp, + const float beta, + float* C, + int thread_id = 0, + int num_threads = 1); + +#if defined(FBGEMM_EXPORTS) +// autotuned kernel splits for various cases m = 1:mb_max +template +void cblas_gemm_compute( + const matrix_op_t transa [[maybe_unused]], + const int m, + const float* A, + const PackedGemmMatrixB& Bp, + const float beta, + float* C, + int thread_id, + int num_threads) { + // ground truth + assert(cpuinfo_initialize()); +#ifndef __aarch64__ + assert(cpuinfo_has_x86_fma3()); + assert(cpuinfo_has_x86_f16c()); +#endif + assert(transa == matrix_op_t::NoTranspose); + + // private scratchpad storage + static thread_local std::unique_ptr> scratchpad( + new std::array()); + + // constants + const int n = Bp.numCols(), k = Bp.numRows(), ldc = n; + const int mb_max = 120; + +#if defined(FBGEMM_USE_REF_KERNEL) && defined(__APPLE__) + const auto& [_, partition] = getIsaHandlers(inst_set_t::sve); +#else + const auto iset = fbgemmInstructionSet(); + const auto& [kernels, partition] = getIsaHandlers(iset); +#endif + +#ifdef FBGEMM_USE_REF_KERNEL + // By some reason, if packed B is using packing layout for avx2, we just use + // avx2 even if avx512 is available. + const int simd_width = +#ifndef __aarch64__ + (iset == inst_set_t::avx512 || iset == inst_set_t::avx512_vnni) && + (Bp.blockColSize() == 16 * Bp.kernelNumColBlocks()) + ? simd_info::WIDTH_32BIT_ELEMS + : simd_info::WIDTH_32BIT_ELEMS; +#else + simd_info::WIDTH_32BIT_ELEMS; +#endif +#endif + + GemmParams gp; + int i_begin = 0, i_end = 0; + i_begin = 0; + i_end = m; + for (auto m0 = i_begin; m0 < i_end; m0 += mb_max) { + int mb = std::min(mb_max, i_end - m0); + assert(mb < static_cast(partition.size())); + for (auto k_ind = 0; k_ind < k; k_ind += Bp.blockRowSize()) { + // set up proper accumulation to avoid "Nan" problem + // accumulate of beta != 0.0 + // do not!!! accumulate otherwise + float beta_ = beta; + if (k_ind != 0) { + // always accumulate with beta_ = 1.0f + beta_ = 1.0f; + } + + const int kb = std::min(Bp.blockRowSize(), Bp.numRows() - k_ind); + + auto m1 = m0; + auto const num_cycles = partition[mb].size(); + for (size_t c = 0; c < num_cycles; ++c) { + auto kernel_nrows = partition[mb][c][0]; + auto nkernel_nrows = partition[mb][c][1]; + auto m_start = m1; + auto m_end = m1 + kernel_nrows * nkernel_nrows; + for (auto m2 = m_start; m2 < m_end; m2 += kernel_nrows) { + assert(kernel_nrows * kb < static_cast(scratchpad->size())); + if (m != 1) { +#ifdef FBGEMM_ENABLE_KLEIDIAI + if constexpr ( + std::is_same::value || + std::is_same::value) { + gp.A = const_cast(&A[m2 * k + k_ind]); + } else { +#endif + PackA( + kernel_nrows, kb, &A[m2 * k + k_ind], k, scratchpad->data()); + gp.A = scratchpad->data(); +#ifdef FBGEMM_ENABLE_KLEIDIAI + } +#endif + } else { + // When m == 1, it is actually vector matrix multiplication. We + // don't need to do the transposition for packA here. Instead, we + // can just pass the pointer of the original A matrix buffer to the + // packed A buffer. + gp.A = const_cast(&A[k_ind]); + } + + int nbcol = n / Bp.blockColSize(); + gp.k = kb; + gp.B = &(Bp(k_ind, 0)); + gp.beta = beta_; + gp.C = &C[m2 * ldc]; + gp.ldc = ldc * sizeof(C[0]); + gp.b_block_cols = nbcol; +#ifdef FBGEMM_ENABLE_KLEIDIAI + if constexpr ( + std::is_same::value || + std::is_same::value) { + gp.lda = k * sizeof(A[0]); + } else { +#endif + gp.b_block_size = gp.k * Bp.blockColSize() * sizeof(gp.B[0]); +#ifdef FBGEMM_ENABLE_KLEIDIAI + } +#endif + if ((n % Bp.blockColSize()) == 0) { + int64_t jb_begin = 0, jb_end = 0; + fbgemmPartition1D( + thread_id, num_threads, gp.b_block_cols, jb_begin, jb_end); + gp.B += gp.k * Bp.blockColSize() * jb_begin; + gp.C += Bp.blockColSize() * jb_begin; + gp.b_block_cols = jb_end - jb_begin; + if (gp.b_block_cols) { +#ifdef FBGEMM_USE_REF_KERNEL + ref_kernel(kernel_nrows, &gp, C, m, n, simd_width); +#else + kernels[kernel_nrows](&gp); +#endif + } + } else { + int last_blk_col = nbcol * Bp.blockColSize(); + if (nbcol) { + int64_t jb_begin = 0, jb_end = 0; + fbgemmPartition1D( + thread_id, num_threads, gp.b_block_cols, jb_begin, jb_end); + gp.B += gp.k * Bp.blockColSize() * jb_begin; + gp.C += Bp.blockColSize() * jb_begin; + gp.b_block_cols = jb_end - jb_begin; + if (gp.b_block_cols) { +#ifdef FBGEMM_USE_REF_KERNEL + ref_kernel(kernel_nrows, &gp, C, m, n, simd_width); +#else + kernels[kernel_nrows](&gp); +#endif + } + } + + // use one thread to handle the fringe cases + if (thread_id == num_threads - 1) { + // leftover + const int rem [[maybe_unused]] = n - last_blk_col; + assert(rem < Bp.blockColSize()); + + // small temporary buffer: the size should be larger than the + // required kernel_nrow x kernel_ncols elements computed in the + // registers. + std::array c_tmp{0.f}; + assert( + static_cast(c_tmp.size()) >= + kernel_nrows * Bp.blockColSize()); + + gp.B = &(Bp(k_ind, last_blk_col)); + gp.C = c_tmp.data(); + gp.ldc = Bp.blockColSize() * sizeof(C[0]); + gp.b_block_cols = 1; +#ifdef FBGEMM_USE_REF_KERNEL + ref_kernel( + kernel_nrows, &gp, c_tmp.data(), 14, 32, simd_width); +#else + kernels[kernel_nrows](&gp); +#endif + for (int i = 0; i < kernel_nrows; i++) { + // Todo: use assembly + for (int j = last_blk_col; j < n; j++) { + assert( + i * Bp.blockColSize() + (j - last_blk_col) < + static_cast(sizeof(c_tmp) / sizeof(c_tmp[0]))); + if (beta_ == 0.f) { + C[(m2 + i) * ldc + j] = + c_tmp[i * Bp.blockColSize() + (j - last_blk_col)]; + } else { + C[(m2 + i) * ldc + j] = beta_ * C[(m2 + i) * ldc + j] + + c_tmp[i * Bp.blockColSize() + (j - last_blk_col)]; + } + } + } + } + } + } + m1 += kernel_nrows * nkernel_nrows; + } + } + } +} +#endif + +#undef FBGEMM_USE_REF_KERNEL +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI64.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI64.h new file mode 100644 index 0000000000000000000000000000000000000000..8d95013257c8419d468815ce055bfb56898a432c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI64.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include "fbgemm/Utils.h" + +namespace fbgemm { + +FBGEMM_API void cblas_gemm_i64_i64acc( + matrix_op_t transa, + matrix_op_t transb, + int M, + int N, + int K, + const std::int64_t* A, + int lda, + const std::int64_t* B, + int ldb, + bool accumulate, + std::int64_t* C, + int ldc); + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DepthwiseAvx2.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DepthwiseAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..70571cded3d6f574afd2f471cb418baf2ab9022a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DepthwiseAvx2.h @@ -0,0 +1,117 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include "fbgemm/ConvUtils.h" +#include "fbgemm/FbgemmBuild.h" +#include "fbgemm/UtilsAvx2.h" + +namespace fbgemm { + +class FBGEMM_API PackedDepthWiseConvMatrix { + public: + /** + * @param IC the number of input channels (same as the number of groups + * because depth-wise convolution has one input channel per group) + * @param OC the number of output channels + * @param kernel_prod the product of all kernels. For example, kernel_prod = + * 9 for 3x3 conv, and 27 for 3x3x3 conv. + * @param smat the source unpacked weight in GRS layout + */ + PackedDepthWiseConvMatrix(int OC, int kernel_prod, const std::int8_t* smat); + PackedDepthWiseConvMatrix(const PackedDepthWiseConvMatrix&) = delete; + PackedDepthWiseConvMatrix(PackedDepthWiseConvMatrix&&) = delete; + PackedDepthWiseConvMatrix& operator=(const PackedDepthWiseConvMatrix&) = + delete; + PackedDepthWiseConvMatrix& operator=(PackedDepthWiseConvMatrix&&) = delete; + virtual ~PackedDepthWiseConvMatrix(); + + const std::int8_t* PackedMat() const { + return pmat_; + } + + int GetKernelProduct() const { + return kernel_prod_; + } + + /** + * @brief Unpacks pmat_ into unpack_data. + * Used for recovering the weight matrix into the original format + */ + void unpack(std::int8_t* unpacked_data); + + /** + * @brief returns the index into pmat_ given the row and column for smat + */ + int addr(int r, int c); + + private: + const int OC_; /**< the number of output channels */ + const int kernel_prod_; /** the product of all kernel dims */ + std::int8_t* pmat_; /** packed weight */ +}; // PackedDepthWiseConvMatrix + +/** + * Depth-wise convolution that results in the same output feature size as the + * input feature. That is PAD_T = PAD_B = (R - 1) / 2 and PAD_L = PAD_R = + * (S - 1) / 2. This function also does requantization. + * @param col_offsets nullptr if col_offsets are folded into bias + * @param act_times_w_scale Only used if BIAS_TYPE is float, i.e., bias is + * unquantized. + */ +template +FBGEMM_API void depthwise_2d_same_pad( + int N, + int H, + int W, + int IC, + int OC, + int stride_h, + int stride_w, + std::int32_t A_zero_point, + const std::uint8_t* A, + const std::int32_t* B_zero_point, + const PackedDepthWiseConvMatrix& Bp, + const float* C_multiplier, + std::int32_t C_zero_point, + std::uint8_t* C, + const std::int32_t* col_offsets, + const BIAS_TYPE* bias, + bool fuse_relu = false, + const float* act_times_w_scale = nullptr, + int thread_id = 0, + int num_threads = 1); + +/** + * @param col_offsets nullptr if col_offsets are folded into bias + */ +template +FBGEMM_API void depthwise_3d_same_pad( + const conv_param_t<3>& conv_p, + std::int32_t A_zero_point, + const std::uint8_t* A, + const std::int32_t* B_zero_point, + const PackedDepthWiseConvMatrix& Bp, + const float* C_multiplier, + std::int32_t C_zero_point, + std::uint8_t* C, + const std::int32_t* col_offsets, + const BIAS_TYPE* bias, + bool fuse_relu = false, + const float* act_times_w_scale = nullptr, + int thread_id = 0, + int num_threads = 1); + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DirectconvAvx2.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DirectconvAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..e0cd02f1eea7b442fa31bbe03ca5074ca30b2f1c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DirectconvAvx2.h @@ -0,0 +1,69 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include "fbgemm/ConvUtils.h" +#include "fbgemm/FbgemmBuild.h" + +namespace fbgemm { + +class FBGEMM_API PackedDirectConvMatrix { + public: + /** + * @param IC the number of input channels + * @param OC the number of output channels + * @param kernel_prod the product of all kernels. For example, kernel_prod = + * 9 for 3x3 conv, and 27 for 3x3x3 conv. + * @param smat the source unpacked weight in GRS layout + */ + PackedDirectConvMatrix( + int IC_per_G, + int OC_per_G, + int filter_prod, + const std::int8_t* smat); + PackedDirectConvMatrix(const PackedDirectConvMatrix&) = delete; + PackedDirectConvMatrix(PackedDirectConvMatrix&&) = delete; + PackedDirectConvMatrix& operator=(const PackedDirectConvMatrix&) = delete; + PackedDirectConvMatrix& operator=(PackedDirectConvMatrix&&) = delete; + + virtual ~PackedDirectConvMatrix(); + + const std::int8_t* PackedMat() const { + return pmat_; + } + + const bool& is_first_call() const { + return first_call; + } + + /** + compute the column offsets of the weight matrix. + output of this function is the col_offsets vector + col_offses dimension is the same as conv_p.OUT_DIM + */ + template + FBGEMM_API void col_offsets_with_zero_pt_s8acc32_DirectConvT( + const fbgemm::conv_param_t& conv_p, + std::int32_t* B_zero_point, + std::vector& col_offsets, + int ncols_per_quant_group); + + private: + std::int8_t* pmat_; /** packed weight */ + bool first_call{true}; +}; + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8Spmdm.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8Spmdm.h new file mode 100644 index 0000000000000000000000000000000000000000..650f5d6bf6ab5c67548f79997f170ef26cdaf614 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8Spmdm.h @@ -0,0 +1,140 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include "./ConvUtils.h" // @manual +#include "./FbgemmBuild.h" // @manual +#include "./Utils.h" // @manual + +// #define FBGEMM_MEASURE_TIME_BREAKDOWN + +#ifdef FBGEMM_MEASURE_TIME_BREAKDOWN +#include +#include +extern double spmdm_initial_time; +extern double spmdm_transpose_uint8_time; +extern double spmdm_transpose_32xN_time; +extern double spmdm_compute_time; +extern double spmdm_transpose_Nx32_time; +extern double spmdm_run_time; +extern double sconv_run_time; +#endif + +namespace fbgemm { + +/** + * @brief A class to represent a matrix in Compressed Sparse Column (CSC) + * format. + * + * The second input matrix of matrix multiplication is usually weight and can + * be sparse, and it's usually more efficient to use CSC format to represent + * the second input matrix. + */ +class FBGEMM_API CompressedSparseColumn { + public: + CompressedSparseColumn(int num_of_rows, int num_of_cols); + + std::vector& ColPtr() { + return colptr_; + } + std::vector& RowIdx() { + return rowidx_; + } + std::vector& Values() { + return values_; + } + std::vector& KHs() { + return kh_; + } + std::vector& KWs() { + return kw_; + } + /** + * ICs include group: i.e. for ith input channels withint group g, ICs contain + * g*(groups_per_input_channels) + i + */ + std::vector& ICs() { + return ic_; + } + + std::size_t NumOfRows() const { + return num_rows_; + } + std::size_t NumOfCols() const { + return colptr_.size() - 1; + } + std::int32_t NumOfNonZeros() const { + return colptr_.back(); + } + + /** + * @return Total number of non-zero elements as a fraction of total + * elements. + */ + double Density() const; + + /** + * @return True if the number of non-zeros per row is smaller than a small + * threshold. + */ + bool IsHyperSparse() const; + + /** + * @brief Perform dense-matrix * sparse matrix. + * + * C += A (dense matrix) * B (this CSC matrix) if accumulation = true \n + * C = A (dense matrix) * B (this CSC matrix) if accumulation = false + */ + void SpMDM( + const block_type_t& block, + const std::uint8_t* A, + int lda, + bool accumulation, + std::int32_t* C, + int ldc) const; + + void SparseConv( + const conv_param_t<>& conv_p, + const block_type_t& block, + const std::uint8_t* A, + std::int32_t A_zero_point, + bool accumulation, + std::int32_t* C, + int ldc) const; + + private: + const std::size_t num_rows_; + std::vector colptr_; // corresponds to out channels + std::vector values_; + + // For SpMDM + std::vector rowidx_; // kh kw ic are flattened with im2col + + // For direct sparse convolution + std::vector kh_; + std::vector kw_; + std::vector ic_; // in channels + + // Cache IsHyperSparse to minimize its overhead. + mutable bool hyper_sparse_{false}; + + // Whether we can reuse the cached hyper_sparse_ is determined by checking + // if NumOfNonZeros() is same as old_nnz_ saved in previous invocation of + // IsHyperSparse call. + mutable std::int32_t old_nnz_{-1}; +}; + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmPackMatrixB.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmPackMatrixB.h new file mode 100644 index 0000000000000000000000000000000000000000..407c372c434d7091455f7664baccdc902805c4e2 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmPackMatrixB.h @@ -0,0 +1,339 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * Copyright 2024-2025 Arm Limited and/or its affiliates + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +#include "SimdUtils.h" // @manual +#include "Types.h" // @manual +#include "Utils.h" // @manual + +namespace fbgemm { + +template +struct TypeConverter { + template + T operator()(F) const; +}; + +#define PMAT_ALIGNMENT 64 + +/// class that performs packing of matrix in +/// row-major format into +/// internal packed blocked-row major format +template > +class PackedGemmMatrixB { + public: + using value_type = T; + using size_type = uint64_t; + + // takes smat input mamtrix in row-major format; + // packs it into gemm-friendly blocked format; + // allocate space and sets up all the internal variables; + // also premultiplies by alpha during packing. + // brow_ contains tile size along k dimension + // and also is # of fmas updates into int16 container + // before flushing into fp32. + // the smaller the brow_, the higher overhead + // of flushing is. + // kernel_ncol_blocks is the number of column blocks (in the size of 8 fp16, + // or 128 bit, or 1 xmm register size) in the kernel. Because the batch size + // can be dynamic and we need to prepack the weight matrix B, the internal + // packing layout of the weight matrix and kernel_ncol_blocks have to be + // fixed. We can choose kernel_ncol_blocks = 1 (with kernels of 1x1~14x1 + // register layouts), 2 (with kernels of 1x2~6x2 register layout), or 3 (with + // kernels of 1x3~4x3 register layout). + PackedGemmMatrixB( + const matrix_op_t trans, + const int nrow, + const int ncol, + const float alpha, + const float* smat, + const int brow = 512) + : nrow_(nrow), ncol_(ncol), brow_(brow), kernel_ncol_blocks_(2) { +#ifdef FBGEMM_ENABLE_KLEIDIAI + if constexpr (std::is_same::value) { + kernel_ncol_blocks_ = 1; + } +#endif + initializeParam(); + initializeMemory(); + // copy source matrix into packed matrix + this->packFromSrc(trans, alpha, smat); + } + + PackedGemmMatrixB( + const int nrow, + const int ncol, + const int brow, + const int last_brow, + const int bcol, + const int nbrow, + const int nbcol, + const uint64_t size) + : nrow_(nrow), + ncol_(ncol), + brow_(brow), + last_brow_(last_brow), + bcol_(bcol), + nbrow_(nbrow), + nbcol_(nbcol), + size_(size), + kernel_ncol_blocks_(2) { +#ifdef FBGEMM_ENABLE_KLEIDIAI + if constexpr (std::is_same::value) { + kernel_ncol_blocks_ = 1; + } +#endif + initializeMemory(); + } + + PackedGemmMatrixB( + const int nrow, + const int ncol, + const int brow, + const int last_brow, + const int bcol, + const int nbrow, + const int nbcol, + const uint64_t size, + const int kernel_ncol_blocks, + void* pmat) + : nrow_(nrow), + ncol_(ncol), + brow_(brow), + last_brow_(last_brow), + bcol_(bcol), + nbrow_(nbrow), + nbcol_(nbcol), + size_(size), + kernel_ncol_blocks_(kernel_ncol_blocks) { +#ifdef FBGEMM_ENABLE_KLEIDIAI + if constexpr (std::is_same::value) { + kernel_ncol_blocks_ = 1; + } +#endif + pmat_ = static_cast(pmat); + packed_ = true; + pmat_passed_in = true; + } + PackedGemmMatrixB(const PackedGemmMatrixB&) = delete; + PackedGemmMatrixB(PackedGemmMatrixB&&) = delete; + PackedGemmMatrixB& operator=(const PackedGemmMatrixB&) = delete; + PackedGemmMatrixB& operator=(PackedGemmMatrixB&&) = delete; + + void initializeParam() { + if (!cpuinfo_initialize()) { + throw std::runtime_error("Failed to initialize cpuinfo!"); + } + bcol_ = (isZmm(fbgemmInstructionSet()) + ? simd_info::WIDTH_32BIT_ELEMS + : simd_info::WIDTH_32BIT_ELEMS) * + kernelNumColBlocks(); + + // set up internal packing parameters + nbrow_ = (numRows() + blockRowSize() - 1) / blockRowSize(); + last_brow_ = ((nrow_ % blockRowSize()) == 0) ? blockRowSize() + : (nrow_ % blockRowSize()); + nbcol_ = (numCols() + blockColSize() - 1) / blockColSize(); + + if (numCols() != blockColSize() * nbcol_) { +#ifdef VLOG + VLOG(0) << "Packer warning: ncol(" << numCols() + << ") is not a multiple of internal block size (" + << blockColSize() << ")"; + VLOG(0) << "lefover is not super optimized hence overhead will inccur"; +#endif + } + } + + void setPacked(bool p) { + packed_ = p; + } + + bool packed() const { + return packed_; + } + + void initializeMemory() { + // allocate and initialize packed memory + size_ = (blockRowSize() * nbrow_) * (blockColSize() * nbcol_); + pmat_ = static_cast( + fbgemmAlignedAlloc(PMAT_ALIGNMENT, matSize() * sizeof(T))); + memset(pmat_, 0, matSize() * sizeof(T)); + } + + ~PackedGemmMatrixB() { + if (pmat_passed_in == false) { + fbgemmAlignedFree(pmat_); + } + } + + void unpackFromSrc(const matrix_op_t trans, T* src_mat) { + bool tr = (trans == matrix_op_t::Transpose); + for (int i = 0; i < numRows(); i++) { + for (int j = 0; j < numCols(); j++) { + pmat_[tr ? i + numRows() * j : i * numCols() + j] = src_mat[addr(i, j)]; + } + } + packed_ = false; + } + + void unpack(T* origin_buf, const matrix_op_t trans) { + assert(packed_); + bool tr = (trans == matrix_op_t::Transpose); + for (int i = 0; i < numRows(); i++) { + for (int j = 0; j < numCols(); j++) { + origin_buf[tr ? i + numRows() * j : i * numCols() + j] = + pmat_[addr(i, j)]; + } + } + } + + // protected: + // blocked row-major format address arithmetic + uint64_t addr(const int r_, const int c_) const { + uint64_t r = (uint64_t)r_; + uint64_t c = (uint64_t)c_; + + uint64_t block_row_id = r / blockRowSize(); + uint64_t brow_offset = + (block_row_id * nbcol_) * (blockRowSize() * blockColSize()); + uint64_t block_col_id = c / blockColSize(); + uint64_t bcol_offset = block_col_id * + ((static_cast(block_row_id) != nbrow_ - 1) + ? (blockRowSize() * blockColSize()) + : (last_brow_ * blockColSize())); + uint64_t block_offset = brow_offset + bcol_offset; + uint64_t inblock_offset = + r % blockRowSize() * blockColSize() + c % blockColSize(); + + uint64_t index = block_offset + inblock_offset; + assert(static_cast(index) < matSize()); + return index; + } + + void + packFromSrc(const matrix_op_t trans, const float alpha, const float* smat) { + bool tr = (trans == matrix_op_t::Transpose); + // pack + for (int i = 0; i < numRows(); i++) { + for (int j = 0; j < numCols(); j++) { + float src = alpha * + ((tr == false) ? smat[i * numCols() + j] : smat[i + numRows() * j]); + pmat_[addr(i, j)] = C()(src); + } + } + packed_ = true; + } + + // This function takes in an unpacked T matrix of the same size and + // packs it. There is no floating type conversion. + void packFromSrc(const matrix_op_t trans, const T* smat) { + bool tr = (trans == matrix_op_t::Transpose); + for (int i = 0; i < numRows(); ++i) { + for (int j = 0; j < numCols(); ++j) { + pmat_[addr(i, j)] = smat[tr ? i + numRows() * j : i * numCols() + j]; + } + } + packed_ = true; + } + + const T& operator()(const int r, const int c) const { + const auto a = addr(r, c); + assert(r < numRows()); + assert(c < numCols()); + assert(static_cast(a) < this->matSize()); + return pmat_[a]; + } + + int matSize() const { + return size_; + } + int numRows() const { + return nrow_; + } + int numCols() const { + return ncol_; + } + int lastBrow() const { + return last_brow_; + } + int numBrow() const { + return nbrow_; + } + int numBcol() const { + return nbcol_; + } + T* pmat() const { + return pmat_; + } + int blockRowSize() const { + return brow_; + } + int blockColSize() const { + return bcol_; + } + int kernelNumColBlocks() const { + return kernel_ncol_blocks_; + } + + const value_type* data() const { + return pmat_; + } + + uint64_t size() const { + return size_ / sizeof(value_type); + } + + int nrow_, ncol_; + int brow_, last_brow_, bcol_; + int nbrow_, nbcol_; + uint64_t size_; + int kernel_ncol_blocks_; + T* pmat_; + bool packed_{false}; + bool pmat_passed_in{false}; +}; + +#ifndef _M_X64 + +template <> +FBGEMM_API +PackedGemmMatrixB>::PackedGemmMatrixB( + const matrix_op_t trans, + const int nrow, + const int ncol, + const float alpha, + const float* smat, + const int brow); + +template <> +FBGEMM_API +PackedGemmMatrixB>::PackedGemmMatrixB( + const int nrow, + const int ncol, + const int brow, + const int last_brow, + const int bcol, + const int nbrow, + const int nbcol, + const uint64_t size); + +#endif + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmSparse.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmSparse.h new file mode 100644 index 0000000000000000000000000000000000000000..21a3a111271bc10b949cc9912d75fc775ffe3488 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmSparse.h @@ -0,0 +1,230 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +#include "fbgemm/FbgemmBuild.h" +#include "fbgemm/UtilsAvx2.h" +#include "fbgemm/spmmUtilsAvx2.h" + +namespace fbgemm { + +template +struct FBGEMM_API CSRMatrix { + std::vector rowPtr; + std::vector colIdx; + std::vector values; +}; + +/** + * Tiled block CSR format + * Partial blocks are zero-filled + * + */ +template +struct FBGEMM_API BCSRMatrix { + using DTYPE = T; + static constexpr int RB = ROW_BLOCK; // Block size for rows + static constexpr int CB = COL_BLOCK; // Block size for cols + // We only tile in column dimension currently + // COLTILE must be a multiple of COL_BLOCK + static constexpr int COLTILE = 4000; + std::vector rowBPtr; // rowPtr for blocks + std::vector colBIdx; // colIdx for blocks + std::vector values; + // Sum of all elements in a row + std::vector row_offsets; + int R; + int C; + + BCSRMatrix(int Rows, int Cols) { + R = Rows; + C = Cols; + row_offsets.resize(R, 0); + } + + /** + * @brief pack from dense to tiled block CSR format + * @param R number of rows in the matrix + * @param C number of columns in the matrix + * @param src is the source matrix with data type DTYPE + * @param ld is the leading dimension + */ + void pack(const DTYPE* src, size_t ld); + + /** + * @brief pack from dense to tiled block CSR format + * @param R number of rows in the matrix + * @param C number of columns in the matrix + * @param src is the source matrix with data type DTYPE + * + * leading dim of the matrix is assumed to be equal to C + */ + void pack(const DTYPE* src); + + /** + * @brief unpack from tiled block CSR to dense + * @param dst should be able to hold R*C elements of type DTYPE + * @param ld is the leading dimension + */ + void unpack(DTYPE* dst, size_t ld); + + /* + * @brief unpack from tiled block CSR to dense + * @param dst should be able to hold R*C elements of type DTYPE + * + * leading dimension of the matrix is assumed to be equal to C + */ + void unpack(DTYPE* dst); +}; + +template +FBGEMM_API std::unique_ptr> +fbgemmDenseToCSR(int R, int C, const T* inp, int ld); + +template +FBGEMM_API std::unique_ptr> +fbgemmDenseToCSR(int R, int C, const T* inp); + +template +FBGEMM_API std::unique_ptr> +fbgemmDenseToBCSR(int R, int C, const T* inp, int ld); + +template +FBGEMM_API std::unique_ptr> +fbgemmDenseToBCSR(int R, int C, const T* inp); + +/** + * @param accum Controls accumulation. + * 1 means we're accumulating to the C Matrix. + * + * Note on matrix order and layout: + * Unlike other fbgemm functions that follow PyTorch convention where A + * matrix is activation (so in uint8_t for quantized FC/Conv or fp32) and B + * matrix is weight (so in int8_t for quantized FC/Conv or fp32), here A is + * weight matrix. This is because we mostly target sparsity in weights and for + * row-major layout it's more efficient to have A as a sparse matrix: for each + * non-zero of A at ith row and kth column, we can access kth row of B, whose + * elements are contiguous in memory. If B matrix was sparse, for each non-zero + * of B at kth row and jth column, we would've needed to access kth column of A, + * whose elements are not contiguous in memory with C/C++'s row-major layout. + * Alternatively, we can call this function as if we're computing + * C^T = B^T * A^T while maintaining PyTorch's convention that the lefthand + * side matrix B is activation. If B matrix is in column-major layout, we don't + * need to do an extra transposition. The C matrix will be output in + * column-major layout, so if we have a back-to-back Sparse-Dense matrix-matrix + * multiplications, B matrices of subsequent matrices will be already in + * column-major layout. Refer to SparseDenseMMFP32Benchmark.cc for an example. + * + */ +FBGEMM_API void SparseDenseMM( + int M, + int N, + const int* row_ptr, + const int* col_idx, + const float* values, + const float* B, + int ldb, + float* C, + int ldc, + bool accum = false); + +template +FBGEMM_API void fbgemmSparseDenseInt8MM( + int N, + const std::unique_ptr>& bcsr, + const uint8_t* B, + int ldb, + int32_t* C_i32, + uint8_t* C_u8, + int ldc, + trRequantizationParams_t& rParams, + bool accum = false, + int thread_id = 0, + int num_threads = 1); + +namespace internal { + +void SparseDenseMMAvx2( + int M, + int N, + const int* row_ptr, + const int* col_idx, + const float* values, + const float* B, + int ldb, + float* C, + int ldc, + bool accum = false); + +#if !defined(__aarch64__) +void SparseDenseMMAvx512( + int M, + int N, + const int* row_ptr, + const int* col_idx, + const float* values, + const float* B, + int ldb, + float* C, + int ldc, + bool accum = false); + +template +void SparseDenseInt8MMAvx2( + int N, + const std::unique_ptr>& bcsr, + const uint8_t* B, + int ldb, + int32_t* C_i32, + uint8_t* C_u8, + int ldc, + trRequantizationParams_t& rParams, + bool accum = false, + int thread_id = 0, + int num_threads = 1); + +template +void SparseDenseInt8MMAvx512( + int N, + const std::unique_ptr>& bcsr, + const uint8_t* B, + int ldb, + int32_t* C_i32, + uint8_t* C_u8, + int ldc, + trRequantizationParams_t& rParams, + bool accum = false, + int thread_id = 0, + int num_threads = 1); + +template +void SparseDenseInt8MVAvx512( + const std::unique_ptr>& bcsr, + const uint8_t* B, + int ldb, + int32_t* C_i32, + uint8_t* C_u8, + trRequantizationParams_t& rParams, + bool accum = false, + int thread_id = 0, + int num_threads = 1); +#endif + +} // namespace internal + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FloatConversion.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FloatConversion.h new file mode 100644 index 0000000000000000000000000000000000000000..949e9ebefde3ad93ecdd934f7703a6be2b84ea79 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FloatConversion.h @@ -0,0 +1,331 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include + +#include "./Types.h" // @manual + +#ifndef __is_identifier +#define __is_identifier(x) 1 +#endif + +#define __has_keyword(__x) !(__is_identifier(__x)) + +// TODO: we're disabling native fp16 on Windows to workaround test failures +// due to "undefined symbol __gnu_h2f_ieee" error. We should follup on this +// later. +#if __has_keyword(__fp16) && !defined(_WIN32) +#define HAS_NATIVE_FP16_TYPE +using native_fp16_t = __fp16; +#elif __has_keyword(_Float16) && !defined(_WIN32) +#define HAS_NATIVE_FP16_TYPE +using native_fp16_t = _Float16; +#else +using native_fp16_t = void; +#endif + +namespace fbgemm { + +namespace detail { + +template +struct FloatFormat { + using value_type = T; + static constexpr int bits = sizeof(T) * CHAR_BIT; + static constexpr int exponent_bits = ExponentBits; + static constexpr int mantissa_bits = bits - exponent_bits - 1; + static constexpr int sign_bit_pos = bits - 1; + static constexpr int exponent_bias = (1 << (exponent_bits - 1)) - 1; + static constexpr int unbiased_exponent_min = -exponent_bias + 1; + static constexpr int unbiased_exponent_max = + HasInfinity ? exponent_bias : (exponent_bias + 1); + static constexpr T sign_bit = T{1} << sign_bit_pos; + static constexpr T exponent_mask = ((T{1} << exponent_bits) - 1) + << mantissa_bits; + static constexpr T mantissa_mask = (T{1} << mantissa_bits) - 1; + // signaling/quiet encoding is unspecified by IEEE754. This mirrors x86/ARM. + static constexpr T quiet_nan_bit = T{1} << (mantissa_bits - 1); + + static constexpr T nan = exponent_mask | mantissa_mask; + static constexpr T overflow_value = HasInfinity ? exponent_mask : nan; + static constexpr bool has_infinity = HasInfinity; + static constexpr bool has_nan_payload = HasInfinity; +}; + +using IEEE754Single = FloatFormat; +using IEEE754Half = FloatFormat; +// See https://arxiv.org/abs/1905.12322v3 +using BFloat16 = FloatFormat; +// See https://doi.org/10.48550/arXiv.2209.05433 +using FP8_E5M2 = FloatFormat; +// See https://doi.org/10.48550/arXiv.2209.05433 +using FP8_E4M3FN = FloatFormat< + /*T=*/uint8_t, + /*ExponentBits=*/4, + /*HasInfinity=*/false>; + +enum class RoundingMode { + ToNearestTiesToEven, + ToZero, +}; + +// Generic IEEE754 truncation algorithm. +template +[[gnu::always_inline]] inline typename Tgt::value_type ieee754_trunc( + typename Src::value_type value) { + static_assert(Src::exponent_bits >= Tgt::exponent_bits); + static_assert(Src::mantissa_bits > Tgt::mantissa_bits); + using ST = typename Src::value_type; + using TT = typename Tgt::value_type; + + ST src_exponent = value & Src::exponent_mask; + ST src_mantissa = value & Src::mantissa_mask; + // Fast-path: If there is no difference in exponent sizes (e.g. fp32 -> bf16) + // and we round toward zero, then we can just drop the least significant bits. + if constexpr ( + Src::exponent_bits == Tgt::exponent_bits && Src::has_infinity && + Tgt::has_infinity && RoundingMode == RoundingMode::ToZero) { + TT result = value >> (Src::bits - Tgt::bits); + // Turn signaling NaN into quiet NaN. This also avoids that the mantissa + // is completely zero after truncation (which would be misinterpreted as + // INF). + if (src_exponent == Src::exponent_mask && src_mantissa != 0) { + result |= Tgt::quiet_nan_bit; + } + return result; + } + + ST tgt_sign = + (value & Src::sign_bit) >> (Src::sign_bit_pos - Tgt::sign_bit_pos); + constexpr bool denormal_becomes_zero = + Tgt::unbiased_exponent_min - Src::unbiased_exponent_min > + Src::mantissa_bits - Tgt::mantissa_bits; + if constexpr (denormal_becomes_zero) { + // Fast-path for zero exponentbits: This means the number was zero or a + // denormal number that will turn into zero in the Tgt format. + if (src_exponent == 0) { + return tgt_sign; // tgt_exponent == 0, tgt_mantissa == 0 + } + } + + int unbiased_exponent = + (src_exponent >> Src::mantissa_bits) - Src::exponent_bias; + if (unbiased_exponent < Tgt::unbiased_exponent_min) { + int shift = Tgt::unbiased_exponent_min - unbiased_exponent; + if (shift <= Tgt::mantissa_bits + 1) { + // Result is denormal. + ST src_mantissa_one = src_mantissa; + // Add explicit one if the source was not denormal. + if (denormal_becomes_zero || src_exponent != 0) { + src_mantissa_one |= TT{1} << Src::mantissa_bits; + } else { + shift--; + } + TT tgt_mantissa = + src_mantissa_one >> (Src::mantissa_bits - Tgt::mantissa_bits + shift); + + if constexpr (RoundingMode == RoundingMode::ToNearestTiesToEven) { + int half_pos = Src::mantissa_bits - Tgt::mantissa_bits + shift - 1; + ST half = 1 << half_pos; + ST remainder = src_mantissa_one & ((half << 1) - 1); + if (remainder > half || + (remainder == half && (tgt_mantissa & 1) != 0)) { + tgt_mantissa += 1; + } + } else { + static_assert(RoundingMode == RoundingMode::ToZero); + } + return tgt_sign | tgt_mantissa; // tgt_exponent == 0 + } else { + // Result is +/- zero + return tgt_sign; // tgt_exponent == 0, tgt_mantissa == 0 + } + } + + if (unbiased_exponent > Tgt::unbiased_exponent_max) { + if (unbiased_exponent == Src::exponent_bias + 1 && src_mantissa != 0) { + TT tgt_mantissa; + if constexpr (Tgt::has_nan_payload) { + // NaN; not a number + tgt_mantissa = + src_mantissa >> (Src::mantissa_bits - Tgt::mantissa_bits); + tgt_mantissa |= Tgt::quiet_nan_bit; + } else { + tgt_mantissa = Tgt::mantissa_mask; + } + return tgt_sign | Tgt::exponent_mask | tgt_mantissa; + } else { + if (RoundingMode == RoundingMode::ToZero && + (!Src::has_infinity || src_exponent != Src::exponent_mask)) { + // Return largest finite number. + return tgt_sign | (Tgt::exponent_mask - Tgt::has_infinity) | + Tgt::mantissa_mask; + } + // Infinity or NaN for formats without infinity. + return tgt_sign | Tgt::overflow_value; + } + } + + // Normal number. + TT tgt_mantissa = src_mantissa >> (Src::mantissa_bits - Tgt::mantissa_bits); + TT tgt_exponent = (unbiased_exponent + Tgt::exponent_bias) + << Tgt::mantissa_bits; + if constexpr (RoundingMode == RoundingMode::ToNearestTiesToEven) { + ST half = 1 << (Src::mantissa_bits - Tgt::mantissa_bits - 1); + ST remainder = src_mantissa & ((half << 1) - 1); + if (remainder > half || (remainder == half && (tgt_mantissa & 1) != 0)) { + if (tgt_mantissa < Tgt::mantissa_mask) { + tgt_mantissa += 1; + } else { + // Mantissa overflowed, increment exponent. + + // Normally we can just add to the exponent and will naturally end up + // on infinity on overflow. But we need special treatments for formats + // without infinity. + if (Tgt::has_infinity || tgt_exponent != Tgt::exponent_mask) { + tgt_mantissa = 0; + tgt_exponent += TT{1} << Tgt::mantissa_bits; + } else { + // Return NaN. + tgt_mantissa = Tgt::mantissa_mask; + } + } + } + } else { + static_assert(RoundingMode == RoundingMode::ToZero); + } + return tgt_sign | tgt_exponent | tgt_mantissa; +} + +} // namespace detail + +inline float16 cpu_float2half_rn(float f) { + uint32_t f_u32 = 0; + std::memcpy(&f_u32, &f, sizeof(f_u32)); + return detail::ieee754_trunc< + /*Src=*/detail::IEEE754Single, + /*Tgt=*/detail::IEEE754Half, + detail::RoundingMode::ToNearestTiesToEven>(f_u32); +} + +inline float16 cpu_float2half_rz(float f) { + uint32_t f_u32 = 0; + std::memcpy(&f_u32, &f, sizeof(f_u32)); + return detail::ieee754_trunc< + /*Src=*/detail::IEEE754Single, + /*Tgt=*/detail::IEEE754Half, + detail::RoundingMode::ToZero>(f_u32); +} + +// Converts a 16-bit unsigned integer representation of a IEEE754 half-precision +// float into an IEEE754 32-bit single-precision float +inline float cpu_half2float_ref(const float16 h) { + constexpr uint32_t f16_num_exponent_bits = 5; + constexpr uint32_t f16_num_mantissa_bits = 10; + constexpr uint32_t f16_num_non_sign_bits = + f16_num_exponent_bits + f16_num_mantissa_bits; + constexpr uint32_t f16_exponent_bias = 15; + constexpr uint32_t f16_exponent_mask = 0b1'1111; + constexpr uint32_t f16_mantissa_mask = 0b11'1111'1111; + + constexpr uint32_t f32_num_exponent_bits = 8; + constexpr uint32_t f32_num_mantissa_bits = 23; + constexpr uint32_t f32_num_non_sign_bits = + f32_num_exponent_bits + f32_num_mantissa_bits; + constexpr uint32_t f32_exponent_bias = 127; + constexpr uint32_t f32_exponent_mask = 0b1111'1111; + constexpr uint32_t f32_mantissa_mask = 0x7F'FF'FF; + constexpr uint32_t f32_most_significant_bit = 1u << 22; + + // Get sign and exponent alone by themselves + uint32_t sign_bit = (h >> f16_num_non_sign_bits) & 1; + uint32_t exponent = (h >> f16_num_mantissa_bits) & f16_exponent_mask; + // Shift mantissa so that it fills the most significant bits of a float32 + uint32_t mantissa = (h & f16_mantissa_mask) + << (f32_num_mantissa_bits - f16_num_mantissa_bits); + + if (exponent == f16_exponent_mask) { // NaN or Inf + if (mantissa) { + mantissa = f32_mantissa_mask; + sign_bit = 0; + } + exponent = f32_exponent_mask; + } else if (!exponent) { // Denorm or Zero + if (mantissa) { + uint32_t msb = 0; + exponent = f32_exponent_bias - f16_exponent_bias + 1; + do { + msb = mantissa & f32_most_significant_bit; + mantissa <<= 1; // normalize + --exponent; + } while (!msb); + mantissa &= f32_mantissa_mask; // 1.mantissa is implicit + } + } else { + exponent += f32_exponent_bias - f16_exponent_bias; + } + + const uint32_t i = (sign_bit << f32_num_non_sign_bits) | + (exponent << f32_num_mantissa_bits) | mantissa; + + float ret = NAN; + std::memcpy(&ret, &i, sizeof(float)); + return ret; +} + +// Same as the previous function, but use the built-in fp16 to fp32 +// conversion provided by the compiler +inline float cpu_half2float(const float16 h) { +#if defined(HAS_NATIVE_FP16_TYPE) && !defined(MISSING_GNU_F2H_IEEE) + __fp16 h_fp16 = NAN; + std::memcpy(&h_fp16, &h, sizeof(__fp16)); + return h_fp16; +#else + return cpu_half2float_ref(h); +#endif +} + +inline float16 cpu_float2half(const float f) { +#if defined(HAS_NATIVE_FP16_TYPE) && !defined(MISSING_GNU_F2H_IEEE) + __fp16 h = f; + float16 res = 0; + std::memcpy(&res, &h, sizeof(__fp16)); + return res; +#else + return cpu_float2half_rn(f); +#endif +} + +inline float cpu_bf162float(bfloat16 src) { + float ret = NAN; + uint32_t val_fp32 = + static_cast(reinterpret_cast(&src)[0]) << 16; + std::memcpy(&ret, &val_fp32, sizeof(float)); + return ret; +} + +inline bfloat16 cpu_float2bfloat16(float src) { + uint32_t temp = 0; + std::memcpy(&temp, &src, sizeof(uint32_t)); + return (temp + (1u << 15)) >> 16; +} + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/OutputProcessing-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/OutputProcessing-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..4457d5ee0ba204e875009e9632bdda2480fc0f4d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/OutputProcessing-inl.h @@ -0,0 +1,320 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#include + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +template +template +inline int memCopy::f( + outT* out, + inT* inp, + const block_type_t& block, + int ld_out, + int ld_in) const { + static_assert( + std::is_same_v, + "input and output data type must be of same type"); + // only copy if destination is not the same as source + if (out + block.row_start * ld_out + block.col_start != inp) { + for (int i = block.row_start; i < block.row_start + block.row_size; ++i) { + memcpy( + out + block.col_start + i * ld_out, + inp + (i - block.row_start) * ld_in, + block.col_size * sizeof(inT)); + } + } + return nextop_.template f(out, out, block, ld_out, ld_out); +} + +template +template +inline int DoSpmdmOnInpBuffer::f( + outT* out, + inT* inp, + const block_type_t& block, + int ld_out, + int ld_in) const { + assert(B_csc_.NumOfCols() % groups_ == 0); + int n_per_group = B_csc_.NumOfCols() / groups_; + int g = block.col_start / n_per_group; + B_csc_.SpMDM(block, A_ + g * B_csc_.NumOfRows(), lda_, true, inp, ld_in); + return nextop_.template f(out, inp, block, ld_out, ld_in); +} + +template +template +inline int DoSConvOnInpBuffer::f( + outT* out, + inT* inp, + const block_type_t& block, + int ld_out, + int ld_in) const { + B_csc_.SparseConv(conv_p_, block, A_, A_zero_point_, true, inp, ld_in); + return nextop_.template f(out, inp, block, ld_out, ld_in); +} + +template < + bool FUSE_RELU, + QuantizationGranularity Q_GRAN, + typename BIAS_TYPE, + typename outT, + typename inT, + typename nextOPType> +template +inline int +ReQuantizeOutput::f( + outT* out, + const inT* inp, + const block_type_t& block, + int ld_out, + int ld_in) const { + static_assert( + std::is_same_v, "input data type must be of int32_t type"); + int ncol_per_group = ncols_ / groups_; + assert( + block.col_size <= ncol_per_group && + "ReQuantizeOutput should be called at most 1 group at a time."); + if constexpr ( + instSet == inst_set_t::anyarch || !std::is_same_v) { + for (int i = block.row_start; i < block.row_start + block.row_size; ++i) { + for (int j = block.col_start; j < block.col_start + block.col_size; ++j) { + inT raw = inp[(i - block.row_start) * ld_in + (j - block.col_start)]; + if (Aq_zero_point_) { + raw -= Aq_zero_point_ * q_col_offsets_[j]; + } + int Bq_zero_point_idx = 0; + if constexpr (Q_GRAN == QuantizationGranularity::TENSOR) { + Bq_zero_point_idx = 0; + } else if constexpr (Q_GRAN == QuantizationGranularity::GROUP) { + int g = block.col_start / ncol_per_group; + Bq_zero_point_idx = g; + } else { + static_assert(Q_GRAN == QuantizationGranularity::OUT_CHANNEL); + Bq_zero_point_idx = j; + } + if (q_row_offsets_) { + raw -= q_row_offsets_[i - block.row_start] * + Bq_zero_point_[Bq_zero_point_idx]; + } + float raw_f = NAN; + if (bias_) { + if constexpr (std::is_same_v) { + raw_f = raw; + raw_f += bias_[j] / act_times_w_scale_[Bq_zero_point_idx]; + } else { + raw += bias_[j]; + raw_f = raw; + } + } else { + raw_f = raw; + } + + float ab = raw_f * C_multiplier_[Bq_zero_point_idx]; + long rounded = std::lrintf(ab) + C_zero_point_; + + out[i * ld_out + j] = std::max( + FUSE_RELU ? static_cast(C_zero_point_) : 0l, + std::min(255l, rounded)); + } + } + +#if !defined(__aarch64__) + + } else if constexpr ( + instSet == inst_set_t::avx2 || instSet == inst_set_t::avx512) { + bool b_symmetric = + (Q_GRAN == QuantizationGranularity::TENSOR && Bq_zero_point_[0] == 0) || + q_row_offsets_ == nullptr; + + requantizationParams_t r = { + Aq_zero_point_, + Bq_zero_point_, + C_zero_point_, + C_multiplier_, + q_row_offsets_, + q_col_offsets_, + bias_, + ncols_, + groups_, + act_times_w_scale_}; + + if (Aq_zero_point_ == 0) { + if (b_symmetric) { + if (bias_ == nullptr) { + requantizeOutputProcessingAvx2( + out, inp, block, ld_out, ld_in, r); + } else { + requantizeOutputProcessingAvx2( + out, inp, block, ld_out, ld_in, r); + } + } else { + if (bias_ == nullptr) { + requantizeOutputProcessingAvx2( + out, inp, block, ld_out, ld_in, r); + } else { + requantizeOutputProcessingAvx2( + out, inp, block, ld_out, ld_in, r); + } + } + } else { + if (b_symmetric) { + if (bias_ == nullptr) { + requantizeOutputProcessingAvx2( + out, inp, block, ld_out, ld_in, r); + } else { + requantizeOutputProcessingAvx2( + out, inp, block, ld_out, ld_in, r); + } + } else { + if (bias_ == nullptr) { + requantizeOutputProcessingAvx2< + false, + false, + Q_GRAN, + false, + FUSE_RELU>(out, inp, block, ld_out, ld_in, r); + } else { + requantizeOutputProcessingAvx2( + out, inp, block, ld_out, ld_in, r); + } + } + } + +#endif // __aarch64__ + + } else { + assert(0 && "Not supported yet"); + } + return nextop_.template f(out, out, block, ld_out, ld_out); +} + +template < + bool FUSE_RELU, + QuantizationGranularity Q_GRAN, + typename outT, + typename inT, + typename nextOPType> +template +inline int ReQuantizeForFloat::f( + outT* out, + inT* inp, + const block_type_t& block, + int ld_out, + int ld_in) const { + static_assert( + std::is_same_v, "input data type is of not expected type"); + static_assert( + std::is_same_v, "output data type is of not expected type"); + int ncol_per_group = ncols_ / groups_; + assert( + block.col_size <= ncol_per_group && + "ReQuantizeOutput should be called at most 1 group at a time."); + if constexpr ( + instSet == inst_set_t::anyarch || !std::is_same_v) { + for (int i = block.row_start; i < block.row_start + block.row_size; ++i) { + for (int j = block.col_start; j < block.col_start + block.col_size; ++j) { + inT raw = inp[(i - block.row_start) * ld_in + j - block.col_start]; + if (Aq_zero_point_) { + raw -= Aq_zero_point_ * q_col_offsets_[j]; + } + int Bq_zero_point_idx = 0; + if constexpr (Q_GRAN == QuantizationGranularity::TENSOR) { + Bq_zero_point_idx = 0; + } else if constexpr (Q_GRAN == QuantizationGranularity::GROUP) { + int g = block.col_start / ncol_per_group; + Bq_zero_point_idx = g; + } else { + static_assert(Q_GRAN == QuantizationGranularity::OUT_CHANNEL); + Bq_zero_point_idx = j; + } + if (q_row_offsets_) { + raw -= q_row_offsets_[i - block.row_start] * + Bq_zero_point_[Bq_zero_point_idx]; + } + float res = raw * Aq_scale_ * Bq_scale_[Bq_zero_point_idx]; + if (bias_) { + res += bias_[j]; + } + out[i * ld_out + j] = res; + if constexpr (FUSE_RELU) { + out[i * ld_out + j] = std::max(0.0f, out[i * ld_out + j]); + } + } + } + +#if !defined(__aarch64__) + } else if constexpr ( + instSet == inst_set_t::avx2 || instSet == inst_set_t::avx512) { + bool b_symmetric = + (Q_GRAN == QuantizationGranularity::TENSOR && Bq_zero_point_[0] == 0) || + q_row_offsets_ == nullptr; + + requantizationForFloatParams_t r = { + Aq_zero_point_, + Bq_zero_point_, + Aq_scale_, + Bq_scale_, + q_row_offsets_, + q_col_offsets_, + bias_, + ncols_, + groups_}; + + if (Aq_zero_point_ == 0) { + if (b_symmetric) { + if (bias_ == nullptr) { + requantizeForFloatAvx2( + out, inp, block, ld_out, ld_in, r); + } else { + requantizeForFloatAvx2( + out, inp, block, ld_out, ld_in, r); + } + } else { + if (bias_ == nullptr) { + requantizeForFloatAvx2( + out, inp, block, ld_out, ld_in, r); + } else { + requantizeForFloatAvx2( + out, inp, block, ld_out, ld_in, r); + } + } + } else { + if (b_symmetric) { + if (bias_ == nullptr) { + requantizeForFloatAvx2( + out, inp, block, ld_out, ld_in, r); + } else { + requantizeForFloatAvx2( + out, inp, block, ld_out, ld_in, r); + } + } else { + if (bias_ == nullptr) { + requantizeForFloatAvx2( + out, inp, block, ld_out, ld_in, r); + } else { + requantizeForFloatAvx2( + out, inp, block, ld_out, ld_in, r); + } + } + } + +#endif // __aarch64__ + + } else { + assert(0 && "Not supported yet"); + } + + return nextop_.template f(out, out, block, ld_out, ld_out); +} + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/PackingTraits-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/PackingTraits-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..3d9f26ab2b30b805f9399a61bc5063ee58764d37 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/PackingTraits-inl.h @@ -0,0 +1,541 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +/* + * This file configures the important cache blocking parameters and registers + * blocking parameters for the matrix multiplication loops inside FBGEMM. + * + * ROW_INTERLEAVE: the number of interleaved rows to use vpmaddubsw instructions + * for packing B matrix. For 32-bit accumulation, ROW_INTERLEAVE = 4; For 16-bit + * accumulation, ROW_INTERLEAVE = 2. + * + * VLEN: the vector length of one SIMD register. For avx2, VLEN = 256; For + * avx512, VLEN = 512. + * + * NR: the register blocking parameters for N dimension. The total registers + * used in N dimension for C accumulations are NR * ROW_INTERLEAVE * 8 (int8) / + * VLEN. + * + * MR: the register blocking parameters for M dimension. The total number of + * registers used in M dimension for C accumulations is MR. This indicates the + * number of vpbroadcastw instructions for A. + * + * (MR) * (NR * ROW_INTERLEAVE * 8 (int8) / VLEN): the number of registers used + * for C accumulations. This number should be less than the maximum registers we + * can use for C accumulations (A max of 12 out of 16 ymm registers for avx2; a + * max of 28 out of 32 zmm registers for avx512 ). The remaining are used for A + * matrix loading, B matrix loading and as temp registers. C accumulation + * registers should be as large as possible to increase the register + * utilization. + * + * MCB: the cache blocking parameters for M dimension. MCB needs to be a + * multiple of MR. + * + * NCB: the cache blocking parameters for N dimension. NCB needs to be a + * multiple of NR. + * + * KCB: the cache blocking parameters for K dimension. KCB needs to be a + * multiple of ROW_INTERLEAVE. + */ + +/** + * @brief Packing parameter specialization for accumulation into 32-bit + * integers. + * + * This is picked when T is of int8 type (signed or unsigned) and instruction + * set is avx2 + */ +template +struct PackingTraits< + T, + std::int32_t, + inst_set_t::avx2, + std::enable_if_t::value>> { + static constexpr int MR{12}; ///< Register block for M dimension. + static constexpr int NR_MIN{8}; ///< Minimum register block for N dimension. + ///< 8 because 8*ROW_INTERLEAVE int8 elements + ///< completely fill a 256-bit wide vector. + static constexpr int NR{8}; ///< Register block for N dimension. + ///< NR = VLEN/8/ROW_INTERLEAVE = 256 / 8 / 4 = 8. + ///< Total registers used for N dimension: NCB/NR. + ///< Here we use 12 x 1 ymm register blocking for + ///< the registers used for accumulation C. + + static constexpr int ROW_INTERLEAVE{ + 4}; ///< 4 rows are interleaved to use vpmaddubsw instruction for packing + ///< B matrix. + + static constexpr int MCB{ + 120}; ///< Cache block for M dimension (multiple of MR). + static constexpr int NCB{ + 8}; ///< Cache block for N dimension (multiple of NR). + static constexpr int KCB{512}; ///< Cache block for K dimension. + + static std::tuple getCacheBlockParams() { + return std::tuple(int(MCB), int(KCB), int(MR)); + } + static std::tuple getKernelParams() { + return std::tuple( + int(MCB), int(NCB), int(NR_MIN), int(NR)); + } + static std::tuple getMatrixPackAParams() { + return std::tuple(int(MCB), int(KCB), int(ROW_INTERLEAVE)); + } + static std::tuple getMatrixPackBParams() { + return std::tuple(int(KCB), int(NCB), int(ROW_INTERLEAVE)); + } +}; + +/** + * @brief Packing parameter specialization for accumulation into 16-bit + * integers. + * + * This is picked when T is of int8 type (signed or unsigned) and instruction + * set is avx2. + */ +template +struct PackingTraits< + T, + std::int16_t, + inst_set_t::avx2, + std::enable_if_t::value>> { + static constexpr int MR{3}; ///< Register block for M dimension. + static constexpr int NR_MIN{ + 16}; ///< Minimum register block for N dimension. + ///< 16 because 16*ROW_INTERLEAVE int8 elements + ///< completely fill a 256-bit wide vector. + + static constexpr int NR{ + 16}; ///< Register block for N dimension; + ///< NR = VLEN/8/ROW_INTERLEAVE = 256 / 8 / 2 = 16. + ///< Total registers used for N dimension: NCB/NR. + ///< Here we use 3 x 4 ymm register blocking for the + ///< registers used for accumulation C. + + static constexpr int ROW_INTERLEAVE{ + 2}; ///< 2 rows are interleaved to use vpmaddubsw instruction for packing + ///< B matrix. + + static constexpr int MCB{ + 60}; ///< Cache block for M dimension (multiple of MR). + static constexpr int NCB{ + 64}; ///< Cache block for N dimension (multiple of NR). + static constexpr int KCB{256}; ///< Cache block for K dimension. + + static std::tuple getCacheBlockParams() { + return std::tuple(int(MCB), int(KCB), int(MR)); + } + static std::tuple getKernelParams() { + return std::tuple( + int(MCB), int(NCB), int(NR_MIN), int(NR)); + } + static std::tuple getMatrixPackAParams() { + return std::tuple(int(MCB), int(KCB), int(ROW_INTERLEAVE)); + } + static std::tuple getMatrixPackBParams() { + return std::tuple(int(KCB), int(NCB), int(ROW_INTERLEAVE)); + } +}; + +/** + * @brief Packing parameter specialization for float input and float + * accumulation. + * + * This is picked when template paramtere T is of float type and instruction + * set is avx2. + */ +template <> +struct PackingTraits { + static constexpr int MR{3}; ///< Register block for M dimension + static constexpr int NR{32}; ///< Register block for N dimension + + static constexpr int ROW_INTERLEAVE{1}; ///< No Row interleave. + + static constexpr int MCB{ + 24}; ///< Cache block for M dimension (multiple of MR) + static constexpr int NCB{ + 64}; ///< Cache block for N dimension (multiple of NR) + static constexpr int KCB{256}; ///< Cache block for K dimension + + static std::tuple getCacheBlockParams() { + return std::tuple(int(MCB), int(KCB), int(MR)); + } + static std::tuple getMatrixPackAParams() { + return std::tuple(int(MCB), int(KCB), int(ROW_INTERLEAVE)); + } + static std::tuple getMatrixPackBParams() { + return std::tuple(int(KCB), int(NCB), int(ROW_INTERLEAVE)); + } +}; + +/** + * @brief Packing parameter specialization for fp16 input and float + * accumulation. + * + * This is picked when template parameter T is of float16 type and instruction + * set is avx2 + */ +template <> +struct PackingTraits { + static constexpr int BCOL{8}; + static constexpr int ROW_INTERLEAVE{1}; +}; + +/** + * @brief Packing parameter specialization for accumulation into 32-bit + * integers. + * + * This is picked when T is of int8 type (signed or unsigned) and instruction + * set is avx512. + */ +template +struct PackingTraits< + T, + std::int32_t, + inst_set_t::avx512, + std::enable_if_t::value>> { + static constexpr int MR{14}; ///< Register block for M dimension. + static constexpr int NR_MIN{ + 16}; ///< Minimum register block for N dimension. + ///< 16 because 16*ROW_INTERLEAVE int8 elements + ///< completely fill a 512-bit wide vector. + static constexpr int NR{ + 32}; ///< Register block for N dimension. + ///< Must be a multiple of 16 because 16*ROW_INTERLEAVE int8 elements + ///< completely fill a 512-bit wide vector. Total registers used for + ///< N dimension: NR*ROW_INTERLEAVE*8/VLEN. We use MR x + ///< NR*ROW_INTERLEAVE*8/VLEN zmm registers + ///< for C accumulations. + + static constexpr int ROW_INTERLEAVE{ + 4}; ///< 4 rows are interleaved to use vpmaddubsw instruction for packing + ///< B matrix. + + static constexpr int MCB{ + 56}; ///< Cache block for M dimension (multiple of MR). + static constexpr int NCB{ + 32}; ///< Cache block for N dimension (multiple of NR). + static constexpr int KCB{256}; ///< Cache block for K dimension. + + static std::tuple getCacheBlockParams() { + return std::tuple(int(MCB), int(KCB), int(MR)); + } + static std::tuple getKernelParams() { + return std::tuple( + int(MCB), int(NCB), int(NR_MIN), int(NR)); + } + static std::tuple getMatrixPackAParams() { + return std::tuple(int(MCB), int(KCB), int(ROW_INTERLEAVE)); + } + static std::tuple getMatrixPackBParams() { + return std::tuple(int(KCB), int(NCB), int(ROW_INTERLEAVE)); + } +}; + +/** + * @brief Packing parameter specialization for accumulation into 32-bit + * integers. + * + * This is picked when T is of int8 type (signed or unsigned) and instruction + * set is avx512_ymm. + */ +template +struct PackingTraits< + T, + std::int32_t, + inst_set_t::avx512_ymm, + std::enable_if_t::value>> { + static constexpr int MR{7}; ///< Register block for M dimension. + static constexpr int NR_MIN{16}; ///< Minimum register block for N dimension. + ///< 8 because 8*ROW_INTERLEAVE int8 elements + ///< completely fill a 256-bit wide vector. + static constexpr int NR{ + 32}; ///< Register block for N dimension. + ///< NR = VLEN/8/ROW_INTERLEAVE = 256 / 8 / 4 = 8. + ///< Total registers used for N dimension: NCB/NR. + ///< Here we use 12 x 1 ymm register blocking for + ///< the registers used for accumulation C. + + static constexpr int ROW_INTERLEAVE{ + 4}; ///< 4 rows are interleaved to use vpmaddubsw instruction for packing + ///< B matrix. + + static constexpr int MCB{ + 56}; ///< Cache block for M dimension (multiple of MR). + static constexpr int NCB{ + 32}; ///< Cache block for N dimension (multiple of NR). + static constexpr int KCB{256}; ///< Cache block for K dimension. + + static std::tuple getCacheBlockParams() { + return std::tuple(int(MCB), int(KCB), int(MR)); + } + static std::tuple getKernelParams() { + return std::tuple( + int(MCB), int(NCB), int(NR_MIN), int(NR)); + } + static std::tuple getMatrixPackAParams() { + return std::tuple(int(MCB), int(KCB), int(ROW_INTERLEAVE)); + } + static std::tuple getMatrixPackBParams() { + return std::tuple(int(KCB), int(NCB), int(ROW_INTERLEAVE)); + } +}; + +/** + * @brief Packing parameter specialization for accumulation into 16-bit + * integers. + * + * This is picked when T is of int8 type (signed or unsigned) and instruction + * set is avx512. + */ +template +struct PackingTraits< + T, + std::int16_t, + inst_set_t::avx512, + std::enable_if_t::value>> { + static constexpr int MR{6}; ///< Register block for M dimension + static constexpr int NR_MIN{ + 32}; ///< Minimum register block for N dimension; + ///< 32 because 32*ROW_INTERLEAVE int8 elements + ///< completely fill a 512-bit wide vector. + static constexpr int NR{ + 128}; ///< Register block for N dimension; + ///< Must be a multiple of 32 because 32*ROW_INTERLEAVE int8 + ///< elements completely fill a 512-bit wide vector. Total registers + ///< used for N dimension: NR*ROW_INTERLEAVE*8/VLEN. We use MR x + ///< NR*ROW_INTERLEAVE*8/VLEN zmm registers + ///< for C accumulations. + + static constexpr int ROW_INTERLEAVE{ + 2}; ///< 2 rows are interleaved to use vpmaddubsw instruction for packing + ///< B matrix. + + static constexpr int MCB{ + 60}; ///< Cache block for M dimension (multiple of MR). + static constexpr int NCB{ + 128}; ///< Cache block for N dimension (multiple of NR). + static constexpr int KCB{256}; ///< Cache block for K dimension. + + static std::tuple getCacheBlockParams() { + return std::tuple(int(MCB), int(KCB), int(MR)); + } + static std::tuple getKernelParams() { + return std::tuple( + int(MCB), int(NCB), int(NR_MIN), int(NR)); + } + static std::tuple getMatrixPackAParams() { + return std::tuple(int(MCB), int(KCB), int(ROW_INTERLEAVE)); + } + static std::tuple getMatrixPackBParams() { + return std::tuple(int(KCB), int(NCB), int(ROW_INTERLEAVE)); + } +}; + +/** + * @brief Packing parameter specialization for accumulation into 16-bit + * integers. + * + * This is picked when T is of int8 type (signed or unsigned) and instruction + * set is avx512_ymm. + */ +template +struct PackingTraits< + T, + std::int16_t, + inst_set_t::avx512_ymm, + std::enable_if_t::value>> { + static constexpr int MR{6}; ///< Register block for M dimension. + static constexpr int NR_MIN{ + 16}; ///< Minimum register block for N dimension. + ///< 16 because 16*ROW_INTERLEAVE int8 elements + ///< completely fill a 256-bit wide vector. + + static constexpr int NR{ + 16}; ///< Register block for N dimension; + ///< NR = VLEN/8/ROW_INTERLEAVE = 256 / 8 / 2 = 16. + ///< Total registers used for N dimension: NCB/NR. + ///< Here we use 3 x 4 ymm register blocking for the + ///< registers used for accumulation C. + + static constexpr int ROW_INTERLEAVE{ + 2}; ///< 2 rows are interleaved to use vpmaddubsw instruction for packing + ///< B matrix. + + static constexpr int MCB{ + 60}; ///< Cache block for M dimension (multiple of MR). + static constexpr int NCB{ + 64}; ///< Cache block for N dimension (multiple of NR). + static constexpr int KCB{256}; ///< Cache block for K dimension. + + static std::tuple getCacheBlockParams() { + return std::tuple(int(MCB), int(KCB), int(MR)); + } + static std::tuple getKernelParams() { + return std::tuple( + int(MCB), int(NCB), int(NR_MIN), int(NR)); + } + static std::tuple getMatrixPackAParams() { + return std::tuple(int(MCB), int(KCB), int(ROW_INTERLEAVE)); + } + static std::tuple getMatrixPackBParams() { + return std::tuple(int(KCB), int(NCB), int(ROW_INTERLEAVE)); + } +}; + +/** + * @brief Helper struct to type specialize for int16_t and int32_t together. + */ +template +struct is_16or32bit { + static constexpr bool value = + std::is_same_v || std::is_same_v; +}; + +/** + * @brief Packing parameter specialization for accumulation into 32-bit/16-bit + * integers. + * + * Since there is no int16_t accumulation for AVX512 VNNI, we redirect int16_t + * to int32_t accumulation and use the same blocking parameters as int32_t. + * + * This is picked when T is of int8 type (signed or unsigned) and instruction + * set is avx512_vnni. + */ +template +struct PackingTraits< + T, + accT, + inst_set_t::avx512_vnni, + std::enable_if_t::value && is_16or32bit::value>> { + static constexpr int MR{8}; ///< Register block for M dimension. + static constexpr int NR_MIN{ + 16}; ///< Minimum register block for N dimension. + ///< 16 because 16*ROW_INTERLEAVE int8 elements + ///< completely fill a 512-bit wide vector. + static constexpr int NR{ + 48}; ///< Register block for N dimension. + ///< Must be a multiple of 16 because 16*ROW_INTERLEAVE int8 elements + ///< completely fill a 512-bit wide vector. Total registers used for + ///< N dimension: NR*ROW_INTERLEAVE*8/VLEN. We use MR x + ///< NR*ROW_INTERLEAVE*8/VLEN zmm registers + ///< for C accumulations. + + static constexpr int ROW_INTERLEAVE{ + 4}; ///< 4 rows are interleaved to use vpmaddubsw instruction for packing + ///< B matrix. + + static constexpr int MCB{ + 384}; ///< Cache block for M dimension (multiple of MR). + static constexpr int NCB{ + 48}; ///< Cache block for N dimension (multiple of NR). + static constexpr int KCB{512}; ///< Cache block for K dimension. + + static std::tuple getCacheBlockParams() { + return std::tuple(int(MCB), int(KCB), int(MR)); + } + static std::tuple getKernelParams() { + return std::tuple( + int(MCB), int(NCB), int(NR_MIN), int(NR)); + } + static std::tuple getMatrixPackAParams() { + return std::tuple(int(MCB), int(KCB), int(ROW_INTERLEAVE)); + } + static std::tuple getMatrixPackBParams() { + return std::tuple(int(KCB), int(NCB), int(ROW_INTERLEAVE)); + } +}; + +/** + * @brief Packing parameter specialization for accumulation into 32-bit/16-bit + * integers. + * + * Since there is no int16_t accumulation for AVX512 VNNI, we redirect int16_t + * to int32_t accumulation and use the same blocking parameters as int32_t. + * + * This is picked when T is of int8 type (signed or unsigned) and instruction + * set is avx512_vnni_ymm. + */ +template +struct PackingTraits< + T, + accT, + inst_set_t::avx512_vnni_ymm, + std::enable_if_t::value && is_16or32bit::value>> { + static constexpr int MR{4}; ///< Register block for M dimension. + static constexpr int NR_MIN{ + 16}; ///< Minimum register block for N dimension. + ///< 16 because 16*ROW_INTERLEAVE int8 elements + ///< completely fill a 512-bit wide vector. + static constexpr int NR{ + 48}; ///< Register block for N dimension. + ///< Must be a multiple of 16 because 16*ROW_INTERLEAVE int8 elements + ///< completely fill a 512-bit wide vector. Total registers used for + ///< N dimension: NR*ROW_INTERLEAVE*8/VLEN. We use MR x + ///< NR*ROW_INTERLEAVE*8/VLEN zmm registers + ///< for C accumulations. + + static constexpr int ROW_INTERLEAVE{ + 4}; ///< 4 rows are interleaved to use vpmaddubsw instruction for packing + ///< B matrix. + + static constexpr int MCB{ + 384}; ///< Cache block for M dimension (multiple of MR). + static constexpr int NCB{ + 48}; ///< Cache block for N dimension (multiple of NR). + static constexpr int KCB{512}; ///< Cache block for K dimension. + + static std::tuple getCacheBlockParams() { + return std::tuple(int(MCB), int(KCB), int(MR)); + } + static std::tuple getKernelParams() { + return std::tuple( + int(MCB), int(NCB), int(NR_MIN), int(NR)); + } + static std::tuple getMatrixPackAParams() { + return std::tuple(int(MCB), int(KCB), int(ROW_INTERLEAVE)); + } + static std::tuple getMatrixPackBParams() { + return std::tuple(int(KCB), int(NCB), int(ROW_INTERLEAVE)); + } +}; + +/** + * @brief Packing parameter specialization for I64 GEMM + * integers. + * + * This is picked when T is of int64 type and instruction + * set is avx512. + */ +template <> +struct PackingTraits { + static constexpr int MR{2}; ///< Register block for M dimension. + static constexpr int NR_MIN{8}; ///< Minimum register block for N dimension. + ///< 8 because 8 int64 elements + ///< completely fill a 512-bit wide vector. + static constexpr int NR{ + 32}; ///< Register block for N dimension. + ///< Must be a multiple of 16 because 16*ROW_INTERLEAVE int8 elements + ///< completely fill a 512-bit wide vector. Total registers used for + ///< N dimension: NR*8/VLEN. We use MR x + ///< NR*8/VLEN zmm registers + ///< for C accumulations. + + static constexpr int MCB{ + 16}; ///< Cache block for M dimension (multiple of MR). + static constexpr int NCB{ + 64}; ///< Cache block for N dimension (multiple of NR). + static constexpr int KCB{8}; ///< Cache block for K dimension. +}; + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..90e95beb1ed4d8b32ff0ebe84ac37d6686ca1b60 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtils.h @@ -0,0 +1,397 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include "./FbgemmBuild.h" // @manual +#include "./QuantUtilsAvx2.h" // @manual +#include "./QuantUtilsAvx512.h" // @manual +#include "./QuantUtilsNeon.h" // @manual +#include "./Types.h" // @manual +#include "./Utils.h" // @manual + +#include +#include +#include +#include +#include + +/// @defgroup fbgemm-quant-utils-generic Quantization Utilities (Generic) +/// + +namespace fbgemm { + +FBGEMM_API TensorQuantizationParams ChooseQuantizationParams( + float min, + float max, + std::int32_t qmin, + std::int32_t qmax, + bool preserve_sparsity = false, + bool force_scale_power_of_two = false); + +FBGEMM_API void ChooseRequantizationMultiplier( + float real_multiplier, + std::int32_t* quantized_multiplier, + int* right_shift, + int requantization_multiplier_precision = 32); + +//////////////////////////////////////////////////////////////////////////////// +// Utility functions + +// Clamp src in T1 to the desired precision and convert it to T2 +// TODO: T26263653 fix signed-integer-overflow undefined behavior +template +NO_SANITIZE("signed-integer-overflow") +T2 clamp(T1 src, int precision, bool is_signed = false) { + std::int32_t min = is_signed ? -(1LL << (precision - 1)) : 0; + std::int32_t max = + is_signed ? ((1LL << (precision - 1)) - 1) : (1LL << precision) - 1; + + // Make sure T1 and T2 can represent the precision + assert(min >= std::numeric_limits::lowest()); + assert(min >= std::numeric_limits::lowest()); + assert(max <= std::numeric_limits::max()); + assert(max <= std::numeric_limits::max()); + + return std::min(std::max(src, min), max); +} + +/// Quantize src using zero_point and scale, clamp to the specified precision, +/// and convert it to type T +template +T Quantize( + float src, + std::int32_t zero_point, + float scale, + int result_precision, + bool result_is_signed = std::is_signed_v) { + // Note: We want to multiply with src with inv_scale instead of + // dividing src by scale. The same is done in vector code and + // at other places. + // + // Example: + // With scale = 0.00214854861f, zero_point = 0 and src = 0.273939937f + // transformed_val is 127.5 for src * inv_scale while + // transformed_val is 127.499992 for src / scale. + // Eventually 127.5 gets rounded to 128 while 127.499992 gets rounded to 127. + float inv_scale = 1.0f / scale; + + float transformed_val = src * inv_scale; + // nearbyint here performs round-to-nearest-ties-to-even with + // default rounding mode. + // For example, nearbyint(1.4) is 1.0, nearbyint(1.5) is 2.0 + // and nearbyint(2.5) is 2.0 + // Adding zero_point before or after rounding can make a difference + // in exactly halfway cases. + if constexpr (LEGACY) { + transformed_val = std::nearbyint(zero_point + transformed_val); + } else { + transformed_val = zero_point + std::nearbyint(transformed_val); + } + // Please note the use of double. Unlike float, a double can represent + // all int32 values exactly. Using a float results in a float value > + // INT32_MAX conversion to int32 in clamp function and hence an UBSAN error. + return clamp(transformed_val, result_precision, result_is_signed); +} + +template +T Quantize(float src, const TensorQuantizationParams& qparams) { + return Quantize( + src, qparams.zero_point, qparams.scale, qparams.precision); +} + +template +FBGEMM_API void Quantize( + const float* src, + T* dst, + std::int64_t len, + const TensorQuantizationParams& qparams, + int thread_id = 0, + int num_threads = 1); + +/// @ingroup fbgemm-quant-utils-generic +/// +/// Quantize floating point data in `src` to type `T`. +/// +/// @tparam T output quantized data type (`int8_t`, `uint8_t`, and `int32_t` are +/// supported) +/// +/// @tparam LAYOUT layout of input tensor in `src`. (`KCX` and `KXC` are +/// supported) +/// `KCX` corresponds to `KCRS` or `KCTRS` (for weight tensors with time +/// dimension) +/// `KXC` corresponds to `KRSC` or `KTRSC` (for weight tensors with time +/// dimension) +/// +/// @param K Output channels for weight tensors +/// @param C Number of channels +/// @param X `R*S` or `T*R*S` +/// @param G Groups (if `G == C` the function performs channelwise +/// quantization; +/// if `1 < G < C` the function performs groupwise +/// quantization; if `G == 1` the function performs per tensor +/// quantization;) +/// @param scales floating point scales. Size should be equal `G` +/// @param zero_points zero points (should be reprsentable in type `T`). +/// Size should be equal `G` +template +FBGEMM_API void QuantizeGroupwise( + const float* src, + int K, + int C, + int X, + int G, + const float* scales, + const std::int32_t* zero_points, + T* dst); + +template +float Dequantize(T src, const TensorQuantizationParams& qparams) { + return qparams.scale * (src - qparams.zero_point); +} + +template +void Dequantize( + const T* src, + float* dst, + std::int64_t len, + const TensorQuantizationParams& qparams, + int thread_id = 0, + int num_threads = 1) { + int64_t i_begin = 0, i_end = 0; + fbgemmPartition1D(thread_id, num_threads, len, i_begin, i_end); + for (int64_t i = i_begin; i < i_end; i++) { + dst[i] = Dequantize(src[i], qparams); + } +} + +template +float FusedQuantizeDequantize( + float src, + const TensorQuantizationParams& qparams) { + T q = Quantize( + src, qparams.zero_point, qparams.scale, qparams.precision); + return Dequantize(q, qparams); +} + +/// @ingroup fbgemm-quant-utils-generic +/// +/// Fused integer quantization dequantization kernel to accelerate +/// quantization-aware training. Quantize `fp32` values in src to `(u)int8` +/// using the provided qparams, and dequantize quantized integer values back +/// into `fp32`. +template +FBGEMM_API void FusedQuantizeDequantize( + const float* src, + float* dst, + std::int64_t len, + const TensorQuantizationParams& qparams, + int thread_id = 0, + int num_threads = 1, + float noise_ratio = 0.0f); + +//////////////////////////////////////////////////////////////////////////////// +// Requantization (pure fixed-point) + +FBGEMM_API std::int64_t +SaturatingRoundingMulWithShift(std::int32_t a, std::int32_t b, int right_shift); + +template +T Requantize( + std::int32_t src, // int32 input before requantization + std::int32_t zero_point, + std::int32_t multiplier, + int right_shift, + int result_precision, + bool result_is_signed = false) { + std::int64_t quantized_down = + zero_point + SaturatingRoundingMulWithShift(src, multiplier, right_shift); + return clamp( + quantized_down, result_precision, result_is_signed); +} + +template +T RequantizeFixedPoint( + std::int32_t src, // int32 input before requantization + const RequantizationParams& params) { + return Requantize( + src, + params.target_qparams.zero_point, + params.multiplier, + params.right_shift, + params.target_qparams.precision); +} + +template +FBGEMM_API void RequantizeFixedPoint( + const std::int32_t* src, + T* dst, + std::int64_t len, + const RequantizationParams& params, + int thread_id = 0, + int num_threads = 1); + +//////////////////////////////////////////////////////////////////////////////// +// Requantization (with floats) + +template +T Requantize( + std::int32_t src, // int32 input before requantization + std::int32_t zero_point, + float multiplier, + int result_precision, + bool result_is_signed = false) { + long quantized_down = zero_point + std::lrintf(src * multiplier); + return clamp(quantized_down, result_precision, result_is_signed); +} + +template +T Requantize( + std::int32_t src, // int32 input before requantization + const RequantizationParams& params) { + return Requantize( + src, + params.target_qparams.zero_point, + params.real_multiplier, + params.target_qparams.precision); +} + +template +FBGEMM_API void Requantize( + const std::int32_t* src, + T* dst, + std::int64_t len, + const RequantizationParams& params, + int thread_id = 0, + int num_threads = 1); + +/** + * @ingroup fbgemm-quant-utils-generic + * + * Convert float (fp32 or fp16) inputs to rowwise quantized outputs. + * bitrate specifies the number of bits in quantized output. + * Scale and Bias are in fp16. Each row's Scale and Bias are stored in + * the row itself (fused) at the end. + * + * @param bit_rate can be 2, 4, or 8 + */ +template +FBGEMM_API void FloatOrHalfToFusedNBitRowwiseQuantizedSBHalf( + int bit_rate, + const InputType* input, + size_t input_rows, + int input_columns, + std::uint8_t* output, + const InputType* rowwise_min_max = nullptr); + +/** + * Convert fused rowwise quantized inputs to float (fp32 or fp16). + * bitrate specifies the number of bits in quantized input. + * Scale and Bias are in fp16. Each row's Scale and Bias are stored in + * the row itself (fused) at the end. + * + * @param bit_rate can be 2, 4, or 8 + */ +template +FBGEMM_API void FusedNBitRowwiseQuantizedSBHalfToFloatOrHalf( + int bit_rate, + const uint8_t* input, + size_t input_rows, + int input_columns, + OutputType* output, + bool scale_bias_last = true); + +/** + * Convert float or half inputs to rowwise quantized (8-bit) outputs. + * Scale and Bias are in float. Each row's Scale and Bias are stored in + * the row itself (fused) at the end. + * + * This version intentionally supports only 8-bit because we want to discourage + * the usage of float scale and bias with 2 and 4 bit cases as that diminishes + * the overall memory savings. + */ +template +FBGEMM_API void FloatOrHalfToFused8BitRowwiseQuantizedSBFloat( + const InputType* input, + size_t input_rows, + int input_columns, + std::uint8_t* output, + const InputType* rowwise_min_max = nullptr); + +/** + * Convert fused rowwise quantized (8-bit) inputs to float or half outputs. + * Scale and Bias are in float. Each row's Scale and Bias are stored in + * the row itself (fused) at the end. + * + * This version intentionally supports only 8-bit because + * the corresponding quantize version only supports 8-bit. + */ +template +FBGEMM_API void Fused8BitRowwiseQuantizedSBFloatToFloatOrHalf( + const uint8_t* input, + size_t input_rows, + int input_columns, + OutputType* output, + const bool scale_bias_last = true, + const bool quant_padding_float_type = true); + +/** + * Same as ToFusedNBitRowwiseQuantizedSBHalf but unoptimized. + * This should not be called directly except in testing. + */ +template +FBGEMM_API void FloatOrHalfToFusedNBitRowwiseQuantizedSBHalfRef( + int bit_rate, + const InputType* input, + size_t input_rows, + int input_columns, + std::uint8_t* output); + +/** + * Same as FloatOrHalfToFused8BitRowwiseQuantizedSBFloat but unoptimized. + * This should not be called directly except in testing. + */ +template +FBGEMM_API void FloatOrHalfToFused8BitRowwiseQuantizedSBFloatRef( + const InputType* input, + size_t input_rows, + int input_columns, + std::uint8_t* output); + +/** + * Same as FusedNBitRowwiseQuantizedSBHalfToFloat but unoptimized. + * This should not be called directly except in testing. + */ +template +FBGEMM_API void FusedNBitRowwiseQuantizedSBHalfToFloatOrHalfRef( + int bit_rate, + const uint8_t* input, + size_t input_rows, + int input_columns, + OutputType* output, + bool scale_bias_last = true); + +/** + * Same as Fused8BitRowwiseQuantizedSBFloatToFloatOrHalf but unoptimized. + * This should not be called directly except in testing. + */ +template +FBGEMM_API void Fused8BitRowwiseQuantizedSBFloatToFloatOrHalfRef( + const uint8_t* input, + size_t input_rows, + int input_columns, + OutputType* output, + const bool scale_bias_last = true, + const bool quant_padding_float_type = true); + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx2.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..ec985aeba579fdb4bec0cffedc9115fc194ee861 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx2.h @@ -0,0 +1,192 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include "./FbgemmBuild.h" // @manual +#include "./UtilsAvx2.h" // @manual + +/// @defgroup fbgemm-quant-utils-avx2 Quantization Utilities (AVX2) +/// + +namespace fbgemm { + +/// Number of columns in the rowwise min/max buffer passed to the quantization +/// function(s) +constexpr int kRowwiseMinMaxNumCols = 2; + +/// Struct from `gemmlowp` +/// +/// A structure to hold quantization parameters `scale` and `zero_point`. +/// The meaning of these values is as the constants in the quantization equation +/// +/// `real_value = scale * (quantized_value - zero_point)` +/// +/// In other words, 'zero_point' is the quantized value that corresponds +/// to the real value 0, and 'scale' is the difference of real values +/// corresponding to consecutive quantized values. +struct FBGEMM_API TensorQuantizationParams { + float scale; + std::int32_t zero_point; + int precision; + float Min() const; + float Max() const; +}; + +/// Parameters when we scale from int32 intermediate matrix multiplication +/// results to 8-bit integers +struct FBGEMM_API RequantizationParams { + /// For floating-point requantization + float real_multiplier; + + /// For fixed-point requantization + std::int32_t multiplier; + int right_shift; + + TensorQuantizationParams target_qparams; +}; + +/// @ingroup fbgemm-quant-utils-avx2 +/// +/// @brief Find the min and max value in a float matrix. +void FBGEMM_API FindMinMax(const float* m, float* min, float* max, int64_t len); + +#if !defined(__aarch64__) + +//////////////////////////////////////////////////////////////////////////////// +// Utility functions +//////////////////////////////////////////////////////////////////////////////// + +template +void QuantizeAvx2( + const float* src, + T* dst, + int64_t len, + const TensorQuantizationParams& qparams); + +template +void FusedQuantizeDequantizeAvx2( + const float* src, + float* dst, + int len, + const TensorQuantizationParams& qparams, + float noise_ratio = 0.0f); + +/// @ingroup fbgemm-quant-utils-avx2 +/// +/// Random number generator in [0, 9] based on +/// this paper. +uint32_t FBGEMM_API Xor128(); + +void RequantizeFixedPointAvx2( + const std::int32_t* src, + std::uint8_t* dst, + int len, + const RequantizationParams& params); + +void RequantizeAvx2( + const std::int32_t* src, + std::uint8_t* dst, + int len, + const RequantizationParams& params); + +#endif // !defined(__aarch64__) + +/// @ingroup fbgemm-quant-utils-avx2 +/// +/// Requantize with avx2 and bias is fused. +template < + bool A_SYMMETRIC, + bool B_SYMMETRIC, + QuantizationGranularity Q_GRAN, + bool HAS_BIAS, + bool FUSE_RELU, + typename BIAS_TYPE = std::int32_t, + bool DIRECT = false> +FBGEMM_API void requantizeOutputProcessingAvx2( + std::uint8_t* out, + const std::int32_t* inp, + const block_type_t& block, + int ld_out, + int ld_in, + const requantizationParams_t& r); + +template < + bool A_SYMMETRIC, + bool B_SYMMETRIC, + QuantizationGranularity Q_GRAN, + bool HAS_BIAS, + bool FUSE_RELU, + int C_PER_G, + typename BIAS_TYPE = std::int32_t> +FBGEMM_API void requantizeOutputProcessingGConvAvx2( + std::uint8_t* out, + const std::int32_t* inp, + const block_type_t& block, + int ld_out, + int ld_in, + const requantizationParams_t& r); + +template < + bool A_SYMMETRIC, + bool B_SYMMETRIC, + QuantizationGranularity Q_GRAN, + bool HAS_BIAS, + bool FUSE_RELU> +FBGEMM_API void requantizeForFloatAvx2( + float* out, + const std::int32_t* inp, + const block_type_t& block, + int ld_out, + int ld_in, + const requantizationForFloatParams_t& r); + +#if !defined(__aarch64__) + +template +void FloatOrHalfToFusedNBitRowwiseQuantizedSBHalfAvx2( + const InputType* input, + size_t input_rows, + int input_columns, + std::uint8_t* output, + const InputType* rowwise_min_max = nullptr); + +template +void FloatOrHalfToFused8BitRowwiseQuantizedSBFloatAvx2( + const InputType* input, + size_t input_rows, + int input_columns, + std::uint8_t* output, + const InputType* rowwise_min_max = nullptr); + +template +void FusedNBitRowwiseQuantizedSBHalfToFloatOrHalfAvx2( + const std::uint8_t* input, + size_t input_rows, + int input_columns, + OutputType* output); + +template < + typename OutputType, + bool scale_bias_last = true, + bool quant_padding_float_type = true> +void Fused8BitRowwiseQuantizedSBFloatToFloatOrHalfAvx2( + const std::uint8_t* input, + size_t input_rows, + int input_columns, + OutputType* output); + +#endif // !defined(__aarch64__) + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx512.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx512.h new file mode 100644 index 0000000000000000000000000000000000000000..d8330f4808c1b258e94d58c68cd14b8060b31b1c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx512.h @@ -0,0 +1,55 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include "Types.h" +#if !defined(__aarch64__) + +#include +#include "./FbgemmBuild.h" // @manual +#include "./UtilsAvx2.h" // @manual + +/// @defgroup fbgemm-quant-utils-avx512 Quantization Utilities (AVX512) +/// + +namespace fbgemm { + +/// @ingroup fbgemm-quant-utils-avx512 +/// +/// Requantize with AVX512. +template < + bool A_SYMMETRIC, + bool B_SYMMETRIC, + QuantizationGranularity Q_GRAN, + bool HAS_BIAS, + bool FUSE_RELU, + int C_PER_G, + typename BIAS_TYPE = std::int32_t> +FBGEMM_API void requantizeOutputProcessingGConvAvx512( + std::uint8_t* out, + const std::int32_t* inp, + const block_type_t& block, + int ld_out, + int ld_in, + const requantizationParams_t& r); + +template +void Fused8BitRowwiseQuantizedSBFloatToBfloat16Avx512( + const std::uint8_t* input, + size_t input_rows, + int input_columns, + bfloat16* output); +} // namespace fbgemm + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsNeon.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsNeon.h new file mode 100644 index 0000000000000000000000000000000000000000..32e571213b6c83d9dd7dd65b4b5930b9a3974224 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsNeon.h @@ -0,0 +1,53 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#ifdef __aarch64__ + +#include +#include "./FbgemmBuild.h" // @manual + +/// @defgroup fbgemm-quant-utils-avx2 Quantization Utilities (AVX2) +/// + +namespace fbgemm { + +//////////////////////////////////////////////////////////////////////////////// +// Utility functions +//////////////////////////////////////////////////////////////////////////////// + +template +void FloatOrHalfToFused8BitRowwiseQuantizedSBFloatNeon( + const InputType* input, + size_t input_rows, + int input_columns, + uint8_t* output); + +template +void Fused8BitRowwiseQuantizedSBFloatToFloatOrHalfNeon( + const std::uint8_t* input, + size_t input_rows, + int input_columns, + OutputType* output); + +template +void FloatOrHalfToFusedNBitRowwiseQuantizedSBHalfNeon( + const InputType* input, + size_t input_rows, + int input_columns, + std::uint8_t* output); + +} // namespace fbgemm + +#endif // __aarch64__ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/SimdUtils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/SimdUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..6a1f4aca84462476cec8e1aee731c6f691765881 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/SimdUtils.h @@ -0,0 +1,118 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include "./Utils.h" // @manual + +#include // @manual +#include // @manual + +namespace fbgemm { + +#if ASMJIT_LIBRARY_VERSION >= ASMJIT_LIBRARY_MAKE_VERSION(1, 17, 0) +//! 128-bit XMM register (SSE+). +class Xmm : public asmjit::x86::Vec { + public: + using Vec::Vec; + using Vec::operator=; + Xmm(uint32_t regId) : Vec(asmjit::x86::Vec::make_xmm(regId)) {} + //! Casts this register to a register that has half the size (XMM). + ASMJIT_INLINE_NODEBUG Xmm half() const noexcept { + return Xmm(id()); + } +}; + +//! 256-bit YMM register (AVX+). +class Ymm : public asmjit::x86::Vec { + public: + using Vec::Vec; + using Vec::operator=; + Ymm(uint32_t regId) : Vec(asmjit::x86::Vec::make_ymm(regId)) {} + //! Casts this register to a register that has half the size (XMM). + ASMJIT_INLINE_NODEBUG Xmm half() const noexcept { + return Xmm(id()); + } +}; + +//! 512-bit ZMM register (AVX512+). +class Zmm : public asmjit::x86::Vec { + public: + using Vec::Vec; + using Vec::operator=; + Zmm(uint32_t regId) : Vec(asmjit::x86::Vec::make_zmm(regId)) {} + //! Casts this register to a register that has half the size (YMM). + ASMJIT_INLINE_NODEBUG Ymm half() const noexcept { + return Ymm(id()); + } +}; +#else +using Xmm = asmjit::x86::Xmm; +using Ymm = asmjit::x86::Ymm; +using Zmm = asmjit::x86::Zmm; +#endif + +/** + * @brief Some commonly used variables for different instruction sets + */ +template +struct simd_info; + +template <> +struct simd_info { + static constexpr int WIDTH_BITS = 256; + static constexpr int WIDTH_BYTES = 32; + static constexpr int WIDTH_32BIT_ELEMS = 8; + static constexpr int NUM_VEC_REGS = 16; + + using vec_reg_t = Ymm; +}; + +template <> +struct simd_info { + // Implementation is unrolled to match params used on avx2 + static constexpr int WIDTH_BITS = 256; + static constexpr int WIDTH_BYTES = 32; + static constexpr int WIDTH_32BIT_ELEMS = 8; + static constexpr int NUM_VEC_REGS = 32; +}; + +template <> +struct simd_info { + static constexpr int WIDTH_BITS = 512; + static constexpr int WIDTH_BYTES = 64; + static constexpr int WIDTH_32BIT_ELEMS = 16; + static constexpr int NUM_VEC_REGS = 32; + + using vec_reg_t = Zmm; +}; + +template <> +struct simd_info + : public simd_info {}; + +template <> +struct simd_info { + static constexpr int WIDTH_BITS = 256; + static constexpr int WIDTH_BYTES = 32; + static constexpr int WIDTH_32BIT_ELEMS = 8; + static constexpr int NUM_VEC_REGS = 32; + + using vec_reg_t = Ymm; +}; + +template <> +struct simd_info + : public simd_info {}; + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Types.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Types.h new file mode 100644 index 0000000000000000000000000000000000000000..615ea0d87471ee752b9bc76873736ad1a36b0ef4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Types.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace fbgemm { + +using float16 = std::uint16_t; +using bfloat16 = std::uint16_t; + +inline int64_t round_up(int64_t val, int64_t unit) { + return (val + unit - 1) / unit * unit; +} + +inline int64_t div_up(int64_t val, int64_t unit) { + return (val + unit - 1) / unit; +} + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Utils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Utils.h new file mode 100644 index 0000000000000000000000000000000000000000..dc0ef013d11fb4a65fbff6337a5eeac36fbadbc3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Utils.h @@ -0,0 +1,505 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include "./FbgemmBuild.h" // @manual +#include "./UtilsAvx2.h" // @manual + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef HAVE_SVE +#if defined(__aarch64__) && __ARM_FEATURE_SVE && \ + __has_include() +#define HAVE_SVE 1 +#else +#define HAVE_SVE 0 +#endif +#endif + +namespace fbgemm { + +/** + * @brief Helper struct to type specialize for uint8 and int8 together. + */ +template +struct is_8bit { + static constexpr bool value = + std::is_same_v || std::is_same_v; +}; + +/** + * @brief Typed enum to specify matrix operations. + */ +enum class matrix_op_t { NoTranspose, Transpose }; + +/** + * @brief Typed enum for supported instruction sets. + */ +enum class inst_set_t { + anyarch, + avx2, + avx512, + avx512_ymm, + avx512_vnni, + avx512_vnni_ymm, + sve +}; + +/** + * @brief Typed enum for optimized paths for convolutions + */ +enum class optimized_conv_t { + depthwise, + groupwise, + pointwise, + fastpath1d, + im2col, + directconv +}; + +/** + * @brief Typed enum for implementation type. + * + * ref is reference and opt is optimized. + */ +enum class impl_type_t { ref, opt }; + +/** + * @brief Typed enum to specify data layout. + * KCX can be KCRS format or KCTRS format (e.g., for 3-D convolutions) + * KXC can be KRSC format or KTRSC format (e.g., for 3-D convolutions) + */ +enum class FBGEMM_ENUM_CLASS_API layout_t { KCX, KXC }; + +/** + * @brief A function to compare data in two buffers for closeness/equality. + */ +template +FBGEMM_API int compare_buffers( + const T* ref, + const T* test, + int m, + int n, + int ld, + size_t max_mismatches_to_report, + float atol = 1e-3); + +/** + * @brief Print the matrix. + * @param op Transpose type of the matrix. + * @param R The height of the matrix. + * @param C The width of the matrix. + * @param ld The leading dimension of the matrix. + * @param name The prefix string before printing the matrix. + */ +template +void printMatrix( + matrix_op_t op, + const T* inp, + size_t R, + size_t C, + size_t ld, + const std::string& name) { + // R: number of rows in op(inp) + // C: number of cols in op(inp) + // ld: leading dimension in inp + std::cout << name << ":" << "[" << R << ", " << C << "]" << '\n'; + bool tr = (op == matrix_op_t::Transpose); + for (size_t r = 0; r < R; ++r) { + for (size_t c = 0; c < C; ++c) { + T res = tr ? inp[c * ld + r] : inp[r * ld + c]; + if constexpr (std::is_integral_v) { + std::cout << std::setw(5) << static_cast(res) << " "; + } else { + std::cout << std::setw(5) << res << " "; + } + } + std::cout << '\n'; + } +} + +/** + * @brief Transpose a matrix. + * + * @param M the number of rows of input matrix + * @param N the number of columns of input matrix + */ +template +FBGEMM_API void transpose_simd( + int64_t M, + int64_t N, + const T* src, + int64_t ld_src, + T* dst, + int64_t ld_dst); + +/** + * @brief Explicitly set instruction set to be used + */ +FBGEMM_API void fbgemmForceIsa(inst_set_t /*isa*/); + +/** + * @brief Enable AVX512-256 path for Intel(r) Xeon(r) D servers + */ +FBGEMM_API void fbgemmEnableAvx512Ymm(bool /*flag*/); + +/** + * @brief Are we running on a Xeon-D cpu? + */ +FBGEMM_API bool fbgemmIsIntelXeonD(); + +/** + * @brief Are we running on a AVX512 supported cpu? + */ +FBGEMM_API bool fbgemmHasAvx512Support(); + +/** + * @brief Are we running on a AVX2 supported cpu? + */ +FBGEMM_API bool fbgemmHasAvx2Support(); + +/** + * @brief Are we running on a AVX512_VNNI supported cpu? + */ +FBGEMM_API bool fbgemmHasAvx512VnniSupport(); + +/** + * @brief Are we running on a AVX512_BF16 supported cpu? + */ +FBGEMM_API bool fbgemmHasAvx512Bf16Support(); + +/** + * @brief Are we running on a ARM Neon supported cpu? + */ +FBGEMM_API bool fbgemmHasArmNeonSupport(); + +/** + * @brief Are we running on a ARM SVE supported cpu? + */ +FBGEMM_API bool fbgemmHasArmSveSupport(); + +/** + * @brief Are we running on a ARM SVE2 supported cpu? + */ +FBGEMM_API bool fbgemmHasArmSve2Support(); + +/** + * @brief Retrieve current CPU instruction set + */ +FBGEMM_API inst_set_t fbgemmInstructionSet(); + +/** + * @brief Is ISA is wide vector ZMM + */ +FBGEMM_API bool isZmm(inst_set_t /*isa*/); + +/** + * @brief Is ISA is wide vector ZMM + */ +FBGEMM_API bool isYmm(inst_set_t /*isa*/); + +/** + * @brief Helper struct to enable autotuning of FBGEMM packing and kernels. + * + * This structure is optional. If not used, the default values for these + * parameters are picked up from PackingTraits-inl.h. Please see this + * file for details on these parameters. + */ +struct FBGEMM_API BlockingFactors { + int MR; + int NR; + int NR_MIN; + int ROW_INTERLEAVE; + int MCB; + int KCB; + int NCB; +}; + +/** + * @brief A struct to represent the partition information for the threads on the + * m and n dimensions. + */ +struct FBGEMM_API thread_type_t { + int g_num_threads; + int m_num_threads; + int n_num_threads; + int g_thread_id; + int m_thread_id; + int n_thread_id; + + std::string toString() const { + std::string out; + out += "g num threads: " + std::to_string(g_num_threads) + ", "; + out += "m num threads: " + std::to_string(m_num_threads) + ", "; + out += "n num threads: " + std::to_string(n_num_threads) + ", "; + out += "g thread id: " + std::to_string(g_thread_id) + ", "; + out += "m thread id: " + std::to_string(m_thread_id) + ", "; + out += "n thread id: " + std::to_string(n_thread_id); + return out; + } +}; + +/** + * @brief A heuristic algorithm to partition the threads across m and n + * dimensions for parallelization, ensuring the ratio between the number of rows + * allocated to each thread in the m dimension and the number of columns + * allocated to each thread in the n dimension is approximately aspect_ratio. + * + * The less aspect_ratio is, the more favorable it is to parallelize the m + * dimension over the n dimension. + */ +FBGEMM_API int fbgemmGet2DPartition( + int m, + int n, + int nthreads, + int n_align, + double aspect_ratio); + +/** + * @brief A heuristic way to partition the threads across g, m and n dimensions + * for parallelization. + */ +FBGEMM_API thread_type_t fbgemmGetThreadPartition( + int g, + int m, + int n, + int thread_id, + int num_threads, + int n_align = 64); + +template +std::string arrayToString(const std::array& inp) { + std::string out = "["; + for (int i = 0; i < SIZE; ++i) { + out += std::to_string(inp[i]); + out += (i != SIZE - 1) ? std::string(", ") : std::string("]"); + } + return out; +} + +template +bool isValidBlockingFactor(const BlockingFactors* const param) { + constexpr bool is_32bit = std::is_same_v; + constexpr bool is_16bit = std::is_same_v; + static const auto iset = fbgemmInstructionSet(); + + if constexpr (is_32bit) { + if (param->ROW_INTERLEAVE != 4) + return false; + + if (isZmm(iset)) { + if (param->NR_MIN != 16 || param->NR % param->NR_MIN) + return false; + } else if (isYmm(iset)) { + if (param->NR_MIN != 8 || param->NR % param->NR_MIN) + return false; + } + } else if constexpr (is_16bit) { + if (param->ROW_INTERLEAVE != 2) + return false; + + if (isZmm(iset)) { + if (param->NR_MIN != 32 || param->NR % param->NR_MIN) + return false; + } else if (isYmm(iset)) { + if (param->NR_MIN != 16 || param->NR % param->NR_MIN) + return false; + } + } + + if (param->MCB % param->MR) + return false; + if (param->NCB % param->NR) + return false; + if (isZmm(iset)) { + if constexpr (is_32bit) { + // Zmm register usage for C + if (param->MR * (param->NR / param->NR_MIN) > 28) + return false; + } else if constexpr (is_16bit) { + // Zmm register usage for C + one row for loading B + if ((param->MR * (param->NR / param->NR_MIN) + + (param->NR / param->NR_MIN)) > 28) + return false; + } + + } else if (isYmm(iset)) { + if (param->MR * (param->NR / param->NR_MIN) > 12) + return false; + } + return true; +} + +/** + * @brief Partition work across given number of threads + * + * @param start Given thread_id should execute starting from the index + * start + * @param stop Given thread_id should stop executing at the index stop + * + * i.e., the loop should be equivalent to for(int i = start; i < end; ++i) + */ +FBGEMM_API void fbgemmPartition1D( + int thread_id, + int num_threads, + std::int64_t total_work, + std::int64_t& start, + std::int64_t& end); + +/** + * @brief Partition work across given number of threads in blocks + * of size block_size. Each thread gets a multiple of block_size + * work or nothing, except the last one. The last one might + * receive the fringe case. + * + * @param start Given thread_id should execute starting from the index + * start + * @param stop Given thread_id should stop executing at the index stop + * + * The loop can be equivalent to for(int i = start; i < end; i+=block_size) + * except for the last thread. (i.e., thread_id = num_threads - 1) + * + * Example 1: block_size = 2, num_threads = 2 + * total_work start(th 0) end(th 0) start(th 1) end(th 1) + * 4 0 2 2 4 + * 5 0 2 2 5 + * + * Example 2: block_size = 2, num_threads = 3 + * total_work start(th 0) end(th 0) start(th 1) end(th 1) + * 4 0 2 2 4 + * 5 0 2 2 4 + * + * total_work start(th 2) end(th 2) + * 4 4 4 + * 5 4 5 + * + * Example 3: block_size = 2, num_threads = 4 + * total_work start(th 0) end(th 0) start(th 1) end(th 1) + * 4 0 2 2 4 + * 5 0 2 2 4 + * + * total_work start(th 2) end(th 2) start(th 3) end(th 3) + * 4 4 4 4 4 + * 5 4 4 4 5 + */ +FBGEMM_API void fbgemmPartition1DBlocked( + int thread_id, + int num_threads, + std::int64_t total_work, + int block_size, + std::int64_t& start, + std::int64_t& end); + +/** + * @brief A stable sorting algorithm. It sorts 8 bits at a time, hence in a + * worst-case performing sizeof(K) / 8 passes. Providing meaningful max_value + * may help reduce the number of passes performed by radix_sort. If + * maybe_with_neg_vals is set to true, we are performing all possible passes, + * up to a sign bit. If OpenMP is available in a build system, radix_sort works + * in parallel. + */ +template +FBGEMM_API std::pair radix_sort_parallel( + K* const inp_key_buf, + V* const inp_value_buf, + K* const tmp_key_buf, + V* const tmp_value_buf, + const int64_t elements_count, + const int64_t max_value, + const bool maybe_with_neg_vals = false); + +/** + * @brief Helper function that allows us to check whether radix_sort is + * accelerated with OpenMP or not. + */ +FBGEMM_API bool is_radix_sort_accelerated_with_openmp(); + +/** + * Choosing which kernel (autovec/asmjit/ref) to use for nbit-CPU-TBE + * Available kernels: + * * ref: non-optimized, reference implementation that focuses on + * correctness, not performance + * * asmjit: hand-optimized kernel by having asmjit emit SIMD + * instructions during runtime. Only supports x86_64 CPUs with + * AVX2/AVX512 instruction sets + * * autovec: the kernel written in regular C++ code but in a + * way that makes compilers easier to generate vectorized SIMD + * instructions out of it. Supports both x86_64 and aarch64 CPUs. + * Currently only available on Linux. + * How to set environment variables: + * * No environment variables: on x86_64 we will default to asmjit + * kernel, and on aarch64 and linux we will default to autovec. + * On non-linux aarch64 we will fall back to ref. + * * Set FBGEMM_NO_AUTOVEC: on aarch64 linux we will use ref. On other + * platforms this will have no effect. + * * Set FBGEMM_NO_ASMJIT: on x86_64 we will use ref. On other + * platforms this will have no effect. + * * Set FBGEMM_NO_ASMJIT AND FBGEMM_FORCE_AUTOVEC: on x86_64 we will + * use autovec if these two variables are set at the same time. + * No effect on other platforms. + * * FBGEMM_FORCE_AUTOVEC will override FBGEMM_NO_AUTOVEC if they + * are set at the same time. + * * These variables are considered set as long as they exist regardless + * of content. That means assigning values like "1", "true", "y", "0", + * "false" or "no" has the same effect. The easiest way of setting a + * variable is to prepend `=1` before the benchmarking command. + */ +FBGEMM_API bool is_autovec_disabled(); +FBGEMM_API bool is_autovec_forced(); +FBGEMM_API bool is_asmjit_disabled(); +FBGEMM_API bool is_stats_enabled(); + +/** + * @brief A function to check if the input parameter in the nbit CPU TBE kernel + * is valid. + */ +template +void nbit_embedding_sanity_check( + // assertions are ignored in release mode, in which case these parameters + // will be unused + [[maybe_unused]] const int input_bit_rate, + [[maybe_unused]] const int output_bit_rate, + [[maybe_unused]] const bool no_bag) { + assert( + (input_bit_rate == 2 || input_bit_rate == 4) && + "input_bit_rate must be 2 or 4"); + // NOLINTNEXTLINE(bugprone-branch-clone) + if constexpr (std::is_same_v) { + assert( + (no_bag && input_bit_rate == 4 && output_bit_rate == 4) && + "we currently only support int4 to int4 for sequential TBE"); + } else { + assert( + (output_bit_rate == 8 * sizeof(OutType)) && + "output_bit_rate should be equal to 8 * sizeof(OutType)"); + } +} + +#define WARN_ONCE(...) \ + do { \ + static bool _warned = false; \ + if (!_warned) { \ + _warned = true; \ + fprintf(stderr, __VA_ARGS__); \ + } \ + } while (0) + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/UtilsAvx2.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/UtilsAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..6a774a3fb71b17dda3bbf67bf8e5819d6fb95654 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/UtilsAvx2.h @@ -0,0 +1,97 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once +// This file defines common utilities used in code compiled with avx2/avx512 +// flags. + +#include +#include + +namespace fbgemm { + +enum class FBGEMM_ENUM_CLASS_API QuantizationGranularity { + TENSOR, + GROUP, + OUT_CHANNEL, +}; + +/** + * @brief A struct to represent a block of a matrix. + */ +struct FBGEMM_API block_type_t { + int row_start; + int row_size; + int col_start; + int col_size; + + std::string toString() const { + std::string out; + out += "row start:" + std::to_string(row_start) + ", "; + out += "row size:" + std::to_string(row_size) + ", "; + out += "col start:" + std::to_string(col_start) + ", "; + out += "col size:" + std::to_string(col_size); + return out; + } +}; + +/** + * @brief A struct to represent all the requantization parameters. + * + * Please note that this is different from RequantizationParams in + * QuantUtilsAvx2.h as it combines all the parameters needed for various + * quantization granularities + */ +template +struct requantizationParams_t { + using BIAS_T = BIAS_TYPE; + std::int32_t A_zero_point; + const std::int32_t* B_zero_point; + std::int32_t C_zero_point; + const float* C_multiplier; + const std::int32_t* row_offsets; + const std::int32_t* col_offsets; + const BIAS_T* bias; + std::uint32_t ncols; + int groups; + const float* act_times_w_scale; +}; + +/** + * @brief A struct to represent all the parameters for requantizing for floats. + */ +struct requantizationForFloatParams_t { + std::int32_t A_zero_point; + const std::int32_t* B_zero_point; + float A_scale; + const float* B_scale; + const std::int32_t* row_offsets; + const std::int32_t* col_offsets; + const float* bias; + std::uint32_t ncols; + int groups; +}; + +/** + * @brief Allocate size bytes of uninitialized storage whose alignment is + * specified by align. + */ +FBGEMM_API void* +fbgemmAlignedAlloc(size_t align, size_t size, bool raiseException = false); + +/** + * @brief Free memory allocated by fbgemmAlignedAlloc + */ +FBGEMM_API void fbgemmAlignedFree(void* p); + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtils.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..ba473fb3d8e16a65f743b5a048eacca64c360558 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtils.h @@ -0,0 +1,62 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once +#include + +#include "fbgemm/FbgemmBuild.h" +#include "fbgemm/FbgemmSparse.h" +#include "fbgemm/UtilsAvx2.h" +#include "fbgemm/spmmUtilsAvx2.h" + +namespace fbgemm { + +FBGEMM_API void sparseDenseMMRef( + int M, + int N, + const int* row_ptr, + const int* col_idx, + const float* values, + const float* B, + int ldb, + float* C, + int ldc, + bool accum = false); + +template +FBGEMM_API void sparseDenseInt8MMRef( + int N, + const std::unique_ptr>& bcsr, + const uint8_t* B, + int ldb, + int32_t* C_i32, + uint8_t* C_u8, + int ldc, + trRequantizationParams_t& rParams, + bool accum = false, + int thread_id = 0, + int num_threads = 1); + +template +FBGEMM_API void trRequantizeRef( + uint8_t* out, + const int32_t* inp, + const block_type_t& block, + int ld_out, + int ld_in, + const trRequantizationParams_t& r); + +// Get matrix shapes of interest +FBGEMM_API std::vector> getSparseMatrixShapes(); + +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtilsAvx2.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtilsAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..7543b56dfa0410fd678e2ec24fa39a9054dee7d4 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtilsAvx2.h @@ -0,0 +1,44 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once +#include +#include "./FbgemmBuild.h" // @manual +#include "fbgemm/UtilsAvx2.h" + +namespace fbgemm { +struct FBGEMM_API trRequantizationParams_t { + std::int32_t act_zero_point; // activation zero point + const std::int32_t* weight_zero_points; // weight zero point(s) + std::int32_t C_zero_point; + const float C_scale; + const std::int32_t* weight_row_offsets; + const std::int32_t* act_col_offsets; + const float* bias; + const float* act_times_w_scale; +}; + +template < + bool FUSE_RELU, + bool ACT_SYMMETRIC, // whether activation matrix is symmetric + bool WEIGHT_SYMMETRIC, // whether weight matrix is symmetric + bool HAS_BIAS, + QuantizationGranularity Q_GRAN> +FBGEMM_API void trRequantizeOpt( + uint8_t* out, + const int32_t* inp, + const block_type_t& block, + int ld_out, + int ld_in, + const trRequantizationParams_t& rParams); +} // namespace fbgemm + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/args.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/args.h new file mode 100644 index 0000000000000000000000000000000000000000..33309f51f704da42ec73074839969d2ef578da17 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/args.h @@ -0,0 +1,225 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - dynamic argument lists +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_ARGS_H_ +#define FMT_ARGS_H_ + +#ifndef FMT_MODULE +# include // std::reference_wrapper +# include // std::unique_ptr +# include +#endif + +#include "format.h" // std_string_view + +FMT_BEGIN_NAMESPACE +namespace detail { + +template struct is_reference_wrapper : std::false_type {}; +template +struct is_reference_wrapper> : std::true_type {}; + +template auto unwrap(const T& v) -> const T& { return v; } +template +auto unwrap(const std::reference_wrapper& v) -> const T& { + return static_cast(v); +} + +// node is defined outside dynamic_arg_list to workaround a C2504 bug in MSVC +// 2022 (v17.10.0). +// +// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for +// templates it doesn't complain about inability to deduce single translation +// unit for placing vtable. So node is made a fake template. +template struct node { + virtual ~node() = default; + std::unique_ptr> next; +}; + +class dynamic_arg_list { + template struct typed_node : node<> { + T value; + + template + FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {} + + template + FMT_CONSTEXPR typed_node(const basic_string_view& arg) + : value(arg.data(), arg.size()) {} + }; + + std::unique_ptr> head_; + + public: + template auto push(const Arg& arg) -> const T& { + auto new_node = std::unique_ptr>(new typed_node(arg)); + auto& value = new_node->value; + new_node->next = std::move(head_); + head_ = std::move(new_node); + return value; + } +}; +} // namespace detail + +/** + * A dynamic list of formatting arguments with storage. + * + * It can be implicitly converted into `fmt::basic_format_args` for passing + * into type-erased formatting functions such as `fmt::vformat`. + */ +FMT_EXPORT template class dynamic_format_arg_store { + private: + using char_type = typename Context::char_type; + + template struct need_copy { + static constexpr detail::type mapped_type = + detail::mapped_type_constant::value; + + enum { + value = !(detail::is_reference_wrapper::value || + std::is_same>::value || + std::is_same>::value || + (mapped_type != detail::type::cstring_type && + mapped_type != detail::type::string_type && + mapped_type != detail::type::custom_type)) + }; + }; + + template + using stored_t = conditional_t< + std::is_convertible>::value && + !detail::is_reference_wrapper::value, + std::basic_string, T>; + + // Storage of basic_format_arg must be contiguous. + std::vector> data_; + std::vector> named_info_; + + // Storage of arguments not fitting into basic_format_arg must grow + // without relocation because items in data_ refer to it. + detail::dynamic_arg_list dynamic_args_; + + friend class basic_format_args; + + auto data() const -> const basic_format_arg* { + return named_info_.empty() ? data_.data() : data_.data() + 1; + } + + template void emplace_arg(const T& arg) { + data_.emplace_back(arg); + } + + template + void emplace_arg(const detail::named_arg& arg) { + if (named_info_.empty()) + data_.insert(data_.begin(), basic_format_arg(nullptr, 0)); + data_.emplace_back(detail::unwrap(arg.value)); + auto pop_one = [](std::vector>* data) { + data->pop_back(); + }; + std::unique_ptr>, decltype(pop_one)> + guard{&data_, pop_one}; + named_info_.push_back({arg.name, static_cast(data_.size() - 2u)}); + data_[0] = {named_info_.data(), named_info_.size()}; + guard.release(); + } + + public: + constexpr dynamic_format_arg_store() = default; + + operator basic_format_args() const { + return basic_format_args(data(), static_cast(data_.size()), + !named_info_.empty()); + } + + /** + * Adds an argument into the dynamic store for later passing to a formatting + * function. + * + * Note that custom types and string types (but not string views) are copied + * into the store dynamically allocating memory if necessary. + * + * **Example**: + * + * fmt::dynamic_format_arg_store store; + * store.push_back(42); + * store.push_back("abc"); + * store.push_back(1.5f); + * std::string result = fmt::vformat("{} and {} and {}", store); + */ + template void push_back(const T& arg) { + if (detail::const_check(need_copy::value)) + emplace_arg(dynamic_args_.push>(arg)); + else + emplace_arg(detail::unwrap(arg)); + } + + /** + * Adds a reference to the argument into the dynamic store for later passing + * to a formatting function. + * + * **Example**: + * + * fmt::dynamic_format_arg_store store; + * char band[] = "Rolling Stones"; + * store.push_back(std::cref(band)); + * band[9] = 'c'; // Changing str affects the output. + * std::string result = fmt::vformat("{}", store); + * // result == "Rolling Scones" + */ + template void push_back(std::reference_wrapper arg) { + static_assert( + need_copy::value, + "objects of built-in types and string views are always copied"); + emplace_arg(arg.get()); + } + + /** + * Adds named argument into the dynamic store for later passing to a + * formatting function. `std::reference_wrapper` is supported to avoid + * copying of the argument. The name is always copied into the store. + */ + template + void push_back(const detail::named_arg& arg) { + const char_type* arg_name = + dynamic_args_.push>(arg.name).c_str(); + if (detail::const_check(need_copy::value)) { + emplace_arg( + fmt::arg(arg_name, dynamic_args_.push>(arg.value))); + } else { + emplace_arg(fmt::arg(arg_name, arg.value)); + } + } + + /// Erase all elements from the store. + void clear() { + data_.clear(); + named_info_.clear(); + dynamic_args_ = {}; + } + + /// Reserves space to store at least `new_cap` arguments including + /// `new_cap_named` named arguments. + void reserve(size_t new_cap, size_t new_cap_named) { + FMT_ASSERT(new_cap >= new_cap_named, + "set of arguments includes set of named arguments"); + data_.reserve(new_cap); + named_info_.reserve(new_cap_named); + } + + /// Returns the number of elements in the store. + auto size() const noexcept -> size_t { return data_.size(); } +}; + +FMT_END_NAMESPACE + +#endif // FMT_ARGS_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/base.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/base.h new file mode 100644 index 0000000000000000000000000000000000000000..c72f2fbe80572fc8bb73b04f262ebdbd866c278b --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/base.h @@ -0,0 +1,3015 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - the base API for char/UTF-8 +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_BASE_H_ +#define FMT_BASE_H_ + +#if defined(FMT_IMPORT_STD) && !defined(FMT_MODULE) +# define FMT_MODULE +#endif + +#ifndef FMT_MODULE +# include // CHAR_BIT +# include // FILE +# include // memcmp + +# include // std::enable_if +#endif + +// The fmt library version in the form major * 10000 + minor * 100 + patch. +#define FMT_VERSION 120100 + +// Detect compiler versions. +#if defined(__clang__) && !defined(__ibmxl__) +# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) +#else +# define FMT_CLANG_VERSION 0 +#endif +#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) +# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#else +# define FMT_GCC_VERSION 0 +#endif +#if defined(__ICL) +# define FMT_ICC_VERSION __ICL +#elif defined(__INTEL_COMPILER) +# define FMT_ICC_VERSION __INTEL_COMPILER +#else +# define FMT_ICC_VERSION 0 +#endif +#if defined(_MSC_VER) +# define FMT_MSC_VERSION _MSC_VER +#else +# define FMT_MSC_VERSION 0 +#endif + +// Detect standard library versions. +#ifdef _GLIBCXX_RELEASE +# define FMT_GLIBCXX_RELEASE _GLIBCXX_RELEASE +#else +# define FMT_GLIBCXX_RELEASE 0 +#endif +#ifdef _LIBCPP_VERSION +# define FMT_LIBCPP_VERSION _LIBCPP_VERSION +#else +# define FMT_LIBCPP_VERSION 0 +#endif + +#ifdef _MSVC_LANG +# define FMT_CPLUSPLUS _MSVC_LANG +#else +# define FMT_CPLUSPLUS __cplusplus +#endif + +// Detect __has_*. +#ifdef __has_feature +# define FMT_HAS_FEATURE(x) __has_feature(x) +#else +# define FMT_HAS_FEATURE(x) 0 +#endif +#ifdef __has_include +# define FMT_HAS_INCLUDE(x) __has_include(x) +#else +# define FMT_HAS_INCLUDE(x) 0 +#endif +#ifdef __has_builtin +# define FMT_HAS_BUILTIN(x) __has_builtin(x) +#else +# define FMT_HAS_BUILTIN(x) 0 +#endif +#ifdef __has_cpp_attribute +# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define FMT_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +#define FMT_HAS_CPP14_ATTRIBUTE(attribute) \ + (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute)) + +#define FMT_HAS_CPP17_ATTRIBUTE(attribute) \ + (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute)) + +// Detect C++14 relaxed constexpr. +#ifdef FMT_USE_CONSTEXPR +// Use the provided definition. +#elif FMT_GCC_VERSION >= 702 && FMT_CPLUSPLUS >= 201402L +// GCC only allows constexpr member functions in non-literal types since 7.2: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297. +# define FMT_USE_CONSTEXPR 1 +#elif FMT_ICC_VERSION +# define FMT_USE_CONSTEXPR 0 // https://github.com/fmtlib/fmt/issues/1628 +#elif FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912 +# define FMT_USE_CONSTEXPR 1 +#else +# define FMT_USE_CONSTEXPR 0 +#endif +#if FMT_USE_CONSTEXPR +# define FMT_CONSTEXPR constexpr +#else +# define FMT_CONSTEXPR +#endif + +// Detect consteval, C++20 constexpr extensions and std::is_constant_evaluated. +#ifdef FMT_USE_CONSTEVAL +// Use the provided definition. +#elif !defined(__cpp_lib_is_constant_evaluated) +# define FMT_USE_CONSTEVAL 0 +#elif FMT_CPLUSPLUS < 201709L +# define FMT_USE_CONSTEVAL 0 +#elif FMT_GLIBCXX_RELEASE && FMT_GLIBCXX_RELEASE < 10 +# define FMT_USE_CONSTEVAL 0 +#elif FMT_LIBCPP_VERSION && FMT_LIBCPP_VERSION < 10000 +# define FMT_USE_CONSTEVAL 0 +#elif defined(__apple_build_version__) && __apple_build_version__ < 14000029L +# define FMT_USE_CONSTEVAL 0 // consteval is broken in Apple clang < 14. +#elif FMT_MSC_VERSION && FMT_MSC_VERSION < 1929 +# define FMT_USE_CONSTEVAL 0 // consteval is broken in MSVC VS2019 < 16.10. +#elif defined(__cpp_consteval) +# define FMT_USE_CONSTEVAL 1 +#elif FMT_GCC_VERSION >= 1002 || FMT_CLANG_VERSION >= 1101 +# define FMT_USE_CONSTEVAL 1 +#else +# define FMT_USE_CONSTEVAL 0 +#endif +#if FMT_USE_CONSTEVAL +# define FMT_CONSTEVAL consteval +# define FMT_CONSTEXPR20 constexpr +#else +# define FMT_CONSTEVAL +# define FMT_CONSTEXPR20 +#endif + +// Check if exceptions are disabled. +#ifdef FMT_USE_EXCEPTIONS +// Use the provided definition. +#elif defined(__GNUC__) && !defined(__EXCEPTIONS) +# define FMT_USE_EXCEPTIONS 0 +#elif defined(__clang__) && !defined(__cpp_exceptions) +# define FMT_USE_EXCEPTIONS 0 +#elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS +# define FMT_USE_EXCEPTIONS 0 +#else +# define FMT_USE_EXCEPTIONS 1 +#endif +#if FMT_USE_EXCEPTIONS +# define FMT_TRY try +# define FMT_CATCH(x) catch (x) +#else +# define FMT_TRY if (true) +# define FMT_CATCH(x) if (false) +#endif + +#ifdef FMT_NO_UNIQUE_ADDRESS +// Use the provided definition. +#elif FMT_CPLUSPLUS < 202002L +// Not supported. +#elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address) +# define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]] +// VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485). +#elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION +# define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] +#endif +#ifndef FMT_NO_UNIQUE_ADDRESS +# define FMT_NO_UNIQUE_ADDRESS +#endif + +#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough) +# define FMT_FALLTHROUGH [[fallthrough]] +#elif defined(__clang__) +# define FMT_FALLTHROUGH [[clang::fallthrough]] +#elif FMT_GCC_VERSION >= 700 && \ + (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520) +# define FMT_FALLTHROUGH [[gnu::fallthrough]] +#else +# define FMT_FALLTHROUGH +#endif + +// Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings. +#if FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && !defined(__NVCC__) +# define FMT_NORETURN [[noreturn]] +#else +# define FMT_NORETURN +#endif + +#ifdef FMT_NODISCARD +// Use the provided definition. +#elif FMT_HAS_CPP17_ATTRIBUTE(nodiscard) +# define FMT_NODISCARD [[nodiscard]] +#else +# define FMT_NODISCARD +#endif + +#if FMT_GCC_VERSION || FMT_CLANG_VERSION +# define FMT_VISIBILITY(value) __attribute__((visibility(value))) +#else +# define FMT_VISIBILITY(value) +#endif + +// Detect pragmas. +#define FMT_PRAGMA_IMPL(x) _Pragma(#x) +#if FMT_GCC_VERSION >= 504 && !defined(__NVCOMPILER) +// Workaround a _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884 +// and an nvhpc warning: https://github.com/fmtlib/fmt/pull/2582. +# define FMT_PRAGMA_GCC(x) FMT_PRAGMA_IMPL(GCC x) +#else +# define FMT_PRAGMA_GCC(x) +#endif +#if FMT_CLANG_VERSION +# define FMT_PRAGMA_CLANG(x) FMT_PRAGMA_IMPL(clang x) +#else +# define FMT_PRAGMA_CLANG(x) +#endif +#if FMT_MSC_VERSION +# define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__)) +#else +# define FMT_MSC_WARNING(...) +#endif + +// Enable minimal optimizations for more compact code in debug mode. +FMT_PRAGMA_GCC(push_options) +#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE) +FMT_PRAGMA_GCC(optimize("Og")) +# define FMT_GCC_OPTIMIZED +#endif +FMT_PRAGMA_CLANG(diagnostic push) +FMT_PRAGMA_GCC(diagnostic push) + +#ifdef FMT_ALWAYS_INLINE +// Use the provided definition. +#elif FMT_GCC_VERSION || FMT_CLANG_VERSION +# define FMT_ALWAYS_INLINE inline __attribute__((always_inline)) +#else +# define FMT_ALWAYS_INLINE inline +#endif +// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode. +#if defined(NDEBUG) || defined(FMT_GCC_OPTIMIZED) +# define FMT_INLINE FMT_ALWAYS_INLINE +#else +# define FMT_INLINE inline +#endif + +#ifndef FMT_BEGIN_NAMESPACE +# define FMT_BEGIN_NAMESPACE \ + namespace fmt { \ + inline namespace v12 { +# define FMT_END_NAMESPACE \ + } \ + } +#endif + +#ifndef FMT_EXPORT +# define FMT_EXPORT +# define FMT_BEGIN_EXPORT +# define FMT_END_EXPORT +#endif + +#ifdef _WIN32 +# define FMT_WIN32 1 +#else +# define FMT_WIN32 0 +#endif + +#if !defined(FMT_HEADER_ONLY) && FMT_WIN32 +# if defined(FMT_LIB_EXPORT) +# define FMT_API __declspec(dllexport) +# elif defined(FMT_SHARED) +# define FMT_API __declspec(dllimport) +# endif +#elif defined(FMT_LIB_EXPORT) || defined(FMT_SHARED) +# define FMT_API FMT_VISIBILITY("default") +#endif +#ifndef FMT_API +# define FMT_API +#endif + +#ifndef FMT_OPTIMIZE_SIZE +# define FMT_OPTIMIZE_SIZE 0 +#endif + +// FMT_BUILTIN_TYPE=0 may result in smaller library size at the cost of higher +// per-call binary size by passing built-in types through the extension API. +#ifndef FMT_BUILTIN_TYPES +# define FMT_BUILTIN_TYPES 1 +#endif + +#define FMT_APPLY_VARIADIC(expr) \ + using unused = int[]; \ + (void)unused { 0, (expr, 0)... } + +FMT_BEGIN_NAMESPACE + +// Implementations of enable_if_t and other metafunctions for older systems. +template +using enable_if_t = typename std::enable_if::type; +template +using conditional_t = typename std::conditional::type; +template using bool_constant = std::integral_constant; +template +using remove_reference_t = typename std::remove_reference::type; +template +using remove_const_t = typename std::remove_const::type; +template +using remove_cvref_t = typename std::remove_cv>::type; +template +using make_unsigned_t = typename std::make_unsigned::type; +template +using underlying_t = typename std::underlying_type::type; +template using decay_t = typename std::decay::type; +using nullptr_t = decltype(nullptr); + +#if (FMT_GCC_VERSION && FMT_GCC_VERSION < 500) || FMT_MSC_VERSION +// A workaround for gcc 4.9 & MSVC v141 to make void_t work in a SFINAE context. +template struct void_t_impl { + using type = void; +}; +template using void_t = typename void_t_impl::type; +#else +template using void_t = void; +#endif + +struct monostate { + constexpr monostate() {} +}; + +// An enable_if helper to be used in template parameters which results in much +// shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed +// to workaround a bug in MSVC 2019 (see #1140 and #1186). +#ifdef FMT_DOC +# define FMT_ENABLE_IF(...) +#else +# define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0 +#endif + +template constexpr auto min_of(T a, T b) -> T { + return a < b ? a : b; +} +template constexpr auto max_of(T a, T b) -> T { + return a > b ? a : b; +} + +FMT_NORETURN FMT_API void assert_fail(const char* file, int line, + const char* message); + +namespace detail { +// Suppresses "unused variable" warnings with the method described in +// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/. +// (void)var does not work on many Intel compilers. +template FMT_CONSTEXPR void ignore_unused(const T&...) {} + +constexpr auto is_constant_evaluated(bool default_value = false) noexcept + -> bool { +// Workaround for incompatibility between clang 14 and libstdc++ consteval-based +// std::is_constant_evaluated: https://github.com/fmtlib/fmt/issues/3247. +#if FMT_CPLUSPLUS >= 202002L && FMT_GLIBCXX_RELEASE >= 12 && \ + (FMT_CLANG_VERSION >= 1400 && FMT_CLANG_VERSION < 1500) + ignore_unused(default_value); + return __builtin_is_constant_evaluated(); +#elif defined(__cpp_lib_is_constant_evaluated) + ignore_unused(default_value); + return std::is_constant_evaluated(); +#else + return default_value; +#endif +} + +// Suppresses "conditional expression is constant" warnings. +template FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T { + return val; +} + +FMT_NORETURN FMT_API void assert_fail(const char* file, int line, + const char* message); + +#if defined(FMT_ASSERT) +// Use the provided definition. +#elif defined(NDEBUG) +// FMT_ASSERT is not empty to avoid -Wempty-body. +# define FMT_ASSERT(condition, message) \ + fmt::detail::ignore_unused((condition), (message)) +#else +# define FMT_ASSERT(condition, message) \ + ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \ + ? (void)0 \ + : ::fmt::assert_fail(__FILE__, __LINE__, (message))) +#endif + +#ifdef FMT_USE_INT128 +// Use the provided definition. +#elif defined(__SIZEOF_INT128__) && !defined(__NVCC__) && \ + !(FMT_CLANG_VERSION && FMT_MSC_VERSION) +# define FMT_USE_INT128 1 +using int128_opt = __int128_t; // An optional native 128-bit integer. +using uint128_opt = __uint128_t; +inline auto map(int128_opt x) -> int128_opt { return x; } +inline auto map(uint128_opt x) -> uint128_opt { return x; } +#else +# define FMT_USE_INT128 0 +#endif +#if !FMT_USE_INT128 +enum class int128_opt {}; +enum class uint128_opt {}; +// Reduce template instantiations. +inline auto map(int128_opt) -> monostate { return {}; } +inline auto map(uint128_opt) -> monostate { return {}; } +#endif + +#ifdef FMT_USE_BITINT +// Use the provided definition. +#elif FMT_CLANG_VERSION >= 1500 && !defined(__CUDACC__) +# define FMT_USE_BITINT 1 +#else +# define FMT_USE_BITINT 0 +#endif + +#if FMT_USE_BITINT +FMT_PRAGMA_CLANG(diagnostic ignored "-Wbit-int-extension") +template using bitint = _BitInt(N); +template using ubitint = unsigned _BitInt(N); +#else +template struct bitint {}; +template struct ubitint {}; +#endif // FMT_USE_BITINT + +// Casts a nonnegative integer to unsigned. +template +FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t { + FMT_ASSERT(std::is_unsigned::value || value >= 0, "negative value"); + return static_cast>(value); +} + +template +using unsigned_char = conditional_t; + +// A heuristic to detect std::string and std::[experimental::]string_view. +// It is mainly used to avoid dependency on <[experimental/]string_view>. +template +struct is_std_string_like : std::false_type {}; +template +struct is_std_string_like().find_first_of( + typename T::value_type(), 0))>> + : std::is_convertible().data()), + const typename T::value_type*> {}; + +// Check if the literal encoding is UTF-8. +enum { is_utf8_enabled = "\u00A7"[1] == '\xA7' }; +enum { use_utf8 = !FMT_WIN32 || is_utf8_enabled }; + +#ifndef FMT_UNICODE +# define FMT_UNICODE 1 +#endif + +static_assert(!FMT_UNICODE || use_utf8, + "Unicode support requires compiling with /utf-8"); + +template constexpr auto narrow(T*) -> char* { return nullptr; } +constexpr FMT_ALWAYS_INLINE auto narrow(const char* s) -> const char* { + return s; +} + +template +FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, size_t n) -> int { + if (!is_constant_evaluated() && sizeof(Char) == 1) return memcmp(s1, s2, n); + for (; n != 0; ++s1, ++s2, --n) { + if (*s1 < *s2) return -1; + if (*s1 > *s2) return 1; + } + return 0; +} + +namespace adl { +using namespace std; + +template +auto invoke_back_inserter() + -> decltype(back_inserter(std::declval())); +} // namespace adl + +template +struct is_back_insert_iterator : std::false_type {}; + +template +struct is_back_insert_iterator< + It, bool_constant()), + It>::value>> : std::true_type {}; + +// Extracts a reference to the container from *insert_iterator. +template +inline FMT_CONSTEXPR20 auto get_container(OutputIt it) -> + typename OutputIt::container_type& { + struct accessor : OutputIt { + FMT_CONSTEXPR20 accessor(OutputIt base) : OutputIt(base) {} + using OutputIt::container; + }; + return *accessor(it).container; +} +} // namespace detail + +// Parsing-related public API and forward declarations. +FMT_BEGIN_EXPORT + +/** + * An implementation of `std::basic_string_view` for pre-C++17. It provides a + * subset of the API. `fmt::basic_string_view` is used for format strings even + * if `std::basic_string_view` is available to prevent issues when a library is + * compiled with a different `-std` option than the client code (which is not + * recommended). + */ +template class basic_string_view { + private: + const Char* data_; + size_t size_; + + public: + using value_type = Char; + using iterator = const Char*; + + constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {} + + /// Constructs a string view object from a C string and a size. + constexpr basic_string_view(const Char* s, size_t count) noexcept + : data_(s), size_(count) {} + + constexpr basic_string_view(nullptr_t) = delete; + + /// Constructs a string view object from a C string. +#if FMT_GCC_VERSION + FMT_ALWAYS_INLINE +#endif + FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) { +#if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION + if (std::is_same::value && !detail::is_constant_evaluated()) { + size_ = __builtin_strlen(detail::narrow(s)); // strlen is not constexpr. + return; + } +#endif + size_t len = 0; + while (*s++) ++len; + size_ = len; + } + + /// Constructs a string view from a `std::basic_string` or a + /// `std::basic_string_view` object. + template ::value&& std::is_same< + typename S::value_type, Char>::value)> + FMT_CONSTEXPR basic_string_view(const S& s) noexcept + : data_(s.data()), size_(s.size()) {} + + /// Returns a pointer to the string data. + constexpr auto data() const noexcept -> const Char* { return data_; } + + /// Returns the string size. + constexpr auto size() const noexcept -> size_t { return size_; } + + constexpr auto begin() const noexcept -> iterator { return data_; } + constexpr auto end() const noexcept -> iterator { return data_ + size_; } + + constexpr auto operator[](size_t pos) const noexcept -> const Char& { + return data_[pos]; + } + + FMT_CONSTEXPR void remove_prefix(size_t n) noexcept { + data_ += n; + size_ -= n; + } + + FMT_CONSTEXPR auto starts_with(basic_string_view sv) const noexcept + -> bool { + return size_ >= sv.size_ && detail::compare(data_, sv.data_, sv.size_) == 0; + } + FMT_CONSTEXPR auto starts_with(Char c) const noexcept -> bool { + return size_ >= 1 && *data_ == c; + } + FMT_CONSTEXPR auto starts_with(const Char* s) const -> bool { + return starts_with(basic_string_view(s)); + } + + FMT_CONSTEXPR auto compare(basic_string_view other) const -> int { + int result = + detail::compare(data_, other.data_, min_of(size_, other.size_)); + if (result != 0) return result; + return size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); + } + + FMT_CONSTEXPR friend auto operator==(basic_string_view lhs, + basic_string_view rhs) -> bool { + return lhs.compare(rhs) == 0; + } + friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) != 0; + } + friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) < 0; + } + friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) <= 0; + } + friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) > 0; + } + friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool { + return lhs.compare(rhs) >= 0; + } +}; + +using string_view = basic_string_view; + +template class basic_appender; +using appender = basic_appender; + +// Checks whether T is a container with contiguous storage. +template struct is_contiguous : std::false_type {}; + +class context; +template class generic_context; +template class parse_context; + +// Longer aliases for C++20 compatibility. +template using basic_format_parse_context = parse_context; +using format_parse_context = parse_context; +template +using basic_format_context = + conditional_t::value, context, + generic_context>; +using format_context = context; + +template +using buffered_context = + conditional_t::value, context, + generic_context, Char>>; + +template class basic_format_arg; +template class basic_format_args; + +// A separate type would result in shorter symbols but break ABI compatibility +// between clang and gcc on ARM (#1919). +using format_args = basic_format_args; + +// A formatter for objects of type T. +template +struct formatter { + // A deleted default constructor indicates a disabled formatter. + formatter() = delete; +}; + +/// Reports a format error at compile time or, via a `format_error` exception, +/// at runtime. +// This function is intentionally not constexpr to give a compile-time error. +FMT_NORETURN FMT_API void report_error(const char* message); + +enum class presentation_type : unsigned char { + // Common specifiers: + none = 0, + debug = 1, // '?' + string = 2, // 's' (string, bool) + + // Integral, bool and character specifiers: + dec = 3, // 'd' + hex, // 'x' or 'X' + oct, // 'o' + bin, // 'b' or 'B' + chr, // 'c' + + // String and pointer specifiers: + pointer = 3, // 'p' + + // Floating-point specifiers: + exp = 1, // 'e' or 'E' (1 since there is no FP debug presentation) + fixed, // 'f' or 'F' + general, // 'g' or 'G' + hexfloat // 'a' or 'A' +}; + +enum class align { none, left, right, center, numeric }; +enum class sign { none, minus, plus, space }; +enum class arg_id_kind { none, index, name }; + +// Basic format specifiers for built-in and string types. +class basic_specs { + private: + // Data is arranged as follows: + // + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // |type |align| w | p | s |u|#|L| f | unused | + // +-----+-----+---+---+---+-+-+-+-----+---------------------------+ + // + // w - dynamic width info + // p - dynamic precision info + // s - sign + // u - uppercase (e.g. 'X' for 'x') + // # - alternate form ('#') + // L - localized + // f - fill size + // + // Bitfields are not used because of compiler bugs such as gcc bug 61414. + enum : unsigned { + type_mask = 0x00007, + align_mask = 0x00038, + width_mask = 0x000C0, + precision_mask = 0x00300, + sign_mask = 0x00C00, + uppercase_mask = 0x01000, + alternate_mask = 0x02000, + localized_mask = 0x04000, + fill_size_mask = 0x38000, + + align_shift = 3, + width_shift = 6, + precision_shift = 8, + sign_shift = 10, + fill_size_shift = 15, + + max_fill_size = 4 + }; + + unsigned data_ = 1 << fill_size_shift; + static_assert(sizeof(basic_specs::data_) * CHAR_BIT >= 18, ""); + + // Character (code unit) type is erased to prevent template bloat. + char fill_data_[max_fill_size] = {' '}; + + FMT_CONSTEXPR void set_fill_size(size_t size) { + data_ = (data_ & ~fill_size_mask) | + (static_cast(size) << fill_size_shift); + } + + public: + constexpr auto type() const -> presentation_type { + return static_cast(data_ & type_mask); + } + FMT_CONSTEXPR void set_type(presentation_type t) { + data_ = (data_ & ~type_mask) | static_cast(t); + } + + constexpr auto align() const -> align { + return static_cast((data_ & align_mask) >> align_shift); + } + FMT_CONSTEXPR void set_align(fmt::align a) { + data_ = (data_ & ~align_mask) | (static_cast(a) << align_shift); + } + + constexpr auto dynamic_width() const -> arg_id_kind { + return static_cast((data_ & width_mask) >> width_shift); + } + FMT_CONSTEXPR void set_dynamic_width(arg_id_kind w) { + data_ = (data_ & ~width_mask) | (static_cast(w) << width_shift); + } + + FMT_CONSTEXPR auto dynamic_precision() const -> arg_id_kind { + return static_cast((data_ & precision_mask) >> + precision_shift); + } + FMT_CONSTEXPR void set_dynamic_precision(arg_id_kind p) { + data_ = (data_ & ~precision_mask) | + (static_cast(p) << precision_shift); + } + + constexpr auto dynamic() const -> bool { + return (data_ & (width_mask | precision_mask)) != 0; + } + + constexpr auto sign() const -> sign { + return static_cast((data_ & sign_mask) >> sign_shift); + } + FMT_CONSTEXPR void set_sign(fmt::sign s) { + data_ = (data_ & ~sign_mask) | (static_cast(s) << sign_shift); + } + + constexpr auto upper() const -> bool { return (data_ & uppercase_mask) != 0; } + FMT_CONSTEXPR void set_upper() { data_ |= uppercase_mask; } + + constexpr auto alt() const -> bool { return (data_ & alternate_mask) != 0; } + FMT_CONSTEXPR void set_alt() { data_ |= alternate_mask; } + FMT_CONSTEXPR void clear_alt() { data_ &= ~alternate_mask; } + + constexpr auto localized() const -> bool { + return (data_ & localized_mask) != 0; + } + FMT_CONSTEXPR void set_localized() { data_ |= localized_mask; } + + constexpr auto fill_size() const -> size_t { + return (data_ & fill_size_mask) >> fill_size_shift; + } + + template ::value)> + constexpr auto fill() const -> const Char* { + return fill_data_; + } + template ::value)> + constexpr auto fill() const -> const Char* { + return nullptr; + } + + template constexpr auto fill_unit() const -> Char { + using uchar = unsigned char; + return static_cast(static_cast(fill_data_[0]) | + (static_cast(fill_data_[1]) << 8) | + (static_cast(fill_data_[2]) << 16)); + } + + FMT_CONSTEXPR void set_fill(char c) { + fill_data_[0] = c; + set_fill_size(1); + } + + template + FMT_CONSTEXPR void set_fill(basic_string_view s) { + auto size = s.size(); + set_fill_size(size); + if (size == 1) { + unsigned uchar = static_cast>(s[0]); + fill_data_[0] = static_cast(uchar); + fill_data_[1] = static_cast(uchar >> 8); + fill_data_[2] = static_cast(uchar >> 16); + return; + } + FMT_ASSERT(size <= max_fill_size, "invalid fill"); + for (size_t i = 0; i < size; ++i) + fill_data_[i & 3] = static_cast(s[i]); + } + + FMT_CONSTEXPR void copy_fill_from(const basic_specs& specs) { + set_fill_size(specs.fill_size()); + for (size_t i = 0; i < max_fill_size; ++i) + fill_data_[i] = specs.fill_data_[i]; + } +}; + +// Format specifiers for built-in and string types. +struct format_specs : basic_specs { + int width; + int precision; + + constexpr format_specs() : width(0), precision(-1) {} +}; + +/** + * Parsing context consisting of a format string range being parsed and an + * argument counter for automatic indexing. + */ +template class parse_context { + private: + basic_string_view fmt_; + int next_arg_id_; + + enum { use_constexpr_cast = !FMT_GCC_VERSION || FMT_GCC_VERSION >= 1200 }; + + FMT_CONSTEXPR void do_check_arg_id(int arg_id); + + public: + using char_type = Char; + using iterator = const Char*; + + constexpr explicit parse_context(basic_string_view fmt, + int next_arg_id = 0) + : fmt_(fmt), next_arg_id_(next_arg_id) {} + + /// Returns an iterator to the beginning of the format string range being + /// parsed. + constexpr auto begin() const noexcept -> iterator { return fmt_.begin(); } + + /// Returns an iterator past the end of the format string range being parsed. + constexpr auto end() const noexcept -> iterator { return fmt_.end(); } + + /// Advances the begin iterator to `it`. + FMT_CONSTEXPR void advance_to(iterator it) { + fmt_.remove_prefix(detail::to_unsigned(it - begin())); + } + + /// Reports an error if using the manual argument indexing; otherwise returns + /// the next argument index and switches to the automatic indexing. + FMT_CONSTEXPR auto next_arg_id() -> int { + if (next_arg_id_ < 0) { + report_error("cannot switch from manual to automatic argument indexing"); + return 0; + } + int id = next_arg_id_++; + do_check_arg_id(id); + return id; + } + + /// Reports an error if using the automatic argument indexing; otherwise + /// switches to the manual indexing. + FMT_CONSTEXPR void check_arg_id(int id) { + if (next_arg_id_ > 0) { + report_error("cannot switch from automatic to manual argument indexing"); + return; + } + next_arg_id_ = -1; + do_check_arg_id(id); + } + FMT_CONSTEXPR void check_arg_id(basic_string_view) { + next_arg_id_ = -1; + } + FMT_CONSTEXPR void check_dynamic_spec(int arg_id); +}; + +#ifndef FMT_USE_LOCALE +# define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1) +#endif + +// A type-erased reference to std::locale to avoid the heavy include. +class locale_ref { +#if FMT_USE_LOCALE + private: + const void* locale_; // A type-erased pointer to std::locale. + + public: + constexpr locale_ref() : locale_(nullptr) {} + + template + locale_ref(const Locale& loc) : locale_(&loc) { + // Check if std::isalpha is found via ADL to reduce the chance of misuse. + isalpha('x', loc); + } + + inline explicit operator bool() const noexcept { return locale_ != nullptr; } +#endif // FMT_USE_LOCALE + + public: + template auto get() const -> Locale; +}; + +FMT_END_EXPORT + +namespace detail { + +// Specifies if `T` is a code unit type. +template struct is_code_unit : std::false_type {}; +template <> struct is_code_unit : std::true_type {}; +template <> struct is_code_unit : std::true_type {}; +template <> struct is_code_unit : std::true_type {}; +template <> struct is_code_unit : std::true_type {}; +#ifdef __cpp_char8_t +template <> struct is_code_unit : bool_constant {}; +#endif + +// Constructs fmt::basic_string_view from types implicitly convertible +// to it, deducing Char. Explicitly convertible types such as the ones returned +// from FMT_STRING are intentionally excluded. +template ::value)> +constexpr auto to_string_view(const Char* s) -> basic_string_view { + return s; +} +template ::value)> +constexpr auto to_string_view(const T& s) + -> basic_string_view { + return s; +} +template +constexpr auto to_string_view(basic_string_view s) + -> basic_string_view { + return s; +} + +template +struct has_to_string_view : std::false_type {}; +// detail:: is intentional since to_string_view is not an extension point. +template +struct has_to_string_view< + T, void_t()))>> + : std::true_type {}; + +/// String's character (code unit) type. detail:: is intentional to prevent ADL. +template ()))> +using char_t = typename V::value_type; + +enum class type { + none_type, + // Integer types should go first, + int_type, + uint_type, + long_long_type, + ulong_long_type, + int128_type, + uint128_type, + bool_type, + char_type, + last_integer_type = char_type, + // followed by floating-point types. + float_type, + double_type, + long_double_type, + last_numeric_type = long_double_type, + cstring_type, + string_type, + pointer_type, + custom_type +}; + +// Maps core type T to the corresponding type enum constant. +template +struct type_constant : std::integral_constant {}; + +#define FMT_TYPE_CONSTANT(Type, constant) \ + template \ + struct type_constant \ + : std::integral_constant {} + +FMT_TYPE_CONSTANT(int, int_type); +FMT_TYPE_CONSTANT(unsigned, uint_type); +FMT_TYPE_CONSTANT(long long, long_long_type); +FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type); +FMT_TYPE_CONSTANT(int128_opt, int128_type); +FMT_TYPE_CONSTANT(uint128_opt, uint128_type); +FMT_TYPE_CONSTANT(bool, bool_type); +FMT_TYPE_CONSTANT(Char, char_type); +FMT_TYPE_CONSTANT(float, float_type); +FMT_TYPE_CONSTANT(double, double_type); +FMT_TYPE_CONSTANT(long double, long_double_type); +FMT_TYPE_CONSTANT(const Char*, cstring_type); +FMT_TYPE_CONSTANT(basic_string_view, string_type); +FMT_TYPE_CONSTANT(const void*, pointer_type); + +constexpr auto is_integral_type(type t) -> bool { + return t > type::none_type && t <= type::last_integer_type; +} +constexpr auto is_arithmetic_type(type t) -> bool { + return t > type::none_type && t <= type::last_numeric_type; +} + +constexpr auto set(type rhs) -> int { return 1 << static_cast(rhs); } +constexpr auto in(type t, int set) -> bool { + return ((set >> static_cast(t)) & 1) != 0; +} + +// Bitsets of types. +enum { + sint_set = + set(type::int_type) | set(type::long_long_type) | set(type::int128_type), + uint_set = set(type::uint_type) | set(type::ulong_long_type) | + set(type::uint128_type), + bool_set = set(type::bool_type), + char_set = set(type::char_type), + float_set = set(type::float_type) | set(type::double_type) | + set(type::long_double_type), + string_set = set(type::string_type), + cstring_set = set(type::cstring_type), + pointer_set = set(type::pointer_type) +}; + +struct view {}; + +template +struct is_view : std::false_type {}; +template +struct is_view> : std::is_base_of {}; + +template struct named_arg; +template struct is_named_arg : std::false_type {}; +template struct is_static_named_arg : std::false_type {}; + +template +struct is_named_arg> : std::true_type {}; + +template struct named_arg : view { + const Char* name; + const T& value; + + named_arg(const Char* n, const T& v) : name(n), value(v) {} + static_assert(!is_named_arg::value, "nested named arguments"); +}; + +template constexpr auto count() -> int { return B ? 1 : 0; } +template constexpr auto count() -> int { + return (B1 ? 1 : 0) + count(); +} + +template constexpr auto count_named_args() -> int { + return count::value...>(); +} +template constexpr auto count_static_named_args() -> int { + return count::value...>(); +} + +template struct named_arg_info { + const Char* name; + int id; +}; + +// named_args is non-const to suppress a bogus -Wmaybe-uninitialized in gcc 13. +template +FMT_CONSTEXPR void check_for_duplicate(named_arg_info* named_args, + int named_arg_index, + basic_string_view arg_name) { + for (int i = 0; i < named_arg_index; ++i) { + if (named_args[i].name == arg_name) report_error("duplicate named arg"); + } +} + +template ::value)> +void init_named_arg(named_arg_info*, int& arg_index, int&, const T&) { + ++arg_index; +} +template ::value)> +void init_named_arg(named_arg_info* named_args, int& arg_index, + int& named_arg_index, const T& arg) { + check_for_duplicate(named_args, named_arg_index, arg.name); + named_args[named_arg_index++] = {arg.name, arg_index++}; +} + +template ::value)> +FMT_CONSTEXPR void init_static_named_arg(named_arg_info*, int& arg_index, + int&) { + ++arg_index; +} +template ::value)> +FMT_CONSTEXPR void init_static_named_arg(named_arg_info* named_args, + int& arg_index, int& named_arg_index) { + check_for_duplicate(named_args, named_arg_index, T::name); + named_args[named_arg_index++] = {T::name, arg_index++}; +} + +// To minimize the number of types we need to deal with, long is translated +// either to int or to long long depending on its size. +enum { long_short = sizeof(long) == sizeof(int) && FMT_BUILTIN_TYPES }; +using long_type = conditional_t; +using ulong_type = conditional_t; + +template +using format_as_result = + remove_cvref_t()))>; +template +using format_as_member_result = + remove_cvref_t::format_as(std::declval()))>; + +template +struct use_format_as : std::false_type {}; +// format_as member is only used to avoid injection into the std namespace. +template +struct use_format_as_member : std::false_type {}; + +// Only map owning types because mapping views can be unsafe. +template +struct use_format_as< + T, bool_constant>::value>> + : std::true_type {}; +template +struct use_format_as_member< + T, bool_constant>::value>> + : std::true_type {}; + +template > +using use_formatter = + bool_constant<(std::is_class::value || std::is_enum::value || + std::is_union::value || std::is_array::value) && + !has_to_string_view::value && !is_named_arg::value && + !use_format_as::value && !use_format_as_member::value>; + +template > +auto has_formatter_impl(T* p, buffered_context* ctx = nullptr) + -> decltype(formatter().format(*p, *ctx), std::true_type()); +template auto has_formatter_impl(...) -> std::false_type; + +// T can be const-qualified to check if it is const-formattable. +template constexpr auto has_formatter() -> bool { + return decltype(has_formatter_impl(static_cast(nullptr)))::value; +} + +// Maps formatting argument types to natively supported types or user-defined +// types with formatters. Returns void on errors to be SFINAE-friendly. +template struct type_mapper { + static auto map(signed char) -> int; + static auto map(unsigned char) -> unsigned; + static auto map(short) -> int; + static auto map(unsigned short) -> unsigned; + static auto map(int) -> int; + static auto map(unsigned) -> unsigned; + static auto map(long) -> long_type; + static auto map(unsigned long) -> ulong_type; + static auto map(long long) -> long long; + static auto map(unsigned long long) -> unsigned long long; + static auto map(int128_opt) -> int128_opt; + static auto map(uint128_opt) -> uint128_opt; + static auto map(bool) -> bool; + + template + static auto map(bitint) -> conditional_t; + template + static auto map(ubitint) + -> conditional_t; + + template ::value)> + static auto map(T) -> conditional_t< + std::is_same::value || std::is_same::value, Char, void>; + + static auto map(float) -> float; + static auto map(double) -> double; + static auto map(long double) -> long double; + + static auto map(Char*) -> const Char*; + static auto map(const Char*) -> const Char*; + template , + FMT_ENABLE_IF(!std::is_pointer::value)> + static auto map(const T&) -> conditional_t::value, + basic_string_view, void>; + + static auto map(void*) -> const void*; + static auto map(const void*) -> const void*; + static auto map(volatile void*) -> const void*; + static auto map(const volatile void*) -> const void*; + static auto map(nullptr_t) -> const void*; + template ::value || + std::is_member_pointer::value)> + static auto map(const T&) -> void; + + template ::value)> + static auto map(const T& x) -> decltype(map(format_as(x))); + template ::value)> + static auto map(const T& x) -> decltype(map(formatter::format_as(x))); + + template ::value)> + static auto map(T&) -> conditional_t(), T&, void>; + + template ::value)> + static auto map(const T& named_arg) -> decltype(map(named_arg.value)); +}; + +// detail:: is used to workaround a bug in MSVC 2017. +template +using mapped_t = decltype(detail::type_mapper::map(std::declval())); + +// A type constant after applying type_mapper. +template +using mapped_type_constant = type_constant, Char>; + +template ::value> +using stored_type_constant = std::integral_constant< + type, Context::builtin_types || TYPE == type::int_type ? TYPE + : type::custom_type>; +// A parse context with extra data used only in compile-time checks. +template +class compile_parse_context : public parse_context { + private: + int num_args_; + const type* types_; + using base = parse_context; + + public: + FMT_CONSTEXPR explicit compile_parse_context(basic_string_view fmt, + int num_args, const type* types, + int next_arg_id = 0) + : base(fmt, next_arg_id), num_args_(num_args), types_(types) {} + + constexpr auto num_args() const -> int { return num_args_; } + constexpr auto arg_type(int id) const -> type { return types_[id]; } + + FMT_CONSTEXPR auto next_arg_id() -> int { + int id = base::next_arg_id(); + if (id >= num_args_) report_error("argument not found"); + return id; + } + + FMT_CONSTEXPR void check_arg_id(int id) { + base::check_arg_id(id); + if (id >= num_args_) report_error("argument not found"); + } + using base::check_arg_id; + + FMT_CONSTEXPR void check_dynamic_spec(int arg_id) { + ignore_unused(arg_id); + if (arg_id < num_args_ && types_ && !is_integral_type(types_[arg_id])) + report_error("width/precision is not integer"); + } +}; + +// An argument reference. +template union arg_ref { + FMT_CONSTEXPR arg_ref(int idx = 0) : index(idx) {} + FMT_CONSTEXPR arg_ref(basic_string_view n) : name(n) {} + + int index; + basic_string_view name; +}; + +// Format specifiers with width and precision resolved at formatting rather +// than parsing time to allow reusing the same parsed specifiers with +// different sets of arguments (precompilation of format strings). +template struct dynamic_format_specs : format_specs { + arg_ref width_ref; + arg_ref precision_ref; +}; + +// Converts a character to ASCII. Returns '\0' on conversion failure. +template ::value)> +constexpr auto to_ascii(Char c) -> char { + return c <= 0xff ? static_cast(c) : '\0'; +} + +// Returns the number of code units in a code point or 1 on error. +template +FMT_CONSTEXPR auto code_point_length(const Char* begin) -> int { + if (const_check(sizeof(Char) != 1)) return 1; + auto c = static_cast(*begin); + return static_cast((0x3a55000000000000ull >> (2 * (c >> 3))) & 3) + 1; +} + +// Parses the range [begin, end) as an unsigned integer. This function assumes +// that the range is non-empty and the first character is a digit. +template +FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end, + int error_value) noexcept -> int { + FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', ""); + unsigned value = 0, prev = 0; + auto p = begin; + do { + prev = value; + value = value * 10 + unsigned(*p - '0'); + ++p; + } while (p != end && '0' <= *p && *p <= '9'); + auto num_digits = p - begin; + begin = p; + int digits10 = static_cast(sizeof(int) * CHAR_BIT * 3 / 10); + if (num_digits <= digits10) return static_cast(value); + // Check for overflow. + unsigned max = INT_MAX; + return num_digits == digits10 + 1 && + prev * 10ull + unsigned(p[-1] - '0') <= max + ? static_cast(value) + : error_value; +} + +FMT_CONSTEXPR inline auto parse_align(char c) -> align { + switch (c) { + case '<': return align::left; + case '>': return align::right; + case '^': return align::center; + } + return align::none; +} + +template constexpr auto is_name_start(Char c) -> bool { + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '_'; +} + +template +FMT_CONSTEXPR auto parse_arg_id(const Char* begin, const Char* end, + Handler&& handler) -> const Char* { + Char c = *begin; + if (c >= '0' && c <= '9') { + int index = 0; + if (c != '0') + index = parse_nonnegative_int(begin, end, INT_MAX); + else + ++begin; + if (begin == end || (*begin != '}' && *begin != ':')) + report_error("invalid format string"); + else + handler.on_index(index); + return begin; + } + if (FMT_OPTIMIZE_SIZE > 1 || !is_name_start(c)) { + report_error("invalid format string"); + return begin; + } + auto it = begin; + do { + ++it; + } while (it != end && (is_name_start(*it) || ('0' <= *it && *it <= '9'))); + handler.on_name({begin, to_unsigned(it - begin)}); + return it; +} + +template struct dynamic_spec_handler { + parse_context& ctx; + arg_ref& ref; + arg_id_kind& kind; + + FMT_CONSTEXPR void on_index(int id) { + ref = id; + kind = arg_id_kind::index; + ctx.check_arg_id(id); + ctx.check_dynamic_spec(id); + } + FMT_CONSTEXPR void on_name(basic_string_view id) { + ref = id; + kind = arg_id_kind::name; + ctx.check_arg_id(id); + } +}; + +template struct parse_dynamic_spec_result { + const Char* end; + arg_id_kind kind; +}; + +// Parses integer | "{" [arg_id] "}". +template +FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end, + int& value, arg_ref& ref, + parse_context& ctx) + -> parse_dynamic_spec_result { + FMT_ASSERT(begin != end, ""); + auto kind = arg_id_kind::none; + if ('0' <= *begin && *begin <= '9') { + int val = parse_nonnegative_int(begin, end, -1); + if (val == -1) report_error("number is too big"); + value = val; + } else { + if (*begin == '{') { + ++begin; + if (begin != end) { + Char c = *begin; + if (c == '}' || c == ':') { + int id = ctx.next_arg_id(); + ref = id; + kind = arg_id_kind::index; + ctx.check_dynamic_spec(id); + } else { + begin = parse_arg_id(begin, end, + dynamic_spec_handler{ctx, ref, kind}); + } + } + if (begin != end && *begin == '}') return {++begin, kind}; + } + report_error("invalid format string"); + } + return {begin, kind}; +} + +template +FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end, + format_specs& specs, arg_ref& width_ref, + parse_context& ctx) -> const Char* { + auto result = parse_dynamic_spec(begin, end, specs.width, width_ref, ctx); + specs.set_dynamic_width(result.kind); + return result.end; +} + +template +FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end, + format_specs& specs, + arg_ref& precision_ref, + parse_context& ctx) -> const Char* { + ++begin; + if (begin == end) { + report_error("invalid precision"); + return begin; + } + auto result = + parse_dynamic_spec(begin, end, specs.precision, precision_ref, ctx); + specs.set_dynamic_precision(result.kind); + return result.end; +} + +enum class state { start, align, sign, hash, zero, width, precision, locale }; + +// Parses standard format specifiers. +template +FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end, + dynamic_format_specs& specs, + parse_context& ctx, type arg_type) + -> const Char* { + auto c = '\0'; + if (end - begin > 1) { + auto next = to_ascii(begin[1]); + c = parse_align(next) == align::none ? to_ascii(*begin) : '\0'; + } else { + if (begin == end) return begin; + c = to_ascii(*begin); + } + + struct { + state current_state = state::start; + FMT_CONSTEXPR void operator()(state s, bool valid = true) { + if (current_state >= s || !valid) + report_error("invalid format specifier"); + current_state = s; + } + } enter_state; + + using pres = presentation_type; + constexpr auto integral_set = sint_set | uint_set | bool_set | char_set; + struct { + const Char*& begin; + format_specs& specs; + type arg_type; + + FMT_CONSTEXPR auto operator()(pres pres_type, int set) -> const Char* { + if (!in(arg_type, set)) report_error("invalid format specifier"); + specs.set_type(pres_type); + return begin + 1; + } + } parse_presentation_type{begin, specs, arg_type}; + + for (;;) { + switch (c) { + case '<': + case '>': + case '^': + enter_state(state::align); + specs.set_align(parse_align(c)); + ++begin; + break; + case '+': + case ' ': + specs.set_sign(c == ' ' ? sign::space : sign::plus); + FMT_FALLTHROUGH; + case '-': + enter_state(state::sign, in(arg_type, sint_set | float_set)); + ++begin; + break; + case '#': + enter_state(state::hash, is_arithmetic_type(arg_type)); + specs.set_alt(); + ++begin; + break; + case '0': + enter_state(state::zero); + if (!is_arithmetic_type(arg_type)) + report_error("format specifier requires numeric argument"); + if (specs.align() == align::none) { + // Ignore 0 if align is specified for compatibility with std::format. + specs.set_align(align::numeric); + specs.set_fill('0'); + } + ++begin; + break; + // clang-format off + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '{': + // clang-format on + enter_state(state::width); + begin = parse_width(begin, end, specs, specs.width_ref, ctx); + break; + case '.': + enter_state(state::precision, + in(arg_type, float_set | string_set | cstring_set)); + begin = parse_precision(begin, end, specs, specs.precision_ref, ctx); + break; + case 'L': + enter_state(state::locale, is_arithmetic_type(arg_type)); + specs.set_localized(); + ++begin; + break; + case 'd': return parse_presentation_type(pres::dec, integral_set); + case 'X': specs.set_upper(); FMT_FALLTHROUGH; + case 'x': return parse_presentation_type(pres::hex, integral_set); + case 'o': return parse_presentation_type(pres::oct, integral_set); + case 'B': specs.set_upper(); FMT_FALLTHROUGH; + case 'b': return parse_presentation_type(pres::bin, integral_set); + case 'E': specs.set_upper(); FMT_FALLTHROUGH; + case 'e': return parse_presentation_type(pres::exp, float_set); + case 'F': specs.set_upper(); FMT_FALLTHROUGH; + case 'f': return parse_presentation_type(pres::fixed, float_set); + case 'G': specs.set_upper(); FMT_FALLTHROUGH; + case 'g': return parse_presentation_type(pres::general, float_set); + case 'A': specs.set_upper(); FMT_FALLTHROUGH; + case 'a': return parse_presentation_type(pres::hexfloat, float_set); + case 'c': + if (arg_type == type::bool_type) report_error("invalid format specifier"); + return parse_presentation_type(pres::chr, integral_set); + case 's': + return parse_presentation_type(pres::string, + bool_set | string_set | cstring_set); + case 'p': + return parse_presentation_type(pres::pointer, pointer_set | cstring_set); + case '?': + return parse_presentation_type(pres::debug, + char_set | string_set | cstring_set); + case '}': return begin; + default: { + if (*begin == '}') return begin; + // Parse fill and alignment. + auto fill_end = begin + code_point_length(begin); + if (end - fill_end <= 0) { + report_error("invalid format specifier"); + return begin; + } + if (*begin == '{') { + report_error("invalid fill character '{'"); + return begin; + } + auto alignment = parse_align(to_ascii(*fill_end)); + enter_state(state::align, alignment != align::none); + specs.set_fill( + basic_string_view(begin, to_unsigned(fill_end - begin))); + specs.set_align(alignment); + begin = fill_end + 1; + } + } + if (begin == end) return begin; + c = to_ascii(*begin); + } +} + +template +FMT_CONSTEXPR FMT_INLINE auto parse_replacement_field(const Char* begin, + const Char* end, + Handler&& handler) + -> const Char* { + ++begin; + if (begin == end) { + handler.on_error("invalid format string"); + return end; + } + int arg_id = 0; + switch (*begin) { + case '}': + handler.on_replacement_field(handler.on_arg_id(), begin); + return begin + 1; + case '{': handler.on_text(begin, begin + 1); return begin + 1; + case ':': arg_id = handler.on_arg_id(); break; + default: { + struct id_adapter { + Handler& handler; + int arg_id; + + FMT_CONSTEXPR void on_index(int id) { arg_id = handler.on_arg_id(id); } + FMT_CONSTEXPR void on_name(basic_string_view id) { + arg_id = handler.on_arg_id(id); + } + } adapter = {handler, 0}; + begin = parse_arg_id(begin, end, adapter); + arg_id = adapter.arg_id; + Char c = begin != end ? *begin : Char(); + if (c == '}') { + handler.on_replacement_field(arg_id, begin); + return begin + 1; + } + if (c != ':') { + handler.on_error("missing '}' in format string"); + return end; + } + break; + } + } + begin = handler.on_format_specs(arg_id, begin + 1, end); + if (begin == end || *begin != '}') + return handler.on_error("unknown format specifier"), end; + return begin + 1; +} + +template +FMT_CONSTEXPR void parse_format_string(basic_string_view fmt, + Handler&& handler) { + auto begin = fmt.data(), end = begin + fmt.size(); + auto p = begin; + while (p != end) { + auto c = *p++; + if (c == '{') { + handler.on_text(begin, p - 1); + begin = p = parse_replacement_field(p - 1, end, handler); + } else if (c == '}') { + if (p == end || *p != '}') + return handler.on_error("unmatched '}' in format string"); + handler.on_text(begin, p); + begin = ++p; + } + } + handler.on_text(begin, end); +} + +// Checks char specs and returns true iff the presentation type is char-like. +FMT_CONSTEXPR inline auto check_char_specs(const format_specs& specs) -> bool { + auto type = specs.type(); + if (type != presentation_type::none && type != presentation_type::chr && + type != presentation_type::debug) { + return false; + } + if (specs.align() == align::numeric || specs.sign() != sign::none || + specs.alt()) { + report_error("invalid format specifier for char"); + } + return true; +} + +// A base class for compile-time strings. +struct compile_string {}; + +template +FMT_VISIBILITY("hidden") // Suppress an ld warning on macOS (#3769). +FMT_CONSTEXPR auto invoke_parse(parse_context& ctx) -> const Char* { + using mapped_type = remove_cvref_t>; + constexpr bool formattable = + std::is_constructible>::value; + if (!formattable) return ctx.begin(); // Error is reported in the value ctor. + using formatted_type = conditional_t; + return formatter().parse(ctx); +} + +template struct arg_pack {}; + +template +class format_string_checker { + private: + type types_[max_of(1, NUM_ARGS)]; + named_arg_info named_args_[max_of(1, NUM_NAMED_ARGS)]; + compile_parse_context context_; + + using parse_func = auto (*)(parse_context&) -> const Char*; + parse_func parse_funcs_[max_of(1, NUM_ARGS)]; + + public: + template + FMT_CONSTEXPR explicit format_string_checker(basic_string_view fmt, + arg_pack) + : types_{mapped_type_constant::value...}, + named_args_{}, + context_(fmt, NUM_ARGS, types_), + parse_funcs_{&invoke_parse...} { + int arg_index = 0, named_arg_index = 0; + FMT_APPLY_VARIADIC( + init_static_named_arg(named_args_, arg_index, named_arg_index)); + ignore_unused(arg_index, named_arg_index); + } + + FMT_CONSTEXPR void on_text(const Char*, const Char*) {} + + FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); } + FMT_CONSTEXPR auto on_arg_id(int id) -> int { + context_.check_arg_id(id); + return id; + } + FMT_CONSTEXPR auto on_arg_id(basic_string_view id) -> int { + for (int i = 0; i < NUM_NAMED_ARGS; ++i) { + if (named_args_[i].name == id) return named_args_[i].id; + } + if (!DYNAMIC_NAMES) on_error("argument not found"); + return -1; + } + + FMT_CONSTEXPR void on_replacement_field(int id, const Char* begin) { + on_format_specs(id, begin, begin); // Call parse() on empty specs. + } + + FMT_CONSTEXPR auto on_format_specs(int id, const Char* begin, const Char* end) + -> const Char* { + context_.advance_to(begin); + if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_); + + // If id is out of range, it means we do not know the type and cannot parse + // the format at compile time. Instead, skip over content until we finish + // the format spec, accounting for any nested replacements. + for (int bracket_count = 0; + begin != end && (bracket_count > 0 || *begin != '}'); ++begin) { + if (*begin == '{') + ++bracket_count; + else if (*begin == '}') + --bracket_count; + } + return begin; + } + + FMT_NORETURN FMT_CONSTEXPR void on_error(const char* message) { + report_error(message); + } +}; + +/// A contiguous memory buffer with an optional growing ability. It is an +/// internal class and shouldn't be used directly, only via `memory_buffer`. +template class buffer { + private: + T* ptr_; + size_t size_; + size_t capacity_; + + using grow_fun = void (*)(buffer& buf, size_t capacity); + grow_fun grow_; + + protected: + // Don't initialize ptr_ since it is not accessed to save a few cycles. + FMT_MSC_WARNING(suppress : 26495) + FMT_CONSTEXPR buffer(grow_fun grow, size_t sz) noexcept + : size_(sz), capacity_(sz), grow_(grow) {} + + constexpr buffer(grow_fun grow, T* p = nullptr, size_t sz = 0, + size_t cap = 0) noexcept + : ptr_(p), size_(sz), capacity_(cap), grow_(grow) {} + + FMT_CONSTEXPR20 ~buffer() = default; + buffer(buffer&&) = default; + + /// Sets the buffer data and capacity. + FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) noexcept { + ptr_ = buf_data; + capacity_ = buf_capacity; + } + + public: + using value_type = T; + using const_reference = const T&; + + buffer(const buffer&) = delete; + void operator=(const buffer&) = delete; + + auto begin() noexcept -> T* { return ptr_; } + auto end() noexcept -> T* { return ptr_ + size_; } + + auto begin() const noexcept -> const T* { return ptr_; } + auto end() const noexcept -> const T* { return ptr_ + size_; } + + /// Returns the size of this buffer. + constexpr auto size() const noexcept -> size_t { return size_; } + + /// Returns the capacity of this buffer. + constexpr auto capacity() const noexcept -> size_t { return capacity_; } + + /// Returns a pointer to the buffer data (not null-terminated). + FMT_CONSTEXPR auto data() noexcept -> T* { return ptr_; } + FMT_CONSTEXPR auto data() const noexcept -> const T* { return ptr_; } + + /// Clears this buffer. + FMT_CONSTEXPR void clear() { size_ = 0; } + + // Tries resizing the buffer to contain `count` elements. If T is a POD type + // the new elements may not be initialized. + FMT_CONSTEXPR void try_resize(size_t count) { + try_reserve(count); + size_ = min_of(count, capacity_); + } + + // Tries increasing the buffer capacity to `new_capacity`. It can increase the + // capacity by a smaller amount than requested but guarantees there is space + // for at least one additional element either by increasing the capacity or by + // flushing the buffer if it is full. + FMT_CONSTEXPR void try_reserve(size_t new_capacity) { + if (new_capacity > capacity_) grow_(*this, new_capacity); + } + + FMT_CONSTEXPR void push_back(const T& value) { + try_reserve(size_ + 1); + ptr_[size_++] = value; + } + + /// Appends data to the end of the buffer. + template +// Workaround for MSVC2019 to fix error C2893: Failed to specialize function +// template 'void fmt::v11::detail::buffer::append(const U *,const U *)'. +#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1940 + FMT_CONSTEXPR20 +#endif + void + append(const U* begin, const U* end) { + while (begin != end) { + auto size = size_; + auto free_cap = capacity_ - size; + auto count = to_unsigned(end - begin); + if (free_cap < count) { + grow_(*this, size + count); + size = size_; + free_cap = capacity_ - size; + count = count < free_cap ? count : free_cap; + } + // A loop is faster than memcpy on small sizes. + T* out = ptr_ + size; + for (size_t i = 0; i < count; ++i) out[i] = begin[i]; + size_ += count; + begin += count; + } + } + + template FMT_CONSTEXPR auto operator[](Idx index) -> T& { + return ptr_[index]; + } + template + FMT_CONSTEXPR auto operator[](Idx index) const -> const T& { + return ptr_[index]; + } +}; + +struct buffer_traits { + constexpr explicit buffer_traits(size_t) {} + constexpr auto count() const -> size_t { return 0; } + constexpr auto limit(size_t size) const -> size_t { return size; } +}; + +class fixed_buffer_traits { + private: + size_t count_ = 0; + size_t limit_; + + public: + constexpr explicit fixed_buffer_traits(size_t limit) : limit_(limit) {} + constexpr auto count() const -> size_t { return count_; } + FMT_CONSTEXPR auto limit(size_t size) -> size_t { + size_t n = limit_ > count_ ? limit_ - count_ : 0; + count_ += size; + return min_of(size, n); + } +}; + +// A buffer that writes to an output iterator when flushed. +template +class iterator_buffer : public Traits, public buffer { + private: + OutputIt out_; + enum { buffer_size = 256 }; + T data_[buffer_size]; + + static FMT_CONSTEXPR void grow(buffer& buf, size_t) { + if (buf.size() == buffer_size) static_cast(buf).flush(); + } + + void flush() { + auto size = this->size(); + this->clear(); + const T* begin = data_; + const T* end = begin + this->limit(size); + while (begin != end) *out_++ = *begin++; + } + + public: + explicit iterator_buffer(OutputIt out, size_t n = buffer_size) + : Traits(n), buffer(grow, data_, 0, buffer_size), out_(out) {} + iterator_buffer(iterator_buffer&& other) noexcept + : Traits(other), + buffer(grow, data_, 0, buffer_size), + out_(other.out_) {} + ~iterator_buffer() { + // Don't crash if flush fails during unwinding. + FMT_TRY { flush(); } + FMT_CATCH(...) {} + } + + auto out() -> OutputIt { + flush(); + return out_; + } + auto count() const -> size_t { return Traits::count() + this->size(); } +}; + +template +class iterator_buffer : public fixed_buffer_traits, + public buffer { + private: + T* out_; + enum { buffer_size = 256 }; + T data_[buffer_size]; + + static FMT_CONSTEXPR void grow(buffer& buf, size_t) { + if (buf.size() == buf.capacity()) + static_cast(buf).flush(); + } + + void flush() { + size_t n = this->limit(this->size()); + if (this->data() == out_) { + out_ += n; + this->set(data_, buffer_size); + } + this->clear(); + } + + public: + explicit iterator_buffer(T* out, size_t n = buffer_size) + : fixed_buffer_traits(n), buffer(grow, out, 0, n), out_(out) {} + iterator_buffer(iterator_buffer&& other) noexcept + : fixed_buffer_traits(other), + buffer(static_cast(other)), + out_(other.out_) { + if (this->data() != out_) { + this->set(data_, buffer_size); + this->clear(); + } + } + ~iterator_buffer() { flush(); } + + auto out() -> T* { + flush(); + return out_; + } + auto count() const -> size_t { + return fixed_buffer_traits::count() + this->size(); + } +}; + +template class iterator_buffer : public buffer { + public: + explicit iterator_buffer(T* out, size_t = 0) + : buffer([](buffer&, size_t) {}, out, 0, ~size_t()) {} + + auto out() -> T* { return &*this->end(); } +}; + +template +class container_buffer : public buffer { + private: + using value_type = typename Container::value_type; + + static FMT_CONSTEXPR void grow(buffer& buf, size_t capacity) { + auto& self = static_cast(buf); + self.container.resize(capacity); + self.set(&self.container[0], capacity); + } + + public: + Container& container; + + explicit container_buffer(Container& c) + : buffer(grow, c.size()), container(c) {} +}; + +// A buffer that writes to a container with the contiguous storage. +template +class iterator_buffer< + OutputIt, + enable_if_t::value && + is_contiguous::value, + typename OutputIt::container_type::value_type>> + : public container_buffer { + private: + using base = container_buffer; + + public: + explicit iterator_buffer(typename OutputIt::container_type& c) : base(c) {} + explicit iterator_buffer(OutputIt out, size_t = 0) + : base(get_container(out)) {} + + auto out() -> OutputIt { return OutputIt(this->container); } +}; + +// A buffer that counts the number of code units written discarding the output. +template class counting_buffer : public buffer { + private: + enum { buffer_size = 256 }; + T data_[buffer_size]; + size_t count_ = 0; + + static FMT_CONSTEXPR void grow(buffer& buf, size_t) { + if (buf.size() != buffer_size) return; + static_cast(buf).count_ += buf.size(); + buf.clear(); + } + + public: + FMT_CONSTEXPR counting_buffer() : buffer(grow, data_, 0, buffer_size) {} + + constexpr auto count() const noexcept -> size_t { + return count_ + this->size(); + } +}; + +template +struct is_back_insert_iterator> : std::true_type {}; + +template +struct has_back_insert_iterator_container_append : std::false_type {}; +template +struct has_back_insert_iterator_container_append< + OutputIt, InputIt, + void_t()) + .append(std::declval(), + std::declval()))>> : std::true_type {}; + +template +struct has_back_insert_iterator_container_insert_at_end : std::false_type {}; + +template +struct has_back_insert_iterator_container_insert_at_end< + OutputIt, InputIt, + void_t()) + .insert(get_container(std::declval()).end(), + std::declval(), + std::declval()))>> : std::true_type {}; + +// An optimized version of std::copy with the output value type (T). +template ::value&& + has_back_insert_iterator_container_append< + OutputIt, InputIt>::value)> +FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out) + -> OutputIt { + get_container(out).append(begin, end); + return out; +} + +template ::value && + !has_back_insert_iterator_container_append< + OutputIt, InputIt>::value && + has_back_insert_iterator_container_insert_at_end< + OutputIt, InputIt>::value)> +FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out) + -> OutputIt { + auto& c = get_container(out); + c.insert(c.end(), begin, end); + return out; +} + +template ::value && + (has_back_insert_iterator_container_append< + OutputIt, InputIt>::value || + has_back_insert_iterator_container_insert_at_end< + OutputIt, InputIt>::value)))> +FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt { + while (begin != end) *out++ = static_cast(*begin++); + return out; +} + +template +FMT_CONSTEXPR auto copy(basic_string_view s, OutputIt out) -> OutputIt { + return copy(s.begin(), s.end(), out); +} + +template +struct is_buffer_appender : std::false_type {}; +template +struct is_buffer_appender< + It, bool_constant< + is_back_insert_iterator::value && + std::is_base_of, + typename It::container_type>::value>> + : std::true_type {}; + +// Maps an output iterator to a buffer. +template ::value)> +auto get_buffer(OutputIt out) -> iterator_buffer { + return iterator_buffer(out); +} +template ::value)> +auto get_buffer(OutputIt out) -> buffer& { + return get_container(out); +} + +template +auto get_iterator(Buf& buf, OutputIt) -> decltype(buf.out()) { + return buf.out(); +} +template +auto get_iterator(buffer&, OutputIt out) -> OutputIt { + return out; +} + +// This type is intentionally undefined, only used for errors. +template struct type_is_unformattable_for; + +template struct string_value { + const Char* data; + size_t size; + auto str() const -> basic_string_view { return {data, size}; } +}; + +template struct custom_value { + using char_type = typename Context::char_type; + void* value; + void (*format)(void* arg, parse_context& parse_ctx, Context& ctx); +}; + +template struct named_arg_value { + const named_arg_info* data; + size_t size; +}; + +struct custom_tag {}; + +#if !FMT_BUILTIN_TYPES +# define FMT_BUILTIN , monostate +#else +# define FMT_BUILTIN +#endif + +// A formatting argument value. +template class value { + public: + using char_type = typename Context::char_type; + + union { + monostate no_value; + int int_value; + unsigned uint_value; + long long long_long_value; + unsigned long long ulong_long_value; + int128_opt int128_value; + uint128_opt uint128_value; + bool bool_value; + char_type char_value; + float float_value; + double double_value; + long double long_double_value; + const void* pointer; + string_value string; + custom_value custom; + named_arg_value named_args; + }; + + constexpr FMT_INLINE value() : no_value() {} + constexpr FMT_INLINE value(signed char x) : int_value(x) {} + constexpr FMT_INLINE value(unsigned char x FMT_BUILTIN) : uint_value(x) {} + constexpr FMT_INLINE value(signed short x) : int_value(x) {} + constexpr FMT_INLINE value(unsigned short x FMT_BUILTIN) : uint_value(x) {} + constexpr FMT_INLINE value(int x) : int_value(x) {} + constexpr FMT_INLINE value(unsigned x FMT_BUILTIN) : uint_value(x) {} + FMT_CONSTEXPR FMT_INLINE value(long x FMT_BUILTIN) : value(long_type(x)) {} + FMT_CONSTEXPR FMT_INLINE value(unsigned long x FMT_BUILTIN) + : value(ulong_type(x)) {} + constexpr FMT_INLINE value(long long x FMT_BUILTIN) : long_long_value(x) {} + constexpr FMT_INLINE value(unsigned long long x FMT_BUILTIN) + : ulong_long_value(x) {} + FMT_INLINE value(int128_opt x FMT_BUILTIN) : int128_value(x) {} + FMT_INLINE value(uint128_opt x FMT_BUILTIN) : uint128_value(x) {} + constexpr FMT_INLINE value(bool x FMT_BUILTIN) : bool_value(x) {} + + template + constexpr FMT_INLINE value(bitint x FMT_BUILTIN) : long_long_value(x) { + static_assert(N <= 64, "unsupported _BitInt"); + } + template + constexpr FMT_INLINE value(ubitint x FMT_BUILTIN) : ulong_long_value(x) { + static_assert(N <= 64, "unsupported _BitInt"); + } + + template ::value)> + constexpr FMT_INLINE value(T x FMT_BUILTIN) : char_value(x) { + static_assert( + std::is_same::value || std::is_same::value, + "mixing character types is disallowed"); + } + + constexpr FMT_INLINE value(float x FMT_BUILTIN) : float_value(x) {} + constexpr FMT_INLINE value(double x FMT_BUILTIN) : double_value(x) {} + FMT_INLINE value(long double x FMT_BUILTIN) : long_double_value(x) {} + + FMT_CONSTEXPR FMT_INLINE value(char_type* x FMT_BUILTIN) { + string.data = x; + if (is_constant_evaluated()) string.size = 0; + } + FMT_CONSTEXPR FMT_INLINE value(const char_type* x FMT_BUILTIN) { + string.data = x; + if (is_constant_evaluated()) string.size = 0; + } + template , + FMT_ENABLE_IF(!std::is_pointer::value)> + FMT_CONSTEXPR value(const T& x FMT_BUILTIN) { + static_assert(std::is_same::value, + "mixing character types is disallowed"); + auto sv = to_string_view(x); + string.data = sv.data(); + string.size = sv.size(); + } + FMT_INLINE value(void* x FMT_BUILTIN) : pointer(x) {} + FMT_INLINE value(const void* x FMT_BUILTIN) : pointer(x) {} + FMT_INLINE value(volatile void* x FMT_BUILTIN) + : pointer(const_cast(x)) {} + FMT_INLINE value(const volatile void* x FMT_BUILTIN) + : pointer(const_cast(x)) {} + FMT_INLINE value(nullptr_t) : pointer(nullptr) {} + + template ::value || + std::is_member_pointer::value)> + value(const T&) { + // Formatting of arbitrary pointers is disallowed. If you want to format a + // pointer cast it to `void*` or `const void*`. In particular, this forbids + // formatting of `[const] volatile char*` printed as bool by iostreams. + static_assert(sizeof(T) == 0, + "formatting of non-void pointers is disallowed"); + } + + template ::value)> + value(const T& x) : value(format_as(x)) {} + template ::value)> + value(const T& x) : value(formatter::format_as(x)) {} + + template ::value)> + value(const T& named_arg) : value(named_arg.value) {} + + template ::value || !FMT_BUILTIN_TYPES)> + FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {} + + FMT_ALWAYS_INLINE value(const named_arg_info* args, size_t size) + : named_args{args, size} {} + + private: + template ())> + FMT_CONSTEXPR value(T& x, custom_tag) { + using value_type = remove_const_t; + // T may overload operator& e.g. std::vector::reference in libc++. + if (!is_constant_evaluated()) { + custom.value = + const_cast(&reinterpret_cast(x)); + } else { + custom.value = nullptr; +#if defined(__cpp_if_constexpr) + if constexpr (std::is_same*>::value) + custom.value = const_cast(&x); +#endif + } + custom.format = format_custom; + } + + template ())> + FMT_CONSTEXPR value(const T&, custom_tag) { + // Cannot format an argument; to make type T formattable provide a + // formatter specialization: https://fmt.dev/latest/api.html#udt. + type_is_unformattable_for _; + } + + // Formats an argument of a custom type, such as a user-defined class. + template + static void format_custom(void* arg, parse_context& parse_ctx, + Context& ctx) { + auto f = formatter(); + parse_ctx.advance_to(f.parse(parse_ctx)); + using qualified_type = + conditional_t(), const T, T>; + // format must be const for compatibility with std::format and compilation. + const auto& cf = f; + ctx.advance_to(cf.format(*static_cast(arg), ctx)); + } +}; + +enum { packed_arg_bits = 4 }; +// Maximum number of arguments with packed types. +enum { max_packed_args = 62 / packed_arg_bits }; +enum : unsigned long long { is_unpacked_bit = 1ULL << 63 }; +enum : unsigned long long { has_named_args_bit = 1ULL << 62 }; + +template +struct is_output_iterator : std::false_type {}; + +template <> struct is_output_iterator : std::true_type {}; + +template +struct is_output_iterator< + It, T, + enable_if_t&>()++), + T>::value>> : std::true_type {}; + +template constexpr auto encode_types() -> unsigned long long { + return 0; +} + +template +constexpr auto encode_types() -> unsigned long long { + return static_cast(stored_type_constant::value) | + (encode_types() << packed_arg_bits); +} + +template +constexpr auto make_descriptor() -> unsigned long long { + return NUM_ARGS <= max_packed_args ? encode_types() + : is_unpacked_bit | NUM_ARGS; +} + +template +using arg_t = conditional_t, + basic_format_arg>; + +template +struct named_arg_store { + // args_[0].named_args points to named_args to avoid bloating format_args. + arg_t args[1u + NUM_ARGS]; + named_arg_info + named_args[static_cast(NUM_NAMED_ARGS)]; + + template + FMT_CONSTEXPR FMT_ALWAYS_INLINE named_arg_store(T&... values) + : args{{named_args, NUM_NAMED_ARGS}, values...} { + int arg_index = 0, named_arg_index = 0; + FMT_APPLY_VARIADIC( + init_named_arg(named_args, arg_index, named_arg_index, values)); + } + + named_arg_store(named_arg_store&& rhs) { + args[0] = {named_args, NUM_NAMED_ARGS}; + for (size_t i = 1; i < sizeof(args) / sizeof(*args); ++i) + args[i] = rhs.args[i]; + for (size_t i = 0; i < NUM_NAMED_ARGS; ++i) + named_args[i] = rhs.named_args[i]; + } + + named_arg_store(const named_arg_store& rhs) = delete; + auto operator=(const named_arg_store& rhs) -> named_arg_store& = delete; + auto operator=(named_arg_store&& rhs) -> named_arg_store& = delete; + operator const arg_t*() const { return args + 1; } +}; + +// An array of references to arguments. It can be implicitly converted to +// `basic_format_args` for passing into type-erased formatting functions +// such as `vformat`. It is a plain struct to reduce binary size in debug mode. +template +struct format_arg_store { + // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning. + using type = + conditional_t[max_of(1, NUM_ARGS)], + named_arg_store>; + type args; +}; + +// TYPE can be different from type_constant, e.g. for __float128. +template struct native_formatter { + private: + dynamic_format_specs specs_; + + public: + using nonlocking = void; + + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin(); + auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, TYPE); + if (const_check(TYPE == type::char_type)) check_char_specs(specs_); + return end; + } + + template + FMT_CONSTEXPR void set_debug_format(bool set = true) { + specs_.set_type(set ? presentation_type::debug : presentation_type::none); + } + + FMT_PRAGMA_CLANG(diagnostic ignored "-Wundefined-inline") + template + FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const + -> decltype(ctx.out()); +}; + +template +struct locking + : bool_constant::value == type::custom_type> {}; +template +struct locking>::nonlocking>> + : std::false_type {}; + +template FMT_CONSTEXPR inline auto is_locking() -> bool { + return locking::value; +} +template +FMT_CONSTEXPR inline auto is_locking() -> bool { + return locking::value || is_locking(); +} + +FMT_API void vformat_to(buffer& buf, string_view fmt, format_args args, + locale_ref loc = {}); + +#if FMT_WIN32 +FMT_API void vprint_mojibake(FILE*, string_view, format_args, bool); +#else // format_args is passed by reference since it is defined later. +inline void vprint_mojibake(FILE*, string_view, const format_args&, bool) {} +#endif +} // namespace detail + +// The main public API. + +template +FMT_CONSTEXPR void parse_context::do_check_arg_id(int arg_id) { + // Argument id is only checked at compile time during parsing because + // formatting has its own validation. + if (detail::is_constant_evaluated() && use_constexpr_cast) { + auto ctx = static_cast*>(this); + if (arg_id >= ctx->num_args()) report_error("argument not found"); + } +} + +template +FMT_CONSTEXPR void parse_context::check_dynamic_spec(int arg_id) { + using detail::compile_parse_context; + if (detail::is_constant_evaluated() && use_constexpr_cast) + static_cast*>(this)->check_dynamic_spec(arg_id); +} + +FMT_BEGIN_EXPORT + +// An output iterator that appends to a buffer. It is used instead of +// back_insert_iterator to reduce symbol sizes and avoid dependency. +template class basic_appender { + protected: + detail::buffer* container; + + public: + using container_type = detail::buffer; + + FMT_CONSTEXPR basic_appender(detail::buffer& buf) : container(&buf) {} + + FMT_CONSTEXPR20 auto operator=(T c) -> basic_appender& { + container->push_back(c); + return *this; + } + FMT_CONSTEXPR20 auto operator*() -> basic_appender& { return *this; } + FMT_CONSTEXPR20 auto operator++() -> basic_appender& { return *this; } + FMT_CONSTEXPR20 auto operator++(int) -> basic_appender { return *this; } +}; + +// A formatting argument. Context is a template parameter for the compiled API +// where output can be unbuffered. +template class basic_format_arg { + private: + detail::value value_; + detail::type type_; + + friend class basic_format_args; + + using char_type = typename Context::char_type; + + public: + class handle { + private: + detail::custom_value custom_; + + public: + explicit handle(detail::custom_value custom) : custom_(custom) {} + + void format(parse_context& parse_ctx, Context& ctx) const { + custom_.format(custom_.value, parse_ctx, ctx); + } + }; + + constexpr basic_format_arg() : type_(detail::type::none_type) {} + basic_format_arg(const detail::named_arg_info* args, size_t size) + : value_(args, size) {} + template + basic_format_arg(T&& val) + : value_(val), type_(detail::stored_type_constant::value) {} + + constexpr explicit operator bool() const noexcept { + return type_ != detail::type::none_type; + } + auto type() const -> detail::type { return type_; } + + /** + * Visits an argument dispatching to the appropriate visit method based on + * the argument type. For example, if the argument type is `double` then + * `vis(value)` will be called with the value of type `double`. + */ + template + FMT_CONSTEXPR FMT_INLINE auto visit(Visitor&& vis) const -> decltype(vis(0)) { + using detail::map; + switch (type_) { + case detail::type::none_type: break; + case detail::type::int_type: return vis(value_.int_value); + case detail::type::uint_type: return vis(value_.uint_value); + case detail::type::long_long_type: return vis(value_.long_long_value); + case detail::type::ulong_long_type: return vis(value_.ulong_long_value); + case detail::type::int128_type: return vis(map(value_.int128_value)); + case detail::type::uint128_type: return vis(map(value_.uint128_value)); + case detail::type::bool_type: return vis(value_.bool_value); + case detail::type::char_type: return vis(value_.char_value); + case detail::type::float_type: return vis(value_.float_value); + case detail::type::double_type: return vis(value_.double_value); + case detail::type::long_double_type: return vis(value_.long_double_value); + case detail::type::cstring_type: return vis(value_.string.data); + case detail::type::string_type: return vis(value_.string.str()); + case detail::type::pointer_type: return vis(value_.pointer); + case detail::type::custom_type: return vis(handle(value_.custom)); + } + return vis(monostate()); + } + + auto format_custom(const char_type* parse_begin, + parse_context& parse_ctx, Context& ctx) + -> bool { + if (type_ != detail::type::custom_type) return false; + parse_ctx.advance_to(parse_begin); + value_.custom.format(value_.custom.value, parse_ctx, ctx); + return true; + } +}; + +/** + * A view of a collection of formatting arguments. To avoid lifetime issues it + * should only be used as a parameter type in type-erased functions such as + * `vformat`: + * + * void vlog(fmt::string_view fmt, fmt::format_args args); // OK + * fmt::format_args args = fmt::make_format_args(); // Dangling reference + */ +template class basic_format_args { + private: + // A descriptor that contains information about formatting arguments. + // If the number of arguments is less or equal to max_packed_args then + // argument types are passed in the descriptor. This reduces binary code size + // per formatting function call. + unsigned long long desc_; + union { + // If is_packed() returns true then argument values are stored in values_; + // otherwise they are stored in args_. This is done to improve cache + // locality and reduce compiled code size since storing larger objects + // may require more code (at least on x86-64) even if the same amount of + // data is actually copied to stack. It saves ~10% on the bloat test. + const detail::value* values_; + const basic_format_arg* args_; + }; + + constexpr auto is_packed() const -> bool { + return (desc_ & detail::is_unpacked_bit) == 0; + } + constexpr auto has_named_args() const -> bool { + return (desc_ & detail::has_named_args_bit) != 0; + } + + FMT_CONSTEXPR auto type(int index) const -> detail::type { + int shift = index * detail::packed_arg_bits; + unsigned mask = (1 << detail::packed_arg_bits) - 1; + return static_cast((desc_ >> shift) & mask); + } + + template + using store = + detail::format_arg_store; + + public: + using format_arg = basic_format_arg; + + constexpr basic_format_args() : desc_(0), args_(nullptr) {} + + /// Constructs a `basic_format_args` object from `format_arg_store`. + template + constexpr FMT_ALWAYS_INLINE basic_format_args( + const store& s) + : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)), + values_(s.args) {} + + template detail::max_packed_args)> + constexpr basic_format_args(const store& s) + : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)), + args_(s.args) {} + + /// Constructs a `basic_format_args` object from a dynamic list of arguments. + constexpr basic_format_args(const format_arg* args, int count, + bool has_named = false) + : desc_(detail::is_unpacked_bit | detail::to_unsigned(count) | + (has_named ? +detail::has_named_args_bit : 0)), + args_(args) {} + + /// Returns the argument with the specified id. + FMT_CONSTEXPR auto get(int id) const -> format_arg { + auto arg = format_arg(); + if (!is_packed()) { + if (id < max_size()) arg = args_[id]; + return arg; + } + if (static_cast(id) >= detail::max_packed_args) return arg; + arg.type_ = type(id); + if (arg.type_ != detail::type::none_type) arg.value_ = values_[id]; + return arg; + } + + template + auto get(basic_string_view name) const -> format_arg { + int id = get_id(name); + return id >= 0 ? get(id) : format_arg(); + } + + template + FMT_CONSTEXPR auto get_id(basic_string_view name) const -> int { + if (!has_named_args()) return -1; + const auto& named_args = + (is_packed() ? values_[-1] : args_[-1].value_).named_args; + for (size_t i = 0; i < named_args.size; ++i) { + if (named_args.data[i].name == name) return named_args.data[i].id; + } + return -1; + } + + auto max_size() const -> int { + unsigned long long max_packed = detail::max_packed_args; + return static_cast(is_packed() ? max_packed + : desc_ & ~detail::is_unpacked_bit); + } +}; + +// A formatting context. +class context { + private: + appender out_; + format_args args_; + FMT_NO_UNIQUE_ADDRESS locale_ref loc_; + + public: + using char_type = char; ///< The character type for the output. + using iterator = appender; + using format_arg = basic_format_arg; + enum { builtin_types = FMT_BUILTIN_TYPES }; + + /// Constructs a `context` object. References to the arguments are stored + /// in the object so make sure they have appropriate lifetimes. + FMT_CONSTEXPR context(iterator out, format_args args, locale_ref loc = {}) + : out_(out), args_(args), loc_(loc) {} + context(context&&) = default; + context(const context&) = delete; + void operator=(const context&) = delete; + + FMT_CONSTEXPR auto arg(int id) const -> format_arg { return args_.get(id); } + inline auto arg(string_view name) const -> format_arg { + return args_.get(name); + } + FMT_CONSTEXPR auto arg_id(string_view name) const -> int { + return args_.get_id(name); + } + auto args() const -> const format_args& { return args_; } + + // Returns an iterator to the beginning of the output range. + FMT_CONSTEXPR auto out() const -> iterator { return out_; } + + // Advances the begin iterator to `it`. + FMT_CONSTEXPR void advance_to(iterator) {} + + FMT_CONSTEXPR auto locale() const -> locale_ref { return loc_; } +}; + +template struct runtime_format_string { + basic_string_view str; +}; + +/** + * Creates a runtime format string. + * + * **Example**: + * + * // Check format string at runtime instead of compile-time. + * fmt::print(fmt::runtime("{:d}"), "I am not a number"); + */ +inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; } + +/// A compile-time format string. Use `format_string` in the public API to +/// prevent type deduction. +template struct fstring { + private: + static constexpr int num_static_named_args = + detail::count_static_named_args(); + + using checker = detail::format_string_checker< + char, static_cast(sizeof...(T)), num_static_named_args, + num_static_named_args != detail::count_named_args()>; + + using arg_pack = detail::arg_pack; + + public: + string_view str; + using t = fstring; + + // Reports a compile-time error if S is not a valid format string for T. + template + FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) { + using namespace detail; + static_assert(count<(is_view>::value && + std::is_reference::value)...>() == 0, + "passing views as lvalues is disallowed"); + if (FMT_USE_CONSTEVAL) parse_format_string(s, checker(s, arg_pack())); +#ifdef FMT_ENFORCE_COMPILE_STRING + static_assert( + FMT_USE_CONSTEVAL && sizeof(s) != 0, + "FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING"); +#endif + } + template ::value)> + FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) { + auto sv = string_view(str); + if (FMT_USE_CONSTEVAL) + detail::parse_format_string(sv, checker(sv, arg_pack())); +#ifdef FMT_ENFORCE_COMPILE_STRING + static_assert( + FMT_USE_CONSTEVAL && sizeof(s) != 0, + "FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING"); +#endif + } + template ::value&& + std::is_same::value)> + FMT_ALWAYS_INLINE fstring(const S&) : str(S()) { + FMT_CONSTEXPR auto sv = string_view(S()); + FMT_CONSTEXPR int unused = + (parse_format_string(sv, checker(sv, arg_pack())), 0); + detail::ignore_unused(unused); + } + fstring(runtime_format_string<> fmt) : str(fmt.str) {} + + // Returning by reference generates better code in debug mode. + FMT_ALWAYS_INLINE operator const string_view&() const { return str; } + auto get() const -> string_view { return str; } +}; + +template using format_string = typename fstring::t; + +template +using is_formattable = bool_constant::value, int*, T>, Char>, + void>::value>; +#ifdef __cpp_concepts +template +concept formattable = is_formattable, Char>::value; +#endif + +// A formatter specialization for natively supported types. +template +struct formatter::value != + detail::type::custom_type>> + : detail::native_formatter::value> { +}; + +/** + * Constructs an object that stores references to arguments and can be + * implicitly converted to `format_args`. `Context` can be omitted in which case + * it defaults to `context`. See `arg` for lifetime considerations. + */ +// Take arguments by lvalue references to avoid some lifetime issues, e.g. +// auto args = make_format_args(std::string()); +template (), + unsigned long long DESC = detail::make_descriptor()> +constexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args) + -> detail::format_arg_store { + // Suppress warnings for pathological types convertible to detail::value. + FMT_PRAGMA_GCC(diagnostic ignored "-Wconversion") + return {{args...}}; +} + +template +using vargs = + detail::format_arg_store(), + detail::make_descriptor()>; + +/** + * Returns a named argument to be used in a formatting function. + * It should only be used in a call to a formatting function. + * + * **Example**: + * + * fmt::print("The answer is {answer}.", fmt::arg("answer", 42)); + */ +template +inline auto arg(const Char* name, const T& arg) -> detail::named_arg { + return {name, arg}; +} + +/// Formats a string and writes the output to `out`. +template , + char>::value)> +auto vformat_to(OutputIt&& out, string_view fmt, format_args args) + -> remove_cvref_t { + auto&& buf = detail::get_buffer(out); + detail::vformat_to(buf, fmt, args, {}); + return detail::get_iterator(buf, out); +} + +/** + * Formats `args` according to specifications in `fmt`, writes the result to + * the output iterator `out` and returns the iterator past the end of the output + * range. `format_to` does not append a terminating null character. + * + * **Example**: + * + * auto out = std::vector(); + * fmt::format_to(std::back_inserter(out), "{}", 42); + */ +template , + char>::value)> +FMT_INLINE auto format_to(OutputIt&& out, format_string fmt, T&&... args) + -> remove_cvref_t { + return vformat_to(out, fmt.str, vargs{{args...}}); +} + +template struct format_to_n_result { + /// Iterator past the end of the output range. + OutputIt out; + /// Total (not truncated) output size. + size_t size; +}; + +template ::value)> +auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args) + -> format_to_n_result { + using traits = detail::fixed_buffer_traits; + auto buf = detail::iterator_buffer(out, n); + detail::vformat_to(buf, fmt, args, {}); + return {buf.out(), buf.count()}; +} + +/** + * Formats `args` according to specifications in `fmt`, writes up to `n` + * characters of the result to the output iterator `out` and returns the total + * (not truncated) output size and the iterator past the end of the output + * range. `format_to_n` does not append a terminating null character. + */ +template ::value)> +FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string fmt, + T&&... args) -> format_to_n_result { + return vformat_to_n(out, n, fmt.str, vargs{{args...}}); +} + +struct format_to_result { + /// Pointer to just after the last successful write in the array. + char* out; + /// Specifies if the output was truncated. + bool truncated; + + FMT_CONSTEXPR operator char*() const { + // Report truncation to prevent silent data loss. + if (truncated) report_error("output is truncated"); + return out; + } +}; + +template +auto vformat_to(char (&out)[N], string_view fmt, format_args args) + -> format_to_result { + auto result = vformat_to_n(out, N, fmt, args); + return {result.out, result.size > N}; +} + +template +FMT_INLINE auto format_to(char (&out)[N], format_string fmt, T&&... args) + -> format_to_result { + auto result = vformat_to_n(out, N, fmt.str, vargs{{args...}}); + return {result.out, result.size > N}; +} + +/// Returns the number of chars in the output of `format(fmt, args...)`. +template +FMT_NODISCARD FMT_INLINE auto formatted_size(format_string fmt, + T&&... args) -> size_t { + auto buf = detail::counting_buffer<>(); + detail::vformat_to(buf, fmt.str, vargs{{args...}}, {}); + return buf.count(); +} + +FMT_API void vprint(string_view fmt, format_args args); +FMT_API void vprint(FILE* f, string_view fmt, format_args args); +FMT_API void vprintln(FILE* f, string_view fmt, format_args args); +FMT_API void vprint_buffered(FILE* f, string_view fmt, format_args args); + +/** + * Formats `args` according to specifications in `fmt` and writes the output + * to `stdout`. + * + * **Example**: + * + * fmt::print("The answer is {}.", 42); + */ +template +FMT_INLINE void print(format_string fmt, T&&... args) { + vargs va = {{args...}}; + if (detail::const_check(!detail::use_utf8)) + return detail::vprint_mojibake(stdout, fmt.str, va, false); + return detail::is_locking() ? vprint_buffered(stdout, fmt.str, va) + : vprint(fmt.str, va); +} + +/** + * Formats `args` according to specifications in `fmt` and writes the + * output to the file `f`. + * + * **Example**: + * + * fmt::print(stderr, "Don't {}!", "panic"); + */ +template +FMT_INLINE void print(FILE* f, format_string fmt, T&&... args) { + vargs va = {{args...}}; + if (detail::const_check(!detail::use_utf8)) + return detail::vprint_mojibake(f, fmt.str, va, false); + return detail::is_locking() ? vprint_buffered(f, fmt.str, va) + : vprint(f, fmt.str, va); +} + +/// Formats `args` according to specifications in `fmt` and writes the output +/// to the file `f` followed by a newline. +template +FMT_INLINE void println(FILE* f, format_string fmt, T&&... args) { + vargs va = {{args...}}; + return detail::const_check(detail::use_utf8) + ? vprintln(f, fmt.str, va) + : detail::vprint_mojibake(f, fmt.str, va, true); +} + +/// Formats `args` according to specifications in `fmt` and writes the output +/// to `stdout` followed by a newline. +template +FMT_INLINE void println(format_string fmt, T&&... args) { + return fmt::println(stdout, fmt, static_cast(args)...); +} + +FMT_PRAGMA_GCC(diagnostic pop) +FMT_PRAGMA_CLANG(diagnostic pop) +FMT_PRAGMA_GCC(pop_options) +FMT_END_EXPORT +FMT_END_NAMESPACE + +#ifdef FMT_HEADER_ONLY +# include "format.h" +#endif +#endif // FMT_BASE_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/chrono.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/chrono.h new file mode 100644 index 0000000000000000000000000000000000000000..d4519b16353e00d73bdcc493926625937f8c1808 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/chrono.h @@ -0,0 +1,2251 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - chrono support +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_CHRONO_H_ +#define FMT_CHRONO_H_ + +#ifndef FMT_MODULE +# include +# include +# include // std::isfinite +# include // std::memcpy +# include +# include +# include +# include +# include +#endif + +#include "format.h" + +FMT_BEGIN_NAMESPACE + +// Enable safe chrono durations, unless explicitly disabled. +#ifndef FMT_SAFE_DURATION_CAST +# define FMT_SAFE_DURATION_CAST 1 +#endif +#if FMT_SAFE_DURATION_CAST + +// For conversion between std::chrono::durations without undefined +// behaviour or erroneous results. +// This is a stripped down version of duration_cast, for inclusion in fmt. +// See https://github.com/pauldreik/safe_duration_cast +// +// Copyright Paul Dreik 2019 +namespace safe_duration_cast { + +// DEPRECATED! +template ::value && + std::numeric_limits::is_signed == + std::numeric_limits::is_signed)> +FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec) + -> To { + ec = 0; + using F = std::numeric_limits; + using T = std::numeric_limits; + static_assert(F::is_integer, "From must be integral"); + static_assert(T::is_integer, "To must be integral"); + + // A and B are both signed, or both unsigned. + if (detail::const_check(F::digits <= T::digits)) { + // From fits in To without any problem. + } else { + // From does not always fit in To, resort to a dynamic check. + if (from < (T::min)() || from > (T::max)()) { + // outside range. + ec = 1; + return {}; + } + } + return static_cast(from); +} + +/// Converts From to To, without loss. If the dynamic value of from +/// can't be converted to To without loss, ec is set. +template ::value && + std::numeric_limits::is_signed != + std::numeric_limits::is_signed)> +FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec) + -> To { + ec = 0; + using F = std::numeric_limits; + using T = std::numeric_limits; + static_assert(F::is_integer, "From must be integral"); + static_assert(T::is_integer, "To must be integral"); + + if (detail::const_check(F::is_signed && !T::is_signed)) { + // From may be negative, not allowed! + if (fmt::detail::is_negative(from)) { + ec = 1; + return {}; + } + // From is positive. Can it always fit in To? + if (detail::const_check(F::digits > T::digits) && + from > static_cast(detail::max_value())) { + ec = 1; + return {}; + } + } + + if (detail::const_check(!F::is_signed && T::is_signed && + F::digits >= T::digits) && + from > static_cast(detail::max_value())) { + ec = 1; + return {}; + } + return static_cast(from); // Lossless conversion. +} + +template ::value)> +FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec) + -> To { + ec = 0; + return from; +} // function + +// clang-format off +/** + * converts From to To if possible, otherwise ec is set. + * + * input | output + * ---------------------------------|--------------- + * NaN | NaN + * Inf | Inf + * normal, fits in output | converted (possibly lossy) + * normal, does not fit in output | ec is set + * subnormal | best effort + * -Inf | -Inf + */ +// clang-format on +template ::value)> +FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To { + ec = 0; + using T = std::numeric_limits; + static_assert(std::is_floating_point::value, "From must be floating"); + static_assert(std::is_floating_point::value, "To must be floating"); + + // catch the only happy case + if (std::isfinite(from)) { + if (from >= T::lowest() && from <= (T::max)()) { + return static_cast(from); + } + // not within range. + ec = 1; + return {}; + } + + // nan and inf will be preserved + return static_cast(from); +} // function + +template ::value)> +FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To { + ec = 0; + static_assert(std::is_floating_point::value, "From must be floating"); + return from; +} + +/// Safe duration_cast between floating point durations +template ::value), + FMT_ENABLE_IF(std::is_floating_point::value)> +auto safe_duration_cast(std::chrono::duration from, + int& ec) -> To { + using From = std::chrono::duration; + ec = 0; + + // the basic idea is that we need to convert from count() in the from type + // to count() in the To type, by multiplying it with this: + struct Factor + : std::ratio_divide {}; + + static_assert(Factor::num > 0, "num must be positive"); + static_assert(Factor::den > 0, "den must be positive"); + + // the conversion is like this: multiply from.count() with Factor::num + // /Factor::den and convert it to To::rep, all this without + // overflow/underflow. let's start by finding a suitable type that can hold + // both To, From and Factor::num + using IntermediateRep = + typename std::common_type::type; + + // force conversion of From::rep -> IntermediateRep to be safe, + // even if it will never happen be narrowing in this context. + IntermediateRep count = + safe_float_conversion(from.count(), ec); + if (ec) { + return {}; + } + + // multiply with Factor::num without overflow or underflow + if (detail::const_check(Factor::num != 1)) { + constexpr auto max1 = detail::max_value() / + static_cast(Factor::num); + if (count > max1) { + ec = 1; + return {}; + } + constexpr auto min1 = std::numeric_limits::lowest() / + static_cast(Factor::num); + if (count < min1) { + ec = 1; + return {}; + } + count *= static_cast(Factor::num); + } + + // this can't go wrong, right? den>0 is checked earlier. + if (detail::const_check(Factor::den != 1)) { + using common_t = typename std::common_type::type; + count /= static_cast(Factor::den); + } + + // convert to the to type, safely + using ToRep = typename To::rep; + + const ToRep tocount = safe_float_conversion(count, ec); + if (ec) { + return {}; + } + return To{tocount}; +} +} // namespace safe_duration_cast +#endif + +namespace detail { + +// Check if std::chrono::utc_time is available. +#ifdef FMT_USE_UTC_TIME +// Use the provided definition. +#elif defined(__cpp_lib_chrono) +# define FMT_USE_UTC_TIME (__cpp_lib_chrono >= 201907L) +#else +# define FMT_USE_UTC_TIME 0 +#endif +#if FMT_USE_UTC_TIME +using utc_clock = std::chrono::utc_clock; +#else +struct utc_clock { + template void to_sys(T); +}; +#endif + +// Check if std::chrono::local_time is available. +#ifdef FMT_USE_LOCAL_TIME +// Use the provided definition. +#elif defined(__cpp_lib_chrono) +# define FMT_USE_LOCAL_TIME (__cpp_lib_chrono >= 201907L) +#else +# define FMT_USE_LOCAL_TIME 0 +#endif +#if FMT_USE_LOCAL_TIME +using local_t = std::chrono::local_t; +#else +struct local_t {}; +#endif + +} // namespace detail + +template +using sys_time = std::chrono::time_point; + +template +using utc_time = std::chrono::time_point; + +template +using local_time = std::chrono::time_point; + +namespace detail { + +// Prevents expansion of a preceding token as a function-style macro. +// Usage: f FMT_NOMACRO() +#define FMT_NOMACRO + +template struct null {}; +inline auto gmtime_r(...) -> null<> { return null<>(); } +inline auto gmtime_s(...) -> null<> { return null<>(); } + +// It is defined here and not in ostream.h because the latter has expensive +// includes. +template class formatbuf : public StreamBuf { + private: + using char_type = typename StreamBuf::char_type; + using streamsize = decltype(std::declval().sputn(nullptr, 0)); + using int_type = typename StreamBuf::int_type; + using traits_type = typename StreamBuf::traits_type; + + buffer& buffer_; + + public: + explicit formatbuf(buffer& buf) : buffer_(buf) {} + + protected: + // The put area is always empty. This makes the implementation simpler and has + // the advantage that the streambuf and the buffer are always in sync and + // sputc never writes into uninitialized memory. A disadvantage is that each + // call to sputc always results in a (virtual) call to overflow. There is no + // disadvantage here for sputn since this always results in a call to xsputn. + + auto overflow(int_type ch) -> int_type override { + if (!traits_type::eq_int_type(ch, traits_type::eof())) + buffer_.push_back(static_cast(ch)); + return ch; + } + + auto xsputn(const char_type* s, streamsize count) -> streamsize override { + buffer_.append(s, s + count); + return count; + } +}; + +inline auto get_classic_locale() -> const std::locale& { + static const auto& locale = std::locale::classic(); + return locale; +} + +template struct codecvt_result { + static constexpr size_t max_size = 32; + CodeUnit buf[max_size]; + CodeUnit* end; +}; + +template +void write_codecvt(codecvt_result& out, string_view in, + const std::locale& loc) { + FMT_PRAGMA_CLANG(diagnostic push) + FMT_PRAGMA_CLANG(diagnostic ignored "-Wdeprecated") + auto& f = std::use_facet>(loc); + FMT_PRAGMA_CLANG(diagnostic pop) + auto mb = std::mbstate_t(); + const char* from_next = nullptr; + auto result = f.in(mb, in.begin(), in.end(), from_next, std::begin(out.buf), + std::end(out.buf), out.end); + if (result != std::codecvt_base::ok) + FMT_THROW(format_error("failed to format time")); +} + +template +auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc) + -> OutputIt { + if (const_check(detail::use_utf8) && loc != get_classic_locale()) { + // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and + // gcc-4. +#if FMT_MSC_VERSION != 0 || \ + (defined(__GLIBCXX__) && \ + (!defined(_GLIBCXX_USE_DUAL_ABI) || _GLIBCXX_USE_DUAL_ABI == 0)) + // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5 + // and newer. + using code_unit = wchar_t; +#else + using code_unit = char32_t; +#endif + + using unit_t = codecvt_result; + unit_t unit; + write_codecvt(unit, in, loc); + // In UTF-8 is used one to four one-byte code units. + auto u = + to_utf8>(); + if (!u.convert({unit.buf, to_unsigned(unit.end - unit.buf)})) + FMT_THROW(format_error("failed to format time")); + return copy(u.c_str(), u.c_str() + u.size(), out); + } + return copy(in.data(), in.data() + in.size(), out); +} + +template ::value)> +auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc) + -> OutputIt { + codecvt_result unit; + write_codecvt(unit, sv, loc); + return copy(unit.buf, unit.end, out); +} + +template ::value)> +auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc) + -> OutputIt { + return write_encoded_tm_str(out, sv, loc); +} + +template +inline void do_write(buffer& buf, const std::tm& time, + const std::locale& loc, char format, char modifier) { + auto&& format_buf = formatbuf>(buf); + auto&& os = std::basic_ostream(&format_buf); + os.imbue(loc); + const auto& facet = std::use_facet>(loc); + auto end = facet.put(os, os, Char(' '), &time, format, modifier); + if (end.failed()) FMT_THROW(format_error("failed to format time")); +} + +template ::value)> +auto write(OutputIt out, const std::tm& time, const std::locale& loc, + char format, char modifier = 0) -> OutputIt { + auto&& buf = get_buffer(out); + do_write(buf, time, loc, format, modifier); + return get_iterator(buf, out); +} + +template ::value)> +auto write(OutputIt out, const std::tm& time, const std::locale& loc, + char format, char modifier = 0) -> OutputIt { + auto&& buf = basic_memory_buffer(); + do_write(buf, time, loc, format, modifier); + return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc); +} + +template +using is_similar_arithmetic_type = + bool_constant<(std::is_integral::value && std::is_integral::value) || + (std::is_floating_point::value && + std::is_floating_point::value)>; + +FMT_NORETURN inline void throw_duration_error() { + FMT_THROW(format_error("cannot format duration")); +} + +// Cast one integral duration to another with an overflow check. +template ::value&& + std::is_integral::value)> +auto duration_cast(std::chrono::duration from) -> To { +#if !FMT_SAFE_DURATION_CAST + return std::chrono::duration_cast(from); +#else + // The conversion factor: to.count() == factor * from.count(). + using factor = std::ratio_divide; + + using common_rep = typename std::common_type::type; + common_rep count = from.count(); // This conversion is lossless. + + // Multiply from.count() by factor and check for overflow. + if (const_check(factor::num != 1)) { + if (count > max_value() / factor::num) throw_duration_error(); + const auto min = (std::numeric_limits::min)() / factor::num; + if (const_check(!std::is_unsigned::value) && count < min) + throw_duration_error(); + count *= factor::num; + } + if (const_check(factor::den != 1)) count /= factor::den; + int ec = 0; + auto to = + To(safe_duration_cast::lossless_integral_conversion( + count, ec)); + if (ec) throw_duration_error(); + return to; +#endif +} + +template ::value&& + std::is_floating_point::value)> +auto duration_cast(std::chrono::duration from) -> To { +#if FMT_SAFE_DURATION_CAST + // Preserve infinity and NaN. + if (!isfinite(from.count())) return static_cast(from.count()); + // Throwing version of safe_duration_cast is only available for + // integer to integer or float to float casts. + int ec; + To to = safe_duration_cast::safe_duration_cast(from, ec); + if (ec) throw_duration_error(); + return to; +#else + // Standard duration cast, may overflow. + return std::chrono::duration_cast(from); +#endif +} + +template ::value)> +auto duration_cast(std::chrono::duration from) -> To { + // Mixed integer <-> float cast is not supported by safe duration_cast. + return std::chrono::duration_cast(from); +} + +template +auto to_time_t(sys_time time_point) -> std::time_t { + // Cannot use std::chrono::system_clock::to_time_t since this would first + // require a cast to std::chrono::system_clock::time_point, which could + // overflow. + return detail::duration_cast>( + time_point.time_since_epoch()) + .count(); +} + +} // namespace detail + +FMT_BEGIN_EXPORT + +/** + * Converts given time since epoch as `std::time_t` value into calendar time, + * expressed in Coordinated Universal Time (UTC). Unlike `std::gmtime`, this + * function is thread-safe on most platforms. + */ +inline auto gmtime(std::time_t time) -> std::tm { + struct dispatcher { + std::time_t time_; + std::tm tm_; + + inline dispatcher(std::time_t t) : time_(t) {} + + inline auto run() -> bool { + using namespace fmt::detail; + return handle(gmtime_r(&time_, &tm_)); + } + + inline auto handle(std::tm* tm) -> bool { return tm != nullptr; } + + inline auto handle(detail::null<>) -> bool { + using namespace fmt::detail; + return fallback(gmtime_s(&tm_, &time_)); + } + + inline auto fallback(int res) -> bool { return res == 0; } + +#if !FMT_MSC_VERSION + inline auto fallback(detail::null<>) -> bool { + std::tm* tm = std::gmtime(&time_); + if (tm) tm_ = *tm; + return tm != nullptr; + } +#endif + }; + auto gt = dispatcher(time); + // Too big time values may be unsupported. + if (!gt.run()) FMT_THROW(format_error("time_t value out of range")); + return gt.tm_; +} + +template +inline auto gmtime(sys_time time_point) -> std::tm { + return gmtime(detail::to_time_t(time_point)); +} + +namespace detail { + +// Writes two-digit numbers a, b and c separated by sep to buf. +// The method by Pavel Novikov based on +// https://johnnylee-sde.github.io/Fast-unsigned-integer-to-time-string/. +inline void write_digit2_separated(char* buf, unsigned a, unsigned b, + unsigned c, char sep) { + unsigned long long digits = + a | (b << 24) | (static_cast(c) << 48); + // Convert each value to BCD. + // We have x = a * 10 + b and we want to convert it to BCD y = a * 16 + b. + // The difference is + // y - x = a * 6 + // a can be found from x: + // a = floor(x / 10) + // then + // y = x + a * 6 = x + floor(x / 10) * 6 + // floor(x / 10) is (x * 205) >> 11 (needs 16 bits). + digits += (((digits * 205) >> 11) & 0x000f00000f00000f) * 6; + // Put low nibbles to high bytes and high nibbles to low bytes. + digits = ((digits & 0x00f00000f00000f0) >> 4) | + ((digits & 0x000f00000f00000f) << 8); + auto usep = static_cast(sep); + // Add ASCII '0' to each digit byte and insert separators. + digits |= 0x3030003030003030 | (usep << 16) | (usep << 40); + + constexpr size_t len = 8; + if (const_check(is_big_endian())) { + char tmp[len]; + std::memcpy(tmp, &digits, len); + std::reverse_copy(tmp, tmp + len, buf); + } else { + std::memcpy(buf, &digits, len); + } +} + +template +FMT_CONSTEXPR inline auto get_units() -> const char* { + if (std::is_same::value) return "as"; + if (std::is_same::value) return "fs"; + if (std::is_same::value) return "ps"; + if (std::is_same::value) return "ns"; + if (std::is_same::value) + return detail::use_utf8 ? "µs" : "us"; + if (std::is_same::value) return "ms"; + if (std::is_same::value) return "cs"; + if (std::is_same::value) return "ds"; + if (std::is_same>::value) return "s"; + if (std::is_same::value) return "das"; + if (std::is_same::value) return "hs"; + if (std::is_same::value) return "ks"; + if (std::is_same::value) return "Ms"; + if (std::is_same::value) return "Gs"; + if (std::is_same::value) return "Ts"; + if (std::is_same::value) return "Ps"; + if (std::is_same::value) return "Es"; + if (std::is_same>::value) return "min"; + if (std::is_same>::value) return "h"; + if (std::is_same>::value) return "d"; + return nullptr; +} + +enum class numeric_system { + standard, + // Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale. + alternative +}; + +// Glibc extensions for formatting numeric values. +enum class pad_type { + // Pad a numeric result string with zeros (the default). + zero, + // Do not pad a numeric result string. + none, + // Pad a numeric result string with spaces. + space, +}; + +template +auto write_padding(OutputIt out, pad_type pad, int width) -> OutputIt { + if (pad == pad_type::none) return out; + return detail::fill_n(out, width, pad == pad_type::space ? ' ' : '0'); +} + +template +auto write_padding(OutputIt out, pad_type pad) -> OutputIt { + if (pad != pad_type::none) *out++ = pad == pad_type::space ? ' ' : '0'; + return out; +} + +// Parses a put_time-like format string and invokes handler actions. +template +FMT_CONSTEXPR auto parse_chrono_format(const Char* begin, const Char* end, + Handler&& handler) -> const Char* { + if (begin == end || *begin == '}') return begin; + if (*begin != '%') FMT_THROW(format_error("invalid format")); + auto ptr = begin; + while (ptr != end) { + pad_type pad = pad_type::zero; + auto c = *ptr; + if (c == '}') break; + if (c != '%') { + ++ptr; + continue; + } + if (begin != ptr) handler.on_text(begin, ptr); + ++ptr; // consume '%' + if (ptr == end) FMT_THROW(format_error("invalid format")); + c = *ptr; + switch (c) { + case '_': + pad = pad_type::space; + ++ptr; + break; + case '-': + pad = pad_type::none; + ++ptr; + break; + } + if (ptr == end) FMT_THROW(format_error("invalid format")); + c = *ptr++; + switch (c) { + case '%': handler.on_text(ptr - 1, ptr); break; + case 'n': { + const Char newline[] = {'\n'}; + handler.on_text(newline, newline + 1); + break; + } + case 't': { + const Char tab[] = {'\t'}; + handler.on_text(tab, tab + 1); + break; + } + // Year: + case 'Y': handler.on_year(numeric_system::standard, pad); break; + case 'y': handler.on_short_year(numeric_system::standard); break; + case 'C': handler.on_century(numeric_system::standard); break; + case 'G': handler.on_iso_week_based_year(); break; + case 'g': handler.on_iso_week_based_short_year(); break; + // Day of the week: + case 'a': handler.on_abbr_weekday(); break; + case 'A': handler.on_full_weekday(); break; + case 'w': handler.on_dec0_weekday(numeric_system::standard); break; + case 'u': handler.on_dec1_weekday(numeric_system::standard); break; + // Month: + case 'b': + case 'h': handler.on_abbr_month(); break; + case 'B': handler.on_full_month(); break; + case 'm': handler.on_dec_month(numeric_system::standard, pad); break; + // Day of the year/month: + case 'U': + handler.on_dec0_week_of_year(numeric_system::standard, pad); + break; + case 'W': + handler.on_dec1_week_of_year(numeric_system::standard, pad); + break; + case 'V': handler.on_iso_week_of_year(numeric_system::standard, pad); break; + case 'j': handler.on_day_of_year(pad); break; + case 'd': handler.on_day_of_month(numeric_system::standard, pad); break; + case 'e': + handler.on_day_of_month(numeric_system::standard, pad_type::space); + break; + // Hour, minute, second: + case 'H': handler.on_24_hour(numeric_system::standard, pad); break; + case 'I': handler.on_12_hour(numeric_system::standard, pad); break; + case 'M': handler.on_minute(numeric_system::standard, pad); break; + case 'S': handler.on_second(numeric_system::standard, pad); break; + // Other: + case 'c': handler.on_datetime(numeric_system::standard); break; + case 'x': handler.on_loc_date(numeric_system::standard); break; + case 'X': handler.on_loc_time(numeric_system::standard); break; + case 'D': handler.on_us_date(); break; + case 'F': handler.on_iso_date(); break; + case 'r': handler.on_12_hour_time(); break; + case 'R': handler.on_24_hour_time(); break; + case 'T': handler.on_iso_time(); break; + case 'p': handler.on_am_pm(); break; + case 'Q': handler.on_duration_value(); break; + case 'q': handler.on_duration_unit(); break; + case 'z': handler.on_utc_offset(numeric_system::standard); break; + case 'Z': handler.on_tz_name(); break; + // Alternative representation: + case 'E': { + if (ptr == end) FMT_THROW(format_error("invalid format")); + c = *ptr++; + switch (c) { + case 'Y': handler.on_year(numeric_system::alternative, pad); break; + case 'y': handler.on_offset_year(); break; + case 'C': handler.on_century(numeric_system::alternative); break; + case 'c': handler.on_datetime(numeric_system::alternative); break; + case 'x': handler.on_loc_date(numeric_system::alternative); break; + case 'X': handler.on_loc_time(numeric_system::alternative); break; + case 'z': handler.on_utc_offset(numeric_system::alternative); break; + default: FMT_THROW(format_error("invalid format")); + } + break; + } + case 'O': + if (ptr == end) FMT_THROW(format_error("invalid format")); + c = *ptr++; + switch (c) { + case 'y': handler.on_short_year(numeric_system::alternative); break; + case 'm': handler.on_dec_month(numeric_system::alternative, pad); break; + case 'U': + handler.on_dec0_week_of_year(numeric_system::alternative, pad); + break; + case 'W': + handler.on_dec1_week_of_year(numeric_system::alternative, pad); + break; + case 'V': + handler.on_iso_week_of_year(numeric_system::alternative, pad); + break; + case 'd': + handler.on_day_of_month(numeric_system::alternative, pad); + break; + case 'e': + handler.on_day_of_month(numeric_system::alternative, pad_type::space); + break; + case 'w': handler.on_dec0_weekday(numeric_system::alternative); break; + case 'u': handler.on_dec1_weekday(numeric_system::alternative); break; + case 'H': handler.on_24_hour(numeric_system::alternative, pad); break; + case 'I': handler.on_12_hour(numeric_system::alternative, pad); break; + case 'M': handler.on_minute(numeric_system::alternative, pad); break; + case 'S': handler.on_second(numeric_system::alternative, pad); break; + case 'z': handler.on_utc_offset(numeric_system::alternative); break; + default: FMT_THROW(format_error("invalid format")); + } + break; + default: FMT_THROW(format_error("invalid format")); + } + begin = ptr; + } + if (begin != ptr) handler.on_text(begin, ptr); + return ptr; +} + +template struct null_chrono_spec_handler { + FMT_CONSTEXPR void unsupported() { + static_cast(this)->unsupported(); + } + FMT_CONSTEXPR void on_year(numeric_system, pad_type) { unsupported(); } + FMT_CONSTEXPR void on_short_year(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_offset_year() { unsupported(); } + FMT_CONSTEXPR void on_century(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_iso_week_based_year() { unsupported(); } + FMT_CONSTEXPR void on_iso_week_based_short_year() { unsupported(); } + FMT_CONSTEXPR void on_abbr_weekday() { unsupported(); } + FMT_CONSTEXPR void on_full_weekday() { unsupported(); } + FMT_CONSTEXPR void on_dec0_weekday(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_dec1_weekday(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_abbr_month() { unsupported(); } + FMT_CONSTEXPR void on_full_month() { unsupported(); } + FMT_CONSTEXPR void on_dec_month(numeric_system, pad_type) { unsupported(); } + FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system, pad_type) { + unsupported(); + } + FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system, pad_type) { + unsupported(); + } + FMT_CONSTEXPR void on_iso_week_of_year(numeric_system, pad_type) { + unsupported(); + } + FMT_CONSTEXPR void on_day_of_year(pad_type) { unsupported(); } + FMT_CONSTEXPR void on_day_of_month(numeric_system, pad_type) { + unsupported(); + } + FMT_CONSTEXPR void on_24_hour(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_12_hour(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_minute(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_second(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_datetime(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_loc_date(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_loc_time(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_us_date() { unsupported(); } + FMT_CONSTEXPR void on_iso_date() { unsupported(); } + FMT_CONSTEXPR void on_12_hour_time() { unsupported(); } + FMT_CONSTEXPR void on_24_hour_time() { unsupported(); } + FMT_CONSTEXPR void on_iso_time() { unsupported(); } + FMT_CONSTEXPR void on_am_pm() { unsupported(); } + FMT_CONSTEXPR void on_duration_value() { unsupported(); } + FMT_CONSTEXPR void on_duration_unit() { unsupported(); } + FMT_CONSTEXPR void on_utc_offset(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_tz_name() { unsupported(); } +}; + +class tm_format_checker : public null_chrono_spec_handler { + private: + bool has_timezone_ = false; + + public: + constexpr explicit tm_format_checker(bool has_timezone) + : has_timezone_(has_timezone) {} + + FMT_NORETURN inline void unsupported() { + FMT_THROW(format_error("no format")); + } + + template + FMT_CONSTEXPR void on_text(const Char*, const Char*) {} + FMT_CONSTEXPR void on_year(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_short_year(numeric_system) {} + FMT_CONSTEXPR void on_offset_year() {} + FMT_CONSTEXPR void on_century(numeric_system) {} + FMT_CONSTEXPR void on_iso_week_based_year() {} + FMT_CONSTEXPR void on_iso_week_based_short_year() {} + FMT_CONSTEXPR void on_abbr_weekday() {} + FMT_CONSTEXPR void on_full_weekday() {} + FMT_CONSTEXPR void on_dec0_weekday(numeric_system) {} + FMT_CONSTEXPR void on_dec1_weekday(numeric_system) {} + FMT_CONSTEXPR void on_abbr_month() {} + FMT_CONSTEXPR void on_full_month() {} + FMT_CONSTEXPR void on_dec_month(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_iso_week_of_year(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_day_of_year(pad_type) {} + FMT_CONSTEXPR void on_day_of_month(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_second(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_datetime(numeric_system) {} + FMT_CONSTEXPR void on_loc_date(numeric_system) {} + FMT_CONSTEXPR void on_loc_time(numeric_system) {} + FMT_CONSTEXPR void on_us_date() {} + FMT_CONSTEXPR void on_iso_date() {} + FMT_CONSTEXPR void on_12_hour_time() {} + FMT_CONSTEXPR void on_24_hour_time() {} + FMT_CONSTEXPR void on_iso_time() {} + FMT_CONSTEXPR void on_am_pm() {} + FMT_CONSTEXPR void on_utc_offset(numeric_system) { + if (!has_timezone_) FMT_THROW(format_error("no timezone")); + } + FMT_CONSTEXPR void on_tz_name() { + if (!has_timezone_) FMT_THROW(format_error("no timezone")); + } +}; + +inline auto tm_wday_full_name(int wday) -> const char* { + static constexpr const char* full_name_list[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"}; + return wday >= 0 && wday <= 6 ? full_name_list[wday] : "?"; +} +inline auto tm_wday_short_name(int wday) -> const char* { + static constexpr const char* short_name_list[] = {"Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat"}; + return wday >= 0 && wday <= 6 ? short_name_list[wday] : "???"; +} + +inline auto tm_mon_full_name(int mon) -> const char* { + static constexpr const char* full_name_list[] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"}; + return mon >= 0 && mon <= 11 ? full_name_list[mon] : "?"; +} +inline auto tm_mon_short_name(int mon) -> const char* { + static constexpr const char* short_name_list[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + }; + return mon >= 0 && mon <= 11 ? short_name_list[mon] : "???"; +} + +template +struct has_tm_gmtoff : std::false_type {}; +template +struct has_tm_gmtoff> : std::true_type {}; + +template struct has_tm_zone : std::false_type {}; +template +struct has_tm_zone> : std::true_type {}; + +template ::value)> +auto set_tm_zone(T& time, char* tz) -> bool { + time.tm_zone = tz; + return true; +} +template ::value)> +auto set_tm_zone(T&, char*) -> bool { + return false; +} + +inline auto utc() -> char* { + static char tz[] = "UTC"; + return tz; +} + +// Converts value to Int and checks that it's in the range [0, upper). +template ::value)> +inline auto to_nonnegative_int(T value, Int upper) -> Int { + if (!std::is_unsigned::value && + (value < 0 || to_unsigned(value) > to_unsigned(upper))) { + FMT_THROW(format_error("chrono value is out of range")); + } + return static_cast(value); +} +template ::value)> +inline auto to_nonnegative_int(T value, Int upper) -> Int { + auto int_value = static_cast(value); + if (int_value < 0 || value > static_cast(upper)) + FMT_THROW(format_error("invalid value")); + return int_value; +} + +constexpr auto pow10(std::uint32_t n) -> long long { + return n == 0 ? 1 : 10 * pow10(n - 1); +} + +// Counts the number of fractional digits in the range [0, 18] according to the +// C++20 spec. If more than 18 fractional digits are required then returns 6 for +// microseconds precision. +template () / 10)> +struct count_fractional_digits { + static constexpr int value = + Num % Den == 0 ? N : count_fractional_digits::value; +}; + +// Base case that doesn't instantiate any more templates +// in order to avoid overflow. +template +struct count_fractional_digits { + static constexpr int value = (Num % Den == 0) ? N : 6; +}; + +// Format subseconds which are given as an integer type with an appropriate +// number of digits. +template +void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) { + constexpr auto num_fractional_digits = + count_fractional_digits::value; + + using subsecond_precision = std::chrono::duration< + typename std::common_type::type, + std::ratio<1, pow10(num_fractional_digits)>>; + + const auto fractional = d - detail::duration_cast(d); + const auto subseconds = + std::chrono::treat_as_floating_point< + typename subsecond_precision::rep>::value + ? fractional.count() + : detail::duration_cast(fractional).count(); + auto n = static_cast>(subseconds); + const int num_digits = count_digits(n); + + int leading_zeroes = (std::max)(0, num_fractional_digits - num_digits); + if (precision < 0) { + FMT_ASSERT(!std::is_floating_point::value, ""); + if (std::ratio_less::value) { + *out++ = '.'; + out = detail::fill_n(out, leading_zeroes, '0'); + out = format_decimal(out, n, num_digits); + } + } else if (precision > 0) { + *out++ = '.'; + leading_zeroes = min_of(leading_zeroes, precision); + int remaining = precision - leading_zeroes; + out = detail::fill_n(out, leading_zeroes, '0'); + if (remaining < num_digits) { + int num_truncated_digits = num_digits - remaining; + n /= to_unsigned(pow10(to_unsigned(num_truncated_digits))); + if (n != 0) out = format_decimal(out, n, remaining); + return; + } + if (n != 0) { + out = format_decimal(out, n, num_digits); + remaining -= num_digits; + } + out = detail::fill_n(out, remaining, '0'); + } +} + +// Format subseconds which are given as a floating point type with an +// appropriate number of digits. We cannot pass the Duration here, as we +// explicitly need to pass the Rep value in the duration_formatter. +template +void write_floating_seconds(memory_buffer& buf, Duration duration, + int num_fractional_digits = -1) { + using rep = typename Duration::rep; + FMT_ASSERT(std::is_floating_point::value, ""); + + auto val = duration.count(); + + if (num_fractional_digits < 0) { + // For `std::round` with fallback to `round`: + // On some toolchains `std::round` is not available (e.g. GCC 6). + using namespace std; + num_fractional_digits = + count_fractional_digits::value; + if (num_fractional_digits < 6 && static_cast(round(val)) != val) + num_fractional_digits = 6; + } + + fmt::format_to(std::back_inserter(buf), FMT_STRING("{:.{}f}"), + std::fmod(val * static_cast(Duration::period::num) / + static_cast(Duration::period::den), + static_cast(60)), + num_fractional_digits); +} + +template +class tm_writer { + private: + static constexpr int days_per_week = 7; + + const std::locale& loc_; + bool is_classic_; + OutputIt out_; + const Duration* subsecs_; + const std::tm& tm_; + + auto tm_sec() const noexcept -> int { + FMT_ASSERT(tm_.tm_sec >= 0 && tm_.tm_sec <= 61, ""); + return tm_.tm_sec; + } + auto tm_min() const noexcept -> int { + FMT_ASSERT(tm_.tm_min >= 0 && tm_.tm_min <= 59, ""); + return tm_.tm_min; + } + auto tm_hour() const noexcept -> int { + FMT_ASSERT(tm_.tm_hour >= 0 && tm_.tm_hour <= 23, ""); + return tm_.tm_hour; + } + auto tm_mday() const noexcept -> int { + FMT_ASSERT(tm_.tm_mday >= 1 && tm_.tm_mday <= 31, ""); + return tm_.tm_mday; + } + auto tm_mon() const noexcept -> int { + FMT_ASSERT(tm_.tm_mon >= 0 && tm_.tm_mon <= 11, ""); + return tm_.tm_mon; + } + auto tm_year() const noexcept -> long long { return 1900ll + tm_.tm_year; } + auto tm_wday() const noexcept -> int { + FMT_ASSERT(tm_.tm_wday >= 0 && tm_.tm_wday <= 6, ""); + return tm_.tm_wday; + } + auto tm_yday() const noexcept -> int { + FMT_ASSERT(tm_.tm_yday >= 0 && tm_.tm_yday <= 365, ""); + return tm_.tm_yday; + } + + auto tm_hour12() const noexcept -> int { + auto h = tm_hour(); + auto z = h < 12 ? h : h - 12; + return z == 0 ? 12 : z; + } + + // POSIX and the C Standard are unclear or inconsistent about what %C and %y + // do if the year is negative or exceeds 9999. Use the convention that %C + // concatenated with %y yields the same output as %Y, and that %Y contains at + // least 4 characters, with more only if necessary. + auto split_year_lower(long long year) const noexcept -> int { + auto l = year % 100; + if (l < 0) l = -l; // l in [0, 99] + return static_cast(l); + } + + // Algorithm: https://en.wikipedia.org/wiki/ISO_week_date. + auto iso_year_weeks(long long curr_year) const noexcept -> int { + auto prev_year = curr_year - 1; + auto curr_p = + (curr_year + curr_year / 4 - curr_year / 100 + curr_year / 400) % + days_per_week; + auto prev_p = + (prev_year + prev_year / 4 - prev_year / 100 + prev_year / 400) % + days_per_week; + return 52 + ((curr_p == 4 || prev_p == 3) ? 1 : 0); + } + auto iso_week_num(int tm_yday, int tm_wday) const noexcept -> int { + return (tm_yday + 11 - (tm_wday == 0 ? days_per_week : tm_wday)) / + days_per_week; + } + auto tm_iso_week_year() const noexcept -> long long { + auto year = tm_year(); + auto w = iso_week_num(tm_yday(), tm_wday()); + if (w < 1) return year - 1; + if (w > iso_year_weeks(year)) return year + 1; + return year; + } + auto tm_iso_week_of_year() const noexcept -> int { + auto year = tm_year(); + auto w = iso_week_num(tm_yday(), tm_wday()); + if (w < 1) return iso_year_weeks(year - 1); + if (w > iso_year_weeks(year)) return 1; + return w; + } + + void write1(int value) { + *out_++ = static_cast('0' + to_unsigned(value) % 10); + } + void write2(int value) { + const char* d = digits2(to_unsigned(value) % 100); + *out_++ = *d++; + *out_++ = *d; + } + void write2(int value, pad_type pad) { + unsigned int v = to_unsigned(value) % 100; + if (v >= 10) { + const char* d = digits2(v); + *out_++ = *d++; + *out_++ = *d; + } else { + out_ = detail::write_padding(out_, pad); + *out_++ = static_cast('0' + v); + } + } + + void write_year_extended(long long year, pad_type pad) { + // At least 4 characters. + int width = 4; + bool negative = year < 0; + if (negative) { + year = 0 - year; + --width; + } + uint32_or_64_or_128_t n = to_unsigned(year); + const int num_digits = count_digits(n); + if (negative && pad == pad_type::zero) *out_++ = '-'; + if (width > num_digits) + out_ = detail::write_padding(out_, pad, width - num_digits); + if (negative && pad != pad_type::zero) *out_++ = '-'; + out_ = format_decimal(out_, n, num_digits); + } + void write_year(long long year, pad_type pad) { + write_year_extended(year, pad); + } + + void write_utc_offset(long long offset, numeric_system ns) { + if (offset < 0) { + *out_++ = '-'; + offset = -offset; + } else { + *out_++ = '+'; + } + offset /= 60; + write2(static_cast(offset / 60)); + if (ns != numeric_system::standard) *out_++ = ':'; + write2(static_cast(offset % 60)); + } + + template ::value)> + void format_utc_offset(const T& tm, numeric_system ns) { + write_utc_offset(tm.tm_gmtoff, ns); + } + template ::value)> + void format_utc_offset(const T&, numeric_system ns) { + write_utc_offset(0, ns); + } + + template ::value)> + void format_tz_name(const T& tm) { + out_ = write_tm_str(out_, tm.tm_zone, loc_); + } + template ::value)> + void format_tz_name(const T&) { + out_ = std::copy_n(utc(), 3, out_); + } + + void format_localized(char format, char modifier = 0) { + out_ = write(out_, tm_, loc_, format, modifier); + } + + public: + tm_writer(const std::locale& loc, OutputIt out, const std::tm& tm, + const Duration* subsecs = nullptr) + : loc_(loc), + is_classic_(loc_ == get_classic_locale()), + out_(out), + subsecs_(subsecs), + tm_(tm) {} + + auto out() const -> OutputIt { return out_; } + + FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) { + out_ = copy(begin, end, out_); + } + + void on_abbr_weekday() { + if (is_classic_) + out_ = write(out_, tm_wday_short_name(tm_wday())); + else + format_localized('a'); + } + void on_full_weekday() { + if (is_classic_) + out_ = write(out_, tm_wday_full_name(tm_wday())); + else + format_localized('A'); + } + void on_dec0_weekday(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) return write1(tm_wday()); + format_localized('w', 'O'); + } + void on_dec1_weekday(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) { + auto wday = tm_wday(); + write1(wday == 0 ? days_per_week : wday); + } else { + format_localized('u', 'O'); + } + } + + void on_abbr_month() { + if (is_classic_) + out_ = write(out_, tm_mon_short_name(tm_mon())); + else + format_localized('b'); + } + void on_full_month() { + if (is_classic_) + out_ = write(out_, tm_mon_full_name(tm_mon())); + else + format_localized('B'); + } + + void on_datetime(numeric_system ns) { + if (is_classic_) { + on_abbr_weekday(); + *out_++ = ' '; + on_abbr_month(); + *out_++ = ' '; + on_day_of_month(numeric_system::standard, pad_type::space); + *out_++ = ' '; + on_iso_time(); + *out_++ = ' '; + on_year(numeric_system::standard, pad_type::space); + } else { + format_localized('c', ns == numeric_system::standard ? '\0' : 'E'); + } + } + void on_loc_date(numeric_system ns) { + if (is_classic_) + on_us_date(); + else + format_localized('x', ns == numeric_system::standard ? '\0' : 'E'); + } + void on_loc_time(numeric_system ns) { + if (is_classic_) + on_iso_time(); + else + format_localized('X', ns == numeric_system::standard ? '\0' : 'E'); + } + void on_us_date() { + char buf[8]; + write_digit2_separated(buf, to_unsigned(tm_mon() + 1), + to_unsigned(tm_mday()), + to_unsigned(split_year_lower(tm_year())), '/'); + out_ = copy(std::begin(buf), std::end(buf), out_); + } + void on_iso_date() { + auto year = tm_year(); + char buf[10]; + size_t offset = 0; + if (year >= 0 && year < 10000) { + write2digits(buf, static_cast(year / 100)); + } else { + offset = 4; + write_year_extended(year, pad_type::zero); + year = 0; + } + write_digit2_separated(buf + 2, static_cast(year % 100), + to_unsigned(tm_mon() + 1), to_unsigned(tm_mday()), + '-'); + out_ = copy(std::begin(buf) + offset, std::end(buf), out_); + } + + void on_utc_offset(numeric_system ns) { format_utc_offset(tm_, ns); } + void on_tz_name() { format_tz_name(tm_); } + + void on_year(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) + return write_year(tm_year(), pad); + format_localized('Y', 'E'); + } + void on_short_year(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) + return write2(split_year_lower(tm_year())); + format_localized('y', 'O'); + } + void on_offset_year() { + if (is_classic_) return write2(split_year_lower(tm_year())); + format_localized('y', 'E'); + } + + void on_century(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) { + auto year = tm_year(); + auto upper = year / 100; + if (year >= -99 && year < 0) { + // Zero upper on negative year. + *out_++ = '-'; + *out_++ = '0'; + } else if (upper >= 0 && upper < 100) { + write2(static_cast(upper)); + } else { + out_ = write(out_, upper); + } + } else { + format_localized('C', 'E'); + } + } + + void on_dec_month(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) + return write2(tm_mon() + 1, pad); + format_localized('m', 'O'); + } + + void on_dec0_week_of_year(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) + return write2((tm_yday() + days_per_week - tm_wday()) / days_per_week, + pad); + format_localized('U', 'O'); + } + void on_dec1_week_of_year(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) { + auto wday = tm_wday(); + write2((tm_yday() + days_per_week - + (wday == 0 ? (days_per_week - 1) : (wday - 1))) / + days_per_week, + pad); + } else { + format_localized('W', 'O'); + } + } + void on_iso_week_of_year(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) + return write2(tm_iso_week_of_year(), pad); + format_localized('V', 'O'); + } + + void on_iso_week_based_year() { + write_year(tm_iso_week_year(), pad_type::zero); + } + void on_iso_week_based_short_year() { + write2(split_year_lower(tm_iso_week_year())); + } + + void on_day_of_year(pad_type pad) { + auto yday = tm_yday() + 1; + auto digit1 = yday / 100; + if (digit1 != 0) + write1(digit1); + else + out_ = detail::write_padding(out_, pad); + write2(yday % 100, pad); + } + + void on_day_of_month(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) + return write2(tm_mday(), pad); + format_localized('d', 'O'); + } + + void on_24_hour(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) + return write2(tm_hour(), pad); + format_localized('H', 'O'); + } + void on_12_hour(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) + return write2(tm_hour12(), pad); + format_localized('I', 'O'); + } + void on_minute(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) + return write2(tm_min(), pad); + format_localized('M', 'O'); + } + + void on_second(numeric_system ns, pad_type pad) { + if (is_classic_ || ns == numeric_system::standard) { + write2(tm_sec(), pad); + if (subsecs_) { + if (std::is_floating_point::value) { + auto buf = memory_buffer(); + write_floating_seconds(buf, *subsecs_); + if (buf.size() > 1) { + // Remove the leading "0", write something like ".123". + out_ = copy(buf.begin() + 1, buf.end(), out_); + } + } else { + write_fractional_seconds(out_, *subsecs_); + } + } + } else { + // Currently no formatting of subseconds when a locale is set. + format_localized('S', 'O'); + } + } + + void on_12_hour_time() { + if (is_classic_) { + char buf[8]; + write_digit2_separated(buf, to_unsigned(tm_hour12()), + to_unsigned(tm_min()), to_unsigned(tm_sec()), ':'); + out_ = copy(std::begin(buf), std::end(buf), out_); + *out_++ = ' '; + on_am_pm(); + } else { + format_localized('r'); + } + } + void on_24_hour_time() { + write2(tm_hour()); + *out_++ = ':'; + write2(tm_min()); + } + void on_iso_time() { + on_24_hour_time(); + *out_++ = ':'; + on_second(numeric_system::standard, pad_type::zero); + } + + void on_am_pm() { + if (is_classic_) { + *out_++ = tm_hour() < 12 ? 'A' : 'P'; + *out_++ = 'M'; + } else { + format_localized('p'); + } + } + + // These apply to chrono durations but not tm. + void on_duration_value() {} + void on_duration_unit() {} +}; + +struct chrono_format_checker : null_chrono_spec_handler { + bool has_precision_integral = false; + + FMT_NORETURN inline void unsupported() { FMT_THROW(format_error("no date")); } + + template + FMT_CONSTEXPR void on_text(const Char*, const Char*) {} + FMT_CONSTEXPR void on_day_of_year(pad_type) {} + FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_second(numeric_system, pad_type) {} + FMT_CONSTEXPR void on_12_hour_time() {} + FMT_CONSTEXPR void on_24_hour_time() {} + FMT_CONSTEXPR void on_iso_time() {} + FMT_CONSTEXPR void on_am_pm() {} + FMT_CONSTEXPR void on_duration_value() const { + if (has_precision_integral) + FMT_THROW(format_error("precision not allowed for this argument type")); + } + FMT_CONSTEXPR void on_duration_unit() {} +}; + +template ::value&& has_isfinite::value)> +inline auto isfinite(T) -> bool { + return true; +} + +template ::value)> +inline auto mod(T x, int y) -> T { + return x % static_cast(y); +} +template ::value)> +inline auto mod(T x, int y) -> T { + return std::fmod(x, static_cast(y)); +} + +// If T is an integral type, maps T to its unsigned counterpart, otherwise +// leaves it unchanged (unlike std::make_unsigned). +template ::value> +struct make_unsigned_or_unchanged { + using type = T; +}; + +template struct make_unsigned_or_unchanged { + using type = typename std::make_unsigned::type; +}; + +template ::value)> +inline auto get_milliseconds(std::chrono::duration d) + -> std::chrono::duration { + // This may overflow and/or the result may not fit in the target type. +#if FMT_SAFE_DURATION_CAST + using common_seconds_type = + typename std::common_type::type; + auto d_as_common = detail::duration_cast(d); + auto d_as_whole_seconds = + detail::duration_cast(d_as_common); + // This conversion should be nonproblematic. + auto diff = d_as_common - d_as_whole_seconds; + auto ms = detail::duration_cast>(diff); + return ms; +#else + auto s = detail::duration_cast(d); + return detail::duration_cast(d - s); +#endif +} + +template ::value)> +auto format_duration_value(OutputIt out, Rep val, int) -> OutputIt { + return write(out, val); +} + +template ::value)> +auto format_duration_value(OutputIt out, Rep val, int precision) -> OutputIt { + auto specs = format_specs(); + specs.precision = precision; + specs.set_type(precision >= 0 ? presentation_type::fixed + : presentation_type::general); + return write(out, val, specs); +} + +template +auto copy_unit(string_view unit, OutputIt out, Char) -> OutputIt { + return copy(unit.begin(), unit.end(), out); +} + +template +auto copy_unit(string_view unit, OutputIt out, wchar_t) -> OutputIt { + // This works when wchar_t is UTF-32 because units only contain characters + // that have the same representation in UTF-16 and UTF-32. + utf8_to_utf16 u(unit); + return copy(u.c_str(), u.c_str() + u.size(), out); +} + +template +auto format_duration_unit(OutputIt out) -> OutputIt { + if (const char* unit = get_units()) + return copy_unit(string_view(unit), out, Char()); + *out++ = '['; + out = write(out, Period::num); + if (const_check(Period::den != 1)) { + *out++ = '/'; + out = write(out, Period::den); + } + *out++ = ']'; + *out++ = 's'; + return out; +} + +class get_locale { + private: + union { + std::locale locale_; + }; + bool has_locale_ = false; + + public: + inline get_locale(bool localized, locale_ref loc) : has_locale_(localized) { + if (!localized) return; + ignore_unused(loc); + ::new (&locale_) std::locale( +#if FMT_USE_LOCALE + loc.template get() +#endif + ); + } + inline ~get_locale() { + if (has_locale_) locale_.~locale(); + } + inline operator const std::locale&() const { + return has_locale_ ? locale_ : get_classic_locale(); + } +}; + +template +struct duration_formatter { + using iterator = basic_appender; + iterator out; + // rep is unsigned to avoid overflow. + using rep = + conditional_t::value && sizeof(Rep) < sizeof(int), + unsigned, typename make_unsigned_or_unchanged::type>; + rep val; + int precision; + locale_ref locale; + bool localized = false; + using seconds = std::chrono::duration; + seconds s; + using milliseconds = std::chrono::duration; + bool negative; + + using tm_writer_type = tm_writer; + + duration_formatter(iterator o, std::chrono::duration d, + locale_ref loc) + : out(o), val(static_cast(d.count())), locale(loc), negative(false) { + if (d.count() < 0) { + val = 0 - val; + negative = true; + } + + // this may overflow and/or the result may not fit in the + // target type. + // might need checked conversion (rep!=Rep) + s = detail::duration_cast(std::chrono::duration(val)); + } + + // returns true if nan or inf, writes to out. + auto handle_nan_inf() -> bool { + if (isfinite(val)) return false; + if (isnan(val)) { + write_nan(); + return true; + } + // must be +-inf + if (val > 0) + std::copy_n("inf", 3, out); + else + std::copy_n("-inf", 4, out); + return true; + } + + auto days() const -> Rep { return static_cast(s.count() / 86400); } + auto hour() const -> Rep { + return static_cast(mod((s.count() / 3600), 24)); + } + + auto hour12() const -> Rep { + Rep hour = static_cast(mod((s.count() / 3600), 12)); + return hour <= 0 ? 12 : hour; + } + + auto minute() const -> Rep { + return static_cast(mod((s.count() / 60), 60)); + } + auto second() const -> Rep { return static_cast(mod(s.count(), 60)); } + + auto time() const -> std::tm { + auto time = std::tm(); + time.tm_hour = to_nonnegative_int(hour(), 24); + time.tm_min = to_nonnegative_int(minute(), 60); + time.tm_sec = to_nonnegative_int(second(), 60); + return time; + } + + void write_sign() { + if (!negative) return; + *out++ = '-'; + negative = false; + } + + void write(Rep value, int width, pad_type pad = pad_type::zero) { + write_sign(); + if (isnan(value)) return write_nan(); + uint32_or_64_or_128_t n = + to_unsigned(to_nonnegative_int(value, max_value())); + int num_digits = detail::count_digits(n); + if (width > num_digits) { + out = detail::write_padding(out, pad, width - num_digits); + } + out = format_decimal(out, n, num_digits); + } + + void write_nan() { std::copy_n("nan", 3, out); } + + template + void format_tm(const tm& time, Callback cb, Args... args) { + if (isnan(val)) return write_nan(); + get_locale loc(localized, locale); + auto w = tm_writer_type(loc, out, time); + (w.*cb)(args...); + out = w.out(); + } + + void on_text(const Char* begin, const Char* end) { + copy(begin, end, out); + } + + // These are not implemented because durations don't have date information. + void on_abbr_weekday() {} + void on_full_weekday() {} + void on_dec0_weekday(numeric_system) {} + void on_dec1_weekday(numeric_system) {} + void on_abbr_month() {} + void on_full_month() {} + void on_datetime(numeric_system) {} + void on_loc_date(numeric_system) {} + void on_loc_time(numeric_system) {} + void on_us_date() {} + void on_iso_date() {} + void on_utc_offset(numeric_system) {} + void on_tz_name() {} + void on_year(numeric_system, pad_type) {} + void on_short_year(numeric_system) {} + void on_offset_year() {} + void on_century(numeric_system) {} + void on_iso_week_based_year() {} + void on_iso_week_based_short_year() {} + void on_dec_month(numeric_system, pad_type) {} + void on_dec0_week_of_year(numeric_system, pad_type) {} + void on_dec1_week_of_year(numeric_system, pad_type) {} + void on_iso_week_of_year(numeric_system, pad_type) {} + void on_day_of_month(numeric_system, pad_type) {} + + void on_day_of_year(pad_type) { + if (handle_nan_inf()) return; + write(days(), 0); + } + + void on_24_hour(numeric_system ns, pad_type pad) { + if (handle_nan_inf()) return; + + if (ns == numeric_system::standard) return write(hour(), 2, pad); + auto time = tm(); + time.tm_hour = to_nonnegative_int(hour(), 24); + format_tm(time, &tm_writer_type::on_24_hour, ns, pad); + } + + void on_12_hour(numeric_system ns, pad_type pad) { + if (handle_nan_inf()) return; + + if (ns == numeric_system::standard) return write(hour12(), 2, pad); + auto time = tm(); + time.tm_hour = to_nonnegative_int(hour12(), 12); + format_tm(time, &tm_writer_type::on_12_hour, ns, pad); + } + + void on_minute(numeric_system ns, pad_type pad) { + if (handle_nan_inf()) return; + + if (ns == numeric_system::standard) return write(minute(), 2, pad); + auto time = tm(); + time.tm_min = to_nonnegative_int(minute(), 60); + format_tm(time, &tm_writer_type::on_minute, ns, pad); + } + + void on_second(numeric_system ns, pad_type pad) { + if (handle_nan_inf()) return; + + if (ns == numeric_system::standard) { + if (std::is_floating_point::value) { + auto buf = memory_buffer(); + write_floating_seconds(buf, std::chrono::duration(val), + precision); + if (negative) *out++ = '-'; + if (buf.size() < 2 || buf[1] == '.') + out = detail::write_padding(out, pad); + out = copy(buf.begin(), buf.end(), out); + } else { + write(second(), 2, pad); + write_fractional_seconds( + out, std::chrono::duration(val), precision); + } + return; + } + auto time = tm(); + time.tm_sec = to_nonnegative_int(second(), 60); + format_tm(time, &tm_writer_type::on_second, ns, pad); + } + + void on_12_hour_time() { + if (handle_nan_inf()) return; + format_tm(time(), &tm_writer_type::on_12_hour_time); + } + + void on_24_hour_time() { + if (handle_nan_inf()) { + *out++ = ':'; + handle_nan_inf(); + return; + } + + write(hour(), 2); + *out++ = ':'; + write(minute(), 2); + } + + void on_iso_time() { + on_24_hour_time(); + *out++ = ':'; + if (handle_nan_inf()) return; + on_second(numeric_system::standard, pad_type::zero); + } + + void on_am_pm() { + if (handle_nan_inf()) return; + format_tm(time(), &tm_writer_type::on_am_pm); + } + + void on_duration_value() { + if (handle_nan_inf()) return; + write_sign(); + out = format_duration_value(out, val, precision); + } + + void on_duration_unit() { out = format_duration_unit(out); } +}; + +} // namespace detail + +#if defined(__cpp_lib_chrono) && __cpp_lib_chrono >= 201907 +using weekday = std::chrono::weekday; +using day = std::chrono::day; +using month = std::chrono::month; +using year = std::chrono::year; +using year_month_day = std::chrono::year_month_day; +#else +// A fallback version of weekday. +class weekday { + private: + unsigned char value_; + + public: + weekday() = default; + constexpr explicit weekday(unsigned wd) noexcept + : value_(static_cast(wd != 7 ? wd : 0)) {} + constexpr auto c_encoding() const noexcept -> unsigned { return value_; } +}; + +class day { + private: + unsigned char value_; + + public: + day() = default; + constexpr explicit day(unsigned d) noexcept + : value_(static_cast(d)) {} + constexpr explicit operator unsigned() const noexcept { return value_; } +}; + +class month { + private: + unsigned char value_; + + public: + month() = default; + constexpr explicit month(unsigned m) noexcept + : value_(static_cast(m)) {} + constexpr explicit operator unsigned() const noexcept { return value_; } +}; + +class year { + private: + int value_; + + public: + year() = default; + constexpr explicit year(int y) noexcept : value_(y) {} + constexpr explicit operator int() const noexcept { return value_; } +}; + +class year_month_day { + private: + fmt::year year_; + fmt::month month_; + fmt::day day_; + + public: + year_month_day() = default; + constexpr year_month_day(const year& y, const month& m, const day& d) noexcept + : year_(y), month_(m), day_(d) {} + constexpr auto year() const noexcept -> fmt::year { return year_; } + constexpr auto month() const noexcept -> fmt::month { return month_; } + constexpr auto day() const noexcept -> fmt::day { return day_; } +}; +#endif // __cpp_lib_chrono >= 201907 + +template +struct formatter : private formatter { + private: + bool use_tm_formatter_ = false; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(), end = ctx.end(); + if (it != end && *it == 'L') { + ++it; + this->set_localized(); + } + use_tm_formatter_ = it != end && *it != '}'; + return use_tm_formatter_ ? formatter::parse(ctx) : it; + } + + template + auto format(weekday wd, FormatContext& ctx) const -> decltype(ctx.out()) { + auto time = std::tm(); + time.tm_wday = static_cast(wd.c_encoding()); + if (use_tm_formatter_) return formatter::format(time, ctx); + detail::get_locale loc(this->localized(), ctx.locale()); + auto w = detail::tm_writer(loc, ctx.out(), time); + w.on_abbr_weekday(); + return w.out(); + } +}; + +template +struct formatter : private formatter { + private: + bool use_tm_formatter_ = false; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(), end = ctx.end(); + use_tm_formatter_ = it != end && *it != '}'; + return use_tm_formatter_ ? formatter::parse(ctx) : it; + } + + template + auto format(day d, FormatContext& ctx) const -> decltype(ctx.out()) { + auto time = std::tm(); + time.tm_mday = static_cast(static_cast(d)); + if (use_tm_formatter_) return formatter::format(time, ctx); + detail::get_locale loc(false, ctx.locale()); + auto w = detail::tm_writer(loc, ctx.out(), time); + w.on_day_of_month(detail::numeric_system::standard, detail::pad_type::zero); + return w.out(); + } +}; + +template +struct formatter : private formatter { + private: + bool use_tm_formatter_ = false; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(), end = ctx.end(); + if (it != end && *it == 'L') { + ++it; + this->set_localized(); + } + use_tm_formatter_ = it != end && *it != '}'; + return use_tm_formatter_ ? formatter::parse(ctx) : it; + } + + template + auto format(month m, FormatContext& ctx) const -> decltype(ctx.out()) { + auto time = std::tm(); + time.tm_mon = static_cast(static_cast(m)) - 1; + if (use_tm_formatter_) return formatter::format(time, ctx); + detail::get_locale loc(this->localized(), ctx.locale()); + auto w = detail::tm_writer(loc, ctx.out(), time); + w.on_abbr_month(); + return w.out(); + } +}; + +template +struct formatter : private formatter { + private: + bool use_tm_formatter_ = false; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(), end = ctx.end(); + use_tm_formatter_ = it != end && *it != '}'; + return use_tm_formatter_ ? formatter::parse(ctx) : it; + } + + template + auto format(year y, FormatContext& ctx) const -> decltype(ctx.out()) { + auto time = std::tm(); + time.tm_year = static_cast(y) - 1900; + if (use_tm_formatter_) return formatter::format(time, ctx); + detail::get_locale loc(false, ctx.locale()); + auto w = detail::tm_writer(loc, ctx.out(), time); + w.on_year(detail::numeric_system::standard, detail::pad_type::zero); + return w.out(); + } +}; + +template +struct formatter : private formatter { + private: + bool use_tm_formatter_ = false; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(), end = ctx.end(); + use_tm_formatter_ = it != end && *it != '}'; + return use_tm_formatter_ ? formatter::parse(ctx) : it; + } + + template + auto format(year_month_day val, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto time = std::tm(); + time.tm_year = static_cast(val.year()) - 1900; + time.tm_mon = static_cast(static_cast(val.month())) - 1; + time.tm_mday = static_cast(static_cast(val.day())); + if (use_tm_formatter_) return formatter::format(time, ctx); + detail::get_locale loc(true, ctx.locale()); + auto w = detail::tm_writer(loc, ctx.out(), time); + w.on_iso_date(); + return w.out(); + } +}; + +template +struct formatter, Char> { + private: + format_specs specs_; + detail::arg_ref width_ref_; + detail::arg_ref precision_ref_; + basic_string_view fmt_; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(), end = ctx.end(); + if (it == end || *it == '}') return it; + + it = detail::parse_align(it, end, specs_); + if (it == end) return it; + + Char c = *it; + if ((c >= '0' && c <= '9') || c == '{') { + it = detail::parse_width(it, end, specs_, width_ref_, ctx); + if (it == end) return it; + } + + auto checker = detail::chrono_format_checker(); + if (*it == '.') { + checker.has_precision_integral = !std::is_floating_point::value; + it = detail::parse_precision(it, end, specs_, precision_ref_, ctx); + } + if (it != end && *it == 'L') { + specs_.set_localized(); + ++it; + } + end = detail::parse_chrono_format(it, end, checker); + fmt_ = {it, detail::to_unsigned(end - it)}; + return end; + } + + template + auto format(std::chrono::duration d, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto specs = specs_; + auto precision = specs.precision; + specs.precision = -1; + auto begin = fmt_.begin(), end = fmt_.end(); + // As a possible future optimization, we could avoid extra copying if width + // is not specified. + auto buf = basic_memory_buffer(); + auto out = basic_appender(buf); + detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, + ctx); + detail::handle_dynamic_spec(specs.dynamic_precision(), precision, + precision_ref_, ctx); + if (begin == end || *begin == '}') { + out = detail::format_duration_value(out, d.count(), precision); + detail::format_duration_unit(out); + } else { + auto f = + detail::duration_formatter(out, d, ctx.locale()); + f.precision = precision; + f.localized = specs_.localized(); + detail::parse_chrono_format(begin, end, f); + } + return detail::write( + ctx.out(), basic_string_view(buf.data(), buf.size()), specs); + } +}; + +template struct formatter { + private: + format_specs specs_; + detail::arg_ref width_ref_; + basic_string_view fmt_ = + detail::string_literal(); + + protected: + auto localized() const -> bool { return specs_.localized(); } + FMT_CONSTEXPR void set_localized() { specs_.set_localized(); } + + FMT_CONSTEXPR auto do_parse(parse_context& ctx, bool has_timezone) + -> const Char* { + auto it = ctx.begin(), end = ctx.end(); + if (it == end || *it == '}') return it; + + it = detail::parse_align(it, end, specs_); + if (it == end) return it; + + Char c = *it; + if ((c >= '0' && c <= '9') || c == '{') { + it = detail::parse_width(it, end, specs_, width_ref_, ctx); + if (it == end) return it; + } + + if (*it == 'L') { + specs_.set_localized(); + ++it; + } + + end = detail::parse_chrono_format(it, end, + detail::tm_format_checker(has_timezone)); + // Replace the default format string only if the new spec is not empty. + if (end != it) fmt_ = {it, detail::to_unsigned(end - it)}; + return end; + } + + template + auto do_format(const std::tm& tm, FormatContext& ctx, + const Duration* subsecs) const -> decltype(ctx.out()) { + auto specs = specs_; + auto buf = basic_memory_buffer(); + auto out = basic_appender(buf); + detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, + ctx); + + auto loc_ref = specs.localized() ? ctx.locale() : locale_ref(); + detail::get_locale loc(static_cast(loc_ref), loc_ref); + auto w = detail::tm_writer, Char, Duration>( + loc, out, tm, subsecs); + detail::parse_chrono_format(fmt_.begin(), fmt_.end(), w); + return detail::write( + ctx.out(), basic_string_view(buf.data(), buf.size()), specs); + } + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return do_parse(ctx, detail::has_tm_gmtoff::value); + } + + template + auto format(const std::tm& tm, FormatContext& ctx) const + -> decltype(ctx.out()) { + return do_format(tm, ctx, nullptr); + } +}; + +// DEPRECATED! Reversed order of template parameters. +template +struct formatter, Char> : private formatter { + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return this->do_parse(ctx, true); + } + + template + auto format(sys_time val, FormatContext& ctx) const + -> decltype(ctx.out()) { + std::tm tm = gmtime(val); + using period = typename Duration::period; + if (detail::const_check( + period::num == 1 && period::den == 1 && + !std::is_floating_point::value)) { + detail::set_tm_zone(tm, detail::utc()); + return formatter::format(tm, ctx); + } + Duration epoch = val.time_since_epoch(); + Duration subsecs = detail::duration_cast( + epoch - detail::duration_cast(epoch)); + if (subsecs.count() < 0) { + auto second = detail::duration_cast(std::chrono::seconds(1)); + if (tm.tm_sec != 0) { + --tm.tm_sec; + } else { + tm = gmtime(val - second); + detail::set_tm_zone(tm, detail::utc()); + } + subsecs += second; + } + return formatter::do_format(tm, ctx, &subsecs); + } +}; + +template +struct formatter, Char> + : formatter, Char> { + template + auto format(utc_time val, FormatContext& ctx) const + -> decltype(ctx.out()) { + return formatter, Char>::format( + detail::utc_clock::to_sys(val), ctx); + } +}; + +template +struct formatter, Char> + : private formatter { + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return this->do_parse(ctx, false); + } + + template + auto format(local_time val, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto time_since_epoch = val.time_since_epoch(); + auto seconds_since_epoch = + detail::duration_cast(time_since_epoch); + // Use gmtime to prevent time zone conversion since local_time has an + // unspecified time zone. + std::tm t = gmtime(seconds_since_epoch.count()); + using period = typename Duration::period; + if (period::num == 1 && period::den == 1 && + !std::is_floating_point::value) { + return formatter::format(t, ctx); + } + auto subsecs = + detail::duration_cast(time_since_epoch - seconds_since_epoch); + return formatter::do_format(t, ctx, &subsecs); + } +}; + +FMT_END_EXPORT +FMT_END_NAMESPACE + +#endif // FMT_CHRONO_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/color.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/color.h new file mode 100644 index 0000000000000000000000000000000000000000..3246ddceea28f0df7c347a5661d597e21a149edc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/color.h @@ -0,0 +1,642 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - color support +// +// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_COLOR_H_ +#define FMT_COLOR_H_ + +#include "format.h" + +FMT_BEGIN_NAMESPACE +FMT_BEGIN_EXPORT + +enum class color : uint32_t { + alice_blue = 0xF0F8FF, // rgb(240,248,255) + antique_white = 0xFAEBD7, // rgb(250,235,215) + aqua = 0x00FFFF, // rgb(0,255,255) + aquamarine = 0x7FFFD4, // rgb(127,255,212) + azure = 0xF0FFFF, // rgb(240,255,255) + beige = 0xF5F5DC, // rgb(245,245,220) + bisque = 0xFFE4C4, // rgb(255,228,196) + black = 0x000000, // rgb(0,0,0) + blanched_almond = 0xFFEBCD, // rgb(255,235,205) + blue = 0x0000FF, // rgb(0,0,255) + blue_violet = 0x8A2BE2, // rgb(138,43,226) + brown = 0xA52A2A, // rgb(165,42,42) + burly_wood = 0xDEB887, // rgb(222,184,135) + cadet_blue = 0x5F9EA0, // rgb(95,158,160) + chartreuse = 0x7FFF00, // rgb(127,255,0) + chocolate = 0xD2691E, // rgb(210,105,30) + coral = 0xFF7F50, // rgb(255,127,80) + cornflower_blue = 0x6495ED, // rgb(100,149,237) + cornsilk = 0xFFF8DC, // rgb(255,248,220) + crimson = 0xDC143C, // rgb(220,20,60) + cyan = 0x00FFFF, // rgb(0,255,255) + dark_blue = 0x00008B, // rgb(0,0,139) + dark_cyan = 0x008B8B, // rgb(0,139,139) + dark_golden_rod = 0xB8860B, // rgb(184,134,11) + dark_gray = 0xA9A9A9, // rgb(169,169,169) + dark_green = 0x006400, // rgb(0,100,0) + dark_khaki = 0xBDB76B, // rgb(189,183,107) + dark_magenta = 0x8B008B, // rgb(139,0,139) + dark_olive_green = 0x556B2F, // rgb(85,107,47) + dark_orange = 0xFF8C00, // rgb(255,140,0) + dark_orchid = 0x9932CC, // rgb(153,50,204) + dark_red = 0x8B0000, // rgb(139,0,0) + dark_salmon = 0xE9967A, // rgb(233,150,122) + dark_sea_green = 0x8FBC8F, // rgb(143,188,143) + dark_slate_blue = 0x483D8B, // rgb(72,61,139) + dark_slate_gray = 0x2F4F4F, // rgb(47,79,79) + dark_turquoise = 0x00CED1, // rgb(0,206,209) + dark_violet = 0x9400D3, // rgb(148,0,211) + deep_pink = 0xFF1493, // rgb(255,20,147) + deep_sky_blue = 0x00BFFF, // rgb(0,191,255) + dim_gray = 0x696969, // rgb(105,105,105) + dodger_blue = 0x1E90FF, // rgb(30,144,255) + fire_brick = 0xB22222, // rgb(178,34,34) + floral_white = 0xFFFAF0, // rgb(255,250,240) + forest_green = 0x228B22, // rgb(34,139,34) + fuchsia = 0xFF00FF, // rgb(255,0,255) + gainsboro = 0xDCDCDC, // rgb(220,220,220) + ghost_white = 0xF8F8FF, // rgb(248,248,255) + gold = 0xFFD700, // rgb(255,215,0) + golden_rod = 0xDAA520, // rgb(218,165,32) + gray = 0x808080, // rgb(128,128,128) + green = 0x008000, // rgb(0,128,0) + green_yellow = 0xADFF2F, // rgb(173,255,47) + honey_dew = 0xF0FFF0, // rgb(240,255,240) + hot_pink = 0xFF69B4, // rgb(255,105,180) + indian_red = 0xCD5C5C, // rgb(205,92,92) + indigo = 0x4B0082, // rgb(75,0,130) + ivory = 0xFFFFF0, // rgb(255,255,240) + khaki = 0xF0E68C, // rgb(240,230,140) + lavender = 0xE6E6FA, // rgb(230,230,250) + lavender_blush = 0xFFF0F5, // rgb(255,240,245) + lawn_green = 0x7CFC00, // rgb(124,252,0) + lemon_chiffon = 0xFFFACD, // rgb(255,250,205) + light_blue = 0xADD8E6, // rgb(173,216,230) + light_coral = 0xF08080, // rgb(240,128,128) + light_cyan = 0xE0FFFF, // rgb(224,255,255) + light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210) + light_gray = 0xD3D3D3, // rgb(211,211,211) + light_green = 0x90EE90, // rgb(144,238,144) + light_pink = 0xFFB6C1, // rgb(255,182,193) + light_salmon = 0xFFA07A, // rgb(255,160,122) + light_sea_green = 0x20B2AA, // rgb(32,178,170) + light_sky_blue = 0x87CEFA, // rgb(135,206,250) + light_slate_gray = 0x778899, // rgb(119,136,153) + light_steel_blue = 0xB0C4DE, // rgb(176,196,222) + light_yellow = 0xFFFFE0, // rgb(255,255,224) + lime = 0x00FF00, // rgb(0,255,0) + lime_green = 0x32CD32, // rgb(50,205,50) + linen = 0xFAF0E6, // rgb(250,240,230) + magenta = 0xFF00FF, // rgb(255,0,255) + maroon = 0x800000, // rgb(128,0,0) + medium_aquamarine = 0x66CDAA, // rgb(102,205,170) + medium_blue = 0x0000CD, // rgb(0,0,205) + medium_orchid = 0xBA55D3, // rgb(186,85,211) + medium_purple = 0x9370DB, // rgb(147,112,219) + medium_sea_green = 0x3CB371, // rgb(60,179,113) + medium_slate_blue = 0x7B68EE, // rgb(123,104,238) + medium_spring_green = 0x00FA9A, // rgb(0,250,154) + medium_turquoise = 0x48D1CC, // rgb(72,209,204) + medium_violet_red = 0xC71585, // rgb(199,21,133) + midnight_blue = 0x191970, // rgb(25,25,112) + mint_cream = 0xF5FFFA, // rgb(245,255,250) + misty_rose = 0xFFE4E1, // rgb(255,228,225) + moccasin = 0xFFE4B5, // rgb(255,228,181) + navajo_white = 0xFFDEAD, // rgb(255,222,173) + navy = 0x000080, // rgb(0,0,128) + old_lace = 0xFDF5E6, // rgb(253,245,230) + olive = 0x808000, // rgb(128,128,0) + olive_drab = 0x6B8E23, // rgb(107,142,35) + orange = 0xFFA500, // rgb(255,165,0) + orange_red = 0xFF4500, // rgb(255,69,0) + orchid = 0xDA70D6, // rgb(218,112,214) + pale_golden_rod = 0xEEE8AA, // rgb(238,232,170) + pale_green = 0x98FB98, // rgb(152,251,152) + pale_turquoise = 0xAFEEEE, // rgb(175,238,238) + pale_violet_red = 0xDB7093, // rgb(219,112,147) + papaya_whip = 0xFFEFD5, // rgb(255,239,213) + peach_puff = 0xFFDAB9, // rgb(255,218,185) + peru = 0xCD853F, // rgb(205,133,63) + pink = 0xFFC0CB, // rgb(255,192,203) + plum = 0xDDA0DD, // rgb(221,160,221) + powder_blue = 0xB0E0E6, // rgb(176,224,230) + purple = 0x800080, // rgb(128,0,128) + rebecca_purple = 0x663399, // rgb(102,51,153) + red = 0xFF0000, // rgb(255,0,0) + rosy_brown = 0xBC8F8F, // rgb(188,143,143) + royal_blue = 0x4169E1, // rgb(65,105,225) + saddle_brown = 0x8B4513, // rgb(139,69,19) + salmon = 0xFA8072, // rgb(250,128,114) + sandy_brown = 0xF4A460, // rgb(244,164,96) + sea_green = 0x2E8B57, // rgb(46,139,87) + sea_shell = 0xFFF5EE, // rgb(255,245,238) + sienna = 0xA0522D, // rgb(160,82,45) + silver = 0xC0C0C0, // rgb(192,192,192) + sky_blue = 0x87CEEB, // rgb(135,206,235) + slate_blue = 0x6A5ACD, // rgb(106,90,205) + slate_gray = 0x708090, // rgb(112,128,144) + snow = 0xFFFAFA, // rgb(255,250,250) + spring_green = 0x00FF7F, // rgb(0,255,127) + steel_blue = 0x4682B4, // rgb(70,130,180) + tan = 0xD2B48C, // rgb(210,180,140) + teal = 0x008080, // rgb(0,128,128) + thistle = 0xD8BFD8, // rgb(216,191,216) + tomato = 0xFF6347, // rgb(255,99,71) + turquoise = 0x40E0D0, // rgb(64,224,208) + violet = 0xEE82EE, // rgb(238,130,238) + wheat = 0xF5DEB3, // rgb(245,222,179) + white = 0xFFFFFF, // rgb(255,255,255) + white_smoke = 0xF5F5F5, // rgb(245,245,245) + yellow = 0xFFFF00, // rgb(255,255,0) + yellow_green = 0x9ACD32 // rgb(154,205,50) +}; // enum class color + +enum class terminal_color : uint8_t { + black = 30, + red, + green, + yellow, + blue, + magenta, + cyan, + white, + bright_black = 90, + bright_red, + bright_green, + bright_yellow, + bright_blue, + bright_magenta, + bright_cyan, + bright_white +}; + +enum class emphasis : uint8_t { + bold = 1, + faint = 1 << 1, + italic = 1 << 2, + underline = 1 << 3, + blink = 1 << 4, + reverse = 1 << 5, + conceal = 1 << 6, + strikethrough = 1 << 7, +}; + +// rgb is a struct for red, green and blue colors. +// Using the name "rgb" makes some editors show the color in a tooltip. +struct rgb { + constexpr rgb() : r(0), g(0), b(0) {} + constexpr rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {} + constexpr rgb(uint32_t hex) + : r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {} + constexpr rgb(color hex) + : r((uint32_t(hex) >> 16) & 0xFF), + g((uint32_t(hex) >> 8) & 0xFF), + b(uint32_t(hex) & 0xFF) {} + uint8_t r; + uint8_t g; + uint8_t b; +}; + +namespace detail { + +// A bit-packed variant of an RGB color, a terminal color, or unset color. +// see text_style for the bit-packing scheme. +struct color_type { + constexpr color_type() noexcept = default; + constexpr color_type(color rgb_color) noexcept + : value_(static_cast(rgb_color) | (1 << 24)) {} + constexpr color_type(rgb rgb_color) noexcept + : color_type(static_cast( + (static_cast(rgb_color.r) << 16) | + (static_cast(rgb_color.g) << 8) | rgb_color.b)) {} + constexpr color_type(terminal_color term_color) noexcept + : value_(static_cast(term_color) | (3 << 24)) {} + + constexpr auto is_terminal_color() const noexcept -> bool { + return (value_ & (1 << 25)) != 0; + } + + constexpr auto value() const noexcept -> uint32_t { + return value_ & 0xFFFFFF; + } + + constexpr color_type(uint32_t value) noexcept : value_(value) {} + + uint32_t value_ = 0; +}; +} // namespace detail + +/// A text style consisting of foreground and background colors and emphasis. +class text_style { + // The information is packed as follows: + // ┌──┐ + // │ 0│─┐ + // │..│ ├── foreground color value + // │23│─┘ + // ├──┤ + // │24│─┬── discriminator for the above value. 00 if unset, 01 if it's + // │25│─┘ an RGB color, or 11 if it's a terminal color (10 is unused) + // ├──┤ + // │26│──── overflow bit, always zero (see below) + // ├──┤ + // │27│─┐ + // │..│ │ + // │50│ │ + // ├──┤ │ + // │51│ ├── background color (same format as the foreground color) + // │52│ │ + // ├──┤ │ + // │53│─┘ + // ├──┤ + // │54│─┐ + // │..│ ├── emphases + // │61│─┘ + // ├──┤ + // │62│─┬── unused + // │63│─┘ + // └──┘ + // The overflow bits are there to make operator|= efficient. + // When ORing, we must throw if, for either the foreground or background, + // one style specifies a terminal color and the other specifies any color + // (terminal or RGB); in other words, if one discriminator is 11 and the + // other is 11 or 01. + // + // We do that check by adding the styles. Consider what adding does to each + // possible pair of discriminators: + // 00 + 00 = 000 + // 01 + 00 = 001 + // 11 + 00 = 011 + // 01 + 01 = 010 + // 11 + 01 = 100 (!!) + // 11 + 11 = 110 (!!) + // In the last two cases, the ones we want to catch, the third bit——the + // overflow bit——is set. Bingo. + // + // We must take into account the possible carry bit from the bits + // before the discriminator. The only potentially problematic case is + // 11 + 00 = 011 (a carry bit would make it 100, not good!), but a carry + // bit is impossible in that case, because 00 (unset color) means the + // 24 bits that precede the discriminator are all zero. + // + // This test can be applied to both colors simultaneously. + + public: + FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept + : style_(static_cast(em) << 54) {} + + FMT_CONSTEXPR auto operator|=(text_style rhs) -> text_style& { + if (((style_ + rhs.style_) & ((1ULL << 26) | (1ULL << 53))) != 0) + report_error("can't OR a terminal color"); + style_ |= rhs.style_; + return *this; + } + + friend FMT_CONSTEXPR auto operator|(text_style lhs, text_style rhs) + -> text_style { + return lhs |= rhs; + } + + FMT_CONSTEXPR auto operator==(text_style rhs) const noexcept -> bool { + return style_ == rhs.style_; + } + + FMT_CONSTEXPR auto operator!=(text_style rhs) const noexcept -> bool { + return !(*this == rhs); + } + + FMT_CONSTEXPR auto has_foreground() const noexcept -> bool { + return (style_ & (1 << 24)) != 0; + } + FMT_CONSTEXPR auto has_background() const noexcept -> bool { + return (style_ & (1ULL << 51)) != 0; + } + FMT_CONSTEXPR auto has_emphasis() const noexcept -> bool { + return (style_ >> 54) != 0; + } + FMT_CONSTEXPR auto get_foreground() const noexcept -> detail::color_type { + FMT_ASSERT(has_foreground(), "no foreground specified for this style"); + return style_ & 0x3FFFFFF; + } + FMT_CONSTEXPR auto get_background() const noexcept -> detail::color_type { + FMT_ASSERT(has_background(), "no background specified for this style"); + return (style_ >> 27) & 0x3FFFFFF; + } + FMT_CONSTEXPR auto get_emphasis() const noexcept -> emphasis { + FMT_ASSERT(has_emphasis(), "no emphasis specified for this style"); + return static_cast(style_ >> 54); + } + + private: + FMT_CONSTEXPR text_style(uint64_t style) noexcept : style_(style) {} + + friend FMT_CONSTEXPR auto fg(detail::color_type foreground) noexcept + -> text_style; + + friend FMT_CONSTEXPR auto bg(detail::color_type background) noexcept + -> text_style; + + uint64_t style_ = 0; +}; + +/// Creates a text style from the foreground (text) color. +FMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept + -> text_style { + return foreground.value_; +} + +/// Creates a text style from the background color. +FMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept + -> text_style { + return static_cast(background.value_) << 27; +} + +FMT_CONSTEXPR inline auto operator|(emphasis lhs, emphasis rhs) noexcept + -> text_style { + return text_style(lhs) | rhs; +} + +namespace detail { + +template struct ansi_color_escape { + FMT_CONSTEXPR ansi_color_escape(color_type text_color, + const char* esc) noexcept { + // If we have a terminal color, we need to output another escape code + // sequence. + if (text_color.is_terminal_color()) { + bool is_background = esc == string_view("\x1b[48;2;"); + uint32_t value = text_color.value(); + // Background ASCII codes are the same as the foreground ones but with + // 10 more. + if (is_background) value += 10u; + + buffer[size++] = static_cast('\x1b'); + buffer[size++] = static_cast('['); + + if (value >= 100u) { + buffer[size++] = static_cast('1'); + value %= 100u; + } + buffer[size++] = static_cast('0' + value / 10u); + buffer[size++] = static_cast('0' + value % 10u); + + buffer[size++] = static_cast('m'); + return; + } + + for (int i = 0; i < 7; i++) { + buffer[i] = static_cast(esc[i]); + } + rgb color(text_color.value()); + to_esc(color.r, buffer + 7, ';'); + to_esc(color.g, buffer + 11, ';'); + to_esc(color.b, buffer + 15, 'm'); + size = 19; + } + FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept { + uint8_t em_codes[num_emphases] = {}; + if (has_emphasis(em, emphasis::bold)) em_codes[0] = 1; + if (has_emphasis(em, emphasis::faint)) em_codes[1] = 2; + if (has_emphasis(em, emphasis::italic)) em_codes[2] = 3; + if (has_emphasis(em, emphasis::underline)) em_codes[3] = 4; + if (has_emphasis(em, emphasis::blink)) em_codes[4] = 5; + if (has_emphasis(em, emphasis::reverse)) em_codes[5] = 7; + if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8; + if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9; + + buffer[size++] = static_cast('\x1b'); + buffer[size++] = static_cast('['); + + for (size_t i = 0; i < num_emphases; ++i) { + if (!em_codes[i]) continue; + buffer[size++] = static_cast('0' + em_codes[i]); + buffer[size++] = static_cast(';'); + } + + buffer[size - 1] = static_cast('m'); + } + FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; } + + FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; } + FMT_CONSTEXPR auto end() const noexcept -> const Char* { + return buffer + size; + } + + private: + static constexpr size_t num_emphases = 8; + Char buffer[7u + 4u * num_emphases] = {}; + size_t size = 0; + + static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out, + char delimiter) noexcept { + out[0] = static_cast('0' + c / 100); + out[1] = static_cast('0' + c / 10 % 10); + out[2] = static_cast('0' + c % 10); + out[3] = static_cast(delimiter); + } + static FMT_CONSTEXPR auto has_emphasis(emphasis em, emphasis mask) noexcept + -> bool { + return static_cast(em) & static_cast(mask); + } +}; + +template +FMT_CONSTEXPR auto make_foreground_color(color_type foreground) noexcept + -> ansi_color_escape { + return ansi_color_escape(foreground, "\x1b[38;2;"); +} + +template +FMT_CONSTEXPR auto make_background_color(color_type background) noexcept + -> ansi_color_escape { + return ansi_color_escape(background, "\x1b[48;2;"); +} + +template +FMT_CONSTEXPR auto make_emphasis(emphasis em) noexcept + -> ansi_color_escape { + return ansi_color_escape(em); +} + +template inline void reset_color(buffer& buffer) { + auto reset_color = string_view("\x1b[0m"); + buffer.append(reset_color.begin(), reset_color.end()); +} + +template struct styled_arg : view { + const T& value; + text_style style; + styled_arg(const T& v, text_style s) : value(v), style(s) {} +}; + +template +void vformat_to(buffer& buf, text_style ts, basic_string_view fmt, + basic_format_args> args) { + if (ts.has_emphasis()) { + auto emphasis = make_emphasis(ts.get_emphasis()); + buf.append(emphasis.begin(), emphasis.end()); + } + if (ts.has_foreground()) { + auto foreground = make_foreground_color(ts.get_foreground()); + buf.append(foreground.begin(), foreground.end()); + } + if (ts.has_background()) { + auto background = make_background_color(ts.get_background()); + buf.append(background.begin(), background.end()); + } + vformat_to(buf, fmt, args); + if (ts != text_style()) reset_color(buf); +} +} // namespace detail + +inline void vprint(FILE* f, text_style ts, string_view fmt, format_args args) { + auto buf = memory_buffer(); + detail::vformat_to(buf, ts, fmt, args); + print(f, FMT_STRING("{}"), string_view(buf.begin(), buf.size())); +} + +/** + * Formats a string and prints it to the specified file stream using ANSI + * escape sequences to specify text formatting. + * + * **Example**: + * + * fmt::print(fmt::emphasis::bold | fg(fmt::color::red), + * "Elapsed time: {0:.2f} seconds", 1.23); + */ +template +void print(FILE* f, text_style ts, format_string fmt, T&&... args) { + vprint(f, ts, fmt.str, vargs{{args...}}); +} + +/** + * Formats a string and prints it to stdout using ANSI escape sequences to + * specify text formatting. + * + * **Example**: + * + * fmt::print(fmt::emphasis::bold | fg(fmt::color::red), + * "Elapsed time: {0:.2f} seconds", 1.23); + */ +template +void print(text_style ts, format_string fmt, T&&... args) { + return print(stdout, ts, fmt, std::forward(args)...); +} + +inline auto vformat(text_style ts, string_view fmt, format_args args) + -> std::string { + auto buf = memory_buffer(); + detail::vformat_to(buf, ts, fmt, args); + return fmt::to_string(buf); +} + +/** + * Formats arguments and returns the result as a string using ANSI escape + * sequences to specify text formatting. + * + * **Example**: + * + * ``` + * #include + * std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red), + * "The answer is {}", 42); + * ``` + */ +template +inline auto format(text_style ts, format_string fmt, T&&... args) + -> std::string { + return fmt::vformat(ts, fmt.str, vargs{{args...}}); +} + +/// Formats a string with the given text_style and writes the output to `out`. +template ::value)> +auto vformat_to(OutputIt out, text_style ts, string_view fmt, format_args args) + -> OutputIt { + auto&& buf = detail::get_buffer(out); + detail::vformat_to(buf, ts, fmt, args); + return detail::get_iterator(buf, out); +} + +/** + * Formats arguments with the given text style, writes the result to the output + * iterator `out` and returns the iterator past the end of the output range. + * + * **Example**: + * + * std::vector out; + * fmt::format_to(std::back_inserter(out), + * fmt::emphasis::bold | fg(fmt::color::red), "{}", 42); + */ +template ::value)> +inline auto format_to(OutputIt out, text_style ts, format_string fmt, + T&&... args) -> OutputIt { + return vformat_to(out, ts, fmt.str, vargs{{args...}}); +} + +template +struct formatter, Char> : formatter { + template + auto format(const detail::styled_arg& arg, FormatContext& ctx) const + -> decltype(ctx.out()) { + const auto& ts = arg.style; + auto out = ctx.out(); + + bool has_style = false; + if (ts.has_emphasis()) { + has_style = true; + auto emphasis = detail::make_emphasis(ts.get_emphasis()); + out = detail::copy(emphasis.begin(), emphasis.end(), out); + } + if (ts.has_foreground()) { + has_style = true; + auto foreground = + detail::make_foreground_color(ts.get_foreground()); + out = detail::copy(foreground.begin(), foreground.end(), out); + } + if (ts.has_background()) { + has_style = true; + auto background = + detail::make_background_color(ts.get_background()); + out = detail::copy(background.begin(), background.end(), out); + } + out = formatter::format(arg.value, ctx); + if (has_style) { + auto reset_color = string_view("\x1b[0m"); + out = detail::copy(reset_color.begin(), reset_color.end(), out); + } + return out; + } +}; + +/** + * Returns an argument that will be formatted using ANSI escape sequences, + * to be used in a formatting function. + * + * **Example**: + * + * fmt::print("Elapsed time: {0:.2f} seconds", + * fmt::styled(1.23, fmt::fg(fmt::color::green) | + * fmt::bg(fmt::color::blue))); + */ +template +FMT_CONSTEXPR auto styled(const T& value, text_style ts) + -> detail::styled_arg> { + return detail::styled_arg>{value, ts}; +} + +FMT_END_EXPORT +FMT_END_NAMESPACE + +#endif // FMT_COLOR_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/compile.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/compile.h new file mode 100644 index 0000000000000000000000000000000000000000..955135a39f4eab50b903bd3bfee0cb9217f0238d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/compile.h @@ -0,0 +1,593 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - experimental format string compilation +// +// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_COMPILE_H_ +#define FMT_COMPILE_H_ + +#ifndef FMT_MODULE +# include // std::back_inserter +#endif + +#include "format.h" + +FMT_BEGIN_NAMESPACE +FMT_BEGIN_EXPORT + +// A compile-time string which is compiled into fast formatting code. +class compiled_string {}; + +template +struct is_compiled_string : std::is_base_of {}; + +/** + * Converts a string literal `s` into a format string that will be parsed at + * compile time and converted into efficient formatting code. Requires C++17 + * `constexpr if` compiler support. + * + * **Example**: + * + * // Converts 42 into std::string using the most efficient method and no + * // runtime format string processing. + * std::string s = fmt::format(FMT_COMPILE("{}"), 42); + */ +#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) +# define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::compiled_string) +#else +# define FMT_COMPILE(s) FMT_STRING(s) +#endif + +/** + * Converts a string literal into a format string that will be parsed at + * compile time and converted into efficient formatting code. Requires support + * for class types in constant template parameters (a C++20 feature). + * + * **Example**: + * + * // Converts 42 into std::string using the most efficient method and no + * // runtime format string processing. + * using namespace fmt::literals; + * std::string s = fmt::format("{}"_cf, 42); + */ +#if FMT_USE_NONTYPE_TEMPLATE_ARGS +inline namespace literals { +template constexpr auto operator""_cf() { + return FMT_COMPILE(Str.data); +} +} // namespace literals +#endif + +FMT_END_EXPORT + +namespace detail { + +template +constexpr auto first(const T& value, const Tail&...) -> const T& { + return value; +} + +#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) +template struct type_list {}; + +// Returns a reference to the argument at index N from [first, rest...]. +template +constexpr auto get([[maybe_unused]] const T& first, + [[maybe_unused]] const Args&... rest) -> const auto& { + static_assert(N < 1 + sizeof...(Args), "index is out of bounds"); + if constexpr (N == 0) + return first; + else + return detail::get(rest...); +} + +# if FMT_USE_NONTYPE_TEMPLATE_ARGS +template +constexpr auto get_arg_index_by_name(basic_string_view name) -> int { + if constexpr (is_static_named_arg()) { + if (name == T::name) return N; + } + if constexpr (sizeof...(Args) > 0) + return get_arg_index_by_name(name); + (void)name; // Workaround an MSVC bug about "unused" parameter. + return -1; +} +# endif + +template +FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view name) -> int { +# if FMT_USE_NONTYPE_TEMPLATE_ARGS + if constexpr (sizeof...(Args) > 0) + return get_arg_index_by_name<0, Args...>(name); +# endif + (void)name; + return -1; +} + +template +constexpr auto get_arg_index_by_name(basic_string_view name, + type_list) -> int { + return get_arg_index_by_name(name); +} + +template struct get_type_impl; + +template struct get_type_impl> { + using type = + remove_cvref_t(std::declval()...))>; +}; + +template +using get_type = typename get_type_impl::type; + +template struct is_compiled_format : std::false_type {}; + +template struct text { + basic_string_view data; + using char_type = Char; + + template + constexpr auto format(OutputIt out, const T&...) const -> OutputIt { + return write(out, data); + } +}; + +template +struct is_compiled_format> : std::true_type {}; + +template +constexpr auto make_text(basic_string_view s, size_t pos, size_t size) + -> text { + return {{&s[pos], size}}; +} + +template struct code_unit { + Char value; + using char_type = Char; + + template + constexpr auto format(OutputIt out, const T&...) const -> OutputIt { + *out++ = value; + return out; + } +}; + +// This ensures that the argument type is convertible to `const T&`. +template +constexpr auto get_arg_checked(const Args&... args) -> const T& { + const auto& arg = detail::get(args...); + if constexpr (detail::is_named_arg>()) { + return arg.value; + } else { + return arg; + } +} + +template +struct is_compiled_format> : std::true_type {}; + +// A replacement field that refers to argument N. +template struct field { + using char_type = Char; + + template + constexpr auto format(OutputIt out, const T&... args) const -> OutputIt { + const V& arg = get_arg_checked(args...); + if constexpr (std::is_convertible>::value) { + auto s = basic_string_view(arg); + return copy(s.begin(), s.end(), out); + } else { + return write(out, arg); + } + } +}; + +template +struct is_compiled_format> : std::true_type {}; + +// A replacement field that refers to argument with name. +template struct runtime_named_field { + using char_type = Char; + basic_string_view name; + + template + constexpr static auto try_format_argument( + OutputIt& out, + // [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9 + [[maybe_unused]] basic_string_view arg_name, const T& arg) -> bool { + if constexpr (is_named_arg::type>::value) { + if (arg_name == arg.name) { + out = write(out, arg.value); + return true; + } + } + return false; + } + + template + constexpr auto format(OutputIt out, const T&... args) const -> OutputIt { + bool found = (try_format_argument(out, name, args) || ...); + if (!found) { + FMT_THROW(format_error("argument with specified name is not found")); + } + return out; + } +}; + +template +struct is_compiled_format> : std::true_type {}; + +// A replacement field that refers to argument N and has format specifiers. +template struct spec_field { + using char_type = Char; + formatter fmt; + + template + constexpr FMT_INLINE auto format(OutputIt out, const T&... args) const + -> OutputIt { + const auto& vargs = + fmt::make_format_args>(args...); + basic_format_context ctx(out, vargs); + return fmt.format(get_arg_checked(args...), ctx); + } +}; + +template +struct is_compiled_format> : std::true_type {}; + +template struct concat { + L lhs; + R rhs; + using char_type = typename L::char_type; + + template + constexpr auto format(OutputIt out, const T&... args) const -> OutputIt { + out = lhs.format(out, args...); + return rhs.format(out, args...); + } +}; + +template +struct is_compiled_format> : std::true_type {}; + +template +constexpr auto make_concat(L lhs, R rhs) -> concat { + return {lhs, rhs}; +} + +struct unknown_format {}; + +template +constexpr auto parse_text(basic_string_view str, size_t pos) -> size_t { + for (size_t size = str.size(); pos != size; ++pos) { + if (str[pos] == '{' || str[pos] == '}') break; + } + return pos; +} + +template +constexpr auto compile_format_string(S fmt); + +template +constexpr auto parse_tail(T head, S fmt) { + if constexpr (POS != basic_string_view(fmt).size()) { + constexpr auto tail = compile_format_string(fmt); + if constexpr (std::is_same, + unknown_format>()) + return tail; + else + return make_concat(head, tail); + } else { + return head; + } +} + +template struct parse_specs_result { + formatter fmt; + size_t end; + int next_arg_id; +}; + +enum { manual_indexing_id = -1 }; + +template +constexpr auto parse_specs(basic_string_view str, size_t pos, + int next_arg_id) -> parse_specs_result { + str.remove_prefix(pos); + auto ctx = + compile_parse_context(str, max_value(), nullptr, next_arg_id); + auto f = formatter(); + auto end = f.parse(ctx); + return {f, pos + fmt::detail::to_unsigned(end - str.data()), + next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()}; +} + +template struct arg_id_handler { + arg_id_kind kind; + arg_ref arg_id; + + constexpr auto on_auto() -> int { + FMT_ASSERT(false, "handler cannot be used with automatic indexing"); + return 0; + } + constexpr auto on_index(int id) -> int { + kind = arg_id_kind::index; + arg_id = arg_ref(id); + return 0; + } + constexpr auto on_name(basic_string_view id) -> int { + kind = arg_id_kind::name; + arg_id = arg_ref(id); + return 0; + } +}; + +template struct parse_arg_id_result { + arg_id_kind kind; + arg_ref arg_id; + const Char* arg_id_end; +}; + +template +constexpr auto parse_arg_id(const Char* begin, const Char* end) { + auto handler = arg_id_handler{arg_id_kind::none, arg_ref{}}; + auto arg_id_end = parse_arg_id(begin, end, handler); + return parse_arg_id_result{handler.kind, handler.arg_id, arg_id_end}; +} + +template struct field_type { + using type = remove_cvref_t; +}; + +template +struct field_type::value>> { + using type = remove_cvref_t; +}; + +template +constexpr auto parse_replacement_field_then_tail(S fmt) { + using char_type = typename S::char_type; + constexpr auto str = basic_string_view(fmt); + constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type(); + if constexpr (c == '}') { + return parse_tail( + field::type, ARG_INDEX>(), fmt); + } else if constexpr (c != ':') { + FMT_THROW(format_error("expected ':'")); + } else { + constexpr auto result = parse_specs::type>( + str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID); + if constexpr (result.end >= str.size() || str[result.end] != '}') { + FMT_THROW(format_error("expected '}'")); + return 0; + } else { + return parse_tail( + spec_field::type, ARG_INDEX>{ + result.fmt}, + fmt); + } + } +} + +// Compiles a non-empty format string and returns the compiled representation +// or unknown_format() on unrecognized input. +template +constexpr auto compile_format_string(S fmt) { + using char_type = typename S::char_type; + constexpr auto str = basic_string_view(fmt); + if constexpr (str[POS] == '{') { + if constexpr (POS + 1 == str.size()) + FMT_THROW(format_error("unmatched '{' in format string")); + if constexpr (str[POS + 1] == '{') { + return parse_tail(make_text(str, POS, 1), fmt); + } else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') { + static_assert(ID != manual_indexing_id, + "cannot switch from manual to automatic argument indexing"); + constexpr auto next_id = + ID != manual_indexing_id ? ID + 1 : manual_indexing_id; + return parse_replacement_field_then_tail, Args, + POS + 1, ID, next_id>(fmt); + } else { + constexpr auto arg_id_result = + parse_arg_id(str.data() + POS + 1, str.data() + str.size()); + constexpr auto arg_id_end_pos = arg_id_result.arg_id_end - str.data(); + constexpr char_type c = + arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type(); + static_assert(c == '}' || c == ':', "missing '}' in format string"); + if constexpr (arg_id_result.kind == arg_id_kind::index) { + static_assert( + ID == manual_indexing_id || ID == 0, + "cannot switch from automatic to manual argument indexing"); + constexpr auto arg_index = arg_id_result.arg_id.index; + return parse_replacement_field_then_tail, + Args, arg_id_end_pos, + arg_index, manual_indexing_id>( + fmt); + } else if constexpr (arg_id_result.kind == arg_id_kind::name) { + constexpr auto arg_index = + get_arg_index_by_name(arg_id_result.arg_id.name, Args{}); + if constexpr (arg_index >= 0) { + constexpr auto next_id = + ID != manual_indexing_id ? ID + 1 : manual_indexing_id; + return parse_replacement_field_then_tail< + decltype(get_type::value), Args, arg_id_end_pos, + arg_index, next_id>(fmt); + } else if constexpr (c == '}') { + return parse_tail( + runtime_named_field{arg_id_result.arg_id.name}, fmt); + } else if constexpr (c == ':') { + return unknown_format(); // no type info for specs parsing + } + } + } + } else if constexpr (str[POS] == '}') { + if constexpr (POS + 1 == str.size()) + FMT_THROW(format_error("unmatched '}' in format string")); + return parse_tail(make_text(str, POS, 1), fmt); + } else { + constexpr auto end = parse_text(str, POS + 1); + if constexpr (end - POS > 1) { + return parse_tail(make_text(str, POS, end - POS), fmt); + } else { + return parse_tail(code_unit{str[POS]}, fmt); + } + } +} + +template ::value)> +constexpr auto compile(S fmt) { + constexpr auto str = basic_string_view(fmt); + if constexpr (str.size() == 0) { + return detail::make_text(str, 0, 0); + } else { + constexpr auto result = + detail::compile_format_string, 0, 0>(fmt); + return result; + } +} +#endif // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) +} // namespace detail + +FMT_BEGIN_EXPORT + +#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) + +template ::value)> +FMT_INLINE FMT_CONSTEXPR_STRING auto format(const CompiledFormat& cf, + const T&... args) + -> std::basic_string { + auto s = std::basic_string(); + cf.format(std::back_inserter(s), args...); + return s; +} + +template ::value)> +constexpr FMT_INLINE auto format_to(OutputIt out, const CompiledFormat& cf, + const T&... args) -> OutputIt { + return cf.format(out, args...); +} + +template ::value)> +FMT_INLINE FMT_CONSTEXPR_STRING auto format(const S&, T&&... args) + -> std::basic_string { + if constexpr (std::is_same::value) { + constexpr auto str = basic_string_view(S()); + if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}') { + const auto& first = detail::first(args...); + if constexpr (detail::is_named_arg< + remove_cvref_t>::value) { + return fmt::to_string(first.value); + } else { + return fmt::to_string(first); + } + } + } + constexpr auto compiled = detail::compile(S()); + if constexpr (std::is_same, + detail::unknown_format>()) { + return fmt::format( + static_cast>(S()), + std::forward(args)...); + } else { + return fmt::format(compiled, std::forward(args)...); + } +} + +template ::value)> +FMT_CONSTEXPR auto format_to(OutputIt out, const S&, T&&... args) -> OutputIt { + constexpr auto compiled = detail::compile(S()); + if constexpr (std::is_same, + detail::unknown_format>()) { + return fmt::format_to( + out, static_cast>(S()), + std::forward(args)...); + } else { + return fmt::format_to(out, compiled, std::forward(args)...); + } +} +#endif + +template ::value)> +auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args) + -> format_to_n_result { + using traits = detail::fixed_buffer_traits; + auto buf = detail::iterator_buffer(out, n); + fmt::format_to(std::back_inserter(buf), fmt, std::forward(args)...); + return {buf.out(), buf.count()}; +} + +template ::value)> +FMT_CONSTEXPR20 auto formatted_size(const S& fmt, T&&... args) -> size_t { + auto buf = detail::counting_buffer<>(); + fmt::format_to(appender(buf), fmt, std::forward(args)...); + return buf.count(); +} + +template ::value)> +void print(std::FILE* f, const S& fmt, T&&... args) { + auto buf = memory_buffer(); + fmt::format_to(appender(buf), fmt, std::forward(args)...); + detail::print(f, {buf.data(), buf.size()}); +} + +template ::value)> +void print(const S& fmt, T&&... args) { + print(stdout, fmt, std::forward(args)...); +} + +template class static_format_result { + private: + char data[N]; + + public: + template ::value)> + explicit FMT_CONSTEXPR static_format_result(const S& fmt, T&&... args) { + *fmt::format_to(data, fmt, std::forward(args)...) = '\0'; + } + + auto str() const -> fmt::string_view { return {data, N - 1}; } + auto c_str() const -> const char* { return data; } +}; + +/** + * Formats arguments according to the format string `fmt_str` and produces + * a string of the exact required size at compile time. Both the format string + * and the arguments must be compile-time expressions. + * + * The resulting string can be accessed as a C string via `c_str()` or as + * a `fmt::string_view` via `str()`. + * + * **Example**: + * + * // Produces the static string "42" at compile time. + * static constexpr auto result = FMT_STATIC_FORMAT("{}", 42); + * const char* s = result.c_str(); + */ +#define FMT_STATIC_FORMAT(fmt_str, ...) \ + fmt::static_format_result< \ + fmt::formatted_size(FMT_COMPILE(fmt_str), __VA_ARGS__) + 1>( \ + FMT_COMPILE(fmt_str), __VA_ARGS__) + +FMT_END_EXPORT +FMT_END_NAMESPACE + +#endif // FMT_COMPILE_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/core.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/core.h new file mode 100644 index 0000000000000000000000000000000000000000..6d2b271f05c9ff22b8c67f8cfa7bc2c8dbdef5b1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/core.h @@ -0,0 +1,10 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// This file is only provided for compatibility and may be removed in future +// versions. Use fmt/base.h if you don't need fmt::format and fmt/format.h +// otherwise. + +#include "format.h" + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format-inl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..ccf962a394ea93bc040d5e9b94bfb7e0bcf30bb7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format-inl.h @@ -0,0 +1,1953 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - implementation +// +// Copyright (c) 2012 - 2016, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_FORMAT_INL_H_ +#define FMT_FORMAT_INL_H_ + +#ifndef FMT_MODULE +# include +# include // errno +# include +# include +# include +#endif + +#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE) +# include // _isatty +#endif + +#include "format.h" + +#if FMT_USE_LOCALE && !defined(FMT_MODULE) +# include +#endif + +#ifndef FMT_FUNC +# define FMT_FUNC +#endif + +FMT_BEGIN_NAMESPACE + +#ifndef FMT_CUSTOM_ASSERT_FAIL +FMT_FUNC void assert_fail(const char* file, int line, const char* message) { + // Use unchecked std::fprintf to avoid triggering another assertion when + // writing to stderr fails. + std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message); + abort(); +} +#endif + +#if FMT_USE_LOCALE +namespace detail { +using std::locale; +using std::numpunct; +using std::use_facet; +} // namespace detail +#else +namespace detail { +struct locale {}; +template struct numpunct { + auto grouping() const -> std::string { return "\03"; } + auto thousands_sep() const -> Char { return ','; } + auto decimal_point() const -> Char { return '.'; } +}; +template Facet use_facet(locale) { return {}; } +} // namespace detail +#endif // FMT_USE_LOCALE + +template auto locale_ref::get() const -> Locale { + using namespace detail; + static_assert(std::is_same::value, ""); +#if FMT_USE_LOCALE + if (locale_) return *static_cast(locale_); +#endif + return locale(); +} + +namespace detail { + +FMT_FUNC void format_error_code(detail::buffer& out, int error_code, + string_view message) noexcept { + // Report error code making sure that the output fits into + // inline_buffer_size to avoid dynamic memory allocation and potential + // bad_alloc. + out.try_resize(0); + static const char SEP[] = ": "; + static const char ERROR_STR[] = "error "; + // Subtract 2 to account for terminating null characters in SEP and ERROR_STR. + size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2; + auto abs_value = static_cast>(error_code); + if (detail::is_negative(error_code)) { + abs_value = 0 - abs_value; + ++error_code_size; + } + error_code_size += detail::to_unsigned(detail::count_digits(abs_value)); + auto it = appender(out); + if (message.size() <= inline_buffer_size - error_code_size) + fmt::format_to(it, FMT_STRING("{}{}"), message, SEP); + fmt::format_to(it, FMT_STRING("{}{}"), ERROR_STR, error_code); + FMT_ASSERT(out.size() <= inline_buffer_size, ""); +} + +FMT_FUNC void do_report_error(format_func func, int error_code, + const char* message) noexcept { + memory_buffer full_message; + func(full_message, error_code, message); + // Don't use fwrite_all because the latter may throw. + if (std::fwrite(full_message.data(), full_message.size(), 1, stderr) > 0) + std::fputc('\n', stderr); +} + +// A wrapper around fwrite that throws on error. +inline void fwrite_all(const void* ptr, size_t count, FILE* stream) { + size_t written = std::fwrite(ptr, 1, count, stream); + if (written < count) + FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); +} + +template +FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result { + auto&& facet = use_facet>(loc.get()); + auto grouping = facet.grouping(); + auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep(); + return {std::move(grouping), thousands_sep}; +} +template +FMT_FUNC auto decimal_point_impl(locale_ref loc) -> Char { + return use_facet>(loc.get()).decimal_point(); +} + +#if FMT_USE_LOCALE +FMT_FUNC auto write_loc(appender out, loc_value value, + const format_specs& specs, locale_ref loc) -> bool { + auto locale = loc.get(); + // We cannot use the num_put facet because it may produce output in + // a wrong encoding. + using facet = format_facet; + if (std::has_facet(locale)) + return use_facet(locale).put(out, value, specs); + return facet(locale).put(out, value, specs); +} +#endif +} // namespace detail + +FMT_FUNC void report_error(const char* message) { +#if FMT_MSC_VERSION || defined(__NVCC__) + // Silence unreachable code warnings in MSVC and NVCC because these + // are nearly impossible to fix in a generic code. + volatile bool b = true; + if (!b) return; +#endif + FMT_THROW(format_error(message)); +} + +template typename Locale::id format_facet::id; + +template format_facet::format_facet(Locale& loc) { + auto& np = detail::use_facet>(loc); + grouping_ = np.grouping(); + if (!grouping_.empty()) separator_ = std::string(1, np.thousands_sep()); +} + +#if FMT_USE_LOCALE +template <> +FMT_API FMT_FUNC auto format_facet::do_put( + appender out, loc_value val, const format_specs& specs) const -> bool { + return val.visit( + detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_}); +} +#endif + +FMT_FUNC auto vsystem_error(int error_code, string_view fmt, format_args args) + -> std::system_error { + auto ec = std::error_code(error_code, std::generic_category()); + return std::system_error(ec, vformat(fmt, args)); +} + +namespace detail { + +template +inline auto operator==(basic_fp x, basic_fp y) -> bool { + return x.f == y.f && x.e == y.e; +} + +// Compilers should be able to optimize this into the ror instruction. +FMT_INLINE auto rotr(uint32_t n, uint32_t r) noexcept -> uint32_t { + r &= 31; + return (n >> r) | (n << (32 - r)); +} +FMT_INLINE auto rotr(uint64_t n, uint32_t r) noexcept -> uint64_t { + r &= 63; + return (n >> r) | (n << (64 - r)); +} + +// Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox. +namespace dragonbox { +// Computes upper 64 bits of multiplication of a 32-bit unsigned integer and a +// 64-bit unsigned integer. +inline auto umul96_upper64(uint32_t x, uint64_t y) noexcept -> uint64_t { + return umul128_upper64(static_cast(x) << 32, y); +} + +// Computes lower 128 bits of multiplication of a 64-bit unsigned integer and a +// 128-bit unsigned integer. +inline auto umul192_lower128(uint64_t x, uint128_fallback y) noexcept + -> uint128_fallback { + uint64_t high = x * y.high(); + uint128_fallback high_low = umul128(x, y.low()); + return {high + high_low.high(), high_low.low()}; +} + +// Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a +// 64-bit unsigned integer. +inline auto umul96_lower64(uint32_t x, uint64_t y) noexcept -> uint64_t { + return x * y; +} + +// Various fast log computations. +inline auto floor_log10_pow2_minus_log10_4_over_3(int e) noexcept -> int { + FMT_ASSERT(e <= 2936 && e >= -2985, "too large exponent"); + return (e * 631305 - 261663) >> 21; +} + +FMT_INLINE_VARIABLE constexpr struct div_small_pow10_infos_struct { + uint32_t divisor; + int shift_amount; +} div_small_pow10_infos[] = {{10, 16}, {100, 16}}; + +// Replaces n by floor(n / pow(10, N)) returning true if and only if n is +// divisible by pow(10, N). +// Precondition: n <= pow(10, N + 1). +template +auto check_divisibility_and_divide_by_pow10(uint32_t& n) noexcept -> bool { + // The numbers below are chosen such that: + // 1. floor(n/d) = floor(nm / 2^k) where d=10 or d=100, + // 2. nm mod 2^k < m if and only if n is divisible by d, + // where m is magic_number, k is shift_amount + // and d is divisor. + // + // Item 1 is a common technique of replacing division by a constant with + // multiplication, see e.g. "Division by Invariant Integers Using + // Multiplication" by Granlund and Montgomery (1994). magic_number (m) is set + // to ceil(2^k/d) for large enough k. + // The idea for item 2 originates from Schubfach. + constexpr auto info = div_small_pow10_infos[N - 1]; + FMT_ASSERT(n <= info.divisor * 10, "n is too large"); + constexpr uint32_t magic_number = + (1u << info.shift_amount) / info.divisor + 1; + n *= magic_number; + const uint32_t comparison_mask = (1u << info.shift_amount) - 1; + bool result = (n & comparison_mask) < magic_number; + n >>= info.shift_amount; + return result; +} + +// Computes floor(n / pow(10, N)) for small n and N. +// Precondition: n <= pow(10, N + 1). +template auto small_division_by_pow10(uint32_t n) noexcept -> uint32_t { + constexpr auto info = div_small_pow10_infos[N - 1]; + FMT_ASSERT(n <= info.divisor * 10, "n is too large"); + constexpr uint32_t magic_number = + (1u << info.shift_amount) / info.divisor + 1; + return (n * magic_number) >> info.shift_amount; +} + +// Computes floor(n / 10^(kappa + 1)) (float) +inline auto divide_by_10_to_kappa_plus_1(uint32_t n) noexcept -> uint32_t { + // 1374389535 = ceil(2^37/100) + return static_cast((static_cast(n) * 1374389535) >> 37); +} +// Computes floor(n / 10^(kappa + 1)) (double) +inline auto divide_by_10_to_kappa_plus_1(uint64_t n) noexcept -> uint64_t { + // 2361183241434822607 = ceil(2^(64+7)/1000) + return umul128_upper64(n, 2361183241434822607ull) >> 7; +} + +// Various subroutines using pow10 cache +template struct cache_accessor; + +template <> struct cache_accessor { + using carrier_uint = float_info::carrier_uint; + using cache_entry_type = uint64_t; + + static auto get_cached_power(int k) noexcept -> uint64_t { + FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, + "k is out of range"); + static constexpr uint64_t pow10_significands[] = { + 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f, + 0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb, + 0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28, + 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb, + 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a, + 0xe69594bec44de15c, 0x901d7cf73ab0acda, 0xb424dc35095cd810, + 0xe12e13424bb40e14, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff, + 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd, + 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424, + 0xd1b71758e219652c, 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b, + 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000, + 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, + 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, + 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000, + 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000, + 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000, + 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, + 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000, + 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0, + 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940985, + 0xa18f07d736b90be6, 0xc9f2c9cd04674edf, 0xfc6f7c4045812297, + 0x9dc5ada82b70b59e, 0xc5371912364ce306, 0xf684df56c3e01bc7, + 0x9a130b963a6c115d, 0xc097ce7bc90715b4, 0xf0bdc21abb48db21, + 0x96769950b50d88f5, 0xbc143fa4e250eb32, 0xeb194f8e1ae525fe, + 0x92efd1b8d0cf37bf, 0xb7abc627050305ae, 0xe596b7b0c643c71a, + 0x8f7e32ce7bea5c70, 0xb35dbf821ae4f38c, 0xe0352f62a19e306f}; + return pow10_significands[k - float_info::min_k]; + } + + struct compute_mul_result { + carrier_uint result; + bool is_integer; + }; + struct compute_mul_parity_result { + bool parity; + bool is_integer; + }; + + static auto compute_mul(carrier_uint u, + const cache_entry_type& cache) noexcept + -> compute_mul_result { + auto r = umul96_upper64(u, cache); + return {static_cast(r >> 32), + static_cast(r) == 0}; + } + + static auto compute_delta(const cache_entry_type& cache, int beta) noexcept + -> uint32_t { + return static_cast(cache >> (64 - 1 - beta)); + } + + static auto compute_mul_parity(carrier_uint two_f, + const cache_entry_type& cache, + int beta) noexcept + -> compute_mul_parity_result { + FMT_ASSERT(beta >= 1, ""); + FMT_ASSERT(beta < 64, ""); + + auto r = umul96_lower64(two_f, cache); + return {((r >> (64 - beta)) & 1) != 0, + static_cast(r >> (32 - beta)) == 0}; + } + + static auto compute_left_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta) noexcept -> carrier_uint { + return static_cast( + (cache - (cache >> (num_significand_bits() + 2))) >> + (64 - num_significand_bits() - 1 - beta)); + } + + static auto compute_right_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta) noexcept -> carrier_uint { + return static_cast( + (cache + (cache >> (num_significand_bits() + 1))) >> + (64 - num_significand_bits() - 1 - beta)); + } + + static auto compute_round_up_for_shorter_interval_case( + const cache_entry_type& cache, int beta) noexcept -> carrier_uint { + return (static_cast( + cache >> (64 - num_significand_bits() - 2 - beta)) + + 1) / + 2; + } +}; + +template <> struct cache_accessor { + using carrier_uint = float_info::carrier_uint; + using cache_entry_type = uint128_fallback; + + static auto get_cached_power(int k) noexcept -> uint128_fallback { + FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, + "k is out of range"); + + static constexpr uint128_fallback pow10_significands[] = { +#if FMT_USE_FULL_CACHE_DRAGONBOX + {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, + {0x9faacf3df73609b1, 0x77b191618c54e9ad}, + {0xc795830d75038c1d, 0xd59df5b9ef6a2418}, + {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e}, + {0x9becce62836ac577, 0x4ee367f9430aec33}, + {0xc2e801fb244576d5, 0x229c41f793cda740}, + {0xf3a20279ed56d48a, 0x6b43527578c11110}, + {0x9845418c345644d6, 0x830a13896b78aaaa}, + {0xbe5691ef416bd60c, 0x23cc986bc656d554}, + {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9}, + {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa}, + {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54}, + {0xe858ad248f5c22c9, 0xd1b3400f8f9cff69}, + {0x91376c36d99995be, 0x23100809b9c21fa2}, + {0xb58547448ffffb2d, 0xabd40a0c2832a78b}, + {0xe2e69915b3fff9f9, 0x16c90c8f323f516d}, + {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4}, + {0xb1442798f49ffb4a, 0x99cd11cfdf41779d}, + {0xdd95317f31c7fa1d, 0x40405643d711d584}, + {0x8a7d3eef7f1cfc52, 0x482835ea666b2573}, + {0xad1c8eab5ee43b66, 0xda3243650005eed0}, + {0xd863b256369d4a40, 0x90bed43e40076a83}, + {0x873e4f75e2224e68, 0x5a7744a6e804a292}, + {0xa90de3535aaae202, 0x711515d0a205cb37}, + {0xd3515c2831559a83, 0x0d5a5b44ca873e04}, + {0x8412d9991ed58091, 0xe858790afe9486c3}, + {0xa5178fff668ae0b6, 0x626e974dbe39a873}, + {0xce5d73ff402d98e3, 0xfb0a3d212dc81290}, + {0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a}, + {0xa139029f6a239f72, 0x1c1fffc1ebc44e81}, + {0xc987434744ac874e, 0xa327ffb266b56221}, + {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9}, + {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa}, + {0xc4ce17b399107c22, 0xcb550fb4384d21d4}, + {0xf6019da07f549b2b, 0x7e2a53a146606a49}, + {0x99c102844f94e0fb, 0x2eda7444cbfc426e}, + {0xc0314325637a1939, 0xfa911155fefb5309}, + {0xf03d93eebc589f88, 0x793555ab7eba27cb}, + {0x96267c7535b763b5, 0x4bc1558b2f3458df}, + {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17}, + {0xea9c227723ee8bcb, 0x465e15a979c1cadd}, + {0x92a1958a7675175f, 0x0bfacd89ec191eca}, + {0xb749faed14125d36, 0xcef980ec671f667c}, + {0xe51c79a85916f484, 0x82b7e12780e7401b}, + {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811}, + {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16}, + {0xdfbdcece67006ac9, 0x67a791e093e1d49b}, + {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1}, + {0xaecc49914078536d, 0x58fae9f773886e19}, + {0xda7f5bf590966848, 0xaf39a475506a899f}, + {0x888f99797a5e012d, 0x6d8406c952429604}, + {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84}, + {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65}, + {0x855c3be0a17fcd26, 0x5cf2eea09a550680}, + {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, + {0xd0601d8efc57b08b, 0xf13b94daf124da27}, + {0x823c12795db6ce57, 0x76c53d08d6b70859}, + {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f}, + {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a}, + {0xfe5d54150b090b02, 0xd3f93b35435d7c4d}, + {0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0}, + {0xc6b8e9b0709f109a, 0x359ab6419ca1091c}, + {0xf867241c8cc6d4c0, 0xc30163d203c94b63}, + {0x9b407691d7fc44f8, 0x79e0de63425dcf1e}, + {0xc21094364dfb5636, 0x985915fc12f542e5}, + {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e}, + {0x979cf3ca6cec5b5a, 0xa705992ceecf9c43}, + {0xbd8430bd08277231, 0x50c6ff782a838354}, + {0xece53cec4a314ebd, 0xa4f8bf5635246429}, + {0x940f4613ae5ed136, 0x871b7795e136be9a}, + {0xb913179899f68584, 0x28e2557b59846e40}, + {0xe757dd7ec07426e5, 0x331aeada2fe589d0}, + {0x9096ea6f3848984f, 0x3ff0d2c85def7622}, + {0xb4bca50b065abe63, 0x0fed077a756b53aa}, + {0xe1ebce4dc7f16dfb, 0xd3e8495912c62895}, + {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d}, + {0xb080392cc4349dec, 0xbd8d794d96aacfb4}, + {0xdca04777f541c567, 0xecf0d7a0fc5583a1}, + {0x89e42caaf9491b60, 0xf41686c49db57245}, + {0xac5d37d5b79b6239, 0x311c2875c522ced6}, + {0xd77485cb25823ac7, 0x7d633293366b828c}, + {0x86a8d39ef77164bc, 0xae5dff9c02033198}, + {0xa8530886b54dbdeb, 0xd9f57f830283fdfd}, + {0xd267caa862a12d66, 0xd072df63c324fd7c}, + {0x8380dea93da4bc60, 0x4247cb9e59f71e6e}, + {0xa46116538d0deb78, 0x52d9be85f074e609}, + {0xcd795be870516656, 0x67902e276c921f8c}, + {0x806bd9714632dff6, 0x00ba1cd8a3db53b7}, + {0xa086cfcd97bf97f3, 0x80e8a40eccd228a5}, + {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce}, + {0xfad2a4b13d1b5d6c, 0x796b805720085f82}, + {0x9cc3a6eec6311a63, 0xcbe3303674053bb1}, + {0xc3f490aa77bd60fc, 0xbedbfc4411068a9d}, + {0xf4f1b4d515acb93b, 0xee92fb5515482d45}, + {0x991711052d8bf3c5, 0x751bdd152d4d1c4b}, + {0xbf5cd54678eef0b6, 0xd262d45a78a0635e}, + {0xef340a98172aace4, 0x86fb897116c87c35}, + {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1}, + {0xbae0a846d2195712, 0x8974836059cca10a}, + {0xe998d258869facd7, 0x2bd1a438703fc94c}, + {0x91ff83775423cc06, 0x7b6306a34627ddd0}, + {0xb67f6455292cbf08, 0x1a3bc84c17b1d543}, + {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94}, + {0x8e938662882af53e, 0x547eb47b7282ee9d}, + {0xb23867fb2a35b28d, 0xe99e619a4f23aa44}, + {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5}, + {0x8b3c113c38f9f37e, 0xde83bc408dd3dd05}, + {0xae0b158b4738705e, 0x9624ab50b148d446}, + {0xd98ddaee19068c76, 0x3badd624dd9b0958}, + {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7}, + {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d}, + {0xd47487cc8470652b, 0x7647c32000696720}, + {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074}, + {0xa5fb0a17c777cf09, 0xf468107100525891}, + {0xcf79cc9db955c2cc, 0x7182148d4066eeb5}, + {0x81ac1fe293d599bf, 0xc6f14cd848405531}, + {0xa21727db38cb002f, 0xb8ada00e5a506a7d}, + {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d}, + {0xfd442e4688bd304a, 0x908f4a166d1da664}, + {0x9e4a9cec15763e2e, 0x9a598e4e043287ff}, + {0xc5dd44271ad3cdba, 0x40eff1e1853f29fe}, + {0xf7549530e188c128, 0xd12bee59e68ef47d}, + {0x9a94dd3e8cf578b9, 0x82bb74f8301958cf}, + {0xc13a148e3032d6e7, 0xe36a52363c1faf02}, + {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2}, + {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba}, + {0xbcb2b812db11a5de, 0x7415d448f6b6f0e8}, + {0xebdf661791d60f56, 0x111b495b3464ad22}, + {0x936b9fcebb25c995, 0xcab10dd900beec35}, + {0xb84687c269ef3bfb, 0x3d5d514f40eea743}, + {0xe65829b3046b0afa, 0x0cb4a5a3112a5113}, + {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac}, + {0xb3f4e093db73a093, 0x59ed216765690f57}, + {0xe0f218b8d25088b8, 0x306869c13ec3532d}, + {0x8c974f7383725573, 0x1e414218c73a13fc}, + {0xafbd2350644eeacf, 0xe5d1929ef90898fb}, + {0xdbac6c247d62a583, 0xdf45f746b74abf3a}, + {0x894bc396ce5da772, 0x6b8bba8c328eb784}, + {0xab9eb47c81f5114f, 0x066ea92f3f326565}, + {0xd686619ba27255a2, 0xc80a537b0efefebe}, + {0x8613fd0145877585, 0xbd06742ce95f5f37}, + {0xa798fc4196e952e7, 0x2c48113823b73705}, + {0xd17f3b51fca3a7a0, 0xf75a15862ca504c6}, + {0x82ef85133de648c4, 0x9a984d73dbe722fc}, + {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb}, + {0xcc963fee10b7d1b3, 0x318df905079926a9}, + {0xffbbcfe994e5c61f, 0xfdf17746497f7053}, + {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634}, + {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1}, + {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1}, + {0x9c1661a651213e2d, 0x06bea10ca65c084f}, + {0xc31bfa0fe5698db8, 0x486e494fcff30a63}, + {0xf3e2f893dec3f126, 0x5a89dba3c3efccfb}, + {0x986ddb5c6b3a76b7, 0xf89629465a75e01d}, + {0xbe89523386091465, 0xf6bbb397f1135824}, + {0xee2ba6c0678b597f, 0x746aa07ded582e2d}, + {0x94db483840b717ef, 0xa8c2a44eb4571cdd}, + {0xba121a4650e4ddeb, 0x92f34d62616ce414}, + {0xe896a0d7e51e1566, 0x77b020baf9c81d18}, + {0x915e2486ef32cd60, 0x0ace1474dc1d122f}, + {0xb5b5ada8aaff80b8, 0x0d819992132456bb}, + {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a}, + {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, + {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3}, + {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf}, + {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c}, + {0xad4ab7112eb3929d, 0x86c16c98d2c953c7}, + {0xd89d64d57a607744, 0xe871c7bf077ba8b8}, + {0x87625f056c7c4a8b, 0x11471cd764ad4973}, + {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0}, + {0xd389b47879823479, 0x4aff1d108d4ec2c4}, + {0x843610cb4bf160cb, 0xcedf722a585139bb}, + {0xa54394fe1eedb8fe, 0xc2974eb4ee658829}, + {0xce947a3da6a9273e, 0x733d226229feea33}, + {0x811ccc668829b887, 0x0806357d5a3f5260}, + {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8}, + {0xc9bcff6034c13052, 0xfc89b393dd02f0b6}, + {0xfc2c3f3841f17c67, 0xbbac2078d443ace3}, + {0x9d9ba7832936edc0, 0xd54b944b84aa4c0e}, + {0xc5029163f384a931, 0x0a9e795e65d4df12}, + {0xf64335bcf065d37d, 0x4d4617b5ff4a16d6}, + {0x99ea0196163fa42e, 0x504bced1bf8e4e46}, + {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7}, + {0xf07da27a82c37088, 0x5d767327bb4e5a4d}, + {0x964e858c91ba2655, 0x3a6a07f8d510f870}, + {0xbbe226efb628afea, 0x890489f70a55368c}, + {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f}, + {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e}, + {0xb77ada0617e3bbcb, 0x09ce6ebb40173745}, + {0xe55990879ddcaabd, 0xcc420a6a101d0516}, + {0x8f57fa54c2a9eab6, 0x9fa946824a12232e}, + {0xb32df8e9f3546564, 0x47939822dc96abfa}, + {0xdff9772470297ebd, 0x59787e2b93bc56f8}, + {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b}, + {0xaefae51477a06b03, 0xede622920b6b23f2}, + {0xdab99e59958885c4, 0xe95fab368e45ecee}, + {0x88b402f7fd75539b, 0x11dbcb0218ebb415}, + {0xaae103b5fcd2a881, 0xd652bdc29f26a11a}, + {0xd59944a37c0752a2, 0x4be76d3346f04960}, + {0x857fcae62d8493a5, 0x6f70a4400c562ddc}, + {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953}, + {0xd097ad07a71f26b2, 0x7e2000a41346a7a8}, + {0x825ecc24c873782f, 0x8ed400668c0c28c9}, + {0xa2f67f2dfa90563b, 0x728900802f0f32fb}, + {0xcbb41ef979346bca, 0x4f2b40a03ad2ffba}, + {0xfea126b7d78186bc, 0xe2f610c84987bfa9}, + {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca}, + {0xc6ede63fa05d3143, 0x91503d1c79720dbc}, + {0xf8a95fcf88747d94, 0x75a44c6397ce912b}, + {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb}, + {0xc24452da229b021b, 0xfbe85badce996169}, + {0xf2d56790ab41c2a2, 0xfae27299423fb9c4}, + {0x97c560ba6b0919a5, 0xdccd879fc967d41b}, + {0xbdb6b8e905cb600f, 0x5400e987bbc1c921}, + {0xed246723473e3813, 0x290123e9aab23b69}, + {0x9436c0760c86e30b, 0xf9a0b6720aaf6522}, + {0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, + {0xe7958cb87392c2c2, 0xb60b1d1230b20e05}, + {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3}, + {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4}, + {0xe2280b6c20dd5232, 0x25c6da63c38de1b1}, + {0x8d590723948a535f, 0x579c487e5a38ad0f}, + {0xb0af48ec79ace837, 0x2d835a9df0c6d852}, + {0xdcdb1b2798182244, 0xf8e431456cf88e66}, + {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900}, + {0xac8b2d36eed2dac5, 0xe272467e3d222f40}, + {0xd7adf884aa879177, 0x5b0ed81dcc6abb10}, + {0x86ccbb52ea94baea, 0x98e947129fc2b4ea}, + {0xa87fea27a539e9a5, 0x3f2398d747b36225}, + {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae}, + {0x83a3eeeef9153e89, 0x1953cf68300424ad}, + {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8}, + {0xcdb02555653131b6, 0x3792f412cb06794e}, + {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1}, + {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5}, + {0xc8de047564d20a8b, 0xf245825a5a445276}, + {0xfb158592be068d2e, 0xeed6e2f0f0d56713}, + {0x9ced737bb6c4183d, 0x55464dd69685606c}, + {0xc428d05aa4751e4c, 0xaa97e14c3c26b887}, + {0xf53304714d9265df, 0xd53dd99f4b3066a9}, + {0x993fe2c6d07b7fab, 0xe546a8038efe402a}, + {0xbf8fdb78849a5f96, 0xde98520472bdd034}, + {0xef73d256a5c0f77c, 0x963e66858f6d4441}, + {0x95a8637627989aad, 0xdde7001379a44aa9}, + {0xbb127c53b17ec159, 0x5560c018580d5d53}, + {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7}, + {0x9226712162ab070d, 0xcab3961304ca70e9}, + {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23}, + {0xe45c10c42a2b3b05, 0x8cb89a7db77c506b}, + {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243}, + {0xb267ed1940f1c61c, 0x55f038b237591ed4}, + {0xdf01e85f912e37a3, 0x6b6c46dec52f6689}, + {0x8b61313bbabce2c6, 0x2323ac4b3b3da016}, + {0xae397d8aa96c1b77, 0xabec975e0a0d081b}, + {0xd9c7dced53c72255, 0x96e7bd358c904a22}, + {0x881cea14545c7575, 0x7e50d64177da2e55}, + {0xaa242499697392d2, 0xdde50bd1d5d0b9ea}, + {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865}, + {0x84ec3c97da624ab4, 0xbd5af13bef0b113f}, + {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f}, + {0xcfb11ead453994ba, 0x67de18eda5814af3}, + {0x81ceb32c4b43fcf4, 0x80eacf948770ced8}, + {0xa2425ff75e14fc31, 0xa1258379a94d028e}, + {0xcad2f7f5359a3b3e, 0x096ee45813a04331}, + {0xfd87b5f28300ca0d, 0x8bca9d6e188853fd}, + {0x9e74d1b791e07e48, 0x775ea264cf55347e}, + {0xc612062576589dda, 0x95364afe032a819e}, + {0xf79687aed3eec551, 0x3a83ddbd83f52205}, + {0x9abe14cd44753b52, 0xc4926a9672793543}, + {0xc16d9a0095928a27, 0x75b7053c0f178294}, + {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, + {0x971da05074da7bee, 0xd3f6fc16ebca5e04}, + {0xbce5086492111aea, 0x88f4bb1ca6bcf585}, + {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6}, + {0x9392ee8e921d5d07, 0x3aff322e62439fd0}, + {0xb877aa3236a4b449, 0x09befeb9fad487c3}, + {0xe69594bec44de15b, 0x4c2ebe687989a9b4}, + {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11}, + {0xb424dc35095cd80f, 0x538484c19ef38c95}, + {0xe12e13424bb40e13, 0x2865a5f206b06fba}, + {0x8cbccc096f5088cb, 0xf93f87b7442e45d4}, + {0xafebff0bcb24aafe, 0xf78f69a51539d749}, + {0xdbe6fecebdedd5be, 0xb573440e5a884d1c}, + {0x89705f4136b4a597, 0x31680a88f8953031}, + {0xabcc77118461cefc, 0xfdc20d2b36ba7c3e}, + {0xd6bf94d5e57a42bc, 0x3d32907604691b4d}, + {0x8637bd05af6c69b5, 0xa63f9a49c2c1b110}, + {0xa7c5ac471b478423, 0x0fcf80dc33721d54}, + {0xd1b71758e219652b, 0xd3c36113404ea4a9}, + {0x83126e978d4fdf3b, 0x645a1cac083126ea}, + {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4}, + {0xcccccccccccccccc, 0xcccccccccccccccd}, + {0x8000000000000000, 0x0000000000000000}, + {0xa000000000000000, 0x0000000000000000}, + {0xc800000000000000, 0x0000000000000000}, + {0xfa00000000000000, 0x0000000000000000}, + {0x9c40000000000000, 0x0000000000000000}, + {0xc350000000000000, 0x0000000000000000}, + {0xf424000000000000, 0x0000000000000000}, + {0x9896800000000000, 0x0000000000000000}, + {0xbebc200000000000, 0x0000000000000000}, + {0xee6b280000000000, 0x0000000000000000}, + {0x9502f90000000000, 0x0000000000000000}, + {0xba43b74000000000, 0x0000000000000000}, + {0xe8d4a51000000000, 0x0000000000000000}, + {0x9184e72a00000000, 0x0000000000000000}, + {0xb5e620f480000000, 0x0000000000000000}, + {0xe35fa931a0000000, 0x0000000000000000}, + {0x8e1bc9bf04000000, 0x0000000000000000}, + {0xb1a2bc2ec5000000, 0x0000000000000000}, + {0xde0b6b3a76400000, 0x0000000000000000}, + {0x8ac7230489e80000, 0x0000000000000000}, + {0xad78ebc5ac620000, 0x0000000000000000}, + {0xd8d726b7177a8000, 0x0000000000000000}, + {0x878678326eac9000, 0x0000000000000000}, + {0xa968163f0a57b400, 0x0000000000000000}, + {0xd3c21bcecceda100, 0x0000000000000000}, + {0x84595161401484a0, 0x0000000000000000}, + {0xa56fa5b99019a5c8, 0x0000000000000000}, + {0xcecb8f27f4200f3a, 0x0000000000000000}, + {0x813f3978f8940984, 0x4000000000000000}, + {0xa18f07d736b90be5, 0x5000000000000000}, + {0xc9f2c9cd04674ede, 0xa400000000000000}, + {0xfc6f7c4045812296, 0x4d00000000000000}, + {0x9dc5ada82b70b59d, 0xf020000000000000}, + {0xc5371912364ce305, 0x6c28000000000000}, + {0xf684df56c3e01bc6, 0xc732000000000000}, + {0x9a130b963a6c115c, 0x3c7f400000000000}, + {0xc097ce7bc90715b3, 0x4b9f100000000000}, + {0xf0bdc21abb48db20, 0x1e86d40000000000}, + {0x96769950b50d88f4, 0x1314448000000000}, + {0xbc143fa4e250eb31, 0x17d955a000000000}, + {0xeb194f8e1ae525fd, 0x5dcfab0800000000}, + {0x92efd1b8d0cf37be, 0x5aa1cae500000000}, + {0xb7abc627050305ad, 0xf14a3d9e40000000}, + {0xe596b7b0c643c719, 0x6d9ccd05d0000000}, + {0x8f7e32ce7bea5c6f, 0xe4820023a2000000}, + {0xb35dbf821ae4f38b, 0xdda2802c8a800000}, + {0xe0352f62a19e306e, 0xd50b2037ad200000}, + {0x8c213d9da502de45, 0x4526f422cc340000}, + {0xaf298d050e4395d6, 0x9670b12b7f410000}, + {0xdaf3f04651d47b4c, 0x3c0cdd765f114000}, + {0x88d8762bf324cd0f, 0xa5880a69fb6ac800}, + {0xab0e93b6efee0053, 0x8eea0d047a457a00}, + {0xd5d238a4abe98068, 0x72a4904598d6d880}, + {0x85a36366eb71f041, 0x47a6da2b7f864750}, + {0xa70c3c40a64e6c51, 0x999090b65f67d924}, + {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d}, + {0x82818f1281ed449f, 0xbff8f10e7a8921a5}, + {0xa321f2d7226895c7, 0xaff72d52192b6a0e}, + {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764491}, + {0xfee50b7025c36a08, 0x02f236d04753d5b5}, + {0x9f4f2726179a2245, 0x01d762422c946591}, + {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef6}, + {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb3}, + {0x9b934c3b330c8577, 0x63cc55f49f88eb30}, + {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fc}, + {0xf316271c7fc3908a, 0x8bef464e3945ef7b}, + {0x97edd871cfda3a56, 0x97758bf0e3cbb5ad}, + {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea318}, + {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bde}, + {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6b}, + {0xb975d6b6ee39e436, 0xb3e2fd538e122b45}, + {0xe7d34c64a9c85d44, 0x60dbbca87196b617}, + {0x90e40fbeea1d3a4a, 0xbc8955e946fe31ce}, + {0xb51d13aea4a488dd, 0x6babab6398bdbe42}, + {0xe264589a4dcdab14, 0xc696963c7eed2dd2}, + {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca3}, + {0xb0de65388cc8ada8, 0x3b25a55f43294bcc}, + {0xdd15fe86affad912, 0x49ef0eb713f39ebf}, + {0x8a2dbf142dfcc7ab, 0x6e3569326c784338}, + {0xacb92ed9397bf996, 0x49c2c37f07965405}, + {0xd7e77a8f87daf7fb, 0xdc33745ec97be907}, + {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a4}, + {0xa8acd7c0222311bc, 0xc40832ea0d68ce0d}, + {0xd2d80db02aabd62b, 0xf50a3fa490c30191}, + {0x83c7088e1aab65db, 0x792667c6da79e0fb}, + {0xa4b8cab1a1563f52, 0x577001b891185939}, + {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87}, + {0x80b05e5ac60b6178, 0x544f8158315b05b5}, + {0xa0dc75f1778e39d6, 0x696361ae3db1c722}, + {0xc913936dd571c84c, 0x03bc3a19cd1e38ea}, + {0xfb5878494ace3a5f, 0x04ab48a04065c724}, + {0x9d174b2dcec0e47b, 0x62eb0d64283f9c77}, + {0xc45d1df942711d9a, 0x3ba5d0bd324f8395}, + {0xf5746577930d6500, 0xca8f44ec7ee3647a}, + {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecc}, + {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67f}, + {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101f}, + {0x95d04aee3b80ece5, 0xbba1f1d158724a13}, + {0xbb445da9ca61281f, 0x2a8a6e45ae8edc98}, + {0xea1575143cf97226, 0xf52d09d71a3293be}, + {0x924d692ca61be758, 0x593c2626705f9c57}, + {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836d}, + {0xe498f455c38b997a, 0x0b6dfb9c0f956448}, + {0x8edf98b59a373fec, 0x4724bd4189bd5ead}, + {0xb2977ee300c50fe7, 0x58edec91ec2cb658}, + {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ee}, + {0x8b865b215899f46c, 0xbd79e0d20082ee75}, + {0xae67f1e9aec07187, 0xecd8590680a3aa12}, + {0xda01ee641a708de9, 0xe80e6f4820cc9496}, + {0x884134fe908658b2, 0x3109058d147fdcde}, + {0xaa51823e34a7eede, 0xbd4b46f0599fd416}, + {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91b}, + {0x850fadc09923329e, 0x03e2cf6bc604ddb1}, + {0xa6539930bf6bff45, 0x84db8346b786151d}, + {0xcfe87f7cef46ff16, 0xe612641865679a64}, + {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07f}, + {0xa26da3999aef7749, 0xe3be5e330f38f09e}, + {0xcb090c8001ab551c, 0x5cadf5bfd3072cc6}, + {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f7}, + {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afb}, + {0xc646d63501a1511d, 0xb281e1fd541501b9}, + {0xf7d88bc24209a565, 0x1f225a7ca91a4227}, + {0x9ae757596946075f, 0x3375788de9b06959}, + {0xc1a12d2fc3978937, 0x0052d6b1641c83af}, + {0xf209787bb47d6b84, 0xc0678c5dbd23a49b}, + {0x9745eb4d50ce6332, 0xf840b7ba963646e1}, + {0xbd176620a501fbff, 0xb650e5a93bc3d899}, + {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebf}, + {0x93ba47c980e98cdf, 0xc66f336c36b10138}, + {0xb8a8d9bbe123f017, 0xb80b0047445d4185}, + {0xe6d3102ad96cec1d, 0xa60dc059157491e6}, + {0x9043ea1ac7e41392, 0x87c89837ad68db30}, + {0xb454e4a179dd1877, 0x29babe4598c311fc}, + {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67b}, + {0x8ce2529e2734bb1d, 0x1899e4a65f58660d}, + {0xb01ae745b101e9e4, 0x5ec05dcff72e7f90}, + {0xdc21a1171d42645d, 0x76707543f4fa1f74}, + {0x899504ae72497eba, 0x6a06494a791c53a9}, + {0xabfa45da0edbde69, 0x0487db9d17636893}, + {0xd6f8d7509292d603, 0x45a9d2845d3c42b7}, + {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3}, + {0xa7f26836f282b732, 0x8e6cac7768d7141f}, + {0xd1ef0244af2364ff, 0x3207d795430cd927}, + {0x8335616aed761f1f, 0x7f44e6bd49e807b9}, + {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a7}, + {0xcd036837130890a1, 0x36dba887c37a8c10}, + {0x802221226be55a64, 0xc2494954da2c978a}, + {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6d}, + {0xc83553c5c8965d3d, 0x6f92829494e5acc8}, + {0xfa42a8b73abbf48c, 0xcb772339ba1f17fa}, + {0x9c69a97284b578d7, 0xff2a760414536efc}, + {0xc38413cf25e2d70d, 0xfef5138519684abb}, + {0xf46518c2ef5b8cd1, 0x7eb258665fc25d6a}, + {0x98bf2f79d5993802, 0xef2f773ffbd97a62}, + {0xbeeefb584aff8603, 0xaafb550ffacfd8fb}, + {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf39}, + {0x952ab45cfa97a0b2, 0xdd945a747bf26184}, + {0xba756174393d88df, 0x94f971119aeef9e5}, + {0xe912b9d1478ceb17, 0x7a37cd5601aab85e}, + {0x91abb422ccb812ee, 0xac62e055c10ab33b}, + {0xb616a12b7fe617aa, 0x577b986b314d600a}, + {0xe39c49765fdf9d94, 0xed5a7e85fda0b80c}, + {0x8e41ade9fbebc27d, 0x14588f13be847308}, + {0xb1d219647ae6b31c, 0x596eb2d8ae258fc9}, + {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bc}, + {0x8aec23d680043bee, 0x25de7bb9480d5855}, + {0xada72ccc20054ae9, 0xaf561aa79a10ae6b}, + {0xd910f7ff28069da4, 0x1b2ba1518094da05}, + {0x87aa9aff79042286, 0x90fb44d2f05d0843}, + {0xa99541bf57452b28, 0x353a1607ac744a54}, + {0xd3fa922f2d1675f2, 0x42889b8997915ce9}, + {0x847c9b5d7c2e09b7, 0x69956135febada12}, + {0xa59bc234db398c25, 0x43fab9837e699096}, + {0xcf02b2c21207ef2e, 0x94f967e45e03f4bc}, + {0x8161afb94b44f57d, 0x1d1be0eebac278f6}, + {0xa1ba1ba79e1632dc, 0x6462d92a69731733}, + {0xca28a291859bbf93, 0x7d7b8f7503cfdcff}, + {0xfcb2cb35e702af78, 0x5cda735244c3d43f}, + {0x9defbf01b061adab, 0x3a0888136afa64a8}, + {0xc56baec21c7a1916, 0x088aaa1845b8fdd1}, + {0xf6c69a72a3989f5b, 0x8aad549e57273d46}, + {0x9a3c2087a63f6399, 0x36ac54e2f678864c}, + {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7de}, + {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d6}, + {0x969eb7c47859e743, 0x9f644ae5a4b1b326}, + {0xbc4665b596706114, 0x873d5d9f0dde1fef}, + {0xeb57ff22fc0c7959, 0xa90cb506d155a7eb}, + {0x9316ff75dd87cbd8, 0x09a7f12442d588f3}, + {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb30}, + {0xe5d3ef282a242e81, 0x8f1668c8a86da5fb}, + {0x8fa475791a569d10, 0xf96e017d694487bd}, + {0xb38d92d760ec4455, 0x37c981dcc395a9ad}, + {0xe070f78d3927556a, 0x85bbe253f47b1418}, + {0x8c469ab843b89562, 0x93956d7478ccec8f}, + {0xaf58416654a6babb, 0x387ac8d1970027b3}, + {0xdb2e51bfe9d0696a, 0x06997b05fcc0319f}, + {0x88fcf317f22241e2, 0x441fece3bdf81f04}, + {0xab3c2fddeeaad25a, 0xd527e81cad7626c4}, + {0xd60b3bd56a5586f1, 0x8a71e223d8d3b075}, + {0x85c7056562757456, 0xf6872d5667844e4a}, + {0xa738c6bebb12d16c, 0xb428f8ac016561dc}, + {0xd106f86e69d785c7, 0xe13336d701beba53}, + {0x82a45b450226b39c, 0xecc0024661173474}, + {0xa34d721642b06084, 0x27f002d7f95d0191}, + {0xcc20ce9bd35c78a5, 0x31ec038df7b441f5}, + {0xff290242c83396ce, 0x7e67047175a15272}, + {0x9f79a169bd203e41, 0x0f0062c6e984d387}, + {0xc75809c42c684dd1, 0x52c07b78a3e60869}, + {0xf92e0c3537826145, 0xa7709a56ccdf8a83}, + {0x9bbcc7a142b17ccb, 0x88a66076400bb692}, + {0xc2abf989935ddbfe, 0x6acff893d00ea436}, + {0xf356f7ebf83552fe, 0x0583f6b8c4124d44}, + {0x98165af37b2153de, 0xc3727a337a8b704b}, + {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5d}, + {0xeda2ee1c7064130c, 0x1162def06f79df74}, + {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba9}, + {0xb9a74a0637ce2ee1, 0x6d953e2bd7173693}, + {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0438}, + {0x910ab1d4db9914a0, 0x1d9c9892400a22a3}, + {0xb54d5e4a127f59c8, 0x2503beb6d00cab4c}, + {0xe2a0b5dc971f303a, 0x2e44ae64840fd61e}, + {0x8da471a9de737e24, 0x5ceaecfed289e5d3}, + {0xb10d8e1456105dad, 0x7425a83e872c5f48}, + {0xdd50f1996b947518, 0xd12f124e28f7771a}, + {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa70}, + {0xace73cbfdc0bfb7b, 0x636cc64d1001550c}, + {0xd8210befd30efa5a, 0x3c47f7e05401aa4f}, + {0x8714a775e3e95c78, 0x65acfaec34810a72}, + {0xa8d9d1535ce3b396, 0x7f1839a741a14d0e}, + {0xd31045a8341ca07c, 0x1ede48111209a051}, + {0x83ea2b892091e44d, 0x934aed0aab460433}, + {0xa4e4b66b68b65d60, 0xf81da84d56178540}, + {0xce1de40642e3f4b9, 0x36251260ab9d668f}, + {0x80d2ae83e9ce78f3, 0xc1d72b7c6b42601a}, + {0xa1075a24e4421730, 0xb24cf65b8612f820}, + {0xc94930ae1d529cfc, 0xdee033f26797b628}, + {0xfb9b7cd9a4a7443c, 0x169840ef017da3b2}, + {0x9d412e0806e88aa5, 0x8e1f289560ee864f}, + {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e3}, + {0xf5b5d7ec8acb58a2, 0xae10af696774b1dc}, + {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef2a}, + {0xbff610b0cc6edd3f, 0x17fd090a58d32af4}, + {0xeff394dcff8a948e, 0xddfc4b4cef07f5b1}, + {0x95f83d0a1fb69cd9, 0x4abdaf101564f98f}, + {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f2}, + {0xea53df5fd18d5513, 0x84c86189216dc5ee}, + {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb5}, + {0xb7118682dbb66a77, 0x3fbc8c33221dc2a2}, + {0xe4d5e82392a40515, 0x0fabaf3feaa5334b}, + {0x8f05b1163ba6832d, 0x29cb4d87f2a7400f}, + {0xb2c71d5bca9023f8, 0x743e20e9ef511013}, + {0xdf78e4b2bd342cf6, 0x914da9246b255417}, + {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548f}, + {0xae9672aba3d0c320, 0xa184ac2473b529b2}, + {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741f}, + {0x8865899617fb1871, 0x7e2fa67c7a658893}, + {0xaa7eebfb9df9de8d, 0xddbb901b98feeab8}, + {0xd51ea6fa85785631, 0x552a74227f3ea566}, + {0x8533285c936b35de, 0xd53a88958f872760}, + {0xa67ff273b8460356, 0x8a892abaf368f138}, + {0xd01fef10a657842c, 0x2d2b7569b0432d86}, + {0x8213f56a67f6b29b, 0x9c3b29620e29fc74}, + {0xa298f2c501f45f42, 0x8349f3ba91b47b90}, + {0xcb3f2f7642717713, 0x241c70a936219a74}, + {0xfe0efb53d30dd4d7, 0xed238cd383aa0111}, + {0x9ec95d1463e8a506, 0xf4363804324a40ab}, + {0xc67bb4597ce2ce48, 0xb143c6053edcd0d6}, + {0xf81aa16fdc1b81da, 0xdd94b7868e94050b}, + {0x9b10a4e5e9913128, 0xca7cf2b4191c8327}, + {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f1}, + {0xf24a01a73cf2dccf, 0xbc633b39673c8ced}, + {0x976e41088617ca01, 0xd5be0503e085d814}, + {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e19}, + {0xec9c459d51852ba2, 0xddf8e7d60ed1219f}, + {0x93e1ab8252f33b45, 0xcabb90e5c942b504}, + {0xb8da1662e7b00a17, 0x3d6a751f3b936244}, + {0xe7109bfba19c0c9d, 0x0cc512670a783ad5}, + {0x906a617d450187e2, 0x27fb2b80668b24c6}, + {0xb484f9dc9641e9da, 0xb1f9f660802dedf7}, + {0xe1a63853bbd26451, 0x5e7873f8a0396974}, + {0x8d07e33455637eb2, 0xdb0b487b6423e1e9}, + {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda63}, + {0xdc5c5301c56b75f7, 0x7641a140cc7810fc}, + {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9e}, + {0xac2820d9623bf429, 0x546345fa9fbdcd45}, + {0xd732290fbacaf133, 0xa97c177947ad4096}, + {0x867f59a9d4bed6c0, 0x49ed8eabcccc485e}, + {0xa81f301449ee8c70, 0x5c68f256bfff5a75}, + {0xd226fc195c6a2f8c, 0x73832eec6fff3112}, + {0x83585d8fd9c25db7, 0xc831fd53c5ff7eac}, + {0xa42e74f3d032f525, 0xba3e7ca8b77f5e56}, + {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35ec}, + {0x80444b5e7aa7cf85, 0x7980d163cf5b81b4}, + {0xa0555e361951c366, 0xd7e105bcc3326220}, + {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa8}, + {0xfa856334878fc150, 0xb14f98f6f0feb952}, + {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d4}, + {0xc3b8358109e84f07, 0x0a862f80ec4700c9}, + {0xf4a642e14c6262c8, 0xcd27bb612758c0fb}, + {0x98e7e9cccfbd7dbd, 0x8038d51cb897789d}, + {0xbf21e44003acdd2c, 0xe0470a63e6bd56c4}, + {0xeeea5d5004981478, 0x1858ccfce06cac75}, + {0x95527a5202df0ccb, 0x0f37801e0c43ebc9}, + {0xbaa718e68396cffd, 0xd30560258f54e6bb}, + {0xe950df20247c83fd, 0x47c6b82ef32a206a}, + {0x91d28b7416cdd27e, 0x4cdc331d57fa5442}, + {0xb6472e511c81471d, 0xe0133fe4adf8e953}, + {0xe3d8f9e563a198e5, 0x58180fddd97723a7}, + {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7649}, + {0xb201833b35d63f73, 0x2cd2cc6551e513db}, + {0xde81e40a034bcf4f, 0xf8077f7ea65e58d2}, + {0x8b112e86420f6191, 0xfb04afaf27faf783}, + {0xadd57a27d29339f6, 0x79c5db9af1f9b564}, + {0xd94ad8b1c7380874, 0x18375281ae7822bd}, + {0x87cec76f1c830548, 0x8f2293910d0b15b6}, + {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb23}, + {0xd433179d9c8cb841, 0x5fa60692a46151ec}, + {0x849feec281d7f328, 0xdbc7c41ba6bcd334}, + {0xa5c7ea73224deff3, 0x12b9b522906c0801}, + {0xcf39e50feae16bef, 0xd768226b34870a01}, + {0x81842f29f2cce375, 0xe6a1158300d46641}, + {0xa1e53af46f801c53, 0x60495ae3c1097fd1}, + {0xca5e89b18b602368, 0x385bb19cb14bdfc5}, + {0xfcf62c1dee382c42, 0x46729e03dd9ed7b6}, + {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d2}, + {0xc5a05277621be293, 0xc7098b7305241886}, + {0xf70867153aa2db38, 0xb8cbee4fc66d1ea8}, + {0x9a65406d44a5c903, 0x737f74f1dc043329}, + {0xc0fe908895cf3b44, 0x505f522e53053ff3}, + {0xf13e34aabb430a15, 0x647726b9e7c68ff0}, + {0x96c6e0eab509e64d, 0x5eca783430dc19f6}, + {0xbc789925624c5fe0, 0xb67d16413d132073}, + {0xeb96bf6ebadf77d8, 0xe41c5bd18c57e890}, + {0x933e37a534cbaae7, 0x8e91b962f7b6f15a}, + {0xb80dc58e81fe95a1, 0x723627bbb5a4adb1}, + {0xe61136f2227e3b09, 0xcec3b1aaa30dd91d}, + {0x8fcac257558ee4e6, 0x213a4f0aa5e8a7b2}, + {0xb3bd72ed2af29e1f, 0xa988e2cd4f62d19e}, + {0xe0accfa875af45a7, 0x93eb1b80a33b8606}, + {0x8c6c01c9498d8b88, 0xbc72f130660533c4}, + {0xaf87023b9bf0ee6a, 0xeb8fad7c7f8680b5}, + {0xdb68c2ca82ed2a05, 0xa67398db9f6820e2}, +#else + {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, + {0xce5d73ff402d98e3, 0xfb0a3d212dc81290}, + {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, + {0x86a8d39ef77164bc, 0xae5dff9c02033198}, + {0xd98ddaee19068c76, 0x3badd624dd9b0958}, + {0xafbd2350644eeacf, 0xe5d1929ef90898fb}, + {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, + {0xe55990879ddcaabd, 0xcc420a6a101d0516}, + {0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, + {0x95a8637627989aad, 0xdde7001379a44aa9}, + {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, + {0xc350000000000000, 0x0000000000000000}, + {0x9dc5ada82b70b59d, 0xf020000000000000}, + {0xfee50b7025c36a08, 0x02f236d04753d5b5}, + {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87}, + {0xa6539930bf6bff45, 0x84db8346b786151d}, + {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3}, + {0xd910f7ff28069da4, 0x1b2ba1518094da05}, + {0xaf58416654a6babb, 0x387ac8d1970027b3}, + {0x8da471a9de737e24, 0x5ceaecfed289e5d3}, + {0xe4d5e82392a40515, 0x0fabaf3feaa5334b}, + {0xb8da1662e7b00a17, 0x3d6a751f3b936244}, + {0x95527a5202df0ccb, 0x0f37801e0c43ebc9}, + {0xf13e34aabb430a15, 0x647726b9e7c68ff0} +#endif + }; + +#if FMT_USE_FULL_CACHE_DRAGONBOX + return pow10_significands[k - float_info::min_k]; +#else + static constexpr uint64_t powers_of_5_64[] = { + 0x0000000000000001, 0x0000000000000005, 0x0000000000000019, + 0x000000000000007d, 0x0000000000000271, 0x0000000000000c35, + 0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1, + 0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd, + 0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9, + 0x000000071afd498d, 0x0000002386f26fc1, 0x000000b1a2bc2ec5, + 0x000003782dace9d9, 0x00001158e460913d, 0x000056bc75e2d631, + 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed, + 0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9}; + + static const int compression_ratio = 27; + + // Compute base index. + int cache_index = (k - float_info::min_k) / compression_ratio; + int kb = cache_index * compression_ratio + float_info::min_k; + int offset = k - kb; + + // Get base cache. + uint128_fallback base_cache = pow10_significands[cache_index]; + if (offset == 0) return base_cache; + + // Compute the required amount of bit-shift. + int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset; + FMT_ASSERT(alpha > 0 && alpha < 64, "shifting error detected"); + + // Try to recover the real cache. + uint64_t pow5 = powers_of_5_64[offset]; + uint128_fallback recovered_cache = umul128(base_cache.high(), pow5); + uint128_fallback middle_low = umul128(base_cache.low(), pow5); + + recovered_cache += middle_low.high(); + + uint64_t high_to_middle = recovered_cache.high() << (64 - alpha); + uint64_t middle_to_low = recovered_cache.low() << (64 - alpha); + + recovered_cache = + uint128_fallback{(recovered_cache.low() >> alpha) | high_to_middle, + ((middle_low.low() >> alpha) | middle_to_low)}; + FMT_ASSERT(recovered_cache.low() + 1 != 0, ""); + return {recovered_cache.high(), recovered_cache.low() + 1}; +#endif + } + + struct compute_mul_result { + carrier_uint result; + bool is_integer; + }; + struct compute_mul_parity_result { + bool parity; + bool is_integer; + }; + + static auto compute_mul(carrier_uint u, + const cache_entry_type& cache) noexcept + -> compute_mul_result { + auto r = umul192_upper128(u, cache); + return {r.high(), r.low() == 0}; + } + + static auto compute_delta(const cache_entry_type& cache, int beta) noexcept + -> uint32_t { + return static_cast(cache.high() >> (64 - 1 - beta)); + } + + static auto compute_mul_parity(carrier_uint two_f, + const cache_entry_type& cache, + int beta) noexcept + -> compute_mul_parity_result { + FMT_ASSERT(beta >= 1, ""); + FMT_ASSERT(beta < 64, ""); + + auto r = umul192_lower128(two_f, cache); + return {((r.high() >> (64 - beta)) & 1) != 0, + ((r.high() << beta) | (r.low() >> (64 - beta))) == 0}; + } + + static auto compute_left_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta) noexcept -> carrier_uint { + return (cache.high() - + (cache.high() >> (num_significand_bits() + 2))) >> + (64 - num_significand_bits() - 1 - beta); + } + + static auto compute_right_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta) noexcept -> carrier_uint { + return (cache.high() + + (cache.high() >> (num_significand_bits() + 1))) >> + (64 - num_significand_bits() - 1 - beta); + } + + static auto compute_round_up_for_shorter_interval_case( + const cache_entry_type& cache, int beta) noexcept -> carrier_uint { + return ((cache.high() >> (64 - num_significand_bits() - 2 - beta)) + + 1) / + 2; + } +}; + +FMT_FUNC auto get_cached_power(int k) noexcept -> uint128_fallback { + return cache_accessor::get_cached_power(k); +} + +// Various integer checks +template +auto is_left_endpoint_integer_shorter_interval(int exponent) noexcept -> bool { + const int case_shorter_interval_left_endpoint_lower_threshold = 2; + const int case_shorter_interval_left_endpoint_upper_threshold = 3; + return exponent >= case_shorter_interval_left_endpoint_lower_threshold && + exponent <= case_shorter_interval_left_endpoint_upper_threshold; +} + +// Remove trailing zeros from n and return the number of zeros removed (float). +FMT_INLINE auto remove_trailing_zeros(uint32_t& n, int s = 0) noexcept -> int { + FMT_ASSERT(n != 0, ""); + // Modular inverse of 5 (mod 2^32): (mod_inv_5 * 5) mod 2^32 = 1. + constexpr uint32_t mod_inv_5 = 0xcccccccd; + constexpr uint32_t mod_inv_25 = 0xc28f5c29; // = mod_inv_5 * mod_inv_5 + + while (true) { + auto q = rotr(n * mod_inv_25, 2); + if (q > max_value() / 100) break; + n = q; + s += 2; + } + auto q = rotr(n * mod_inv_5, 1); + if (q <= max_value() / 10) { + n = q; + s |= 1; + } + return s; +} + +// Removes trailing zeros and returns the number of zeros removed (double). +FMT_INLINE auto remove_trailing_zeros(uint64_t& n) noexcept -> int { + FMT_ASSERT(n != 0, ""); + + // Is n is divisible by 10^8? + constexpr uint32_t ten_pow_8 = 100000000u; + if ((n % ten_pow_8) == 0) { + // If yes, work with the quotient... + auto n32 = static_cast(n / ten_pow_8); + // ... and use the 32 bit variant of the function + int num_zeros = remove_trailing_zeros(n32, 8); + n = n32; + return num_zeros; + } + + // If n is not divisible by 10^8, work with n itself. + constexpr uint64_t mod_inv_5 = 0xcccccccccccccccd; + constexpr uint64_t mod_inv_25 = 0x8f5c28f5c28f5c29; // mod_inv_5 * mod_inv_5 + + int s = 0; + while (true) { + auto q = rotr(n * mod_inv_25, 2); + if (q > max_value() / 100) break; + n = q; + s += 2; + } + auto q = rotr(n * mod_inv_5, 1); + if (q <= max_value() / 10) { + n = q; + s |= 1; + } + + return s; +} + +// The main algorithm for shorter interval case +template +FMT_INLINE auto shorter_interval_case(int exponent) noexcept -> decimal_fp { + decimal_fp ret_value; + // Compute k and beta + const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent); + const int beta = exponent + floor_log2_pow10(-minus_k); + + // Compute xi and zi + using cache_entry_type = typename cache_accessor::cache_entry_type; + const cache_entry_type cache = cache_accessor::get_cached_power(-minus_k); + + auto xi = cache_accessor::compute_left_endpoint_for_shorter_interval_case( + cache, beta); + auto zi = cache_accessor::compute_right_endpoint_for_shorter_interval_case( + cache, beta); + + // If the left endpoint is not an integer, increase it + if (!is_left_endpoint_integer_shorter_interval(exponent)) ++xi; + + // Try bigger divisor + ret_value.significand = zi / 10; + + // If succeed, remove trailing zeros if necessary and return + if (ret_value.significand * 10 >= xi) { + ret_value.exponent = minus_k + 1; + ret_value.exponent += remove_trailing_zeros(ret_value.significand); + return ret_value; + } + + // Otherwise, compute the round-up of y + ret_value.significand = + cache_accessor::compute_round_up_for_shorter_interval_case(cache, + beta); + ret_value.exponent = minus_k; + + // When tie occurs, choose one of them according to the rule + if (exponent >= float_info::shorter_interval_tie_lower_threshold && + exponent <= float_info::shorter_interval_tie_upper_threshold) { + ret_value.significand = ret_value.significand % 2 == 0 + ? ret_value.significand + : ret_value.significand - 1; + } else if (ret_value.significand < xi) { + ++ret_value.significand; + } + return ret_value; +} + +template auto to_decimal(T x) noexcept -> decimal_fp { + // Step 1: integer promotion & Schubfach multiplier calculation. + + using carrier_uint = typename float_info::carrier_uint; + using cache_entry_type = typename cache_accessor::cache_entry_type; + auto br = bit_cast(x); + + // Extract significand bits and exponent bits. + const carrier_uint significand_mask = + (static_cast(1) << num_significand_bits()) - 1; + carrier_uint significand = (br & significand_mask); + int exponent = + static_cast((br & exponent_mask()) >> num_significand_bits()); + + if (exponent != 0) { // Check if normal. + exponent -= exponent_bias() + num_significand_bits(); + + // Shorter interval case; proceed like Schubfach. + // In fact, when exponent == 1 and significand == 0, the interval is + // regular. However, it can be shown that the end-results are anyway same. + if (significand == 0) return shorter_interval_case(exponent); + + significand |= (static_cast(1) << num_significand_bits()); + } else { + // Subnormal case; the interval is always regular. + if (significand == 0) return {0, 0}; + exponent = + std::numeric_limits::min_exponent - num_significand_bits() - 1; + } + + const bool include_left_endpoint = (significand % 2 == 0); + const bool include_right_endpoint = include_left_endpoint; + + // Compute k and beta. + const int minus_k = floor_log10_pow2(exponent) - float_info::kappa; + const cache_entry_type cache = cache_accessor::get_cached_power(-minus_k); + const int beta = exponent + floor_log2_pow10(-minus_k); + + // Compute zi and deltai. + // 10^kappa <= deltai < 10^(kappa + 1) + const uint32_t deltai = cache_accessor::compute_delta(cache, beta); + const carrier_uint two_fc = significand << 1; + + // For the case of binary32, the result of integer check is not correct for + // 29711844 * 2^-82 + // = 6.1442653300000000008655037797566933477355632930994033813476... * 10^-18 + // and 29711844 * 2^-81 + // = 1.2288530660000000001731007559513386695471126586198806762695... * 10^-17, + // and they are the unique counterexamples. However, since 29711844 is even, + // this does not cause any problem for the endpoints calculations; it can only + // cause a problem when we need to perform integer check for the center. + // Fortunately, with these inputs, that branch is never executed, so we are + // fine. + const typename cache_accessor::compute_mul_result z_mul = + cache_accessor::compute_mul((two_fc | 1) << beta, cache); + + // Step 2: Try larger divisor; remove trailing zeros if necessary. + + // Using an upper bound on zi, we might be able to optimize the division + // better than the compiler; we are computing zi / big_divisor here. + decimal_fp ret_value; + ret_value.significand = divide_by_10_to_kappa_plus_1(z_mul.result); + uint32_t r = static_cast(z_mul.result - float_info::big_divisor * + ret_value.significand); + + if (r < deltai) { + // Exclude the right endpoint if necessary. + if (r == 0 && (z_mul.is_integer & !include_right_endpoint)) { + --ret_value.significand; + r = float_info::big_divisor; + goto small_divisor_case_label; + } + } else if (r > deltai) { + goto small_divisor_case_label; + } else { + // r == deltai; compare fractional parts. + const typename cache_accessor::compute_mul_parity_result x_mul = + cache_accessor::compute_mul_parity(two_fc - 1, cache, beta); + + if (!(x_mul.parity | (x_mul.is_integer & include_left_endpoint))) + goto small_divisor_case_label; + } + ret_value.exponent = minus_k + float_info::kappa + 1; + + // We may need to remove trailing zeros. + ret_value.exponent += remove_trailing_zeros(ret_value.significand); + return ret_value; + + // Step 3: Find the significand with the smaller divisor. + +small_divisor_case_label: + ret_value.significand *= 10; + ret_value.exponent = minus_k + float_info::kappa; + + uint32_t dist = r - (deltai / 2) + (float_info::small_divisor / 2); + const bool approx_y_parity = + ((dist ^ (float_info::small_divisor / 2)) & 1) != 0; + + // Is dist divisible by 10^kappa? + const bool divisible_by_small_divisor = + check_divisibility_and_divide_by_pow10::kappa>(dist); + + // Add dist / 10^kappa to the significand. + ret_value.significand += dist; + + if (!divisible_by_small_divisor) return ret_value; + + // Check z^(f) >= epsilon^(f). + // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1, + // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f). + // Since there are only 2 possibilities, we only need to care about the + // parity. Also, zi and r should have the same parity since the divisor + // is an even number. + const auto y_mul = cache_accessor::compute_mul_parity(two_fc, cache, beta); + + // If z^(f) >= epsilon^(f), we might have a tie when z^(f) == epsilon^(f), + // or equivalently, when y is an integer. + if (y_mul.parity != approx_y_parity) + --ret_value.significand; + else if (y_mul.is_integer & (ret_value.significand % 2 != 0)) + --ret_value.significand; + return ret_value; +} +} // namespace dragonbox +} // namespace detail + +template <> struct formatter { + FMT_CONSTEXPR auto parse(format_parse_context& ctx) + -> format_parse_context::iterator { + return ctx.begin(); + } + + auto format(const detail::bigint& n, format_context& ctx) const + -> format_context::iterator { + auto out = ctx.out(); + bool first = true; + for (auto i = n.bigits_.size(); i > 0; --i) { + auto value = n.bigits_[i - 1u]; + if (first) { + out = fmt::format_to(out, FMT_STRING("{:x}"), value); + first = false; + continue; + } + out = fmt::format_to(out, FMT_STRING("{:08x}"), value); + } + if (n.exp_ > 0) + out = fmt::format_to(out, FMT_STRING("p{}"), + n.exp_ * detail::bigint::bigit_bits); + return out; + } +}; + +FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) { + for_each_codepoint(s, [this](uint32_t cp, string_view) { + if (cp == invalid_code_point) FMT_THROW(std::runtime_error("invalid utf8")); + if (cp <= 0xFFFF) { + buffer_.push_back(static_cast(cp)); + } else { + cp -= 0x10000; + buffer_.push_back(static_cast(0xD800 + (cp >> 10))); + buffer_.push_back(static_cast(0xDC00 + (cp & 0x3FF))); + } + return true; + }); + buffer_.push_back(0); +} + +FMT_FUNC void format_system_error(detail::buffer& out, int error_code, + const char* message) noexcept { + FMT_TRY { + auto ec = std::error_code(error_code, std::generic_category()); + detail::write(appender(out), std::system_error(ec, message).what()); + return; + } + FMT_CATCH(...) {} + format_error_code(out, error_code, message); +} + +FMT_FUNC void report_system_error(int error_code, + const char* message) noexcept { + do_report_error(format_system_error, error_code, message); +} + +FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string { + // Don't optimize the "{}" case to keep the binary size small and because it + // can be better optimized in fmt::format anyway. + auto buffer = memory_buffer(); + detail::vformat_to(buffer, fmt, args); + return to_string(buffer); +} + +namespace detail { + +FMT_FUNC void vformat_to(buffer& buf, string_view fmt, format_args args, + locale_ref loc) { + auto out = appender(buf); + if (fmt.size() == 2 && equal2(fmt.data(), "{}")) + return args.get(0).visit(default_arg_formatter{out}); + parse_format_string(fmt, + format_handler<>{parse_context<>(fmt), {out, args, loc}}); +} + +template struct span { + T* data; + size_t size; +}; + +template auto flockfile(F* f) -> decltype(_lock_file(f)) { + _lock_file(f); +} +template auto funlockfile(F* f) -> decltype(_unlock_file(f)) { + _unlock_file(f); +} + +#ifndef getc_unlocked +template auto getc_unlocked(F* f) -> decltype(_fgetc_nolock(f)) { + return _fgetc_nolock(f); +} +#endif + +template +struct has_flockfile : std::false_type {}; + +template +struct has_flockfile()))>> + : std::true_type {}; + +// A FILE wrapper. F is FILE defined as a template parameter to make system API +// detection work. +template class file_base { + public: + F* file_; + + public: + file_base(F* file) : file_(file) {} + operator F*() const { return file_; } + + // Reads a code unit from the stream. + auto get() -> int { + int result = getc_unlocked(file_); + if (result == EOF && ferror(file_) != 0) + FMT_THROW(system_error(errno, FMT_STRING("getc failed"))); + return result; + } + + // Puts the code unit back into the stream buffer. + void unget(char c) { + if (ungetc(c, file_) == EOF) + FMT_THROW(system_error(errno, FMT_STRING("ungetc failed"))); + } + + void flush() { fflush(this->file_); } +}; + +// A FILE wrapper for glibc. +template class glibc_file : public file_base { + private: + enum { + line_buffered = 0x200, // _IO_LINE_BUF + unbuffered = 2 // _IO_UNBUFFERED + }; + + public: + using file_base::file_base; + + auto is_buffered() const -> bool { + return (this->file_->_flags & unbuffered) == 0; + } + + void init_buffer() { + if (this->file_->_IO_write_ptr < this->file_->_IO_write_end) return; + // Force buffer initialization by placing and removing a char in a buffer. + putc_unlocked(0, this->file_); + --this->file_->_IO_write_ptr; + } + + // Returns the file's read buffer. + auto get_read_buffer() const -> span { + auto ptr = this->file_->_IO_read_ptr; + return {ptr, to_unsigned(this->file_->_IO_read_end - ptr)}; + } + + // Returns the file's write buffer. + auto get_write_buffer() const -> span { + auto ptr = this->file_->_IO_write_ptr; + return {ptr, to_unsigned(this->file_->_IO_buf_end - ptr)}; + } + + void advance_write_buffer(size_t size) { this->file_->_IO_write_ptr += size; } + + auto needs_flush() const -> bool { + if ((this->file_->_flags & line_buffered) == 0) return false; + char* end = this->file_->_IO_write_end; + auto size = max_of(this->file_->_IO_write_ptr - end, 0); + return memchr(end, '\n', static_cast(size)); + } + + void flush() { fflush_unlocked(this->file_); } +}; + +// A FILE wrapper for Apple's libc. +template class apple_file : public file_base { + private: + enum { + line_buffered = 1, // __SNBF + unbuffered = 2 // __SLBF + }; + + public: + using file_base::file_base; + + auto is_buffered() const -> bool { + return (this->file_->_flags & unbuffered) == 0; + } + + void init_buffer() { + if (this->file_->_p) return; + // Force buffer initialization by placing and removing a char in a buffer. + if (!FMT_CLANG_ANALYZER) putc_unlocked(0, this->file_); + --this->file_->_p; + ++this->file_->_w; + } + + auto get_read_buffer() const -> span { + return {reinterpret_cast(this->file_->_p), + to_unsigned(this->file_->_r)}; + } + + auto get_write_buffer() const -> span { + return {reinterpret_cast(this->file_->_p), + to_unsigned(this->file_->_bf._base + this->file_->_bf._size - + this->file_->_p)}; + } + + void advance_write_buffer(size_t size) { + this->file_->_p += size; + this->file_->_w -= size; + } + + auto needs_flush() const -> bool { + if ((this->file_->_flags & line_buffered) == 0) return false; + return memchr(this->file_->_p + this->file_->_w, '\n', + to_unsigned(-this->file_->_w)); + } +}; + +// A fallback FILE wrapper. +template class fallback_file : public file_base { + private: + char next_; // The next unconsumed character in the buffer. + bool has_next_ = false; + + public: + using file_base::file_base; + + auto is_buffered() const -> bool { return false; } + auto needs_flush() const -> bool { return false; } + void init_buffer() {} + + auto get_read_buffer() const -> span { + return {&next_, has_next_ ? 1u : 0u}; + } + + auto get_write_buffer() const -> span { return {nullptr, 0}; } + + void advance_write_buffer(size_t) {} + + auto get() -> int { + has_next_ = false; + return file_base::get(); + } + + void unget(char c) { + file_base::unget(c); + next_ = c; + has_next_ = true; + } +}; + +#ifndef FMT_USE_FALLBACK_FILE +# define FMT_USE_FALLBACK_FILE 0 +#endif + +template +auto get_file(F* f, int) -> apple_file { + return f; +} +template +inline auto get_file(F* f, int) -> glibc_file { + return f; +} + +inline auto get_file(FILE* f, ...) -> fallback_file { return f; } + +using file_ref = decltype(get_file(static_cast(nullptr), 0)); + +template +class file_print_buffer : public buffer { + public: + explicit file_print_buffer(F*) : buffer(nullptr, size_t()) {} +}; + +template +class file_print_buffer::value>> + : public buffer { + private: + file_ref file_; + + static void grow(buffer& base, size_t) { + auto& self = static_cast(base); + self.file_.advance_write_buffer(self.size()); + if (self.file_.get_write_buffer().size == 0) self.file_.flush(); + auto buf = self.file_.get_write_buffer(); + FMT_ASSERT(buf.size > 0, ""); + self.set(buf.data, buf.size); + self.clear(); + } + + public: + explicit file_print_buffer(F* f) : buffer(grow, size_t()), file_(f) { + flockfile(f); + file_.init_buffer(); + auto buf = file_.get_write_buffer(); + set(buf.data, buf.size); + } + ~file_print_buffer() { + file_.advance_write_buffer(size()); + bool flush = file_.needs_flush(); + F* f = file_; // Make funlockfile depend on the template parameter F + funlockfile(f); // for the system API detection to work. + if (flush) fflush(file_); + } +}; + +#if !defined(_WIN32) || defined(FMT_USE_WRITE_CONSOLE) +FMT_FUNC auto write_console(int, string_view) -> bool { return false; } +#else +using dword = conditional_t; +extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( // + void*, const void*, dword, dword*, void*); + +FMT_FUNC bool write_console(int fd, string_view text) { + auto u16 = utf8_to_utf16(text); + return WriteConsoleW(reinterpret_cast(_get_osfhandle(fd)), u16.c_str(), + static_cast(u16.size()), nullptr, nullptr) != 0; +} +#endif + +#ifdef _WIN32 +// Print assuming legacy (non-Unicode) encoding. +FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args, + bool newline) { + auto buffer = memory_buffer(); + detail::vformat_to(buffer, fmt, args); + if (newline) buffer.push_back('\n'); + fwrite_all(buffer.data(), buffer.size(), f); +} +#endif + +FMT_FUNC void print(std::FILE* f, string_view text) { +#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE) + int fd = _fileno(f); + if (_isatty(fd)) { + std::fflush(f); + if (write_console(fd, text)) return; + } +#endif + fwrite_all(text.data(), text.size(), f); +} +} // namespace detail + +FMT_FUNC void vprint_buffered(std::FILE* f, string_view fmt, format_args args) { + auto buffer = memory_buffer(); + detail::vformat_to(buffer, fmt, args); + detail::print(f, {buffer.data(), buffer.size()}); +} + +FMT_FUNC void vprint(std::FILE* f, string_view fmt, format_args args) { + if (!detail::file_ref(f).is_buffered() || !detail::has_flockfile<>()) + return vprint_buffered(f, fmt, args); + auto&& buffer = detail::file_print_buffer<>(f); + return detail::vformat_to(buffer, fmt, args); +} + +FMT_FUNC void vprintln(std::FILE* f, string_view fmt, format_args args) { + auto buffer = memory_buffer(); + detail::vformat_to(buffer, fmt, args); + buffer.push_back('\n'); + detail::print(f, {buffer.data(), buffer.size()}); +} + +FMT_FUNC void vprint(string_view fmt, format_args args) { + vprint(stdout, fmt, args); +} + +namespace detail { + +struct singleton { + unsigned char upper; + unsigned char lower_count; +}; + +inline auto is_printable(uint16_t x, const singleton* singletons, + size_t singletons_size, + const unsigned char* singleton_lowers, + const unsigned char* normal, size_t normal_size) + -> bool { + auto upper = x >> 8; + auto lower_start = 0; + for (size_t i = 0; i < singletons_size; ++i) { + auto s = singletons[i]; + auto lower_end = lower_start + s.lower_count; + if (upper < s.upper) break; + if (upper == s.upper) { + for (auto j = lower_start; j < lower_end; ++j) { + if (singleton_lowers[j] == (x & 0xff)) return false; + } + } + lower_start = lower_end; + } + + auto xsigned = static_cast(x); + auto current = true; + for (size_t i = 0; i < normal_size; ++i) { + auto v = static_cast(normal[i]); + auto len = (v & 0x80) != 0 ? (v & 0x7f) << 8 | normal[++i] : v; + xsigned -= len; + if (xsigned < 0) break; + current = !current; + } + return current; +} + +// This code is generated by support/printable.py. +FMT_FUNC auto is_printable(uint32_t cp) -> bool { + static constexpr singleton singletons0[] = { + {0x00, 1}, {0x03, 5}, {0x05, 6}, {0x06, 3}, {0x07, 6}, {0x08, 8}, + {0x09, 17}, {0x0a, 28}, {0x0b, 25}, {0x0c, 20}, {0x0d, 16}, {0x0e, 13}, + {0x0f, 4}, {0x10, 3}, {0x12, 18}, {0x13, 9}, {0x16, 1}, {0x17, 5}, + {0x18, 2}, {0x19, 3}, {0x1a, 7}, {0x1c, 2}, {0x1d, 1}, {0x1f, 22}, + {0x20, 3}, {0x2b, 3}, {0x2c, 2}, {0x2d, 11}, {0x2e, 1}, {0x30, 3}, + {0x31, 2}, {0x32, 1}, {0xa7, 2}, {0xa9, 2}, {0xaa, 4}, {0xab, 8}, + {0xfa, 2}, {0xfb, 5}, {0xfd, 4}, {0xfe, 3}, {0xff, 9}, + }; + static constexpr unsigned char singletons0_lower[] = { + 0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57, 0x58, 0x8b, 0x8c, 0x90, + 0x1c, 0x1d, 0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f, + 0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92, 0xa9, 0xb1, + 0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04, + 0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a, 0x5d, + 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf, + 0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, + 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, + 0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65, 0x8d, + 0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d, + 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, + 0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7, + 0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, + 0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7, + 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, + 0xfe, 0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e, + 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, + 0x17, 0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e, + 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, + 0x74, 0x75, 0x96, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, + 0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0, + 0xc1, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27, + 0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91, + 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, + 0xfe, 0xff, + }; + static constexpr singleton singletons1[] = { + {0x00, 6}, {0x01, 1}, {0x03, 1}, {0x04, 2}, {0x08, 8}, {0x09, 2}, + {0x0a, 5}, {0x0b, 2}, {0x0e, 4}, {0x10, 1}, {0x11, 2}, {0x12, 5}, + {0x13, 17}, {0x14, 1}, {0x15, 2}, {0x17, 2}, {0x19, 13}, {0x1c, 5}, + {0x1d, 8}, {0x24, 1}, {0x6a, 3}, {0x6b, 2}, {0xbc, 2}, {0xd1, 2}, + {0xd4, 12}, {0xd5, 9}, {0xd6, 2}, {0xd7, 2}, {0xda, 1}, {0xe0, 5}, + {0xe1, 2}, {0xe8, 2}, {0xee, 32}, {0xf0, 4}, {0xf8, 2}, {0xf9, 2}, + {0xfa, 2}, {0xfb, 1}, + }; + static constexpr unsigned char singletons1_lower[] = { + 0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x9e, 0x9f, 0x06, 0x07, + 0x09, 0x36, 0x3d, 0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36, + 0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd, 0x35, 0xe0, 0x12, 0x87, + 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, + 0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5c, 0xb6, 0xb7, 0x1b, + 0x1c, 0x07, 0x08, 0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9, + 0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66, + 0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, + 0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc, + 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, + 0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, 0xc5, 0xc6, + 0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c, + 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, + 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0, + 0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93, + }; + static constexpr unsigned char normal0[] = { + 0x00, 0x20, 0x5f, 0x22, 0x82, 0xdf, 0x04, 0x82, 0x44, 0x08, 0x1b, 0x04, + 0x06, 0x11, 0x81, 0xac, 0x0e, 0x80, 0xab, 0x35, 0x28, 0x0b, 0x80, 0xe0, + 0x03, 0x19, 0x08, 0x01, 0x04, 0x2f, 0x04, 0x34, 0x04, 0x07, 0x03, 0x01, + 0x07, 0x06, 0x07, 0x11, 0x0a, 0x50, 0x0f, 0x12, 0x07, 0x55, 0x07, 0x03, + 0x04, 0x1c, 0x0a, 0x09, 0x03, 0x08, 0x03, 0x07, 0x03, 0x02, 0x03, 0x03, + 0x03, 0x0c, 0x04, 0x05, 0x03, 0x0b, 0x06, 0x01, 0x0e, 0x15, 0x05, 0x3a, + 0x03, 0x11, 0x07, 0x06, 0x05, 0x10, 0x07, 0x57, 0x07, 0x02, 0x07, 0x15, + 0x0d, 0x50, 0x04, 0x43, 0x03, 0x2d, 0x03, 0x01, 0x04, 0x11, 0x06, 0x0f, + 0x0c, 0x3a, 0x04, 0x1d, 0x25, 0x5f, 0x20, 0x6d, 0x04, 0x6a, 0x25, 0x80, + 0xc8, 0x05, 0x82, 0xb0, 0x03, 0x1a, 0x06, 0x82, 0xfd, 0x03, 0x59, 0x07, + 0x15, 0x0b, 0x17, 0x09, 0x14, 0x0c, 0x14, 0x0c, 0x6a, 0x06, 0x0a, 0x06, + 0x1a, 0x06, 0x59, 0x07, 0x2b, 0x05, 0x46, 0x0a, 0x2c, 0x04, 0x0c, 0x04, + 0x01, 0x03, 0x31, 0x0b, 0x2c, 0x04, 0x1a, 0x06, 0x0b, 0x03, 0x80, 0xac, + 0x06, 0x0a, 0x06, 0x21, 0x3f, 0x4c, 0x04, 0x2d, 0x03, 0x74, 0x08, 0x3c, + 0x03, 0x0f, 0x03, 0x3c, 0x07, 0x38, 0x08, 0x2b, 0x05, 0x82, 0xff, 0x11, + 0x18, 0x08, 0x2f, 0x11, 0x2d, 0x03, 0x20, 0x10, 0x21, 0x0f, 0x80, 0x8c, + 0x04, 0x82, 0x97, 0x19, 0x0b, 0x15, 0x88, 0x94, 0x05, 0x2f, 0x05, 0x3b, + 0x07, 0x02, 0x0e, 0x18, 0x09, 0x80, 0xb3, 0x2d, 0x74, 0x0c, 0x80, 0xd6, + 0x1a, 0x0c, 0x05, 0x80, 0xff, 0x05, 0x80, 0xdf, 0x0c, 0xee, 0x0d, 0x03, + 0x84, 0x8d, 0x03, 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, 0x80, + 0xcb, 0x2a, 0x38, 0x03, 0x0a, 0x06, 0x38, 0x08, 0x46, 0x08, 0x0c, 0x06, + 0x74, 0x0b, 0x1e, 0x03, 0x5a, 0x04, 0x59, 0x09, 0x80, 0x83, 0x18, 0x1c, + 0x0a, 0x16, 0x09, 0x4c, 0x04, 0x80, 0x8a, 0x06, 0xab, 0xa4, 0x0c, 0x17, + 0x04, 0x31, 0xa1, 0x04, 0x81, 0xda, 0x26, 0x07, 0x0c, 0x05, 0x05, 0x80, + 0xa5, 0x11, 0x81, 0x6d, 0x10, 0x78, 0x28, 0x2a, 0x06, 0x4c, 0x04, 0x80, + 0x8d, 0x04, 0x80, 0xbe, 0x03, 0x1b, 0x03, 0x0f, 0x0d, + }; + static constexpr unsigned char normal1[] = { + 0x5e, 0x22, 0x7b, 0x05, 0x03, 0x04, 0x2d, 0x03, 0x66, 0x03, 0x01, 0x2f, + 0x2e, 0x80, 0x82, 0x1d, 0x03, 0x31, 0x0f, 0x1c, 0x04, 0x24, 0x09, 0x1e, + 0x05, 0x2b, 0x05, 0x44, 0x04, 0x0e, 0x2a, 0x80, 0xaa, 0x06, 0x24, 0x04, + 0x24, 0x04, 0x28, 0x08, 0x34, 0x0b, 0x01, 0x80, 0x90, 0x81, 0x37, 0x09, + 0x16, 0x0a, 0x08, 0x80, 0x98, 0x39, 0x03, 0x63, 0x08, 0x09, 0x30, 0x16, + 0x05, 0x21, 0x03, 0x1b, 0x05, 0x01, 0x40, 0x38, 0x04, 0x4b, 0x05, 0x2f, + 0x04, 0x0a, 0x07, 0x09, 0x07, 0x40, 0x20, 0x27, 0x04, 0x0c, 0x09, 0x36, + 0x03, 0x3a, 0x05, 0x1a, 0x07, 0x04, 0x0c, 0x07, 0x50, 0x49, 0x37, 0x33, + 0x0d, 0x33, 0x07, 0x2e, 0x08, 0x0a, 0x81, 0x26, 0x52, 0x4e, 0x28, 0x08, + 0x2a, 0x56, 0x1c, 0x14, 0x17, 0x09, 0x4e, 0x04, 0x1e, 0x0f, 0x43, 0x0e, + 0x19, 0x07, 0x0a, 0x06, 0x48, 0x08, 0x27, 0x09, 0x75, 0x0b, 0x3f, 0x41, + 0x2a, 0x06, 0x3b, 0x05, 0x0a, 0x06, 0x51, 0x06, 0x01, 0x05, 0x10, 0x03, + 0x05, 0x80, 0x8b, 0x62, 0x1e, 0x48, 0x08, 0x0a, 0x80, 0xa6, 0x5e, 0x22, + 0x45, 0x0b, 0x0a, 0x06, 0x0d, 0x13, 0x39, 0x07, 0x0a, 0x36, 0x2c, 0x04, + 0x10, 0x80, 0xc0, 0x3c, 0x64, 0x53, 0x0c, 0x48, 0x09, 0x0a, 0x46, 0x45, + 0x1b, 0x48, 0x08, 0x53, 0x1d, 0x39, 0x81, 0x07, 0x46, 0x0a, 0x1d, 0x03, + 0x47, 0x49, 0x37, 0x03, 0x0e, 0x08, 0x0a, 0x06, 0x39, 0x07, 0x0a, 0x81, + 0x36, 0x19, 0x80, 0xb7, 0x01, 0x0f, 0x32, 0x0d, 0x83, 0x9b, 0x66, 0x75, + 0x0b, 0x80, 0xc4, 0x8a, 0xbc, 0x84, 0x2f, 0x8f, 0xd1, 0x82, 0x47, 0xa1, + 0xb9, 0x82, 0x39, 0x07, 0x2a, 0x04, 0x02, 0x60, 0x26, 0x0a, 0x46, 0x0a, + 0x28, 0x05, 0x13, 0x82, 0xb0, 0x5b, 0x65, 0x4b, 0x04, 0x39, 0x07, 0x11, + 0x40, 0x05, 0x0b, 0x02, 0x0e, 0x97, 0xf8, 0x08, 0x84, 0xd6, 0x2a, 0x09, + 0xa2, 0xf7, 0x81, 0x1f, 0x31, 0x03, 0x11, 0x04, 0x08, 0x81, 0x8c, 0x89, + 0x04, 0x6b, 0x05, 0x0d, 0x03, 0x09, 0x07, 0x10, 0x93, 0x60, 0x80, 0xf6, + 0x0a, 0x73, 0x08, 0x6e, 0x17, 0x46, 0x80, 0x9a, 0x14, 0x0c, 0x57, 0x09, + 0x19, 0x80, 0x87, 0x81, 0x47, 0x03, 0x85, 0x42, 0x0f, 0x15, 0x85, 0x50, + 0x2b, 0x80, 0xd5, 0x2d, 0x03, 0x1a, 0x04, 0x02, 0x81, 0x70, 0x3a, 0x05, + 0x01, 0x85, 0x00, 0x80, 0xd7, 0x29, 0x4c, 0x04, 0x0a, 0x04, 0x02, 0x83, + 0x11, 0x44, 0x4c, 0x3d, 0x80, 0xc2, 0x3c, 0x06, 0x01, 0x04, 0x55, 0x05, + 0x1b, 0x34, 0x02, 0x81, 0x0e, 0x2c, 0x04, 0x64, 0x0c, 0x56, 0x0a, 0x80, + 0xae, 0x38, 0x1d, 0x0d, 0x2c, 0x04, 0x09, 0x07, 0x02, 0x0e, 0x06, 0x80, + 0x9a, 0x83, 0xd8, 0x08, 0x0d, 0x03, 0x0d, 0x03, 0x74, 0x0c, 0x59, 0x07, + 0x0c, 0x14, 0x0c, 0x04, 0x38, 0x08, 0x0a, 0x06, 0x28, 0x08, 0x22, 0x4e, + 0x81, 0x54, 0x0c, 0x15, 0x03, 0x03, 0x05, 0x07, 0x09, 0x19, 0x07, 0x07, + 0x09, 0x03, 0x0d, 0x07, 0x29, 0x80, 0xcb, 0x25, 0x0a, 0x84, 0x06, + }; + auto lower = static_cast(cp); + if (cp < 0x10000) { + return is_printable(lower, singletons0, + sizeof(singletons0) / sizeof(*singletons0), + singletons0_lower, normal0, sizeof(normal0)); + } + if (cp < 0x20000) { + return is_printable(lower, singletons1, + sizeof(singletons1) / sizeof(*singletons1), + singletons1_lower, normal1, sizeof(normal1)); + } + if (0x2a6de <= cp && cp < 0x2a700) return false; + if (0x2b735 <= cp && cp < 0x2b740) return false; + if (0x2b81e <= cp && cp < 0x2b820) return false; + if (0x2cea2 <= cp && cp < 0x2ceb0) return false; + if (0x2ebe1 <= cp && cp < 0x2f800) return false; + if (0x2fa1e <= cp && cp < 0x30000) return false; + if (0x3134b <= cp && cp < 0xe0100) return false; + if (0xe01f0 <= cp && cp < 0x110000) return false; + return cp < 0x110000; +} + +} // namespace detail + +FMT_END_NAMESPACE + +#endif // FMT_FORMAT_INL_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format.h new file mode 100644 index 0000000000000000000000000000000000000000..a16acbf64ad9b35b0b008127d7a80a794da7ac0f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format.h @@ -0,0 +1,4400 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + Formatting library for C++ + + Copyright (c) 2012 - present, Victor Zverovich + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + --- Optional exception to the license --- + + As an exception, if, as a result of your compiling your source code, portions + of this Software are embedded into a machine-executable object form of such + source code, you may redistribute such embedded portions in such object form + without including the above copyright and permission notices. + */ + +#ifndef FMT_FORMAT_H_ +#define FMT_FORMAT_H_ + +#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES +# define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES +# define FMT_REMOVE_TRANSITIVE_INCLUDES +#endif + +#include "base.h" + +// libc++ supports string_view in pre-c++17. +#if FMT_HAS_INCLUDE() && \ + (FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION)) +# define FMT_USE_STRING_VIEW +#endif + +#ifndef FMT_MODULE +# include // malloc, free + +# include // std::signbit +# include // std::byte +# include // uint32_t +# include // std::memcpy +# include // std::numeric_limits +# include // std::bad_alloc +# if defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI) +// Workaround for pre gcc 5 libstdc++. +# include // std::allocator_traits +# endif +# include // std::runtime_error +# include // std::string +# include // std::system_error + +// Check FMT_CPLUSPLUS to avoid a warning in MSVC. +# if FMT_HAS_INCLUDE() && FMT_CPLUSPLUS > 201703L +# include // std::bit_cast +# endif + +# if defined(FMT_USE_STRING_VIEW) +# include +# endif + +# if FMT_MSC_VERSION +# include // _BitScanReverse[64], _umul128 +# endif +#endif // FMT_MODULE + +#if defined(FMT_USE_NONTYPE_TEMPLATE_ARGS) +// Use the provided definition. +#elif defined(__NVCOMPILER) +# define FMT_USE_NONTYPE_TEMPLATE_ARGS 0 +#elif FMT_GCC_VERSION >= 903 && FMT_CPLUSPLUS >= 201709L +# define FMT_USE_NONTYPE_TEMPLATE_ARGS 1 +#elif defined(__cpp_nontype_template_args) && \ + __cpp_nontype_template_args >= 201911L +# define FMT_USE_NONTYPE_TEMPLATE_ARGS 1 +#elif FMT_CLANG_VERSION >= 1200 && FMT_CPLUSPLUS >= 202002L +# define FMT_USE_NONTYPE_TEMPLATE_ARGS 1 +#else +# define FMT_USE_NONTYPE_TEMPLATE_ARGS 0 +#endif + +#if defined __cpp_inline_variables && __cpp_inline_variables >= 201606L +# define FMT_INLINE_VARIABLE inline +#else +# define FMT_INLINE_VARIABLE +#endif + +// Check if RTTI is disabled. +#ifdef FMT_USE_RTTI +// Use the provided definition. +#elif defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || defined(_CPPRTTI) || \ + defined(__INTEL_RTTI__) || defined(__RTTI) +// __RTTI is for EDG compilers. _CPPRTTI is for MSVC. +# define FMT_USE_RTTI 1 +#else +# define FMT_USE_RTTI 0 +#endif + +// Visibility when compiled as a shared library/object. +#if defined(FMT_LIB_EXPORT) || defined(FMT_SHARED) +# define FMT_SO_VISIBILITY(value) FMT_VISIBILITY(value) +#else +# define FMT_SO_VISIBILITY(value) +#endif + +#if FMT_GCC_VERSION || FMT_CLANG_VERSION +# define FMT_NOINLINE __attribute__((noinline)) +#else +# define FMT_NOINLINE +#endif + +#ifdef FMT_DEPRECATED +// Use the provided definition. +#elif FMT_HAS_CPP14_ATTRIBUTE(deprecated) +# define FMT_DEPRECATED [[deprecated]] +#else +# define FMT_DEPRECATED /* deprecated */ +#endif + +// Detect constexpr std::string. +#if !FMT_USE_CONSTEVAL +# define FMT_USE_CONSTEXPR_STRING 0 +#elif defined(__cpp_lib_constexpr_string) && \ + __cpp_lib_constexpr_string >= 201907L +# if FMT_CLANG_VERSION && FMT_GLIBCXX_RELEASE +// clang + libstdc++ are able to work only starting with gcc13.3 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113294 +# if FMT_GLIBCXX_RELEASE < 13 +# define FMT_USE_CONSTEXPR_STRING 0 +# elif FMT_GLIBCXX_RELEASE == 13 && __GLIBCXX__ < 20240521 +# define FMT_USE_CONSTEXPR_STRING 0 +# else +# define FMT_USE_CONSTEXPR_STRING 1 +# endif +# else +# define FMT_USE_CONSTEXPR_STRING 1 +# endif +#else +# define FMT_USE_CONSTEXPR_STRING 0 +#endif +#if FMT_USE_CONSTEXPR_STRING +# define FMT_CONSTEXPR_STRING constexpr +#else +# define FMT_CONSTEXPR_STRING +#endif + +// GCC 4.9 doesn't support qualified names in specializations. +namespace std { +template struct iterator_traits> { + using iterator_category = output_iterator_tag; + using value_type = T; + using difference_type = + decltype(static_cast(nullptr) - static_cast(nullptr)); + using pointer = void; + using reference = void; +}; +} // namespace std + +#ifdef FMT_THROW +// Use the provided definition. +#elif FMT_USE_EXCEPTIONS +# define FMT_THROW(x) throw x +#else +# define FMT_THROW(x) ::fmt::assert_fail(__FILE__, __LINE__, (x).what()) +#endif + +#ifdef __clang_analyzer__ +# define FMT_CLANG_ANALYZER 1 +#else +# define FMT_CLANG_ANALYZER 0 +#endif + +// Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of +// integer formatter template instantiations to just one by only using the +// largest integer type. This results in a reduction in binary size but will +// cause a decrease in integer formatting performance. +#if !defined(FMT_REDUCE_INT_INSTANTIATIONS) +# define FMT_REDUCE_INT_INSTANTIATIONS 0 +#endif + +FMT_BEGIN_NAMESPACE + +template +struct is_contiguous> + : std::true_type {}; + +namespace detail { + +// __builtin_clz is broken in clang with Microsoft codegen: +// https://github.com/fmtlib/fmt/issues/519. +#if !FMT_MSC_VERSION +# if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION +# define FMT_BUILTIN_CLZ(n) __builtin_clz(n) +# endif +# if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION +# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) +# endif +#endif + +// Some compilers masquerade as both MSVC and GCC but otherwise support +// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the +// MSVC intrinsics if the clz and clzll builtins are not available. +#if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) +// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning. +# ifndef __clang__ +# pragma intrinsic(_BitScanReverse) +# ifdef _WIN64 +# pragma intrinsic(_BitScanReverse64) +# endif +# endif + +inline auto clz(uint32_t x) -> int { + FMT_ASSERT(x != 0, ""); + FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. + unsigned long r = 0; + _BitScanReverse(&r, x); + return 31 ^ static_cast(r); +} +# define FMT_BUILTIN_CLZ(n) detail::clz(n) + +inline auto clzll(uint64_t x) -> int { + FMT_ASSERT(x != 0, ""); + FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. + unsigned long r = 0; +# ifdef _WIN64 + _BitScanReverse64(&r, x); +# else + // Scan the high 32 bits. + if (_BitScanReverse(&r, static_cast(x >> 32))) + return 63 ^ static_cast(r + 32); + // Scan the low 32 bits. + _BitScanReverse(&r, static_cast(x)); +# endif + return 63 ^ static_cast(r); +} +# define FMT_BUILTIN_CLZLL(n) detail::clzll(n) +#endif // FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) + +FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) { + ignore_unused(condition); +#ifdef FMT_FUZZ + if (condition) throw std::runtime_error("fuzzing limit reached"); +#endif +} + +#if defined(FMT_USE_STRING_VIEW) +template using std_string_view = std::basic_string_view; +#else +template struct std_string_view { + operator basic_string_view() const; +}; +#endif + +template struct string_literal { + static constexpr Char value[sizeof...(C)] = {C...}; + constexpr operator basic_string_view() const { + return {value, sizeof...(C)}; + } +}; +#if FMT_CPLUSPLUS < 201703L +template +constexpr Char string_literal::value[sizeof...(C)]; +#endif + +// Implementation of std::bit_cast for pre-C++20. +template +FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To { +#ifdef __cpp_lib_bit_cast + if (is_constant_evaluated()) return std::bit_cast(from); +#endif + auto to = To(); + // The cast suppresses a bogus -Wclass-memaccess on GCC. + std::memcpy(static_cast(&to), &from, sizeof(to)); + return to; +} + +inline auto is_big_endian() -> bool { +#ifdef _WIN32 + return false; +#elif defined(__BIG_ENDIAN__) + return true; +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) + return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__; +#else + struct bytes { + char data[sizeof(int)]; + }; + return bit_cast(1).data[0] == 0; +#endif +} + +class uint128_fallback { + private: + uint64_t lo_, hi_; + + public: + constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {} + constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {} + + constexpr auto high() const noexcept -> uint64_t { return hi_; } + constexpr auto low() const noexcept -> uint64_t { return lo_; } + + template ::value)> + constexpr explicit operator T() const { + return static_cast(lo_); + } + + friend constexpr auto operator==(const uint128_fallback& lhs, + const uint128_fallback& rhs) -> bool { + return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_; + } + friend constexpr auto operator!=(const uint128_fallback& lhs, + const uint128_fallback& rhs) -> bool { + return !(lhs == rhs); + } + friend constexpr auto operator>(const uint128_fallback& lhs, + const uint128_fallback& rhs) -> bool { + return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_; + } + friend constexpr auto operator|(const uint128_fallback& lhs, + const uint128_fallback& rhs) + -> uint128_fallback { + return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_}; + } + friend constexpr auto operator&(const uint128_fallback& lhs, + const uint128_fallback& rhs) + -> uint128_fallback { + return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_}; + } + friend constexpr auto operator~(const uint128_fallback& n) + -> uint128_fallback { + return {~n.hi_, ~n.lo_}; + } + friend FMT_CONSTEXPR auto operator+(const uint128_fallback& lhs, + const uint128_fallback& rhs) + -> uint128_fallback { + auto result = uint128_fallback(lhs); + result += rhs; + return result; + } + friend FMT_CONSTEXPR auto operator*(const uint128_fallback& lhs, uint32_t rhs) + -> uint128_fallback { + FMT_ASSERT(lhs.hi_ == 0, ""); + uint64_t hi = (lhs.lo_ >> 32) * rhs; + uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs; + uint64_t new_lo = (hi << 32) + lo; + return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo}; + } + friend constexpr auto operator-(const uint128_fallback& lhs, uint64_t rhs) + -> uint128_fallback { + return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs}; + } + FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback { + if (shift == 64) return {0, hi_}; + if (shift > 64) return uint128_fallback(0, hi_) >> (shift - 64); + return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)}; + } + FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback { + if (shift == 64) return {lo_, 0}; + if (shift > 64) return uint128_fallback(lo_, 0) << (shift - 64); + return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)}; + } + FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback& { + return *this = *this >> shift; + } + FMT_CONSTEXPR void operator+=(uint128_fallback n) { + uint64_t new_lo = lo_ + n.lo_; + uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0); + FMT_ASSERT(new_hi >= hi_, ""); + lo_ = new_lo; + hi_ = new_hi; + } + FMT_CONSTEXPR void operator&=(uint128_fallback n) { + lo_ &= n.lo_; + hi_ &= n.hi_; + } + + FMT_CONSTEXPR20 auto operator+=(uint64_t n) noexcept -> uint128_fallback& { + if (is_constant_evaluated()) { + lo_ += n; + hi_ += (lo_ < n ? 1 : 0); + return *this; + } +#if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__) + unsigned long long carry; + lo_ = __builtin_addcll(lo_, n, 0, &carry); + hi_ += carry; +#elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__) + unsigned long long result; + auto carry = __builtin_ia32_addcarryx_u64(0, lo_, n, &result); + lo_ = result; + hi_ += carry; +#elif defined(_MSC_VER) && defined(_M_X64) + auto carry = _addcarry_u64(0, lo_, n, &lo_); + _addcarry_u64(carry, hi_, 0, &hi_); +#else + lo_ += n; + hi_ += (lo_ < n ? 1 : 0); +#endif + return *this; + } +}; + +using uint128_t = conditional_t; + +#ifdef UINTPTR_MAX +using uintptr_t = ::uintptr_t; +#else +using uintptr_t = uint128_t; +#endif + +// Returns the largest possible value for type T. Same as +// std::numeric_limits::max() but shorter and not affected by the max macro. +template constexpr auto max_value() -> T { + return (std::numeric_limits::max)(); +} +template constexpr auto num_bits() -> int { + return std::numeric_limits::digits; +} +// std::numeric_limits::digits may return 0 for 128-bit ints. +template <> constexpr auto num_bits() -> int { return 128; } +template <> constexpr auto num_bits() -> int { return 128; } +template <> constexpr auto num_bits() -> int { return 128; } + +// A heterogeneous bit_cast used for converting 96-bit long double to uint128_t +// and 128-bit pointers to uint128_fallback. +template sizeof(From))> +inline auto bit_cast(const From& from) -> To { + constexpr auto size = static_cast(sizeof(From) / sizeof(unsigned short)); + struct data_t { + unsigned short value[static_cast(size)]; + } data = bit_cast(from); + auto result = To(); + if (const_check(is_big_endian())) { + for (int i = 0; i < size; ++i) + result = (result << num_bits()) | data.value[i]; + } else { + for (int i = size - 1; i >= 0; --i) + result = (result << num_bits()) | data.value[i]; + } + return result; +} + +template +FMT_CONSTEXPR20 inline auto countl_zero_fallback(UInt n) -> int { + int lz = 0; + constexpr UInt msb_mask = static_cast(1) << (num_bits() - 1); + for (; (n & msb_mask) == 0; n <<= 1) lz++; + return lz; +} + +FMT_CONSTEXPR20 inline auto countl_zero(uint32_t n) -> int { +#ifdef FMT_BUILTIN_CLZ + if (!is_constant_evaluated()) return FMT_BUILTIN_CLZ(n); +#endif + return countl_zero_fallback(n); +} + +FMT_CONSTEXPR20 inline auto countl_zero(uint64_t n) -> int { +#ifdef FMT_BUILTIN_CLZLL + if (!is_constant_evaluated()) return FMT_BUILTIN_CLZLL(n); +#endif + return countl_zero_fallback(n); +} + +FMT_INLINE void assume(bool condition) { + (void)condition; +#if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION + __builtin_assume(condition); +#elif FMT_GCC_VERSION + if (!condition) __builtin_unreachable(); +#endif +} + +// Attempts to reserve space for n extra characters in the output range. +// Returns a pointer to the reserved range or a reference to it. +template ::value&& + is_contiguous::value)> +#if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION +__attribute__((no_sanitize("undefined"))) +#endif +FMT_CONSTEXPR20 inline auto +reserve(OutputIt it, size_t n) -> typename OutputIt::value_type* { + auto& c = get_container(it); + size_t size = c.size(); + c.resize(size + n); + return &c[size]; +} + +template +FMT_CONSTEXPR20 inline auto reserve(basic_appender it, size_t n) + -> basic_appender { + buffer& buf = get_container(it); + buf.try_reserve(buf.size() + n); + return it; +} + +template +constexpr auto reserve(Iterator& it, size_t) -> Iterator& { + return it; +} + +template +using reserve_iterator = + remove_reference_t(), 0))>; + +template +constexpr auto to_pointer(OutputIt, size_t) -> T* { + return nullptr; +} +template FMT_CONSTEXPR auto to_pointer(T*& ptr, size_t n) -> T* { + T* begin = ptr; + ptr += n; + return begin; +} +template +FMT_CONSTEXPR20 auto to_pointer(basic_appender it, size_t n) -> T* { + buffer& buf = get_container(it); + buf.try_reserve(buf.size() + n); + auto size = buf.size(); + if (buf.capacity() < size + n) return nullptr; + buf.try_resize(size + n); + return buf.data() + size; +} + +template ::value&& + is_contiguous::value)> +inline auto base_iterator(OutputIt it, + typename OutputIt::container_type::value_type*) + -> OutputIt { + return it; +} + +template +constexpr auto base_iterator(Iterator, Iterator it) -> Iterator { + return it; +} + +// is spectacularly slow to compile in C++20 so use a simple fill_n +// instead (#1998). +template +FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value) + -> OutputIt { + for (Size i = 0; i < count; ++i) *out++ = value; + return out; +} +template +FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* { + if (is_constant_evaluated()) return fill_n(out, count, value); + static_assert(sizeof(T) == 1, + "sizeof(T) must be 1 to use char for initialization"); + std::memset(out, value, to_unsigned(count)); + return out + count; +} + +template +FMT_CONSTEXPR FMT_NOINLINE auto copy_noinline(InputIt begin, InputIt end, + OutputIt out) -> OutputIt { + return copy(begin, end, out); +} + +// A public domain branchless UTF-8 decoder by Christopher Wellons: +// https://github.com/skeeto/branchless-utf8 +/* Decode the next character, c, from s, reporting errors in e. + * + * Since this is a branchless decoder, four bytes will be read from the + * buffer regardless of the actual length of the next character. This + * means the buffer _must_ have at least three bytes of zero padding + * following the end of the data stream. + * + * Errors are reported in e, which will be non-zero if the parsed + * character was somehow invalid: invalid byte sequence, non-canonical + * encoding, or a surrogate half. + * + * The function returns a pointer to the next character. When an error + * occurs, this pointer will be a guess that depends on the particular + * error, but it will always advance at least one byte. + */ +FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e) + -> const char* { + constexpr int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07}; + constexpr uint32_t mins[] = {4194304, 0, 128, 2048, 65536}; + constexpr int shiftc[] = {0, 18, 12, 6, 0}; + constexpr int shifte[] = {0, 6, 4, 2, 0}; + + int len = "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4" + [static_cast(*s) >> 3]; + // Compute the pointer to the next character early so that the next + // iteration can start working on the next character. Neither Clang + // nor GCC figure out this reordering on their own. + const char* next = s + len + !len; + + using uchar = unsigned char; + + // Assume a four-byte character and load four bytes. Unused bits are + // shifted out. + *c = uint32_t(uchar(s[0]) & masks[len]) << 18; + *c |= uint32_t(uchar(s[1]) & 0x3f) << 12; + *c |= uint32_t(uchar(s[2]) & 0x3f) << 6; + *c |= uint32_t(uchar(s[3]) & 0x3f) << 0; + *c >>= shiftc[len]; + + // Accumulate the various error conditions. + *e = (*c < mins[len]) << 6; // non-canonical encoding + *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half? + *e |= (*c > 0x10FFFF) << 8; // out of range? + *e |= (uchar(s[1]) & 0xc0) >> 2; + *e |= (uchar(s[2]) & 0xc0) >> 4; + *e |= uchar(s[3]) >> 6; + *e ^= 0x2a; // top two bits of each tail byte correct? + *e >>= shifte[len]; + + return next; +} + +constexpr FMT_INLINE_VARIABLE uint32_t invalid_code_point = ~uint32_t(); + +// Invokes f(cp, sv) for every code point cp in s with sv being the string view +// corresponding to the code point. cp is invalid_code_point on error. +template +FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) { + auto decode = [f](const char* buf_ptr, const char* ptr) { + auto cp = uint32_t(); + auto error = 0; + auto end = utf8_decode(buf_ptr, &cp, &error); + bool result = f(error ? invalid_code_point : cp, + string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr))); + return result ? (error ? buf_ptr + 1 : end) : nullptr; + }; + + auto p = s.data(); + const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars. + if (s.size() >= block_size) { + for (auto end = p + s.size() - block_size + 1; p < end;) { + p = decode(p, p); + if (!p) return; + } + } + auto num_chars_left = to_unsigned(s.data() + s.size() - p); + if (num_chars_left == 0) return; + + // Suppress bogus -Wstringop-overflow. + if (FMT_GCC_VERSION) num_chars_left &= 3; + char buf[2 * block_size - 1] = {}; + copy(p, p + num_chars_left, buf); + const char* buf_ptr = buf; + do { + auto end = decode(buf_ptr, p); + if (!end) return; + p += end - buf_ptr; + buf_ptr = end; + } while (buf_ptr < buf + num_chars_left); +} + +FMT_CONSTEXPR inline auto display_width_of(uint32_t cp) noexcept -> size_t { + return to_unsigned( + 1 + (cp >= 0x1100 && + (cp <= 0x115f || // Hangul Jamo init. consonants + cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET + cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET + // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE: + (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) || + (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables + (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs + (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms + (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms + (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms + (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms + (cp >= 0x20000 && cp <= 0x2fffd) || // CJK + (cp >= 0x30000 && cp <= 0x3fffd) || + // Miscellaneous Symbols and Pictographs + Emoticons: + (cp >= 0x1f300 && cp <= 0x1f64f) || + // Supplemental Symbols and Pictographs: + (cp >= 0x1f900 && cp <= 0x1f9ff)))); +} + +template struct is_integral : std::is_integral {}; +template <> struct is_integral : std::true_type {}; +template <> struct is_integral : std::true_type {}; + +template +using is_signed = + std::integral_constant::is_signed || + std::is_same::value>; + +template +using is_integer = + bool_constant::value && !std::is_same::value && + !std::is_same::value && + !std::is_same::value>; + +#if defined(FMT_USE_FLOAT128) +// Use the provided definition. +#elif FMT_CLANG_VERSION >= 309 && FMT_HAS_INCLUDE() +# define FMT_USE_FLOAT128 1 +#elif FMT_GCC_VERSION && defined(_GLIBCXX_USE_FLOAT128) && \ + !defined(__STRICT_ANSI__) +# define FMT_USE_FLOAT128 1 +#else +# define FMT_USE_FLOAT128 0 +#endif +#if FMT_USE_FLOAT128 +using float128 = __float128; +#else +struct float128 {}; +#endif + +template using is_float128 = std::is_same; + +template struct is_floating_point : std::is_floating_point {}; +template <> struct is_floating_point : std::true_type {}; + +template ::value> +struct is_fast_float : bool_constant::is_iec559 && + sizeof(T) <= sizeof(double)> {}; +template struct is_fast_float : std::false_type {}; + +template +using fast_float_t = conditional_t; + +template +using is_double_double = bool_constant::digits == 106>; + +#ifndef FMT_USE_FULL_CACHE_DRAGONBOX +# define FMT_USE_FULL_CACHE_DRAGONBOX 0 +#endif + +// An allocator that uses malloc/free to allow removing dependency on the C++ +// standard libary runtime. std::decay is used for back_inserter to be found by +// ADL when applied to memory_buffer. +template struct allocator : private std::decay { + using value_type = T; + + auto allocate(size_t n) -> T* { + FMT_ASSERT(n <= max_value() / sizeof(T), ""); + T* p = static_cast(malloc(n * sizeof(T))); + if (!p) FMT_THROW(std::bad_alloc()); + return p; + } + + void deallocate(T* p, size_t) { free(p); } + + constexpr friend auto operator==(allocator, allocator) noexcept -> bool { + return true; // All instances of this allocator are equivalent. + } + constexpr friend auto operator!=(allocator, allocator) noexcept -> bool { + return false; + } +}; + +template +FMT_CONSTEXPR auto maybe_set_debug_format(Formatter& f, bool set) + -> decltype(f.set_debug_format(set)) { + f.set_debug_format(set); +} +template +FMT_CONSTEXPR void maybe_set_debug_format(Formatter&, ...) {} + +} // namespace detail + +FMT_BEGIN_EXPORT + +// The number of characters to store in the basic_memory_buffer object itself +// to avoid dynamic memory allocation. +enum { inline_buffer_size = 500 }; + +/** + * A dynamically growing memory buffer for trivially copyable/constructible + * types with the first `SIZE` elements stored in the object itself. Most + * commonly used via the `memory_buffer` alias for `char`. + * + * **Example**: + * + * auto out = fmt::memory_buffer(); + * fmt::format_to(std::back_inserter(out), "The answer is {}.", 42); + * + * This will append "The answer is 42." to `out`. The buffer content can be + * converted to `std::string` with `to_string(out)`. + */ +template > +class basic_memory_buffer : public detail::buffer { + private: + T store_[SIZE]; + + // Don't inherit from Allocator to avoid generating type_info for it. + FMT_NO_UNIQUE_ADDRESS Allocator alloc_; + + // Deallocate memory allocated by the buffer. + FMT_CONSTEXPR20 void deallocate() { + T* data = this->data(); + if (data != store_) alloc_.deallocate(data, this->capacity()); + } + + static FMT_CONSTEXPR20 void grow(detail::buffer& buf, size_t size) { + detail::abort_fuzzing_if(size > 5000); + auto& self = static_cast(buf); + const size_t max_size = + std::allocator_traits::max_size(self.alloc_); + size_t old_capacity = buf.capacity(); + size_t new_capacity = old_capacity + old_capacity / 2; + if (size > new_capacity) + new_capacity = size; + else if (new_capacity > max_size) + new_capacity = max_of(size, max_size); + T* old_data = buf.data(); + T* new_data = self.alloc_.allocate(new_capacity); + // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481). + detail::assume(buf.size() <= new_capacity); + // The following code doesn't throw, so the raw pointer above doesn't leak. + memcpy(new_data, old_data, buf.size() * sizeof(T)); + self.set(new_data, new_capacity); + // deallocate must not throw according to the standard, but even if it does, + // the buffer already uses the new storage and will deallocate it in + // destructor. + if (old_data != self.store_) self.alloc_.deallocate(old_data, old_capacity); + } + + public: + using value_type = T; + using const_reference = const T&; + + FMT_CONSTEXPR explicit basic_memory_buffer( + const Allocator& alloc = Allocator()) + : detail::buffer(grow), alloc_(alloc) { + this->set(store_, SIZE); + if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T()); + } + FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); } + + private: + template :: + propagate_on_container_move_assignment::value)> + FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool { + alloc_ = std::move(other.alloc_); + return true; + } + // If the allocator does not propagate then copy the data from other. + template :: + propagate_on_container_move_assignment::value)> + FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool { + T* data = other.data(); + if (alloc_ == other.alloc_ || data == other.store_) return true; + size_t size = other.size(); + // Perform copy operation, allocators are different. + this->resize(size); + detail::copy(data, data + size, this->data()); + return false; + } + + // Move data from other to this buffer. + FMT_CONSTEXPR20 void move(basic_memory_buffer& other) { + T* data = other.data(); + size_t size = other.size(), capacity = other.capacity(); + if (!move_alloc(other)) return; + if (data == other.store_) { + this->set(store_, capacity); + detail::copy(other.store_, other.store_ + size, store_); + } else { + this->set(data, capacity); + // Set pointer to the inline array so that delete is not called + // when deallocating. + other.set(other.store_, 0); + other.clear(); + } + this->resize(size); + } + + public: + /// Constructs a `basic_memory_buffer` object moving the content of the other + /// object to it. + FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer&& other) noexcept + : detail::buffer(grow) { + move(other); + } + + /// Moves the content of the other `basic_memory_buffer` object to this one. + auto operator=(basic_memory_buffer&& other) noexcept -> basic_memory_buffer& { + FMT_ASSERT(this != &other, ""); + deallocate(); + move(other); + return *this; + } + + // Returns a copy of the allocator associated with this buffer. + auto get_allocator() const -> Allocator { return alloc_; } + + /// Resizes the buffer to contain `count` elements. If T is a POD type new + /// elements may not be initialized. + FMT_CONSTEXPR void resize(size_t count) { this->try_resize(count); } + + /// Increases the buffer capacity to `new_capacity`. + void reserve(size_t new_capacity) { this->try_reserve(new_capacity); } + + using detail::buffer::append; + template + FMT_CONSTEXPR20 void append(const ContiguousRange& range) { + append(range.data(), range.data() + range.size()); + } +}; + +using memory_buffer = basic_memory_buffer; + +template +FMT_NODISCARD auto to_string(const basic_memory_buffer& buf) + -> std::string { + auto size = buf.size(); + detail::assume(size < std::string().max_size()); + return {buf.data(), size}; +} + +// A writer to a buffered stream. It doesn't own the underlying stream. +class writer { + private: + detail::buffer* buf_; + + // We cannot create a file buffer in advance because any write to a FILE may + // invalidate it. + FILE* file_; + + public: + inline writer(FILE* f) : buf_(nullptr), file_(f) {} + inline writer(detail::buffer& buf) : buf_(&buf) {} + + /// Formats `args` according to specifications in `fmt` and writes the + /// output to the file. + template void print(format_string fmt, T&&... args) { + if (buf_) + fmt::format_to(appender(*buf_), fmt, std::forward(args)...); + else + fmt::print(file_, fmt, std::forward(args)...); + } +}; + +class string_buffer { + private: + std::string str_; + detail::container_buffer buf_; + + public: + inline string_buffer() : buf_(str_) {} + + inline operator writer() { return buf_; } + inline auto str() -> std::string& { return str_; } +}; + +template +struct is_contiguous> : std::true_type { +}; + +// Suppress a misleading warning in older versions of clang. +FMT_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables") + +/// An error reported from a formatting function. +class FMT_SO_VISIBILITY("default") format_error : public std::runtime_error { + public: + using std::runtime_error::runtime_error; +}; + +class loc_value; + +FMT_END_EXPORT +namespace detail { +FMT_API auto write_console(int fd, string_view text) -> bool; +FMT_API void print(FILE*, string_view); +} // namespace detail + +namespace detail { +template struct fixed_string { + FMT_CONSTEXPR20 fixed_string(const Char (&s)[N]) { + detail::copy(static_cast(s), s + N, + data); + } + Char data[N] = {}; +}; + +// Converts a compile-time string to basic_string_view. +FMT_EXPORT template +constexpr auto compile_string_to_view(const Char (&s)[N]) + -> basic_string_view { + // Remove trailing NUL character if needed. Won't be present if this is used + // with a raw character array (i.e. not defined as a string). + return {s, N - (std::char_traits::to_int_type(s[N - 1]) == 0 ? 1 : 0)}; +} +FMT_EXPORT template +constexpr auto compile_string_to_view(basic_string_view s) + -> basic_string_view { + return s; +} + +// Returns true if value is negative, false otherwise. +// Same as `value < 0` but doesn't produce warnings if T is an unsigned type. +template ::value)> +constexpr auto is_negative(T value) -> bool { + return value < 0; +} +template ::value)> +constexpr auto is_negative(T) -> bool { + return false; +} + +// Smallest of uint32_t, uint64_t, uint128_t that is large enough to +// represent all values of an integral type T. +template +using uint32_or_64_or_128_t = + conditional_t() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS, + uint32_t, + conditional_t() <= 64, uint64_t, uint128_t>>; +template +using uint64_or_128_t = conditional_t() <= 64, uint64_t, uint128_t>; + +#define FMT_POWERS_OF_10(factor) \ + factor * 10, (factor) * 100, (factor) * 1000, (factor) * 10000, \ + (factor) * 100000, (factor) * 1000000, (factor) * 10000000, \ + (factor) * 100000000, (factor) * 1000000000 + +// Converts value in the range [0, 100) to a string. +// GCC generates slightly better code when value is pointer-size. +inline auto digits2(size_t value) -> const char* { + // Align data since unaligned access may be slower when crossing a + // hardware-specific boundary. + alignas(2) static const char data[] = + "0001020304050607080910111213141516171819" + "2021222324252627282930313233343536373839" + "4041424344454647484950515253545556575859" + "6061626364656667686970717273747576777879" + "8081828384858687888990919293949596979899"; + return &data[value * 2]; +} + +template constexpr auto getsign(sign s) -> Char { + return static_cast(((' ' << 24) | ('+' << 16) | ('-' << 8)) >> + (static_cast(s) * 8)); +} + +template FMT_CONSTEXPR auto count_digits_fallback(T n) -> int { + int count = 1; + for (;;) { + // Integer division is slow so do it for a group of four digits instead + // of for every digit. The idea comes from the talk by Alexandrescu + // "Three Optimization Tips for C++". See speed-test for a comparison. + if (n < 10) return count; + if (n < 100) return count + 1; + if (n < 1000) return count + 2; + if (n < 10000) return count + 3; + n /= 10000u; + count += 4; + } +} +#if FMT_USE_INT128 +FMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int { + return count_digits_fallback(n); +} +#endif + +#ifdef FMT_BUILTIN_CLZLL +// It is a separate function rather than a part of count_digits to workaround +// the lack of static constexpr in constexpr functions. +inline auto do_count_digits(uint64_t n) -> int { + // This has comparable performance to the version by Kendall Willets + // (https://github.com/fmtlib/format-benchmark/blob/master/digits10) + // but uses smaller tables. + // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)). + static constexpr uint8_t bsr2log10[] = { + 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, + 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, + 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20}; + auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63]; + static constexpr uint64_t zero_or_powers_of_10[] = { + 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL), + 10000000000000000000ULL}; + return t - (n < zero_or_powers_of_10[t]); +} +#endif + +// Returns the number of decimal digits in n. Leading zeros are not counted +// except for n == 0 in which case count_digits returns 1. +FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int { +#ifdef FMT_BUILTIN_CLZLL + if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n); +#endif + return count_digits_fallback(n); +} + +// Counts the number of digits in n. BITS = log2(radix). +template +FMT_CONSTEXPR auto count_digits(UInt n) -> int { +#ifdef FMT_BUILTIN_CLZ + if (!is_constant_evaluated() && num_bits() == 32) + return (FMT_BUILTIN_CLZ(static_cast(n) | 1) ^ 31) / BITS + 1; +#endif + // Lambda avoids unreachable code warnings from NVHPC. + return [](UInt m) { + int num_digits = 0; + do { + ++num_digits; + } while ((m >>= BITS) != 0); + return num_digits; + }(n); +} + +#ifdef FMT_BUILTIN_CLZ +// It is a separate function rather than a part of count_digits to workaround +// the lack of static constexpr in constexpr functions. +FMT_INLINE auto do_count_digits(uint32_t n) -> int { +// An optimization by Kendall Willets from https://bit.ly/3uOIQrB. +// This increments the upper 32 bits (log10(T) - 1) when >= T is added. +# define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T) + static constexpr uint64_t table[] = { + FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8 + FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64 + FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512 + FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096 + FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k + FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k + FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k + FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M + FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M + FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M + FMT_INC(1000000000), FMT_INC(1000000000) // 4B + }; + auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31]; + return static_cast((n + inc) >> 32); +} +#endif + +// Optional version of count_digits for better performance on 32-bit platforms. +FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int { +#ifdef FMT_BUILTIN_CLZ + if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n); +#endif + return count_digits_fallback(n); +} + +template constexpr auto digits10() noexcept -> int { + return std::numeric_limits::digits10; +} +template <> constexpr auto digits10() noexcept -> int { return 38; } +template <> constexpr auto digits10() noexcept -> int { return 38; } + +template struct thousands_sep_result { + std::string grouping; + Char thousands_sep; +}; + +template +FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result; +template +inline auto thousands_sep(locale_ref loc) -> thousands_sep_result { + auto result = thousands_sep_impl(loc); + return {result.grouping, Char(result.thousands_sep)}; +} +template <> +inline auto thousands_sep(locale_ref loc) -> thousands_sep_result { + return thousands_sep_impl(loc); +} + +template +FMT_API auto decimal_point_impl(locale_ref loc) -> Char; +template inline auto decimal_point(locale_ref loc) -> Char { + return Char(decimal_point_impl(loc)); +} +template <> inline auto decimal_point(locale_ref loc) -> wchar_t { + return decimal_point_impl(loc); +} + +#ifndef FMT_HEADER_ONLY +FMT_BEGIN_EXPORT +extern template FMT_API auto thousands_sep_impl(locale_ref) + -> thousands_sep_result; +extern template FMT_API auto thousands_sep_impl(locale_ref) + -> thousands_sep_result; +extern template FMT_API auto decimal_point_impl(locale_ref) -> char; +extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t; +FMT_END_EXPORT +#endif // FMT_HEADER_ONLY + +// Compares two characters for equality. +template auto equal2(const Char* lhs, const char* rhs) -> bool { + return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]); +} +inline auto equal2(const char* lhs, const char* rhs) -> bool { + return memcmp(lhs, rhs, 2) == 0; +} + +// Writes a two-digit value to out. +template +FMT_CONSTEXPR20 FMT_INLINE void write2digits(Char* out, size_t value) { + if (!is_constant_evaluated() && std::is_same::value && + !FMT_OPTIMIZE_SIZE) { + memcpy(out, digits2(value), 2); + return; + } + *out++ = static_cast('0' + value / 10); + *out = static_cast('0' + value % 10); +} + +// Formats a decimal unsigned integer value writing to out pointing to a buffer +// of specified size. The caller must ensure that the buffer is large enough. +template +FMT_CONSTEXPR20 auto do_format_decimal(Char* out, UInt value, int size) + -> Char* { + FMT_ASSERT(size >= count_digits(value), "invalid digit count"); + unsigned n = to_unsigned(size); + while (value >= 100) { + // Integer division is slow so do it for a group of two digits instead + // of for every digit. The idea comes from the talk by Alexandrescu + // "Three Optimization Tips for C++". See speed-test for a comparison. + n -= 2; + write2digits(out + n, static_cast(value % 100)); + value /= 100; + } + if (value >= 10) { + n -= 2; + write2digits(out + n, static_cast(value)); + } else { + out[--n] = static_cast('0' + value); + } + return out + n; +} + +template +FMT_CONSTEXPR FMT_INLINE auto format_decimal(Char* out, UInt value, + int num_digits) -> Char* { + do_format_decimal(out, value, num_digits); + return out + num_digits; +} + +template >::value)> +FMT_CONSTEXPR auto format_decimal(OutputIt out, UInt value, int num_digits) + -> OutputIt { + if (auto ptr = to_pointer(out, to_unsigned(num_digits))) { + do_format_decimal(ptr, value, num_digits); + return out; + } + // Buffer is large enough to hold all digits (digits10 + 1). + char buffer[digits10() + 1]; + if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0'); + do_format_decimal(buffer, value, num_digits); + return copy_noinline(buffer, buffer + num_digits, out); +} + +template +FMT_CONSTEXPR auto do_format_base2e(int base_bits, Char* out, UInt value, + int size, bool upper = false) -> Char* { + out += size; + do { + const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef"; + unsigned digit = static_cast(value & ((1u << base_bits) - 1)); + *--out = static_cast(base_bits < 4 ? static_cast('0' + digit) + : digits[digit]); + } while ((value >>= base_bits) != 0); + return out; +} + +// Formats an unsigned integer in the power of two base (binary, octal, hex). +template +FMT_CONSTEXPR auto format_base2e(int base_bits, Char* out, UInt value, + int num_digits, bool upper = false) -> Char* { + do_format_base2e(base_bits, out, value, num_digits, upper); + return out + num_digits; +} + +template ::value)> +FMT_CONSTEXPR inline auto format_base2e(int base_bits, OutputIt out, UInt value, + int num_digits, bool upper = false) + -> OutputIt { + if (auto ptr = to_pointer(out, to_unsigned(num_digits))) { + format_base2e(base_bits, ptr, value, num_digits, upper); + return out; + } + // Make buffer large enough for any base. + char buffer[num_bits()]; + if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\0'); + format_base2e(base_bits, buffer, value, num_digits, upper); + return detail::copy_noinline(buffer, buffer + num_digits, out); +} + +// A converter from UTF-8 to UTF-16. +class utf8_to_utf16 { + private: + basic_memory_buffer buffer_; + + public: + FMT_API explicit utf8_to_utf16(string_view s); + inline operator basic_string_view() const { + return {&buffer_[0], size()}; + } + inline auto size() const -> size_t { return buffer_.size() - 1; } + inline auto c_str() const -> const wchar_t* { return &buffer_[0]; } + inline auto str() const -> std::wstring { return {&buffer_[0], size()}; } +}; + +enum class to_utf8_error_policy { abort, replace }; + +// A converter from UTF-16/UTF-32 (host endian) to UTF-8. +template class to_utf8 { + private: + Buffer buffer_; + + public: + to_utf8() {} + explicit to_utf8(basic_string_view s, + to_utf8_error_policy policy = to_utf8_error_policy::abort) { + static_assert(sizeof(WChar) == 2 || sizeof(WChar) == 4, + "expected utf16 or utf32"); + if (!convert(s, policy)) { + FMT_THROW(std::runtime_error(sizeof(WChar) == 2 ? "invalid utf16" + : "invalid utf32")); + } + } + operator string_view() const { return string_view(&buffer_[0], size()); } + auto size() const -> size_t { return buffer_.size() - 1; } + auto c_str() const -> const char* { return &buffer_[0]; } + auto str() const -> std::string { return std::string(&buffer_[0], size()); } + + // Performs conversion returning a bool instead of throwing exception on + // conversion error. This method may still throw in case of memory allocation + // error. + auto convert(basic_string_view s, + to_utf8_error_policy policy = to_utf8_error_policy::abort) + -> bool { + if (!convert(buffer_, s, policy)) return false; + buffer_.push_back(0); + return true; + } + static auto convert(Buffer& buf, basic_string_view s, + to_utf8_error_policy policy = to_utf8_error_policy::abort) + -> bool { + for (auto p = s.begin(); p != s.end(); ++p) { + uint32_t c = static_cast(*p); + if (sizeof(WChar) == 2 && c >= 0xd800 && c <= 0xdfff) { + // Handle a surrogate pair. + ++p; + if (p == s.end() || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) { + if (policy == to_utf8_error_policy::abort) return false; + buf.append(string_view("\xEF\xBF\xBD")); + --p; + continue; + } + c = (c << 10) + static_cast(*p) - 0x35fdc00; + } + if (c < 0x80) { + buf.push_back(static_cast(c)); + } else if (c < 0x800) { + buf.push_back(static_cast(0xc0 | (c >> 6))); + buf.push_back(static_cast(0x80 | (c & 0x3f))); + } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) { + buf.push_back(static_cast(0xe0 | (c >> 12))); + buf.push_back(static_cast(0x80 | ((c & 0xfff) >> 6))); + buf.push_back(static_cast(0x80 | (c & 0x3f))); + } else if (c >= 0x10000 && c <= 0x10ffff) { + buf.push_back(static_cast(0xf0 | (c >> 18))); + buf.push_back(static_cast(0x80 | ((c & 0x3ffff) >> 12))); + buf.push_back(static_cast(0x80 | ((c & 0xfff) >> 6))); + buf.push_back(static_cast(0x80 | (c & 0x3f))); + } else { + return false; + } + } + return true; + } +}; + +// Computes 128-bit result of multiplication of two 64-bit unsigned integers. +FMT_INLINE auto umul128(uint64_t x, uint64_t y) noexcept -> uint128_fallback { +#if FMT_USE_INT128 + auto p = static_cast(x) * static_cast(y); + return {static_cast(p >> 64), static_cast(p)}; +#elif defined(_MSC_VER) && defined(_M_X64) + auto hi = uint64_t(); + auto lo = _umul128(x, y, &hi); + return {hi, lo}; +#else + const uint64_t mask = static_cast(max_value()); + + uint64_t a = x >> 32; + uint64_t b = x & mask; + uint64_t c = y >> 32; + uint64_t d = y & mask; + + uint64_t ac = a * c; + uint64_t bc = b * c; + uint64_t ad = a * d; + uint64_t bd = b * d; + + uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask); + + return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32), + (intermediate << 32) + (bd & mask)}; +#endif +} + +namespace dragonbox { +// Computes floor(log10(pow(2, e))) for e in [-2620, 2620] using the method from +// https://fmt.dev/papers/Dragonbox.pdf#page=28, section 6.1. +inline auto floor_log10_pow2(int e) noexcept -> int { + FMT_ASSERT(e <= 2620 && e >= -2620, "too large exponent"); + static_assert((-1 >> 1) == -1, "right shift is not arithmetic"); + return (e * 315653) >> 20; +} + +inline auto floor_log2_pow10(int e) noexcept -> int { + FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent"); + return (e * 1741647) >> 19; +} + +// Computes upper 64 bits of multiplication of two 64-bit unsigned integers. +inline auto umul128_upper64(uint64_t x, uint64_t y) noexcept -> uint64_t { +#if FMT_USE_INT128 + auto p = static_cast(x) * static_cast(y); + return static_cast(p >> 64); +#elif defined(_MSC_VER) && defined(_M_X64) + return __umulh(x, y); +#else + return umul128(x, y).high(); +#endif +} + +// Computes upper 128 bits of multiplication of a 64-bit unsigned integer and a +// 128-bit unsigned integer. +inline auto umul192_upper128(uint64_t x, uint128_fallback y) noexcept + -> uint128_fallback { + uint128_fallback r = umul128(x, y.high()); + r += umul128_upper64(x, y.low()); + return r; +} + +FMT_API auto get_cached_power(int k) noexcept -> uint128_fallback; + +// Type-specific information that Dragonbox uses. +template struct float_info; + +template <> struct float_info { + using carrier_uint = uint32_t; + static const int exponent_bits = 8; + static const int kappa = 1; + static const int big_divisor = 100; + static const int small_divisor = 10; + static const int min_k = -31; + static const int max_k = 46; + static const int shorter_interval_tie_lower_threshold = -35; + static const int shorter_interval_tie_upper_threshold = -35; +}; + +template <> struct float_info { + using carrier_uint = uint64_t; + static const int exponent_bits = 11; + static const int kappa = 2; + static const int big_divisor = 1000; + static const int small_divisor = 100; + static const int min_k = -292; + static const int max_k = 341; + static const int shorter_interval_tie_lower_threshold = -77; + static const int shorter_interval_tie_upper_threshold = -77; +}; + +// An 80- or 128-bit floating point number. +template +struct float_info::digits == 64 || + std::numeric_limits::digits == 113 || + is_float128::value>> { + using carrier_uint = detail::uint128_t; + static const int exponent_bits = 15; +}; + +// A double-double floating point number. +template +struct float_info::value>> { + using carrier_uint = detail::uint128_t; +}; + +template struct decimal_fp { + using significand_type = typename float_info::carrier_uint; + significand_type significand; + int exponent; +}; + +template FMT_API auto to_decimal(T x) noexcept -> decimal_fp; +} // namespace dragonbox + +// Returns true iff Float has the implicit bit which is not stored. +template constexpr auto has_implicit_bit() -> bool { + // An 80-bit FP number has a 64-bit significand an no implicit bit. + return std::numeric_limits::digits != 64; +} + +// Returns the number of significand bits stored in Float. The implicit bit is +// not counted since it is not stored. +template constexpr auto num_significand_bits() -> int { + // std::numeric_limits may not support __float128. + return is_float128() ? 112 + : (std::numeric_limits::digits - + (has_implicit_bit() ? 1 : 0)); +} + +template +constexpr auto exponent_mask() -> + typename dragonbox::float_info::carrier_uint { + using float_uint = typename dragonbox::float_info::carrier_uint; + return ((float_uint(1) << dragonbox::float_info::exponent_bits) - 1) + << num_significand_bits(); +} +template constexpr auto exponent_bias() -> int { + // std::numeric_limits may not support __float128. + return is_float128() ? 16383 + : std::numeric_limits::max_exponent - 1; +} + +FMT_CONSTEXPR inline auto compute_exp_size(int exp) -> int { + auto prefix_size = 2; // sign + 'e' + auto abs_exp = exp >= 0 ? exp : -exp; + if (abs_exp < 100) return prefix_size + 2; + return prefix_size + (abs_exp >= 1000 ? 4 : 3); +} + +// Writes the exponent exp in the form "[+-]d{2,3}" to buffer. +template +FMT_CONSTEXPR auto write_exponent(int exp, OutputIt out) -> OutputIt { + FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range"); + if (exp < 0) { + *out++ = static_cast('-'); + exp = -exp; + } else { + *out++ = static_cast('+'); + } + auto uexp = static_cast(exp); + if (is_constant_evaluated()) { + if (uexp < 10) *out++ = '0'; + return format_decimal(out, uexp, count_digits(uexp)); + } + if (uexp >= 100u) { + const char* top = digits2(uexp / 100); + if (uexp >= 1000u) *out++ = static_cast(top[0]); + *out++ = static_cast(top[1]); + uexp %= 100; + } + const char* d = digits2(uexp); + *out++ = static_cast(d[0]); + *out++ = static_cast(d[1]); + return out; +} + +// A floating-point number f * pow(2, e) where F is an unsigned type. +template struct basic_fp { + F f; + int e; + + static constexpr int num_significand_bits = + static_cast(sizeof(F) * num_bits()); + + constexpr basic_fp() : f(0), e(0) {} + constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {} + + // Constructs fp from an IEEE754 floating-point number. + template FMT_CONSTEXPR basic_fp(Float n) { assign(n); } + + // Assigns n to this and return true iff predecessor is closer than successor. + template ::value)> + FMT_CONSTEXPR auto assign(Float n) -> bool { + static_assert(std::numeric_limits::digits <= 113, "unsupported FP"); + // Assume Float is in the format [sign][exponent][significand]. + using carrier_uint = typename dragonbox::float_info::carrier_uint; + const auto num_float_significand_bits = + detail::num_significand_bits(); + const auto implicit_bit = carrier_uint(1) << num_float_significand_bits; + const auto significand_mask = implicit_bit - 1; + auto u = bit_cast(n); + f = static_cast(u & significand_mask); + auto biased_e = static_cast((u & exponent_mask()) >> + num_float_significand_bits); + // The predecessor is closer if n is a normalized power of 2 (f == 0) + // other than the smallest normalized number (biased_e > 1). + auto is_predecessor_closer = f == 0 && biased_e > 1; + if (biased_e == 0) + biased_e = 1; // Subnormals use biased exponent 1 (min exponent). + else if (has_implicit_bit()) + f += static_cast(implicit_bit); + e = biased_e - exponent_bias() - num_float_significand_bits; + if (!has_implicit_bit()) ++e; + return is_predecessor_closer; + } + + template ::value)> + FMT_CONSTEXPR auto assign(Float n) -> bool { + static_assert(std::numeric_limits::is_iec559, "unsupported FP"); + return assign(static_cast(n)); + } +}; + +using fp = basic_fp; + +// Normalizes the value converted from double and multiplied by (1 << SHIFT). +template +FMT_CONSTEXPR auto normalize(basic_fp value) -> basic_fp { + // Handle subnormals. + const auto implicit_bit = F(1) << num_significand_bits(); + const auto shifted_implicit_bit = implicit_bit << SHIFT; + while ((value.f & shifted_implicit_bit) == 0) { + value.f <<= 1; + --value.e; + } + // Subtract 1 to account for hidden bit. + const auto offset = basic_fp::num_significand_bits - + num_significand_bits() - SHIFT - 1; + value.f <<= offset; + value.e -= offset; + return value; +} + +// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking. +FMT_CONSTEXPR inline auto multiply(uint64_t lhs, uint64_t rhs) -> uint64_t { +#if FMT_USE_INT128 + auto product = static_cast<__uint128_t>(lhs) * rhs; + auto f = static_cast(product >> 64); + return (static_cast(product) & (1ULL << 63)) != 0 ? f + 1 : f; +#else + // Multiply 32-bit parts of significands. + uint64_t mask = (1ULL << 32) - 1; + uint64_t a = lhs >> 32, b = lhs & mask; + uint64_t c = rhs >> 32, d = rhs & mask; + uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d; + // Compute mid 64-bit of result and round. + uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31); + return ac + (ad >> 32) + (bc >> 32) + (mid >> 32); +#endif +} + +FMT_CONSTEXPR inline auto operator*(fp x, fp y) -> fp { + return {multiply(x.f, y.f), x.e + y.e + 64}; +} + +template () == num_bits()> +using convert_float_result = + conditional_t::value || doublish, double, T>; + +template +constexpr auto convert_float(T value) -> convert_float_result { + return static_cast>(value); +} + +template +auto select(T true_value, F) -> T { + return true_value; +} +template +auto select(T, F false_value) -> F { + return false_value; +} + +template +FMT_CONSTEXPR FMT_NOINLINE auto fill(OutputIt it, size_t n, + const basic_specs& specs) -> OutputIt { + auto fill_size = specs.fill_size(); + if (fill_size == 1) return detail::fill_n(it, n, specs.fill_unit()); + if (const Char* data = specs.fill()) { + for (size_t i = 0; i < n; ++i) it = copy(data, data + fill_size, it); + } + return it; +} + +// Writes the output of f, padded according to format specifications in specs. +// size: output size in code units. +// width: output display width in (terminal) column positions. +template +FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs& specs, + size_t size, size_t width, F&& f) -> OutputIt { + static_assert(default_align == align::left || default_align == align::right, + ""); + unsigned spec_width = to_unsigned(specs.width); + size_t padding = spec_width > width ? spec_width - width : 0; + // Shifts are encoded as string literals because static constexpr is not + // supported in constexpr functions. + auto* shifts = + default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01"; + size_t left_padding = padding >> shifts[static_cast(specs.align())]; + size_t right_padding = padding - left_padding; + auto it = reserve(out, size + padding * specs.fill_size()); + if (left_padding != 0) it = fill(it, left_padding, specs); + it = f(it); + if (right_padding != 0) it = fill(it, right_padding, specs); + return base_iterator(out, it); +} + +template +constexpr auto write_padded(OutputIt out, const format_specs& specs, + size_t size, F&& f) -> OutputIt { + return write_padded(out, specs, size, size, f); +} + +template +FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, + const format_specs& specs = {}) -> OutputIt { + return write_padded( + out, specs, bytes.size(), [bytes](reserve_iterator it) { + const char* data = bytes.data(); + return copy(data, data + bytes.size(), it); + }); +} + +template +auto write_ptr(OutputIt out, UIntPtr value, const format_specs* specs) + -> OutputIt { + int num_digits = count_digits<4>(value); + auto size = to_unsigned(num_digits) + size_t(2); + auto write = [=](reserve_iterator it) { + *it++ = static_cast('0'); + *it++ = static_cast('x'); + return format_base2e(4, it, value, num_digits); + }; + return specs ? write_padded(out, *specs, size, write) + : base_iterator(out, write(reserve(out, size))); +} + +// Returns true iff the code point cp is printable. +FMT_API auto is_printable(uint32_t cp) -> bool; + +inline auto needs_escape(uint32_t cp) -> bool { + if (cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\') return true; + if (const_check(FMT_OPTIMIZE_SIZE > 1)) return false; + return !is_printable(cp); +} + +template struct find_escape_result { + const Char* begin; + const Char* end; + uint32_t cp; +}; + +template +auto find_escape(const Char* begin, const Char* end) + -> find_escape_result { + for (; begin != end; ++begin) { + uint32_t cp = static_cast>(*begin); + if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue; + if (needs_escape(cp)) return {begin, begin + 1, cp}; + } + return {begin, nullptr, 0}; +} + +inline auto find_escape(const char* begin, const char* end) + -> find_escape_result { + if (const_check(!use_utf8)) return find_escape(begin, end); + auto result = find_escape_result{end, nullptr, 0}; + for_each_codepoint(string_view(begin, to_unsigned(end - begin)), + [&](uint32_t cp, string_view sv) { + if (needs_escape(cp)) { + result = {sv.begin(), sv.end(), cp}; + return false; + } + return true; + }); + return result; +} + +template +auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt { + *out++ = static_cast('\\'); + *out++ = static_cast(prefix); + Char buf[width]; + fill_n(buf, width, static_cast('0')); + format_base2e(4, buf, cp, width); + return copy(buf, buf + width, out); +} + +template +auto write_escaped_cp(OutputIt out, const find_escape_result& escape) + -> OutputIt { + auto c = static_cast(escape.cp); + switch (escape.cp) { + case '\n': + *out++ = static_cast('\\'); + c = static_cast('n'); + break; + case '\r': + *out++ = static_cast('\\'); + c = static_cast('r'); + break; + case '\t': + *out++ = static_cast('\\'); + c = static_cast('t'); + break; + case '"': FMT_FALLTHROUGH; + case '\'': FMT_FALLTHROUGH; + case '\\': *out++ = static_cast('\\'); break; + default: + if (escape.cp < 0x100) return write_codepoint<2, Char>(out, 'x', escape.cp); + if (escape.cp < 0x10000) + return write_codepoint<4, Char>(out, 'u', escape.cp); + if (escape.cp < 0x110000) + return write_codepoint<8, Char>(out, 'U', escape.cp); + for (Char escape_char : basic_string_view( + escape.begin, to_unsigned(escape.end - escape.begin))) { + out = write_codepoint<2, Char>(out, 'x', + static_cast(escape_char) & 0xFF); + } + return out; + } + *out++ = c; + return out; +} + +template +auto write_escaped_string(OutputIt out, basic_string_view str) + -> OutputIt { + *out++ = static_cast('"'); + auto begin = str.begin(), end = str.end(); + do { + auto escape = find_escape(begin, end); + out = copy(begin, escape.begin, out); + begin = escape.end; + if (!begin) break; + out = write_escaped_cp(out, escape); + } while (begin != end); + *out++ = static_cast('"'); + return out; +} + +template +auto write_escaped_char(OutputIt out, Char v) -> OutputIt { + Char v_array[1] = {v}; + *out++ = static_cast('\''); + if ((needs_escape(static_cast(v)) && v != static_cast('"')) || + v == static_cast('\'')) { + out = write_escaped_cp(out, + find_escape_result{v_array, v_array + 1, + static_cast(v)}); + } else { + *out++ = v; + } + *out++ = static_cast('\''); + return out; +} + +template +FMT_CONSTEXPR auto write_char(OutputIt out, Char value, + const format_specs& specs) -> OutputIt { + bool is_debug = specs.type() == presentation_type::debug; + return write_padded(out, specs, 1, [=](reserve_iterator it) { + if (is_debug) return write_escaped_char(it, value); + *it++ = value; + return it; + }); +} + +template class digit_grouping { + private: + std::string grouping_; + std::basic_string thousands_sep_; + + struct next_state { + std::string::const_iterator group; + int pos; + }; + auto initial_state() const -> next_state { return {grouping_.begin(), 0}; } + + // Returns the next digit group separator position. + auto next(next_state& state) const -> int { + if (thousands_sep_.empty()) return max_value(); + if (state.group == grouping_.end()) return state.pos += grouping_.back(); + if (*state.group <= 0 || *state.group == max_value()) + return max_value(); + state.pos += *state.group++; + return state.pos; + } + + public: + explicit digit_grouping(locale_ref loc, bool localized = true) { + if (!localized) return; + auto sep = thousands_sep(loc); + grouping_ = sep.grouping; + if (sep.thousands_sep) thousands_sep_.assign(1, sep.thousands_sep); + } + digit_grouping(std::string grouping, std::basic_string sep) + : grouping_(std::move(grouping)), thousands_sep_(std::move(sep)) {} + + auto has_separator() const -> bool { return !thousands_sep_.empty(); } + + auto count_separators(int num_digits) const -> int { + int count = 0; + auto state = initial_state(); + while (num_digits > next(state)) ++count; + return count; + } + + // Applies grouping to digits and writes the output to out. + template + auto apply(Out out, basic_string_view digits) const -> Out { + auto num_digits = static_cast(digits.size()); + auto separators = basic_memory_buffer(); + separators.push_back(0); + auto state = initial_state(); + while (int i = next(state)) { + if (i >= num_digits) break; + separators.push_back(i); + } + for (int i = 0, sep_index = static_cast(separators.size() - 1); + i < num_digits; ++i) { + if (num_digits - i == separators[sep_index]) { + out = copy(thousands_sep_.data(), + thousands_sep_.data() + thousands_sep_.size(), out); + --sep_index; + } + *out++ = static_cast(digits[to_unsigned(i)]); + } + return out; + } +}; + +FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) { + prefix |= prefix != 0 ? value << 8 : value; + prefix += (1u + (value > 0xff ? 1 : 0)) << 24; +} + +// Writes a decimal integer with digit grouping. +template +auto write_int(OutputIt out, UInt value, unsigned prefix, + const format_specs& specs, const digit_grouping& grouping) + -> OutputIt { + static_assert(std::is_same, UInt>::value, ""); + int num_digits = 0; + auto buffer = memory_buffer(); + switch (specs.type()) { + default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH; + case presentation_type::none: + case presentation_type::dec: + num_digits = count_digits(value); + format_decimal(appender(buffer), value, num_digits); + break; + case presentation_type::hex: + if (specs.alt()) + prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0'); + num_digits = count_digits<4>(value); + format_base2e(4, appender(buffer), value, num_digits, specs.upper()); + break; + case presentation_type::oct: + num_digits = count_digits<3>(value); + // Octal prefix '0' is counted as a digit, so only add it if precision + // is not greater than the number of digits. + if (specs.alt() && specs.precision <= num_digits && value != 0) + prefix_append(prefix, '0'); + format_base2e(3, appender(buffer), value, num_digits); + break; + case presentation_type::bin: + if (specs.alt()) + prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0'); + num_digits = count_digits<1>(value); + format_base2e(1, appender(buffer), value, num_digits); + break; + case presentation_type::chr: + return write_char(out, static_cast(value), specs); + } + + unsigned size = (prefix != 0 ? prefix >> 24 : 0) + to_unsigned(num_digits) + + to_unsigned(grouping.count_separators(num_digits)); + return write_padded( + out, specs, size, size, [&](reserve_iterator it) { + for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) + *it++ = static_cast(p & 0xff); + return grouping.apply(it, string_view(buffer.data(), buffer.size())); + }); +} + +#if FMT_USE_LOCALE +// Writes a localized value. +FMT_API auto write_loc(appender out, loc_value value, const format_specs& specs, + locale_ref loc) -> bool; +auto write_loc(basic_appender out, loc_value value, + const format_specs& specs, locale_ref loc) -> bool; +#endif +template +inline auto write_loc(OutputIt, const loc_value&, const format_specs&, + locale_ref) -> bool { + return false; +} + +template struct write_int_arg { + UInt abs_value; + unsigned prefix; +}; + +template +FMT_CONSTEXPR auto make_write_int_arg(T value, sign s) + -> write_int_arg> { + auto prefix = 0u; + auto abs_value = static_cast>(value); + if (is_negative(value)) { + prefix = 0x01000000 | '-'; + abs_value = 0 - abs_value; + } else { + constexpr unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '}; + prefix = prefixes[static_cast(s)]; + } + return {abs_value, prefix}; +} + +template struct loc_writer { + basic_appender out; + const format_specs& specs; + std::basic_string sep; + std::string grouping; + std::basic_string decimal_point; + + template ::value)> + auto operator()(T value) -> bool { + auto arg = make_write_int_arg(value, specs.sign()); + write_int(out, static_cast>(arg.abs_value), arg.prefix, + specs, digit_grouping(grouping, sep)); + return true; + } + + template ::value)> + auto operator()(T) -> bool { + return false; + } +}; + +// Size and padding computation separate from write_int to avoid template bloat. +struct size_padding { + unsigned size; + unsigned padding; + + FMT_CONSTEXPR size_padding(int num_digits, unsigned prefix, + const format_specs& specs) + : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) { + if (specs.align() == align::numeric) { + auto width = to_unsigned(specs.width); + if (width > size) { + padding = width - size; + size = width; + } + } else if (specs.precision > num_digits) { + size = (prefix >> 24) + to_unsigned(specs.precision); + padding = to_unsigned(specs.precision - num_digits); + } + } +}; + +template +FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg arg, + const format_specs& specs) -> OutputIt { + static_assert(std::is_same>::value, ""); + + constexpr size_t buffer_size = num_bits(); + char buffer[buffer_size]; + if (is_constant_evaluated()) fill_n(buffer, buffer_size, '\0'); + const char* begin = nullptr; + const char* end = buffer + buffer_size; + + auto abs_value = arg.abs_value; + auto prefix = arg.prefix; + switch (specs.type()) { + default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH; + case presentation_type::none: + case presentation_type::dec: + begin = do_format_decimal(buffer, abs_value, buffer_size); + break; + case presentation_type::hex: + begin = do_format_base2e(4, buffer, abs_value, buffer_size, specs.upper()); + if (specs.alt()) + prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0'); + break; + case presentation_type::oct: { + begin = do_format_base2e(3, buffer, abs_value, buffer_size); + // Octal prefix '0' is counted as a digit, so only add it if precision + // is not greater than the number of digits. + auto num_digits = end - begin; + if (specs.alt() && specs.precision <= num_digits && abs_value != 0) + prefix_append(prefix, '0'); + break; + } + case presentation_type::bin: + begin = do_format_base2e(1, buffer, abs_value, buffer_size); + if (specs.alt()) + prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0'); + break; + case presentation_type::chr: + return write_char(out, static_cast(abs_value), specs); + } + + // Write an integer in the format + // + // prefix contains chars in three lower bytes and the size in the fourth byte. + int num_digits = static_cast(end - begin); + // Slightly faster check for specs.width == 0 && specs.precision == -1. + if ((specs.width | (specs.precision + 1)) == 0) { + auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24)); + for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) + *it++ = static_cast(p & 0xff); + return base_iterator(out, copy(begin, end, it)); + } + auto sp = size_padding(num_digits, prefix, specs); + unsigned padding = sp.padding; + return write_padded( + out, specs, sp.size, [=](reserve_iterator it) { + for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) + *it++ = static_cast(p & 0xff); + it = detail::fill_n(it, padding, static_cast('0')); + return copy(begin, end, it); + }); +} + +template +FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(OutputIt out, + write_int_arg arg, + const format_specs& specs) + -> OutputIt { + return write_int(out, arg, specs); +} + +template ::value && + !std::is_same::value && + !std::is_same::value)> +FMT_CONSTEXPR FMT_INLINE auto write(basic_appender out, T value, + const format_specs& specs, locale_ref loc) + -> basic_appender { + if (specs.localized() && write_loc(out, value, specs, loc)) return out; + return write_int_noinline(out, make_write_int_arg(value, specs.sign()), + specs); +} + +// An inlined version of write used in format string compilation. +template ::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same>::value)> +FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, + const format_specs& specs, locale_ref loc) + -> OutputIt { + if (specs.localized() && write_loc(out, value, specs, loc)) return out; + return write_int(out, make_write_int_arg(value, specs.sign()), specs); +} + +template +FMT_CONSTEXPR auto write(OutputIt out, Char value, const format_specs& specs, + locale_ref loc = {}) -> OutputIt { + // char is formatted as unsigned char for consistency across platforms. + using unsigned_type = + conditional_t::value, unsigned char, unsigned>; + return check_char_specs(specs) + ? write_char(out, value, specs) + : write(out, static_cast(value), specs, loc); +} + +template ::value)> +FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, + const format_specs& specs) -> OutputIt { + bool is_debug = specs.type() == presentation_type::debug; + if (specs.precision < 0 && specs.width == 0) { + auto&& it = reserve(out, s.size()); + return is_debug ? write_escaped_string(it, s) : copy(s, it); + } + + size_t display_width_limit = + specs.precision < 0 ? SIZE_MAX : to_unsigned(specs.precision); + size_t display_width = + !is_debug || specs.precision == 0 ? 0 : 1; // Account for opening '"'. + size_t size = !is_debug || specs.precision == 0 ? 0 : 1; + for_each_codepoint(s, [&](uint32_t cp, string_view sv) { + if (is_debug && needs_escape(cp)) { + counting_buffer buf; + write_escaped_cp(basic_appender(buf), + find_escape_result{sv.begin(), sv.end(), cp}); + // We're reinterpreting bytes as display width. That's okay + // because write_escaped_cp() only writes ASCII characters. + size_t cp_width = buf.count(); + if (display_width + cp_width <= display_width_limit) { + display_width += cp_width; + size += cp_width; + // If this is the end of the string, account for closing '"'. + if (display_width < display_width_limit && sv.end() == s.end()) { + ++display_width; + ++size; + } + return true; + } + + size += display_width_limit - display_width; + display_width = display_width_limit; + return false; + } + + size_t cp_width = display_width_of(cp); + if (cp_width + display_width <= display_width_limit) { + display_width += cp_width; + size += sv.size(); + // If this is the end of the string, account for closing '"'. + if (is_debug && display_width < display_width_limit && + sv.end() == s.end()) { + ++display_width; + ++size; + } + return true; + } + + return false; + }); + + struct bounded_output_iterator { + reserve_iterator underlying_iterator; + size_t bound; + + FMT_CONSTEXPR auto operator*() -> bounded_output_iterator& { return *this; } + FMT_CONSTEXPR auto operator++() -> bounded_output_iterator& { + return *this; + } + FMT_CONSTEXPR auto operator++(int) -> bounded_output_iterator& { + return *this; + } + FMT_CONSTEXPR auto operator=(char c) -> bounded_output_iterator& { + if (bound > 0) { + *underlying_iterator++ = c; + --bound; + } + return *this; + } + }; + + return write_padded( + out, specs, size, display_width, [=](reserve_iterator it) { + return is_debug + ? write_escaped_string(bounded_output_iterator{it, size}, s) + .underlying_iterator + : copy(s.data(), s.data() + size, it); + }); +} + +template ::value)> +FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, + const format_specs& specs) -> OutputIt { + auto data = s.data(); + auto size = s.size(); + if (specs.precision >= 0 && to_unsigned(specs.precision) < size) + size = to_unsigned(specs.precision); + + bool is_debug = specs.type() == presentation_type::debug; + if (is_debug) { + auto buf = counting_buffer(); + write_escaped_string(basic_appender(buf), s); + size = buf.count(); + } + + return write_padded( + out, specs, size, [=](reserve_iterator it) { + return is_debug ? write_escaped_string(it, s) + : copy(data, data + size, it); + }); +} + +template +FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, + const format_specs& specs, locale_ref) -> OutputIt { + return write(out, s, specs); +} + +template +FMT_CONSTEXPR auto write(OutputIt out, const Char* s, const format_specs& specs, + locale_ref) -> OutputIt { + if (specs.type() == presentation_type::pointer) + return write_ptr(out, bit_cast(s), &specs); + if (!s) report_error("string pointer is null"); + return write(out, basic_string_view(s), specs, {}); +} + +template ::value && + !std::is_same::value && + !std::is_same::value)> +FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { + auto abs_value = static_cast>(value); + bool negative = is_negative(value); + // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer. + if (negative) abs_value = ~abs_value + 1; + int num_digits = count_digits(abs_value); + auto size = (negative ? 1 : 0) + static_cast(num_digits); + if (auto ptr = to_pointer(out, size)) { + if (negative) *ptr++ = static_cast('-'); + format_decimal(ptr, abs_value, num_digits); + return out; + } + if (negative) *out++ = static_cast('-'); + return format_decimal(out, abs_value, num_digits); +} + +template +FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, + format_specs& specs) -> const Char* { + FMT_ASSERT(begin != end, ""); + auto alignment = align::none; + auto p = begin + code_point_length(begin); + if (end - p <= 0) p = begin; + for (;;) { + switch (to_ascii(*p)) { + case '<': alignment = align::left; break; + case '>': alignment = align::right; break; + case '^': alignment = align::center; break; + } + if (alignment != align::none) { + if (p != begin) { + auto c = *begin; + if (c == '}') return begin; + if (c == '{') { + report_error("invalid fill character '{'"); + return begin; + } + specs.set_fill(basic_string_view(begin, to_unsigned(p - begin))); + begin = p + 1; + } else { + ++begin; + } + break; + } else if (p == begin) { + break; + } + p = begin; + } + specs.set_align(alignment); + return begin; +} + +template +FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan, + format_specs specs, sign s) -> OutputIt { + auto str = + isnan ? (specs.upper() ? "NAN" : "nan") : (specs.upper() ? "INF" : "inf"); + constexpr size_t str_size = 3; + auto size = str_size + (s != sign::none ? 1 : 0); + // Replace '0'-padding with space for non-finite values. + const bool is_zero_fill = + specs.fill_size() == 1 && specs.fill_unit() == '0'; + if (is_zero_fill) specs.set_fill(' '); + return write_padded(out, specs, size, + [=](reserve_iterator it) { + if (s != sign::none) + *it++ = detail::getsign(s); + return copy(str, str + str_size, it); + }); +} + +// A decimal floating-point number significand * pow(10, exp). +struct big_decimal_fp { + const char* significand; + int significand_size; + int exponent; +}; + +constexpr auto get_significand_size(const big_decimal_fp& f) -> int { + return f.significand_size; +} +template +inline auto get_significand_size(const dragonbox::decimal_fp& f) -> int { + return count_digits(f.significand); +} + +template +constexpr auto write_significand(OutputIt out, const char* significand, + int significand_size) -> OutputIt { + return copy(significand, significand + significand_size, out); +} +template +inline auto write_significand(OutputIt out, UInt significand, + int significand_size) -> OutputIt { + return format_decimal(out, significand, significand_size); +} +template +FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand, + int significand_size, int exponent, + const Grouping& grouping) -> OutputIt { + if (!grouping.has_separator()) { + out = write_significand(out, significand, significand_size); + return detail::fill_n(out, exponent, static_cast('0')); + } + auto buffer = memory_buffer(); + write_significand(appender(buffer), significand, significand_size); + detail::fill_n(appender(buffer), exponent, '0'); + return grouping.apply(out, string_view(buffer.data(), buffer.size())); +} + +template ::value)> +inline auto write_significand(Char* out, UInt significand, int significand_size, + int integral_size, Char decimal_point) -> Char* { + if (!decimal_point) return format_decimal(out, significand, significand_size); + out += significand_size + 1; + Char* end = out; + int floating_size = significand_size - integral_size; + for (int i = floating_size / 2; i > 0; --i) { + out -= 2; + write2digits(out, static_cast(significand % 100)); + significand /= 100; + } + if (floating_size % 2 != 0) { + *--out = static_cast('0' + significand % 10); + significand /= 10; + } + *--out = decimal_point; + format_decimal(out - integral_size, significand, integral_size); + return end; +} + +template >::value)> +inline auto write_significand(OutputIt out, UInt significand, + int significand_size, int integral_size, + Char decimal_point) -> OutputIt { + // Buffer is large enough to hold digits (digits10 + 1) and a decimal point. + Char buffer[digits10() + 2]; + auto end = write_significand(buffer, significand, significand_size, + integral_size, decimal_point); + return detail::copy_noinline(buffer, end, out); +} + +template +FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand, + int significand_size, int integral_size, + Char decimal_point) -> OutputIt { + out = detail::copy_noinline(significand, significand + integral_size, + out); + if (!decimal_point) return out; + *out++ = decimal_point; + return detail::copy_noinline(significand + integral_size, + significand + significand_size, out); +} + +template +FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand, + int significand_size, int integral_size, + Char decimal_point, + const Grouping& grouping) -> OutputIt { + if (!grouping.has_separator()) { + return write_significand(out, significand, significand_size, integral_size, + decimal_point); + } + auto buffer = basic_memory_buffer(); + write_significand(basic_appender(buffer), significand, significand_size, + integral_size, decimal_point); + grouping.apply( + out, basic_string_view(buffer.data(), to_unsigned(integral_size))); + return detail::copy_noinline(buffer.data() + integral_size, + buffer.end(), out); +} + +// Numbers with exponents greater or equal to the returned value will use +// the exponential notation. +template FMT_CONSTEVAL auto exp_upper() -> int { + return std::numeric_limits::digits10 != 0 + ? min_of(16, std::numeric_limits::digits10 + 1) + : 16; +} + +// Use the fixed notation if the exponent is in [-4, exp_upper), +// e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation. +constexpr auto use_fixed(int exp, int exp_upper) -> bool { + return exp >= -4 && exp < exp_upper; +} + +template class fallback_digit_grouping { + public: + constexpr fallback_digit_grouping(locale_ref, bool) {} + + constexpr auto has_separator() const -> bool { return false; } + + constexpr auto count_separators(int) const -> int { return 0; } + + template + constexpr auto apply(Out out, basic_string_view) const -> Out { + return out; + } +}; + +template +FMT_CONSTEXPR20 auto write_fixed(OutputIt out, const DecimalFP& f, + int significand_size, Char decimal_point, + const format_specs& specs, sign s, + locale_ref loc = {}) -> OutputIt { + using iterator = reserve_iterator; + + int exp = f.exponent + significand_size; + long long size = significand_size + (s != sign::none ? 1 : 0); + if (f.exponent >= 0) { + // 1234e5 -> 123400000[.0+] + size += f.exponent; + int num_zeros = specs.precision - exp; + abort_fuzzing_if(num_zeros > 5000); + if (specs.alt()) { + ++size; + if (num_zeros <= 0 && specs.type() != presentation_type::fixed) + num_zeros = 0; + if (num_zeros > 0) size += num_zeros; + } + auto grouping = Grouping(loc, specs.localized()); + size += grouping.count_separators(exp); + return write_padded( + out, specs, static_cast(size), [&](iterator it) { + if (s != sign::none) *it++ = detail::getsign(s); + it = write_significand(it, f.significand, significand_size, + f.exponent, grouping); + if (!specs.alt()) return it; + *it++ = decimal_point; + return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it; + }); + } + if (exp > 0) { + // 1234e-2 -> 12.34[0+] + int num_zeros = specs.alt() ? specs.precision - significand_size : 0; + size += 1 + max_of(num_zeros, 0); + auto grouping = Grouping(loc, specs.localized()); + size += grouping.count_separators(exp); + return write_padded( + out, specs, to_unsigned(size), [&](iterator it) { + if (s != sign::none) *it++ = detail::getsign(s); + it = write_significand(it, f.significand, significand_size, exp, + decimal_point, grouping); + return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it; + }); + } + // 1234e-6 -> 0.001234 + int num_zeros = -exp; + if (significand_size == 0 && specs.precision >= 0 && + specs.precision < num_zeros) { + num_zeros = specs.precision; + } + bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt(); + size += 1 + (pointy ? 1 : 0) + num_zeros; + return write_padded( + out, specs, to_unsigned(size), [&](iterator it) { + if (s != sign::none) *it++ = detail::getsign(s); + *it++ = Char('0'); + if (!pointy) return it; + *it++ = decimal_point; + it = detail::fill_n(it, num_zeros, Char('0')); + return write_significand(it, f.significand, significand_size); + }); +} + +template +FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f, + const format_specs& specs, sign s, + int exp_upper, locale_ref loc) -> OutputIt { + Char point = specs.localized() ? detail::decimal_point(loc) : Char('.'); + int significand_size = get_significand_size(f); + int exp = f.exponent + significand_size - 1; + if (specs.type() == presentation_type::fixed || + (specs.type() != presentation_type::exp && + use_fixed(exp, specs.precision > 0 ? specs.precision : exp_upper))) { + return write_fixed(out, f, significand_size, point, specs, + s, loc); + } + + // Write value in the exponential format. + int num_zeros = 0; + long long size = significand_size + (s != sign::none ? 1 : 0); + if (specs.alt()) { + num_zeros = max_of(specs.precision - significand_size, 0); + size += num_zeros; + } else if (significand_size == 1) { + point = Char(); + } + size += (point ? 1 : 0) + compute_exp_size(exp); + char exp_char = specs.upper() ? 'E' : 'e'; + auto write = [=](reserve_iterator it) { + if (s != sign::none) *it++ = detail::getsign(s); + // Insert a decimal point after the first digit and add an exponent. + it = write_significand(it, f.significand, significand_size, 1, point); + if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0')); + *it++ = Char(exp_char); + return write_exponent(exp, it); + }; + auto usize = to_unsigned(size); + return specs.width > 0 + ? write_padded(out, specs, usize, write) + : base_iterator(out, write(reserve(out, usize))); +} + +template +FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f, + const format_specs& specs, sign s, + int exp_upper, locale_ref loc) -> OutputIt { + if (is_constant_evaluated()) { + return do_write_float>(out, f, specs, s, + exp_upper, loc); + } else { + return do_write_float>(out, f, specs, s, + exp_upper, loc); + } +} + +template constexpr auto isnan(T value) -> bool { + return value != value; // std::isnan doesn't support __float128. +} + +template +struct has_isfinite : std::false_type {}; + +template +struct has_isfinite> + : std::true_type {}; + +template ::value&& has_isfinite::value)> +FMT_CONSTEXPR20 auto isfinite(T value) -> bool { + constexpr T inf = T(std::numeric_limits::infinity()); + if (is_constant_evaluated()) + return !detail::isnan(value) && value < inf && value > -inf; + return std::isfinite(value); +} +template ::value)> +FMT_CONSTEXPR auto isfinite(T value) -> bool { + T inf = T(std::numeric_limits::infinity()); + // std::isfinite doesn't support __float128. + return !detail::isnan(value) && value < inf && value > -inf; +} + +template ::value)> +FMT_INLINE FMT_CONSTEXPR auto signbit(T value) -> bool { + if (is_constant_evaluated()) { +#ifdef __cpp_if_constexpr + if constexpr (std::numeric_limits::is_iec559) { + auto bits = detail::bit_cast(static_cast(value)); + return (bits >> (num_bits() - 1)) != 0; + } +#endif + } + return std::signbit(static_cast(value)); +} + +inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) { + // Adjust fixed precision by exponent because it is relative to decimal + // point. + if (exp10 > 0 && precision > max_value() - exp10) + FMT_THROW(format_error("number is too big")); + precision += exp10; +} + +class bigint { + private: + // A bigint is a number in the form bigit_[N - 1] ... bigit_[0] * 32^exp_. + using bigit = uint32_t; // A big digit. + using double_bigit = uint64_t; + enum { bigit_bits = num_bits() }; + enum { bigits_capacity = 32 }; + basic_memory_buffer bigits_; + int exp_; + + friend struct formatter; + + FMT_CONSTEXPR auto get_bigit(int i) const -> bigit { + return i >= exp_ && i < num_bigits() ? bigits_[i - exp_] : 0; + } + + FMT_CONSTEXPR void subtract_bigits(int index, bigit other, bigit& borrow) { + auto result = double_bigit(bigits_[index]) - other - borrow; + bigits_[index] = static_cast(result); + borrow = static_cast(result >> (bigit_bits * 2 - 1)); + } + + FMT_CONSTEXPR void remove_leading_zeros() { + int num_bigits = static_cast(bigits_.size()) - 1; + while (num_bigits > 0 && bigits_[num_bigits] == 0) --num_bigits; + bigits_.resize(to_unsigned(num_bigits + 1)); + } + + // Computes *this -= other assuming aligned bigints and *this >= other. + FMT_CONSTEXPR void subtract_aligned(const bigint& other) { + FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints"); + FMT_ASSERT(compare(*this, other) >= 0, ""); + bigit borrow = 0; + int i = other.exp_ - exp_; + for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) + subtract_bigits(i, other.bigits_[j], borrow); + if (borrow != 0) subtract_bigits(i, 0, borrow); + FMT_ASSERT(borrow == 0, ""); + remove_leading_zeros(); + } + + FMT_CONSTEXPR void multiply(uint32_t value) { + bigit carry = 0; + const double_bigit wide_value = value; + for (size_t i = 0, n = bigits_.size(); i < n; ++i) { + double_bigit result = bigits_[i] * wide_value + carry; + bigits_[i] = static_cast(result); + carry = static_cast(result >> bigit_bits); + } + if (carry != 0) bigits_.push_back(carry); + } + + template ::value || + std::is_same::value)> + FMT_CONSTEXPR void multiply(UInt value) { + using half_uint = + conditional_t::value, uint64_t, uint32_t>; + const int shift = num_bits() - bigit_bits; + const UInt lower = static_cast(value); + const UInt upper = value >> num_bits(); + UInt carry = 0; + for (size_t i = 0, n = bigits_.size(); i < n; ++i) { + UInt result = lower * bigits_[i] + static_cast(carry); + carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) + + (carry >> bigit_bits); + bigits_[i] = static_cast(result); + } + while (carry != 0) { + bigits_.push_back(static_cast(carry)); + carry >>= bigit_bits; + } + } + + template ::value || + std::is_same::value)> + FMT_CONSTEXPR void assign(UInt n) { + size_t num_bigits = 0; + do { + bigits_[num_bigits++] = static_cast(n); + n >>= bigit_bits; + } while (n != 0); + bigits_.resize(num_bigits); + exp_ = 0; + } + + public: + FMT_CONSTEXPR bigint() : exp_(0) {} + explicit bigint(uint64_t n) { assign(n); } + + bigint(const bigint&) = delete; + void operator=(const bigint&) = delete; + + FMT_CONSTEXPR void assign(const bigint& other) { + auto size = other.bigits_.size(); + bigits_.resize(size); + auto data = other.bigits_.data(); + copy(data, data + size, bigits_.data()); + exp_ = other.exp_; + } + + template FMT_CONSTEXPR void operator=(Int n) { + FMT_ASSERT(n > 0, ""); + assign(uint64_or_128_t(n)); + } + + FMT_CONSTEXPR auto num_bigits() const -> int { + return static_cast(bigits_.size()) + exp_; + } + + FMT_CONSTEXPR auto operator<<=(int shift) -> bigint& { + FMT_ASSERT(shift >= 0, ""); + exp_ += shift / bigit_bits; + shift %= bigit_bits; + if (shift == 0) return *this; + bigit carry = 0; + for (size_t i = 0, n = bigits_.size(); i < n; ++i) { + bigit c = bigits_[i] >> (bigit_bits - shift); + bigits_[i] = (bigits_[i] << shift) + carry; + carry = c; + } + if (carry != 0) bigits_.push_back(carry); + return *this; + } + + template FMT_CONSTEXPR auto operator*=(Int value) -> bigint& { + FMT_ASSERT(value > 0, ""); + multiply(uint32_or_64_or_128_t(value)); + return *this; + } + + friend FMT_CONSTEXPR auto compare(const bigint& b1, const bigint& b2) -> int { + int num_bigits1 = b1.num_bigits(), num_bigits2 = b2.num_bigits(); + if (num_bigits1 != num_bigits2) return num_bigits1 > num_bigits2 ? 1 : -1; + int i = static_cast(b1.bigits_.size()) - 1; + int j = static_cast(b2.bigits_.size()) - 1; + int end = i - j; + if (end < 0) end = 0; + for (; i >= end; --i, --j) { + bigit b1_bigit = b1.bigits_[i], b2_bigit = b2.bigits_[j]; + if (b1_bigit != b2_bigit) return b1_bigit > b2_bigit ? 1 : -1; + } + if (i != j) return i > j ? 1 : -1; + return 0; + } + + // Returns compare(lhs1 + lhs2, rhs). + friend FMT_CONSTEXPR auto add_compare(const bigint& lhs1, const bigint& lhs2, + const bigint& rhs) -> int { + int max_lhs_bigits = max_of(lhs1.num_bigits(), lhs2.num_bigits()); + int num_rhs_bigits = rhs.num_bigits(); + if (max_lhs_bigits + 1 < num_rhs_bigits) return -1; + if (max_lhs_bigits > num_rhs_bigits) return 1; + double_bigit borrow = 0; + int min_exp = min_of(min_of(lhs1.exp_, lhs2.exp_), rhs.exp_); + for (int i = num_rhs_bigits - 1; i >= min_exp; --i) { + double_bigit sum = double_bigit(lhs1.get_bigit(i)) + lhs2.get_bigit(i); + bigit rhs_bigit = rhs.get_bigit(i); + if (sum > rhs_bigit + borrow) return 1; + borrow = rhs_bigit + borrow - sum; + if (borrow > 1) return -1; + borrow <<= bigit_bits; + } + return borrow != 0 ? -1 : 0; + } + + // Assigns pow(10, exp) to this bigint. + FMT_CONSTEXPR20 void assign_pow10(int exp) { + FMT_ASSERT(exp >= 0, ""); + if (exp == 0) return *this = 1; + int bitmask = 1 << (num_bits() - + countl_zero(static_cast(exp)) - 1); + // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by + // repeated squaring and multiplication. + *this = 5; + bitmask >>= 1; + while (bitmask != 0) { + square(); + if ((exp & bitmask) != 0) *this *= 5; + bitmask >>= 1; + } + *this <<= exp; // Multiply by pow(2, exp) by shifting. + } + + FMT_CONSTEXPR20 void square() { + int num_bigits = static_cast(bigits_.size()); + int num_result_bigits = 2 * num_bigits; + basic_memory_buffer n(std::move(bigits_)); + bigits_.resize(to_unsigned(num_result_bigits)); + auto sum = uint128_t(); + for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) { + // Compute bigit at position bigit_index of the result by adding + // cross-product terms n[i] * n[j] such that i + j == bigit_index. + for (int i = 0, j = bigit_index; j >= 0; ++i, --j) { + // Most terms are multiplied twice which can be optimized in the future. + sum += double_bigit(n[i]) * n[j]; + } + bigits_[bigit_index] = static_cast(sum); + sum >>= num_bits(); // Compute the carry. + } + // Do the same for the top half. + for (int bigit_index = num_bigits; bigit_index < num_result_bigits; + ++bigit_index) { + for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;) + sum += double_bigit(n[i++]) * n[j--]; + bigits_[bigit_index] = static_cast(sum); + sum >>= num_bits(); + } + remove_leading_zeros(); + exp_ *= 2; + } + + // If this bigint has a bigger exponent than other, adds trailing zero to make + // exponents equal. This simplifies some operations such as subtraction. + FMT_CONSTEXPR void align(const bigint& other) { + int exp_difference = exp_ - other.exp_; + if (exp_difference <= 0) return; + int num_bigits = static_cast(bigits_.size()); + bigits_.resize(to_unsigned(num_bigits + exp_difference)); + for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j) + bigits_[j] = bigits_[i]; + fill_n(bigits_.data(), to_unsigned(exp_difference), 0U); + exp_ -= exp_difference; + } + + // Divides this bignum by divisor, assigning the remainder to this and + // returning the quotient. + FMT_CONSTEXPR auto divmod_assign(const bigint& divisor) -> int { + FMT_ASSERT(this != &divisor, ""); + if (compare(*this, divisor) < 0) return 0; + FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, ""); + align(divisor); + int quotient = 0; + do { + subtract_aligned(divisor); + ++quotient; + } while (compare(*this, divisor) >= 0); + return quotient; + } +}; + +// format_dragon flags. +enum dragon { + predecessor_closer = 1, + fixup = 2, // Run fixup to correct exp10 which can be off by one. + fixed = 4, +}; + +// Formats a floating-point number using a variation of the Fixed-Precision +// Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White: +// https://fmt.dev/papers/p372-steele.pdf. +FMT_CONSTEXPR20 inline void format_dragon(basic_fp value, + unsigned flags, int num_digits, + buffer& buf, int& exp10) { + bigint numerator; // 2 * R in (FPP)^2. + bigint denominator; // 2 * S in (FPP)^2. + // lower and upper are differences between value and corresponding boundaries. + bigint lower; // (M^- in (FPP)^2). + bigint upper_store; // upper's value if different from lower. + bigint* upper = nullptr; // (M^+ in (FPP)^2). + // Shift numerator and denominator by an extra bit or two (if lower boundary + // is closer) to make lower and upper integers. This eliminates multiplication + // by 2 during later computations. + bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0; + int shift = is_predecessor_closer ? 2 : 1; + if (value.e >= 0) { + numerator = value.f; + numerator <<= value.e + shift; + lower = 1; + lower <<= value.e; + if (is_predecessor_closer) { + upper_store = 1; + upper_store <<= value.e + 1; + upper = &upper_store; + } + denominator.assign_pow10(exp10); + denominator <<= shift; + } else if (exp10 < 0) { + numerator.assign_pow10(-exp10); + lower.assign(numerator); + if (is_predecessor_closer) { + upper_store.assign(numerator); + upper_store <<= 1; + upper = &upper_store; + } + numerator *= value.f; + numerator <<= shift; + denominator = 1; + denominator <<= shift - value.e; + } else { + numerator = value.f; + numerator <<= shift; + denominator.assign_pow10(exp10); + denominator <<= shift - value.e; + lower = 1; + if (is_predecessor_closer) { + upper_store = 1ULL << 1; + upper = &upper_store; + } + } + int even = static_cast((value.f & 1) == 0); + if (!upper) upper = &lower; + bool shortest = num_digits < 0; + if ((flags & dragon::fixup) != 0) { + if (add_compare(numerator, *upper, denominator) + even <= 0) { + --exp10; + numerator *= 10; + if (num_digits < 0) { + lower *= 10; + if (upper != &lower) *upper *= 10; + } + } + if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1); + } + // Invariant: value == (numerator / denominator) * pow(10, exp10). + if (shortest) { + // Generate the shortest representation. + num_digits = 0; + char* data = buf.data(); + for (;;) { + int digit = numerator.divmod_assign(denominator); + bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower. + // numerator + upper >[=] pow10: + bool high = add_compare(numerator, *upper, denominator) + even > 0; + data[num_digits++] = static_cast('0' + digit); + if (low || high) { + if (!low) { + ++data[num_digits - 1]; + } else if (high) { + int result = add_compare(numerator, numerator, denominator); + // Round half to even. + if (result > 0 || (result == 0 && (digit % 2) != 0)) + ++data[num_digits - 1]; + } + buf.try_resize(to_unsigned(num_digits)); + exp10 -= num_digits - 1; + return; + } + numerator *= 10; + lower *= 10; + if (upper != &lower) *upper *= 10; + } + } + // Generate the given number of digits. + exp10 -= num_digits - 1; + if (num_digits <= 0) { + auto digit = '0'; + if (num_digits == 0) { + denominator *= 10; + digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0'; + } + buf.push_back(digit); + return; + } + buf.try_resize(to_unsigned(num_digits)); + for (int i = 0; i < num_digits - 1; ++i) { + int digit = numerator.divmod_assign(denominator); + buf[i] = static_cast('0' + digit); + numerator *= 10; + } + int digit = numerator.divmod_assign(denominator); + auto result = add_compare(numerator, numerator, denominator); + if (result > 0 || (result == 0 && (digit % 2) != 0)) { + if (digit == 9) { + const auto overflow = '0' + 10; + buf[num_digits - 1] = overflow; + // Propagate the carry. + for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) { + buf[i] = '0'; + ++buf[i - 1]; + } + if (buf[0] == overflow) { + buf[0] = '1'; + if ((flags & dragon::fixed) != 0) + buf.push_back('0'); + else + ++exp10; + } + return; + } + ++digit; + } + buf[num_digits - 1] = static_cast('0' + digit); +} + +// Formats a floating-point number using the hexfloat format. +template ::value)> +FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs, + buffer& buf) { + // float is passed as double to reduce the number of instantiations and to + // simplify implementation. + static_assert(!std::is_same::value, ""); + + using info = dragonbox::float_info; + + // Assume Float is in the format [sign][exponent][significand]. + using carrier_uint = typename info::carrier_uint; + + const auto num_float_significand_bits = detail::num_significand_bits(); + + basic_fp f(value); + f.e += num_float_significand_bits; + if (!has_implicit_bit()) --f.e; + + const auto num_fraction_bits = + num_float_significand_bits + (has_implicit_bit() ? 1 : 0); + const auto num_xdigits = (num_fraction_bits + 3) / 4; + + const auto leading_shift = ((num_xdigits - 1) * 4); + const auto leading_mask = carrier_uint(0xF) << leading_shift; + const auto leading_xdigit = + static_cast((f.f & leading_mask) >> leading_shift); + if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1); + + int print_xdigits = num_xdigits - 1; + if (specs.precision >= 0 && print_xdigits > specs.precision) { + const int shift = ((print_xdigits - specs.precision - 1) * 4); + const auto mask = carrier_uint(0xF) << shift; + const auto v = static_cast((f.f & mask) >> shift); + + if (v >= 8) { + const auto inc = carrier_uint(1) << (shift + 4); + f.f += inc; + f.f &= ~(inc - 1); + } + + // Check long double overflow + if (!has_implicit_bit()) { + const auto implicit_bit = carrier_uint(1) << num_float_significand_bits; + if ((f.f & implicit_bit) == implicit_bit) { + f.f >>= 4; + f.e += 4; + } + } + + print_xdigits = specs.precision; + } + + char xdigits[num_bits() / 4]; + detail::fill_n(xdigits, sizeof(xdigits), '0'); + format_base2e(4, xdigits, f.f, num_xdigits, specs.upper()); + + // Remove zero tail + while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits; + + buf.push_back('0'); + buf.push_back(specs.upper() ? 'X' : 'x'); + buf.push_back(xdigits[0]); + if (specs.alt() || print_xdigits > 0 || print_xdigits < specs.precision) + buf.push_back('.'); + buf.append(xdigits + 1, xdigits + 1 + print_xdigits); + for (; print_xdigits < specs.precision; ++print_xdigits) buf.push_back('0'); + + buf.push_back(specs.upper() ? 'P' : 'p'); + + uint32_t abs_e; + if (f.e < 0) { + buf.push_back('-'); + abs_e = static_cast(-f.e); + } else { + buf.push_back('+'); + abs_e = static_cast(f.e); + } + format_decimal(appender(buf), abs_e, detail::count_digits(abs_e)); +} + +template ::value)> +FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs, + buffer& buf) { + format_hexfloat(static_cast(value), specs, buf); +} + +constexpr auto fractional_part_rounding_thresholds(int index) -> uint32_t { + // For checking rounding thresholds. + // The kth entry is chosen to be the smallest integer such that the + // upper 32-bits of 10^(k+1) times it is strictly bigger than 5 * 10^k. + // It is equal to ceil(2^31 + 2^32/10^(k + 1)). + // These are stored in a string literal because we cannot have static arrays + // in constexpr functions and non-static ones are poorly optimized. + return U"\x9999999a\x828f5c29\x80418938\x80068db9\x8000a7c6\x800010c7" + U"\x800001ae\x8000002b"[index]; +} + +template +FMT_CONSTEXPR20 auto format_float(Float value, int precision, + const format_specs& specs, bool binary32, + buffer& buf) -> int { + // float is passed as double to reduce the number of instantiations. + static_assert(!std::is_same::value, ""); + auto converted_value = convert_float(value); + + const bool fixed = specs.type() == presentation_type::fixed; + if (value == 0) { + if (precision <= 0 || !fixed) { + buf.push_back('0'); + return 0; + } + buf.try_resize(to_unsigned(precision)); + fill_n(buf.data(), precision, '0'); + return -precision; + } + + int exp = 0; + bool use_dragon = true; + unsigned dragon_flags = 0; + if (!is_fast_float() || is_constant_evaluated()) { + const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10) + using info = dragonbox::float_info; + const auto f = basic_fp(converted_value); + // Compute exp, an approximate power of 10, such that + // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1). + // This is based on log10(value) == log2(value) / log2(10) and approximation + // of log2(value) by e + num_fraction_bits idea from double-conversion. + auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10; + exp = static_cast(e); + if (e > exp) ++exp; // Compute ceil. + dragon_flags = dragon::fixup; + } else { + // Extract significand bits and exponent bits. + using info = dragonbox::float_info; + auto br = bit_cast(static_cast(value)); + + const uint64_t significand_mask = + (static_cast(1) << num_significand_bits()) - 1; + uint64_t significand = (br & significand_mask); + int exponent = static_cast((br & exponent_mask()) >> + num_significand_bits()); + + if (exponent != 0) { // Check if normal. + exponent -= exponent_bias() + num_significand_bits(); + significand |= + (static_cast(1) << num_significand_bits()); + significand <<= 1; + } else { + // Normalize subnormal inputs. + FMT_ASSERT(significand != 0, "zeros should not appear here"); + int shift = countl_zero(significand); + FMT_ASSERT(shift >= num_bits() - num_significand_bits(), + ""); + shift -= (num_bits() - num_significand_bits() - 2); + exponent = (std::numeric_limits::min_exponent - + num_significand_bits()) - + shift; + significand <<= shift; + } + + // Compute the first several nonzero decimal significand digits. + // We call the number we get the first segment. + const int k = info::kappa - dragonbox::floor_log10_pow2(exponent); + exp = -k; + const int beta = exponent + dragonbox::floor_log2_pow10(k); + uint64_t first_segment; + bool has_more_segments; + int digits_in_the_first_segment; + { + const auto r = dragonbox::umul192_upper128( + significand << beta, dragonbox::get_cached_power(k)); + first_segment = r.high(); + has_more_segments = r.low() != 0; + + // The first segment can have 18 ~ 19 digits. + if (first_segment >= 1000000000000000000ULL) { + digits_in_the_first_segment = 19; + } else { + // When it is of 18-digits, we align it to 19-digits by adding a bogus + // zero at the end. + digits_in_the_first_segment = 18; + first_segment *= 10; + } + } + + // Compute the actual number of decimal digits to print. + if (fixed) adjust_precision(precision, exp + digits_in_the_first_segment); + + // Use Dragon4 only when there might be not enough digits in the first + // segment. + if (digits_in_the_first_segment > precision) { + use_dragon = false; + + if (precision <= 0) { + exp += digits_in_the_first_segment; + + if (precision < 0) { + // Nothing to do, since all we have are just leading zeros. + buf.try_resize(0); + } else { + // We may need to round-up. + buf.try_resize(1); + if ((first_segment | static_cast(has_more_segments)) > + 5000000000000000000ULL) { + buf[0] = '1'; + } else { + buf[0] = '0'; + } + } + } // precision <= 0 + else { + exp += digits_in_the_first_segment - precision; + + // When precision > 0, we divide the first segment into three + // subsegments, each with 9, 9, and 0 ~ 1 digits so that each fits + // in 32-bits which usually allows faster calculation than in + // 64-bits. Since some compiler (e.g. MSVC) doesn't know how to optimize + // division-by-constant for large 64-bit divisors, we do it here + // manually. The magic number 7922816251426433760 below is equal to + // ceil(2^(64+32) / 10^10). + const uint32_t first_subsegment = static_cast( + dragonbox::umul128_upper64(first_segment, 7922816251426433760ULL) >> + 32); + const uint64_t second_third_subsegments = + first_segment - first_subsegment * 10000000000ULL; + + uint64_t prod; + uint32_t digits; + bool should_round_up; + int number_of_digits_to_print = min_of(precision, 9); + + // Print a 9-digits subsegment, either the first or the second. + auto print_subsegment = [&](uint32_t subsegment, char* buffer) { + int number_of_digits_printed = 0; + + // If we want to print an odd number of digits from the subsegment, + if ((number_of_digits_to_print & 1) != 0) { + // Convert to 64-bit fixed-point fractional form with 1-digit + // integer part. The magic number 720575941 is a good enough + // approximation of 2^(32 + 24) / 10^8; see + // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case + // for details. + prod = ((subsegment * static_cast(720575941)) >> 24) + 1; + digits = static_cast(prod >> 32); + *buffer = static_cast('0' + digits); + number_of_digits_printed++; + } + // If we want to print an even number of digits from the + // first_subsegment, + else { + // Convert to 64-bit fixed-point fractional form with 2-digits + // integer part. The magic number 450359963 is a good enough + // approximation of 2^(32 + 20) / 10^7; see + // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case + // for details. + prod = ((subsegment * static_cast(450359963)) >> 20) + 1; + digits = static_cast(prod >> 32); + write2digits(buffer, digits); + number_of_digits_printed += 2; + } + + // Print all digit pairs. + while (number_of_digits_printed < number_of_digits_to_print) { + prod = static_cast(prod) * static_cast(100); + digits = static_cast(prod >> 32); + write2digits(buffer + number_of_digits_printed, digits); + number_of_digits_printed += 2; + } + }; + + // Print first subsegment. + print_subsegment(first_subsegment, buf.data()); + + // Perform rounding if the first subsegment is the last subsegment to + // print. + if (precision <= 9) { + // Rounding inside the subsegment. + // We round-up if: + // - either the fractional part is strictly larger than 1/2, or + // - the fractional part is exactly 1/2 and the last digit is odd. + // We rely on the following observations: + // - If fractional_part >= threshold, then the fractional part is + // strictly larger than 1/2. + // - If the MSB of fractional_part is set, then the fractional part + // must be at least 1/2. + // - When the MSB of fractional_part is set, either + // second_third_subsegments being nonzero or has_more_segments + // being true means there are further digits not printed, so the + // fractional part is strictly larger than 1/2. + if (precision < 9) { + uint32_t fractional_part = static_cast(prod); + should_round_up = + fractional_part >= fractional_part_rounding_thresholds( + 8 - number_of_digits_to_print) || + ((fractional_part >> 31) & + ((digits & 1) | (second_third_subsegments != 0) | + has_more_segments)) != 0; + } + // Rounding at the subsegment boundary. + // In this case, the fractional part is at least 1/2 if and only if + // second_third_subsegments >= 5000000000ULL, and is strictly larger + // than 1/2 if we further have either second_third_subsegments > + // 5000000000ULL or has_more_segments == true. + else { + should_round_up = second_third_subsegments > 5000000000ULL || + (second_third_subsegments == 5000000000ULL && + ((digits & 1) != 0 || has_more_segments)); + } + } + // Otherwise, print the second subsegment. + else { + // Compilers are not aware of how to leverage the maximum value of + // second_third_subsegments to find out a better magic number which + // allows us to eliminate an additional shift. 1844674407370955162 = + // ceil(2^64/10) < ceil(2^64*(10^9/(10^10 - 1))). + const uint32_t second_subsegment = + static_cast(dragonbox::umul128_upper64( + second_third_subsegments, 1844674407370955162ULL)); + const uint32_t third_subsegment = + static_cast(second_third_subsegments) - + second_subsegment * 10; + + number_of_digits_to_print = precision - 9; + print_subsegment(second_subsegment, buf.data() + 9); + + // Rounding inside the subsegment. + if (precision < 18) { + // The condition third_subsegment != 0 implies that the segment was + // of 19 digits, so in this case the third segment should be + // consisting of a genuine digit from the input. + uint32_t fractional_part = static_cast(prod); + should_round_up = + fractional_part >= fractional_part_rounding_thresholds( + 8 - number_of_digits_to_print) || + ((fractional_part >> 31) & + ((digits & 1) | (third_subsegment != 0) | + has_more_segments)) != 0; + } + // Rounding at the subsegment boundary. + else { + // In this case, the segment must be of 19 digits, thus + // the third subsegment should be consisting of a genuine digit from + // the input. + should_round_up = third_subsegment > 5 || + (third_subsegment == 5 && + ((digits & 1) != 0 || has_more_segments)); + } + } + + // Round-up if necessary. + if (should_round_up) { + ++buf[precision - 1]; + for (int i = precision - 1; i > 0 && buf[i] > '9'; --i) { + buf[i] = '0'; + ++buf[i - 1]; + } + if (buf[0] > '9') { + buf[0] = '1'; + if (fixed) + buf[precision++] = '0'; + else + ++exp; + } + } + buf.try_resize(to_unsigned(precision)); + } + } // if (digits_in_the_first_segment > precision) + else { + // Adjust the exponent for its use in Dragon4. + exp += digits_in_the_first_segment - 1; + } + } + if (use_dragon) { + auto f = basic_fp(); + bool is_predecessor_closer = binary32 ? f.assign(static_cast(value)) + : f.assign(converted_value); + if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer; + if (fixed) dragon_flags |= dragon::fixed; + // Limit precision to the maximum possible number of significant digits in + // an IEEE754 double because we don't need to generate zeros. + const int max_double_digits = 767; + if (precision > max_double_digits) precision = max_double_digits; + format_dragon(f, dragon_flags, precision, buf, exp); + } + if (!fixed && !specs.alt()) { + // Remove trailing zeros. + auto num_digits = buf.size(); + while (num_digits > 0 && buf[num_digits - 1] == '0') { + --num_digits; + ++exp; + } + buf.try_resize(num_digits); + } + return exp; +} + +template ::value)> +FMT_CONSTEXPR20 auto write(OutputIt out, T value, format_specs specs, + locale_ref loc = {}) -> OutputIt { + if (specs.localized() && write_loc(out, value, specs, loc)) return out; + + // Use signbit because value < 0 is false for NaN. + sign s = detail::signbit(value) ? sign::minus : specs.sign(); + + if (!detail::isfinite(value)) + return write_nonfinite(out, detail::isnan(value), specs, s); + + if (specs.align() == align::numeric && s != sign::none) { + *out++ = detail::getsign(s); + s = sign::none; + if (specs.width != 0) --specs.width; + } + + const int exp_upper = detail::exp_upper(); + int precision = specs.precision; + if (precision < 0) { + if (specs.type() != presentation_type::none) { + precision = 6; + } else if (is_fast_float::value && !is_constant_evaluated()) { + // Use Dragonbox for the shortest format. + auto dec = dragonbox::to_decimal(static_cast>(value)); + return write_float(out, dec, specs, s, exp_upper, loc); + } + } + + memory_buffer buffer; + if (specs.type() == presentation_type::hexfloat) { + if (s != sign::none) buffer.push_back(detail::getsign(s)); + format_hexfloat(convert_float(value), specs, buffer); + return write_bytes(out, {buffer.data(), buffer.size()}, + specs); + } + + if (specs.type() == presentation_type::exp) { + if (precision == max_value()) + report_error("number is too big"); + else + ++precision; + if (specs.precision != 0) specs.set_alt(); + } else if (specs.type() == presentation_type::fixed) { + if (specs.precision != 0) specs.set_alt(); + } else if (precision == 0) { + precision = 1; + } + int exp = format_float(convert_float(value), precision, specs, + std::is_same(), buffer); + + specs.precision = precision; + auto f = big_decimal_fp{buffer.data(), static_cast(buffer.size()), exp}; + return write_float(out, f, specs, s, exp_upper, loc); +} + +template ::value)> +FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt { + if (is_constant_evaluated()) return write(out, value, format_specs()); + + auto s = detail::signbit(value) ? sign::minus : sign::none; + auto mask = exponent_mask>(); + if ((bit_cast(value) & mask) == mask) + return write_nonfinite(out, std::isnan(value), {}, s); + + auto dec = dragonbox::to_decimal(static_cast>(value)); + auto significand = dec.significand; + int significand_size = count_digits(significand); + int exponent = dec.exponent + significand_size - 1; + if (use_fixed(exponent, detail::exp_upper())) { + return write_fixed>( + out, dec, significand_size, Char('.'), {}, s); + } + + // Write value in the exponential format. + const char* prefix = "e+"; + int abs_exponent = exponent; + if (exponent < 0) { + abs_exponent = -exponent; + prefix = "e-"; + } + auto has_decimal_point = significand_size != 1; + size_t size = std::is_pointer::value + ? 0u + : to_unsigned((s != sign::none ? 1 : 0) + significand_size + + (has_decimal_point ? 1 : 0) + + (abs_exponent >= 100 ? 5 : 4)); + if (auto ptr = to_pointer(out, size)) { + if (s != sign::none) *ptr++ = Char('-'); + if (has_decimal_point) { + auto begin = ptr; + ptr = format_decimal(ptr, significand, significand_size + 1); + *begin = begin[1]; + begin[1] = '.'; + } else { + *ptr++ = static_cast('0' + significand); + } + if (std::is_same::value) { + memcpy(ptr, prefix, 2); + ptr += 2; + } else { + *ptr++ = prefix[0]; + *ptr++ = prefix[1]; + } + if (abs_exponent >= 100) { + *ptr++ = static_cast('0' + abs_exponent / 100); + abs_exponent %= 100; + } + write2digits(ptr, static_cast(abs_exponent)); + return select::value>(ptr + 2, out); + } + auto it = reserve(out, size); + if (s != sign::none) *it++ = Char('-'); + // Insert a decimal point after the first digit and add an exponent. + it = write_significand(it, significand, significand_size, 1, + has_decimal_point ? Char('.') : Char()); + *it++ = Char('e'); + it = write_exponent(exponent, it); + return base_iterator(out, it); +} + +template ::value && + !is_fast_float::value)> +inline auto write(OutputIt out, T value) -> OutputIt { + return write(out, value, {}); +} + +template +auto write(OutputIt out, monostate, format_specs = {}, locale_ref = {}) + -> OutputIt { + FMT_ASSERT(false, ""); + return out; +} + +template +FMT_CONSTEXPR auto write(OutputIt out, basic_string_view value) + -> OutputIt { + return copy_noinline(value.begin(), value.end(), out); +} + +template ::value)> +constexpr auto write(OutputIt out, const T& value) -> OutputIt { + return write(out, to_string_view(value)); +} + +// FMT_ENABLE_IF() condition separated to workaround an MSVC bug. +template < + typename Char, typename OutputIt, typename T, + bool check = std::is_enum::value && !std::is_same::value && + mapped_type_constant::value != type::custom_type, + FMT_ENABLE_IF(check)> +FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { + return write(out, static_cast>(value)); +} + +template ::value)> +FMT_CONSTEXPR auto write(OutputIt out, T value, const format_specs& specs = {}, + locale_ref = {}) -> OutputIt { + return specs.type() != presentation_type::none && + specs.type() != presentation_type::string + ? write(out, value ? 1 : 0, specs, {}) + : write_bytes(out, value ? "true" : "false", specs); +} + +template +FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt { + auto it = reserve(out, 1); + *it++ = value; + return base_iterator(out, it); +} + +template +FMT_CONSTEXPR20 auto write(OutputIt out, const Char* value) -> OutputIt { + if (value) return write(out, basic_string_view(value)); + report_error("string pointer is null"); + return out; +} + +template ::value)> +auto write(OutputIt out, const T* value, const format_specs& specs = {}, + locale_ref = {}) -> OutputIt { + return write_ptr(out, bit_cast(value), &specs); +} + +template ::value == + type::custom_type && + !std::is_fundamental::value)> +FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> OutputIt { + auto f = formatter(); + auto parse_ctx = parse_context({}); + f.parse(parse_ctx); + auto ctx = basic_format_context(out, {}, {}); + return f.format(value, ctx); +} + +template +using is_builtin = + bool_constant::value || FMT_BUILTIN_TYPES>; + +// An argument visitor that formats the argument and writes it via the output +// iterator. It's a class and not a generic lambda for compatibility with C++11. +template struct default_arg_formatter { + using context = buffered_context; + + basic_appender out; + + void operator()(monostate) { report_error("argument not found"); } + + template ::value)> + void operator()(T value) { + write(out, value); + } + + template ::value)> + void operator()(T) { + FMT_ASSERT(false, ""); + } + + void operator()(typename basic_format_arg::handle h) { + // Use a null locale since the default format must be unlocalized. + auto parse_ctx = parse_context({}); + auto format_ctx = context(out, {}, {}); + h.format(parse_ctx, format_ctx); + } +}; + +template struct arg_formatter { + basic_appender out; + const format_specs& specs; + FMT_NO_UNIQUE_ADDRESS locale_ref locale; + + template ::value)> + FMT_CONSTEXPR FMT_INLINE void operator()(T value) { + detail::write(out, value, specs, locale); + } + + template ::value)> + void operator()(T) { + FMT_ASSERT(false, ""); + } + + void operator()(typename basic_format_arg>::handle) { + // User-defined types are handled separately because they require access + // to the parse context. + } +}; + +struct dynamic_spec_getter { + template ::value)> + FMT_CONSTEXPR auto operator()(T value) -> unsigned long long { + return is_negative(value) ? ~0ull : static_cast(value); + } + + template ::value)> + FMT_CONSTEXPR auto operator()(T) -> unsigned long long { + report_error("width/precision is not integer"); + return 0; + } +}; + +template +FMT_CONSTEXPR void handle_dynamic_spec( + arg_id_kind kind, int& value, + const arg_ref& ref, Context& ctx) { + if (kind == arg_id_kind::none) return; + auto arg = + kind == arg_id_kind::index ? ctx.arg(ref.index) : ctx.arg(ref.name); + if (!arg) report_error("argument not found"); + unsigned long long result = arg.visit(dynamic_spec_getter()); + if (result > to_unsigned(max_value())) + report_error("width/precision is out of range"); + value = static_cast(result); +} + +#if FMT_USE_NONTYPE_TEMPLATE_ARGS +template Str> +struct static_named_arg : view { + static constexpr auto name = Str.data; + + const T& value; + static_named_arg(const T& v) : value(v) {} +}; + +template Str> +struct is_named_arg> : std::true_type {}; + +template Str> +struct is_static_named_arg> : std::true_type { +}; + +template Str> +struct udl_arg { + template auto operator=(T&& value) const { + return static_named_arg(std::forward(value)); + } +}; +#else +template struct udl_arg { + const Char* str; + + template auto operator=(T&& value) const -> named_arg { + return {str, std::forward(value)}; + } +}; +#endif // FMT_USE_NONTYPE_TEMPLATE_ARGS + +template struct format_handler { + parse_context parse_ctx; + buffered_context ctx; + + void on_text(const Char* begin, const Char* end) { + copy_noinline(begin, end, ctx.out()); + } + + FMT_CONSTEXPR auto on_arg_id() -> int { return parse_ctx.next_arg_id(); } + FMT_CONSTEXPR auto on_arg_id(int id) -> int { + parse_ctx.check_arg_id(id); + return id; + } + FMT_CONSTEXPR auto on_arg_id(basic_string_view id) -> int { + parse_ctx.check_arg_id(id); + int arg_id = ctx.arg_id(id); + if (arg_id < 0) report_error("argument not found"); + return arg_id; + } + + FMT_INLINE void on_replacement_field(int id, const Char*) { + ctx.arg(id).visit(default_arg_formatter{ctx.out()}); + } + + auto on_format_specs(int id, const Char* begin, const Char* end) + -> const Char* { + auto arg = ctx.arg(id); + if (!arg) report_error("argument not found"); + // Not using a visitor for custom types gives better codegen. + if (arg.format_custom(begin, parse_ctx, ctx)) return parse_ctx.begin(); + + auto specs = dynamic_format_specs(); + begin = parse_format_specs(begin, end, specs, parse_ctx, arg.type()); + if (specs.dynamic()) { + handle_dynamic_spec(specs.dynamic_width(), specs.width, specs.width_ref, + ctx); + handle_dynamic_spec(specs.dynamic_precision(), specs.precision, + specs.precision_ref, ctx); + } + + arg.visit(arg_formatter{ctx.out(), specs, ctx.locale()}); + return begin; + } + + FMT_NORETURN void on_error(const char* message) { report_error(message); } +}; + +// It is used in format-inl.h and os.cc. +using format_func = void (*)(detail::buffer&, int, const char*); +FMT_API void do_report_error(format_func func, int error_code, + const char* message) noexcept; + +FMT_API void format_error_code(buffer& out, int error_code, + string_view message) noexcept; + +template +template +FMT_CONSTEXPR auto native_formatter::format( + const T& val, FormatContext& ctx) const -> decltype(ctx.out()) { + if (!specs_.dynamic()) + return write(ctx.out(), val, specs_, ctx.locale()); + auto specs = format_specs(specs_); + handle_dynamic_spec(specs.dynamic_width(), specs.width, specs_.width_ref, + ctx); + handle_dynamic_spec(specs.dynamic_precision(), specs.precision, + specs_.precision_ref, ctx); + return write(ctx.out(), val, specs, ctx.locale()); +} +} // namespace detail + +FMT_BEGIN_EXPORT + +// A generic formatting context with custom output iterator and character +// (code unit) support. Char is the format string code unit type which can be +// different from OutputIt::value_type. +template class generic_context { + private: + OutputIt out_; + basic_format_args args_; + locale_ref loc_; + + public: + using char_type = Char; + using iterator = OutputIt; + enum { builtin_types = FMT_BUILTIN_TYPES }; + + constexpr generic_context(OutputIt out, + basic_format_args args, + locale_ref loc = {}) + : out_(out), args_(args), loc_(loc) {} + generic_context(generic_context&&) = default; + generic_context(const generic_context&) = delete; + void operator=(const generic_context&) = delete; + + constexpr auto arg(int id) const -> basic_format_arg { + return args_.get(id); + } + auto arg(basic_string_view name) const + -> basic_format_arg { + return args_.get(name); + } + constexpr auto arg_id(basic_string_view name) const -> int { + return args_.get_id(name); + } + + constexpr auto out() const -> iterator { return out_; } + + void advance_to(iterator it) { + if (!detail::is_back_insert_iterator()) out_ = it; + } + + constexpr auto locale() const -> locale_ref { return loc_; } +}; + +class loc_value { + private: + basic_format_arg value_; + + public: + template ::value)> + loc_value(T value) : value_(value) {} + + template ::value)> + loc_value(T) {} + + template auto visit(Visitor&& vis) -> decltype(vis(0)) { + return value_.visit(vis); + } +}; + +// A locale facet that formats values in UTF-8. +// It is parameterized on the locale to avoid the heavy include. +template class format_facet : public Locale::facet { + private: + std::string separator_; + std::string grouping_; + std::string decimal_point_; + + protected: + virtual auto do_put(appender out, loc_value val, + const format_specs& specs) const -> bool; + + public: + static FMT_API typename Locale::id id; + + explicit format_facet(Locale& loc); + explicit format_facet(string_view sep = "", std::string grouping = "\3", + std::string decimal_point = ".") + : separator_(sep.data(), sep.size()), + grouping_(grouping), + decimal_point_(decimal_point) {} + + auto put(appender out, loc_value val, const format_specs& specs) const + -> bool { + return do_put(out, val, specs); + } +}; + +#define FMT_FORMAT_AS(Type, Base) \ + template \ + struct formatter : formatter { \ + template \ + FMT_CONSTEXPR auto format(Type value, FormatContext& ctx) const \ + -> decltype(ctx.out()) { \ + return formatter::format(value, ctx); \ + } \ + } + +FMT_FORMAT_AS(signed char, int); +FMT_FORMAT_AS(unsigned char, unsigned); +FMT_FORMAT_AS(short, int); +FMT_FORMAT_AS(unsigned short, unsigned); +FMT_FORMAT_AS(long, detail::long_type); +FMT_FORMAT_AS(unsigned long, detail::ulong_type); +FMT_FORMAT_AS(Char*, const Char*); +FMT_FORMAT_AS(detail::std_string_view, basic_string_view); +FMT_FORMAT_AS(std::nullptr_t, const void*); +FMT_FORMAT_AS(void*, const void*); + +template +struct formatter : formatter, Char> {}; + +template +class formatter, Char> + : public formatter, Char> {}; + +template +struct formatter, Char> : formatter {}; +template +struct formatter, Char> + : formatter {}; + +template +struct formatter + : detail::native_formatter {}; + +template +struct formatter>> + : formatter, Char> { + template + FMT_CONSTEXPR auto format(const T& value, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto&& val = format_as(value); // Make an lvalue reference for format. + return formatter, Char>::format(val, ctx); + } +}; + +/** + * Converts `p` to `const void*` for pointer formatting. + * + * **Example**: + * + * auto s = fmt::format("{}", fmt::ptr(p)); + */ +template auto ptr(T p) -> const void* { + static_assert(std::is_pointer::value, "fmt::ptr used with non-pointer"); + return detail::bit_cast(p); +} + +/** + * Converts `e` to the underlying type. + * + * **Example**: + * + * enum class color { red, green, blue }; + * auto s = fmt::format("{}", fmt::underlying(color::red)); // s == "0" + */ +template +constexpr auto underlying(Enum e) noexcept -> underlying_t { + return static_cast>(e); +} + +namespace enums { +template ::value)> +constexpr auto format_as(Enum e) noexcept -> underlying_t { + return static_cast>(e); +} +} // namespace enums + +#ifdef __cpp_lib_byte +template +struct formatter : formatter { + static auto format_as(std::byte b) -> unsigned char { + return static_cast(b); + } + template + auto format(std::byte b, Context& ctx) const -> decltype(ctx.out()) { + return formatter::format(format_as(b), ctx); + } +}; +#endif + +struct bytes { + string_view data; + + inline explicit bytes(string_view s) : data(s) {} +}; + +template <> struct formatter { + private: + detail::dynamic_format_specs<> specs_; + + public: + FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { + return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, + detail::type::string_type); + } + + template + auto format(bytes b, FormatContext& ctx) const -> decltype(ctx.out()) { + auto specs = specs_; + detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, + specs.width_ref, ctx); + detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision, + specs.precision_ref, ctx); + return detail::write_bytes(ctx.out(), b.data, specs); + } +}; + +// group_digits_view is not derived from view because it copies the argument. +template struct group_digits_view { + T value; +}; + +/** + * Returns a view that formats an integer value using ',' as a + * locale-independent thousands separator. + * + * **Example**: + * + * fmt::print("{}", fmt::group_digits(12345)); + * // Output: "12,345" + */ +template auto group_digits(T value) -> group_digits_view { + return {value}; +} + +template struct formatter> : formatter { + private: + detail::dynamic_format_specs<> specs_; + + public: + FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { + return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, + detail::type::int_type); + } + + template + auto format(group_digits_view view, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto specs = specs_; + detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, + specs.width_ref, ctx); + detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision, + specs.precision_ref, ctx); + auto arg = detail::make_write_int_arg(view.value, specs.sign()); + return detail::write_int( + ctx.out(), static_cast>(arg.abs_value), + arg.prefix, specs, detail::digit_grouping("\3", ",")); + } +}; + +template struct nested_view { + const formatter* fmt; + const T* value; +}; + +template +struct formatter, Char> { + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return ctx.begin(); + } + template + auto format(nested_view view, FormatContext& ctx) const + -> decltype(ctx.out()) { + return view.fmt->format(*view.value, ctx); + } +}; + +template struct nested_formatter { + private: + basic_specs specs_; + int width_; + formatter formatter_; + + public: + constexpr nested_formatter() : width_(0) {} + + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(), end = ctx.end(); + if (it == end) return it; + auto specs = format_specs(); + it = detail::parse_align(it, end, specs); + specs_ = specs; + Char c = *it; + auto width_ref = detail::arg_ref(); + if ((c >= '0' && c <= '9') || c == '{') { + it = detail::parse_width(it, end, specs, width_ref, ctx); + width_ = specs.width; + } + ctx.advance_to(it); + return formatter_.parse(ctx); + } + + template + auto write_padded(FormatContext& ctx, F write) const -> decltype(ctx.out()) { + if (width_ == 0) return write(ctx.out()); + auto buf = basic_memory_buffer(); + write(basic_appender(buf)); + auto specs = format_specs(); + specs.width = width_; + specs.copy_fill_from(specs_); + specs.set_align(specs_.align()); + return detail::write( + ctx.out(), basic_string_view(buf.data(), buf.size()), specs); + } + + auto nested(const T& value) const -> nested_view { + return nested_view{&formatter_, &value}; + } +}; + +inline namespace literals { +#if FMT_USE_NONTYPE_TEMPLATE_ARGS +template constexpr auto operator""_a() { + using char_t = remove_cvref_t; + return detail::udl_arg(); +} +#else +/** + * User-defined literal equivalent of `fmt::arg`. + * + * **Example**: + * + * using namespace fmt::literals; + * fmt::print("The answer is {answer}.", "answer"_a=42); + */ +constexpr auto operator""_a(const char* s, size_t) -> detail::udl_arg { + return {s}; +} +#endif // FMT_USE_NONTYPE_TEMPLATE_ARGS +} // namespace literals + +/// A fast integer formatter. +class format_int { + private: + // Buffer should be large enough to hold all digits (digits10 + 1), + // a sign and a null character. + enum { buffer_size = std::numeric_limits::digits10 + 3 }; + mutable char buffer_[buffer_size]; + char* str_; + + template + FMT_CONSTEXPR20 auto format_unsigned(UInt value) -> char* { + auto n = static_cast>(value); + return detail::do_format_decimal(buffer_, n, buffer_size - 1); + } + + template + FMT_CONSTEXPR20 auto format_signed(Int value) -> char* { + auto abs_value = static_cast>(value); + bool negative = value < 0; + if (negative) abs_value = 0 - abs_value; + auto begin = format_unsigned(abs_value); + if (negative) *--begin = '-'; + return begin; + } + + public: + FMT_CONSTEXPR20 explicit format_int(int value) : str_(format_signed(value)) {} + FMT_CONSTEXPR20 explicit format_int(long value) + : str_(format_signed(value)) {} + FMT_CONSTEXPR20 explicit format_int(long long value) + : str_(format_signed(value)) {} + FMT_CONSTEXPR20 explicit format_int(unsigned value) + : str_(format_unsigned(value)) {} + FMT_CONSTEXPR20 explicit format_int(unsigned long value) + : str_(format_unsigned(value)) {} + FMT_CONSTEXPR20 explicit format_int(unsigned long long value) + : str_(format_unsigned(value)) {} + + /// Returns the number of characters written to the output buffer. + FMT_CONSTEXPR20 auto size() const -> size_t { + return detail::to_unsigned(buffer_ - str_ + buffer_size - 1); + } + + /// Returns a pointer to the output buffer content. No terminating null + /// character is appended. + FMT_CONSTEXPR20 auto data() const -> const char* { return str_; } + + /// Returns a pointer to the output buffer content with terminating null + /// character appended. + FMT_CONSTEXPR20 auto c_str() const -> const char* { + buffer_[buffer_size - 1] = '\0'; + return str_; + } + + /// Returns the content of the output buffer as an `std::string`. + inline auto str() const -> std::string { return {str_, size()}; } +}; + +#if FMT_CLANG_ANALYZER +# define FMT_STRING_IMPL(s, base) s +#else +# define FMT_STRING_IMPL(s, base) \ + [] { \ + /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \ + /* Use a macro-like name to avoid shadowing warnings. */ \ + struct FMT_VISIBILITY("hidden") FMT_COMPILE_STRING : base { \ + using char_type = fmt::remove_cvref_t; \ + constexpr explicit operator fmt::basic_string_view() \ + const { \ + return fmt::detail::compile_string_to_view(s); \ + } \ + }; \ + using FMT_STRING_VIEW = \ + fmt::basic_string_view; \ + fmt::detail::ignore_unused(FMT_STRING_VIEW(FMT_COMPILE_STRING())); \ + return FMT_COMPILE_STRING(); \ + }() +#endif // FMT_CLANG_ANALYZER + +/** + * Constructs a legacy compile-time format string from a string literal `s`. + * + * **Example**: + * + * // A compile-time error because 'd' is an invalid specifier for strings. + * std::string s = fmt::format(FMT_STRING("{:d}"), "foo"); + */ +#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string) + +FMT_API auto vsystem_error(int error_code, string_view fmt, format_args args) + -> std::system_error; + +/** + * Constructs `std::system_error` with a message formatted with + * `fmt::format(fmt, args...)`. + * `error_code` is a system error code as given by `errno`. + * + * **Example**: + * + * // This throws std::system_error with the description + * // cannot open file 'madeup': No such file or directory + * // or similar (system message may vary). + * const char* filename = "madeup"; + * FILE* file = fopen(filename, "r"); + * if (!file) + * throw fmt::system_error(errno, "cannot open file '{}'", filename); + */ +template +auto system_error(int error_code, format_string fmt, T&&... args) + -> std::system_error { + return vsystem_error(error_code, fmt.str, vargs{{args...}}); +} + +/** + * Formats an error message for an error returned by an operating system or a + * language runtime, for example a file opening error, and writes it to `out`. + * The format is the same as the one used by `std::system_error(ec, message)` + * where `ec` is `std::error_code(error_code, std::generic_category())`. + * It is implementation-defined but normally looks like: + * + * : + * + * where `` is the passed message and `` is the system + * message corresponding to the error code. + * `error_code` is a system error code as given by `errno`. + */ +FMT_API void format_system_error(detail::buffer& out, int error_code, + const char* message) noexcept; + +// Reports a system error without throwing an exception. +// Can be used to report errors from destructors. +FMT_API void report_system_error(int error_code, const char* message) noexcept; + +inline auto vformat(locale_ref loc, string_view fmt, format_args args) + -> std::string { + auto buf = memory_buffer(); + detail::vformat_to(buf, fmt, args, loc); + return {buf.data(), buf.size()}; +} + +template +FMT_INLINE auto format(locale_ref loc, format_string fmt, T&&... args) + -> std::string { + return vformat(loc, fmt.str, vargs{{args...}}); +} + +template ::value)> +auto vformat_to(OutputIt out, locale_ref loc, string_view fmt, format_args args) + -> OutputIt { + auto&& buf = detail::get_buffer(out); + detail::vformat_to(buf, fmt, args, loc); + return detail::get_iterator(buf, out); +} + +template ::value)> +FMT_INLINE auto format_to(OutputIt out, locale_ref loc, format_string fmt, + T&&... args) -> OutputIt { + return fmt::vformat_to(out, loc, fmt.str, vargs{{args...}}); +} + +template +FMT_NODISCARD FMT_INLINE auto formatted_size(locale_ref loc, + format_string fmt, + T&&... args) -> size_t { + auto buf = detail::counting_buffer<>(); + detail::vformat_to(buf, fmt.str, vargs{{args...}}, loc); + return buf.count(); +} + +FMT_API auto vformat(string_view fmt, format_args args) -> std::string; + +/** + * Formats `args` according to specifications in `fmt` and returns the result + * as a string. + * + * **Example**: + * + * #include + * std::string message = fmt::format("The answer is {}.", 42); + */ +template +FMT_NODISCARD FMT_INLINE auto format(format_string fmt, T&&... args) + -> std::string { + return vformat(fmt.str, vargs{{args...}}); +} + +/** + * Converts `value` to `std::string` using the default format for type `T`. + * + * **Example**: + * + * std::string answer = fmt::to_string(42); + */ +template ::value)> +FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(T value) -> std::string { + // The buffer should be large enough to store the number including the sign + // or "false" for bool. + char buffer[max_of(detail::digits10() + 2, 5)]; + return {buffer, detail::write(buffer, value)}; +} + +template ::value)> +FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value) + -> std::string { + return to_string(format_as(value)); +} + +template ::value && + !detail::use_format_as::value)> +FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value) + -> std::string { + auto buffer = memory_buffer(); + detail::write(appender(buffer), value); + return {buffer.data(), buffer.size()}; +} + +FMT_END_EXPORT +FMT_END_NAMESPACE + +#ifdef FMT_HEADER_ONLY +# define FMT_FUNC inline +# include "format-inl.h" +#endif + +// Restore _LIBCPP_REMOVE_TRANSITIVE_INCLUDES. +#ifdef FMT_REMOVE_TRANSITIVE_INCLUDES +# undef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES +#endif + +#endif // FMT_FORMAT_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/os.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/os.h new file mode 100644 index 0000000000000000000000000000000000000000..a412fd64a3045f2128b2746dc5bbd0cb90b81654 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/os.h @@ -0,0 +1,432 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - optional OS-specific functionality +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_OS_H_ +#define FMT_OS_H_ + +#include "format.h" + +#ifndef FMT_MODULE +# include +# include +# include +# include // std::system_error + +# if FMT_HAS_INCLUDE() +# include // LC_NUMERIC_MASK on macOS +# endif +#endif // FMT_MODULE + +#ifndef FMT_USE_FCNTL +// UWP doesn't provide _pipe. +# if FMT_HAS_INCLUDE("winapifamily.h") +# include +# endif +# if (FMT_HAS_INCLUDE() || defined(__APPLE__) || \ + defined(__linux__)) && \ + (!defined(WINAPI_FAMILY) || \ + (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) && \ + !defined(__wasm__) +# include // for O_RDONLY +# define FMT_USE_FCNTL 1 +# else +# define FMT_USE_FCNTL 0 +# endif +#endif + +#ifndef FMT_POSIX +# if defined(_WIN32) && !defined(__MINGW32__) +// Fix warnings about deprecated symbols. +# define FMT_POSIX(call) _##call +# else +# define FMT_POSIX(call) call +# endif +#endif + +// Calls to system functions are wrapped in FMT_SYSTEM for testability. +#ifdef FMT_SYSTEM +# define FMT_HAS_SYSTEM +# define FMT_POSIX_CALL(call) FMT_SYSTEM(call) +#else +# define FMT_SYSTEM(call) ::call +# ifdef _WIN32 +// Fix warnings about deprecated symbols. +# define FMT_POSIX_CALL(call) ::_##call +# else +# define FMT_POSIX_CALL(call) ::call +# endif +#endif + +// Retries the expression while it evaluates to error_result and errno +// equals to EINTR. +#ifndef _WIN32 +# define FMT_RETRY_VAL(result, expression, error_result) \ + do { \ + (result) = (expression); \ + } while ((result) == (error_result) && errno == EINTR) +#else +# define FMT_RETRY_VAL(result, expression, error_result) result = (expression) +#endif + +#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1) + +FMT_BEGIN_NAMESPACE +FMT_BEGIN_EXPORT + +/** + * A reference to a null-terminated string. It can be constructed from a C + * string or `std::string`. + * + * You can use one of the following type aliases for common character types: + * + * +---------------+-----------------------------+ + * | Type | Definition | + * +===============+=============================+ + * | cstring_view | basic_cstring_view | + * +---------------+-----------------------------+ + * | wcstring_view | basic_cstring_view | + * +---------------+-----------------------------+ + * + * This class is most useful as a parameter type for functions that wrap C APIs. + */ +template class basic_cstring_view { + private: + const Char* data_; + + public: + /// Constructs a string reference object from a C string. + basic_cstring_view(const Char* s) : data_(s) {} + + /// Constructs a string reference from an `std::string` object. + basic_cstring_view(const std::basic_string& s) : data_(s.c_str()) {} + + /// Returns the pointer to a C string. + auto c_str() const -> const Char* { return data_; } +}; + +using cstring_view = basic_cstring_view; +using wcstring_view = basic_cstring_view; + +#ifdef _WIN32 +FMT_API const std::error_category& system_category() noexcept; + +namespace detail { +FMT_API void format_windows_error(buffer& out, int error_code, + const char* message) noexcept; +} + +FMT_API std::system_error vwindows_error(int error_code, string_view fmt, + format_args args); + +/** + * Constructs a `std::system_error` object with the description of the form + * + * : + * + * where `` is the formatted message and `` is the + * system message corresponding to the error code. + * `error_code` is a Windows error code as given by `GetLastError`. + * If `error_code` is not a valid error code such as -1, the system message + * will look like "error -1". + * + * **Example**: + * + * // This throws a system_error with the description + * // cannot open file 'foo': The system cannot find the file specified. + * // or similar (system message may vary) if the file doesn't exist. + * const char *filename = "foo"; + * LPOFSTRUCT of = LPOFSTRUCT(); + * HFILE file = OpenFile(filename, &of, OF_READ); + * if (file == HFILE_ERROR) { + * throw fmt::windows_error(GetLastError(), + * "cannot open file '{}'", filename); + * } + */ +template +auto windows_error(int error_code, string_view message, const T&... args) + -> std::system_error { + return vwindows_error(error_code, message, vargs{{args...}}); +} + +// Reports a Windows error without throwing an exception. +// Can be used to report errors from destructors. +FMT_API void report_windows_error(int error_code, const char* message) noexcept; +#else +inline auto system_category() noexcept -> const std::error_category& { + return std::system_category(); +} +#endif // _WIN32 + +// std::system is not available on some platforms such as iOS (#2248). +#ifdef __OSX__ +template > +void say(const S& fmt, Args&&... args) { + std::system(format("say \"{}\"", format(fmt, args...)).c_str()); +} +#endif + +// A buffered file. +class buffered_file { + private: + FILE* file_; + + friend class file; + + inline explicit buffered_file(FILE* f) : file_(f) {} + + public: + buffered_file(const buffered_file&) = delete; + void operator=(const buffered_file&) = delete; + + // Constructs a buffered_file object which doesn't represent any file. + inline buffered_file() noexcept : file_(nullptr) {} + + // Destroys the object closing the file it represents if any. + FMT_API ~buffered_file() noexcept; + + public: + inline buffered_file(buffered_file&& other) noexcept : file_(other.file_) { + other.file_ = nullptr; + } + + inline auto operator=(buffered_file&& other) -> buffered_file& { + close(); + file_ = other.file_; + other.file_ = nullptr; + return *this; + } + + // Opens a file. + FMT_API buffered_file(cstring_view filename, cstring_view mode); + + // Closes the file. + FMT_API void close(); + + // Returns the pointer to a FILE object representing this file. + inline auto get() const noexcept -> FILE* { return file_; } + + FMT_API auto descriptor() const -> int; + + template + inline void print(string_view fmt, const T&... args) { + fmt::vargs vargs = {{args...}}; + detail::is_locking() ? fmt::vprint_buffered(file_, fmt, vargs) + : fmt::vprint(file_, fmt, vargs); + } +}; + +#if FMT_USE_FCNTL + +// A file. Closed file is represented by a file object with descriptor -1. +// Methods that are not declared with noexcept may throw +// fmt::system_error in case of failure. Note that some errors such as +// closing the file multiple times will cause a crash on Windows rather +// than an exception. You can get standard behavior by overriding the +// invalid parameter handler with _set_invalid_parameter_handler. +class FMT_API file { + private: + int fd_; // File descriptor. + + // Constructs a file object with a given descriptor. + explicit file(int fd) : fd_(fd) {} + + friend struct pipe; + + public: + // Possible values for the oflag argument to the constructor. + enum { + RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only. + WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only. + RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing. + CREATE = FMT_POSIX(O_CREAT), // Create if the file doesn't exist. + APPEND = FMT_POSIX(O_APPEND), // Open in append mode. + TRUNC = FMT_POSIX(O_TRUNC) // Truncate the content of the file. + }; + + // Constructs a file object which doesn't represent any file. + inline file() noexcept : fd_(-1) {} + + // Opens a file and constructs a file object representing this file. + file(cstring_view path, int oflag); + + public: + file(const file&) = delete; + void operator=(const file&) = delete; + + inline file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; } + + // Move assignment is not noexcept because close may throw. + inline auto operator=(file&& other) -> file& { + close(); + fd_ = other.fd_; + other.fd_ = -1; + return *this; + } + + // Destroys the object closing the file it represents if any. + ~file() noexcept; + + // Returns the file descriptor. + inline auto descriptor() const noexcept -> int { return fd_; } + + // Closes the file. + void close(); + + // Returns the file size. The size has signed type for consistency with + // stat::st_size. + auto size() const -> long long; + + // Attempts to read count bytes from the file into the specified buffer. + auto read(void* buffer, size_t count) -> size_t; + + // Attempts to write count bytes from the specified buffer to the file. + auto write(const void* buffer, size_t count) -> size_t; + + // Duplicates a file descriptor with the dup function and returns + // the duplicate as a file object. + static auto dup(int fd) -> file; + + // Makes fd be the copy of this file descriptor, closing fd first if + // necessary. + void dup2(int fd); + + // Makes fd be the copy of this file descriptor, closing fd first if + // necessary. + void dup2(int fd, std::error_code& ec) noexcept; + + // Creates a buffered_file object associated with this file and detaches + // this file object from the file. + auto fdopen(const char* mode) -> buffered_file; + +# if defined(_WIN32) && !defined(__MINGW32__) + // Opens a file and constructs a file object representing this file by + // wcstring_view filename. Windows only. + static file open_windows_file(wcstring_view path, int oflag); +# endif +}; + +struct FMT_API pipe { + file read_end; + file write_end; + + // Creates a pipe setting up read_end and write_end file objects for reading + // and writing respectively. + pipe(); +}; + +// Returns the memory page size. +auto getpagesize() -> long; + +namespace detail { + +struct buffer_size { + constexpr buffer_size() = default; + size_t value = 0; + FMT_CONSTEXPR auto operator=(size_t val) const -> buffer_size { + auto bs = buffer_size(); + bs.value = val; + return bs; + } +}; + +struct ostream_params { + int oflag = file::WRONLY | file::CREATE | file::TRUNC; + size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768; + + constexpr ostream_params() {} + + template + ostream_params(T... params, int new_oflag) : ostream_params(params...) { + oflag = new_oflag; + } + + template + ostream_params(T... params, detail::buffer_size bs) + : ostream_params(params...) { + this->buffer_size = bs.value; + } + +// Intel has a bug that results in failure to deduce a constructor +// for empty parameter packs. +# if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000 + ostream_params(int new_oflag) : oflag(new_oflag) {} + ostream_params(detail::buffer_size bs) : buffer_size(bs.value) {} +# endif +}; + +} // namespace detail + +FMT_INLINE_VARIABLE constexpr auto buffer_size = detail::buffer_size(); + +/// A fast buffered output stream for writing from a single thread. Writing from +/// multiple threads without external synchronization may result in a data race. +class ostream : private detail::buffer { + private: + file file_; + + FMT_API ostream(cstring_view path, const detail::ostream_params& params); + + FMT_API static void grow(buffer& buf, size_t); + + public: + FMT_API ostream(ostream&& other) noexcept; + FMT_API ~ostream(); + + operator writer() { + detail::buffer& buf = *this; + return buf; + } + + inline void flush() { + if (size() == 0) return; + file_.write(data(), size() * sizeof(data()[0])); + clear(); + } + + template + friend auto output_file(cstring_view path, T... params) -> ostream; + + inline void close() { + flush(); + file_.close(); + } + + /// Formats `args` according to specifications in `fmt` and writes the + /// output to the file. + template void print(format_string fmt, T&&... args) { + vformat_to(appender(*this), fmt.str, vargs{{args...}}); + } +}; + +/** + * Opens a file for writing. Supported parameters passed in `params`: + * + * - ``: Flags passed to [open]( + * https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html) + * (`file::WRONLY | file::CREATE | file::TRUNC` by default) + * - `buffer_size=`: Output buffer size + * + * **Example**: + * + * auto out = fmt::output_file("guide.txt"); + * out.print("Don't {}", "Panic"); + */ +template +inline auto output_file(cstring_view path, T... params) -> ostream { + return {path, detail::ostream_params(params...)}; +} +#endif // FMT_USE_FCNTL + +FMT_END_EXPORT +FMT_END_NAMESPACE + +#endif // FMT_OS_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ostream.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ostream.h new file mode 100644 index 0000000000000000000000000000000000000000..a3c4887750d4bc5227e3e79f34f8869f706d82f5 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ostream.h @@ -0,0 +1,172 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - std::ostream support +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_OSTREAM_H_ +#define FMT_OSTREAM_H_ + +#ifndef FMT_MODULE +# include // std::filebuf +#endif + +#ifdef _WIN32 +# ifdef __GLIBCXX__ +# include +# include +# endif +# include +#endif + +#include "chrono.h" // formatbuf + +#ifdef _MSVC_STL_UPDATE +# define FMT_MSVC_STL_UPDATE _MSVC_STL_UPDATE +#elif defined(_MSC_VER) && _MSC_VER < 1912 // VS 15.5 +# define FMT_MSVC_STL_UPDATE _MSVC_LANG +#else +# define FMT_MSVC_STL_UPDATE 0 +#endif + +FMT_BEGIN_NAMESPACE +namespace detail { + +// Generate a unique explicit instantiation in every translation unit using a +// tag type in an anonymous namespace. +namespace { +struct file_access_tag {}; +} // namespace +template +class file_access { + friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; } +}; + +#if FMT_MSVC_STL_UPDATE +template class file_access; +auto get_file(std::filebuf&) -> FILE*; +#endif + +// Write the content of buf to os. +// It is a separate function rather than a part of vprint to simplify testing. +template +void write_buffer(std::basic_ostream& os, buffer& buf) { + const Char* buf_data = buf.data(); + using unsigned_streamsize = make_unsigned_t; + unsigned_streamsize size = buf.size(); + unsigned_streamsize max_size = to_unsigned(max_value()); + do { + unsigned_streamsize n = size <= max_size ? size : max_size; + os.write(buf_data, static_cast(n)); + buf_data += n; + size -= n; + } while (size != 0); +} + +template struct streamed_view { + const T& value; +}; +} // namespace detail + +// Formats an object of type T that has an overloaded ostream operator<<. +template +struct basic_ostream_formatter : formatter, Char> { + void set_debug_format() = delete; + + template + auto format(const T& value, Context& ctx) const -> decltype(ctx.out()) { + auto buffer = basic_memory_buffer(); + auto&& formatbuf = detail::formatbuf>(buffer); + auto&& output = std::basic_ostream(&formatbuf); + output.imbue(std::locale::classic()); // The default is always unlocalized. + output << value; + output.exceptions(std::ios_base::failbit | std::ios_base::badbit); + return formatter, Char>::format( + {buffer.data(), buffer.size()}, ctx); + } +}; + +using ostream_formatter = basic_ostream_formatter; + +template +struct formatter, Char> + : basic_ostream_formatter { + template + auto format(detail::streamed_view view, Context& ctx) const + -> decltype(ctx.out()) { + return basic_ostream_formatter::format(view.value, ctx); + } +}; + +/** + * Returns a view that formats `value` via an ostream `operator<<`. + * + * **Example**: + * + * fmt::print("Current thread id: {}\n", + * fmt::streamed(std::this_thread::get_id())); + */ +template +constexpr auto streamed(const T& value) -> detail::streamed_view { + return {value}; +} + +inline void vprint(std::ostream& os, string_view fmt, format_args args) { + auto buffer = memory_buffer(); + detail::vformat_to(buffer, fmt, args); + FILE* f = nullptr; +#if FMT_MSVC_STL_UPDATE && FMT_USE_RTTI + if (auto* buf = dynamic_cast(os.rdbuf())) + f = detail::get_file(*buf); +#elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI + auto* rdbuf = os.rdbuf(); + if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf*>(rdbuf)) + f = sfbuf->file(); + else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf*>(rdbuf)) + f = fbuf->file(); +#endif +#ifdef _WIN32 + if (f) { + int fd = _fileno(f); + if (_isatty(fd)) { + os.flush(); + if (detail::write_console(fd, {buffer.data(), buffer.size()})) return; + } + } +#endif + detail::ignore_unused(f); + detail::write_buffer(os, buffer); +} + +/** + * Prints formatted data to the stream `os`. + * + * **Example**: + * + * fmt::print(cerr, "Don't {}!", "panic"); + */ +FMT_EXPORT template +void print(std::ostream& os, format_string fmt, T&&... args) { + fmt::vargs vargs = {{args...}}; + if (detail::const_check(detail::use_utf8)) return vprint(os, fmt.str, vargs); + auto buffer = memory_buffer(); + detail::vformat_to(buffer, fmt.str, vargs); + detail::write_buffer(os, buffer); +} + +FMT_EXPORT template +void println(std::ostream& os, format_string fmt, T&&... args) { + fmt::print(os, FMT_STRING("{}\n"), + fmt::format(fmt, std::forward(args)...)); +} + +FMT_END_NAMESPACE + +#endif // FMT_OSTREAM_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/printf.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/printf.h new file mode 100644 index 0000000000000000000000000000000000000000..087cbae23c6d72af09fb88bdc6c5db721f4f6832 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/printf.h @@ -0,0 +1,629 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - legacy printf implementation +// +// Copyright (c) 2012 - 2016, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_PRINTF_H_ +#define FMT_PRINTF_H_ + +#ifndef FMT_MODULE +# include // std::find +# include // std::numeric_limits +#endif + +#include "format.h" + +FMT_BEGIN_NAMESPACE +FMT_BEGIN_EXPORT + +template class basic_printf_context { + private: + basic_appender out_; + basic_format_args args_; + + static_assert(std::is_same::value || + std::is_same::value, + "Unsupported code unit type."); + + public: + using char_type = Char; + enum { builtin_types = 1 }; + + /// Constructs a `printf_context` object. References to the arguments are + /// stored in the context object so make sure they have appropriate lifetimes. + basic_printf_context(basic_appender out, + basic_format_args args) + : out_(out), args_(args) {} + + auto out() -> basic_appender { return out_; } + void advance_to(basic_appender) {} + + auto locale() -> locale_ref { return {}; } + + auto arg(int id) const -> basic_format_arg { + return args_.get(id); + } +}; + +namespace detail { + +// Return the result via the out param to workaround gcc bug 77539. +template +FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool { + for (out = first; out != last; ++out) { + if (*out == value) return true; + } + return false; +} + +template <> +inline auto find(const char* first, const char* last, char value, + const char*& out) -> bool { + out = + static_cast(memchr(first, value, to_unsigned(last - first))); + return out != nullptr; +} + +// Checks if a value fits in int - used to avoid warnings about comparing +// signed and unsigned integers. +template struct int_checker { + template static auto fits_in_int(T value) -> bool { + return value <= to_unsigned(max_value()); + } + inline static auto fits_in_int(bool) -> bool { return true; } +}; + +template <> struct int_checker { + template static auto fits_in_int(T value) -> bool { + return value >= (std::numeric_limits::min)() && + value <= max_value(); + } + inline static auto fits_in_int(int) -> bool { return true; } +}; + +struct printf_precision_handler { + template ::value)> + auto operator()(T value) -> int { + if (!int_checker::is_signed>::fits_in_int(value)) + report_error("number is too big"); + return max_of(static_cast(value), 0); + } + + template ::value)> + auto operator()(T) -> int { + report_error("precision is not integer"); + return 0; + } +}; + +// An argument visitor that returns true iff arg is a zero integer. +struct is_zero_int { + template ::value)> + auto operator()(T value) -> bool { + return value == 0; + } + + template ::value)> + auto operator()(T) -> bool { + return false; + } +}; + +template struct make_unsigned_or_bool : std::make_unsigned {}; + +template <> struct make_unsigned_or_bool { + using type = bool; +}; + +template class arg_converter { + private: + using char_type = typename Context::char_type; + + basic_format_arg& arg_; + char_type type_; + + public: + arg_converter(basic_format_arg& arg, char_type type) + : arg_(arg), type_(type) {} + + void operator()(bool value) { + if (type_ != 's') operator()(value); + } + + template ::value)> + void operator()(U value) { + bool is_signed = type_ == 'd' || type_ == 'i'; + using target_type = conditional_t::value, U, T>; + if (const_check(sizeof(target_type) <= sizeof(int))) { + // Extra casts are used to silence warnings. + using unsigned_type = typename make_unsigned_or_bool::type; + if (is_signed) + arg_ = static_cast(static_cast(value)); + else + arg_ = static_cast(static_cast(value)); + } else { + // glibc's printf doesn't sign extend arguments of smaller types: + // std::printf("%lld", -42); // prints "4294967254" + // but we don't have to do the same because it's a UB. + if (is_signed) + arg_ = static_cast(value); + else + arg_ = static_cast::type>(value); + } + } + + template ::value)> + void operator()(U) {} // No conversion needed for non-integral types. +}; + +// Converts an integer argument to T for printf, if T is an integral type. +// If T is void, the argument is converted to corresponding signed or unsigned +// type depending on the type specifier: 'd' and 'i' - signed, other - +// unsigned). +template +void convert_arg(basic_format_arg& arg, Char type) { + arg.visit(arg_converter(arg, type)); +} + +// Converts an integer argument to char for printf. +template class char_converter { + private: + basic_format_arg& arg_; + + public: + explicit char_converter(basic_format_arg& arg) : arg_(arg) {} + + template ::value)> + void operator()(T value) { + arg_ = static_cast(value); + } + + template ::value)> + void operator()(T) {} // No conversion needed for non-integral types. +}; + +// An argument visitor that return a pointer to a C string if argument is a +// string or null otherwise. +template struct get_cstring { + template auto operator()(T) -> const Char* { return nullptr; } + auto operator()(const Char* s) -> const Char* { return s; } +}; + +// Checks if an argument is a valid printf width specifier and sets +// left alignment if it is negative. +class printf_width_handler { + private: + format_specs& specs_; + + public: + inline explicit printf_width_handler(format_specs& specs) : specs_(specs) {} + + template ::value)> + auto operator()(T value) -> unsigned { + auto width = static_cast>(value); + if (detail::is_negative(value)) { + specs_.set_align(align::left); + width = 0 - width; + } + unsigned int_max = to_unsigned(max_value()); + if (width > int_max) report_error("number is too big"); + return static_cast(width); + } + + template ::value)> + auto operator()(T) -> unsigned { + report_error("width is not integer"); + return 0; + } +}; + +// Workaround for a bug with the XL compiler when initializing +// printf_arg_formatter's base class. +template +auto make_arg_formatter(basic_appender iter, format_specs& s) + -> arg_formatter { + return {iter, s, locale_ref()}; +} + +// The `printf` argument formatter. +template +class printf_arg_formatter : public arg_formatter { + private: + using base = arg_formatter; + using context_type = basic_printf_context; + + context_type& context_; + + void write_null_pointer(bool is_string = false) { + auto s = this->specs; + s.set_type(presentation_type::none); + write_bytes(this->out, is_string ? "(null)" : "(nil)", s); + } + + template void write(T value) { + detail::write(this->out, value, this->specs, this->locale); + } + + public: + printf_arg_formatter(basic_appender iter, format_specs& s, + context_type& ctx) + : base(make_arg_formatter(iter, s)), context_(ctx) {} + + void operator()(monostate value) { write(value); } + + template ::value)> + void operator()(T value) { + // MSVC2013 fails to compile separate overloads for bool and Char so use + // std::is_same instead. + if (!std::is_same::value) { + write(value); + return; + } + format_specs s = this->specs; + if (s.type() != presentation_type::none && + s.type() != presentation_type::chr) { + return (*this)(static_cast(value)); + } + s.set_sign(sign::none); + s.clear_alt(); + s.set_fill(' '); // Ignore '0' flag for char types. + // align::numeric needs to be overwritten here since the '0' flag is + // ignored for non-numeric types + if (s.align() == align::none || s.align() == align::numeric) + s.set_align(align::right); + detail::write(this->out, static_cast(value), s); + } + + template ::value)> + void operator()(T value) { + write(value); + } + + void operator()(const char* value) { + if (value) + write(value); + else + write_null_pointer(this->specs.type() != presentation_type::pointer); + } + + void operator()(const wchar_t* value) { + if (value) + write(value); + else + write_null_pointer(this->specs.type() != presentation_type::pointer); + } + + void operator()(basic_string_view value) { write(value); } + + void operator()(const void* value) { + if (value) + write(value); + else + write_null_pointer(); + } + + void operator()(typename basic_format_arg::handle handle) { + auto parse_ctx = parse_context({}); + handle.format(parse_ctx, context_); + } +}; + +template +void parse_flags(format_specs& specs, const Char*& it, const Char* end) { + for (; it != end; ++it) { + switch (*it) { + case '-': specs.set_align(align::left); break; + case '+': specs.set_sign(sign::plus); break; + case '0': specs.set_fill('0'); break; + case ' ': + if (specs.sign() != sign::plus) specs.set_sign(sign::space); + break; + case '#': specs.set_alt(); break; + default: return; + } + } +} + +template +auto parse_header(const Char*& it, const Char* end, format_specs& specs, + GetArg get_arg) -> int { + int arg_index = -1; + Char c = *it; + if (c >= '0' && c <= '9') { + // Parse an argument index (if followed by '$') or a width possibly + // preceded with '0' flag(s). + int value = parse_nonnegative_int(it, end, -1); + if (it != end && *it == '$') { // value is an argument index + ++it; + arg_index = value != -1 ? value : max_value(); + } else { + if (c == '0') specs.set_fill('0'); + if (value != 0) { + // Nonzero value means that we parsed width and don't need to + // parse it or flags again, so return now. + if (value == -1) report_error("number is too big"); + specs.width = value; + return arg_index; + } + } + } + parse_flags(specs, it, end); + // Parse width. + if (it != end) { + if (*it >= '0' && *it <= '9') { + specs.width = parse_nonnegative_int(it, end, -1); + if (specs.width == -1) report_error("number is too big"); + } else if (*it == '*') { + ++it; + specs.width = static_cast( + get_arg(-1).visit(detail::printf_width_handler(specs))); + } + } + return arg_index; +} + +inline auto parse_printf_presentation_type(char c, type t, bool& upper) + -> presentation_type { + using pt = presentation_type; + constexpr auto integral_set = sint_set | uint_set | bool_set | char_set; + switch (c) { + case 'd': return in(t, integral_set) ? pt::dec : pt::none; + case 'o': return in(t, integral_set) ? pt::oct : pt::none; + case 'X': upper = true; FMT_FALLTHROUGH; + case 'x': return in(t, integral_set) ? pt::hex : pt::none; + case 'E': upper = true; FMT_FALLTHROUGH; + case 'e': return in(t, float_set) ? pt::exp : pt::none; + case 'F': upper = true; FMT_FALLTHROUGH; + case 'f': return in(t, float_set) ? pt::fixed : pt::none; + case 'G': upper = true; FMT_FALLTHROUGH; + case 'g': return in(t, float_set) ? pt::general : pt::none; + case 'A': upper = true; FMT_FALLTHROUGH; + case 'a': return in(t, float_set) ? pt::hexfloat : pt::none; + case 'c': return in(t, integral_set) ? pt::chr : pt::none; + case 's': return in(t, string_set | cstring_set) ? pt::string : pt::none; + case 'p': return in(t, pointer_set | cstring_set) ? pt::pointer : pt::none; + default: return pt::none; + } +} + +template +void vprintf(buffer& buf, basic_string_view format, + basic_format_args args) { + using iterator = basic_appender; + auto out = iterator(buf); + auto context = basic_printf_context(out, args); + auto parse_ctx = parse_context(format); + + // Returns the argument with specified index or, if arg_index is -1, the next + // argument. + auto get_arg = [&](int arg_index) { + if (arg_index < 0) + arg_index = parse_ctx.next_arg_id(); + else + parse_ctx.check_arg_id(--arg_index); + auto arg = context.arg(arg_index); + if (!arg) report_error("argument not found"); + return arg; + }; + + const Char* start = parse_ctx.begin(); + const Char* end = parse_ctx.end(); + auto it = start; + while (it != end) { + if (!find(it, end, '%', it)) { + it = end; // find leaves it == nullptr if it doesn't find '%'. + break; + } + Char c = *it++; + if (it != end && *it == c) { + write(out, basic_string_view(start, to_unsigned(it - start))); + start = ++it; + continue; + } + write(out, basic_string_view(start, to_unsigned(it - 1 - start))); + + auto specs = format_specs(); + specs.set_align(align::right); + + // Parse argument index, flags and width. + int arg_index = parse_header(it, end, specs, get_arg); + if (arg_index == 0) report_error("argument not found"); + + // Parse precision. + if (it != end && *it == '.') { + ++it; + c = it != end ? *it : 0; + if ('0' <= c && c <= '9') { + specs.precision = parse_nonnegative_int(it, end, 0); + } else if (c == '*') { + ++it; + specs.precision = + static_cast(get_arg(-1).visit(printf_precision_handler())); + } else { + specs.precision = 0; + } + } + + auto arg = get_arg(arg_index); + // For d, i, o, u, x, and X conversion specifiers, if a precision is + // specified, the '0' flag is ignored + if (specs.precision >= 0 && is_integral_type(arg.type())) { + // Ignore '0' for non-numeric types or if '-' present. + specs.set_fill(' '); + } + if (specs.precision >= 0 && arg.type() == type::cstring_type) { + auto str = arg.visit(get_cstring()); + auto str_end = str + specs.precision; + auto nul = std::find(str, str_end, Char()); + auto sv = basic_string_view( + str, to_unsigned(nul != str_end ? nul - str : specs.precision)); + arg = sv; + } + if (specs.alt() && arg.visit(is_zero_int())) specs.clear_alt(); + if (specs.fill_unit() == '0') { + if (is_arithmetic_type(arg.type()) && specs.align() != align::left) { + specs.set_align(align::numeric); + } else { + // Ignore '0' flag for non-numeric types or if '-' flag is also present. + specs.set_fill(' '); + } + } + + // Parse length and convert the argument to the required type. + c = it != end ? *it++ : 0; + Char t = it != end ? *it : 0; + switch (c) { + case 'h': + if (t == 'h') { + ++it; + t = it != end ? *it : 0; + convert_arg(arg, t); + } else { + convert_arg(arg, t); + } + break; + case 'l': + if (t == 'l') { + ++it; + t = it != end ? *it : 0; + convert_arg(arg, t); + } else { + convert_arg(arg, t); + } + break; + case 'j': convert_arg(arg, t); break; + case 'z': convert_arg(arg, t); break; + case 't': convert_arg(arg, t); break; + case 'L': + // printf produces garbage when 'L' is omitted for long double, no + // need to do the same. + break; + default: --it; convert_arg(arg, c); + } + + // Parse type. + if (it == end) report_error("invalid format string"); + char type = static_cast(*it++); + if (is_integral_type(arg.type())) { + // Normalize type. + switch (type) { + case 'i': + case 'u': type = 'd'; break; + case 'c': + arg.visit(char_converter>(arg)); + break; + } + } + bool upper = false; + specs.set_type(parse_printf_presentation_type(type, arg.type(), upper)); + if (specs.type() == presentation_type::none) + report_error("invalid format specifier"); + if (upper) specs.set_upper(); + + start = it; + + // Format argument. + arg.visit(printf_arg_formatter(out, specs, context)); + } + write(out, basic_string_view(start, to_unsigned(it - start))); +} +} // namespace detail + +using printf_context = basic_printf_context; +using wprintf_context = basic_printf_context; + +using printf_args = basic_format_args; +using wprintf_args = basic_format_args; + +/// Constructs an `format_arg_store` object that contains references to +/// arguments and can be implicitly converted to `printf_args`. +template +inline auto make_printf_args(T&... args) + -> decltype(fmt::make_format_args>(args...)) { + return fmt::make_format_args>(args...); +} + +template struct vprintf_args { + using type = basic_format_args>; +}; + +template +inline auto vsprintf(basic_string_view fmt, + typename vprintf_args::type args) + -> std::basic_string { + auto buf = basic_memory_buffer(); + detail::vprintf(buf, fmt, args); + return {buf.data(), buf.size()}; +} + +/** + * Formats `args` according to specifications in `fmt` and returns the result + * as as string. + * + * **Example**: + * + * std::string message = fmt::sprintf("The answer is %d", 42); + */ +template +inline auto sprintf(string_view fmt, const T&... args) -> std::string { + return vsprintf(fmt, make_printf_args(args...)); +} +template +FMT_DEPRECATED auto sprintf(basic_string_view fmt, const T&... args) + -> std::wstring { + return vsprintf(fmt, make_printf_args(args...)); +} + +template +auto vfprintf(std::FILE* f, basic_string_view fmt, + typename vprintf_args::type args) -> int { + auto buf = basic_memory_buffer(); + detail::vprintf(buf, fmt, args); + size_t size = buf.size(); + return std::fwrite(buf.data(), sizeof(Char), size, f) < size + ? -1 + : static_cast(size); +} + +/** + * Formats `args` according to specifications in `fmt` and writes the output + * to `f`. + * + * **Example**: + * + * fmt::fprintf(stderr, "Don't %s!", "panic"); + */ +template +inline auto fprintf(std::FILE* f, string_view fmt, const T&... args) -> int { + return vfprintf(f, fmt, make_printf_args(args...)); +} +template +FMT_DEPRECATED auto fprintf(std::FILE* f, basic_string_view fmt, + const T&... args) -> int { + return vfprintf(f, fmt, make_printf_args(args...)); +} + +/** + * Formats `args` according to specifications in `fmt` and writes the output + * to `stdout`. + * + * **Example**: + * + * fmt::printf("Elapsed time: %.2f seconds", 1.23); + */ +template +inline auto printf(string_view fmt, const T&... args) -> int { + return vfprintf(stdout, fmt, make_printf_args(args...)); +} + +FMT_END_EXPORT +FMT_END_NAMESPACE + +#endif // FMT_PRINTF_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ranges.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ranges.h new file mode 100644 index 0000000000000000000000000000000000000000..f8df05f9a4517bb9add87f261a6c29b9c7ec19f6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ranges.h @@ -0,0 +1,856 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - range and tuple support +// +// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_RANGES_H_ +#define FMT_RANGES_H_ + +#ifndef FMT_MODULE +# include +# include +# include +# include +# include +#endif + +#include "format.h" + +#if FMT_HAS_CPP_ATTRIBUTE(clang::lifetimebound) +# define FMT_LIFETIMEBOUND [[clang::lifetimebound]] +#else +# define FMT_LIFETIMEBOUND +#endif +FMT_PRAGMA_CLANG(diagnostic error "-Wreturn-stack-address") + +FMT_BEGIN_NAMESPACE + +FMT_EXPORT +enum class range_format { disabled, map, set, sequence, string, debug_string }; + +namespace detail { + +template class is_map { + template static auto check(U*) -> typename U::mapped_type; + template static void check(...); + + public: + static constexpr bool value = + !std::is_void(nullptr))>::value; +}; + +template class is_set { + template static auto check(U*) -> typename U::key_type; + template static void check(...); + + public: + static constexpr bool value = + !std::is_void(nullptr))>::value && !is_map::value; +}; + +// C array overload +template +auto range_begin(const T (&arr)[N]) -> const T* { + return arr; +} +template auto range_end(const T (&arr)[N]) -> const T* { + return arr + N; +} + +template +struct has_member_fn_begin_end_t : std::false_type {}; + +template +struct has_member_fn_begin_end_t().begin()), + decltype(std::declval().end())>> + : std::true_type {}; + +// Member function overloads. +template +auto range_begin(T&& rng) -> decltype(static_cast(rng).begin()) { + return static_cast(rng).begin(); +} +template +auto range_end(T&& rng) -> decltype(static_cast(rng).end()) { + return static_cast(rng).end(); +} + +// ADL overloads. Only participate in overload resolution if member functions +// are not found. +template +auto range_begin(T&& rng) + -> enable_if_t::value, + decltype(begin(static_cast(rng)))> { + return begin(static_cast(rng)); +} +template +auto range_end(T&& rng) -> enable_if_t::value, + decltype(end(static_cast(rng)))> { + return end(static_cast(rng)); +} + +template +struct has_const_begin_end : std::false_type {}; +template +struct has_mutable_begin_end : std::false_type {}; + +template +struct has_const_begin_end< + T, void_t&>())), + decltype(detail::range_end( + std::declval&>()))>> + : std::true_type {}; + +template +struct has_mutable_begin_end< + T, void_t())), + decltype(detail::range_end(std::declval())), + // the extra int here is because older versions of MSVC don't + // SFINAE properly unless there are distinct types + int>> : std::true_type {}; + +template struct is_range_ : std::false_type {}; +template +struct is_range_ + : std::integral_constant::value || + has_mutable_begin_end::value)> {}; + +// tuple_size and tuple_element check. +template class is_tuple_like_ { + template ::type> + static auto check(U* p) -> decltype(std::tuple_size::value, 0); + template static void check(...); + + public: + static constexpr bool value = + !std::is_void(nullptr))>::value; +}; + +// Check for integer_sequence +#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900 +template +using integer_sequence = std::integer_sequence; +template using index_sequence = std::index_sequence; +template using make_index_sequence = std::make_index_sequence; +#else +template struct integer_sequence { + using value_type = T; + + static FMT_CONSTEXPR auto size() -> size_t { return sizeof...(N); } +}; + +template using index_sequence = integer_sequence; + +template +struct make_integer_sequence : make_integer_sequence {}; +template +struct make_integer_sequence : integer_sequence {}; + +template +using make_index_sequence = make_integer_sequence; +#endif + +template +using tuple_index_sequence = make_index_sequence::value>; + +template ::value> +class is_tuple_formattable_ { + public: + static constexpr bool value = false; +}; +template class is_tuple_formattable_ { + template + static auto all_true(index_sequence, + integer_sequence= 0)...>) -> std::true_type; + static auto all_true(...) -> std::false_type; + + template + static auto check(index_sequence) -> decltype(all_true( + index_sequence{}, + integer_sequence::type, + C>::value)...>{})); + + public: + static constexpr bool value = + decltype(check(tuple_index_sequence{}))::value; +}; + +template +FMT_CONSTEXPR void for_each(index_sequence, Tuple&& t, F&& f) { + using std::get; + // Using a free function get(Tuple) now. + const int unused[] = {0, ((void)f(get(t)), 0)...}; + ignore_unused(unused); +} + +template +FMT_CONSTEXPR void for_each(Tuple&& t, F&& f) { + for_each(tuple_index_sequence>(), + std::forward(t), std::forward(f)); +} + +template +void for_each2(index_sequence, Tuple1&& t1, Tuple2&& t2, F&& f) { + using std::get; + const int unused[] = {0, ((void)f(get(t1), get(t2)), 0)...}; + ignore_unused(unused); +} + +template +void for_each2(Tuple1&& t1, Tuple2&& t2, F&& f) { + for_each2(tuple_index_sequence>(), + std::forward(t1), std::forward(t2), + std::forward(f)); +} + +namespace tuple { +// Workaround a bug in MSVC 2019 (v140). +template +using result_t = std::tuple, Char>...>; + +using std::get; +template +auto get_formatters(index_sequence) + -> result_t(std::declval()))...>; +} // namespace tuple + +#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920 +// Older MSVC doesn't get the reference type correctly for arrays. +template struct range_reference_type_impl { + using type = decltype(*detail::range_begin(std::declval())); +}; + +template struct range_reference_type_impl { + using type = T&; +}; + +template +using range_reference_type = typename range_reference_type_impl::type; +#else +template +using range_reference_type = + decltype(*detail::range_begin(std::declval())); +#endif + +// We don't use the Range's value_type for anything, but we do need the Range's +// reference type, with cv-ref stripped. +template +using uncvref_type = remove_cvref_t>; + +template +struct range_format_kind_ + : std::integral_constant, T>::value + ? range_format::disabled + : is_map::value ? range_format::map + : is_set::value ? range_format::set + : range_format::sequence> {}; + +template +using range_format_constant = std::integral_constant; + +// These are not generic lambdas for compatibility with C++11. +template struct parse_empty_specs { + template FMT_CONSTEXPR void operator()(Formatter& f) { + f.parse(ctx); + detail::maybe_set_debug_format(f, true); + } + parse_context& ctx; +}; +template struct format_tuple_element { + using char_type = typename FormatContext::char_type; + + template + void operator()(const formatter& f, const T& v) { + if (i > 0) ctx.advance_to(detail::copy(separator, ctx.out())); + ctx.advance_to(f.format(v, ctx)); + ++i; + } + + int i; + FormatContext& ctx; + basic_string_view separator; +}; + +} // namespace detail + +FMT_EXPORT +template struct is_tuple_like { + static constexpr bool value = + detail::is_tuple_like_::value && !detail::is_range_::value; +}; + +FMT_EXPORT +template struct is_tuple_formattable { + static constexpr bool value = detail::is_tuple_formattable_::value; +}; + +template +struct formatter::value && + fmt::is_tuple_formattable::value>> { + private: + decltype(detail::tuple::get_formatters( + detail::tuple_index_sequence())) formatters_; + + basic_string_view separator_ = detail::string_literal{}; + basic_string_view opening_bracket_ = + detail::string_literal{}; + basic_string_view closing_bracket_ = + detail::string_literal{}; + + public: + FMT_CONSTEXPR formatter() {} + + FMT_CONSTEXPR void set_separator(basic_string_view sep) { + separator_ = sep; + } + + FMT_CONSTEXPR void set_brackets(basic_string_view open, + basic_string_view close) { + opening_bracket_ = open; + closing_bracket_ = close; + } + + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(); + auto end = ctx.end(); + if (it != end && detail::to_ascii(*it) == 'n') { + ++it; + set_brackets({}, {}); + set_separator({}); + } + if (it != end && *it != '}') report_error("invalid format specifier"); + ctx.advance_to(it); + detail::for_each(formatters_, detail::parse_empty_specs{ctx}); + return it; + } + + template + auto format(const Tuple& value, FormatContext& ctx) const + -> decltype(ctx.out()) { + ctx.advance_to(detail::copy(opening_bracket_, ctx.out())); + detail::for_each2( + formatters_, value, + detail::format_tuple_element{0, ctx, separator_}); + return detail::copy(closing_bracket_, ctx.out()); + } +}; + +FMT_EXPORT +template struct is_range { + static constexpr bool value = + detail::is_range_::value && !detail::has_to_string_view::value; +}; + +namespace detail { + +template +using range_formatter_type = formatter, Char>; + +template +using maybe_const_range = + conditional_t::value, const R, R>; + +template +struct is_formattable_delayed + : is_formattable>, Char> {}; +} // namespace detail + +template struct conjunction : std::true_type {}; +template struct conjunction

: P {}; +template +struct conjunction + : conditional_t, P1> {}; + +FMT_EXPORT +template +struct range_formatter; + +template +struct range_formatter< + T, Char, + enable_if_t>, + is_formattable>::value>> { + private: + detail::range_formatter_type underlying_; + basic_string_view separator_ = detail::string_literal{}; + basic_string_view opening_bracket_ = + detail::string_literal{}; + basic_string_view closing_bracket_ = + detail::string_literal{}; + bool is_debug = false; + + template ::value)> + auto write_debug_string(Output& out, It it, Sentinel end) const -> Output { + auto buf = basic_memory_buffer(); + for (; it != end; ++it) buf.push_back(*it); + auto specs = format_specs(); + specs.set_type(presentation_type::debug); + return detail::write( + out, basic_string_view(buf.data(), buf.size()), specs); + } + + template ::value)> + auto write_debug_string(Output& out, It, Sentinel) const -> Output { + return out; + } + + public: + FMT_CONSTEXPR range_formatter() {} + + FMT_CONSTEXPR auto underlying() -> detail::range_formatter_type& { + return underlying_; + } + + FMT_CONSTEXPR void set_separator(basic_string_view sep) { + separator_ = sep; + } + + FMT_CONSTEXPR void set_brackets(basic_string_view open, + basic_string_view close) { + opening_bracket_ = open; + closing_bracket_ = close; + } + + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(); + auto end = ctx.end(); + detail::maybe_set_debug_format(underlying_, true); + if (it == end) return underlying_.parse(ctx); + + switch (detail::to_ascii(*it)) { + case 'n': + set_brackets({}, {}); + ++it; + break; + case '?': + is_debug = true; + set_brackets({}, {}); + ++it; + if (it == end || *it != 's') report_error("invalid format specifier"); + FMT_FALLTHROUGH; + case 's': + if (!std::is_same::value) + report_error("invalid format specifier"); + if (!is_debug) { + set_brackets(detail::string_literal{}, + detail::string_literal{}); + set_separator({}); + detail::maybe_set_debug_format(underlying_, false); + } + ++it; + return it; + } + + if (it != end && *it != '}') { + if (*it != ':') report_error("invalid format specifier"); + detail::maybe_set_debug_format(underlying_, false); + ++it; + } + + ctx.advance_to(it); + return underlying_.parse(ctx); + } + + template + auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) { + auto out = ctx.out(); + auto it = detail::range_begin(range); + auto end = detail::range_end(range); + if (is_debug) return write_debug_string(out, std::move(it), end); + + out = detail::copy(opening_bracket_, out); + int i = 0; + for (; it != end; ++it) { + if (i > 0) out = detail::copy(separator_, out); + ctx.advance_to(out); + auto&& item = *it; // Need an lvalue + out = underlying_.format(item, ctx); + ++i; + } + out = detail::copy(closing_bracket_, out); + return out; + } +}; + +FMT_EXPORT +template +struct range_format_kind + : conditional_t< + is_range::value, detail::range_format_kind_, + std::integral_constant> {}; + +template +struct formatter< + R, Char, + enable_if_t::value != range_format::disabled && + range_format_kind::value != range_format::map && + range_format_kind::value != range_format::string && + range_format_kind::value != range_format::debug_string>, + detail::is_formattable_delayed>::value>> { + private: + using range_type = detail::maybe_const_range; + range_formatter, Char> range_formatter_; + + public: + using nonlocking = void; + + FMT_CONSTEXPR formatter() { + if (detail::const_check(range_format_kind::value != + range_format::set)) + return; + range_formatter_.set_brackets(detail::string_literal{}, + detail::string_literal{}); + } + + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return range_formatter_.parse(ctx); + } + + template + auto format(range_type& range, FormatContext& ctx) const + -> decltype(ctx.out()) { + return range_formatter_.format(range, ctx); + } +}; + +// A map formatter. +template +struct formatter< + R, Char, + enable_if_t::value == range_format::map>, + detail::is_formattable_delayed>::value>> { + private: + using map_type = detail::maybe_const_range; + using element_type = detail::uncvref_type; + + decltype(detail::tuple::get_formatters( + detail::tuple_index_sequence())) formatters_; + bool no_delimiters_ = false; + + public: + FMT_CONSTEXPR formatter() {} + + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + auto it = ctx.begin(); + auto end = ctx.end(); + if (it != end) { + if (detail::to_ascii(*it) == 'n') { + no_delimiters_ = true; + ++it; + } + if (it != end && *it != '}') { + if (*it != ':') report_error("invalid format specifier"); + ++it; + } + ctx.advance_to(it); + } + detail::for_each(formatters_, detail::parse_empty_specs{ctx}); + return it; + } + + template + auto format(map_type& map, FormatContext& ctx) const -> decltype(ctx.out()) { + auto out = ctx.out(); + basic_string_view open = detail::string_literal{}; + if (!no_delimiters_) out = detail::copy(open, out); + int i = 0; + basic_string_view sep = detail::string_literal{}; + for (auto&& value : map) { + if (i > 0) out = detail::copy(sep, out); + ctx.advance_to(out); + detail::for_each2(formatters_, value, + detail::format_tuple_element{ + 0, ctx, detail::string_literal{}}); + ++i; + } + basic_string_view close = detail::string_literal{}; + if (!no_delimiters_) out = detail::copy(close, out); + return out; + } +}; + +// A (debug_)string formatter. +template +struct formatter< + R, Char, + enable_if_t::value == range_format::string || + range_format_kind::value == + range_format::debug_string>> { + private: + using range_type = detail::maybe_const_range; + using string_type = + conditional_t, + decltype(detail::range_begin(std::declval())), + decltype(detail::range_end(std::declval()))>::value, + detail::std_string_view, std::basic_string>; + + formatter underlying_; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return underlying_.parse(ctx); + } + + template + auto format(range_type& range, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + if (detail::const_check(range_format_kind::value == + range_format::debug_string)) + *out++ = '"'; + out = underlying_.format( + string_type{detail::range_begin(range), detail::range_end(range)}, ctx); + if (detail::const_check(range_format_kind::value == + range_format::debug_string)) + *out++ = '"'; + return out; + } +}; + +template +struct join_view : detail::view { + It begin; + Sentinel end; + basic_string_view sep; + + join_view(It b, Sentinel e, basic_string_view s) + : begin(std::move(b)), end(e), sep(s) {} +}; + +template +struct formatter, Char> { + private: + using value_type = +#ifdef __cpp_lib_ranges + std::iter_value_t; +#else + typename std::iterator_traits::value_type; +#endif + formatter, Char> value_formatter_; + + using view = conditional_t::value, + const join_view, + join_view>; + + public: + using nonlocking = void; + + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return value_formatter_.parse(ctx); + } + + template + auto format(view& value, FormatContext& ctx) const -> decltype(ctx.out()) { + using iter = + conditional_t::value, It, It&>; + iter it = value.begin; + auto out = ctx.out(); + if (it == value.end) return out; + out = value_formatter_.format(*it, ctx); + ++it; + while (it != value.end) { + out = detail::copy(value.sep.begin(), value.sep.end(), out); + ctx.advance_to(out); + out = value_formatter_.format(*it, ctx); + ++it; + } + return out; + } +}; + +FMT_EXPORT +template struct tuple_join_view : detail::view { + const Tuple& tuple; + basic_string_view sep; + + tuple_join_view(const Tuple& t, basic_string_view s) + : tuple(t), sep{s} {} +}; + +// Define FMT_TUPLE_JOIN_SPECIFIERS to enable experimental format specifiers +// support in tuple_join. It is disabled by default because of issues with +// the dynamic width and precision. +#ifndef FMT_TUPLE_JOIN_SPECIFIERS +# define FMT_TUPLE_JOIN_SPECIFIERS 0 +#endif + +template +struct formatter, Char, + enable_if_t::value>> { + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return do_parse(ctx, std::tuple_size()); + } + + template + auto format(const tuple_join_view& value, + FormatContext& ctx) const -> typename FormatContext::iterator { + return do_format(value, ctx, std::tuple_size()); + } + + private: + decltype(detail::tuple::get_formatters( + detail::tuple_index_sequence())) formatters_; + + FMT_CONSTEXPR auto do_parse(parse_context& ctx, + std::integral_constant) + -> const Char* { + return ctx.begin(); + } + + template + FMT_CONSTEXPR auto do_parse(parse_context& ctx, + std::integral_constant) + -> const Char* { + auto end = ctx.begin(); +#if FMT_TUPLE_JOIN_SPECIFIERS + end = std::get::value - N>(formatters_).parse(ctx); + if (N > 1) { + auto end1 = do_parse(ctx, std::integral_constant()); + if (end != end1) + report_error("incompatible format specs for tuple elements"); + } +#endif + return end; + } + + template + auto do_format(const tuple_join_view&, FormatContext& ctx, + std::integral_constant) const -> + typename FormatContext::iterator { + return ctx.out(); + } + + template + auto do_format(const tuple_join_view& value, FormatContext& ctx, + std::integral_constant) const -> + typename FormatContext::iterator { + using std::get; + auto out = + std::get::value - N>(formatters_) + .format(get::value - N>(value.tuple), ctx); + if (N <= 1) return out; + out = detail::copy(value.sep, out); + ctx.advance_to(out); + return do_format(value, ctx, std::integral_constant()); + } +}; + +namespace detail { +// Check if T has an interface like a container adaptor (e.g. std::stack, +// std::queue, std::priority_queue). +template class is_container_adaptor_like { + template static auto check(U* p) -> typename U::container_type; + template static void check(...); + + public: + static constexpr bool value = + !std::is_void(nullptr))>::value; +}; + +template struct all { + const Container& c; + auto begin() const -> typename Container::const_iterator { return c.begin(); } + auto end() const -> typename Container::const_iterator { return c.end(); } +}; +} // namespace detail + +template +struct formatter< + T, Char, + enable_if_t, + bool_constant::value == + range_format::disabled>>::value>> + : formatter, Char> { + using all = detail::all; + template + auto format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) { + struct getter : T { + static auto get(const T& v) -> all { + return {v.*(&getter::c)}; // Access c through the derived class. + } + }; + return formatter::format(getter::get(value), ctx); + } +}; + +FMT_BEGIN_EXPORT + +/// Returns a view that formats the iterator range `[begin, end)` with elements +/// separated by `sep`. +template +auto join(It begin, Sentinel end, string_view sep) -> join_view { + return {std::move(begin), end, sep}; +} + +/** + * Returns a view that formats `range` with elements separated by `sep`. + * + * **Example**: + * + * auto v = std::vector{1, 2, 3}; + * fmt::print("{}", fmt::join(v, ", ")); + * // Output: 1, 2, 3 + * + * `fmt::join` applies passed format specifiers to the range elements: + * + * fmt::print("{:02}", fmt::join(v, ", ")); + * // Output: 01, 02, 03 + */ +template ::value)> +auto join(Range&& r, string_view sep) + -> join_view { + return {detail::range_begin(r), detail::range_end(r), sep}; +} + +/** + * Returns an object that formats `std::tuple` with elements separated by `sep`. + * + * **Example**: + * + * auto t = std::tuple(1, 'a'); + * fmt::print("{}", fmt::join(t, ", ")); + * // Output: 1, a + */ +template ::value)> +FMT_CONSTEXPR auto join(const Tuple& tuple FMT_LIFETIMEBOUND, string_view sep) + -> tuple_join_view { + return {tuple, sep}; +} + +/** + * Returns an object that formats `std::initializer_list` with elements + * separated by `sep`. + * + * **Example**: + * + * fmt::print("{}", fmt::join({1, 2, 3}, ", ")); + * // Output: "1, 2, 3" + */ +template +auto join(std::initializer_list list, string_view sep) + -> join_view { + return join(std::begin(list), std::end(list), sep); +} + +FMT_END_EXPORT +FMT_END_NAMESPACE + +#endif // FMT_RANGES_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/std.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/std.h new file mode 100644 index 0000000000000000000000000000000000000000..1c166432291fad18366482ec158f73c137e84806 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/std.h @@ -0,0 +1,732 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - formatters for standard library types +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_STD_H_ +#define FMT_STD_H_ + +#include "format.h" +#include "ostream.h" + +#ifndef FMT_MODULE +# include +# include +# include +# include +# include // std::reference_wrapper +# include +# include +# include +# include // std::type_info +# include // std::make_index_sequence + +// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC. +# if FMT_CPLUSPLUS >= 201703L +# if FMT_HAS_INCLUDE() && \ + (!defined(FMT_CPP_LIB_FILESYSTEM) || FMT_CPP_LIB_FILESYSTEM != 0) +# include +# endif +# if FMT_HAS_INCLUDE() +# include +# endif +# if FMT_HAS_INCLUDE() +# include +# endif +# endif +// Use > instead of >= in the version check because may be +// available after C++17 but before C++20 is marked as implemented. +# if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE() +# include +# endif +# if FMT_CPLUSPLUS > 202002L && FMT_HAS_INCLUDE() +# include +# endif +#endif // FMT_MODULE + +#if FMT_HAS_INCLUDE() +# include +#endif + +// GCC 4 does not support FMT_HAS_INCLUDE. +#if FMT_HAS_INCLUDE() || defined(__GLIBCXX__) +# include +// Android NDK with gabi++ library on some architectures does not implement +// abi::__cxa_demangle(). +# ifndef __GABIXX_CXXABI_H__ +# define FMT_HAS_ABI_CXA_DEMANGLE +# endif +#endif + +#ifdef FMT_CPP_LIB_FILESYSTEM +// Use the provided definition. +#elif defined(__cpp_lib_filesystem) +# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem +#else +# define FMT_CPP_LIB_FILESYSTEM 0 +#endif + +#ifdef FMT_CPP_LIB_VARIANT +// Use the provided definition. +#elif defined(__cpp_lib_variant) +# define FMT_CPP_LIB_VARIANT __cpp_lib_variant +#else +# define FMT_CPP_LIB_VARIANT 0 +#endif + +FMT_BEGIN_NAMESPACE +namespace detail { + +#if FMT_CPP_LIB_FILESYSTEM + +template +auto get_path_string(const std::filesystem::path& p, + const std::basic_string& native) { + if constexpr (std::is_same_v && std::is_same_v) + return to_utf8(native, to_utf8_error_policy::replace); + else + return p.string(); +} + +template +void write_escaped_path(basic_memory_buffer& quoted, + const std::filesystem::path& p, + const std::basic_string& native) { + if constexpr (std::is_same_v && + std::is_same_v) { + auto buf = basic_memory_buffer(); + write_escaped_string(std::back_inserter(buf), native); + bool valid = to_utf8::convert(quoted, {buf.data(), buf.size()}); + FMT_ASSERT(valid, "invalid utf16"); + } else if constexpr (std::is_same_v) { + write_escaped_string( + std::back_inserter(quoted), native); + } else { + write_escaped_string(std::back_inserter(quoted), p.string()); + } +} + +#endif // FMT_CPP_LIB_FILESYSTEM + +#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT + +template +auto write_escaped_alternative(OutputIt out, const T& v, FormatContext& ctx) + -> OutputIt { + if constexpr (has_to_string_view::value) + return write_escaped_string(out, detail::to_string_view(v)); + if constexpr (std::is_same_v) return write_escaped_char(out, v); + + formatter, Char> underlying; + maybe_set_debug_format(underlying, true); + return underlying.format(v, ctx); +} +#endif + +#if FMT_CPP_LIB_VARIANT + +template struct is_variant_like_ : std::false_type {}; +template +struct is_variant_like_> : std::true_type {}; + +template class is_variant_formattable { + template + static auto check(std::index_sequence) -> std::conjunction< + is_formattable, Char>...>; + + public: + static constexpr bool value = decltype(check( + std::make_index_sequence::value>()))::value; +}; + +#endif // FMT_CPP_LIB_VARIANT + +#if FMT_USE_RTTI +inline auto normalize_libcxx_inline_namespaces(string_view demangled_name_view, + char* begin) -> string_view { + // Normalization of stdlib inline namespace names. + // libc++ inline namespaces. + // std::__1::* -> std::* + // std::__1::__fs::* -> std::* + // libstdc++ inline namespaces. + // std::__cxx11::* -> std::* + // std::filesystem::__cxx11::* -> std::filesystem::* + if (demangled_name_view.starts_with("std::")) { + char* to = begin + 5; // std:: + for (const char *from = to, *end = begin + demangled_name_view.size(); + from < end;) { + // This is safe, because demangled_name is NUL-terminated. + if (from[0] == '_' && from[1] == '_') { + const char* next = from + 1; + while (next < end && *next != ':') next++; + if (next[0] == ':' && next[1] == ':') { + from = next + 2; + continue; + } + } + *to++ = *from++; + } + demangled_name_view = {begin, detail::to_unsigned(to - begin)}; + } + return demangled_name_view; +} + +template +auto normalize_msvc_abi_name(string_view abi_name_view, OutputIt out) + -> OutputIt { + const string_view demangled_name(abi_name_view); + for (size_t i = 0; i < demangled_name.size(); ++i) { + auto sub = demangled_name; + sub.remove_prefix(i); + if (sub.starts_with("enum ")) { + i += 4; + continue; + } + if (sub.starts_with("class ") || sub.starts_with("union ")) { + i += 5; + continue; + } + if (sub.starts_with("struct ")) { + i += 6; + continue; + } + if (*sub.begin() != ' ') *out++ = *sub.begin(); + } + return out; +} + +template +auto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt { +# ifdef FMT_HAS_ABI_CXA_DEMANGLE + int status = 0; + size_t size = 0; + std::unique_ptr demangled_name_ptr( + abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &free); + + string_view demangled_name_view; + if (demangled_name_ptr) { + demangled_name_view = normalize_libcxx_inline_namespaces( + demangled_name_ptr.get(), demangled_name_ptr.get()); + } else { + demangled_name_view = string_view(ti.name()); + } + return detail::write_bytes(out, demangled_name_view); +# elif FMT_MSC_VERSION && defined(_MSVC_STL_UPDATE) + return normalize_msvc_abi_name(ti.name(), out); +# elif FMT_MSC_VERSION && defined(_LIBCPP_VERSION) + const string_view demangled_name = ti.name(); + std::string name_copy(demangled_name.size(), '\0'); + // normalize_msvc_abi_name removes class, struct, union etc that MSVC has in + // front of types + name_copy.erase(normalize_msvc_abi_name(demangled_name, name_copy.begin()), + name_copy.end()); + // normalize_libcxx_inline_namespaces removes the inline __1, __2, etc + // namespaces libc++ uses for ABI versioning On MSVC ABI + libc++ + // environments, we need to eliminate both of them. + const string_view normalized_name = + normalize_libcxx_inline_namespaces(name_copy, name_copy.data()); + return detail::write_bytes(out, normalized_name); +# else + return detail::write_bytes(out, string_view(ti.name())); +# endif +} + +#endif // FMT_USE_RTTI + +template +struct has_flip : std::false_type {}; + +template +struct has_flip().flip())>> + : std::true_type {}; + +template struct is_bit_reference_like { + static constexpr bool value = std::is_convertible::value && + std::is_nothrow_assignable::value && + has_flip::value; +}; + +// Workaround for libc++ incompatibility with C++ standard. +// According to the Standard, `bitset::operator[] const` returns bool. +#if defined(_LIBCPP_VERSION) && !defined(FMT_IMPORT_STD) +template +struct is_bit_reference_like> { + static constexpr bool value = true; +}; +#endif + +template +struct has_format_as : std::false_type {}; +template +struct has_format_as()))>> + : std::true_type {}; + +template +struct has_format_as_member : std::false_type {}; +template +struct has_format_as_member< + T, void_t::format_as(std::declval()))>> + : std::true_type {}; + +} // namespace detail + +template +auto ptr(const std::unique_ptr& p) -> const void* { + return p.get(); +} +template auto ptr(const std::shared_ptr& p) -> const void* { + return p.get(); +} + +#if FMT_CPP_LIB_FILESYSTEM + +template struct formatter { + private: + format_specs specs_; + detail::arg_ref width_ref_; + bool debug_ = false; + char path_type_ = 0; + + public: + FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; } + + FMT_CONSTEXPR auto parse(parse_context& ctx) { + auto it = ctx.begin(), end = ctx.end(); + if (it == end) return it; + + it = detail::parse_align(it, end, specs_); + if (it == end) return it; + + Char c = *it; + if ((c >= '0' && c <= '9') || c == '{') + it = detail::parse_width(it, end, specs_, width_ref_, ctx); + if (it != end && *it == '?') { + debug_ = true; + ++it; + } + if (it != end && (*it == 'g')) path_type_ = detail::to_ascii(*it++); + return it; + } + + template + auto format(const std::filesystem::path& p, FormatContext& ctx) const { + auto specs = specs_; + auto path_string = + !path_type_ ? p.native() + : p.generic_string(); + + detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, + ctx); + if (!debug_) { + auto s = detail::get_path_string(p, path_string); + return detail::write(ctx.out(), basic_string_view(s), specs); + } + auto quoted = basic_memory_buffer(); + detail::write_escaped_path(quoted, p, path_string); + return detail::write(ctx.out(), + basic_string_view(quoted.data(), quoted.size()), + specs); + } +}; + +class path : public std::filesystem::path { + public: + auto display_string() const -> std::string { + const std::filesystem::path& base = *this; + return fmt::format(FMT_STRING("{}"), base); + } + auto system_string() const -> std::string { return string(); } + + auto generic_display_string() const -> std::string { + const std::filesystem::path& base = *this; + return fmt::format(FMT_STRING("{:g}"), base); + } + auto generic_system_string() const -> std::string { return generic_string(); } +}; + +#endif // FMT_CPP_LIB_FILESYSTEM + +template +struct formatter, Char> + : nested_formatter, Char> { + private: + // This is a functor because C++11 doesn't support generic lambdas. + struct writer { + const std::bitset& bs; + + template + FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt { + for (auto pos = N; pos > 0; --pos) + out = detail::write(out, bs[pos - 1] ? Char('1') : Char('0')); + return out; + } + }; + + public: + template + auto format(const std::bitset& bs, FormatContext& ctx) const + -> decltype(ctx.out()) { + return this->write_padded(ctx, writer{bs}); + } +}; + +template +struct formatter : basic_ostream_formatter {}; + +#ifdef __cpp_lib_optional +template +struct formatter, Char, + std::enable_if_t::value>> { + private: + formatter, Char> underlying_; + static constexpr basic_string_view optional = + detail::string_literal{}; + static constexpr basic_string_view none = + detail::string_literal{}; + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) { + detail::maybe_set_debug_format(underlying_, true); + return underlying_.parse(ctx); + } + + template + auto format(const std::optional& opt, FormatContext& ctx) const + -> decltype(ctx.out()) { + if (!opt) return detail::write(ctx.out(), none); + + auto out = ctx.out(); + out = detail::write(out, optional); + ctx.advance_to(out); + out = underlying_.format(*opt, ctx); + return detail::write(out, ')'); + } +}; +#endif // __cpp_lib_optional + +#ifdef __cpp_lib_expected +template +struct formatter, Char, + std::enable_if_t<(std::is_void::value || + is_formattable::value) && + is_formattable::value>> { + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return ctx.begin(); + } + + template + auto format(const std::expected& value, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + + if (value.has_value()) { + out = detail::write(out, "expected("); + if constexpr (!std::is_void::value) + out = detail::write_escaped_alternative(out, *value, ctx); + } else { + out = detail::write(out, "unexpected("); + out = detail::write_escaped_alternative(out, value.error(), ctx); + } + *out++ = ')'; + return out; + } +}; +#endif // __cpp_lib_expected + +#ifdef __cpp_lib_source_location +template <> struct formatter { + FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); } + + template + auto format(const std::source_location& loc, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + out = detail::write(out, loc.file_name()); + out = detail::write(out, ':'); + out = detail::write(out, loc.line()); + out = detail::write(out, ':'); + out = detail::write(out, loc.column()); + out = detail::write(out, ": "); + out = detail::write(out, loc.function_name()); + return out; + } +}; +#endif + +#if FMT_CPP_LIB_VARIANT + +template struct is_variant_like { + static constexpr bool value = detail::is_variant_like_::value; +}; + +template struct formatter { + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return ctx.begin(); + } + + template + auto format(const std::monostate&, FormatContext& ctx) const + -> decltype(ctx.out()) { + return detail::write(ctx.out(), "monostate"); + } +}; + +template +struct formatter, + detail::is_variant_formattable>>> { + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return ctx.begin(); + } + + template + auto format(const Variant& value, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + + out = detail::write(out, "variant("); + FMT_TRY { + std::visit( + [&](const auto& v) { + out = detail::write_escaped_alternative(out, v, ctx); + }, + value); + } + FMT_CATCH(const std::bad_variant_access&) { + detail::write(out, "valueless by exception"); + } + *out++ = ')'; + return out; + } +}; + +#endif // FMT_CPP_LIB_VARIANT + +template <> struct formatter { + private: + format_specs specs_; + detail::arg_ref width_ref_; + bool debug_ = false; + + public: + FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; } + + FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { + auto it = ctx.begin(), end = ctx.end(); + if (it == end) return it; + + it = detail::parse_align(it, end, specs_); + + char c = *it; + if (it != end && ((c >= '0' && c <= '9') || c == '{')) + it = detail::parse_width(it, end, specs_, width_ref_, ctx); + + if (it != end && *it == '?') { + debug_ = true; + ++it; + } + if (it != end && *it == 's') { + specs_.set_type(presentation_type::string); + ++it; + } + return it; + } + + template + FMT_CONSTEXPR20 auto format(const std::error_code& ec, + FormatContext& ctx) const -> decltype(ctx.out()) { + auto specs = specs_; + detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_, + ctx); + auto buf = memory_buffer(); + if (specs_.type() == presentation_type::string) { + buf.append(ec.message()); + } else { + buf.append(string_view(ec.category().name())); + buf.push_back(':'); + detail::write(appender(buf), ec.value()); + } + auto quoted = memory_buffer(); + auto str = string_view(buf.data(), buf.size()); + if (debug_) { + detail::write_escaped_string(std::back_inserter(quoted), str); + str = string_view(quoted.data(), quoted.size()); + } + return detail::write(ctx.out(), str, specs); + } +}; + +#if FMT_USE_RTTI +template <> struct formatter { + public: + FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { + return ctx.begin(); + } + + template + auto format(const std::type_info& ti, Context& ctx) const + -> decltype(ctx.out()) { + return detail::write_demangled_name(ctx.out(), ti); + } +}; +#endif // FMT_USE_RTTI + +template +struct formatter< + T, char, + typename std::enable_if::value>::type> { + private: + bool with_typename_ = false; + + public: + FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* { + auto it = ctx.begin(); + auto end = ctx.end(); + if (it == end || *it == '}') return it; + if (*it == 't') { + ++it; + with_typename_ = FMT_USE_RTTI != 0; + } + return it; + } + + template + auto format(const std::exception& ex, Context& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); +#if FMT_USE_RTTI + if (with_typename_) { + out = detail::write_demangled_name(out, typeid(ex)); + *out++ = ':'; + *out++ = ' '; + } +#endif + return detail::write_bytes(out, string_view(ex.what())); + } +}; + +// We can't use std::vector::reference and +// std::bitset::reference because the compiler can't deduce Allocator and N +// in partial specialization. +template +struct formatter::value>> + : formatter { + template + FMT_CONSTEXPR auto format(const BitRef& v, FormatContext& ctx) const + -> decltype(ctx.out()) { + return formatter::format(v, ctx); + } +}; + +template +struct formatter, Char, + enable_if_t::value>> + : formatter { + template + auto format(const std::atomic& v, FormatContext& ctx) const + -> decltype(ctx.out()) { + return formatter::format(v.load(), ctx); + } +}; + +#ifdef __cpp_lib_atomic_flag_test +template +struct formatter : formatter { + template + auto format(const std::atomic_flag& v, FormatContext& ctx) const + -> decltype(ctx.out()) { + return formatter::format(v.test(), ctx); + } +}; +#endif // __cpp_lib_atomic_flag_test + +template struct formatter, Char> { + private: + detail::dynamic_format_specs specs_; + + template + FMT_CONSTEXPR auto do_format(const std::complex& c, + detail::dynamic_format_specs& specs, + FormatContext& ctx, OutputIt out) const + -> OutputIt { + if (c.real() != 0) { + *out++ = Char('('); + out = detail::write(out, c.real(), specs, ctx.locale()); + specs.set_sign(sign::plus); + out = detail::write(out, c.imag(), specs, ctx.locale()); + if (!detail::isfinite(c.imag())) *out++ = Char(' '); + *out++ = Char('i'); + *out++ = Char(')'); + return out; + } + out = detail::write(out, c.imag(), specs, ctx.locale()); + if (!detail::isfinite(c.imag())) *out++ = Char(' '); + *out++ = Char('i'); + return out; + } + + public: + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin(); + return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, + detail::type_constant::value); + } + + template + auto format(const std::complex& c, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto specs = specs_; + if (specs.dynamic()) { + detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, + specs.width_ref, ctx); + detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision, + specs.precision_ref, ctx); + } + + if (specs.width == 0) return do_format(c, specs, ctx, ctx.out()); + auto buf = basic_memory_buffer(); + + auto outer_specs = format_specs(); + outer_specs.width = specs.width; + outer_specs.copy_fill_from(specs); + outer_specs.set_align(specs.align()); + + specs.width = 0; + specs.set_fill({}); + specs.set_align(align::none); + + do_format(c, specs, ctx, basic_appender(buf)); + return detail::write(ctx.out(), + basic_string_view(buf.data(), buf.size()), + outer_specs); + } +}; + +template +struct formatter, Char, + // Guard against format_as because reference_wrapper is + // implicitly convertible to T&. + enable_if_t, Char>::value && + !detail::has_format_as::value && + !detail::has_format_as_member::value>> + : formatter, Char> { + template + auto format(std::reference_wrapper ref, FormatContext& ctx) const + -> decltype(ctx.out()) { + return formatter, Char>::format(ref.get(), ctx); + } +}; + +FMT_END_NAMESPACE + +#endif // FMT_STD_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/xchar.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/xchar.h new file mode 100644 index 0000000000000000000000000000000000000000..1cf7170e8bc421671f0e575a60e8b5c1f53d0ce6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/xchar.h @@ -0,0 +1,361 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +// Formatting library for C++ - optional wchar_t and exotic character support +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_XCHAR_H_ +#define FMT_XCHAR_H_ + +#include "color.h" +#include "format.h" +#include "ostream.h" +#include "ranges.h" + +#ifndef FMT_MODULE +# include +# if FMT_USE_LOCALE +# include +# endif +#endif + +FMT_BEGIN_NAMESPACE +namespace detail { + +template +using is_exotic_char = bool_constant::value>; + +template struct format_string_char {}; + +template +struct format_string_char< + S, void_t())))>> { + using type = char_t; +}; + +template +struct format_string_char< + S, enable_if_t::value>> { + using type = typename S::char_type; +}; + +template +using format_string_char_t = typename format_string_char::type; + +inline auto write_loc(basic_appender out, loc_value value, + const format_specs& specs, locale_ref loc) -> bool { +#if FMT_USE_LOCALE + auto& numpunct = + std::use_facet>(loc.get()); + auto separator = std::wstring(); + auto grouping = numpunct.grouping(); + if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep()); + return value.visit(loc_writer{out, specs, separator, grouping, {}}); +#endif + return false; +} + +template +void vformat_to(buffer& buf, basic_string_view fmt, + basic_format_args> args, + locale_ref loc = {}) { + static_assert(!std::is_same::value, ""); + auto out = basic_appender(buf); + parse_format_string( + fmt, format_handler{parse_context(fmt), {out, args, loc}}); +} +} // namespace detail + +FMT_BEGIN_EXPORT + +using wstring_view = basic_string_view; +using wformat_parse_context = parse_context; +using wformat_context = buffered_context; +using wformat_args = basic_format_args; +using wmemory_buffer = basic_memory_buffer; + +template struct basic_fstring { + private: + basic_string_view str_; + + static constexpr int num_static_named_args = + detail::count_static_named_args(); + + using checker = detail::format_string_checker< + Char, static_cast(sizeof...(T)), num_static_named_args, + num_static_named_args != detail::count_named_args()>; + + using arg_pack = detail::arg_pack; + + public: + using t = basic_fstring; + + template >::value)> + FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_fstring(const S& s) : str_(s) { + if (FMT_USE_CONSTEVAL) + detail::parse_format_string(s, checker(s, arg_pack())); + } + template ::value&& + std::is_same::value)> + FMT_ALWAYS_INLINE basic_fstring(const S&) : str_(S()) { + FMT_CONSTEXPR auto sv = basic_string_view(S()); + FMT_CONSTEXPR int ignore = + (parse_format_string(sv, checker(sv, arg_pack())), 0); + detail::ignore_unused(ignore); + } + basic_fstring(runtime_format_string fmt) : str_(fmt.str) {} + + operator basic_string_view() const { return str_; } + auto get() const -> basic_string_view { return str_; } +}; + +template +using basic_format_string = basic_fstring; + +template +using wformat_string = typename basic_format_string::t; +inline auto runtime(wstring_view s) -> runtime_format_string { + return {{s}}; +} + +template +constexpr auto make_wformat_args(T&... args) + -> decltype(fmt::make_format_args(args...)) { + return fmt::make_format_args(args...); +} + +#if !FMT_USE_NONTYPE_TEMPLATE_ARGS +inline namespace literals { +inline auto operator""_a(const wchar_t* s, size_t) -> detail::udl_arg { + return {s}; +} +} // namespace literals +#endif + +template +auto join(It begin, Sentinel end, wstring_view sep) + -> join_view { + return {begin, end, sep}; +} + +template ::value)> +auto join(Range&& range, wstring_view sep) + -> join_view { + return join(std::begin(range), std::end(range), sep); +} + +template +auto join(std::initializer_list list, wstring_view sep) + -> join_view { + return join(std::begin(list), std::end(list), sep); +} + +template ::value)> +auto join(const Tuple& tuple, basic_string_view sep) + -> tuple_join_view { + return {tuple, sep}; +} + +template ::value)> +auto vformat(basic_string_view fmt, + basic_format_args> args) + -> std::basic_string { + auto buf = basic_memory_buffer(); + detail::vformat_to(buf, fmt, args); + return {buf.data(), buf.size()}; +} + +template +auto format(wformat_string fmt, T&&... args) -> std::wstring { + return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...)); +} + +template +auto format_to(OutputIt out, wformat_string fmt, T&&... args) + -> OutputIt { + return vformat_to(out, fmt::wstring_view(fmt), + fmt::make_wformat_args(args...)); +} + +// Pass char_t as a default template parameter instead of using +// std::basic_string> to reduce the symbol size. +template , + FMT_ENABLE_IF(!std::is_same::value && + !std::is_same::value)> +auto format(const S& fmt, T&&... args) -> std::basic_string { + return vformat(detail::to_string_view(fmt), + fmt::make_format_args>(args...)); +} + +template , + FMT_ENABLE_IF(detail::is_exotic_char::value)> +inline auto vformat(locale_ref loc, const S& fmt, + basic_format_args> args) + -> std::basic_string { + auto buf = basic_memory_buffer(); + detail::vformat_to(buf, detail::to_string_view(fmt), args, loc); + return {buf.data(), buf.size()}; +} + +template , + FMT_ENABLE_IF(detail::is_exotic_char::value)> +inline auto format(locale_ref loc, const S& fmt, T&&... args) + -> std::basic_string { + return vformat(loc, detail::to_string_view(fmt), + fmt::make_format_args>(args...)); +} + +template , + FMT_ENABLE_IF(detail::is_output_iterator::value&& + detail::is_exotic_char::value)> +auto vformat_to(OutputIt out, const S& fmt, + basic_format_args> args) -> OutputIt { + auto&& buf = detail::get_buffer(out); + detail::vformat_to(buf, detail::to_string_view(fmt), args); + return detail::get_iterator(buf, out); +} + +template , + FMT_ENABLE_IF(detail::is_output_iterator::value && + !std::is_same::value && + !std::is_same::value)> +inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt { + return vformat_to(out, detail::to_string_view(fmt), + fmt::make_format_args>(args...)); +} + +template , + FMT_ENABLE_IF(detail::is_output_iterator::value&& + detail::is_exotic_char::value)> +inline auto vformat_to(OutputIt out, locale_ref loc, const S& fmt, + basic_format_args> args) + -> OutputIt { + auto&& buf = detail::get_buffer(out); + vformat_to(buf, detail::to_string_view(fmt), args, loc); + return detail::get_iterator(buf, out); +} + +template , + bool enable = detail::is_output_iterator::value && + detail::is_exotic_char::value> +inline auto format_to(OutputIt out, locale_ref loc, const S& fmt, T&&... args) + -> typename std::enable_if::type { + return vformat_to(out, loc, detail::to_string_view(fmt), + fmt::make_format_args>(args...)); +} + +template ::value&& + detail::is_exotic_char::value)> +inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view fmt, + basic_format_args> args) + -> format_to_n_result { + using traits = detail::fixed_buffer_traits; + auto buf = detail::iterator_buffer(out, n); + detail::vformat_to(buf, fmt, args); + return {buf.out(), buf.count()}; +} + +template , + FMT_ENABLE_IF(detail::is_output_iterator::value&& + detail::is_exotic_char::value)> +inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args) + -> format_to_n_result { + return vformat_to_n(out, n, fmt::basic_string_view(fmt), + fmt::make_format_args>(args...)); +} + +template , + FMT_ENABLE_IF(detail::is_exotic_char::value)> +inline auto formatted_size(const S& fmt, T&&... args) -> size_t { + auto buf = detail::counting_buffer(); + detail::vformat_to(buf, detail::to_string_view(fmt), + fmt::make_format_args>(args...)); + return buf.count(); +} + +inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) { + auto buf = wmemory_buffer(); + detail::vformat_to(buf, fmt, args); + buf.push_back(L'\0'); + if (std::fputws(buf.data(), f) == -1) + FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); +} + +inline void vprint(wstring_view fmt, wformat_args args) { + vprint(stdout, fmt, args); +} + +template +void print(std::FILE* f, wformat_string fmt, T&&... args) { + return vprint(f, wstring_view(fmt), fmt::make_wformat_args(args...)); +} + +template void print(wformat_string fmt, T&&... args) { + return vprint(wstring_view(fmt), fmt::make_wformat_args(args...)); +} + +template +void println(std::FILE* f, wformat_string fmt, T&&... args) { + return print(f, L"{}\n", fmt::format(fmt, std::forward(args)...)); +} + +template void println(wformat_string fmt, T&&... args) { + return print(L"{}\n", fmt::format(fmt, std::forward(args)...)); +} + +inline auto vformat(text_style ts, wstring_view fmt, wformat_args args) + -> std::wstring { + auto buf = wmemory_buffer(); + detail::vformat_to(buf, ts, fmt, args); + return {buf.data(), buf.size()}; +} + +template +inline auto format(text_style ts, wformat_string fmt, T&&... args) + -> std::wstring { + return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...)); +} + +inline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) { + auto buffer = basic_memory_buffer(); + detail::vformat_to(buffer, fmt, args); + detail::write_buffer(os, buffer); +} + +template +void print(std::wostream& os, wformat_string fmt, T&&... args) { + vprint(os, fmt, fmt::make_format_args>(args...)); +} + +template +void println(std::wostream& os, wformat_string fmt, T&&... args) { + print(os, L"{}\n", fmt::format(fmt, std::forward(args)...)); +} + +/// Converts `value` to `std::wstring` using the default format for type `T`. +template inline auto to_wstring(const T& value) -> std::wstring { + return format(FMT_STRING(L"{}"), value); +} +FMT_END_EXPORT +FMT_END_NAMESPACE + +#endif // FMT_XCHAR_H_ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16.h new file mode 100644 index 0000000000000000000000000000000000000000..f5dc61d18ded7ef41d8e9698de12c2fe21094b81 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16.h @@ -0,0 +1,16 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#ifndef FP16_H +#define FP16_H + +#include + +#if defined(PSIMD_H) +#include +#endif + +#endif /* FP16_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/bitcasts.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/bitcasts.h new file mode 100644 index 0000000000000000000000000000000000000000..55461b797fb041b8f5d5b6a313cf2ec6fedcce6d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/bitcasts.h @@ -0,0 +1,97 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#ifndef FP16_BITCASTS_H +#define FP16_BITCASTS_H + +#if defined(__cplusplus) && (__cplusplus >= 201103L) + #include +#elif !defined(__OPENCL_VERSION__) + #include +#endif + +#if defined(__INTEL_COMPILER) + #include +#endif + +#if defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) + #include +#endif + + +static inline float fp32_from_bits(uint32_t w) { +#if defined(__OPENCL_VERSION__) + return as_float(w); +#elif defined(__CUDA_ARCH__) + return __uint_as_float((unsigned int) w); +#elif defined(__INTEL_COMPILER) + return _castu32_f32(w); +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) + return _CopyFloatFromInt32((__int32) w); +#else + union { + uint32_t as_bits; + float as_value; + } fp32 = { w }; + return fp32.as_value; +#endif +} + +static inline uint32_t fp32_to_bits(float f) { +#if defined(__OPENCL_VERSION__) + return as_uint(f); +#elif defined(__CUDA_ARCH__) + return (uint32_t) __float_as_uint(f); +#elif defined(__INTEL_COMPILER) + return _castf32_u32(f); +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) + return (uint32_t) _CopyInt32FromFloat(f); +#else + union { + float as_value; + uint32_t as_bits; + } fp32 = { f }; + return fp32.as_bits; +#endif +} + +static inline double fp64_from_bits(uint64_t w) { +#if defined(__OPENCL_VERSION__) + return as_double(w); +#elif defined(__CUDA_ARCH__) + return __longlong_as_double((long long) w); +#elif defined(__INTEL_COMPILER) + return _castu64_f64(w); +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) + return _CopyDoubleFromInt64((__int64) w); +#else + union { + uint64_t as_bits; + double as_value; + } fp64 = { w }; + return fp64.as_value; +#endif +} + +static inline uint64_t fp64_to_bits(double f) { +#if defined(__OPENCL_VERSION__) + return as_ulong(f); +#elif defined(__CUDA_ARCH__) + return (uint64_t) __double_as_longlong(f); +#elif defined(__INTEL_COMPILER) + return _castf64_u64(f); +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) + return (uint64_t) _CopyInt64FromDouble(f); +#else + union { + double as_value; + uint64_t as_bits; + } fp64 = { f }; + return fp64.as_bits; +#endif +} + +#endif /* FP16_BITCASTS_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/fp16.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/fp16.h new file mode 100644 index 0000000000000000000000000000000000000000..4e29f28ccea774a363d6c624d53a4acc9783b4a3 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/fp16.h @@ -0,0 +1,456 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#ifndef FP16_FP16_H +#define FP16_FP16_H + +#if defined(__cplusplus) && (__cplusplus >= 201103L) + #include + #include +#elif !defined(__OPENCL_VERSION__) + #include + #include +#endif + +#ifdef _MSC_VER + #include +#endif + +#include + + +/* + * Convert a 16-bit floating-point number in IEEE half-precision format, in bit representation, to + * a 32-bit floating-point number in IEEE single-precision format, in bit representation. + * + * @note The implementation doesn't use any floating-point operations. + */ +static inline uint32_t fp16_ieee_to_fp32_bits(uint16_t h) { + /* + * Extend the half-precision floating-point number to 32 bits and shift to the upper part of the 32-bit word: + * +---+-----+------------+-------------------+ + * | S |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 31 26-30 16-25 0-15 + * + * S - sign bit, E - bits of the biased exponent, M - bits of the mantissa, 0 - zero bits. + */ + const uint32_t w = (uint32_t) h << 16; + /* + * Extract the sign of the input number into the high bit of the 32-bit word: + * + * +---+----------------------------------+ + * | S |0000000 00000000 00000000 00000000| + * +---+----------------------------------+ + * Bits 31 0-31 + */ + const uint32_t sign = w & UINT32_C(0x80000000); + /* + * Extract mantissa and biased exponent of the input number into the bits 0-30 of the 32-bit word: + * + * +---+-----+------------+-------------------+ + * | 0 |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 30 27-31 17-26 0-16 + */ + const uint32_t nonsign = w & UINT32_C(0x7FFFFFFF); + /* + * Renorm shift is the number of bits to shift mantissa left to make the half-precision number normalized. + * If the initial number is normalized, some of its high 6 bits (sign == 0 and 5-bit exponent) equals one. + * In this case renorm_shift == 0. If the number is denormalize, renorm_shift > 0. Note that if we shift + * denormalized nonsign by renorm_shift, the unit bit of mantissa will shift into exponent, turning the + * biased exponent into 1, and making mantissa normalized (i.e. without leading 1). + */ +#ifdef _MSC_VER + unsigned long nonsign_bsr; + _BitScanReverse(&nonsign_bsr, (unsigned long) nonsign); + uint32_t renorm_shift = (uint32_t) nonsign_bsr ^ 31; +#else + uint32_t renorm_shift = __builtin_clz(nonsign); +#endif + renorm_shift = renorm_shift > 5 ? renorm_shift - 5 : 0; + /* + * Iff half-precision number has exponent of 15, the addition overflows it into bit 31, + * and the subsequent shift turns the high 9 bits into 1. Thus + * inf_nan_mask == + * 0x7F800000 if the half-precision number had exponent of 15 (i.e. was NaN or infinity) + * 0x00000000 otherwise + */ + const int32_t inf_nan_mask = ((int32_t) (nonsign + 0x04000000) >> 8) & INT32_C(0x7F800000); + /* + * Iff nonsign is 0, it overflows into 0xFFFFFFFF, turning bit 31 into 1. Otherwise, bit 31 remains 0. + * The signed shift right by 31 broadcasts bit 31 into all bits of the zero_mask. Thus + * zero_mask == + * 0xFFFFFFFF if the half-precision number was zero (+0.0h or -0.0h) + * 0x00000000 otherwise + */ + const int32_t zero_mask = (int32_t) (nonsign - 1) >> 31; + /* + * 1. Shift nonsign left by renorm_shift to normalize it (if the input was denormal) + * 2. Shift nonsign right by 3 so the exponent (5 bits originally) becomes an 8-bit field and 10-bit mantissa + * shifts into the 10 high bits of the 23-bit mantissa of IEEE single-precision number. + * 3. Add 0x70 to the exponent (starting at bit 23) to compensate the different in exponent bias + * (0x7F for single-precision number less 0xF for half-precision number). + * 4. Subtract renorm_shift from the exponent (starting at bit 23) to account for renormalization. As renorm_shift + * is less than 0x70, this can be combined with step 3. + * 5. Binary OR with inf_nan_mask to turn the exponent into 0xFF if the input was NaN or infinity. + * 6. Binary ANDNOT with zero_mask to turn the mantissa and exponent into zero if the input was zero. + * 7. Combine with the sign of the input number. + */ + return sign | ((((nonsign << renorm_shift >> 3) + ((0x70 - renorm_shift) << 23)) | inf_nan_mask) & ~zero_mask); +} + +/* + * Convert a 16-bit floating-point number in IEEE half-precision format, in bit representation, to + * a 32-bit floating-point number in IEEE single-precision format. + * + * @note The implementation relies on IEEE-like (no assumption about rounding mode and no operations on denormals) + * floating-point operations and bitcasts between integer and floating-point variables. + */ +static inline float fp16_ieee_to_fp32_value(uint16_t h) { + /* + * Extend the half-precision floating-point number to 32 bits and shift to the upper part of the 32-bit word: + * +---+-----+------------+-------------------+ + * | S |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 31 26-30 16-25 0-15 + * + * S - sign bit, E - bits of the biased exponent, M - bits of the mantissa, 0 - zero bits. + */ + const uint32_t w = (uint32_t) h << 16; + /* + * Extract the sign of the input number into the high bit of the 32-bit word: + * + * +---+----------------------------------+ + * | S |0000000 00000000 00000000 00000000| + * +---+----------------------------------+ + * Bits 31 0-31 + */ + const uint32_t sign = w & UINT32_C(0x80000000); + /* + * Extract mantissa and biased exponent of the input number into the high bits of the 32-bit word: + * + * +-----+------------+---------------------+ + * |EEEEE|MM MMMM MMMM|0 0000 0000 0000 0000| + * +-----+------------+---------------------+ + * Bits 27-31 17-26 0-16 + */ + const uint32_t two_w = w + w; + + /* + * Shift mantissa and exponent into bits 23-28 and bits 13-22 so they become mantissa and exponent + * of a single-precision floating-point number: + * + * S|Exponent | Mantissa + * +-+---+-----+------------+----------------+ + * |0|000|EEEEE|MM MMMM MMMM|0 0000 0000 0000| + * +-+---+-----+------------+----------------+ + * Bits | 23-31 | 0-22 + * + * Next, there are some adjustments to the exponent: + * - The exponent needs to be corrected by the difference in exponent bias between single-precision and half-precision + * formats (0x7F - 0xF = 0x70) + * - Inf and NaN values in the inputs should become Inf and NaN values after conversion to the single-precision number. + * Therefore, if the biased exponent of the half-precision input was 0x1F (max possible value), the biased exponent + * of the single-precision output must be 0xFF (max possible value). We do this correction in two steps: + * - First, we adjust the exponent by (0xFF - 0x1F) = 0xE0 (see exp_offset below) rather than by 0x70 suggested + * by the difference in the exponent bias (see above). + * - Then we multiply the single-precision result of exponent adjustment by 2**(-112) to reverse the effect of + * exponent adjustment by 0xE0 less the necessary exponent adjustment by 0x70 due to difference in exponent bias. + * The floating-point multiplication hardware would ensure than Inf and NaN would retain their value on at least + * partially IEEE754-compliant implementations. + * + * Note that the above operations do not handle denormal inputs (where biased exponent == 0). However, they also do not + * operate on denormal inputs, and do not produce denormal results. + */ + const uint32_t exp_offset = UINT32_C(0xE0) << 23; +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__) + const float exp_scale = 0x1.0p-112f; +#else + const float exp_scale = fp32_from_bits(UINT32_C(0x7800000)); +#endif + const float normalized_value = fp32_from_bits((two_w >> 4) + exp_offset) * exp_scale; + + /* + * Convert denormalized half-precision inputs into single-precision results (always normalized). + * Zero inputs are also handled here. + * + * In a denormalized number the biased exponent is zero, and mantissa has on-zero bits. + * First, we shift mantissa into bits 0-9 of the 32-bit word. + * + * zeros | mantissa + * +---------------------------+------------+ + * |0000 0000 0000 0000 0000 00|MM MMMM MMMM| + * +---------------------------+------------+ + * Bits 10-31 0-9 + * + * Now, remember that denormalized half-precision numbers are represented as: + * FP16 = mantissa * 2**(-24). + * The trick is to construct a normalized single-precision number with the same mantissa and thehalf-precision input + * and with an exponent which would scale the corresponding mantissa bits to 2**(-24). + * A normalized single-precision floating-point number is represented as: + * FP32 = (1 + mantissa * 2**(-23)) * 2**(exponent - 127) + * Therefore, when the biased exponent is 126, a unit change in the mantissa of the input denormalized half-precision + * number causes a change of the constructud single-precision number by 2**(-24), i.e. the same ammount. + * + * The last step is to adjust the bias of the constructed single-precision number. When the input half-precision number + * is zero, the constructed single-precision number has the value of + * FP32 = 1 * 2**(126 - 127) = 2**(-1) = 0.5 + * Therefore, we need to subtract 0.5 from the constructed single-precision number to get the numerical equivalent of + * the input half-precision number. + */ + const uint32_t magic_mask = UINT32_C(126) << 23; + const float magic_bias = 0.5f; + const float denormalized_value = fp32_from_bits((two_w >> 17) | magic_mask) - magic_bias; + + /* + * - Choose either results of conversion of input as a normalized number, or as a denormalized number, depending on the + * input exponent. The variable two_w contains input exponent in bits 27-31, therefore if its smaller than 2**27, the + * input is either a denormal number, or zero. + * - Combine the result of conversion of exponent and mantissa with the sign of the input number. + */ + const uint32_t denormalized_cutoff = UINT32_C(1) << 27; + const uint32_t result = sign | + (two_w < denormalized_cutoff ? fp32_to_bits(denormalized_value) : fp32_to_bits(normalized_value)); + return fp32_from_bits(result); +} + +/* + * Convert a 32-bit floating-point number in IEEE single-precision format to a 16-bit floating-point number in + * IEEE half-precision format, in bit representation. + * + * @note The implementation relies on IEEE-like (no assumption about rounding mode and no operations on denormals) + * floating-point operations and bitcasts between integer and floating-point variables. + */ +static inline uint16_t fp16_ieee_from_fp32_value(float f) { +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__) + const float scale_to_inf = 0x1.0p+112f; + const float scale_to_zero = 0x1.0p-110f; +#else + const float scale_to_inf = fp32_from_bits(UINT32_C(0x77800000)); + const float scale_to_zero = fp32_from_bits(UINT32_C(0x08800000)); +#endif + float base = (fabsf(f) * scale_to_inf) * scale_to_zero; + + const uint32_t w = fp32_to_bits(f); + const uint32_t shl1_w = w + w; + const uint32_t sign = w & UINT32_C(0x80000000); + uint32_t bias = shl1_w & UINT32_C(0xFF000000); + if (bias < UINT32_C(0x71000000)) { + bias = UINT32_C(0x71000000); + } + + base = fp32_from_bits((bias >> 1) + UINT32_C(0x07800000)) + base; + const uint32_t bits = fp32_to_bits(base); + const uint32_t exp_bits = (bits >> 13) & UINT32_C(0x00007C00); + const uint32_t mantissa_bits = bits & UINT32_C(0x00000FFF); + const uint32_t nonsign = exp_bits + mantissa_bits; + return (sign >> 16) | (shl1_w > UINT32_C(0xFF000000) ? UINT16_C(0x7E00) : nonsign); +} + +/* + * Convert a 16-bit floating-point number in ARM alternative half-precision format, in bit representation, to + * a 32-bit floating-point number in IEEE single-precision format, in bit representation. + * + * @note The implementation doesn't use any floating-point operations. + */ +static inline uint32_t fp16_alt_to_fp32_bits(uint16_t h) { + /* + * Extend the half-precision floating-point number to 32 bits and shift to the upper part of the 32-bit word: + * +---+-----+------------+-------------------+ + * | S |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 31 26-30 16-25 0-15 + * + * S - sign bit, E - bits of the biased exponent, M - bits of the mantissa, 0 - zero bits. + */ + const uint32_t w = (uint32_t) h << 16; + /* + * Extract the sign of the input number into the high bit of the 32-bit word: + * + * +---+----------------------------------+ + * | S |0000000 00000000 00000000 00000000| + * +---+----------------------------------+ + * Bits 31 0-31 + */ + const uint32_t sign = w & UINT32_C(0x80000000); + /* + * Extract mantissa and biased exponent of the input number into the bits 0-30 of the 32-bit word: + * + * +---+-----+------------+-------------------+ + * | 0 |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 30 27-31 17-26 0-16 + */ + const uint32_t nonsign = w & UINT32_C(0x7FFFFFFF); + /* + * Renorm shift is the number of bits to shift mantissa left to make the half-precision number normalized. + * If the initial number is normalized, some of its high 6 bits (sign == 0 and 5-bit exponent) equals one. + * In this case renorm_shift == 0. If the number is denormalize, renorm_shift > 0. Note that if we shift + * denormalized nonsign by renorm_shift, the unit bit of mantissa will shift into exponent, turning the + * biased exponent into 1, and making mantissa normalized (i.e. without leading 1). + */ +#ifdef _MSC_VER + unsigned long nonsign_bsr; + _BitScanReverse(&nonsign_bsr, (unsigned long) nonsign); + uint32_t renorm_shift = (uint32_t) nonsign_bsr ^ 31; +#else + uint32_t renorm_shift = __builtin_clz(nonsign); +#endif + renorm_shift = renorm_shift > 5 ? renorm_shift - 5 : 0; + /* + * Iff nonsign is 0, it overflows into 0xFFFFFFFF, turning bit 31 into 1. Otherwise, bit 31 remains 0. + * The signed shift right by 31 broadcasts bit 31 into all bits of the zero_mask. Thus + * zero_mask == + * 0xFFFFFFFF if the half-precision number was zero (+0.0h or -0.0h) + * 0x00000000 otherwise + */ + const int32_t zero_mask = (int32_t) (nonsign - 1) >> 31; + /* + * 1. Shift nonsign left by renorm_shift to normalize it (if the input was denormal) + * 2. Shift nonsign right by 3 so the exponent (5 bits originally) becomes an 8-bit field and 10-bit mantissa + * shifts into the 10 high bits of the 23-bit mantissa of IEEE single-precision number. + * 3. Add 0x70 to the exponent (starting at bit 23) to compensate the different in exponent bias + * (0x7F for single-precision number less 0xF for half-precision number). + * 4. Subtract renorm_shift from the exponent (starting at bit 23) to account for renormalization. As renorm_shift + * is less than 0x70, this can be combined with step 3. + * 5. Binary ANDNOT with zero_mask to turn the mantissa and exponent into zero if the input was zero. + * 6. Combine with the sign of the input number. + */ + return sign | (((nonsign << renorm_shift >> 3) + ((0x70 - renorm_shift) << 23)) & ~zero_mask); +} + +/* + * Convert a 16-bit floating-point number in ARM alternative half-precision format, in bit representation, to + * a 32-bit floating-point number in IEEE single-precision format. + * + * @note The implementation relies on IEEE-like (no assumption about rounding mode and no operations on denormals) + * floating-point operations and bitcasts between integer and floating-point variables. + */ +static inline float fp16_alt_to_fp32_value(uint16_t h) { + /* + * Extend the half-precision floating-point number to 32 bits and shift to the upper part of the 32-bit word: + * +---+-----+------------+-------------------+ + * | S |EEEEE|MM MMMM MMMM|0000 0000 0000 0000| + * +---+-----+------------+-------------------+ + * Bits 31 26-30 16-25 0-15 + * + * S - sign bit, E - bits of the biased exponent, M - bits of the mantissa, 0 - zero bits. + */ + const uint32_t w = (uint32_t) h << 16; + /* + * Extract the sign of the input number into the high bit of the 32-bit word: + * + * +---+----------------------------------+ + * | S |0000000 00000000 00000000 00000000| + * +---+----------------------------------+ + * Bits 31 0-31 + */ + const uint32_t sign = w & UINT32_C(0x80000000); + /* + * Extract mantissa and biased exponent of the input number into the high bits of the 32-bit word: + * + * +-----+------------+---------------------+ + * |EEEEE|MM MMMM MMMM|0 0000 0000 0000 0000| + * +-----+------------+---------------------+ + * Bits 27-31 17-26 0-16 + */ + const uint32_t two_w = w + w; + + /* + * Shift mantissa and exponent into bits 23-28 and bits 13-22 so they become mantissa and exponent + * of a single-precision floating-point number: + * + * S|Exponent | Mantissa + * +-+---+-----+------------+----------------+ + * |0|000|EEEEE|MM MMMM MMMM|0 0000 0000 0000| + * +-+---+-----+------------+----------------+ + * Bits | 23-31 | 0-22 + * + * Next, the exponent is adjusted for the difference in exponent bias between single-precision and half-precision + * formats (0x7F - 0xF = 0x70). This operation never overflows or generates non-finite values, as the largest + * half-precision exponent is 0x1F and after the adjustment is can not exceed 0x8F < 0xFE (largest single-precision + * exponent for non-finite values). + * + * Note that this operation does not handle denormal inputs (where biased exponent == 0). However, they also do not + * operate on denormal inputs, and do not produce denormal results. + */ + const uint32_t exp_offset = UINT32_C(0x70) << 23; + const float normalized_value = fp32_from_bits((two_w >> 4) + exp_offset); + + /* + * Convert denormalized half-precision inputs into single-precision results (always normalized). + * Zero inputs are also handled here. + * + * In a denormalized number the biased exponent is zero, and mantissa has on-zero bits. + * First, we shift mantissa into bits 0-9 of the 32-bit word. + * + * zeros | mantissa + * +---------------------------+------------+ + * |0000 0000 0000 0000 0000 00|MM MMMM MMMM| + * +---------------------------+------------+ + * Bits 10-31 0-9 + * + * Now, remember that denormalized half-precision numbers are represented as: + * FP16 = mantissa * 2**(-24). + * The trick is to construct a normalized single-precision number with the same mantissa and thehalf-precision input + * and with an exponent which would scale the corresponding mantissa bits to 2**(-24). + * A normalized single-precision floating-point number is represented as: + * FP32 = (1 + mantissa * 2**(-23)) * 2**(exponent - 127) + * Therefore, when the biased exponent is 126, a unit change in the mantissa of the input denormalized half-precision + * number causes a change of the constructud single-precision number by 2**(-24), i.e. the same ammount. + * + * The last step is to adjust the bias of the constructed single-precision number. When the input half-precision number + * is zero, the constructed single-precision number has the value of + * FP32 = 1 * 2**(126 - 127) = 2**(-1) = 0.5 + * Therefore, we need to subtract 0.5 from the constructed single-precision number to get the numerical equivalent of + * the input half-precision number. + */ + const uint32_t magic_mask = UINT32_C(126) << 23; + const float magic_bias = 0.5f; + const float denormalized_value = fp32_from_bits((two_w >> 17) | magic_mask) - magic_bias; + + /* + * - Choose either results of conversion of input as a normalized number, or as a denormalized number, depending on the + * input exponent. The variable two_w contains input exponent in bits 27-31, therefore if its smaller than 2**27, the + * input is either a denormal number, or zero. + * - Combine the result of conversion of exponent and mantissa with the sign of the input number. + */ + const uint32_t denormalized_cutoff = UINT32_C(1) << 27; + const uint32_t result = sign | + (two_w < denormalized_cutoff ? fp32_to_bits(denormalized_value) : fp32_to_bits(normalized_value)); + return fp32_from_bits(result); +} + +/* + * Convert a 32-bit floating-point number in IEEE single-precision format to a 16-bit floating-point number in + * ARM alternative half-precision format, in bit representation. + * + * @note The implementation relies on IEEE-like (no assumption about rounding mode and no operations on denormals) + * floating-point operations and bitcasts between integer and floating-point variables. + */ +static inline uint16_t fp16_alt_from_fp32_value(float f) { + const uint32_t w = fp32_to_bits(f); + const uint32_t sign = w & UINT32_C(0x80000000); + const uint32_t shl1_w = w + w; + + const uint32_t shl1_max_fp16_fp32 = UINT32_C(0x8FFFC000); + const uint32_t shl1_base = shl1_w > shl1_max_fp16_fp32 ? shl1_max_fp16_fp32 : shl1_w; + uint32_t shl1_bias = shl1_base & UINT32_C(0xFF000000); + const uint32_t exp_difference = 23 - 10; + const uint32_t shl1_bias_min = (127 - 1 - exp_difference) << 24; + if (shl1_bias < shl1_bias_min) { + shl1_bias = shl1_bias_min; + } + + const float bias = fp32_from_bits((shl1_bias >> 1) + ((exp_difference + 2) << 23)); + const float base = fp32_from_bits((shl1_base >> 1) + (2 << 23)) + bias; + + const uint32_t exp_f = fp32_to_bits(base) >> 13; + return (sign >> 16) | ((exp_f & UINT32_C(0x00007C00)) + (fp32_to_bits(base) & UINT32_C(0x00000FFF))); +} + +#endif /* FP16_FP16_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/psimd.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/psimd.h new file mode 100644 index 0000000000000000000000000000000000000000..346df7b3de42625fb0c1b6774b614ffce0e94993 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/psimd.h @@ -0,0 +1,136 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#ifndef FP16_PSIMD_H +#define FP16_PSIMD_H + +#if defined(__cplusplus) && (__cplusplus >= 201103L) + #include +#elif !defined(__OPENCL_VERSION__) + #include +#endif + +#include + + +PSIMD_INTRINSIC psimd_f32 fp16_ieee_to_fp32_psimd(psimd_u16 half) { + const psimd_u32 word = (psimd_u32) psimd_interleave_lo_u16(psimd_zero_u16(), half); + + const psimd_u32 sign = word & psimd_splat_u32(UINT32_C(0x80000000)); + const psimd_u32 shr3_nonsign = (word + word) >> psimd_splat_u32(4); + + const psimd_u32 exp_offset = psimd_splat_u32(UINT32_C(0x70000000)); +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__) + const psimd_f32 exp_scale = psimd_splat_f32(0x1.0p-112f); +#else + const psimd_f32 exp_scale = psimd_splat_f32(fp32_from_bits(UINT32_C(0x7800000))); +#endif + const psimd_f32 norm_nonsign = psimd_mul_f32((psimd_f32) (shr3_nonsign + exp_offset), exp_scale); + + const psimd_u16 magic_mask = psimd_splat_u16(UINT16_C(0x3E80)); + const psimd_f32 magic_bias = psimd_splat_f32(0.25f); + const psimd_f32 denorm_nonsign = psimd_sub_f32((psimd_f32) psimd_interleave_lo_u16(half + half, magic_mask), magic_bias); + + const psimd_s32 denorm_cutoff = psimd_splat_s32(INT32_C(0x00800000)); + const psimd_s32 denorm_mask = (psimd_s32) shr3_nonsign < denorm_cutoff; + return (psimd_f32) (sign | (psimd_s32) psimd_blend_f32(denorm_mask, denorm_nonsign, norm_nonsign)); +} + +PSIMD_INTRINSIC psimd_f32x2 fp16_ieee_to_fp32x2_psimd(psimd_u16 half) { + const psimd_u32 word_lo = (psimd_u32) psimd_interleave_lo_u16(psimd_zero_u16(), half); + const psimd_u32 word_hi = (psimd_u32) psimd_interleave_hi_u16(psimd_zero_u16(), half); + + const psimd_u32 sign_mask = psimd_splat_u32(UINT32_C(0x80000000)); + const psimd_u32 sign_lo = word_lo & sign_mask; + const psimd_u32 sign_hi = word_hi & sign_mask; + const psimd_u32 shr3_nonsign_lo = (word_lo + word_lo) >> psimd_splat_u32(4); + const psimd_u32 shr3_nonsign_hi = (word_hi + word_hi) >> psimd_splat_u32(4); + + const psimd_u32 exp_offset = psimd_splat_u32(UINT32_C(0x70000000)); +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__) + const psimd_f32 exp_scale = psimd_splat_f32(0x1.0p-112f); +#else + const psimd_f32 exp_scale = psimd_splat_f32(fp32_from_bits(UINT32_C(0x7800000))); +#endif + const psimd_f32 norm_nonsign_lo = psimd_mul_f32((psimd_f32) (shr3_nonsign_lo + exp_offset), exp_scale); + const psimd_f32 norm_nonsign_hi = psimd_mul_f32((psimd_f32) (shr3_nonsign_hi + exp_offset), exp_scale); + + const psimd_u16 magic_mask = psimd_splat_u16(UINT16_C(0x3E80)); + const psimd_u16 shl1_half = half + half; + const psimd_f32 magic_bias = psimd_splat_f32(0.25f); + const psimd_f32 denorm_nonsign_lo = psimd_sub_f32((psimd_f32) psimd_interleave_lo_u16(shl1_half, magic_mask), magic_bias); + const psimd_f32 denorm_nonsign_hi = psimd_sub_f32((psimd_f32) psimd_interleave_hi_u16(shl1_half, magic_mask), magic_bias); + + const psimd_s32 denorm_cutoff = psimd_splat_s32(INT32_C(0x00800000)); + const psimd_s32 denorm_mask_lo = (psimd_s32) shr3_nonsign_lo < denorm_cutoff; + const psimd_s32 denorm_mask_hi = (psimd_s32) shr3_nonsign_hi < denorm_cutoff; + + psimd_f32x2 result; + result.lo = (psimd_f32) (sign_lo | (psimd_s32) psimd_blend_f32(denorm_mask_lo, denorm_nonsign_lo, norm_nonsign_lo)); + result.hi = (psimd_f32) (sign_hi | (psimd_s32) psimd_blend_f32(denorm_mask_hi, denorm_nonsign_hi, norm_nonsign_hi)); + return result; +} + +PSIMD_INTRINSIC psimd_f32 fp16_alt_to_fp32_psimd(psimd_u16 half) { + const psimd_u32 word = (psimd_u32) psimd_interleave_lo_u16(psimd_zero_u16(), half); + + const psimd_u32 sign = word & psimd_splat_u32(INT32_C(0x80000000)); + const psimd_u32 shr3_nonsign = (word + word) >> psimd_splat_u32(4); + +#if 0 + const psimd_s32 exp112_offset = psimd_splat_s32(INT32_C(0x38000000)); + const psimd_s32 nonsign_bits = (psimd_s32) shr3_nonsign + exp112_offset; + const psimd_s32 exp1_offset = psimd_splat_s32(INT32_C(0x00800000)); + const psimd_f32 two_nonsign = (psimd_f32) (nonsign_bits + exp1_offset); + const psimd_s32 exp113_offset = exp112_offset | exp1_offset; + return (psimd_f32) (sign | (psimd_s32) psimd_sub_f32(two_nonsign, (psimd_f32) psimd_max_s32(nonsign_bits, exp113_offset))); +#else + const psimd_u32 exp_offset = psimd_splat_u32(UINT32_C(0x38000000)); + const psimd_f32 nonsign = (psimd_f32) (shr3_nonsign + exp_offset); +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__) + const psimd_f32 denorm_bias = psimd_splat_f32(0x1.0p-14f); +#else + const psimd_f32 denorm_bias = psimd_splat_f32(fp32_from_bits(UINT32_C(0x38800000))); +#endif + return (psimd_f32) (sign | (psimd_s32) psimd_sub_f32(psimd_add_f32(nonsign, nonsign), psimd_max_f32(nonsign, denorm_bias))); +#endif +} + +PSIMD_INTRINSIC psimd_f32x2 fp16_alt_to_fp32x2_psimd(psimd_u16 half) { + const psimd_u32 word_lo = (psimd_u32) psimd_interleave_lo_u16(psimd_zero_u16(), half); + const psimd_u32 word_hi = (psimd_u32) psimd_interleave_hi_u16(psimd_zero_u16(), half); + + const psimd_u32 sign_mask = psimd_splat_u32(UINT32_C(0x80000000)); + const psimd_u32 sign_lo = word_lo & sign_mask; + const psimd_u32 sign_hi = word_hi & sign_mask; + const psimd_u32 shr3_nonsign_lo = (word_lo + word_lo) >> psimd_splat_u32(4); + const psimd_u32 shr3_nonsign_hi = (word_hi + word_hi) >> psimd_splat_u32(4); + +#if 1 + const psimd_s32 exp112_offset = psimd_splat_s32(INT32_C(0x38000000)); + const psimd_s32 nonsign_bits_lo = (psimd_s32) shr3_nonsign_lo + exp112_offset; + const psimd_s32 nonsign_bits_hi = (psimd_s32) shr3_nonsign_hi + exp112_offset; + const psimd_s32 exp1_offset = psimd_splat_s32(INT32_C(0x00800000)); + const psimd_f32 two_nonsign_lo = (psimd_f32) (nonsign_bits_lo + exp1_offset); + const psimd_f32 two_nonsign_hi = (psimd_f32) (nonsign_bits_hi + exp1_offset); + const psimd_s32 exp113_offset = exp1_offset | exp112_offset; + psimd_f32x2 result; + result.lo = (psimd_f32) (sign_lo | (psimd_s32) psimd_sub_f32(two_nonsign_lo, (psimd_f32) psimd_max_s32(nonsign_bits_lo, exp113_offset))); + result.hi = (psimd_f32) (sign_hi | (psimd_s32) psimd_sub_f32(two_nonsign_hi, (psimd_f32) psimd_max_s32(nonsign_bits_hi, exp113_offset))); + return result; +#else + const psimd_u32 exp_offset = psimd_splat_u32(UINT32_C(0x38000000)); + const psimd_f32 nonsign_lo = (psimd_f32) (shr3_nonsign_lo + exp_offset); + const psimd_f32 nonsign_hi = (psimd_f32) (shr3_nonsign_hi + exp_offset); + const psimd_f32 denorm_bias = psimd_splat_f32(0x1.0p-14f); + psimd_f32x2 result; + result.lo = (psimd_f32) (sign_lo | (psimd_s32) psimd_sub_f32(psimd_add_f32(nonsign_lo, nonsign_lo), psimd_max_f32(nonsign_lo, denorm_bias))); + result.hi = (psimd_f32) (sign_hi | (psimd_s32) psimd_sub_f32(psimd_add_f32(nonsign_hi, nonsign_hi), psimd_max_f32(nonsign_hi, denorm_bias))); + return result; +#endif +} + +#endif /* FP16_PSIMD_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fxdiv.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fxdiv.h new file mode 100644 index 0000000000000000000000000000000000000000..abdd7c70f51f5cbdb1880901060e3df90f91e682 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fxdiv.h @@ -0,0 +1,430 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#ifndef FXDIV_H +#define FXDIV_H + +#if defined(__cplusplus) && (__cplusplus >= 201103L) + #include + #include + #include +#elif !defined(__OPENCL_VERSION__) + #include + #include + #include +#endif + +#if defined(_MSC_VER) + #include + #if defined(_M_IX86) || defined(_M_X64) + #include + #endif +#endif + +#ifndef FXDIV_USE_INLINE_ASSEMBLY + #define FXDIV_USE_INLINE_ASSEMBLY 0 +#endif + +static inline uint64_t fxdiv_mulext_uint32_t(uint32_t a, uint32_t b) { +#if defined(_MSC_VER) && defined(_M_IX86) + return (uint64_t) __emulu((unsigned int) a, (unsigned int) b); +#else + return (uint64_t) a * (uint64_t) b; +#endif +} + +static inline uint32_t fxdiv_mulhi_uint32_t(uint32_t a, uint32_t b) { +#if defined(__OPENCL_VERSION__) + return mul_hi(a, b); +#elif defined(__CUDA_ARCH__) + return (uint32_t) __umulhi((unsigned int) a, (unsigned int) b); +#elif defined(_MSC_VER) && defined(_M_IX86) + return (uint32_t) (__emulu((unsigned int) a, (unsigned int) b) >> 32); +#elif defined(_MSC_VER) && defined(_M_ARM) + return (uint32_t) _MulUnsignedHigh((unsigned long) a, (unsigned long) b); +#else + return (uint32_t) (((uint64_t) a * (uint64_t) b) >> 32); +#endif +} + +static inline uint64_t fxdiv_mulhi_uint64_t(uint64_t a, uint64_t b) { +#if defined(__OPENCL_VERSION__) + return mul_hi(a, b); +#elif defined(__CUDA_ARCH__) + return (uint64_t) __umul64hi((unsigned long long) a, (unsigned long long) b); +#elif defined(_MSC_VER) && defined(_M_X64) + return (uint64_t) __umulh((unsigned __int64) a, (unsigned __int64) b); +#elif defined(__GNUC__) && defined(__SIZEOF_INT128__) + return (uint64_t) (((((unsigned __int128) a) * ((unsigned __int128) b))) >> 64); +#else + const uint32_t a_lo = (uint32_t) a; + const uint32_t a_hi = (uint32_t) (a >> 32); + const uint32_t b_lo = (uint32_t) b; + const uint32_t b_hi = (uint32_t) (b >> 32); + + const uint64_t t = fxdiv_mulext_uint32_t(a_hi, b_lo) + + (uint64_t) fxdiv_mulhi_uint32_t(a_lo, b_lo); + return fxdiv_mulext_uint32_t(a_hi, b_hi) + (t >> 32) + + ((fxdiv_mulext_uint32_t(a_lo, b_hi) + (uint64_t) (uint32_t) t) >> 32); +#endif +} + +static inline size_t fxdiv_mulhi_size_t(size_t a, size_t b) { +#if SIZE_MAX == UINT32_MAX + return (size_t) fxdiv_mulhi_uint32_t((uint32_t) a, (uint32_t) b); +#elif SIZE_MAX == UINT64_MAX + return (size_t) fxdiv_mulhi_uint64_t((uint64_t) a, (uint64_t) b); +#else + #error Unsupported platform +#endif +} + +struct fxdiv_divisor_uint32_t { + uint32_t value; + uint32_t m; + uint8_t s1; + uint8_t s2; +}; + +struct fxdiv_result_uint32_t { + uint32_t quotient; + uint32_t remainder; +}; + +struct fxdiv_divisor_uint64_t { + uint64_t value; + uint64_t m; + uint8_t s1; + uint8_t s2; +}; + +struct fxdiv_result_uint64_t { + uint64_t quotient; + uint64_t remainder; +}; + +struct fxdiv_divisor_size_t { + size_t value; + size_t m; + uint8_t s1; + uint8_t s2; +}; + +struct fxdiv_result_size_t { + size_t quotient; + size_t remainder; +}; + +static inline struct fxdiv_divisor_uint32_t fxdiv_init_uint32_t(uint32_t d) { + struct fxdiv_divisor_uint32_t result = { d }; + if (d == 1) { + result.m = UINT32_C(1); + result.s1 = 0; + result.s2 = 0; + } else { + #if defined(__OPENCL_VERSION__) + const uint32_t l_minus_1 = 31 - clz(d - 1); + #elif defined(__CUDA_ARCH__) + const uint32_t l_minus_1 = 31 - __clz((int) (d - 1)); + #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64)) + unsigned long l_minus_1; + _BitScanReverse(&l_minus_1, (unsigned long) (d - 1)); + #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && FXDIV_USE_INLINE_ASSEMBLY + uint32_t l_minus_1; + __asm__("BSRL %[d_minus_1], %[l_minus_1]" + : [l_minus_1] "=r" (l_minus_1) + : [d_minus_1] "r" (d - 1) + : "cc"); + #elif defined(__GNUC__) + const uint32_t l_minus_1 = 31 - __builtin_clz(d - 1); + #else + /* Based on Algorithm 2 from Hacker's delight */ + + uint32_t l_minus_1 = 0; + uint32_t x = d - 1; + uint32_t y = x >> 16; + if (y != 0) { + l_minus_1 += 16; + x = y; + } + y = x >> 8; + if (y != 0) { + l_minus_1 += 8; + x = y; + } + y = x >> 4; + if (y != 0) { + l_minus_1 += 4; + x = y; + } + y = x >> 2; + if (y != 0) { + l_minus_1 += 2; + x = y; + } + if ((x & 2) != 0) { + l_minus_1 += 1; + } + #endif + uint32_t u_hi = (UINT32_C(2) << (uint32_t) l_minus_1) - d; + + /* Division of 64-bit number u_hi:UINT32_C(0) by 32-bit number d, 32-bit quotient output q */ + #if defined(__GNUC__) && defined(__i386__) && FXDIV_USE_INLINE_ASSEMBLY + uint32_t q; + __asm__("DIVL %[d]" + : "=a" (q), "+d" (u_hi) + : [d] "r" (d), "a" (0) + : "cc"); + #elif (defined(_MSC_VER) && _MSC_VER >= 1920) && !defined(__clang__) && !defined(__INTEL_COMPILER) && (defined(_M_IX86) || defined(_M_X64)) + unsigned int remainder; + const uint32_t q = (uint32_t) _udiv64((unsigned __int64) ((uint64_t) u_hi << 32), (unsigned int) d, &remainder); + #else + const uint32_t q = ((uint64_t) u_hi << 32) / d; + #endif + + result.m = q + UINT32_C(1); + result.s1 = 1; + result.s2 = (uint8_t) l_minus_1; + } + return result; +} + +static inline struct fxdiv_divisor_uint64_t fxdiv_init_uint64_t(uint64_t d) { + struct fxdiv_divisor_uint64_t result = { d }; + if (d == 1) { + result.m = UINT64_C(1); + result.s1 = 0; + result.s2 = 0; + } else { + #if defined(__OPENCL_VERSION__) + const uint32_t nlz_d = clz(d); + const uint32_t l_minus_1 = 63 - clz(d - 1); + #elif defined(__CUDA_ARCH__) + const uint32_t nlz_d = __clzll((long long) d); + const uint32_t l_minus_1 = 63 - __clzll((long long) (d - 1)); + #elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) + unsigned long l_minus_1; + _BitScanReverse64(&l_minus_1, (unsigned __int64) (d - 1)); + unsigned long bsr_d; + _BitScanReverse64(&bsr_d, (unsigned __int64) d); + const uint32_t nlz_d = bsr_d ^ 0x3F; + #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_ARM)) + const uint64_t d_minus_1 = d - 1; + const uint8_t d_is_power_of_2 = (d & d_minus_1) == 0; + unsigned long l_minus_1; + if ((uint32_t) (d_minus_1 >> 32) == 0) { + _BitScanReverse(&l_minus_1, (unsigned long) d_minus_1); + } else { + _BitScanReverse(&l_minus_1, (unsigned long) (uint32_t) (d_minus_1 >> 32)); + l_minus_1 += 32; + } + const uint32_t nlz_d = ((uint8_t) l_minus_1 ^ UINT8_C(0x3F)) - d_is_power_of_2; + #elif defined(__GNUC__) && defined(__x86_64__) && FXDIV_USE_INLINE_ASSEMBLY + uint64_t l_minus_1; + __asm__("BSRQ %[d_minus_1], %[l_minus_1]" + : [l_minus_1] "=r" (l_minus_1) + : [d_minus_1] "r" (d - 1) + : "cc"); + #elif defined(__GNUC__) + const uint32_t l_minus_1 = 63 - __builtin_clzll(d - 1); + const uint32_t nlz_d = __builtin_clzll(d); + #else + /* Based on Algorithm 2 from Hacker's delight */ + const uint64_t d_minus_1 = d - 1; + const uint32_t d_is_power_of_2 = (d & d_minus_1) == 0; + uint32_t l_minus_1 = 0; + uint32_t x = (uint32_t) d_minus_1; + uint32_t y = d_minus_1 >> 32; + if (y != 0) { + l_minus_1 += 32; + x = y; + } + y = x >> 16; + if (y != 0) { + l_minus_1 += 16; + x = y; + } + y = x >> 8; + if (y != 0) { + l_minus_1 += 8; + x = y; + } + y = x >> 4; + if (y != 0) { + l_minus_1 += 4; + x = y; + } + y = x >> 2; + if (y != 0) { + l_minus_1 += 2; + x = y; + } + if ((x & 2) != 0) { + l_minus_1 += 1; + } + const uint32_t nlz_d = (l_minus_1 ^ UINT32_C(0x3F)) - d_is_power_of_2; + #endif + uint64_t u_hi = (UINT64_C(2) << (uint32_t) l_minus_1) - d; + + /* Division of 128-bit number u_hi:UINT64_C(0) by 64-bit number d, 64-bit quotient output q */ + #if defined(__GNUC__) && defined(__x86_64__) && FXDIV_USE_INLINE_ASSEMBLY + uint64_t q; + __asm__("DIVQ %[d]" + : "=a" (q), "+d" (u_hi) + : [d] "r" (d), "a" (UINT64_C(0)) + : "cc"); + #elif 0 && defined(__GNUC__) && defined(__SIZEOF_INT128__) + /* GCC, Clang, and Intel Compiler fail to inline optimized implementation and call into support library for 128-bit division */ + const uint64_t q = (uint64_t) (((unsigned __int128) u_hi << 64) / ((unsigned __int128) d)); + #elif (defined(_MSC_VER) && _MSC_VER >= 1920) && !defined(__clang__) && !defined(__INTEL_COMPILER) && defined(_M_X64) + unsigned __int64 remainder; + const uint64_t q = (uint64_t) _udiv128((unsigned __int64) u_hi, 0, (unsigned __int64) d, &remainder); + #else + /* Implementation based on code from Hacker's delight */ + + /* Normalize divisor and shift divident left */ + d <<= nlz_d; + u_hi <<= nlz_d; + /* Break divisor up into two 32-bit digits */ + const uint64_t d_hi = (uint32_t) (d >> 32); + const uint32_t d_lo = (uint32_t) d; + + /* Compute the first quotient digit, q1 */ + uint64_t q1 = u_hi / d_hi; + uint64_t r1 = u_hi - q1 * d_hi; + + while ((q1 >> 32) != 0 || fxdiv_mulext_uint32_t((uint32_t) q1, d_lo) > (r1 << 32)) { + q1 -= 1; + r1 += d_hi; + if ((r1 >> 32) != 0) { + break; + } + } + + /* Multiply and subtract. */ + u_hi = (u_hi << 32) - q1 * d; + + /* Compute the second quotient digit, q0 */ + uint64_t q0 = u_hi / d_hi; + uint64_t r0 = u_hi - q0 * d_hi; + + while ((q0 >> 32) != 0 || fxdiv_mulext_uint32_t((uint32_t) q0, d_lo) > (r0 << 32)) { + q0 -= 1; + r0 += d_hi; + if ((r0 >> 32) != 0) { + break; + } + } + const uint64_t q = (q1 << 32) | (uint32_t) q0; + #endif + result.m = q + UINT64_C(1); + result.s1 = 1; + result.s2 = (uint8_t) l_minus_1; + } + return result; +} + +static inline struct fxdiv_divisor_size_t fxdiv_init_size_t(size_t d) { +#if SIZE_MAX == UINT32_MAX + const struct fxdiv_divisor_uint32_t uint_result = fxdiv_init_uint32_t((uint32_t) d); +#elif SIZE_MAX == UINT64_MAX + const struct fxdiv_divisor_uint64_t uint_result = fxdiv_init_uint64_t((uint64_t) d); +#else + #error Unsupported platform +#endif + struct fxdiv_divisor_size_t size_result = { + (size_t) uint_result.value, + (size_t) uint_result.m, + uint_result.s1, + uint_result.s2 + }; + return size_result; +} + +static inline uint32_t fxdiv_quotient_uint32_t(uint32_t n, const struct fxdiv_divisor_uint32_t divisor) { + const uint32_t t = fxdiv_mulhi_uint32_t(n, divisor.m); + return (t + ((n - t) >> divisor.s1)) >> divisor.s2; +} + +static inline uint64_t fxdiv_quotient_uint64_t(uint64_t n, const struct fxdiv_divisor_uint64_t divisor) { + const uint64_t t = fxdiv_mulhi_uint64_t(n, divisor.m); + return (t + ((n - t) >> divisor.s1)) >> divisor.s2; +} + +static inline size_t fxdiv_quotient_size_t(size_t n, const struct fxdiv_divisor_size_t divisor) { +#if SIZE_MAX == UINT32_MAX + const struct fxdiv_divisor_uint32_t uint32_divisor = { + (uint32_t) divisor.value, + (uint32_t) divisor.m, + divisor.s1, + divisor.s2 + }; + return fxdiv_quotient_uint32_t((uint32_t) n, uint32_divisor); +#elif SIZE_MAX == UINT64_MAX + const struct fxdiv_divisor_uint64_t uint64_divisor = { + (uint64_t) divisor.value, + (uint64_t) divisor.m, + divisor.s1, + divisor.s2 + }; + return fxdiv_quotient_uint64_t((uint64_t) n, uint64_divisor); +#else + #error Unsupported platform +#endif +} + +static inline uint32_t fxdiv_remainder_uint32_t(uint32_t n, const struct fxdiv_divisor_uint32_t divisor) { + const uint32_t quotient = fxdiv_quotient_uint32_t(n, divisor); + return n - quotient * divisor.value; +} + +static inline uint64_t fxdiv_remainder_uint64_t(uint64_t n, const struct fxdiv_divisor_uint64_t divisor) { + const uint64_t quotient = fxdiv_quotient_uint64_t(n, divisor); + return n - quotient * divisor.value; +} + +static inline size_t fxdiv_remainder_size_t(size_t n, const struct fxdiv_divisor_size_t divisor) { + const size_t quotient = fxdiv_quotient_size_t(n, divisor); + return n - quotient * divisor.value; +} + +static inline uint32_t fxdiv_round_down_uint32_t(uint32_t n, const struct fxdiv_divisor_uint32_t granularity) { + const uint32_t quotient = fxdiv_quotient_uint32_t(n, granularity); + return quotient * granularity.value; +} + +static inline uint64_t fxdiv_round_down_uint64_t(uint64_t n, const struct fxdiv_divisor_uint64_t granularity) { + const uint64_t quotient = fxdiv_quotient_uint64_t(n, granularity); + return quotient * granularity.value; +} + +static inline size_t fxdiv_round_down_size_t(size_t n, const struct fxdiv_divisor_size_t granularity) { + const size_t quotient = fxdiv_quotient_size_t(n, granularity); + return quotient * granularity.value; +} + +static inline struct fxdiv_result_uint32_t fxdiv_divide_uint32_t(uint32_t n, const struct fxdiv_divisor_uint32_t divisor) { + const uint32_t quotient = fxdiv_quotient_uint32_t(n, divisor); + const uint32_t remainder = n - quotient * divisor.value; + struct fxdiv_result_uint32_t result = { quotient, remainder }; + return result; +} + +static inline struct fxdiv_result_uint64_t fxdiv_divide_uint64_t(uint64_t n, const struct fxdiv_divisor_uint64_t divisor) { + const uint64_t quotient = fxdiv_quotient_uint64_t(n, divisor); + const uint64_t remainder = n - quotient * divisor.value; + struct fxdiv_result_uint64_t result = { quotient, remainder }; + return result; +} + +static inline struct fxdiv_result_size_t fxdiv_divide_size_t(size_t n, const struct fxdiv_divisor_size_t divisor) { + const size_t quotient = fxdiv_quotient_size_t(n, divisor); + const size_t remainder = n - quotient * divisor.value; + struct fxdiv_result_size_t result = { quotient, remainder }; + return result; +} + +#endif /* FXDIV_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify-zca.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify-zca.h new file mode 100644 index 0000000000000000000000000000000000000000..b67e229749262849bf6a7947afc4a1470c730c65 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify-zca.h @@ -0,0 +1,86 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + Copyright (C) 2005-2019 Intel Corporation + + SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause +*/ + +/** + * Zero Cost Annotations (ZCA) + * + * Intel Compiler supports two intrinsics that could be used for code annotations + * without incurring significant run-time costs when the tools are not in use. + * Each annotation is more than a mere mark in the instruction stream. + * It can accept an expression argument like a call to a routine does. + * There are two forms of the intrinsic, with the following signatures: + * + * extern "C" void __notify_intrinsic( const char *annotation, const volatile void *tag); + * extern "C" void __notify_zc_intrinsic(const char *annotation, const volatile void *tag); + * + * The string annotation must be a compile-time constant. It specifies the type of the annotation. + * The pointer tag is computed at run time. It specifies the data associated with the annotation. + * Each intrinsic implies a compiler fence: the compiler must not move any memory + * operation across it. The reason for this restriction is that annotation might denote an + * event that must be precisely placed with respect to memory operations. + * + * The difference between the two intrinsics is that __notify_intrinsic must leave a + * probe-ready instruction sequence in the instruction stream where the instrinsic + * occurs. The __notify_zc_intrinsic does not leave such a sequence, and hence is closer to "zero cost". + **/ + +#pragma once +#include "ittnotify.h" + +#ifndef INTEL_NO_ITTNOTIFY_API +#if (defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER)) && (ITT_PLATFORM == ITT_PLATFORM_WIN || ITT_PLATFORM == ITT_PLATFORM_POSIX) +#define ITT_ENABLE_LOW_OVERHEAD_ANNOTATIONS +#else +#error Zero cost (low overhead) annotations are not supported on this platform +#endif +#endif + +/** + * Zero cost annotations for memory allocation and deallocation + **/ +#ifdef ITT_ENABLE_LOW_OVERHEAD_ANNOTATIONS +#pragma pack(push, 1) +typedef struct ___itt_zca_allocation_info { + size_t size; /*!< Size of allocated memory */ + void** ptr; /*!< Pointer to allocated memory pointer */ + int initialized; /*!< Is allocated memory initialized */ +} __itt_zca_allocation_info; +#pragma pack(pop) + +#define __itt_zca_mem_allocate_begin() __notify_intrinsic((char*)"mem_allocate_begin", 0) +#define __itt_zca_mem_allocate_end(ptr, size, init) { __itt_zca_allocation_info __itt_zca_alloc_info = { size, ptr, init }; __notify_intrinsic((char*)"mem_allocate_end", (void*)&__itt_zca_alloc_info); } +#define __itt_zca_mem_free_begin(ptr) __notify_intrinsic((char*)"mem_free_begin", (void*)ptr) +#define __itt_zca_mem_free_end() __notify_intrinsic((char*)"mem_free_end", 0) +#else +#define __itt_zca_mem_allocate_begin() +#define __itt_zca_mem_allocate_end(ptr, size, init) +#define __itt_zca_mem_free_begin(ptr) +#define __itt_zca_mem_free_end() +#endif + +/** + * Zero cost annotations for threading + **/ +#ifdef ITT_ENABLE_LOW_OVERHEAD_ANNOTATIONS +#define __itt_zca_suppress_push(id) __notify_zc_intrinsic((char*)"__itt_suppress_push", (void*)id); +#define __itt_zca_suppress_pop(id) __notify_zc_intrinsic((char*)"__itt_suppress_pop", (void*)id); +#define __itt_zca_sync_create(id) __notify_zc_intrinsic((char*)"__itt_sync_create", (void*)id) +#define __itt_zca_sync_acquired(id) __notify_zc_intrinsic((char*)"__itt_sync_acquired", (void*)id) +#define __itt_zca_sync_releasing(id) __notify_zc_intrinsic((char*)"__itt_sync_releasing", (void*)id) +#define __itt_zca_sync_destroy(id) __notify_zc_intrinsic((char*)"__itt_sync_destroy", (void*)id) +#else +#define __itt_zca_suppress_push(id) +#define __itt_zca_suppress_pop(id) +#define __itt_zca_sync_create(id) +#define __itt_zca_sync_acquired(id) +#define __itt_zca_sync_releasing(id) +#define __itt_zca_sync_destroy(id) +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify.h new file mode 100644 index 0000000000000000000000000000000000000000..37328bf8211232f97b866f1113bbcda4b49dda7c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify.h @@ -0,0 +1,4721 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + Copyright (C) 2005-2019 Intel Corporation + + SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause +*/ +#ifndef _ITTNOTIFY_H_ +#define _ITTNOTIFY_H_ + +/** +@file +@brief Public User API functions and types +@mainpage + +The Instrumentation and Tracing Technology API (ITT API) is used to +annotate a user's program with additional information +that can be used by correctness and performance tools. The user inserts +calls in their program. Those calls generate information that is collected +at runtime, and used by Intel(R) Threading Tools. + +@section API Concepts +The following general concepts are used throughout the API. + +@subsection Unicode Support +Many API functions take character string arguments. On Windows, there +are two versions of each such function. The function name is suffixed +by W if Unicode support is enabled, and by A otherwise. Any API function +that takes a character string argument adheres to this convention. + +@subsection Conditional Compilation +Many users prefer having an option to modify ITT API code when linking it +inside their runtimes. ITT API header file provides a mechanism to replace +ITT API function names inside your code with empty strings. To do this, +define the macros INTEL_NO_ITTNOTIFY_API during compilation and remove the +static library from the linker script. + +@subsection Domains +[see domains] +Domains provide a way to separate notification for different modules or +libraries in a program. Domains are specified by dotted character strings, +e.g. TBB.Internal.Control. + +A mechanism (to be specified) is provided to enable and disable +domains. By default, all domains are enabled. +@subsection Named Entities and Instances +Named entities (frames, regions, tasks, and markers) communicate +information about the program to the analysis tools. A named entity often +refers to a section of program code, or to some set of logical concepts +that the programmer wants to group together. + +Named entities relate to the programmer's static view of the program. When +the program actually executes, many instances of a given named entity +may be created. + +The API annotations denote instances of named entities. The actual +named entities are displayed using the analysis tools. In other words, +the named entities come into existence when instances are created. + +Instances of named entities may have instance identifiers (IDs). Some +API calls use instance identifiers to create relationships between +different instances of named entities. Other API calls associate data +with instances of named entities. + +Some named entities must always have instance IDs. In particular, regions +and frames always have IDs. Task and markers need IDs only if the ID is +needed in another API call (such as adding a relation or metadata). + +The lifetime of instance IDs is distinct from the lifetime of +instances. This allows various relationships to be specified separate +from the actual execution of instances. This flexibility comes at the +expense of extra API calls. + +The same ID may not be reused for different instances, unless a previous +[ref] __itt_id_destroy call for that ID has been issued. +*/ + +/** @cond exclude_from_documentation */ +#ifndef ITT_OS_WIN +# define ITT_OS_WIN 1 +#endif /* ITT_OS_WIN */ + +#ifndef ITT_OS_LINUX +# define ITT_OS_LINUX 2 +#endif /* ITT_OS_LINUX */ + +#ifndef ITT_OS_MAC +# define ITT_OS_MAC 3 +#endif /* ITT_OS_MAC */ + +#ifndef ITT_OS_FREEBSD +# define ITT_OS_FREEBSD 4 +#endif /* ITT_OS_FREEBSD */ + +#ifndef ITT_OS_OPENBSD +# define ITT_OS_OPENBSD 5 +#endif /* ITT_OS_OPENBSD */ + +#ifndef ITT_OS +# if defined WIN32 || defined _WIN32 +# define ITT_OS ITT_OS_WIN +# elif defined( __APPLE__ ) && defined( __MACH__ ) +# define ITT_OS ITT_OS_MAC +# elif defined( __FreeBSD__ ) +# define ITT_OS ITT_OS_FREEBSD +# elif defined( __OpenBSD__) +# define ITT_OS ITT_OS_OPENBSD +# else +# define ITT_OS ITT_OS_LINUX +# endif +#endif /* ITT_OS */ + +#ifndef ITT_PLATFORM_WIN +# define ITT_PLATFORM_WIN 1 +#endif /* ITT_PLATFORM_WIN */ + +#ifndef ITT_PLATFORM_POSIX +# define ITT_PLATFORM_POSIX 2 +#endif /* ITT_PLATFORM_POSIX */ + +#ifndef ITT_PLATFORM_MAC +# define ITT_PLATFORM_MAC 3 +#endif /* ITT_PLATFORM_MAC */ + +#ifndef ITT_PLATFORM_FREEBSD +# define ITT_PLATFORM_FREEBSD 4 +#endif /* ITT_PLATFORM_FREEBSD */ + +#ifndef ITT_PLATFORM_OPENBSD +# define ITT_PLATFORM_OPENBSD 5 +#endif /* ITT_PLATFORM_OPENBSD */ + +#ifndef ITT_PLATFORM +# if ITT_OS==ITT_OS_WIN +# define ITT_PLATFORM ITT_PLATFORM_WIN +# elif ITT_OS==ITT_OS_MAC +# define ITT_PLATFORM ITT_PLATFORM_MAC +# elif ITT_OS==ITT_OS_FREEBSD +# define ITT_PLATFORM ITT_PLATFORM_FREEBSD +# elif ITT_OS==ITT_OS_OPENBSD +# define ITT_PLATFORM ITT_PLATFORM_OPENBSD +# else +# define ITT_PLATFORM ITT_PLATFORM_POSIX +# endif +#endif /* ITT_PLATFORM */ + +#if defined(_UNICODE) && !defined(UNICODE) +#define UNICODE +#endif + +#include +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#include +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#include +#if defined(UNICODE) || defined(_UNICODE) +#include +#endif /* UNICODE || _UNICODE */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef ITTAPI_CDECL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define ITTAPI_CDECL __cdecl +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define ITTAPI_CDECL __attribute__ ((cdecl)) +# else /* _M_IX86 || __i386__ */ +# define ITTAPI_CDECL /* actual only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* ITTAPI_CDECL */ + +#ifndef STDCALL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define STDCALL __stdcall +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define STDCALL __attribute__ ((stdcall)) +# else /* _M_IX86 || __i386__ */ +# define STDCALL /* supported only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* STDCALL */ + +#define ITTAPI ITTAPI_CDECL +#define LIBITTAPI ITTAPI_CDECL + +/* TODO: Temporary for compatibility! */ +#define ITTAPI_CALL ITTAPI_CDECL +#define LIBITTAPI_CALL ITTAPI_CDECL + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +/* use __forceinline (VC++ specific) */ +#if defined(__MINGW32__) && !defined(__cplusplus) +#define ITT_INLINE static __inline__ __attribute__((__always_inline__,__gnu_inline__)) +#else +#define ITT_INLINE static __forceinline +#endif /* __MINGW32__ */ + +#define ITT_INLINE_ATTRIBUTE /* nothing */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/* + * Generally, functions are not inlined unless optimization is specified. + * For functions declared inline, this attribute inlines the function even + * if no optimization level was specified. + */ +#ifdef __STRICT_ANSI__ +#define ITT_INLINE static +#define ITT_INLINE_ATTRIBUTE __attribute__((unused)) +#else /* __STRICT_ANSI__ */ +#define ITT_INLINE static inline +#define ITT_INLINE_ATTRIBUTE __attribute__((always_inline, unused)) +#endif /* __STRICT_ANSI__ */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/** @endcond */ + +#ifdef INTEL_ITTNOTIFY_ENABLE_LEGACY +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# pragma message("WARNING!!! Deprecated API is used. Please undefine INTEL_ITTNOTIFY_ENABLE_LEGACY macro") +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# warning "Deprecated API is used. Please undefine INTEL_ITTNOTIFY_ENABLE_LEGACY macro" +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# include "legacy/ittnotify.h" +#endif /* INTEL_ITTNOTIFY_ENABLE_LEGACY */ + +/** @cond exclude_from_documentation */ +/* Helper macro for joining tokens */ +#define ITT_JOIN_AUX(p,n) p##n +#define ITT_JOIN(p,n) ITT_JOIN_AUX(p,n) + +#ifdef ITT_MAJOR +#undef ITT_MAJOR +#endif +#ifdef ITT_MINOR +#undef ITT_MINOR +#endif +#define ITT_MAJOR 3 +#define ITT_MINOR 0 + +/* Standard versioning of a token with major and minor version numbers */ +#define ITT_VERSIONIZE(x) \ + ITT_JOIN(x, \ + ITT_JOIN(_, \ + ITT_JOIN(ITT_MAJOR, \ + ITT_JOIN(_, ITT_MINOR)))) + +#ifndef INTEL_ITTNOTIFY_PREFIX +# define INTEL_ITTNOTIFY_PREFIX __itt_ +#endif /* INTEL_ITTNOTIFY_PREFIX */ +#ifndef INTEL_ITTNOTIFY_POSTFIX +# define INTEL_ITTNOTIFY_POSTFIX _ptr_ +#endif /* INTEL_ITTNOTIFY_POSTFIX */ + +#define ITTNOTIFY_NAME_AUX(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) +#define ITTNOTIFY_NAME(n) ITT_VERSIONIZE(ITTNOTIFY_NAME_AUX(ITT_JOIN(n,INTEL_ITTNOTIFY_POSTFIX))) + +#define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n) +#define ITTNOTIFY_DATA(n) (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n) + +#define ITTNOTIFY_VOID_D0(n,d) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d) +#define ITTNOTIFY_VOID_D1(n,d,x) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x) +#define ITTNOTIFY_VOID_D2(n,d,x,y) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y) +#define ITTNOTIFY_VOID_D3(n,d,x,y,z) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z) +#define ITTNOTIFY_VOID_D4(n,d,x,y,z,a) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) +#define ITTNOTIFY_VOID_D5(n,d,x,y,z,a,b) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) +#define ITTNOTIFY_VOID_D6(n,d,x,y,z,a,b,c) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) +#define ITTNOTIFY_VOID_D2_VA(n,d,x,...) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,__VA_ARGS__) +#define ITTNOTIFY_VOID_D3_VA(n,d,x,y,...) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,__VA_ARGS__) +#define ITTNOTIFY_DATA_D0(n,d) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d) +#define ITTNOTIFY_DATA_D1(n,d,x) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x) +#define ITTNOTIFY_DATA_D2(n,d,x,y) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y) +#define ITTNOTIFY_DATA_D3(n,d,x,y,z) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z) +#define ITTNOTIFY_DATA_D4(n,d,x,y,z,a) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) +#define ITTNOTIFY_DATA_D5(n,d,x,y,z,a,b) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) +#define ITTNOTIFY_DATA_D6(n,d,x,y,z,a,b,c) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) + +#ifdef ITT_STUB +#undef ITT_STUB +#endif +#ifdef ITT_STUBV +#undef ITT_STUBV +#endif +#define ITT_STUBV(api,type,name,args) \ + typedef type (api* ITT_JOIN(ITTNOTIFY_NAME(name),_t)) args; \ + extern ITT_JOIN(ITTNOTIFY_NAME(name),_t) ITTNOTIFY_NAME(name); +#define ITT_STUB ITT_STUBV +/** @endcond */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @cond exclude_from_gpa_documentation */ +/** + * @defgroup public Public API + * @{ + * @} + */ + +/** + * @defgroup control Collection Control + * @ingroup public + * General behavior: application continues to run, but no profiling information is being collected + * + * Pausing occurs not only for the current thread but for all process as well as spawned processes + * - Intel(R) Parallel Inspector and Intel(R) Inspector XE: + * - Does not analyze or report errors that involve memory access. + * - Other errors are reported as usual. Pausing data collection in + * Intel(R) Parallel Inspector and Intel(R) Inspector XE + * only pauses tracing and analyzing memory access. + * It does not pause tracing or analyzing threading APIs. + * . + * - Intel(R) VTune(TM) Profiler: + * - Does continue to record when new threads are started. + * . + * - Other effects: + * - Possible reduction of runtime overhead. + * . + * @{ + */ +/** @brief Pause collection */ +void ITTAPI __itt_pause(void); +/** @brief Resume collection */ +void ITTAPI __itt_resume(void); +/** @brief Detach collection */ +void ITTAPI __itt_detach(void); + +/** + * @enum __itt_collection_scope + * @brief Enumerator for collection scopes + */ +typedef enum { + __itt_collection_scope_host = 1 << 0, + __itt_collection_scope_offload = 1 << 1, + __itt_collection_scope_all = 0x7FFFFFFF +} __itt_collection_scope; + +/** @brief Pause scoped collection */ +void ITTAPI __itt_pause_scoped(__itt_collection_scope); +/** @brief Resume scoped collection */ +void ITTAPI __itt_resume_scoped(__itt_collection_scope); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, pause, (void)) +ITT_STUBV(ITTAPI, void, pause_scoped, (__itt_collection_scope)) +ITT_STUBV(ITTAPI, void, resume, (void)) +ITT_STUBV(ITTAPI, void, resume_scoped, (__itt_collection_scope)) +ITT_STUBV(ITTAPI, void, detach, (void)) +#define __itt_pause ITTNOTIFY_VOID(pause) +#define __itt_pause_ptr ITTNOTIFY_NAME(pause) +#define __itt_pause_scoped ITTNOTIFY_VOID(pause_scoped) +#define __itt_pause_scoped_ptr ITTNOTIFY_NAME(pause_scoped) +#define __itt_resume ITTNOTIFY_VOID(resume) +#define __itt_resume_ptr ITTNOTIFY_NAME(resume) +#define __itt_resume_scoped ITTNOTIFY_VOID(resume_scoped) +#define __itt_resume_scoped_ptr ITTNOTIFY_NAME(resume_scoped) +#define __itt_detach ITTNOTIFY_VOID(detach) +#define __itt_detach_ptr ITTNOTIFY_NAME(detach) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_pause() +#define __itt_pause_ptr 0 +#define __itt_pause_scoped(scope) +#define __itt_pause_scoped_ptr 0 +#define __itt_resume() +#define __itt_resume_ptr 0 +#define __itt_resume_scoped(scope) +#define __itt_resume_scoped_ptr 0 +#define __itt_detach() +#define __itt_detach_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_pause_ptr 0 +#define __itt_pause_scoped_ptr 0 +#define __itt_resume_ptr 0 +#define __itt_resume_scoped_ptr 0 +#define __itt_detach_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} control group */ +/** @endcond */ + +/** + * @defgroup Intel Processor Trace control + * API from this group provides control over collection and analysis of Intel Processor Trace (Intel PT) data + * Information about Intel Processor Trace technology can be found here (Volume 3 chapter 35): + * https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf + * Use this API to mark particular code regions for loading detailed performance statistics. + * This mode makes your analysis faster and more accurate. + * @{ +*/ +typedef unsigned char __itt_pt_region; + +/** + * @brief function saves a region name marked with Intel PT API and returns a region id. + * Only 7 names can be registered. Attempts to register more names will be ignored and a region id with auto names will be returned. + * For automatic naming of regions pass NULL as function parameter +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_pt_region ITTAPI __itt_pt_region_createA(const char *name); +__itt_pt_region ITTAPI __itt_pt_region_createW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_pt_region_create __itt_pt_region_createW +#else /* UNICODE */ +# define __itt_pt_region_create __itt_pt_region_createA +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_pt_region ITTAPI __itt_pt_region_create(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_pt_region, pt_region_createA, (const char *name)) +ITT_STUB(ITTAPI, __itt_pt_region, pt_region_createW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_pt_region, pt_region_create, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_pt_region_createA ITTNOTIFY_DATA(pt_region_createA) +#define __itt_pt_region_createA_ptr ITTNOTIFY_NAME(pt_region_createA) +#define __itt_pt_region_createW ITTNOTIFY_DATA(pt_region_createW) +#define __itt_pt_region_createW_ptr ITTNOTIFY_NAME(pt_region_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_pt_region_create ITTNOTIFY_DATA(pt_region_create) +#define __itt_pt_region_create_ptr ITTNOTIFY_NAME(pt_region_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_pt_region_createA(name) (__itt_pt_region)0 +#define __itt_pt_region_createA_ptr 0 +#define __itt_pt_region_createW(name) (__itt_pt_region)0 +#define __itt_pt_region_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_pt_region_create(name) (__itt_pt_region)0 +#define __itt_pt_region_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_pt_region_createA_ptr 0 +#define __itt_pt_region_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_pt_region_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief function contains a special code pattern identified on the post-processing stage and + * marks the beginning of a code region targeted for Intel PT analysis + * @param[in] region - region id, 0 <= region < 8 +*/ +void __itt_mark_pt_region_begin(__itt_pt_region region); +/** + * @brief function contains a special code pattern identified on the post-processing stage and + * marks the end of a code region targeted for Intel PT analysis + * @param[in] region - region id, 0 <= region < 8 +*/ +void __itt_mark_pt_region_end(__itt_pt_region region); +/** @} Intel PT control group*/ + +/** + * @defgroup threads Threads + * @ingroup public + * Give names to threads + * @{ + */ +/** + * @brief Sets thread name of calling thread + * @param[in] name - name of thread + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_thread_set_nameA(const char *name); +void ITTAPI __itt_thread_set_nameW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_thread_set_name __itt_thread_set_nameW +# define __itt_thread_set_name_ptr __itt_thread_set_nameW_ptr +#else /* UNICODE */ +# define __itt_thread_set_name __itt_thread_set_nameA +# define __itt_thread_set_name_ptr __itt_thread_set_nameA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_thread_set_name(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, thread_set_nameA, (const char *name)) +ITT_STUBV(ITTAPI, void, thread_set_nameW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, thread_set_name, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thread_set_nameA ITTNOTIFY_VOID(thread_set_nameA) +#define __itt_thread_set_nameA_ptr ITTNOTIFY_NAME(thread_set_nameA) +#define __itt_thread_set_nameW ITTNOTIFY_VOID(thread_set_nameW) +#define __itt_thread_set_nameW_ptr ITTNOTIFY_NAME(thread_set_nameW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thread_set_name ITTNOTIFY_VOID(thread_set_name) +#define __itt_thread_set_name_ptr ITTNOTIFY_NAME(thread_set_name) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thread_set_nameA(name) +#define __itt_thread_set_nameA_ptr 0 +#define __itt_thread_set_nameW(name) +#define __itt_thread_set_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thread_set_name(name) +#define __itt_thread_set_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thread_set_nameA_ptr 0 +#define __itt_thread_set_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thread_set_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @cond exclude_from_gpa_documentation */ + +/** + * @brief Mark current thread as ignored from this point on, for the duration of its existence. + */ +void ITTAPI __itt_thread_ignore(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, thread_ignore, (void)) +#define __itt_thread_ignore ITTNOTIFY_VOID(thread_ignore) +#define __itt_thread_ignore_ptr ITTNOTIFY_NAME(thread_ignore) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_thread_ignore() +#define __itt_thread_ignore_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_thread_ignore_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} threads group */ + +/** + * @defgroup suppress Error suppression + * @ingroup public + * General behavior: application continues to run, but errors are suppressed + * + * @{ + */ + +/*****************************************************************//** + * @name group of functions used for error suppression in correctness tools + *********************************************************************/ +/** @{ */ +/** + * @hideinitializer + * @brief possible value for suppression mask + */ +#define __itt_suppress_all_errors 0x7fffffff + +/** + * @hideinitializer + * @brief possible value for suppression mask (suppresses errors from threading analysis) + */ +#define __itt_suppress_threading_errors 0x000000ff + +/** + * @hideinitializer + * @brief possible value for suppression mask (suppresses errors from memory analysis) + */ +#define __itt_suppress_memory_errors 0x0000ff00 + +/** + * @brief Start suppressing errors identified in mask on this thread + */ +void ITTAPI __itt_suppress_push(unsigned int mask); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, suppress_push, (unsigned int mask)) +#define __itt_suppress_push ITTNOTIFY_VOID(suppress_push) +#define __itt_suppress_push_ptr ITTNOTIFY_NAME(suppress_push) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_suppress_push(mask) +#define __itt_suppress_push_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_suppress_push_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Undo the effects of the matching call to __itt_suppress_push + */ +void ITTAPI __itt_suppress_pop(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, suppress_pop, (void)) +#define __itt_suppress_pop ITTNOTIFY_VOID(suppress_pop) +#define __itt_suppress_pop_ptr ITTNOTIFY_NAME(suppress_pop) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_suppress_pop() +#define __itt_suppress_pop_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_suppress_pop_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @enum __itt_suppress_mode + * @brief Enumerator for the suppressing modes + */ +typedef enum __itt_suppress_mode { + __itt_unsuppress_range, + __itt_suppress_range +} __itt_suppress_mode_t; + +/** + * @enum __itt_collection_state + * @brief Enumerator for collection state. + */ +typedef enum { + __itt_collection_uninitialized = 0, /* uninitialized */ + __itt_collection_init_fail = 1, /* failed to init */ + __itt_collection_collector_absent = 2, /* non work state collector is absent */ + __itt_collection_collector_exists = 3, /* work state collector exists */ + __itt_collection_init_successful = 4 /* success to init */ +} __itt_collection_state; + +/** + * @brief Mark a range of memory for error suppression or unsuppression for error types included in mask + */ +void ITTAPI __itt_suppress_mark_range(__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, suppress_mark_range, (__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size)) +#define __itt_suppress_mark_range ITTNOTIFY_VOID(suppress_mark_range) +#define __itt_suppress_mark_range_ptr ITTNOTIFY_NAME(suppress_mark_range) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_suppress_mark_range(mask) +#define __itt_suppress_mark_range_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_suppress_mark_range_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Undo the effect of a matching call to __itt_suppress_mark_range. If not matching + * call is found, nothing is changed. + */ +void ITTAPI __itt_suppress_clear_range(__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, suppress_clear_range, (__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size)) +#define __itt_suppress_clear_range ITTNOTIFY_VOID(suppress_clear_range) +#define __itt_suppress_clear_range_ptr ITTNOTIFY_NAME(suppress_clear_range) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_suppress_clear_range(mask) +#define __itt_suppress_clear_range_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_suppress_clear_range_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} */ +/** @} suppress group */ + +/** + * @defgroup sync Synchronization + * @ingroup public + * Indicate user-written synchronization code + * @{ + */ +/** + * @hideinitializer + * @brief possible value of attribute argument for sync object type + */ +#define __itt_attr_barrier 1 + +/** + * @hideinitializer + * @brief possible value of attribute argument for sync object type + */ +#define __itt_attr_mutex 2 + +/** +@brief Name a synchronization object +@param[in] addr Handle for the synchronization object. You should +use a real address to uniquely identify the synchronization object. +@param[in] objtype null-terminated object type string. If NULL is +passed, the name will be "User Synchronization". +@param[in] objname null-terminated object name string. If NULL, +no name will be assigned to the object. +@param[in] attribute one of [#__itt_attr_barrier, #__itt_attr_mutex] + */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_sync_createA(void *addr, const char *objtype, const char *objname, int attribute); +void ITTAPI __itt_sync_createW(void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_sync_create __itt_sync_createW +# define __itt_sync_create_ptr __itt_sync_createW_ptr +#else /* UNICODE */ +# define __itt_sync_create __itt_sync_createA +# define __itt_sync_create_ptr __itt_sync_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_sync_create (void *addr, const char *objtype, const char *objname, int attribute); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, sync_createA, (void *addr, const char *objtype, const char *objname, int attribute)) +ITT_STUBV(ITTAPI, void, sync_createW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, sync_create, (void *addr, const char* objtype, const char* objname, int attribute)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_createA ITTNOTIFY_VOID(sync_createA) +#define __itt_sync_createA_ptr ITTNOTIFY_NAME(sync_createA) +#define __itt_sync_createW ITTNOTIFY_VOID(sync_createW) +#define __itt_sync_createW_ptr ITTNOTIFY_NAME(sync_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_create ITTNOTIFY_VOID(sync_create) +#define __itt_sync_create_ptr ITTNOTIFY_NAME(sync_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_createA(addr, objtype, objname, attribute) +#define __itt_sync_createA_ptr 0 +#define __itt_sync_createW(addr, objtype, objname, attribute) +#define __itt_sync_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_create(addr, objtype, objname, attribute) +#define __itt_sync_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_createA_ptr 0 +#define __itt_sync_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** +@brief Rename a synchronization object + +You can use the rename call to assign or reassign a name to a given +synchronization object. +@param[in] addr handle for the synchronization object. +@param[in] name null-terminated object name string. +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_sync_renameA(void *addr, const char *name); +void ITTAPI __itt_sync_renameW(void *addr, const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_sync_rename __itt_sync_renameW +# define __itt_sync_rename_ptr __itt_sync_renameW_ptr +#else /* UNICODE */ +# define __itt_sync_rename __itt_sync_renameA +# define __itt_sync_rename_ptr __itt_sync_renameA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_sync_rename(void *addr, const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, sync_renameA, (void *addr, const char *name)) +ITT_STUBV(ITTAPI, void, sync_renameW, (void *addr, const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, sync_rename, (void *addr, const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_renameA ITTNOTIFY_VOID(sync_renameA) +#define __itt_sync_renameA_ptr ITTNOTIFY_NAME(sync_renameA) +#define __itt_sync_renameW ITTNOTIFY_VOID(sync_renameW) +#define __itt_sync_renameW_ptr ITTNOTIFY_NAME(sync_renameW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_rename ITTNOTIFY_VOID(sync_rename) +#define __itt_sync_rename_ptr ITTNOTIFY_NAME(sync_rename) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_renameA(addr, name) +#define __itt_sync_renameA_ptr 0 +#define __itt_sync_renameW(addr, name) +#define __itt_sync_renameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_rename(addr, name) +#define __itt_sync_rename_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_renameA_ptr 0 +#define __itt_sync_renameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_rename_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + @brief Destroy a synchronization object. + @param addr Handle for the synchronization object. + */ +void ITTAPI __itt_sync_destroy(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_destroy, (void *addr)) +#define __itt_sync_destroy ITTNOTIFY_VOID(sync_destroy) +#define __itt_sync_destroy_ptr ITTNOTIFY_NAME(sync_destroy) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_destroy(addr) +#define __itt_sync_destroy_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_destroy_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/*****************************************************************//** + * @name group of functions is used for performance measurement tools + *********************************************************************/ +/** @{ */ +/** + * @brief Enter spin loop on user-defined sync object + */ +void ITTAPI __itt_sync_prepare(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_prepare, (void *addr)) +#define __itt_sync_prepare ITTNOTIFY_VOID(sync_prepare) +#define __itt_sync_prepare_ptr ITTNOTIFY_NAME(sync_prepare) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_prepare(addr) +#define __itt_sync_prepare_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_prepare_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Quit spin loop without acquiring spin object + */ +void ITTAPI __itt_sync_cancel(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_cancel, (void *addr)) +#define __itt_sync_cancel ITTNOTIFY_VOID(sync_cancel) +#define __itt_sync_cancel_ptr ITTNOTIFY_NAME(sync_cancel) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_cancel(addr) +#define __itt_sync_cancel_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_cancel_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Successful spin loop completion (sync object acquired) + */ +void ITTAPI __itt_sync_acquired(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_acquired, (void *addr)) +#define __itt_sync_acquired ITTNOTIFY_VOID(sync_acquired) +#define __itt_sync_acquired_ptr ITTNOTIFY_NAME(sync_acquired) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_acquired(addr) +#define __itt_sync_acquired_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_acquired_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Start sync object releasing code. Is called before the lock release call. + */ +void ITTAPI __itt_sync_releasing(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_releasing, (void *addr)) +#define __itt_sync_releasing ITTNOTIFY_VOID(sync_releasing) +#define __itt_sync_releasing_ptr ITTNOTIFY_NAME(sync_releasing) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_releasing(addr) +#define __itt_sync_releasing_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_releasing_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} */ + +/** @} sync group */ + +/**************************************************************//** + * @name group of functions is used for correctness checking tools + ******************************************************************/ +/** @{ */ +/** + * @ingroup legacy + * @deprecated Legacy API + * @brief Fast synchronization which does no require spinning. + * - This special function is to be used by TBB and OpenMP libraries only when they know + * there is no spin but they need to suppress TC warnings about shared variable modifications. + * - It only has corresponding pointers in static library and does not have corresponding function + * in dynamic library. + * @see void __itt_sync_prepare(void* addr); + */ +void ITTAPI __itt_fsync_prepare(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, fsync_prepare, (void *addr)) +#define __itt_fsync_prepare ITTNOTIFY_VOID(fsync_prepare) +#define __itt_fsync_prepare_ptr ITTNOTIFY_NAME(fsync_prepare) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_fsync_prepare(addr) +#define __itt_fsync_prepare_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_fsync_prepare_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup legacy + * @deprecated Legacy API + * @brief Fast synchronization which does no require spinning. + * - This special function is to be used by TBB and OpenMP libraries only when they know + * there is no spin but they need to suppress TC warnings about shared variable modifications. + * - It only has corresponding pointers in static library and does not have corresponding function + * in dynamic library. + * @see void __itt_sync_cancel(void *addr); + */ +void ITTAPI __itt_fsync_cancel(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, fsync_cancel, (void *addr)) +#define __itt_fsync_cancel ITTNOTIFY_VOID(fsync_cancel) +#define __itt_fsync_cancel_ptr ITTNOTIFY_NAME(fsync_cancel) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_fsync_cancel(addr) +#define __itt_fsync_cancel_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_fsync_cancel_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup legacy + * @deprecated Legacy API + * @brief Fast synchronization which does no require spinning. + * - This special function is to be used by TBB and OpenMP libraries only when they know + * there is no spin but they need to suppress TC warnings about shared variable modifications. + * - It only has corresponding pointers in static library and does not have corresponding function + * in dynamic library. + * @see void __itt_sync_acquired(void *addr); + */ +void ITTAPI __itt_fsync_acquired(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, fsync_acquired, (void *addr)) +#define __itt_fsync_acquired ITTNOTIFY_VOID(fsync_acquired) +#define __itt_fsync_acquired_ptr ITTNOTIFY_NAME(fsync_acquired) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_fsync_acquired(addr) +#define __itt_fsync_acquired_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_fsync_acquired_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup legacy + * @deprecated Legacy API + * @brief Fast synchronization which does no require spinning. + * - This special function is to be used by TBB and OpenMP libraries only when they know + * there is no spin but they need to suppress TC warnings about shared variable modifications. + * - It only has corresponding pointers in static library and does not have corresponding function + * in dynamic library. + * @see void __itt_sync_releasing(void* addr); + */ +void ITTAPI __itt_fsync_releasing(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, fsync_releasing, (void *addr)) +#define __itt_fsync_releasing ITTNOTIFY_VOID(fsync_releasing) +#define __itt_fsync_releasing_ptr ITTNOTIFY_NAME(fsync_releasing) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_fsync_releasing(addr) +#define __itt_fsync_releasing_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_fsync_releasing_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} */ + +/** + * @defgroup model Modeling by Intel(R) Parallel Advisor + * @ingroup public + * This is the subset of itt used for modeling by Intel(R) Parallel Advisor. + * This API is called ONLY using annotate.h, by "Annotation" macros + * the user places in their sources during the parallelism modeling steps. + * + * site_begin/end and task_begin/end take the address of handle variables, + * which are writeable by the API. Handles must be 0 initialized prior + * to the first call to begin, or may cause a run-time failure. + * The handles are initialized in a multi-thread safe way by the API if + * the handle is 0. The commonly expected idiom is one static handle to + * identify a site or task. If a site or task of the same name has already + * been started during this collection, the same handle MAY be returned, + * but is not required to be - it is unspecified if data merging is done + * based on name. These routines also take an instance variable. Like + * the lexical instance, these must be 0 initialized. Unlike the lexical + * instance, this is used to track a single dynamic instance. + * + * API used by the Intel(R) Parallel Advisor to describe potential concurrency + * and related activities. User-added source annotations expand to calls + * to these procedures to enable modeling of a hypothetical concurrent + * execution serially. + * @{ + */ +#if !defined(_ADVISOR_ANNOTATE_H_) || defined(ANNOTATE_EXPAND_NULL) + +typedef void* __itt_model_site; /*!< @brief handle for lexical site */ +typedef void* __itt_model_site_instance; /*!< @brief handle for dynamic instance */ +typedef void* __itt_model_task; /*!< @brief handle for lexical site */ +typedef void* __itt_model_task_instance; /*!< @brief handle for dynamic instance */ + +/** + * @enum __itt_model_disable + * @brief Enumerator for the disable methods + */ +typedef enum { + __itt_model_disable_observation, + __itt_model_disable_collection +} __itt_model_disable; + +#endif /* !_ADVISOR_ANNOTATE_H_ || ANNOTATE_EXPAND_NULL */ + +/** + * @brief ANNOTATE_SITE_BEGIN/ANNOTATE_SITE_END support. + * + * site_begin/end model a potential concurrency site. + * site instances may be recursively nested with themselves. + * site_end exits the most recently started but unended site for the current + * thread. The handle passed to end may be used to validate structure. + * Instances of a site encountered on different threads concurrently + * are considered completely distinct. If the site name for two different + * lexical sites match, it is unspecified whether they are treated as the + * same or different for data presentation. + */ +void ITTAPI __itt_model_site_begin(__itt_model_site *site, __itt_model_site_instance *instance, const char *name); +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_model_site_beginW(const wchar_t *name); +#endif +void ITTAPI __itt_model_site_beginA(const char *name); +void ITTAPI __itt_model_site_beginAL(const char *name, size_t siteNameLen); +void ITTAPI __itt_model_site_end (__itt_model_site *site, __itt_model_site_instance *instance); +void ITTAPI __itt_model_site_end_2(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_site_begin, (__itt_model_site *site, __itt_model_site_instance *instance, const char *name)) +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, model_site_beginW, (const wchar_t *name)) +#endif +ITT_STUBV(ITTAPI, void, model_site_beginA, (const char *name)) +ITT_STUBV(ITTAPI, void, model_site_beginAL, (const char *name, size_t siteNameLen)) +ITT_STUBV(ITTAPI, void, model_site_end, (__itt_model_site *site, __itt_model_site_instance *instance)) +ITT_STUBV(ITTAPI, void, model_site_end_2, (void)) +#define __itt_model_site_begin ITTNOTIFY_VOID(model_site_begin) +#define __itt_model_site_begin_ptr ITTNOTIFY_NAME(model_site_begin) +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_site_beginW ITTNOTIFY_VOID(model_site_beginW) +#define __itt_model_site_beginW_ptr ITTNOTIFY_NAME(model_site_beginW) +#endif +#define __itt_model_site_beginA ITTNOTIFY_VOID(model_site_beginA) +#define __itt_model_site_beginA_ptr ITTNOTIFY_NAME(model_site_beginA) +#define __itt_model_site_beginAL ITTNOTIFY_VOID(model_site_beginAL) +#define __itt_model_site_beginAL_ptr ITTNOTIFY_NAME(model_site_beginAL) +#define __itt_model_site_end ITTNOTIFY_VOID(model_site_end) +#define __itt_model_site_end_ptr ITTNOTIFY_NAME(model_site_end) +#define __itt_model_site_end_2 ITTNOTIFY_VOID(model_site_end_2) +#define __itt_model_site_end_2_ptr ITTNOTIFY_NAME(model_site_end_2) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_site_begin(site, instance, name) +#define __itt_model_site_begin_ptr 0 +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_site_beginW(name) +#define __itt_model_site_beginW_ptr 0 +#endif +#define __itt_model_site_beginA(name) +#define __itt_model_site_beginA_ptr 0 +#define __itt_model_site_beginAL(name, siteNameLen) +#define __itt_model_site_beginAL_ptr 0 +#define __itt_model_site_end(site, instance) +#define __itt_model_site_end_ptr 0 +#define __itt_model_site_end_2() +#define __itt_model_site_end_2_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_site_begin_ptr 0 +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_site_beginW_ptr 0 +#endif +#define __itt_model_site_beginA_ptr 0 +#define __itt_model_site_beginAL_ptr 0 +#define __itt_model_site_end_ptr 0 +#define __itt_model_site_end_2_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_TASK_BEGIN/ANNOTATE_TASK_END support + * + * task_begin/end model a potential task, which is contained within the most + * closely enclosing dynamic site. task_end exits the most recently started + * but unended task. The handle passed to end may be used to validate + * structure. It is unspecified if bad dynamic nesting is detected. If it + * is, it should be encoded in the resulting data collection. The collector + * should not fail due to construct nesting issues, nor attempt to directly + * indicate the problem. + */ +void ITTAPI __itt_model_task_begin(__itt_model_task *task, __itt_model_task_instance *instance, const char *name); +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_model_task_beginW(const wchar_t *name); +void ITTAPI __itt_model_iteration_taskW(const wchar_t *name); +#endif +void ITTAPI __itt_model_task_beginA(const char *name); +void ITTAPI __itt_model_task_beginAL(const char *name, size_t taskNameLen); +void ITTAPI __itt_model_iteration_taskA(const char *name); +void ITTAPI __itt_model_iteration_taskAL(const char *name, size_t taskNameLen); +void ITTAPI __itt_model_task_end (__itt_model_task *task, __itt_model_task_instance *instance); +void ITTAPI __itt_model_task_end_2(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_task_begin, (__itt_model_task *task, __itt_model_task_instance *instance, const char *name)) +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, model_task_beginW, (const wchar_t *name)) +ITT_STUBV(ITTAPI, void, model_iteration_taskW, (const wchar_t *name)) +#endif +ITT_STUBV(ITTAPI, void, model_task_beginA, (const char *name)) +ITT_STUBV(ITTAPI, void, model_task_beginAL, (const char *name, size_t taskNameLen)) +ITT_STUBV(ITTAPI, void, model_iteration_taskA, (const char *name)) +ITT_STUBV(ITTAPI, void, model_iteration_taskAL, (const char *name, size_t taskNameLen)) +ITT_STUBV(ITTAPI, void, model_task_end, (__itt_model_task *task, __itt_model_task_instance *instance)) +ITT_STUBV(ITTAPI, void, model_task_end_2, (void)) +#define __itt_model_task_begin ITTNOTIFY_VOID(model_task_begin) +#define __itt_model_task_begin_ptr ITTNOTIFY_NAME(model_task_begin) +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_task_beginW ITTNOTIFY_VOID(model_task_beginW) +#define __itt_model_task_beginW_ptr ITTNOTIFY_NAME(model_task_beginW) +#define __itt_model_iteration_taskW ITTNOTIFY_VOID(model_iteration_taskW) +#define __itt_model_iteration_taskW_ptr ITTNOTIFY_NAME(model_iteration_taskW) +#endif +#define __itt_model_task_beginA ITTNOTIFY_VOID(model_task_beginA) +#define __itt_model_task_beginA_ptr ITTNOTIFY_NAME(model_task_beginA) +#define __itt_model_task_beginAL ITTNOTIFY_VOID(model_task_beginAL) +#define __itt_model_task_beginAL_ptr ITTNOTIFY_NAME(model_task_beginAL) +#define __itt_model_iteration_taskA ITTNOTIFY_VOID(model_iteration_taskA) +#define __itt_model_iteration_taskA_ptr ITTNOTIFY_NAME(model_iteration_taskA) +#define __itt_model_iteration_taskAL ITTNOTIFY_VOID(model_iteration_taskAL) +#define __itt_model_iteration_taskAL_ptr ITTNOTIFY_NAME(model_iteration_taskAL) +#define __itt_model_task_end ITTNOTIFY_VOID(model_task_end) +#define __itt_model_task_end_ptr ITTNOTIFY_NAME(model_task_end) +#define __itt_model_task_end_2 ITTNOTIFY_VOID(model_task_end_2) +#define __itt_model_task_end_2_ptr ITTNOTIFY_NAME(model_task_end_2) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_task_begin(task, instance, name) +#define __itt_model_task_begin_ptr 0 +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_task_beginW(name) +#define __itt_model_task_beginW_ptr 0 +#endif +#define __itt_model_task_beginA(name) +#define __itt_model_task_beginA_ptr 0 +#define __itt_model_task_beginAL(name, siteNameLen) +#define __itt_model_task_beginAL_ptr 0 +#define __itt_model_iteration_taskA(name) +#define __itt_model_iteration_taskA_ptr 0 +#define __itt_model_iteration_taskAL(name, siteNameLen) +#define __itt_model_iteration_taskAL_ptr 0 +#define __itt_model_task_end(task, instance) +#define __itt_model_task_end_ptr 0 +#define __itt_model_task_end_2() +#define __itt_model_task_end_2_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_task_begin_ptr 0 +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_task_beginW_ptr 0 +#endif +#define __itt_model_task_beginA_ptr 0 +#define __itt_model_task_beginAL_ptr 0 +#define __itt_model_iteration_taskA_ptr 0 +#define __itt_model_iteration_taskAL_ptr 0 +#define __itt_model_task_end_ptr 0 +#define __itt_model_task_end_2_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_LOCK_ACQUIRE/ANNOTATE_LOCK_RELEASE support + * + * lock_acquire/release model a potential lock for both lockset and + * performance modeling. Each unique address is modeled as a separate + * lock, with invalid addresses being valid lock IDs. Specifically: + * no storage is accessed by the API at the specified address - it is only + * used for lock identification. Lock acquires may be self-nested and are + * unlocked by a corresponding number of releases. + * (These closely correspond to __itt_sync_acquired/__itt_sync_releasing, + * but may not have identical semantics.) + */ +void ITTAPI __itt_model_lock_acquire(void *lock); +void ITTAPI __itt_model_lock_acquire_2(void *lock); +void ITTAPI __itt_model_lock_release(void *lock); +void ITTAPI __itt_model_lock_release_2(void *lock); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_lock_acquire, (void *lock)) +ITT_STUBV(ITTAPI, void, model_lock_acquire_2, (void *lock)) +ITT_STUBV(ITTAPI, void, model_lock_release, (void *lock)) +ITT_STUBV(ITTAPI, void, model_lock_release_2, (void *lock)) +#define __itt_model_lock_acquire ITTNOTIFY_VOID(model_lock_acquire) +#define __itt_model_lock_acquire_ptr ITTNOTIFY_NAME(model_lock_acquire) +#define __itt_model_lock_acquire_2 ITTNOTIFY_VOID(model_lock_acquire_2) +#define __itt_model_lock_acquire_2_ptr ITTNOTIFY_NAME(model_lock_acquire_2) +#define __itt_model_lock_release ITTNOTIFY_VOID(model_lock_release) +#define __itt_model_lock_release_ptr ITTNOTIFY_NAME(model_lock_release) +#define __itt_model_lock_release_2 ITTNOTIFY_VOID(model_lock_release_2) +#define __itt_model_lock_release_2_ptr ITTNOTIFY_NAME(model_lock_release_2) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_lock_acquire(lock) +#define __itt_model_lock_acquire_ptr 0 +#define __itt_model_lock_acquire_2(lock) +#define __itt_model_lock_acquire_2_ptr 0 +#define __itt_model_lock_release(lock) +#define __itt_model_lock_release_ptr 0 +#define __itt_model_lock_release_2(lock) +#define __itt_model_lock_release_2_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_lock_acquire_ptr 0 +#define __itt_model_lock_acquire_2_ptr 0 +#define __itt_model_lock_release_ptr 0 +#define __itt_model_lock_release_2_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_RECORD_ALLOCATION/ANNOTATE_RECORD_DEALLOCATION support + * + * record_allocation/deallocation describe user-defined memory allocator + * behavior, which may be required for correctness modeling to understand + * when storage is not expected to be actually reused across threads. + */ +void ITTAPI __itt_model_record_allocation (void *addr, size_t size); +void ITTAPI __itt_model_record_deallocation(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_record_allocation, (void *addr, size_t size)) +ITT_STUBV(ITTAPI, void, model_record_deallocation, (void *addr)) +#define __itt_model_record_allocation ITTNOTIFY_VOID(model_record_allocation) +#define __itt_model_record_allocation_ptr ITTNOTIFY_NAME(model_record_allocation) +#define __itt_model_record_deallocation ITTNOTIFY_VOID(model_record_deallocation) +#define __itt_model_record_deallocation_ptr ITTNOTIFY_NAME(model_record_deallocation) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_record_allocation(addr, size) +#define __itt_model_record_allocation_ptr 0 +#define __itt_model_record_deallocation(addr) +#define __itt_model_record_deallocation_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_record_allocation_ptr 0 +#define __itt_model_record_deallocation_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_INDUCTION_USES support + * + * Note particular storage is inductive through the end of the current site + */ +void ITTAPI __itt_model_induction_uses(void* addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_induction_uses, (void *addr, size_t size)) +#define __itt_model_induction_uses ITTNOTIFY_VOID(model_induction_uses) +#define __itt_model_induction_uses_ptr ITTNOTIFY_NAME(model_induction_uses) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_induction_uses(addr, size) +#define __itt_model_induction_uses_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_induction_uses_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_REDUCTION_USES support + * + * Note particular storage is used for reduction through the end + * of the current site + */ +void ITTAPI __itt_model_reduction_uses(void* addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_reduction_uses, (void *addr, size_t size)) +#define __itt_model_reduction_uses ITTNOTIFY_VOID(model_reduction_uses) +#define __itt_model_reduction_uses_ptr ITTNOTIFY_NAME(model_reduction_uses) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_reduction_uses(addr, size) +#define __itt_model_reduction_uses_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_reduction_uses_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_OBSERVE_USES support + * + * Have correctness modeling record observations about uses of storage + * through the end of the current site + */ +void ITTAPI __itt_model_observe_uses(void* addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_observe_uses, (void *addr, size_t size)) +#define __itt_model_observe_uses ITTNOTIFY_VOID(model_observe_uses) +#define __itt_model_observe_uses_ptr ITTNOTIFY_NAME(model_observe_uses) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_observe_uses(addr, size) +#define __itt_model_observe_uses_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_observe_uses_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_CLEAR_USES support + * + * Clear the special handling of a piece of storage related to induction, + * reduction or observe_uses + */ +void ITTAPI __itt_model_clear_uses(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_clear_uses, (void *addr)) +#define __itt_model_clear_uses ITTNOTIFY_VOID(model_clear_uses) +#define __itt_model_clear_uses_ptr ITTNOTIFY_NAME(model_clear_uses) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_clear_uses(addr) +#define __itt_model_clear_uses_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_clear_uses_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_DISABLE_*_PUSH/ANNOTATE_DISABLE_*_POP support + * + * disable_push/disable_pop push and pop disabling based on a parameter. + * Disabling observations stops processing of memory references during + * correctness modeling, and all annotations that occur in the disabled + * region. This allows description of code that is expected to be handled + * specially during conversion to parallelism or that is not recognized + * by tools (e.g. some kinds of synchronization operations.) + * This mechanism causes all annotations in the disabled region, other + * than disable_push and disable_pop, to be ignored. (For example, this + * might validly be used to disable an entire parallel site and the contained + * tasks and locking in it for data collection purposes.) + * The disable for collection is a more expensive operation, but reduces + * collector overhead significantly. This applies to BOTH correctness data + * collection and performance data collection. For example, a site + * containing a task might only enable data collection for the first 10 + * iterations. Both performance and correctness data should reflect this, + * and the program should run as close to full speed as possible when + * collection is disabled. + */ +void ITTAPI __itt_model_disable_push(__itt_model_disable x); +void ITTAPI __itt_model_disable_pop(void); +void ITTAPI __itt_model_aggregate_task(size_t x); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_disable_push, (__itt_model_disable x)) +ITT_STUBV(ITTAPI, void, model_disable_pop, (void)) +ITT_STUBV(ITTAPI, void, model_aggregate_task, (size_t x)) +#define __itt_model_disable_push ITTNOTIFY_VOID(model_disable_push) +#define __itt_model_disable_push_ptr ITTNOTIFY_NAME(model_disable_push) +#define __itt_model_disable_pop ITTNOTIFY_VOID(model_disable_pop) +#define __itt_model_disable_pop_ptr ITTNOTIFY_NAME(model_disable_pop) +#define __itt_model_aggregate_task ITTNOTIFY_VOID(model_aggregate_task) +#define __itt_model_aggregate_task_ptr ITTNOTIFY_NAME(model_aggregate_task) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_disable_push(x) +#define __itt_model_disable_push_ptr 0 +#define __itt_model_disable_pop() +#define __itt_model_disable_pop_ptr 0 +#define __itt_model_aggregate_task(x) +#define __itt_model_aggregate_task_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_disable_push_ptr 0 +#define __itt_model_disable_pop_ptr 0 +#define __itt_model_aggregate_task_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} model group */ + +/** + * @defgroup heap Heap + * @ingroup public + * Heap group + * @{ + */ + +typedef void* __itt_heap_function; + +/** + * @brief Create an identification for heap function + * @return non-zero identifier or NULL + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_heap_function ITTAPI __itt_heap_function_createA(const char* name, const char* domain); +__itt_heap_function ITTAPI __itt_heap_function_createW(const wchar_t* name, const wchar_t* domain); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_heap_function_create __itt_heap_function_createW +# define __itt_heap_function_create_ptr __itt_heap_function_createW_ptr +#else +# define __itt_heap_function_create __itt_heap_function_createA +# define __itt_heap_function_create_ptr __itt_heap_function_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_heap_function ITTAPI __itt_heap_function_create(const char* name, const char* domain); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createA, (const char* name, const char* domain)) +ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createW, (const wchar_t* name, const wchar_t* domain)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_heap_function, heap_function_create, (const char* name, const char* domain)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_heap_function_createA ITTNOTIFY_DATA(heap_function_createA) +#define __itt_heap_function_createA_ptr ITTNOTIFY_NAME(heap_function_createA) +#define __itt_heap_function_createW ITTNOTIFY_DATA(heap_function_createW) +#define __itt_heap_function_createW_ptr ITTNOTIFY_NAME(heap_function_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_heap_function_create ITTNOTIFY_DATA(heap_function_create) +#define __itt_heap_function_create_ptr ITTNOTIFY_NAME(heap_function_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_heap_function_createA(name, domain) (__itt_heap_function)0 +#define __itt_heap_function_createA_ptr 0 +#define __itt_heap_function_createW(name, domain) (__itt_heap_function)0 +#define __itt_heap_function_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_heap_function_create(name, domain) (__itt_heap_function)0 +#define __itt_heap_function_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_heap_function_createA_ptr 0 +#define __itt_heap_function_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_heap_function_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an allocation begin occurrence. + */ +void ITTAPI __itt_heap_allocate_begin(__itt_heap_function h, size_t size, int initialized); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_allocate_begin, (__itt_heap_function h, size_t size, int initialized)) +#define __itt_heap_allocate_begin ITTNOTIFY_VOID(heap_allocate_begin) +#define __itt_heap_allocate_begin_ptr ITTNOTIFY_NAME(heap_allocate_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_allocate_begin(h, size, initialized) +#define __itt_heap_allocate_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_allocate_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an allocation end occurrence. + */ +void ITTAPI __itt_heap_allocate_end(__itt_heap_function h, void** addr, size_t size, int initialized); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_allocate_end, (__itt_heap_function h, void** addr, size_t size, int initialized)) +#define __itt_heap_allocate_end ITTNOTIFY_VOID(heap_allocate_end) +#define __itt_heap_allocate_end_ptr ITTNOTIFY_NAME(heap_allocate_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_allocate_end(h, addr, size, initialized) +#define __itt_heap_allocate_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_allocate_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record a free begin occurrence. + */ +void ITTAPI __itt_heap_free_begin(__itt_heap_function h, void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_free_begin, (__itt_heap_function h, void* addr)) +#define __itt_heap_free_begin ITTNOTIFY_VOID(heap_free_begin) +#define __itt_heap_free_begin_ptr ITTNOTIFY_NAME(heap_free_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_free_begin(h, addr) +#define __itt_heap_free_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_free_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record a free end occurrence. + */ +void ITTAPI __itt_heap_free_end(__itt_heap_function h, void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_free_end, (__itt_heap_function h, void* addr)) +#define __itt_heap_free_end ITTNOTIFY_VOID(heap_free_end) +#define __itt_heap_free_end_ptr ITTNOTIFY_NAME(heap_free_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_free_end(h, addr) +#define __itt_heap_free_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_free_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record a reallocation begin occurrence. + */ +void ITTAPI __itt_heap_reallocate_begin(__itt_heap_function h, void* addr, size_t new_size, int initialized); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_reallocate_begin, (__itt_heap_function h, void* addr, size_t new_size, int initialized)) +#define __itt_heap_reallocate_begin ITTNOTIFY_VOID(heap_reallocate_begin) +#define __itt_heap_reallocate_begin_ptr ITTNOTIFY_NAME(heap_reallocate_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_reallocate_begin(h, addr, new_size, initialized) +#define __itt_heap_reallocate_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_reallocate_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record a reallocation end occurrence. + */ +void ITTAPI __itt_heap_reallocate_end(__itt_heap_function h, void* addr, void** new_addr, size_t new_size, int initialized); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_reallocate_end, (__itt_heap_function h, void* addr, void** new_addr, size_t new_size, int initialized)) +#define __itt_heap_reallocate_end ITTNOTIFY_VOID(heap_reallocate_end) +#define __itt_heap_reallocate_end_ptr ITTNOTIFY_NAME(heap_reallocate_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_reallocate_end(h, addr, new_addr, new_size, initialized) +#define __itt_heap_reallocate_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_reallocate_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief internal access begin */ +void ITTAPI __itt_heap_internal_access_begin(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_internal_access_begin, (void)) +#define __itt_heap_internal_access_begin ITTNOTIFY_VOID(heap_internal_access_begin) +#define __itt_heap_internal_access_begin_ptr ITTNOTIFY_NAME(heap_internal_access_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_internal_access_begin() +#define __itt_heap_internal_access_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_internal_access_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief internal access end */ +void ITTAPI __itt_heap_internal_access_end(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_internal_access_end, (void)) +#define __itt_heap_internal_access_end ITTNOTIFY_VOID(heap_internal_access_end) +#define __itt_heap_internal_access_end_ptr ITTNOTIFY_NAME(heap_internal_access_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_internal_access_end() +#define __itt_heap_internal_access_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_internal_access_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief record memory growth begin */ +void ITTAPI __itt_heap_record_memory_growth_begin(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_record_memory_growth_begin, (void)) +#define __itt_heap_record_memory_growth_begin ITTNOTIFY_VOID(heap_record_memory_growth_begin) +#define __itt_heap_record_memory_growth_begin_ptr ITTNOTIFY_NAME(heap_record_memory_growth_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_record_memory_growth_begin() +#define __itt_heap_record_memory_growth_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_record_memory_growth_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief record memory growth end */ +void ITTAPI __itt_heap_record_memory_growth_end(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_record_memory_growth_end, (void)) +#define __itt_heap_record_memory_growth_end ITTNOTIFY_VOID(heap_record_memory_growth_end) +#define __itt_heap_record_memory_growth_end_ptr ITTNOTIFY_NAME(heap_record_memory_growth_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_record_memory_growth_end() +#define __itt_heap_record_memory_growth_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_record_memory_growth_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Specify the type of heap detection/reporting to modify. + */ +/** + * @hideinitializer + * @brief Report on memory leaks. + */ +#define __itt_heap_leaks 0x00000001 + +/** + * @hideinitializer + * @brief Report on memory growth. + */ +#define __itt_heap_growth 0x00000002 + + +/** @brief heap reset detection */ +void ITTAPI __itt_heap_reset_detection(unsigned int reset_mask); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_reset_detection, (unsigned int reset_mask)) +#define __itt_heap_reset_detection ITTNOTIFY_VOID(heap_reset_detection) +#define __itt_heap_reset_detection_ptr ITTNOTIFY_NAME(heap_reset_detection) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_reset_detection() +#define __itt_heap_reset_detection_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_reset_detection_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief report */ +void ITTAPI __itt_heap_record(unsigned int record_mask); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_record, (unsigned int record_mask)) +#define __itt_heap_record ITTNOTIFY_VOID(heap_record) +#define __itt_heap_record_ptr ITTNOTIFY_NAME(heap_record) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_record() +#define __itt_heap_record_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_record_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @} heap group */ +/** @endcond */ +/* ========================================================================== */ + +/** + * @defgroup domains Domains + * @ingroup public + * Domains group + * @{ + */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_domain +{ + volatile int flags; /*!< Zero if disabled, non-zero if enabled. The meaning of different non-zero values is reserved to the runtime */ + const char* nameA; /*!< Copy of original name in ASCII. */ +#if defined(UNICODE) || defined(_UNICODE) + const wchar_t* nameW; /*!< Copy of original name in UNICODE. */ +#else /* UNICODE || _UNICODE */ + void* nameW; +#endif /* UNICODE || _UNICODE */ + int extra1; /*!< Reserved to the runtime */ + void* extra2; /*!< Reserved to the runtime */ + struct ___itt_domain* next; +} __itt_domain; + +#pragma pack(pop) +/** @endcond */ + +/** + * @ingroup domains + * @brief Create a domain. + * Create domain using some domain name: the URI naming style is recommended. + * Because the set of domains is expected to be static over the application's + * execution time, there is no mechanism to destroy a domain. + * Any domain can be accessed by any thread in the process, regardless of + * which thread created the domain. This call is thread-safe. + * @param[in] name name of domain + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_domain* ITTAPI __itt_domain_createA(const char *name); +__itt_domain* ITTAPI __itt_domain_createW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_domain_create __itt_domain_createW +# define __itt_domain_create_ptr __itt_domain_createW_ptr +#else /* UNICODE */ +# define __itt_domain_create __itt_domain_createA +# define __itt_domain_create_ptr __itt_domain_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_domain* ITTAPI __itt_domain_create(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_domain*, domain_createA, (const char *name)) +ITT_STUB(ITTAPI, __itt_domain*, domain_createW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_domain*, domain_create, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_domain_createA ITTNOTIFY_DATA(domain_createA) +#define __itt_domain_createA_ptr ITTNOTIFY_NAME(domain_createA) +#define __itt_domain_createW ITTNOTIFY_DATA(domain_createW) +#define __itt_domain_createW_ptr ITTNOTIFY_NAME(domain_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_domain_create ITTNOTIFY_DATA(domain_create) +#define __itt_domain_create_ptr ITTNOTIFY_NAME(domain_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_domain_createA(name) (__itt_domain*)0 +#define __itt_domain_createA_ptr 0 +#define __itt_domain_createW(name) (__itt_domain*)0 +#define __itt_domain_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_domain_create(name) (__itt_domain*)0 +#define __itt_domain_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_domain_createA_ptr 0 +#define __itt_domain_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_domain_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} domains group */ + +/** + * @defgroup ids IDs + * @ingroup public + * IDs group + * @{ + */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_id +{ + unsigned long long d1, d2, d3; +} __itt_id; + +#pragma pack(pop) +/** @endcond */ + +static const __itt_id __itt_null = { 0, 0, 0 }; + +/** + * @ingroup ids + * @brief A convenience function is provided to create an ID without domain control. + * @brief This is a convenience function to initialize an __itt_id structure. This function + * does not affect the collector runtime in any way. After you make the ID with this + * function, you still must create it with the __itt_id_create function before using the ID + * to identify a named entity. + * @param[in] addr The address of object; high QWORD of the ID value. + * @param[in] extra The extra data to unique identify object; low QWORD of the ID value. + */ + +ITT_INLINE __itt_id ITTAPI __itt_id_make(void* addr, unsigned long long extra) ITT_INLINE_ATTRIBUTE; +ITT_INLINE __itt_id ITTAPI __itt_id_make(void* addr, unsigned long long extra) +{ + __itt_id id = __itt_null; + id.d1 = (unsigned long long)((uintptr_t)addr); + id.d2 = (unsigned long long)extra; + id.d3 = (unsigned long long)0; /* Reserved. Must be zero */ + return id; +} + +/** + * @ingroup ids + * @brief Create an instance of identifier. + * This establishes the beginning of the lifetime of an instance of + * the given ID in the trace. Once this lifetime starts, the ID + * can be used to tag named entity instances in calls such as + * __itt_task_begin, and to specify relationships among + * identified named entity instances, using the \ref relations APIs. + * Instance IDs are not domain specific! + * @param[in] domain The domain controlling the execution of this call. + * @param[in] id The ID to create. + */ +void ITTAPI __itt_id_create(const __itt_domain *domain, __itt_id id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, id_create, (const __itt_domain *domain, __itt_id id)) +#define __itt_id_create(d,x) ITTNOTIFY_VOID_D1(id_create,d,x) +#define __itt_id_create_ptr ITTNOTIFY_NAME(id_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_id_create(domain,id) +#define __itt_id_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_id_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup ids + * @brief Destroy an instance of identifier. + * This ends the lifetime of the current instance of the given ID value in the trace. + * Any relationships that are established after this lifetime ends are invalid. + * This call must be performed before the given ID value can be reused for a different + * named entity instance. + * @param[in] domain The domain controlling the execution of this call. + * @param[in] id The ID to destroy. + */ +void ITTAPI __itt_id_destroy(const __itt_domain *domain, __itt_id id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, id_destroy, (const __itt_domain *domain, __itt_id id)) +#define __itt_id_destroy(d,x) ITTNOTIFY_VOID_D1(id_destroy,d,x) +#define __itt_id_destroy_ptr ITTNOTIFY_NAME(id_destroy) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_id_destroy(domain,id) +#define __itt_id_destroy_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_id_destroy_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} ids group */ + +/** + * @defgroup handless String Handles + * @ingroup public + * String Handles group + * @{ + */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_string_handle +{ + const char* strA; /*!< Copy of original string in ASCII. */ +#if defined(UNICODE) || defined(_UNICODE) + const wchar_t* strW; /*!< Copy of original string in UNICODE. */ +#else /* UNICODE || _UNICODE */ + void* strW; +#endif /* UNICODE || _UNICODE */ + int extra1; /*!< Reserved. Must be zero */ + void* extra2; /*!< Reserved. Must be zero */ + struct ___itt_string_handle* next; +} __itt_string_handle; + +#pragma pack(pop) +/** @endcond */ + +/** + * @ingroup handles + * @brief Create a string handle. + * Create and return handle value that can be associated with a string. + * Consecutive calls to __itt_string_handle_create with the same name + * return the same value. Because the set of string handles is expected to remain + * static during the application's execution time, there is no mechanism to destroy a string handle. + * Any string handle can be accessed by any thread in the process, regardless of which thread created + * the string handle. This call is thread-safe. + * @param[in] name The input string + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_string_handle* ITTAPI __itt_string_handle_createA(const char *name); +__itt_string_handle* ITTAPI __itt_string_handle_createW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_string_handle_create __itt_string_handle_createW +# define __itt_string_handle_create_ptr __itt_string_handle_createW_ptr +#else /* UNICODE */ +# define __itt_string_handle_create __itt_string_handle_createA +# define __itt_string_handle_create_ptr __itt_string_handle_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_string_handle* ITTAPI __itt_string_handle_create(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createA, (const char *name)) +ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_create, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_string_handle_createA ITTNOTIFY_DATA(string_handle_createA) +#define __itt_string_handle_createA_ptr ITTNOTIFY_NAME(string_handle_createA) +#define __itt_string_handle_createW ITTNOTIFY_DATA(string_handle_createW) +#define __itt_string_handle_createW_ptr ITTNOTIFY_NAME(string_handle_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_string_handle_create ITTNOTIFY_DATA(string_handle_create) +#define __itt_string_handle_create_ptr ITTNOTIFY_NAME(string_handle_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_string_handle_createA(name) (__itt_string_handle*)0 +#define __itt_string_handle_createA_ptr 0 +#define __itt_string_handle_createW(name) (__itt_string_handle*)0 +#define __itt_string_handle_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_string_handle_create(name) (__itt_string_handle*)0 +#define __itt_string_handle_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_string_handle_createA_ptr 0 +#define __itt_string_handle_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_string_handle_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} handles group */ + +/** @cond exclude_from_documentation */ +typedef unsigned long long __itt_timestamp; +/** @endcond */ + +#define __itt_timestamp_none ((__itt_timestamp)-1LL) + +/** @cond exclude_from_gpa_documentation */ + +/** + * @ingroup timestamps + * @brief Return timestamp corresponding to the current moment. + * This returns the timestamp in the format that is the most relevant for the current + * host or platform (RDTSC, QPC, and others). You can use the "<" operator to + * compare __itt_timestamp values. + */ +__itt_timestamp ITTAPI __itt_get_timestamp(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_timestamp, get_timestamp, (void)) +#define __itt_get_timestamp ITTNOTIFY_DATA(get_timestamp) +#define __itt_get_timestamp_ptr ITTNOTIFY_NAME(get_timestamp) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_get_timestamp() +#define __itt_get_timestamp_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_get_timestamp_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} timestamps */ +/** @endcond */ + +/** @cond exclude_from_gpa_documentation */ + +/** + * @defgroup regions Regions + * @ingroup public + * Regions group + * @{ + */ +/** + * @ingroup regions + * @brief Begin of region instance. + * Successive calls to __itt_region_begin with the same ID are ignored + * until a call to __itt_region_end with the same ID + * @param[in] domain The domain for this region instance + * @param[in] id The instance ID for this region instance. Must not be __itt_null + * @param[in] parentid The instance ID for the parent of this region instance, or __itt_null + * @param[in] name The name of this region + */ +void ITTAPI __itt_region_begin(const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name); + +/** + * @ingroup regions + * @brief End of region instance. + * The first call to __itt_region_end with a given ID ends the + * region. Successive calls with the same ID are ignored, as are + * calls that do not have a matching __itt_region_begin call. + * @param[in] domain The domain for this region instance + * @param[in] id The instance ID for this region instance + */ +void ITTAPI __itt_region_end(const __itt_domain *domain, __itt_id id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, region_begin, (const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, region_end, (const __itt_domain *domain, __itt_id id)) +#define __itt_region_begin(d,x,y,z) ITTNOTIFY_VOID_D3(region_begin,d,x,y,z) +#define __itt_region_begin_ptr ITTNOTIFY_NAME(region_begin) +#define __itt_region_end(d,x) ITTNOTIFY_VOID_D1(region_end,d,x) +#define __itt_region_end_ptr ITTNOTIFY_NAME(region_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_region_begin(d,x,y,z) +#define __itt_region_begin_ptr 0 +#define __itt_region_end(d,x) +#define __itt_region_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_region_begin_ptr 0 +#define __itt_region_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} regions group */ + +/** + * @defgroup frames Frames + * @ingroup public + * Frames are similar to regions, but are intended to be easier to use and to implement. + * In particular: + * - Frames always represent periods of elapsed time + * - By default, frames have no nesting relationships + * @{ + */ + +/** + * @ingroup frames + * @brief Begin a frame instance. + * Successive calls to __itt_frame_begin with the + * same ID are ignored until a call to __itt_frame_end with the same ID. + * @param[in] domain The domain for this frame instance + * @param[in] id The instance ID for this frame instance or NULL + */ +void ITTAPI __itt_frame_begin_v3(const __itt_domain *domain, __itt_id *id); + +/** + * @ingroup frames + * @brief End a frame instance. + * The first call to __itt_frame_end with a given ID + * ends the frame. Successive calls with the same ID are ignored, as are + * calls that do not have a matching __itt_frame_begin call. + * @param[in] domain The domain for this frame instance + * @param[in] id The instance ID for this frame instance or NULL for current + */ +void ITTAPI __itt_frame_end_v3(const __itt_domain *domain, __itt_id *id); + +/** + * @ingroup frames + * @brief Submits a frame instance. + * Successive calls to __itt_frame_begin or __itt_frame_submit with the + * same ID are ignored until a call to __itt_frame_end or __itt_frame_submit + * with the same ID. + * Passing special __itt_timestamp_none value as "end" argument means + * take the current timestamp as the end timestamp. + * @param[in] domain The domain for this frame instance + * @param[in] id The instance ID for this frame instance or NULL + * @param[in] begin Timestamp of the beginning of the frame + * @param[in] end Timestamp of the end of the frame + */ +void ITTAPI __itt_frame_submit_v3(const __itt_domain *domain, __itt_id *id, + __itt_timestamp begin, __itt_timestamp end); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, frame_begin_v3, (const __itt_domain *domain, __itt_id *id)) +ITT_STUBV(ITTAPI, void, frame_end_v3, (const __itt_domain *domain, __itt_id *id)) +ITT_STUBV(ITTAPI, void, frame_submit_v3, (const __itt_domain *domain, __itt_id *id, __itt_timestamp begin, __itt_timestamp end)) +#define __itt_frame_begin_v3(d,x) ITTNOTIFY_VOID_D1(frame_begin_v3,d,x) +#define __itt_frame_begin_v3_ptr ITTNOTIFY_NAME(frame_begin_v3) +#define __itt_frame_end_v3(d,x) ITTNOTIFY_VOID_D1(frame_end_v3,d,x) +#define __itt_frame_end_v3_ptr ITTNOTIFY_NAME(frame_end_v3) +#define __itt_frame_submit_v3(d,x,b,e) ITTNOTIFY_VOID_D3(frame_submit_v3,d,x,b,e) +#define __itt_frame_submit_v3_ptr ITTNOTIFY_NAME(frame_submit_v3) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_frame_begin_v3(domain,id) +#define __itt_frame_begin_v3_ptr 0 +#define __itt_frame_end_v3(domain,id) +#define __itt_frame_end_v3_ptr 0 +#define __itt_frame_submit_v3(domain,id,begin,end) +#define __itt_frame_submit_v3_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_frame_begin_v3_ptr 0 +#define __itt_frame_end_v3_ptr 0 +#define __itt_frame_submit_v3_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} frames group */ +/** @endcond */ + +/** + * @defgroup taskgroup Task Group + * @ingroup public + * Task Group + * @{ + */ +/** + * @ingroup task_groups + * @brief Denotes a task_group instance. + * Successive calls to __itt_task_group with the same ID are ignored. + * @param[in] domain The domain for this task_group instance + * @param[in] id The instance ID for this task_group instance. Must not be __itt_null. + * @param[in] parentid The instance ID for the parent of this task_group instance, or __itt_null. + * @param[in] name The name of this task_group + */ +void ITTAPI __itt_task_group(const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, task_group, (const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name)) +#define __itt_task_group(d,x,y,z) ITTNOTIFY_VOID_D3(task_group,d,x,y,z) +#define __itt_task_group_ptr ITTNOTIFY_NAME(task_group) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_task_group(d,x,y,z) +#define __itt_task_group_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_task_group_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} taskgroup group */ + +/** + * @defgroup tasks Tasks + * @ingroup public + * A task instance represents a piece of work performed by a particular + * thread for a period of time. A call to __itt_task_begin creates a + * task instance. This becomes the current instance for that task on that + * thread. A following call to __itt_task_end on the same thread ends the + * instance. There may be multiple simultaneous instances of tasks with the + * same name on different threads. If an ID is specified, the task instance + * receives that ID. Nested tasks are allowed. + * + * Note: The task is defined by the bracketing of __itt_task_begin and + * __itt_task_end on the same thread. If some scheduling mechanism causes + * task switching (the thread executes a different user task) or task + * switching (the user task switches to a different thread) then this breaks + * the notion of current instance. Additional API calls are required to + * deal with that possibility. + * @{ + */ + +/** + * @ingroup tasks + * @brief Begin a task instance. + * @param[in] domain The domain for this task + * @param[in] taskid The instance ID for this task instance, or __itt_null + * @param[in] parentid The parent instance to which this task instance belongs, or __itt_null + * @param[in] name The name of this task + */ +void ITTAPI __itt_task_begin(const __itt_domain *domain, __itt_id taskid, __itt_id parentid, __itt_string_handle *name); + +/** + * @ingroup tasks + * @brief Begin a task instance. + * @param[in] domain The domain for this task + * @param[in] taskid The identifier for this task instance (may be 0) + * @param[in] parentid The parent of this task (may be 0) + * @param[in] fn The pointer to the function you are tracing + */ +void ITTAPI __itt_task_begin_fn(const __itt_domain *domain, __itt_id taskid, __itt_id parentid, void* fn); + +/** + * @ingroup tasks + * @brief End the current task instance. + * @param[in] domain The domain for this task + */ +void ITTAPI __itt_task_end(const __itt_domain *domain); + +/** + * @ingroup tasks + * @brief Begin an overlapped task instance. + * @param[in] domain The domain for this task. + * @param[in] taskid The identifier for this task instance, *cannot* be __itt_null. + * @param[in] parentid The parent of this task, or __itt_null. + * @param[in] name The name of this task. + */ +void ITTAPI __itt_task_begin_overlapped(const __itt_domain* domain, __itt_id taskid, __itt_id parentid, __itt_string_handle* name); + +/** + * @ingroup tasks + * @brief End an overlapped task instance. + * @param[in] domain The domain for this task + * @param[in] taskid Explicit ID of finished task + */ +void ITTAPI __itt_task_end_overlapped(const __itt_domain *domain, __itt_id taskid); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, task_begin, (const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, task_begin_fn, (const __itt_domain *domain, __itt_id id, __itt_id parentid, void* fn)) +ITT_STUBV(ITTAPI, void, task_end, (const __itt_domain *domain)) +ITT_STUBV(ITTAPI, void, task_begin_overlapped, (const __itt_domain *domain, __itt_id taskid, __itt_id parentid, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, task_end_overlapped, (const __itt_domain *domain, __itt_id taskid)) +#define __itt_task_begin(d,x,y,z) ITTNOTIFY_VOID_D3(task_begin,d,x,y,z) +#define __itt_task_begin_ptr ITTNOTIFY_NAME(task_begin) +#define __itt_task_begin_fn(d,x,y,z) ITTNOTIFY_VOID_D3(task_begin_fn,d,x,y,z) +#define __itt_task_begin_fn_ptr ITTNOTIFY_NAME(task_begin_fn) +#define __itt_task_end(d) ITTNOTIFY_VOID_D0(task_end,d) +#define __itt_task_end_ptr ITTNOTIFY_NAME(task_end) +#define __itt_task_begin_overlapped(d,x,y,z) ITTNOTIFY_VOID_D3(task_begin_overlapped,d,x,y,z) +#define __itt_task_begin_overlapped_ptr ITTNOTIFY_NAME(task_begin_overlapped) +#define __itt_task_end_overlapped(d,x) ITTNOTIFY_VOID_D1(task_end_overlapped,d,x) +#define __itt_task_end_overlapped_ptr ITTNOTIFY_NAME(task_end_overlapped) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_task_begin(domain,id,parentid,name) +#define __itt_task_begin_ptr 0 +#define __itt_task_begin_fn(domain,id,parentid,fn) +#define __itt_task_begin_fn_ptr 0 +#define __itt_task_end(domain) +#define __itt_task_end_ptr 0 +#define __itt_task_begin_overlapped(domain,taskid,parentid,name) +#define __itt_task_begin_overlapped_ptr 0 +#define __itt_task_end_overlapped(domain,taskid) +#define __itt_task_end_overlapped_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_task_begin_ptr 0 +#define __itt_task_begin_fn_ptr 0 +#define __itt_task_end_ptr 0 +#define __itt_task_begin_overlapped_ptr 0 +#define __itt_task_end_overlapped_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} tasks group */ + + +/** + * @defgroup markers Markers + * Markers represent a single discreet event in time. Markers have a scope, + * described by an enumerated type __itt_scope. Markers are created by + * the API call __itt_marker. A marker instance can be given an ID for use in + * adding metadata. + * @{ + */ + +/** + * @brief Describes the scope of an event object in the trace. + */ +typedef enum +{ + __itt_scope_unknown = 0, + __itt_scope_global, + __itt_scope_track_group, + __itt_scope_track, + __itt_scope_task, + __itt_scope_marker +} __itt_scope; + +/** @cond exclude_from_documentation */ +#define __itt_marker_scope_unknown __itt_scope_unknown +#define __itt_marker_scope_global __itt_scope_global +#define __itt_marker_scope_process __itt_scope_track_group +#define __itt_marker_scope_thread __itt_scope_track +#define __itt_marker_scope_task __itt_scope_task +/** @endcond */ + +/** + * @ingroup markers + * @brief Create a marker instance + * @param[in] domain The domain for this marker + * @param[in] id The instance ID for this marker or __itt_null + * @param[in] name The name for this marker + * @param[in] scope The scope for this marker + */ +void ITTAPI __itt_marker(const __itt_domain *domain, __itt_id id, __itt_string_handle *name, __itt_scope scope); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, marker, (const __itt_domain *domain, __itt_id id, __itt_string_handle *name, __itt_scope scope)) +#define __itt_marker(d,x,y,z) ITTNOTIFY_VOID_D3(marker,d,x,y,z) +#define __itt_marker_ptr ITTNOTIFY_NAME(marker) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_marker(domain,id,name,scope) +#define __itt_marker_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_marker_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} markers group */ + +/** + * @defgroup metadata Metadata + * The metadata API is used to attach extra information to named + * entities. Metadata can be attached to an identified named entity by ID, + * or to the current entity (which is always a task). + * + * Conceptually metadata has a type (what kind of metadata), a key (the + * name of the metadata), and a value (the actual data). The encoding of + * the value depends on the type of the metadata. + * + * The type of metadata is specified by an enumerated type __itt_metdata_type. + * @{ + */ + +/** + * @ingroup parameters + * @brief describes the type of metadata + */ +typedef enum { + __itt_metadata_unknown = 0, + __itt_metadata_u64, /**< Unsigned 64-bit integer */ + __itt_metadata_s64, /**< Signed 64-bit integer */ + __itt_metadata_u32, /**< Unsigned 32-bit integer */ + __itt_metadata_s32, /**< Signed 32-bit integer */ + __itt_metadata_u16, /**< Unsigned 16-bit integer */ + __itt_metadata_s16, /**< Signed 16-bit integer */ + __itt_metadata_float, /**< Signed 32-bit floating-point */ + __itt_metadata_double /**< Signed 64-bit floating-point */ +} __itt_metadata_type; + +/** + * @ingroup parameters + * @brief Add metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] format The printf-style format of the metadata + * @param[in] ... The metadata itself as multiple arguments + */ +void ITTAPI __itt_formatted_metadata_add(const __itt_domain *domain, __itt_string_handle *format, ...); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, formatted_metadata_add, (const __itt_domain *domain, __itt_string_handle *format, ...)) +#define __itt_formatted_metadata_add(d,x, ...) ITTNOTIFY_VOID_D2_VA(formatted_metadata_add,d,x,__VA_ARGS__) +#define __itt_formatted_metadata_add_ptr ITTNOTIFY_NAME(formatted_metadata_add) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_formatted_metadata_add(domain, format, metadata) +#define __itt_formatted_metadata_add_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_formatted_metadata_add_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup parameters + * @brief Add metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] taskid The identifier for this task instance, *cannot* be __itt_null. + * @param[in] format The printf-style format of the metadata + * @param[in] ... The metadata itself as multiple arguments + */ +void ITTAPI __itt_formatted_metadata_add_overlapped(const __itt_domain *domain, __itt_id taskid, __itt_string_handle *format, ...); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, formatted_metadata_add_overlapped, (const __itt_domain *domain, __itt_id taskid, __itt_string_handle *format, ...)) +#define __itt_formatted_metadata_add_overlapped(d,x,y, ...) ITTNOTIFY_VOID_D3_VA(formatted_metadata_add_overlapped,d,x,y,__VA_ARGS__) +#define __itt_formatted_metadata_add_overlapped_ptr ITTNOTIFY_NAME(formatted_metadata_add_overlapped) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_formatted_metadata_add_overlapped(domain, taskid, format, metadata) +#define __itt_formatted_metadata_add_overlapped_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_formatted_metadata_add_overlapped_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup parameters + * @brief Add metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task + * @param[in] key The name of the metadata + * @param[in] type The type of the metadata + * @param[in] count The number of elements of the given type. If count == 0, no metadata will be added. + * @param[in] data The metadata itself +*/ +void ITTAPI __itt_metadata_add(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, metadata_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data)) +#define __itt_metadata_add(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(metadata_add,d,x,y,z,a,b) +#define __itt_metadata_add_ptr ITTNOTIFY_NAME(metadata_add) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_metadata_add(d,x,y,z,a,b) +#define __itt_metadata_add_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_metadata_add_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup parameters + * @brief Add string metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task + * @param[in] key The name of the metadata + * @param[in] data The metadata itself + * @param[in] length The number of characters in the string, or -1 if the length is unknown but the string is null-terminated +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_metadata_str_addA(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length); +void ITTAPI __itt_metadata_str_addW(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const wchar_t *data, size_t length); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_metadata_str_add __itt_metadata_str_addW +# define __itt_metadata_str_add_ptr __itt_metadata_str_addW_ptr +#else /* UNICODE */ +# define __itt_metadata_str_add __itt_metadata_str_addA +# define __itt_metadata_str_add_ptr __itt_metadata_str_addA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_metadata_str_add(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length); +#endif + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, metadata_str_addA, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length)) +ITT_STUBV(ITTAPI, void, metadata_str_addW, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const wchar_t *data, size_t length)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, metadata_str_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_addA(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_addA,d,x,y,z,a) +#define __itt_metadata_str_addA_ptr ITTNOTIFY_NAME(metadata_str_addA) +#define __itt_metadata_str_addW(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_addW,d,x,y,z,a) +#define __itt_metadata_str_addW_ptr ITTNOTIFY_NAME(metadata_str_addW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add,d,x,y,z,a) +#define __itt_metadata_str_add_ptr ITTNOTIFY_NAME(metadata_str_add) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_addA(d,x,y,z,a) +#define __itt_metadata_str_addA_ptr 0 +#define __itt_metadata_str_addW(d,x,y,z,a) +#define __itt_metadata_str_addW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add(d,x,y,z,a) +#define __itt_metadata_str_add_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_addA_ptr 0 +#define __itt_metadata_str_addW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup parameters + * @brief Add metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] scope The scope of the instance to which the metadata is to be added + + * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task + + * @param[in] key The name of the metadata + * @param[in] type The type of the metadata + * @param[in] count The number of elements of the given type. If count == 0, no metadata will be added. + * @param[in] data The metadata itself +*/ +void ITTAPI __itt_metadata_add_with_scope(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, metadata_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data)) +#define __itt_metadata_add_with_scope(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(metadata_add_with_scope,d,x,y,z,a,b) +#define __itt_metadata_add_with_scope_ptr ITTNOTIFY_NAME(metadata_add_with_scope) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_metadata_add_with_scope(d,x,y,z,a,b) +#define __itt_metadata_add_with_scope_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_metadata_add_with_scope_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup parameters + * @brief Add string metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] scope The scope of the instance to which the metadata is to be added + + * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task + + * @param[in] key The name of the metadata + * @param[in] data The metadata itself + * @param[in] length The number of characters in the string, or -1 if the length is unknown but the string is null-terminated +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_metadata_str_add_with_scopeA(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length); +void ITTAPI __itt_metadata_str_add_with_scopeW(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const wchar_t *data, size_t length); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_metadata_str_add_with_scope __itt_metadata_str_add_with_scopeW +# define __itt_metadata_str_add_with_scope_ptr __itt_metadata_str_add_with_scopeW_ptr +#else /* UNICODE */ +# define __itt_metadata_str_add_with_scope __itt_metadata_str_add_with_scopeA +# define __itt_metadata_str_add_with_scope_ptr __itt_metadata_str_add_with_scopeA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_metadata_str_add_with_scope(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length); +#endif + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeA, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length)) +ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeW, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const wchar_t *data, size_t length)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, metadata_str_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_add_with_scopeA(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add_with_scopeA,d,x,y,z,a) +#define __itt_metadata_str_add_with_scopeA_ptr ITTNOTIFY_NAME(metadata_str_add_with_scopeA) +#define __itt_metadata_str_add_with_scopeW(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add_with_scopeW,d,x,y,z,a) +#define __itt_metadata_str_add_with_scopeW_ptr ITTNOTIFY_NAME(metadata_str_add_with_scopeW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add_with_scope(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add_with_scope,d,x,y,z,a) +#define __itt_metadata_str_add_with_scope_ptr ITTNOTIFY_NAME(metadata_str_add_with_scope) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_add_with_scopeA(d,x,y,z,a) +#define __itt_metadata_str_add_with_scopeA_ptr 0 +#define __itt_metadata_str_add_with_scopeW(d,x,y,z,a) +#define __itt_metadata_str_add_with_scopeW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add_with_scope(d,x,y,z,a) +#define __itt_metadata_str_add_with_scope_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_add_with_scopeA_ptr 0 +#define __itt_metadata_str_add_with_scopeW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add_with_scope_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @} metadata group */ + +/** + * @defgroup relations Relations + * Instances of named entities can be explicitly associated with other + * instances using instance IDs and the relationship API calls. + * + * @{ + */ + +/** + * @ingroup relations + * @brief The kind of relation between two instances is specified by the enumerated type __itt_relation. + * Relations between instances can be added with an API call. The relation + * API uses instance IDs. Relations can be added before or after the actual + * instances are created and persist independently of the instances. This + * is the motivation for having different lifetimes for instance IDs and + * the actual instances. + */ +typedef enum +{ + __itt_relation_is_unknown = 0, + __itt_relation_is_dependent_on, /**< "A is dependent on B" means that A cannot start until B completes */ + __itt_relation_is_sibling_of, /**< "A is sibling of B" means that A and B were created as a group */ + __itt_relation_is_parent_of, /**< "A is parent of B" means that A created B */ + __itt_relation_is_continuation_of, /**< "A is continuation of B" means that A assumes the dependencies of B */ + __itt_relation_is_child_of, /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */ + __itt_relation_is_continued_by, /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */ + __itt_relation_is_predecessor_to /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */ +} __itt_relation; + +/** + * @ingroup relations + * @brief Add a relation to the current task instance. + * The current task instance is the head of the relation. + * @param[in] domain The domain controlling this call + * @param[in] relation The kind of relation + * @param[in] tail The ID for the tail of the relation + */ +void ITTAPI __itt_relation_add_to_current(const __itt_domain *domain, __itt_relation relation, __itt_id tail); + +/** + * @ingroup relations + * @brief Add a relation between two instance identifiers. + * @param[in] domain The domain controlling this call + * @param[in] head The ID for the head of the relation + * @param[in] relation The kind of relation + * @param[in] tail The ID for the tail of the relation + */ +void ITTAPI __itt_relation_add(const __itt_domain *domain, __itt_id head, __itt_relation relation, __itt_id tail); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, relation_add_to_current, (const __itt_domain *domain, __itt_relation relation, __itt_id tail)) +ITT_STUBV(ITTAPI, void, relation_add, (const __itt_domain *domain, __itt_id head, __itt_relation relation, __itt_id tail)) +#define __itt_relation_add_to_current(d,x,y) ITTNOTIFY_VOID_D2(relation_add_to_current,d,x,y) +#define __itt_relation_add_to_current_ptr ITTNOTIFY_NAME(relation_add_to_current) +#define __itt_relation_add(d,x,y,z) ITTNOTIFY_VOID_D3(relation_add,d,x,y,z) +#define __itt_relation_add_ptr ITTNOTIFY_NAME(relation_add) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_relation_add_to_current(d,x,y) +#define __itt_relation_add_to_current_ptr 0 +#define __itt_relation_add(d,x,y,z) +#define __itt_relation_add_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_relation_add_to_current_ptr 0 +#define __itt_relation_add_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} relations group */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_clock_info +{ + unsigned long long clock_freq; /*!< Clock domain frequency */ + unsigned long long clock_base; /*!< Clock domain base timestamp */ +} __itt_clock_info; + +#pragma pack(pop) +/** @endcond */ + +/** @cond exclude_from_documentation */ +typedef void (ITTAPI *__itt_get_clock_info_fn)(__itt_clock_info* clock_info, void* data); +/** @endcond */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_clock_domain +{ + __itt_clock_info info; /*!< Most recent clock domain info */ + __itt_get_clock_info_fn fn; /*!< Callback function pointer */ + void* fn_data; /*!< Input argument for the callback function */ + int extra1; /*!< Reserved. Must be zero */ + void* extra2; /*!< Reserved. Must be zero */ + struct ___itt_clock_domain* next; +} __itt_clock_domain; + +#pragma pack(pop) +/** @endcond */ + +/** + * @ingroup clockdomains + * @brief Create a clock domain. + * Certain applications require the capability to trace their application using + * a clock domain different than the CPU, for instance the instrumentation of events + * that occur on a GPU. + * Because the set of domains is expected to be static over the application's execution time, + * there is no mechanism to destroy a domain. + * Any domain can be accessed by any thread in the process, regardless of which thread created + * the domain. This call is thread-safe. + * @param[in] fn A pointer to a callback function which retrieves alternative CPU timestamps + * @param[in] fn_data Argument for a callback function; may be NULL + */ +__itt_clock_domain* ITTAPI __itt_clock_domain_create(__itt_get_clock_info_fn fn, void* fn_data); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_clock_domain*, clock_domain_create, (__itt_get_clock_info_fn fn, void* fn_data)) +#define __itt_clock_domain_create ITTNOTIFY_DATA(clock_domain_create) +#define __itt_clock_domain_create_ptr ITTNOTIFY_NAME(clock_domain_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_clock_domain_create(fn,fn_data) (__itt_clock_domain*)0 +#define __itt_clock_domain_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_clock_domain_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup clockdomains + * @brief Recalculate clock domains frequencies and clock base timestamps. + */ +void ITTAPI __itt_clock_domain_reset(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, clock_domain_reset, (void)) +#define __itt_clock_domain_reset ITTNOTIFY_VOID(clock_domain_reset) +#define __itt_clock_domain_reset_ptr ITTNOTIFY_NAME(clock_domain_reset) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_clock_domain_reset() +#define __itt_clock_domain_reset_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_clock_domain_reset_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup clockdomain + * @brief Create an instance of identifier. This establishes the beginning of the lifetime of + * an instance of the given ID in the trace. Once this lifetime starts, the ID can be used to + * tag named entity instances in calls such as __itt_task_begin, and to specify relationships among + * identified named entity instances, using the \ref relations APIs. + * @param[in] domain The domain controlling the execution of this call. + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] id The ID to create. + */ +void ITTAPI __itt_id_create_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id); + +/** + * @ingroup clockdomain + * @brief Destroy an instance of identifier. This ends the lifetime of the current instance of the + * given ID value in the trace. Any relationships that are established after this lifetime ends are + * invalid. This call must be performed before the given ID value can be reused for a different + * named entity instance. + * @param[in] domain The domain controlling the execution of this call. + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] id The ID to destroy. + */ +void ITTAPI __itt_id_destroy_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, id_create_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id)) +ITT_STUBV(ITTAPI, void, id_destroy_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id)) +#define __itt_id_create_ex(d,x,y,z) ITTNOTIFY_VOID_D3(id_create_ex,d,x,y,z) +#define __itt_id_create_ex_ptr ITTNOTIFY_NAME(id_create_ex) +#define __itt_id_destroy_ex(d,x,y,z) ITTNOTIFY_VOID_D3(id_destroy_ex,d,x,y,z) +#define __itt_id_destroy_ex_ptr ITTNOTIFY_NAME(id_destroy_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_id_create_ex(domain,clock_domain,timestamp,id) +#define __itt_id_create_ex_ptr 0 +#define __itt_id_destroy_ex(domain,clock_domain,timestamp,id) +#define __itt_id_destroy_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_id_create_ex_ptr 0 +#define __itt_id_destroy_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup clockdomain + * @brief Begin a task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] taskid The instance ID for this task instance, or __itt_null + * @param[in] parentid The parent instance to which this task instance belongs, or __itt_null + * @param[in] name The name of this task + */ +void ITTAPI __itt_task_begin_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, __itt_string_handle* name); + +/** + * @ingroup clockdomain + * @brief Begin a task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] taskid The identifier for this task instance, or __itt_null + * @param[in] parentid The parent of this task, or __itt_null + * @param[in] fn The pointer to the function you are tracing + */ +void ITTAPI __itt_task_begin_fn_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, void* fn); + +/** + * @ingroup clockdomain + * @brief End the current task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + */ +void ITTAPI __itt_task_end_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, task_begin_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, task_begin_fn_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, void* fn)) +ITT_STUBV(ITTAPI, void, task_end_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp)) +#define __itt_task_begin_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(task_begin_ex,d,x,y,z,a,b) +#define __itt_task_begin_ex_ptr ITTNOTIFY_NAME(task_begin_ex) +#define __itt_task_begin_fn_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(task_begin_fn_ex,d,x,y,z,a,b) +#define __itt_task_begin_fn_ex_ptr ITTNOTIFY_NAME(task_begin_fn_ex) +#define __itt_task_end_ex(d,x,y) ITTNOTIFY_VOID_D2(task_end_ex,d,x,y) +#define __itt_task_end_ex_ptr ITTNOTIFY_NAME(task_end_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_task_begin_ex(domain,clock_domain,timestamp,id,parentid,name) +#define __itt_task_begin_ex_ptr 0 +#define __itt_task_begin_fn_ex(domain,clock_domain,timestamp,id,parentid,fn) +#define __itt_task_begin_fn_ex_ptr 0 +#define __itt_task_end_ex(domain,clock_domain,timestamp) +#define __itt_task_end_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_task_begin_ex_ptr 0 +#define __itt_task_begin_fn_ex_ptr 0 +#define __itt_task_end_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @defgroup counters Counters + * @ingroup public + * Counters are user-defined objects with a monotonically increasing + * value. Counter values are 64-bit unsigned integers. + * Counters have names that can be displayed in + * the tools. + * @{ + */ + +/** + * @brief opaque structure for counter identification + */ +/** @cond exclude_from_documentation */ + +typedef struct ___itt_counter* __itt_counter; + +/** + * @brief Create an unsigned 64 bits integer counter with given name/domain + * + * After __itt_counter_create() is called, __itt_counter_inc(id), __itt_counter_inc_delta(id, delta), + * __itt_counter_set_value(id, value_ptr) or __itt_counter_set_value_ex(id, clock_domain, timestamp, value_ptr) + * can be used to change the value of the counter, where value_ptr is a pointer to an unsigned 64 bits integer + * + * The call is equal to __itt_counter_create_typed(name, domain, __itt_metadata_u64) + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_counter ITTAPI __itt_counter_createA(const char *name, const char *domain); +__itt_counter ITTAPI __itt_counter_createW(const wchar_t *name, const wchar_t *domain); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_counter_create __itt_counter_createW +# define __itt_counter_create_ptr __itt_counter_createW_ptr +#else /* UNICODE */ +# define __itt_counter_create __itt_counter_createA +# define __itt_counter_create_ptr __itt_counter_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_counter ITTAPI __itt_counter_create(const char *name, const char *domain); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_counter, counter_createA, (const char *name, const char *domain)) +ITT_STUB(ITTAPI, __itt_counter, counter_createW, (const wchar_t *name, const wchar_t *domain)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_counter, counter_create, (const char *name, const char *domain)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_createA ITTNOTIFY_DATA(counter_createA) +#define __itt_counter_createA_ptr ITTNOTIFY_NAME(counter_createA) +#define __itt_counter_createW ITTNOTIFY_DATA(counter_createW) +#define __itt_counter_createW_ptr ITTNOTIFY_NAME(counter_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create ITTNOTIFY_DATA(counter_create) +#define __itt_counter_create_ptr ITTNOTIFY_NAME(counter_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_createA(name, domain) +#define __itt_counter_createA_ptr 0 +#define __itt_counter_createW(name, domain) +#define __itt_counter_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create(name, domain) +#define __itt_counter_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_createA_ptr 0 +#define __itt_counter_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Increment the unsigned 64 bits integer counter value + * + * Calling this function to non-unsigned 64 bits integer counters has no effect + */ +void ITTAPI __itt_counter_inc(__itt_counter id); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_inc, (__itt_counter id)) +#define __itt_counter_inc ITTNOTIFY_VOID(counter_inc) +#define __itt_counter_inc_ptr ITTNOTIFY_NAME(counter_inc) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_inc(id) +#define __itt_counter_inc_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_inc_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** + * @brief Increment the unsigned 64 bits integer counter value with x + * + * Calling this function to non-unsigned 64 bits integer counters has no effect + */ +void ITTAPI __itt_counter_inc_delta(__itt_counter id, unsigned long long value); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_inc_delta, (__itt_counter id, unsigned long long value)) +#define __itt_counter_inc_delta ITTNOTIFY_VOID(counter_inc_delta) +#define __itt_counter_inc_delta_ptr ITTNOTIFY_NAME(counter_inc_delta) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_inc_delta(id, value) +#define __itt_counter_inc_delta_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_inc_delta_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Decrement the unsigned 64 bits integer counter value + * + * Calling this function to non-unsigned 64 bits integer counters has no effect + */ +void ITTAPI __itt_counter_dec(__itt_counter id); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_dec, (__itt_counter id)) +#define __itt_counter_dec ITTNOTIFY_VOID(counter_dec) +#define __itt_counter_dec_ptr ITTNOTIFY_NAME(counter_dec) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_dec(id) +#define __itt_counter_dec_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_dec_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** + * @brief Decrement the unsigned 64 bits integer counter value with x + * + * Calling this function to non-unsigned 64 bits integer counters has no effect + */ +void ITTAPI __itt_counter_dec_delta(__itt_counter id, unsigned long long value); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_dec_delta, (__itt_counter id, unsigned long long value)) +#define __itt_counter_dec_delta ITTNOTIFY_VOID(counter_dec_delta) +#define __itt_counter_dec_delta_ptr ITTNOTIFY_NAME(counter_dec_delta) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_dec_delta(id, value) +#define __itt_counter_dec_delta_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_dec_delta_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup counters + * @brief Increment a counter by one. + * The first call with a given name creates a counter by that name and sets its + * value to zero. Successive calls increment the counter value. + * @param[in] domain The domain controlling the call. Counter names are not domain specific. + * The domain argument is used only to enable or disable the API calls. + * @param[in] name The name of the counter + */ +void ITTAPI __itt_counter_inc_v3(const __itt_domain *domain, __itt_string_handle *name); + +/** + * @ingroup counters + * @brief Increment a counter by the value specified in delta. + * @param[in] domain The domain controlling the call. Counter names are not domain specific. + * The domain argument is used only to enable or disable the API calls. + * @param[in] name The name of the counter + * @param[in] delta The amount by which to increment the counter + */ +void ITTAPI __itt_counter_inc_delta_v3(const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_inc_v3, (const __itt_domain *domain, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, counter_inc_delta_v3, (const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta)) +#define __itt_counter_inc_v3(d,x) ITTNOTIFY_VOID_D1(counter_inc_v3,d,x) +#define __itt_counter_inc_v3_ptr ITTNOTIFY_NAME(counter_inc_v3) +#define __itt_counter_inc_delta_v3(d,x,y) ITTNOTIFY_VOID_D2(counter_inc_delta_v3,d,x,y) +#define __itt_counter_inc_delta_v3_ptr ITTNOTIFY_NAME(counter_inc_delta_v3) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_inc_v3(domain,name) +#define __itt_counter_inc_v3_ptr 0 +#define __itt_counter_inc_delta_v3(domain,name,delta) +#define __itt_counter_inc_delta_v3_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_inc_v3_ptr 0 +#define __itt_counter_inc_delta_v3_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + + +/** + * @ingroup counters + * @brief Decrement a counter by one. + * The first call with a given name creates a counter by that name and sets its + * value to zero. Successive calls decrement the counter value. + * @param[in] domain The domain controlling the call. Counter names are not domain specific. + * The domain argument is used only to enable or disable the API calls. + * @param[in] name The name of the counter + */ +void ITTAPI __itt_counter_dec_v3(const __itt_domain *domain, __itt_string_handle *name); + +/** + * @ingroup counters + * @brief Decrement a counter by the value specified in delta. + * @param[in] domain The domain controlling the call. Counter names are not domain specific. + * The domain argument is used only to enable or disable the API calls. + * @param[in] name The name of the counter + * @param[in] delta The amount by which to decrement the counter + */ +void ITTAPI __itt_counter_dec_delta_v3(const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_dec_v3, (const __itt_domain *domain, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, counter_dec_delta_v3, (const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta)) +#define __itt_counter_dec_v3(d,x) ITTNOTIFY_VOID_D1(counter_dec_v3,d,x) +#define __itt_counter_dec_v3_ptr ITTNOTIFY_NAME(counter_dec_v3) +#define __itt_counter_dec_delta_v3(d,x,y) ITTNOTIFY_VOID_D2(counter_dec_delta_v3,d,x,y) +#define __itt_counter_dec_delta_v3_ptr ITTNOTIFY_NAME(counter_dec_delta_v3) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_dec_v3(domain,name) +#define __itt_counter_dec_v3_ptr 0 +#define __itt_counter_dec_delta_v3(domain,name,delta) +#define __itt_counter_dec_delta_v3_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_dec_v3_ptr 0 +#define __itt_counter_dec_delta_v3_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @} counters group */ + + +/** + * @brief Set the counter value + */ +void ITTAPI __itt_counter_set_value(__itt_counter id, void *value_ptr); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_set_value, (__itt_counter id, void *value_ptr)) +#define __itt_counter_set_value ITTNOTIFY_VOID(counter_set_value) +#define __itt_counter_set_value_ptr ITTNOTIFY_NAME(counter_set_value) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_set_value(id, value_ptr) +#define __itt_counter_set_value_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_set_value_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Set the counter value + */ +void ITTAPI __itt_counter_set_value_ex(__itt_counter id, __itt_clock_domain *clock_domain, unsigned long long timestamp, void *value_ptr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_set_value_ex, (__itt_counter id, __itt_clock_domain *clock_domain, unsigned long long timestamp, void *value_ptr)) +#define __itt_counter_set_value_ex ITTNOTIFY_VOID(counter_set_value_ex) +#define __itt_counter_set_value_ex_ptr ITTNOTIFY_NAME(counter_set_value_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_set_value_ex(id, clock_domain, timestamp, value_ptr) +#define __itt_counter_set_value_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_set_value_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Create a typed counter with given name/domain + * + * After __itt_counter_create_typed() is called, __itt_counter_inc(id), __itt_counter_inc_delta(id, delta), + * __itt_counter_set_value(id, value_ptr) or __itt_counter_set_value_ex(id, clock_domain, timestamp, value_ptr) + * can be used to change the value of the counter + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_counter ITTAPI __itt_counter_create_typedA(const char *name, const char *domain, __itt_metadata_type type); +__itt_counter ITTAPI __itt_counter_create_typedW(const wchar_t *name, const wchar_t *domain, __itt_metadata_type type); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_counter_create_typed __itt_counter_create_typedW +# define __itt_counter_create_typed_ptr __itt_counter_create_typedW_ptr +#else /* UNICODE */ +# define __itt_counter_create_typed __itt_counter_create_typedA +# define __itt_counter_create_typed_ptr __itt_counter_create_typedA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_counter ITTAPI __itt_counter_create_typed(const char *name, const char *domain, __itt_metadata_type type); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_counter, counter_create_typedA, (const char *name, const char *domain, __itt_metadata_type type)) +ITT_STUB(ITTAPI, __itt_counter, counter_create_typedW, (const wchar_t *name, const wchar_t *domain, __itt_metadata_type type)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_counter, counter_create_typed, (const char *name, const char *domain, __itt_metadata_type type)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_create_typedA ITTNOTIFY_DATA(counter_create_typedA) +#define __itt_counter_create_typedA_ptr ITTNOTIFY_NAME(counter_create_typedA) +#define __itt_counter_create_typedW ITTNOTIFY_DATA(counter_create_typedW) +#define __itt_counter_create_typedW_ptr ITTNOTIFY_NAME(counter_create_typedW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_typed ITTNOTIFY_DATA(counter_create_typed) +#define __itt_counter_create_typed_ptr ITTNOTIFY_NAME(counter_create_typed) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_create_typedA(name, domain, type) +#define __itt_counter_create_typedA_ptr 0 +#define __itt_counter_create_typedW(name, domain, type) +#define __itt_counter_create_typedW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_typed(name, domain, type) +#define __itt_counter_create_typed_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_create_typedA_ptr 0 +#define __itt_counter_create_typedW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_typed_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Destroy the counter identified by the pointer previously returned by __itt_counter_create() or + * __itt_counter_create_typed() + */ +void ITTAPI __itt_counter_destroy(__itt_counter id); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_destroy, (__itt_counter id)) +#define __itt_counter_destroy ITTNOTIFY_VOID(counter_destroy) +#define __itt_counter_destroy_ptr ITTNOTIFY_NAME(counter_destroy) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_destroy(id) +#define __itt_counter_destroy_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_destroy_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} counters group */ + +/** + * @ingroup markers + * @brief Create a marker instance. + * @param[in] domain The domain for this marker + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] id The instance ID for this marker, or __itt_null + * @param[in] name The name for this marker + * @param[in] scope The scope for this marker + */ +void ITTAPI __itt_marker_ex(const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_string_handle *name, __itt_scope scope); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, marker_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_string_handle *name, __itt_scope scope)) +#define __itt_marker_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(marker_ex,d,x,y,z,a,b) +#define __itt_marker_ex_ptr ITTNOTIFY_NAME(marker_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_marker_ex(domain,clock_domain,timestamp,id,name,scope) +#define __itt_marker_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_marker_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup clockdomain + * @brief Add a relation to the current task instance. + * The current task instance is the head of the relation. + * @param[in] domain The domain controlling this call + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] relation The kind of relation + * @param[in] tail The ID for the tail of the relation + */ +void ITTAPI __itt_relation_add_to_current_ex(const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_relation relation, __itt_id tail); + +/** + * @ingroup clockdomain + * @brief Add a relation between two instance identifiers. + * @param[in] domain The domain controlling this call + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] head The ID for the head of the relation + * @param[in] relation The kind of relation + * @param[in] tail The ID for the tail of the relation + */ +void ITTAPI __itt_relation_add_ex(const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id head, __itt_relation relation, __itt_id tail); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, relation_add_to_current_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_relation relation, __itt_id tail)) +ITT_STUBV(ITTAPI, void, relation_add_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id head, __itt_relation relation, __itt_id tail)) +#define __itt_relation_add_to_current_ex(d,x,y,z,a) ITTNOTIFY_VOID_D4(relation_add_to_current_ex,d,x,y,z,a) +#define __itt_relation_add_to_current_ex_ptr ITTNOTIFY_NAME(relation_add_to_current_ex) +#define __itt_relation_add_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(relation_add_ex,d,x,y,z,a,b) +#define __itt_relation_add_ex_ptr ITTNOTIFY_NAME(relation_add_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_relation_add_to_current_ex(domain,clock_domain,timestame,relation,tail) +#define __itt_relation_add_to_current_ex_ptr 0 +#define __itt_relation_add_ex(domain,clock_domain,timestamp,head,relation,tail) +#define __itt_relation_add_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_relation_add_to_current_ex_ptr 0 +#define __itt_relation_add_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @cond exclude_from_documentation */ +typedef enum ___itt_track_group_type +{ + __itt_track_group_type_normal = 0 +} __itt_track_group_type; +/** @endcond */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_track_group +{ + __itt_string_handle* name; /*!< Name of the track group */ + struct ___itt_track* track; /*!< List of child tracks */ + __itt_track_group_type tgtype; /*!< Type of the track group */ + int extra1; /*!< Reserved. Must be zero */ + void* extra2; /*!< Reserved. Must be zero */ + struct ___itt_track_group* next; +} __itt_track_group; + +#pragma pack(pop) +/** @endcond */ + +/** + * @brief Placeholder for custom track types. Currently, "normal" custom track + * is the only available track type. + */ +typedef enum ___itt_track_type +{ + __itt_track_type_normal = 0 +#ifdef INTEL_ITTNOTIFY_API_PRIVATE + , __itt_track_type_queue +#endif /* INTEL_ITTNOTIFY_API_PRIVATE */ +} __itt_track_type; + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_track +{ + __itt_string_handle* name; /*!< Name of the track group */ + __itt_track_group* group; /*!< Parent group to a track */ + __itt_track_type ttype; /*!< Type of the track */ + int extra1; /*!< Reserved. Must be zero */ + void* extra2; /*!< Reserved. Must be zero */ + struct ___itt_track* next; +} __itt_track; + +#pragma pack(pop) +/** @endcond */ + +/** + * @brief Create logical track group. + */ +__itt_track_group* ITTAPI __itt_track_group_create(__itt_string_handle* name, __itt_track_group_type track_group_type); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_track_group*, track_group_create, (__itt_string_handle* name, __itt_track_group_type track_group_type)) +#define __itt_track_group_create ITTNOTIFY_DATA(track_group_create) +#define __itt_track_group_create_ptr ITTNOTIFY_NAME(track_group_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_track_group_create(name) (__itt_track_group*)0 +#define __itt_track_group_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_track_group_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Create logical track. + */ +__itt_track* ITTAPI __itt_track_create(__itt_track_group* track_group, __itt_string_handle* name, __itt_track_type track_type); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_track*, track_create, (__itt_track_group* track_group,__itt_string_handle* name, __itt_track_type track_type)) +#define __itt_track_create ITTNOTIFY_DATA(track_create) +#define __itt_track_create_ptr ITTNOTIFY_NAME(track_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_track_create(track_group,name,track_type) (__itt_track*)0 +#define __itt_track_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_track_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Set the logical track. + */ +void ITTAPI __itt_set_track(__itt_track* track); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, set_track, (__itt_track *track)) +#define __itt_set_track ITTNOTIFY_VOID(set_track) +#define __itt_set_track_ptr ITTNOTIFY_NAME(set_track) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_set_track(track) +#define __itt_set_track_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_set_track_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/* ========================================================================== */ +/** @cond exclude_from_gpa_documentation */ +/** + * @defgroup events Events + * @ingroup public + * Events group + * @{ + */ +/** @brief user event type */ +typedef int __itt_event; + +/** + * @brief Create an event notification + * @note name or namelen being null/name and namelen not matching, user event feature not enabled + * @return non-zero event identifier upon success and __itt_err otherwise + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_event LIBITTAPI __itt_event_createA(const char *name, int namelen); +__itt_event LIBITTAPI __itt_event_createW(const wchar_t *name, int namelen); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_event_create __itt_event_createW +# define __itt_event_create_ptr __itt_event_createW_ptr +#else +# define __itt_event_create __itt_event_createA +# define __itt_event_create_ptr __itt_event_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_event LIBITTAPI __itt_event_create(const char *name, int namelen); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, __itt_event, event_createA, (const char *name, int namelen)) +ITT_STUB(LIBITTAPI, __itt_event, event_createW, (const wchar_t *name, int namelen)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, __itt_event, event_create, (const char *name, int namelen)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA ITTNOTIFY_DATA(event_createA) +#define __itt_event_createA_ptr ITTNOTIFY_NAME(event_createA) +#define __itt_event_createW ITTNOTIFY_DATA(event_createW) +#define __itt_event_createW_ptr ITTNOTIFY_NAME(event_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create ITTNOTIFY_DATA(event_create) +#define __itt_event_create_ptr ITTNOTIFY_NAME(event_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA(name, namelen) (__itt_event)0 +#define __itt_event_createA_ptr 0 +#define __itt_event_createW(name, namelen) (__itt_event)0 +#define __itt_event_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create(name, namelen) (__itt_event)0 +#define __itt_event_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA_ptr 0 +#define __itt_event_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an event occurrence. + * @return __itt_err upon failure (invalid event id/user event feature not enabled) + */ +int LIBITTAPI __itt_event_start(__itt_event event); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(LIBITTAPI, int, event_start, (__itt_event event)) +#define __itt_event_start ITTNOTIFY_DATA(event_start) +#define __itt_event_start_ptr ITTNOTIFY_NAME(event_start) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_event_start(event) (int)0 +#define __itt_event_start_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_event_start_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an event end occurrence. + * @note It is optional if events do not have durations. + * @return __itt_err upon failure (invalid event id/user event feature not enabled) + */ +int LIBITTAPI __itt_event_end(__itt_event event); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(LIBITTAPI, int, event_end, (__itt_event event)) +#define __itt_event_end ITTNOTIFY_DATA(event_end) +#define __itt_event_end_ptr ITTNOTIFY_NAME(event_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_event_end(event) (int)0 +#define __itt_event_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_event_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} events group */ + + +/** + * @defgroup arrays Arrays Visualizer + * @ingroup public + * Visualize arrays + * @{ + */ + +/** + * @enum __itt_av_data_type + * @brief Defines types of arrays data (for C/C++ intrinsic types) + */ +typedef enum +{ + __itt_e_first = 0, + __itt_e_char = 0, /* 1-byte integer */ + __itt_e_uchar, /* 1-byte unsigned integer */ + __itt_e_int16, /* 2-byte integer */ + __itt_e_uint16, /* 2-byte unsigned integer */ + __itt_e_int32, /* 4-byte integer */ + __itt_e_uint32, /* 4-byte unsigned integer */ + __itt_e_int64, /* 8-byte integer */ + __itt_e_uint64, /* 8-byte unsigned integer */ + __itt_e_float, /* 4-byte floating */ + __itt_e_double, /* 8-byte floating */ + __itt_e_last = __itt_e_double +} __itt_av_data_type; + +/** + * @brief Save an array data to a file. + * Output format is defined by the file extension. The csv and bmp formats are supported (bmp - for 2-dimensional array only). + * @param[in] data - pointer to the array data + * @param[in] rank - the rank of the array + * @param[in] dimensions - pointer to an array of integers, which specifies the array dimensions. + * The size of dimensions must be equal to the rank + * @param[in] type - the type of the array, specified as one of the __itt_av_data_type values (for intrinsic types) + * @param[in] filePath - the file path; the output format is defined by the file extension + * @param[in] columnOrder - defines how the array is stored in the linear memory. + * It should be 1 for column-major order (e.g. in FORTRAN) or 0 - for row-major order (e.g. in C). + */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int ITTAPI __itt_av_saveA(void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder); +int ITTAPI __itt_av_saveW(void *data, int rank, const int *dimensions, int type, const wchar_t *filePath, int columnOrder); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_av_save __itt_av_saveW +# define __itt_av_save_ptr __itt_av_saveW_ptr +#else /* UNICODE */ +# define __itt_av_save __itt_av_saveA +# define __itt_av_save_ptr __itt_av_saveA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int ITTAPI __itt_av_save(void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, int, av_saveA, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder)) +ITT_STUB(ITTAPI, int, av_saveW, (void *data, int rank, const int *dimensions, int type, const wchar_t *filePath, int columnOrder)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, av_save, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_av_saveA ITTNOTIFY_DATA(av_saveA) +#define __itt_av_saveA_ptr ITTNOTIFY_NAME(av_saveA) +#define __itt_av_saveW ITTNOTIFY_DATA(av_saveW) +#define __itt_av_saveW_ptr ITTNOTIFY_NAME(av_saveW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_av_save ITTNOTIFY_DATA(av_save) +#define __itt_av_save_ptr ITTNOTIFY_NAME(av_save) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_av_saveA(name) +#define __itt_av_saveA_ptr 0 +#define __itt_av_saveW(name) +#define __itt_av_saveW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_av_save(name) +#define __itt_av_save_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_av_saveA_ptr 0 +#define __itt_av_saveW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_av_save_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +void ITTAPI __itt_enable_attach(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, enable_attach, (void)) +#define __itt_enable_attach ITTNOTIFY_VOID(enable_attach) +#define __itt_enable_attach_ptr ITTNOTIFY_NAME(enable_attach) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_enable_attach() +#define __itt_enable_attach_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_enable_attach_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @cond exclude_from_gpa_documentation */ + +/** @} arrays group */ + +/** @endcond */ + +/** + * @brief Module load notification + * This API is used to report necessary information in case of bypassing default system loader. + * Notification should be done immidiatelly after this module is loaded to process memory. + * @param[in] start_addr - module start address + * @param[in] end_addr - module end address + * @param[in] path - file system full path to the module + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_module_loadA(void *start_addr, void *end_addr, const char *path); +void ITTAPI __itt_module_loadW(void *start_addr, void *end_addr, const wchar_t *path); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_module_load __itt_module_loadW +# define __itt_module_load_ptr __itt_module_loadW_ptr +#else /* UNICODE */ +# define __itt_module_load __itt_module_loadA +# define __itt_module_load_ptr __itt_module_loadA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_module_load(void *start_addr, void *end_addr, const char *path); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, void, module_loadA, (void *start_addr, void *end_addr, const char *path)) +ITT_STUB(ITTAPI, void, module_loadW, (void *start_addr, void *end_addr, const wchar_t *path)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, void, module_load, (void *start_addr, void *end_addr, const char *path)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_module_loadA ITTNOTIFY_VOID(module_loadA) +#define __itt_module_loadA_ptr ITTNOTIFY_NAME(module_loadA) +#define __itt_module_loadW ITTNOTIFY_VOID(module_loadW) +#define __itt_module_loadW_ptr ITTNOTIFY_NAME(module_loadW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_module_load ITTNOTIFY_VOID(module_load) +#define __itt_module_load_ptr ITTNOTIFY_NAME(module_load) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_module_loadA(start_addr, end_addr, path) +#define __itt_module_loadA_ptr 0 +#define __itt_module_loadW(start_addr, end_addr, path) +#define __itt_module_loadW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_module_load(start_addr, end_addr, path) +#define __itt_module_load_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_module_loadA_ptr 0 +#define __itt_module_loadW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_module_load_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Report module unload + * This API is used to report necessary information in case of bypassing default system loader. + * Notification should be done just before the module is unloaded from process memory. + * @param[in] addr - base address of loaded module + */ +void ITTAPI __itt_module_unload(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, module_unload, (void *addr)) +#define __itt_module_unload ITTNOTIFY_VOID(module_unload) +#define __itt_module_unload_ptr ITTNOTIFY_NAME(module_unload) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_module_unload(addr) +#define __itt_module_unload_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_module_unload_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @cond exclude_from_documentation */ +typedef enum +{ + __itt_module_type_unknown = 0, + __itt_module_type_elf, + __itt_module_type_coff +} __itt_module_type; +/** @endcond */ + +/** @cond exclude_from_documentation */ +typedef enum +{ + itt_section_type_unknown, + itt_section_type_bss, /* notifies that the section contains uninitialized data. These are the relevant section types and the modules that contain them: + * ELF module: SHT_NOBITS section type + * COFF module: IMAGE_SCN_CNT_UNINITIALIZED_DATA section type + */ + itt_section_type_data, /* notifies that section contains initialized data. These are the relevant section types and the modules that contain them: + * ELF module: SHT_PROGBITS section type + * COFF module: IMAGE_SCN_CNT_INITIALIZED_DATA section type + */ + itt_section_type_text /* notifies that the section contains executable code. These are the relevant section types and the modules that contain them: + * ELF module: SHT_PROGBITS section type + * COFF module: IMAGE_SCN_CNT_CODE section type + */ +} __itt_section_type; +/** @endcond */ + +/** + * @hideinitializer + * @brief bit-mask, detects a section attribute that indicates whether a section can be executed as code: + * These are the relevant section attributes and the modules that contain them: + * ELF module: PF_X section attribute + * COFF module: IMAGE_SCN_MEM_EXECUTE attribute + */ +#define __itt_section_exec 0x20000000 + +/** + * @hideinitializer + * @brief bit-mask, detects a section attribute that indicates whether a section can be read. + * These are the relevant section attributes and the modules that contain them: + * ELF module: PF_R attribute + * COFF module: IMAGE_SCN_MEM_READ attribute + */ +#define __itt_section_read 0x40000000 + +/** + * @hideinitializer + * @brief bit-mask, detects a section attribute that indicates whether a section can be written to. + * These are the relevant section attributes and the modules that contain them: + * ELF module: PF_W attribute + * COFF module: IMAGE_SCN_MEM_WRITE attribute + */ +#define __itt_section_write 0x80000000 + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_section_info +{ + const char* name; /*!< Section name in UTF8 */ + __itt_section_type type; /*!< Section content and semantics description */ + size_t flags; /*!< Section bit flags that describe attributes using bit mask + * Zero if disabled, non-zero if enabled + */ + void* start_addr; /*!< Section load(relocated) start address */ + size_t size; /*!< Section file offset */ + size_t file_offset; /*!< Section size */ +} __itt_section_info; + +#pragma pack(pop) +/** @endcond */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_module_object +{ + unsigned int version; /*!< API version*/ + __itt_id module_id; /*!< Unique identifier. This is unchanged for sections that belong to the same module */ + __itt_module_type module_type; /*!< Binary module format */ + const char* module_name; /*!< Unique module name or path to module in UTF8 + * Contains module name when module_bufer and module_size exist + * Contains module path when module_bufer and module_size absent + * module_name remains the same for the certain module_id + */ + void* module_buffer; /*!< Module buffer content */ + size_t module_size; /*!< Module buffer size */ + /*!< If module_buffer and module_size exist, the binary module is dumped onto the system. + * If module_buffer and module_size do not exist, + * the binary module exists on the system already. + * The module_name parameter contains the path to the module. + */ + __itt_section_info* section_array; /*!< Reference to section information */ + size_t section_number; +} __itt_module_object; + +#pragma pack(pop) +/** @endcond */ + +/** + * @brief Load module content and its loaded(relocated) sections. + * This API is useful to save a module, or specify its location on the system and report information about loaded sections. + * The target module is saved on the system if module buffer content and size are available. + * If module buffer content and size are unavailable, the module name contains the path to the existing binary module. + * @param[in] module_obj - provides module and section information, along with unique module identifiers (name,module ID) + * which bind the binary module to particular sections. + */ +void ITTAPI __itt_module_load_with_sections(__itt_module_object* module_obj); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, module_load_with_sections, (__itt_module_object* module_obj)) +#define __itt_module_load_with_sections ITTNOTIFY_VOID(module_load_with_sections) +#define __itt_module_load_with_sections_ptr ITTNOTIFY_NAME(module_load_with_sections) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_module_load_with_sections(module_obj) +#define __itt_module_load_with_sections_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_module_load_with_sections_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Unload a module and its loaded(relocated) sections. + * This API notifies that the module and its sections were unloaded. + * @param[in] module_obj - provides module and sections information, along with unique module identifiers (name,module ID) + * which bind the binary module to particular sections. + */ +void ITTAPI __itt_module_unload_with_sections(__itt_module_object* module_obj); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, module_unload_with_sections, (__itt_module_object* module_obj)) +#define __itt_module_unload_with_sections ITTNOTIFY_VOID(module_unload_with_sections) +#define __itt_module_unload_with_sections_ptr ITTNOTIFY_NAME(module_unload_with_sections) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_module_unload_with_sections(module_obj) +#define __itt_module_unload_with_sections_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_module_unload_with_sections_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_histogram +{ + const __itt_domain* domain; /*!< Domain of the histogram*/ + const char* nameA; /*!< Name of the histogram */ +#if defined(UNICODE) || defined(_UNICODE) + const wchar_t* nameW; +#else /* UNICODE || _UNICODE */ + void* nameW; +#endif /* UNICODE || _UNICODE */ + __itt_metadata_type x_type; /*!< Type of the histogram X axis */ + __itt_metadata_type y_type; /*!< Type of the histogram Y axis */ + int extra1; /*!< Reserved to the runtime */ + void* extra2; /*!< Reserved to the runtime */ + struct ___itt_histogram* next; +} __itt_histogram; + +#pragma pack(pop) +/** @endcond */ + +/** + * @brief Create a typed histogram instance with given name/domain. + * @param[in] domain The domain controlling the call. + * @param[in] name The name of the histogram. + * @param[in] x_type The type of the X axis in histogram (may be 0 to calculate batch statistics). + * @param[in] y_type The type of the Y axis in histogram. +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_histogram* ITTAPI __itt_histogram_createA(const __itt_domain* domain, const char* name, __itt_metadata_type x_type, __itt_metadata_type y_type); +__itt_histogram* ITTAPI __itt_histogram_createW(const __itt_domain* domain, const wchar_t* name, __itt_metadata_type x_type, __itt_metadata_type y_type); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_histogram_create __itt_histogram_createW +# define __itt_histogram_create_ptr __itt_histogram_createW_ptr +#else /* UNICODE */ +# define __itt_histogram_create __itt_histogram_createA +# define __itt_histogram_create_ptr __itt_histogram_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_histogram* ITTAPI __itt_histogram_create(const __itt_domain* domain, const char* name, __itt_metadata_type x_type, __itt_metadata_type y_type); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_histogram*, histogram_createA, (const __itt_domain* domain, const char* name, __itt_metadata_type x_type, __itt_metadata_type y_type)) +ITT_STUB(ITTAPI, __itt_histogram*, histogram_createW, (const __itt_domain* domain, const wchar_t* name, __itt_metadata_type x_type, __itt_metadata_type y_type)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_histogram*, histogram_create, (const __itt_domain* domain, const char* name, __itt_metadata_type x_type, __itt_metadata_type y_type)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_histogram_createA ITTNOTIFY_DATA(histogram_createA) +#define __itt_histogram_createA_ptr ITTNOTIFY_NAME(histogram_createA) +#define __itt_histogram_createW ITTNOTIFY_DATA(histogram_createW) +#define __itt_histogram_createW_ptr ITTNOTIFY_NAME(histogram_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_histogram_create ITTNOTIFY_DATA(histogram_create) +#define __itt_histogram_create_ptr ITTNOTIFY_NAME(histogram_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_histogram_createA(domain, name, x_type, y_type) (__itt_histogram*)0 +#define __itt_histogram_createA_ptr 0 +#define __itt_histogram_createW(domain, name, x_type, y_type) (__itt_histogram*)0 +#define __itt_histogram_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_histogram_create(domain, name, x_type, y_type) (__itt_histogram*)0 +#define __itt_histogram_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_histogram_createA_ptr 0 +#define __itt_histogram_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_histogram_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Submit statistics for a histogram instance. + * @param[in] hist Pointer to the histogram instance to which the histogram statistic is to be dumped. + * @param[in] length The number of elements in dumped axis data array. + * @param[in] x_data The X axis dumped data itself (may be NULL to calculate batch statistics). + * @param[in] y_data The Y axis dumped data itself. +*/ +void ITTAPI __itt_histogram_submit(__itt_histogram* hist, size_t length, void* x_data, void* y_data); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, histogram_submit, (__itt_histogram* hist, size_t length, void* x_data, void* y_data)) +#define __itt_histogram_submit ITTNOTIFY_VOID(histogram_submit) +#define __itt_histogram_submit_ptr ITTNOTIFY_NAME(histogram_submit) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_histogram_submit(hist, length, x_data, y_data) +#define __itt_histogram_submit_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_histogram_submit_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ + +/** +* @brief function allows to obtain the current collection state at the moment +* @return collection state as a enum __itt_collection_state +*/ +__itt_collection_state __itt_get_collection_state(void); + +/** +* @brief function releases resources allocated by ITT API static part +* this API should be called from the library destructor +* @return void +*/ +void __itt_release_resources(void); +/** @endcond */ + +/** + * @brief Create a typed counter with given domain pointer, string name and counter type +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_counter ITTAPI __itt_counter_createA_v3(const __itt_domain* domain, const char* name, __itt_metadata_type type); +__itt_counter ITTAPI __itt_counter_createW_v3(const __itt_domain* domain, const wchar_t* name, __itt_metadata_type type); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_counter_create_v3 __itt_counter_createW_v3 +# define __itt_counter_create_v3_ptr __itt_counter_createW_v3_ptr +#else /* UNICODE */ +# define __itt_counter_create_v3 __itt_counter_createA_v3 +# define __itt_counter_create_v3_ptr __itt_counter_createA_v3_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_counter ITTAPI __itt_counter_create_v3(const __itt_domain* domain, const char* name, __itt_metadata_type type); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_counter, counter_createA_v3, (const __itt_domain* domain, const char* name, __itt_metadata_type type)) +ITT_STUB(ITTAPI, __itt_counter, counter_createW_v3, (const __itt_domain* domain, const wchar_t* name, __itt_metadata_type type)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_counter, counter_create_v3, (const __itt_domain* domain, const char* name, __itt_metadata_type type)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_createA_v3 ITTNOTIFY_DATA(counter_createA_v3) +#define __itt_counter_createA_v3_ptr ITTNOTIFY_NAME(counter_createA_v3) +#define __itt_counter_createW_v3 ITTNOTIFY_DATA(counter_createW_v3) +#define __itt_counter_createW_v3_ptr ITTNOTIFY_NAME(counter_createW_v3) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_v3 ITTNOTIFY_DATA(counter_create_v3) +#define __itt_counter_create_v3_ptr ITTNOTIFY_NAME(counter_create_v3) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_createA_v3(domain, name, type) (__itt_counter)0 +#define __itt_counter_createA_v3_ptr 0 +#define __itt_counter_createW_v3(domain, name, type) (__itt_counter)0 +#define __itt_counter_create_typedW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_v3(domain, name, type) (__itt_counter)0 +#define __itt_counter_create_v3_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_createA_v3_ptr 0 +#define __itt_counter_createW_v3_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_v3_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Set the counter value api + */ +void ITTAPI __itt_counter_set_value_v3(__itt_counter counter, void *value_ptr); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_set_value_v3, (__itt_counter counter, void *value_ptr)) +#define __itt_counter_set_value_v3 ITTNOTIFY_VOID(counter_set_value_v3) +#define __itt_counter_set_value_v3_ptr ITTNOTIFY_NAME(counter_set_value_v3) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_set_value_v3(counter, value_ptr) +#define __itt_counter_set_value_v3_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_set_value_v3_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief describes the type of context metadata +*/ +typedef enum { + __itt_context_unknown = 0, /*!< Undefined type */ + __itt_context_nameA, /*!< ASCII string char* type */ + __itt_context_nameW, /*!< Unicode string wchar_t* type */ + __itt_context_deviceA, /*!< ASCII string char* type */ + __itt_context_deviceW, /*!< Unicode string wchar_t* type */ + __itt_context_unitsA, /*!< ASCII string char* type */ + __itt_context_unitsW, /*!< Unicode string wchar_t* type */ + __itt_context_pci_addrA, /*!< ASCII string char* type */ + __itt_context_pci_addrW, /*!< Unicode string wchar_t* type */ + __itt_context_tid, /*!< Unsigned 64-bit integer type */ + __itt_context_max_val, /*!< Unsigned 64-bit integer type */ + __itt_context_bandwidth_flag, /*!< Unsigned 64-bit integer type */ + __itt_context_latency_flag, /*!< Unsigned 64-bit integer type */ + __itt_context_occupancy_flag, /*!< Unsigned 64-bit integer type */ + __itt_context_on_thread_flag, /*!< Unsigned 64-bit integer type */ + __itt_context_is_abs_val_flag, /*!< Unsigned 64-bit integer type */ + __itt_context_cpu_instructions_flag, /*!< Unsigned 64-bit integer type */ + __itt_context_cpu_cycles_flag /*!< Unsigned 64-bit integer type */ +} __itt_context_type; + +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_context_name __itt_context_nameW +# define __itt_context_device __itt_context_deviceW +# define __itt_context_units __itt_context_unitsW +# define __itt_context_pci_addr __itt_context_pci_addrW +#else /* UNICODE || _UNICODE */ +# define __itt_context_name __itt_context_nameA +# define __itt_context_device __itt_context_deviceA +# define __itt_context_units __itt_context_unitsA +# define __itt_context_pci_addr __itt_context_pci_addrA +#endif /* UNICODE || _UNICODE */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_context_metadata +{ + __itt_context_type type; /*!< Type of the context metadata value */ + void* value; /*!< Pointer to context metadata value itself */ +} __itt_context_metadata; + +#pragma pack(pop) +/** @endcond */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_counter_metadata +{ + __itt_counter counter; /*!< Associated context metadata counter */ + __itt_context_type type; /*!< Type of the context metadata value */ + const char* str_valueA; /*!< String context metadata value */ +#if defined(UNICODE) || defined(_UNICODE) + const wchar_t* str_valueW; +#else /* UNICODE || _UNICODE */ + void* str_valueW; +#endif /* UNICODE || _UNICODE */ + unsigned long long value; /*!< Numeric context metadata value */ + int extra1; /*!< Reserved to the runtime */ + void* extra2; /*!< Reserved to the runtime */ + struct ___itt_counter_metadata* next; +} __itt_counter_metadata; + +#pragma pack(pop) +/** @endcond */ + +/** + * @brief Bind context metadata to counter instance + * @param[in] counter Pointer to the counter instance to which the context metadata is to be associated. + * @param[in] length The number of elements in context metadata array. + * @param[in] metadata The context metadata itself. +*/ +void ITTAPI __itt_bind_context_metadata_to_counter(__itt_counter counter, size_t length, __itt_context_metadata* metadata); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, bind_context_metadata_to_counter, (__itt_counter counter, size_t length, __itt_context_metadata* metadata)) +#define __itt_bind_context_metadata_to_counter ITTNOTIFY_VOID(bind_context_metadata_to_counter) +#define __itt_bind_context_metadata_to_counter_ptr ITTNOTIFY_NAME(bind_context_metadata_to_counter) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_bind_context_metadata_to_counter(counter, length, metadata) +#define __itt_bind_context_metadata_to_counter_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_bind_context_metadata_to_counter_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ITTNOTIFY_H_ */ + +#ifdef INTEL_ITTNOTIFY_API_PRIVATE + +#ifndef _ITTNOTIFY_PRIVATE_ +#define _ITTNOTIFY_PRIVATE_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @ingroup clockdomain + * @brief Begin an overlapped task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] taskid The identifier for this task instance, *cannot* be __itt_null. + * @param[in] parentid The parent of this task, or __itt_null. + * @param[in] name The name of this task. + */ +void ITTAPI __itt_task_begin_overlapped_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, __itt_string_handle* name); + +/** + * @ingroup clockdomain + * @brief End an overlapped task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] taskid Explicit ID of finished task + */ +void ITTAPI __itt_task_end_overlapped_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, task_begin_overlapped_ex, (const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, __itt_string_handle* name)) +ITT_STUBV(ITTAPI, void, task_end_overlapped_ex, (const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid)) +#define __itt_task_begin_overlapped_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(task_begin_overlapped_ex,d,x,y,z,a,b) +#define __itt_task_begin_overlapped_ex_ptr ITTNOTIFY_NAME(task_begin_overlapped_ex) +#define __itt_task_end_overlapped_ex(d,x,y,z) ITTNOTIFY_VOID_D3(task_end_overlapped_ex,d,x,y,z) +#define __itt_task_end_overlapped_ex_ptr ITTNOTIFY_NAME(task_end_overlapped_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_task_begin_overlapped_ex(domain,clock_domain,timestamp,taskid,parentid,name) +#define __itt_task_begin_overlapped_ex_ptr 0 +#define __itt_task_end_overlapped_ex(domain,clock_domain,timestamp,taskid) +#define __itt_task_end_overlapped_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_task_begin_overlapped_ex_ptr 0 +#define __itt_task_end_overlapped_ptr 0 +#define __itt_task_end_overlapped_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @defgroup makrs_internal Marks + * @ingroup internal + * Marks group + * @warning Internal API: + * - It is not shipped to outside of Intel + * - It is delivered to internal Intel teams using e-mail or SVN access only + * @{ + */ +/** @brief user mark type */ +typedef int __itt_mark_type; + +/** + * @brief Creates a user mark type with the specified name using char or Unicode string. + * @param[in] name - name of mark to create + * @return Returns a handle to the mark type + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_mark_type ITTAPI __itt_mark_createA(const char *name); +__itt_mark_type ITTAPI __itt_mark_createW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_mark_create __itt_mark_createW +# define __itt_mark_create_ptr __itt_mark_createW_ptr +#else /* UNICODE */ +# define __itt_mark_create __itt_mark_createA +# define __itt_mark_create_ptr __itt_mark_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_mark_type ITTAPI __itt_mark_create(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_mark_type, mark_createA, (const char *name)) +ITT_STUB(ITTAPI, __itt_mark_type, mark_createW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_mark_type, mark_create, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_createA ITTNOTIFY_DATA(mark_createA) +#define __itt_mark_createA_ptr ITTNOTIFY_NAME(mark_createA) +#define __itt_mark_createW ITTNOTIFY_DATA(mark_createW) +#define __itt_mark_createW_ptr ITTNOTIFY_NAME(mark_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_create ITTNOTIFY_DATA(mark_create) +#define __itt_mark_create_ptr ITTNOTIFY_NAME(mark_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_createA(name) (__itt_mark_type)0 +#define __itt_mark_createA_ptr 0 +#define __itt_mark_createW(name) (__itt_mark_type)0 +#define __itt_mark_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_create(name) (__itt_mark_type)0 +#define __itt_mark_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_createA_ptr 0 +#define __itt_mark_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Creates a "discrete" user mark type of the specified type and an optional parameter using char or Unicode string. + * + * - The mark of "discrete" type is placed to collection results in case of success. It appears in overtime view(s) as a special tick sign. + * - The call is "synchronous" - function returns after mark is actually added to results. + * - This function is useful, for example, to mark different phases of application + * (beginning of the next mark automatically meand end of current region). + * - Can be used together with "continuous" marks (see below) at the same collection session + * @param[in] mt - mark, created by __itt_mark_create(const char* name) function + * @param[in] parameter - string parameter of mark + * @return Returns zero value in case of success, non-zero value otherwise. + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int ITTAPI __itt_markA(__itt_mark_type mt, const char *parameter); +int ITTAPI __itt_markW(__itt_mark_type mt, const wchar_t *parameter); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_mark __itt_markW +# define __itt_mark_ptr __itt_markW_ptr +#else /* UNICODE */ +# define __itt_mark __itt_markA +# define __itt_mark_ptr __itt_markA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int ITTAPI __itt_mark(__itt_mark_type mt, const char *parameter); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, int, markA, (__itt_mark_type mt, const char *parameter)) +ITT_STUB(ITTAPI, int, markW, (__itt_mark_type mt, const wchar_t *parameter)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, mark, (__itt_mark_type mt, const char *parameter)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_markA ITTNOTIFY_DATA(markA) +#define __itt_markA_ptr ITTNOTIFY_NAME(markA) +#define __itt_markW ITTNOTIFY_DATA(markW) +#define __itt_markW_ptr ITTNOTIFY_NAME(markW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark ITTNOTIFY_DATA(mark) +#define __itt_mark_ptr ITTNOTIFY_NAME(mark) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_markA(mt, parameter) (int)0 +#define __itt_markA_ptr 0 +#define __itt_markW(mt, parameter) (int)0 +#define __itt_markW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark(mt, parameter) (int)0 +#define __itt_mark_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_markA_ptr 0 +#define __itt_markW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Use this if necessary to create a "discrete" user event type (mark) for process + * rather then for one thread + * @see int __itt_mark(__itt_mark_type mt, const char* parameter); + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int ITTAPI __itt_mark_globalA(__itt_mark_type mt, const char *parameter); +int ITTAPI __itt_mark_globalW(__itt_mark_type mt, const wchar_t *parameter); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_mark_global __itt_mark_globalW +# define __itt_mark_global_ptr __itt_mark_globalW_ptr +#else /* UNICODE */ +# define __itt_mark_global __itt_mark_globalA +# define __itt_mark_global_ptr __itt_mark_globalA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int ITTAPI __itt_mark_global(__itt_mark_type mt, const char *parameter); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, int, mark_globalA, (__itt_mark_type mt, const char *parameter)) +ITT_STUB(ITTAPI, int, mark_globalW, (__itt_mark_type mt, const wchar_t *parameter)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, mark_global, (__itt_mark_type mt, const char *parameter)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_globalA ITTNOTIFY_DATA(mark_globalA) +#define __itt_mark_globalA_ptr ITTNOTIFY_NAME(mark_globalA) +#define __itt_mark_globalW ITTNOTIFY_DATA(mark_globalW) +#define __itt_mark_globalW_ptr ITTNOTIFY_NAME(mark_globalW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_global ITTNOTIFY_DATA(mark_global) +#define __itt_mark_global_ptr ITTNOTIFY_NAME(mark_global) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_globalA(mt, parameter) (int)0 +#define __itt_mark_globalA_ptr 0 +#define __itt_mark_globalW(mt, parameter) (int)0 +#define __itt_mark_globalW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_global(mt, parameter) (int)0 +#define __itt_mark_global_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_globalA_ptr 0 +#define __itt_mark_globalW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_global_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Creates an "end" point for "continuous" mark with specified name. + * + * - Returns zero value in case of success, non-zero value otherwise. + * Also returns non-zero value when preceding "begin" point for the + * mark with the same name failed to be created or not created. + * - The mark of "continuous" type is placed to collection results in + * case of success. It appears in overtime view(s) as a special tick + * sign (different from "discrete" mark) together with line from + * corresponding "begin" mark to "end" mark. + * @note Continuous marks can overlap and be nested inside each other. + * Discrete mark can be nested inside marked region + * @param[in] mt - mark, created by __itt_mark_create(const char* name) function + * @return Returns zero value in case of success, non-zero value otherwise. + */ +int ITTAPI __itt_mark_off(__itt_mark_type mt); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, int, mark_off, (__itt_mark_type mt)) +#define __itt_mark_off ITTNOTIFY_DATA(mark_off) +#define __itt_mark_off_ptr ITTNOTIFY_NAME(mark_off) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_mark_off(mt) (int)0 +#define __itt_mark_off_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_mark_off_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Use this if necessary to create an "end" point for mark of process + * @see int __itt_mark_off(__itt_mark_type mt); + */ +int ITTAPI __itt_mark_global_off(__itt_mark_type mt); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, int, mark_global_off, (__itt_mark_type mt)) +#define __itt_mark_global_off ITTNOTIFY_DATA(mark_global_off) +#define __itt_mark_global_off_ptr ITTNOTIFY_NAME(mark_global_off) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_mark_global_off(mt) (int)0 +#define __itt_mark_global_off_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_mark_global_off_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} marks group */ + +/** + * @defgroup counters_internal Counters + * @ingroup internal + * Counters group + * @{ + */ + + +/** + * @defgroup stitch Stack Stitching + * @ingroup internal + * Stack Stitching group + * @{ + */ +/** + * @brief opaque structure for counter identification + */ +typedef struct ___itt_caller *__itt_caller; + +/** + * @brief Create the stitch point e.g. a point in call stack where other stacks should be stitched to. + * The function returns a unique identifier which is used to match the cut points with corresponding stitch points. + */ +__itt_caller ITTAPI __itt_stack_caller_create(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_caller, stack_caller_create, (void)) +#define __itt_stack_caller_create ITTNOTIFY_DATA(stack_caller_create) +#define __itt_stack_caller_create_ptr ITTNOTIFY_NAME(stack_caller_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_stack_caller_create() (__itt_caller)0 +#define __itt_stack_caller_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_stack_caller_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Destroy the information about stitch point identified by the pointer previously returned by __itt_stack_caller_create() + */ +void ITTAPI __itt_stack_caller_destroy(__itt_caller id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, stack_caller_destroy, (__itt_caller id)) +#define __itt_stack_caller_destroy ITTNOTIFY_VOID(stack_caller_destroy) +#define __itt_stack_caller_destroy_ptr ITTNOTIFY_NAME(stack_caller_destroy) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_stack_caller_destroy(id) +#define __itt_stack_caller_destroy_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_stack_caller_destroy_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Sets the cut point. Stack from each event which occurs after this call will be cut + * at the same stack level the function was called and stitched to the corresponding stitch point. + */ +void ITTAPI __itt_stack_callee_enter(__itt_caller id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, stack_callee_enter, (__itt_caller id)) +#define __itt_stack_callee_enter ITTNOTIFY_VOID(stack_callee_enter) +#define __itt_stack_callee_enter_ptr ITTNOTIFY_NAME(stack_callee_enter) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_stack_callee_enter(id) +#define __itt_stack_callee_enter_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_stack_callee_enter_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief This function eliminates the cut point which was set by latest __itt_stack_callee_enter(). + */ +void ITTAPI __itt_stack_callee_leave(__itt_caller id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, stack_callee_leave, (__itt_caller id)) +#define __itt_stack_callee_leave ITTNOTIFY_VOID(stack_callee_leave) +#define __itt_stack_callee_leave_ptr ITTNOTIFY_NAME(stack_callee_leave) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_stack_callee_leave(id) +#define __itt_stack_callee_leave_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_stack_callee_leave_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @} stitch group */ + +/* ***************************************************************************************************************************** */ + +#include + +/** @cond exclude_from_documentation */ +typedef enum __itt_error_code +{ + __itt_error_success = 0, /*!< no error */ + __itt_error_no_module = 1, /*!< module can't be loaded */ + /* %1$s -- library name; win: %2$d -- system error code; unx: %2$s -- system error message. */ + __itt_error_no_symbol = 2, /*!< symbol not found */ + /* %1$s -- library name, %2$s -- symbol name. */ + __itt_error_unknown_group = 3, /*!< unknown group specified */ + /* %1$s -- env var name, %2$s -- group name. */ + __itt_error_cant_read_env = 4, /*!< GetEnvironmentVariable() failed */ + /* %1$s -- env var name, %2$d -- system error. */ + __itt_error_env_too_long = 5, /*!< variable value too long */ + /* %1$s -- env var name, %2$d -- actual length of the var, %3$d -- max allowed length. */ + __itt_error_system = 6 /*!< pthread_mutexattr_init or pthread_mutex_init failed */ + /* %1$s -- function name, %2$d -- errno. */ +} __itt_error_code; + +typedef void (__itt_error_handler_t)(__itt_error_code code, va_list); +__itt_error_handler_t* __itt_set_error_handler(__itt_error_handler_t*); + +const char* ITTAPI __itt_api_version(void); +/** @endcond */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#define __itt_error_handler ITT_JOIN(INTEL_ITTNOTIFY_PREFIX, error_handler) +void __itt_error_handler(__itt_error_code code, va_list args); +extern const int ITTNOTIFY_NAME(err); +#define __itt_err ITTNOTIFY_NAME(err) +ITT_STUB(ITTAPI, const char*, api_version, (void)) +#define __itt_api_version ITTNOTIFY_DATA(api_version) +#define __itt_api_version_ptr ITTNOTIFY_NAME(api_version) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_api_version() (const char*)0 +#define __itt_api_version_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_api_version_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ITTNOTIFY_PRIVATE_ */ + +#endif /* INTEL_ITTNOTIFY_API_PRIVATE */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/jitprofiling.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/jitprofiling.h new file mode 100644 index 0000000000000000000000000000000000000000..a2c68e032008c6a43dff11ae2ce2027b9bdbb4fb --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/jitprofiling.h @@ -0,0 +1,647 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + Copyright (C) 2005-2019 Intel Corporation + + SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause +*/ + +#ifndef __JITPROFILING_H__ +#define __JITPROFILING_H__ + +/** + * @brief JIT Profiling APIs + * + * The JIT Profiling API is used to report information about just-in-time + * generated code that can be used by performance tools. The user inserts + * calls in the code generator to report information before JIT-compiled + * code goes to execution. This information is collected at runtime and used + * by tools like Intel(R) VTune(TM) Profiler to display performance metrics + * associated with JIT-compiled code. + * + * These APIs can be used to\n + * - **Profile trace-based and method-based JIT-compiled + * code**. Some examples of environments that you can profile with these APIs: + * dynamic JIT compilation of JavaScript code traces, JIT execution in OpenCL(TM) + * software technology, Java/.NET managed execution environments, and custom + * ISV JIT engines. + * @code + * #include + * + * if (iJIT_IsProfilingActive != iJIT_SAMPLING_ON) { + * return; + * } + * + * iJIT_Method_Load jmethod = {0}; + * jmethod.method_id = iJIT_GetNewMethodID(); + * jmethod.method_name = "method_name"; + * jmethod.class_file_name = "class_name"; + * jmethod.source_file_name = "source_file_name"; + * jmethod.method_load_address = code_addr; + * jmethod.method_size = code_size; + * + * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod); + * iJIT_NotifyEvent(iJVM_EVENT_TYPE_SHUTDOWN, NULL); + * @endcode + * + * * Expected behavior: + * * If any iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event overwrites an + * already reported method, then such a method becomes invalid and its + * memory region is treated as unloaded. VTune Profiler displays the metrics + * collected by the method until it is overwritten. + * * If supplied line number information contains multiple source lines for + * the same assembly instruction (code location), then VTune Profiler picks up + * the first line number. + * * Dynamically generated code can be associated with a module name. + * Use the iJIT_Method_Load_V2 structure.\n + * Clarification of some cases: + * * If you register a function with the same method ID multiple times, + * specifying different module names, then the VTune Profiler picks up + * the module name registered first. If you want to distinguish the same + * function between different JIT engines, supply different method IDs for + * each function. Other symbolic information (for example, source file) + * can be identical. + * + * - **Analyze split functions** (multiple joint or disjoint code regions + * belonging to the same function) **including re-JIT** + * with potential overlapping of code regions in time, which is common in + * resource-limited environments. + * @code + * #include + * + * unsigned int method_id = iJIT_GetNewMethodID(); + * + * iJIT_Method_Load a = {0}; + * a.method_id = method_id; + * a.method_load_address = 0x100; + * a.method_size = 0x20; + * + * iJIT_Method_Load b = {0}; + * b.method_id = method_id; + * b.method_load_address = 0x200; + * b.method_size = 0x30; + * + * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&a); + * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&b); + * @endcode + * + * * Expected behaviour: + * * If a iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event overwrites an + * already reported method, then such a method becomes invalid and + * its memory region is treated as unloaded. + * * All code regions reported with the same method ID are considered as + * belonging to the same method. Symbolic information (method name, + * source file name) will be taken from the first notification, and all + * subsequent notifications with the same method ID will be processed + * only for line number table information. So, the VTune Profiler will map + * samples to a source line using the line number table from the current + * notification while taking the source file name from the very first one.\n + * Clarification of some cases:\n + * * If you register a second code region with a different source file + * name and the same method ID, then this information will be saved and + * will not be considered as an extension of the first code region, but + * VTune Profiler will use the source file of the first code region and map + * performance metrics incorrectly. + * * If you register a second code region with the same source file as + * for the first region and the same method ID, then the source file will be + * discarded but VTune Profiler will map metrics to the source file correctly. + * * If you register a second code region with a null source file and + * the same method ID, then provided line number info will be associated + * with the source file of the first code region. + * + * - **Explore inline functions** including multi-level hierarchy of + * nested inline methods which shows how performance metrics are distributed through them. + * @code + * #include + * + * // method_id parent_id + * // [-- c --] 3000 2000 + * // [---- d -----] 2001 1000 + * // [---- b ----] 2000 1000 + * // [------------ a ----------------] 1000 n/a + * + * iJIT_Method_Load a = {0}; + * a.method_id = 1000; + * + * iJIT_Method_Inline_Load b = {0}; + * b.method_id = 2000; + * b.parent_method_id = 1000; + * + * iJIT_Method_Inline_Load c = {0}; + * c.method_id = 3000; + * c.parent_method_id = 2000; + * + * iJIT_Method_Inline_Load d = {0}; + * d.method_id = 2001; + * d.parent_method_id = 1000; + * + * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&a); + * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&b); + * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&c); + * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&d); + * @endcode + * + * * Requirements: + * * Each inline (iJIT_Method_Inline_Load) method should be associated + * with two method IDs: one for itself; one for its immediate parent. + * * Address regions of inline methods of the same parent method cannot + * overlap each other. + * * Execution of the parent method must not be started until it and all + * its inline methods are reported. + * * Expected behaviour: + * * In case of nested inline methods an order of + * iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED events is not important. + * * If any event overwrites either inline method or top parent method, + * then the parent, including inline methods, becomes invalid and its memory + * region is treated as unloaded. + * + * **Life time of allocated data**\n + * The client sends an event notification to the agent with event-specific + * data, which is a structure. The pointers in the structure refer to memory + * allocated by the client, which responsible for releasing it. The pointers are + * used by the iJIT_NotifyEvent method to copy client's data in a trace file, + * and they are not used after the iJIT_NotifyEvent method returns. + */ + +/** + * @defgroup jitapi JIT Profiling + * @ingroup internal + * @{ + */ + +/** + * @brief Enumerator for the types of notifications + */ +typedef enum iJIT_jvm_event +{ + iJVM_EVENT_TYPE_SHUTDOWN = 2, /**<\brief Send this to shutdown the agent. + * Use NULL for event data. */ + + iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED = 13, /**<\brief Send when dynamic code is + * JIT compiled and loaded into + * memory by the JIT engine, but + * before the code is executed. + * Use iJIT_Method_Load as event + * data. */ +/** @cond exclude_from_documentation */ + iJVM_EVENT_TYPE_METHOD_UNLOAD_START, /**<\brief Send when compiled dynamic + * code is being unloaded from memory. + * Use iJIT_Method_Load as event data.*/ +/** @endcond */ + + iJVM_EVENT_TYPE_METHOD_UPDATE, /**<\brief Send to provide new content for + * a previously reported dynamic code. + * The previous content will be invalidated + * starting from the time of the notification. + * Use iJIT_Method_Load as event data but + * required fields are following: + * - method_id identify the code to update. + * - method_load_address specify start address + * within identified code range + * where update should be started. + * - method_size specify length of updated code + * range. */ + + + iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, /**<\brief Send when an inline dynamic + * code is JIT compiled and loaded + * into memory by the JIT engine, + * but before the parent code region + * starts executing. + * Use iJIT_Method_Inline_Load as event data.*/ + +/** @cond exclude_from_documentation */ + iJVM_EVENT_TYPE_METHOD_UPDATE_V2, +/** @endcond */ + + iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2 = 21, /**<\brief Send when a dynamic code is + * JIT compiled and loaded into + * memory by the JIT engine, but + * before the code is executed. + * Use iJIT_Method_Load_V2 as event data. */ + + iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V3 /**<\brief Send when a dynamic code is + * JIT compiled and loaded into + * memory by the JIT engine, but + * before the code is executed. + * Use iJIT_Method_Load_V3 as event data. */ +} iJIT_JVM_EVENT; + +/** + * @brief Enumerator for the agent's mode + */ +typedef enum _iJIT_IsProfilingActiveFlags +{ + iJIT_NOTHING_RUNNING = 0x0000, /**<\brief The agent is not running; + * iJIT_NotifyEvent calls will + * not be processed. */ + iJIT_SAMPLING_ON = 0x0001, /**<\brief The agent is running and + * ready to process notifications. */ +} iJIT_IsProfilingActiveFlags; + +/** + * @brief Description of a single entry in the line number information of a code region. + * @details A table of line number entries gives information about how the reported code region + * is mapped to source file. + * Intel(R) VTune(TM) Profiler uses line number information to attribute + * the samples (virtual address) to a line number. \n + * It is acceptable to report different code addresses for the same source line: + * @code + * Offset LineNumber + * 1 2 + * 12 4 + * 15 2 + * 18 1 + * 21 30 + * + * VTune Profiler constructs the following table using the client data + * + * Code subrange Line number + * 0-1 2 + * 1-12 4 + * 12-15 2 + * 15-18 1 + * 18-21 30 + * @endcode + */ +typedef struct _LineNumberInfo +{ + unsigned int Offset; /**<\brief Offset from the begining of the code region. */ + unsigned int LineNumber; /**<\brief Matching source line number offset (from beginning of source file). */ + +} *pLineNumberInfo, LineNumberInfo; + +/** + * @brief Enumerator for the code architecture. + */ +typedef enum _iJIT_CodeArchitecture +{ + iJIT_CA_NATIVE = 0, /**<\brief Native to the process architecture that is calling it. */ + + iJIT_CA_32, /**<\brief 32-bit machine code. */ + + iJIT_CA_64 /**<\brief 64-bit machine code. */ + +} iJIT_CodeArchitecture; + +#pragma pack(push, 8) + +/** + * @brief Description of a JIT-compiled method + * @details When you use the iJIT_Method_Load structure to describe + * the JIT compiled method, use iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED + * as an event type to report it. + */ +typedef struct _iJIT_Method_Load +{ + unsigned int method_id; /**<\brief Unique method ID. Cannot be 0. + * You must either use the API function + * iJIT_GetNewMethodID to get a valid and unique + * method ID, or else manage ID uniqueness + * and correct range by yourself.\n + * You must use the same method ID for all code + * regions of the same method, otherwise different + * method IDs specify different methods. */ + + char* method_name; /**<\brief The name of the method. It can be optionally + * prefixed with its class name and appended with + * its complete signature. Can't be NULL. */ + + void* method_load_address; /**<\brief The start virtual address of the method code + * region. If NULL, data provided with + * event are not accepted. */ + + unsigned int method_size; /**<\brief The code size of the method in memory. + * If 0, then data provided with the event are not + * accepted. */ + + unsigned int line_number_size; /**<\brief The number of entries in the line number + * table.0 if none. */ + + pLineNumberInfo line_number_table; /**<\brief Pointer to the line numbers info + * array. Can be NULL if + * line_number_size is 0. See + * LineNumberInfo Structure for a + * description of a single entry in + * the line number info array */ + + unsigned int class_id; /**<\brief This field is obsolete. */ + + char* class_file_name; /**<\brief Class name. Can be NULL.*/ + + char* source_file_name; /**<\brief Source file name. Can be NULL.*/ + +} *piJIT_Method_Load, iJIT_Method_Load; + +/** + * @brief Description of a JIT-compiled method + * @details When you use the iJIT_Method_Load_V2 structure to describe + * the JIT compiled method, use iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2 + * as an event type to report it. + */ +typedef struct _iJIT_Method_Load_V2 +{ + unsigned int method_id; /**<\brief Unique method ID. Cannot be 0. + * You must either use the API function + * iJIT_GetNewMethodID to get a valid and unique + * method ID, or else manage ID uniqueness + * and correct range by yourself.\n + * You must use the same method ID for all code + * regions of the same method, otherwise different + * method IDs specify different methods. */ + + char* method_name; /**<\brief The name of the method. It can be optionally + * prefixed with its class name and appended with + * its complete signature. Can't be NULL. */ + + void* method_load_address; /**<\brief The start virtual address of the method code + * region. If NULL, then data provided with the + * event are not accepted. */ + + unsigned int method_size; /**<\brief The code size of the method in memory. + * If 0, then data provided with the event are not + * accepted. */ + + unsigned int line_number_size; /**<\brief The number of entries in the line number + * table. 0 if none. */ + + pLineNumberInfo line_number_table; /**<\brief Pointer to the line numbers info + * array. Can be NULL if + * line_number_size is 0. See + * LineNumberInfo Structure for a + * description of a single entry in + * the line number info array. */ + + char* class_file_name; /**<\brief Class name. Can be NULL. */ + + char* source_file_name; /**<\brief Source file name. Can be NULL. */ + + char* module_name; /**<\brief Module name. Can be NULL. + The module name can be useful for distinguishing among + different JIT engines. VTune Profiler will display + reported methods grouped by specific module. */ + +} *piJIT_Method_Load_V2, iJIT_Method_Load_V2; + +/** + * @brief Description of a JIT-compiled method + * @details The iJIT_Method_Load_V3 structure is the same as iJIT_Method_Load_V2 + * with a newly introduced 'arch' field that specifies architecture of the code region. + * When you use the iJIT_Method_Load_V3 structure to describe + * the JIT compiled method, use iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V3 + * as an event type to report it. + */ +typedef struct _iJIT_Method_Load_V3 +{ + unsigned int method_id; /**<\brief Unique method ID. Cannot be 0. + * You must either use the API function + * iJIT_GetNewMethodID to get a valid and unique + * method ID, or manage ID uniqueness + * and correct range by yourself.\n + * You must use the same method ID for all code + * regions of the same method, otherwise they are + * treated as regions of different methods. */ + + char* method_name; /**<\brief The name of the method. It can be optionally + * prefixed with its class name and appended with + * its complete signature. Cannot be NULL. */ + + void* method_load_address; /**<\brief The start virtual address of the method code + * region. If NULL, then data provided with the + * event are not accepted. */ + + unsigned int method_size; /**<\brief The code size of the method in memory. + * If 0, then data provided with the event are not + * accepted. */ + + unsigned int line_number_size; /**<\brief The number of entries in the line number + * table. 0 if none. */ + + pLineNumberInfo line_number_table; /**<\brief Pointer to the line numbers info + * array. Can be NULL if + * line_number_size is 0. See + * LineNumberInfo Structure for a + * description of a single entry in + * the line number info array. */ + + char* class_file_name; /**<\brief Class name. Can be NULL. */ + + char* source_file_name; /**<\brief Source file name. Can be NULL. */ + + char* module_name; /**<\brief Module name. Can be NULL. + * The module name can be useful for distinguishing among + * different JIT engines. VTune Profiler will display + * reported methods grouped by specific module. */ + + iJIT_CodeArchitecture module_arch; /**<\brief Architecture of the method's code region. + * By default, it is the same as the process + * architecture that is calling it. + * For example, you can use it if your 32-bit JIT + * engine generates 64-bit code. + * + * If JIT engine reports both 32-bit and 64-bit types + * of methods then VTune Profiler splits the methods + * with the same module name but with different + * architectures in two different modules. VTune Profiler + * modifies the original name provided with a 64-bit method + * version by ending it with '(64)' */ + +} *piJIT_Method_Load_V3, iJIT_Method_Load_V3; + +/** + * @brief Description of an inline JIT-compiled method + * @details When you use the_iJIT_Method_Inline_Load structure to describe + * the JIT compiled method, use iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED + * as an event type to report it. + */ +typedef struct _iJIT_Method_Inline_Load +{ + unsigned int method_id; /**<\brief Unique method ID. Cannot be 0. + * You must either use the API function + * iJIT_GetNewMethodID to get a valid and unique + * method ID, or else manage ID uniqueness + * and correct range by yourself. */ + + unsigned int parent_method_id; /**<\brief Unique immediate parent's method ID. + * Cannot be 0. + * You must either use the API function + * iJIT_GetNewMethodID to get a valid and unique + * method ID, or else manage ID uniqueness + * and correct range by yourself. */ + + char* method_name; /**<\brief The name of the method. It can be optionally + * prefixed with its class name and appended with + * its complete signature. Can't be NULL. */ + + void* method_load_address; /** <\brief The virtual address on which the method + * is inlined. If NULL, then data provided with + * the event are not accepted. */ + + unsigned int method_size; /**<\brief The code size of the method in memory. + * If 0, then data provided with the event are not + * accepted. */ + + unsigned int line_number_size; /**<\brief The number of entries in the line number + * table. 0 if none. */ + + pLineNumberInfo line_number_table; /**<\brief Pointer to the line numbers info + * array. Can be NULL if + * line_number_size is 0. See + * LineNumberInfo Structure for a + * description of a single entry in + * the line number info array */ + + char* class_file_name; /**<\brief Class name. Can be NULL.*/ + + char* source_file_name; /**<\brief Source file name. Can be NULL.*/ + +} *piJIT_Method_Inline_Load, iJIT_Method_Inline_Load; + +/** @cond exclude_from_documentation */ +/** + * @brief Description of a segment type + * @details Use the segment type to specify a type of data supplied + * with the iJVM_EVENT_TYPE_METHOD_UPDATE_V2 event to be applied to + * a certain code trace. + */ +typedef enum _iJIT_SegmentType +{ + iJIT_CT_UNKNOWN = 0, + + iJIT_CT_CODE, /**<\brief Executable code. */ + + iJIT_CT_DATA, /**<\brief Data (not executable code). + * VTune Profiler uses the format string + * (see iJIT_Method_Update) to represent + * this data in the VTune Profiler GUI */ + + iJIT_CT_KEEP, /**<\brief Use the previous markup for the trace. + * Can be used for the following + * iJVM_EVENT_TYPE_METHOD_UPDATE_V2 events, + * if the type of the previously reported segment + * type is the same. */ + iJIT_CT_EOF +} iJIT_SegmentType; + +/** + * @brief Description of a dynamic update of the content within JIT-compiled method + * @details The JIT engine may generate the methods that are updated at runtime + * partially by mixed (data + executable code) content. When you use the iJIT_Method_Update + * structure to describe the update of the content within a JIT-compiled method, + * use iJVM_EVENT_TYPE_METHOD_UPDATE_V2 as an event type to report it. + * + * On the first Update event, VTune Profiler copies the original code range reported by + * the iJVM_EVENT_TYPE_METHOD_LOAD event, then modifies it with the supplied bytes and + * adds the modified range to the original method. For next update events, VTune Profiler + * does the same but it uses the latest modified version of a code region for update. + * Eventually, VTune Profiler GUI displays multiple code ranges for the method reported by + * the iJVM_EVENT_TYPE_METHOD_LOAD event. + * Notes: + * - Multiple update events with different types for the same trace are allowed + * but they must be reported for the same code ranges. + * Example, + * @code + * [-- data---] Allowed + * [-- code --] Allowed + * [code] Ignored + * [-- data---] Allowed + * [-- code --] Allowed + * [------------ trace ---------] + * @endcode + * - The types of previously reported events can be changed but they must be reported + * for the same code ranges. + * Example, + * @code + * [-- data---] Allowed + * [-- code --] Allowed + * [-- data---] Allowed + * [-- code --] Allowed + * [------------ trace ---------] + * @endcode + */ + +typedef struct _iJIT_Method_Update +{ + void* load_address; /**<\brief Start address of the update within a method */ + + unsigned int size; /**<\brief The update size */ + + iJIT_SegmentType type; /**<\brief Type of the update */ + + const char* data_format; /**<\brief C string that contains a format string + * that follows the same specifications as format in printf. + * The format string is used for iJIT_CT_CODE only + * and cannot be NULL. + * Format can be changed on the fly. */ +} *piJIT_Method_Update, iJIT_Method_Update; + +/** @endcond */ + +#pragma pack(pop) + +/** @cond exclude_from_documentation */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef JITAPI_CDECL +# if defined WIN32 || defined _WIN32 +# define JITAPI_CDECL __cdecl +# else /* defined WIN32 || defined _WIN32 */ +# if defined _M_IX86 || defined __i386__ +# define JITAPI_CDECL __attribute__ ((cdecl)) +# else /* _M_IX86 || __i386__ */ +# define JITAPI_CDECL /* actual only on x86_64 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* defined WIN32 || defined _WIN32 */ +#endif /* JITAPI_CDECL */ + +#define JITAPI JITAPI_CDECL +/** @endcond */ + +/** + * @brief Generates a new unique method ID. + * + * You must use this API to obtain unique and valid method IDs for methods or + * traces reported to the agent if you don't have your own mechanism to generate + * unique method IDs. + * + * @return a new unique method ID. When out of unique method IDs, this API + * returns 0, which is not an accepted value. + */ +unsigned int JITAPI iJIT_GetNewMethodID(void); + +/** + * @brief Returns the current mode of the agent. + * + * @return iJIT_SAMPLING_ON, indicating that agent is running, or + * iJIT_NOTHING_RUNNING if no agent is running. + */ +iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive(void); + +/** + * @brief Reports infomation about JIT-compiled code to the agent. + * + * The reported information is used to attribute samples obtained from any + * Intel(R) VTune(TM) Profiler collector. This API needs to be called + * after JIT compilation and before the first entry into the JIT-compiled + * code. + * + * @param[in] event_type - type of the data sent to the agent + * @param[in] EventSpecificData - pointer to event-specific data + * + * @returns 1 on success, otherwise 0. + */ +int JITAPI iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +/** @endcond */ + +/** @} jitapi group */ + +#endif /* __JITPROFILING_H__ */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/AbstractConfig.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/AbstractConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..a7381cd242558ffaf5a0fa58f5a94bf43a421191 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/AbstractConfig.h @@ -0,0 +1,126 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace libkineto { + +class AbstractConfig { + public: + AbstractConfig& operator=(const AbstractConfig&) = delete; + AbstractConfig(AbstractConfig&&) = delete; + AbstractConfig& operator=(AbstractConfig&&) = delete; + + virtual ~AbstractConfig() { + for (const auto& p : featureConfigs_) { + delete p.second; + } + } + + // Return a copy of the full derived class + virtual AbstractConfig* cloneDerived(AbstractConfig& parent) const = 0; + + // Returns true if successfully parsed the config string + bool parse(const std::string& conf); + + // Default setup for signal-triggered profiling + virtual void setSignalDefaults() { + for (auto& p : featureConfigs_) { + p.second->setSignalDefaults(); + } + } + + // Default setup for client-triggered profiling + virtual void setClientDefaults() { + for (auto& p : featureConfigs_) { + p.second->setClientDefaults(); + } + } + + // Time config was created / updated + [[nodiscard]] std::chrono::time_point timestamp() const { + return timestamp_; + } + + // Source config string that this was parsed from + [[nodiscard]] const std::string& source() const { + return source_; + } + + [[nodiscard]] AbstractConfig& feature(const std::string& name) const { + const auto& pos = featureConfigs_.find(name); + return *pos->second; + } + + // Transfers ownership of cfg arg + void addFeature(const std::string& name, AbstractConfig* cfg) { + featureConfigs_[name] = cfg; + } + + protected: + AbstractConfig() = default; + AbstractConfig(const AbstractConfig& other) = default; + + // Return true if the option was recognized and successfully parsed. + // Throw std::invalid_argument if val is invalid. + virtual bool handleOption(const std::string& name, std::string& val); + + // Perform post-validation checks, typically conditons involving + // multiple options. + // Throw std::invalid_argument if automatic correction can not be made. + // + // @param fallbackProfileStartTime Specify a fallback profile start timestamp + // in case it was never specified by the client + virtual void validate(const std::chrono::time_point& fallbackProfileStartTime) = 0; + + // TODO: Separate out each profiler type into features? + virtual void printActivityProfilerConfig(std::ostream& s) const; + virtual void setActivityDependentConfig(); + + // Helpers for use in handleOption + // Split a string by delimiter and remove external white space + [[nodiscard]] std::vector splitAndTrim(const std::string& s, char delim) const; + // Lowercase for case-insensitive comparisons + std::string toLower(std::string& s) const; + // Does string end with suffix + [[nodiscard]] bool endsWith(const std::string& s, const std::string& suffix) const; + // Conversions + [[nodiscard]] int64_t toIntRange(const std::string& val, int64_t min, int64_t max) const; + [[nodiscard]] int32_t toInt32(const std::string& val) const; + [[nodiscard]] int64_t toInt64(const std::string& val) const; + bool toBool(std::string& val) const; + + void cloneFeaturesInto(AbstractConfig& cfg) const { + for (const auto& feature : featureConfigs_) { + cfg.featureConfigs_[feature.first] = feature.second->cloneDerived(cfg); + } + } + + private: + // Time config was created / updated + std::chrono::time_point timestamp_; + + // Original configuration string, used for comparison + std::string source_; + + // Configuration objects for optional features + std::map featureConfigs_; +}; + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityProfilerInterface.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityProfilerInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..27a78877205a07d147b2c5f86be9d9afba871dd7 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityProfilerInterface.h @@ -0,0 +1,108 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +#include "ActivityTraceInterface.h" +#include "ActivityType.h" +#include "IActivityProfiler.h" + +namespace libkineto { + +class ActivityProfilerController; +struct CpuTraceBuffer; +class Config; + +class ActivityProfilerInterface { + public: + virtual ~ActivityProfilerInterface() = default; + + virtual void init() {} + virtual bool isInitialized() { + return false; + } + virtual bool isActive() { + return false; + } + + // *** Asynchronous API *** + // Instead of starting and stopping the trace manually, provide a start time + // and duration and / or iteration stop criterion. + // Tracing terminates when either condition is met. + virtual void scheduleTrace([[maybe_unused]] const std::string& configStr) {} + + // *** Synchronous API *** + // These must be called in order: + // prepareTrace -> startTrace -> stopTrace. + + // Many tracing structures are lazily initialized during trace collection, + // with potentially high overhead. + // Call prepareTrace to enable tracing, then run the region to trace + // at least once (and ideally run the same code that is to be traced) to + // allow tracing structures to be initialized. + virtual void prepareTrace([[maybe_unused]] const std::set& activityTypes, + [[maybe_unused]] const std::string& configStr = "") {} + + // Toggle GPU tracing as a trace is running to omit certain parts of a graph + virtual void toggleCollectionDynamic([[maybe_unused]] const bool enable) {} + + // Start recording, potentially reusing any buffers allocated since + // prepareTrace was called. + virtual void startTrace() {} + + // Stop and process trace, producing an in-memory list of trace records. + // The processing will be done synchronously (using the calling thread.) + virtual std::unique_ptr stopTrace() { + return nullptr; + } + + // Re-evaluate internal state to allow for triggering operations based + // on number of iteration. each implicitly increments the iteration count + virtual void step() {} + + // *** TraceActivity API *** + // FIXME: Pass activityProfiler interface into clientInterface? + virtual void pushCorrelationId([[maybe_unused]] uint64_t id) {} + virtual void popCorrelationId() {} + virtual void transferCpuTrace([[maybe_unused]] std::unique_ptr traceBuffer) {} + + // Correlation ids for user defined spans + virtual void pushUserCorrelationId([[maybe_unused]] uint64_t id) {} + virtual void popUserCorrelationId() {} + + // Saves information for the current thread to be used in profiler output + // Client must record any new kernel thread where the activity has occured. + virtual void recordThreadInfo() {} + + // Record trace metadata, currently supporting only string key and values, + // values with the same key are overwritten + virtual void addMetadata(const std::string& key, const std::string& value) = 0; + + // Add a child activity profiler, this enables frameworks in the application + // to enable custom framework events. + virtual void addChildActivityProfiler([[maybe_unused]] std::unique_ptr profiler) {} + + // Log Invariant Violation to factories enabled. This helps record + // instances when the profiler behaves unexpectedly. + virtual void logInvariantViolation([[maybe_unused]] const std::string& profile_id, + [[maybe_unused]] const std::string& assertion, + [[maybe_unused]] const std::string& error, + [[maybe_unused]] const std::string& group_profile_id = "") {} +}; + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityTraceInterface.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityTraceInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..e4c2ca3791a32c737af5762fce0aa652ea848bb0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityTraceInterface.h @@ -0,0 +1,33 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace libkineto { + +struct ITraceActivity; + +class ActivityTraceInterface { + public: + virtual ~ActivityTraceInterface() = default; + virtual const std::vector* activities() { + return nullptr; + } + virtual void save([[maybe_unused]] const std::string& path) {} +}; + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityType.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityType.h new file mode 100644 index 0000000000000000000000000000000000000000..5f38e3a0a05780a2f8a28a58e0175ec3c245f27f --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityType.h @@ -0,0 +1,114 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace libkineto { + +// Note : All activity types are not enabled by default. Please add them +// at correct position in the enum +enum class ActivityType { + // Activity types enabled by default + CPU_OP = 0, // cpu side ops + USER_ANNOTATION = 1, + GPU_USER_ANNOTATION = 2, + GPU_MEMCPY = 3, + GPU_MEMSET = 4, + CONCURRENT_KERNEL = 5, // on-device kernels + EXTERNAL_CORRELATION = 6, + CUDA_RUNTIME = 7, // host side cuda runtime events + CUDA_DRIVER = 8, // host side cuda driver events + CPU_INSTANT_EVENT = 9, // host side point-like events + PYTHON_FUNCTION = 10, + OVERHEAD = 11, // CUPTI induced overhead events sampled from its overhead API. + MTIA_RUNTIME = 12, // host side MTIA runtime events + MTIA_CCP_EVENTS = 13, // MTIA ondevice CCP events + MTIA_INSIGHT = 14, // MTIA Insight Events + CUDA_SYNC = 15, // synchronization events between runtime and kernels + CUDA_EVENT = 16, // CUDA event activities (cudaEventRecord, etc.) + MTIA_COUNTERS = 17, // MTIA hardware counter events (HBM, cache, DPE, SFU) + + // Optional Activity types + GLOW_RUNTIME = 18, // host side glow runtime events + CUDA_PROFILER_RANGE = 19, // CUPTI Profiler range for performance metrics + HPU_OP = 20, // HPU host side runtime event + XPU_RUNTIME = 21, // host side xpu runtime events + XPU_DRIVER = 22, // host side xpu driver events + COLLECTIVE_COMM = 23, // collective communication + + // PRIVATEUSE1 Activity types are used for custom backends. + // The corresponding device type is `DeviceType::PrivateUse1` in PyTorch. + PRIVATEUSE1_RUNTIME = 24, // host side privateUse1 runtime events + PRIVATEUSE1_DRIVER = 25, // host side privateUse1 driver events + + ENUM_COUNT = 26, // This is to add buffer and not used for any profiling logic. Add + // your new type before it. + OPTIONAL_ACTIVITY_TYPE_START = GLOW_RUNTIME, +}; + +// Return an array of all activity types except COUNT +constexpr int activityTypeCount = (int)ActivityType::ENUM_COUNT; +constexpr int defaultActivityTypeCount = (int)ActivityType::OPTIONAL_ACTIVITY_TYPE_START; + +// These definitions are not part of the public Kineto API. They are inlined +// here because some build configurations include this header +// without linking libkineto, and toString() must resolve at compile time. +struct _ActivityTypeName { + const char* name; + ActivityType type; +}; + +inline constexpr std::array<_ActivityTypeName, activityTypeCount + 1> _activityTypeNames{{ + {"cpu_op", ActivityType::CPU_OP}, + {"user_annotation", ActivityType::USER_ANNOTATION}, + {"gpu_user_annotation", ActivityType::GPU_USER_ANNOTATION}, + {"gpu_memcpy", ActivityType::GPU_MEMCPY}, + {"gpu_memset", ActivityType::GPU_MEMSET}, + {"kernel", ActivityType::CONCURRENT_KERNEL}, + {"external_correlation", ActivityType::EXTERNAL_CORRELATION}, + {"cuda_runtime", ActivityType::CUDA_RUNTIME}, + {"cuda_driver", ActivityType::CUDA_DRIVER}, + {"cpu_instant_event", ActivityType::CPU_INSTANT_EVENT}, + {"python_function", ActivityType::PYTHON_FUNCTION}, + {"overhead", ActivityType::OVERHEAD}, + {"mtia_runtime", ActivityType::MTIA_RUNTIME}, + {"mtia_ccp_events", ActivityType::MTIA_CCP_EVENTS}, + {"mtia_insight", ActivityType::MTIA_INSIGHT}, + {"cuda_sync", ActivityType::CUDA_SYNC}, + {"cuda_event", ActivityType::CUDA_EVENT}, + {"mtia_counters", ActivityType::MTIA_COUNTERS}, + {"glow_runtime", ActivityType::GLOW_RUNTIME}, + {"cuda_profiler_range", ActivityType::CUDA_PROFILER_RANGE}, + {"hpu_op", ActivityType::HPU_OP}, + {"xpu_runtime", ActivityType::XPU_RUNTIME}, + {"xpu_driver", ActivityType::XPU_DRIVER}, + {"collective_comm", ActivityType::COLLECTIVE_COMM}, + {"privateuse1_runtime", ActivityType::PRIVATEUSE1_RUNTIME}, + {"privateuse1_driver", ActivityType::PRIVATEUSE1_DRIVER}, + {"ENUM_COUNT", ActivityType::ENUM_COUNT}, +}}; + +inline const char* toString(ActivityType t) { + return _activityTypeNames[static_cast(t)].name; +} + +ActivityType toActivityType(const std::string& str); + +std::array activityTypes(); +std::array defaultActivityTypes(); + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ClientInterface.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ClientInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..eb570e1258c0fedf3e748c1028bc0fb30f3f7aaa --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ClientInterface.h @@ -0,0 +1,31 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +namespace libkineto { + +class ClientInterface { + public: + virtual ~ClientInterface() = default; + virtual void init() = 0; + virtual void prepare(bool, bool, bool, bool, bool) = 0; + virtual void start() = 0; + virtual void stop() = 0; + virtual void start_memory_profile() = 0; + virtual void stop_memory_profile() = 0; + virtual void export_memory_profile(const std::string&) = 0; +}; + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/Config.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/Config.h new file mode 100644 index 0000000000000000000000000000000000000000..fb5e2c445521030bb6ab884548419321cbabce61 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/Config.h @@ -0,0 +1,541 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include "AbstractConfig.h" +#include "ActivityType.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace libkineto { + +class Config : public AbstractConfig { + public: + Config(); + Config& operator=(const Config&) = delete; + Config(Config&&) = delete; + Config& operator=(Config&&) = delete; + ~Config() override = default; + + // Return a full copy including feature config object + [[nodiscard]] std::unique_ptr clone() const { + auto cfg = std::unique_ptr(new Config(*this)); + cloneFeaturesInto(*cfg); + return cfg; + } + + bool handleOption(const std::string& name, std::string& val) override; + + void setClientDefaults() override; + + // Log events to this file + [[nodiscard]] const std::string& eventLogFile() const { + return eventLogFile_; + } + + [[nodiscard]] bool activityProfilerEnabled() const { + return activityProfilerEnabled_ || activitiesOnDemandTimestamp_.time_since_epoch().count() > 0; + } + + // Log activitiy trace to this file + [[nodiscard]] const std::string& activitiesLogFile() const { + return activitiesLogFile_; + } + + // Log activitiy trace to this url + [[nodiscard]] const std::string& activitiesLogUrl() const { + return activitiesLogUrl_; + } + + void setActivitiesLogUrl(const std::string& url) { + activitiesLogUrl_ = url; + } + + [[nodiscard]] bool activitiesLogToMemory() const { + return activitiesLogToMemory_; + } + + [[nodiscard]] bool eventProfilerEnabled() const { + return !eventNames_.empty() || !metricNames_.empty(); + } + + // Is profiling enabled for the given device? + [[nodiscard]] bool eventProfilerEnabledForDevice(uint32_t dev) const { + return 0 != (eventProfilerDeviceMask_ & (1 << dev)); + } + + // Take a sample (read hardware counters) at this frequency. + // This controls how often counters are read - if all counters cannot + // be collected simultaneously then multiple samples are needed to + // collect all requested counters - see multiplex period. + [[nodiscard]] std::chrono::milliseconds samplePeriod() const { + return samplePeriod_; + } + + void setSamplePeriod(std::chrono::milliseconds period) { + samplePeriod_ = period; + } + + // When all requested counters cannot be collected simultaneously, + // counters will be multiplexed at this frequency. + // Multiplexing can have a large performance impact if done frequently. + // To avoid a perf impact, keep this at 1s or above. + [[nodiscard]] std::chrono::milliseconds multiplexPeriod() const { + return multiplexPeriod_; + } + + void setMultiplexPeriod(std::chrono::milliseconds period) { + multiplexPeriod_ = period; + } + + // Report counters at this frequency. Note that several samples can + // be reported each time, see samplesPerReport. + [[nodiscard]] std::chrono::milliseconds reportPeriod() const { + return reportPeriod_; + } + + void setReportPeriod(std::chrono::milliseconds msecs); + + // Number of samples dispatched each report period. + // Must be in the range [1, report period / sample period]. + // In other words, aggregation is supported but not interpolation. + [[nodiscard]] int samplesPerReport() const { + return samplesPerReport_; + } + + void setSamplesPerReport(int count) { + samplesPerReport_ = count; + } + + // The names of events to collect + [[nodiscard]] const std::set& eventNames() const { + return eventNames_; + } + + // Add additional events to be profiled + void addEvents(const std::set& names) { + eventNames_.insert(names.begin(), names.end()); + } + + // The names of metrics to collect + [[nodiscard]] const std::set& metricNames() const { + return metricNames_; + } + + // Add additional metrics to be profiled + void addMetrics(const std::set& names) { + metricNames_.insert(names.begin(), names.end()); + } + + [[nodiscard]] const std::vector& percentiles() const { + return eventReportPercentiles_; + } + + // Profile for this long, then revert to base config + [[nodiscard]] std::chrono::seconds eventProfilerOnDemandDuration() const { + return eventProfilerOnDemandDuration_; + } + + void setEventProfilerOnDemandDuration(std::chrono::seconds duration) { + eventProfilerOnDemandDuration_ = duration; + } + + // Too many event profilers on a single system can overload the driver. + // At some point, latencies shoot through the roof and collection of samples + // becomes impossible. To avoid this situation we have a limit of profilers + // per GPU. + // NOTE: Communication with a daemon is needed for this feature. + // Library must be built with an active DaemonConfigLoader. + [[nodiscard]] int maxEventProfilersPerGpu() const { + return eventProfilerMaxInstancesPerGpu_; + } + + // On Cuda11 we've seen occasional hangs when reprogramming counters + // Monitor profiling threads and report when a thread is not responding + // for a given number of seconds. + // A period of 0 means disable. + [[nodiscard]] std::chrono::seconds eventProfilerHeartbeatMonitorPeriod() const { + return eventProfilerHeartbeatMonitorPeriod_; + } + + // The types of activities selected in the configuration file + [[nodiscard]] const std::set& selectedActivityTypes() const { + return selectedActivityTypes_; + } + + // Set the types of activities to be traced + [[nodiscard]] bool perThreadBufferEnabled() const { + return perThreadBufferEnabled_; + } + + void setSelectedActivityTypes(const std::set& types) { + selectedActivityTypes_ = types; + } + + [[nodiscard]] bool isReportInputShapesEnabled() const { + return enableReportInputShapes_; + } + + [[nodiscard]] bool isProfileMemoryEnabled() const { + return enableProfileMemory_; + } + + [[nodiscard]] bool isWithStackEnabled() const { + return enableWithStack_; + } + + [[nodiscard]] bool isWithFlopsEnabled() const { + return enableWithFlops_; + } + + [[nodiscard]] bool isWithModulesEnabled() const { + return enableWithModules_; + } + + // Trace for this long + [[nodiscard]] std::chrono::milliseconds activitiesDuration() const { + return activitiesDuration_; + } + + // Trace for this many iterations, determined by external API + [[nodiscard]] int activitiesRunIterations() const { + return activitiesRunIterations_; + } + + [[nodiscard]] int64_t activitiesMaxGpuBufferSize() const { + return activitiesMaxGpuBufferSize_; + } + + [[nodiscard]] std::chrono::seconds activitiesWarmupDuration() const { + return activitiesWarmupDuration_; + } + + [[nodiscard]] int activitiesWarmupIterations() const { + return activitiesWarmupIterations_; + } + + // Show CUDA Synchronization Stream Wait Events + [[nodiscard]] bool activitiesCudaSyncWaitEvents() const { + return activitiesCudaSyncWaitEvents_; + } + + void setActivitiesCudaSyncWaitEvents(bool enable) { + activitiesCudaSyncWaitEvents_ = enable; + } + + // Timestamp at which the profiling to start, requested by the user. + [[nodiscard]] std::chrono::time_point requestTimestamp() const { + if (profileStartTime_.time_since_epoch().count()) { + return profileStartTime_; + } + // If no one requested timestamp, return 0. + if (requestTimestamp_.time_since_epoch().count() == 0) { + return requestTimestamp_; + } + + // TODO(T94634890): Deprecate requestTimestamp + return requestTimestamp_ + maxRequestAge() + activitiesWarmupDuration(); + } + + [[nodiscard]] bool hasProfileStartTime() const { + return requestTimestamp_.time_since_epoch().count() > 0 || profileStartTime_.time_since_epoch().count() > 0; + } + + [[nodiscard]] int profileStartIteration() const { + return profileStartIteration_; + } + + [[nodiscard]] bool hasProfileStartIteration() const { + return profileStartIteration_ >= 0 && activitiesRunIterations_ > 0; + } + + void setProfileStartIteration(int iter) { + profileStartIteration_ = iter; + } + + [[nodiscard]] int profileStartIterationRoundUp() const { + return profileStartIterationRoundUp_; + } + + // calculate the start iteration accounting for warmup + [[nodiscard]] int startIterationIncludingWarmup() const { + if (!hasProfileStartIteration()) { + return -1; + } + return profileStartIteration_ - activitiesWarmupIterations_; + } + + [[nodiscard]] std::chrono::seconds maxRequestAge() const; + + // All VLOG* macros will log if the verbose log level is >= + // the verbosity specified for the verbose log message. + // Default value is -1, so messages with log level 0 will log by default. + [[nodiscard]] int verboseLogLevel() const { + return verboseLogLevel_; + } + + // Modules for which verbose logging is enabled. + // If empty, logging is enabled for all modules. + [[nodiscard]] const std::vector& verboseLogModules() const { + return verboseLogModules_; + } + + [[nodiscard]] bool sigUsr2Enabled() const { + return enableSigUsr2_; + } + + [[nodiscard]] bool ipcFabricEnabled() const { + return enableIpcFabric_; + } + + [[nodiscard]] std::chrono::seconds onDemandConfigUpdateIntervalSecs() const { + return onDemandConfigUpdateIntervalSecs_; + } + + static std::chrono::milliseconds alignUp(std::chrono::milliseconds duration, std::chrono::milliseconds alignment) { + duration += alignment; + return duration - (duration % alignment); + } + + [[nodiscard]] std::chrono::time_point eventProfilerOnDemandStartTime() const { + return eventProfilerOnDemandTimestamp_; + } + + [[nodiscard]] std::chrono::time_point eventProfilerOnDemandEndTime() const { + return eventProfilerOnDemandTimestamp_ + eventProfilerOnDemandDuration_; + } + + [[nodiscard]] std::chrono::time_point activityProfilerRequestReceivedTime() const { + return activitiesOnDemandTimestamp_; + } + + static constexpr std::chrono::milliseconds kControllerIntervalMsecs{1000}; + + // Users may request and set trace id and group trace id. + [[nodiscard]] const std::string& requestTraceID() const { + return requestTraceID_; + } + + void setRequestTraceID(const std::string& tid) { + requestTraceID_ = tid; + } + + [[nodiscard]] const std::string& requestGroupTraceID() const { + return requestGroupTraceID_; + } + + void setRequestGroupTraceID(const std::string& gtid) { + requestGroupTraceID_ = gtid; + } + + [[nodiscard]] size_t cuptiDeviceBufferSize() const { + return cuptiDeviceBufferSize_; + } + + [[nodiscard]] size_t cuptiDeviceBufferPoolLimit() const { + return cuptiDeviceBufferPoolLimit_; + } + + [[nodiscard]] bool memoryProfilerEnabled() const { + return memoryProfilerEnabled_; + } + + [[nodiscard]] int profileMemoryDuration() const { + return profileMemoryDuration_; + } + void updateActivityProfilerRequestReceivedTime(); + + void printActivityProfilerConfig(std::ostream& s) const override; + void setActivityDependentConfig() override; + + void validate(const std::chrono::time_point& fallbackProfileStartTime) override; + + static void addConfigFactory(std::string name, std::function factory); + + void print(std::ostream& s) const; + + // Config relies on some state with global static lifetime. If other + // threads are using the config, it's possible that the global state + // is destroyed before the threads stop. By hanging onto this handle, + // correct destruction order can be ensured. + static std::shared_ptr getStaticObjectsLifetimeHandle(); + + [[nodiscard]] bool getTSCTimestampFlag() const { + return useTSCTimestamp_; + } + + void setTSCTimestampFlag(bool flag) { + useTSCTimestamp_ = flag; + } + + [[nodiscard]] const std::string& getCustomConfig() const { + return customConfig_; + } + + [[nodiscard]] uint32_t maxEvents() const { + return maxEvents_; + } + + private: + explicit Config(const Config& other) = default; + + AbstractConfig* cloneDerived([[maybe_unused]] AbstractConfig& parent) const override { + // Clone from AbstractConfig not supported + assert(false); + return nullptr; + } + + uint8_t createDeviceMask(const std::string& val); + + // Adds valid activity types from the user defined string list in the + // configuration file + void setActivityTypes(const std::vector& selected_activities); + + // Sets the default activity types to be traced + void selectDefaultActivityTypes() { + // If the user has not specified an activity list, add all types + for (ActivityType t : defaultActivityTypes()) { + selectedActivityTypes_.insert(t); + } + } + + int verboseLogLevel_; + std::vector verboseLogModules_; + + // Event profiler + // These settings are also supported in on-demand mode + std::chrono::milliseconds samplePeriod_; + std::chrono::milliseconds reportPeriod_; + int samplesPerReport_; + std::set eventNames_; + std::set metricNames_; + + // On-demand duration + std::chrono::seconds eventProfilerOnDemandDuration_; + // Last on-demand request + std::chrono::time_point eventProfilerOnDemandTimestamp_; + + int eventProfilerMaxInstancesPerGpu_; + + // Monitor whether event profiler threads are stuck + // at this frequency + std::chrono::seconds eventProfilerHeartbeatMonitorPeriod_; + + // These settings can not be changed on-demand + std::string eventLogFile_; + std::vector eventReportPercentiles_ = {5, 25, 50, 75, 95}; + uint8_t eventProfilerDeviceMask_ = static_cast(~0); + std::chrono::milliseconds multiplexPeriod_; + + // Activity profiler + bool activityProfilerEnabled_; + + // Enable per-thread buffer + bool perThreadBufferEnabled_; + std::set selectedActivityTypes_; + + // The activity profiler settings are all on-demand + std::string activitiesLogFile_; + + std::string activitiesLogUrl_; + + // Log activities to memory buffer + bool activitiesLogToMemory_{false}; + + int64_t activitiesMaxGpuBufferSize_; + std::chrono::seconds activitiesWarmupDuration_; + int activitiesWarmupIterations_; + bool activitiesCudaSyncWaitEvents_; + + // Enable Profiler Config Options + // Temporarily disable shape collection until we re-roll out the feature for + // on-demand cases + bool enableReportInputShapes_{false}; + bool enableProfileMemory_{false}; + bool enableWithStack_{false}; + bool enableWithFlops_{false}; + bool enableWithModules_{false}; + + // Profile for specified iterations and duration + std::chrono::milliseconds activitiesDuration_; + int activitiesRunIterations_; + + // Below are not used + // Use this net name for iteration count + std::string activitiesExternalAPIIterationsTarget_; + // Only profile nets that includes this in the name + std::vector activitiesExternalAPIFilter_; + // Only profile nets with at least this many operators + int activitiesExternalAPINetSizeThreshold_; + // Only profile nets with at least this many GPU operators + int activitiesExternalAPIGpuOpCountThreshold_; + // Last activity profiler request + std::chrono::time_point activitiesOnDemandTimestamp_; + + // ActivityProfilers are triggered by either: + // Synchronized start timestamps + std::chrono::time_point profileStartTime_; + // Or start iterations. + int profileStartIteration_; + int profileStartIterationRoundUp_; + + // DEPRECATED + std::chrono::time_point requestTimestamp_; + + // Enable profiling via SIGUSR2 + bool enableSigUsr2_; + + // Enable IPC Fabric instead of thrift communication + bool enableIpcFabric_; + std::chrono::seconds onDemandConfigUpdateIntervalSecs_; + + // Logger Metadata + std::string requestTraceID_; + std::string requestGroupTraceID_; + + // CUPTI Device Buffer + size_t cuptiDeviceBufferSize_; + size_t cuptiDeviceBufferPoolLimit_; + + // CUPTI Timestamp Format + bool useTSCTimestamp_{true}; + + // Memory Profiler + bool memoryProfilerEnabled_{false}; + int profileMemoryDuration_{1000}; + + // Used to flexibly configure some custom options, especially for custom + // backends. How to parse this string is handled by the custom backend. + std::string customConfig_; + + // Roctracer settings + uint32_t maxEvents_{5000000}; +}; + +constexpr char kUseDaemonEnvVar[] = "KINETO_USE_DAEMON"; + +bool isDaemonEnvVarSet(); + +// Returns a reference to the protobuf trace enabled flag. +// This allows the flag to be set externally (e.g., from JustKnobs in FBConfig) +// and read in other components (e.g., ChromeTraceLogger). +bool& get_protobuf_trace_enabled(); + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/GenericTraceActivity.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/GenericTraceActivity.h new file mode 100644 index 0000000000000000000000000000000000000000..6d05084044ea7e663b8b1679f9a8156ddbcd1ce9 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/GenericTraceActivity.h @@ -0,0 +1,173 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "ITraceActivity.h" +#include "ThreadUtil.h" +#include "TraceSpan.h" + +namespace libkineto { + +// Link type, used in GenericTraceActivity.flow.type +constexpr unsigned int kLinkFwdBwd = 1; +constexpr unsigned int kLinkAsyncCpuGpu = 2; + +// @lint-ignore-every CLANGTIDY +// cppcoreguidelines-non-private-member-variables-in-classes +// @lint-ignore-every CLANGTIDY cppcoreguidelines-pro-type-member-init +class GenericTraceActivity : public ITraceActivity { + public: + GenericTraceActivity() : activityType(ActivityType::ENUM_COUNT), traceSpan_(nullptr) {} + + GenericTraceActivity(const TraceSpan& trace, ActivityType type, const std::string& name) + : activityType(type), activityName(name), traceSpan_(&trace) {} + + int64_t deviceId() const override { + return device; + } + + int64_t resourceId() const override { + return resource; + } + + void setDevice(int32_t newDevice) { + device = newDevice; + } + + int32_t getThreadId() const override { + return threadId; + } + + int64_t timestamp() const override { + return startTime; + } + + int64_t duration() const override { + return endTime - startTime; + } + + int64_t correlationId() const override { + return id; + } + + ActivityType type() const override { + return activityType; + } + + const ITraceActivity* linkedActivity() const override { + return linked; + } + + int flowType() const override { + return flow.type; + } + + int64_t flowId() const override { + return flow.id; + } + + bool flowStart() const override { + return flow.start; + } + + const std::string name() const override { + return activityName; + } + + const TraceSpan* traceSpan() const override { + return traceSpan_; + } + + void log(ActivityLogger& logger) const override; + + // Encode client side metadata as a key/value + template + void addMetadata(const std::string& key, const ValType& value) { + metadataMap_.emplace(key, std::make_pair(fmt::format("{}", value), false)); + } + + void addMetadataQuoted(const std::string& key, const std::string& value) { + metadataMap_.emplace(key, std::make_pair(value, true)); + } + + // Store a typed counter value. Preferred over addMetadata for counter + // activities — preserves full double precision and avoids the JSON + // serialize/deserialize round-trip in output backends. + void addCounterValue(const std::string& name, double value) { + counterValues_.emplace_back(name, value); + } + + const std::vector>& counterValues() const override { + return counterValues_; + } + + const std::string getMetadataValue(const std::string& key) const override { + if (auto it = metadataMap_.find(key); it != metadataMap_.end()) { + return it->second.first; + } + return ""; + } + + const std::string metadataJson() const override { + std::stringstream json; + bool first = true; + for (const auto& [key, val] : metadataMap_) { + if (!first) { + json << ", "; + } + // Ok to use fmt::format here as we are not logging + val.second ? json << fmt::format("\"{}\": \"{}\"", key, val.first) + : json << fmt::format("\"{}\": {}", key, val.first); + first = false; + } + return json.str(); + } + + virtual ~GenericTraceActivity() override {} + + int64_t startTime{0}; + int64_t endTime{0}; + int32_t id{0}; + int32_t device{0}; + int32_t resource{0}; + int32_t threadId{0}; + ActivityType activityType; + std::string activityName; + struct Flow { + Flow() : id(0), type(0), start(0) {} + // Ids must be unique within each type + uint32_t id; + // Type will be used to connect flows between profilers, as + // well as look up flow information (name etc) + uint32_t type : 4; + uint32_t start : 1; + } flow; + const ITraceActivity* linked{nullptr}; + + private: + const TraceSpan* traceSpan_; + // Metadata map: { key: (value, quoted)} + std::unordered_map> metadataMap_; + // Typed counter values: (name, double) to avoid round-tripping though string + std::vector> counterValues_; +}; + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/IActivityProfiler.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/IActivityProfiler.h new file mode 100644 index 0000000000000000000000000000000000000000..7c18d5064504cb9bf28574fb04cbca08f4dad426 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/IActivityProfiler.h @@ -0,0 +1,166 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +#include "Config.h" +#include "GenericTraceActivity.h" + +/* This file includes an abstract base class for an activity profiler + * that can be implemented by multiple tracing agents in the application. + * The high level Kineto profiler can co-ordinate start and end of tracing + * and combine together events from multiple such activity profilers. + */ + +namespace libkineto { + +struct CpuTraceBuffer; + +#ifdef _MSC_VER +// workaround for the predefined ERROR macro on Windows +#undef ERROR +#endif // _MSC_VER + +enum class TraceStatus { + READY, // Accepting trace requests + WARMUP, // Performing trace warmup + RECORDING, // Actively collecting activities + PROCESSING, // Recording is complete, preparing results + ERROR, // One or more errors (and possibly also warnings) occurred. + WARNING, // One or more warnings occurred. +}; + +/* DeviceInfo: + * Can be used to specify process name, sort order, PID and device label. + * The sort order is determined by the sortIndex field to handle ordering of + * processes and gpu rows in the trace viewer. + */ +struct DeviceInfo { + DeviceInfo(int64_t id, int64_t sortIndex, std::string name, std::string label) + : id(id), sortIndex(sortIndex), name(std::move(name)), label(std::move(label)) {} + int64_t id; // process id + int64_t sortIndex; // position in trace view + const std::string name; // process name + const std::string label; // device label +}; + +/* ResourceInfo: + * Can be used to specify resource inside device + */ +struct ResourceInfo { + ResourceInfo(int64_t deviceId, int64_t id, int64_t sortIndex, std::string name) + : id(id), sortIndex(sortIndex), deviceId(deviceId), name(std::move(name)) {} + int64_t id; // resource id + int64_t sortIndex; // position in trace view + int64_t deviceId; // id of device which owns this resource (specified in + // DeviceInfo.id) + const std::string name; // resource name +}; + +using getLinkedActivityCallback = std::function; + +/* IActivityProfilerSession: + * an opaque object that can be used by a high level profiler to + * start/stop and return trace events. + */ +class IActivityProfilerSession { + public: + virtual ~IActivityProfilerSession() = default; + + // start the trace collection synchronously + virtual void start() = 0; + + // stop the trace collection synchronously + virtual void stop() = 0; + + TraceStatus status() { + return status_; + } + + // returns errors with this trace + virtual std::vector errors() = 0; + + // processes trace activities using logger + virtual void processTrace(ActivityLogger& logger) = 0; + + virtual void processTrace(ActivityLogger& logger, + [[maybe_unused]] getLinkedActivityCallback getLinkedActivity, + [[maybe_unused]] int64_t startTime, + [[maybe_unused]] int64_t endTime) { + processTrace(logger); + } + + // returns device info used in this trace, could be nullptr + virtual std::unique_ptr getDeviceInfo() = 0; + + // returns resource info used in this trace, could be empty + virtual std::vector getResourceInfos() = 0; + + // release ownership of the trace events and metadata + virtual std::unique_ptr getTraceBuffer() = 0; + + // XXX define trace formats + // virtual save(string name, TraceFormat format) + + virtual void pushCorrelationId([[maybe_unused]] uint64_t id) {} + virtual void popCorrelationId() {} + + virtual void pushUserCorrelationId([[maybe_unused]] uint64_t id) {} + virtual void popUserCorrelationId() {} + + virtual std::string getDeviceProperties() { + return ""; + } + + virtual std::unordered_map getMetadata() { + return {}; + } + + protected: + TraceStatus status_ = TraceStatus::READY; +}; + +/* Activity Profiler Plugins: + * These allow other frameworks to integrate into Kineto's primariy + * activity profiler. While the primary activity profiler handles + * timing the trace collections and correlating events the plugins + * can become source of new trace activity types. + */ +class IActivityProfiler { + public: + virtual ~IActivityProfiler() = default; + + // name of profiler + [[nodiscard]] virtual const std::string& name() const = 0; + + // returns activity types this profiler supports + [[nodiscard]] virtual const std::set& availableActivities() const = 0; + + // Calls prepare() on registered tracer providers passing in the relevant + // activity types. Returns a profiler session handle + virtual std::unique_ptr configure(const std::set& activity_types, + const Config& config) = 0; + + // asynchronous version of the above with future timestamp and duration. + virtual std::unique_ptr configure(int64_t ts_ms, + int64_t duration_ms, + const std::set& activity_types, + const Config& config) = 0; +}; + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ILoggerObserver.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ILoggerObserver.h new file mode 100644 index 0000000000000000000000000000000000000000..c80aabebd583f75e47d00120a60add0b08a480c1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ILoggerObserver.h @@ -0,0 +1,66 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#define NOGDI +#include + +// Stages in libkineto used when pushing logs to UST Logger. +constexpr char kWarmUpStage[] = "Warm Up"; +constexpr char kCollectionStage[] = "Collection"; +constexpr char kPostProcessingStage[] = "Post Processing"; + +// Special string in UST for determining if traces are empty +constexpr char kEmptyTrace[] = "No Valid Trace Events (CPU/GPU) found. Outputting empty trace."; + +#if !USE_GOOGLE_LOG + +#include +#include + +#include + +#ifdef _MSC_VER +// unset a predefined ERROR (windows) +#undef ERROR +#endif // _MSC_VER + +namespace libkineto { + +enum LoggerOutputType { VERBOSE = 0, INFO = 1, WARNING = 2, STAGE = 3, ERROR = 4, USDT = 5, ENUM_COUNT = 6 }; + +const char* toString(LoggerOutputType t); +LoggerOutputType toLoggerOutputType(const std::string& str); + +constexpr int LoggerTypeCount = (int)LoggerOutputType::ENUM_COUNT; + +class ILoggerObserver { + public: + virtual ~ILoggerObserver() = default; + virtual void write(const std::string& message, LoggerOutputType ot) = 0; + virtual const std::map> extractCollectorMetadata() = 0; + virtual void reset() = 0; + virtual void addDevice(const int64_t device) = 0; + virtual void setTraceDurationMS(const int64_t duration) = 0; + virtual void addEventCount(const int64_t count) = 0; + virtual void setTraceID([[maybe_unused]] const std::string& traceID) {} + virtual void setGroupTraceID([[maybe_unused]] const std::string& groupTraceID) {} + virtual void addDestination(const std::string& dest) = 0; + virtual void setTriggerOnDemand() {} + virtual void addMetadata(const std::string& key, const std::string& value) = 0; +}; + +} // namespace libkineto + +#endif // !USE_GOOGLE_LOG + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ITraceActivity.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ITraceActivity.h new file mode 100644 index 0000000000000000000000000000000000000000..1598dfb4d38c5b8ee5f6d387f74e7c742e14cf71 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ITraceActivity.h @@ -0,0 +1,77 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +#include "ActivityType.h" + +namespace libkineto { + +class ActivityLogger; +struct TraceSpan; + +// Generic activity interface is borrowed from tensorboard protobuf format. +struct ITraceActivity { + virtual ~ITraceActivity() = default; + // Device is a physical or logical entity, e.g. CPU, GPU or process + [[nodiscard]] virtual int64_t deviceId() const = 0; + // A resource is something on the device, h/w thread, + // functional units etc. + [[nodiscard]] virtual int64_t resourceId() const = 0; + // s/w thread + [[nodiscard]] virtual int32_t getThreadId() const = 0; + // Start timestamp in nanoseconds + [[nodiscard]] virtual int64_t timestamp() const = 0; + // Duration in nanoseconds + [[nodiscard]] virtual int64_t duration() const = 0; + // Used to link up async activities + [[nodiscard]] virtual int64_t correlationId() const = 0; + // Part of a flow, identified by flow id and type + [[nodiscard]] virtual int flowType() const = 0; + [[nodiscard]] virtual int64_t flowId() const = 0; + [[nodiscard]] virtual bool flowStart() const = 0; + [[nodiscard]] virtual ActivityType type() const = 0; + [[nodiscard]] virtual const std::string name() const = 0; + // Optional linked activity + [[nodiscard]] virtual const ITraceActivity* linkedActivity() const = 0; + // Optional containing trace object + [[nodiscard]] virtual const TraceSpan* traceSpan() const = 0; + // Log activity + virtual void log(ActivityLogger& logger) const = 0; + // Return json formatted metadata + // FIXME: Return iterator to dynamic type map here instead + [[nodiscard]] virtual const std::string metadataJson() const = 0; + // Return the metadata value in string format with key + // @lint-ignore CLANGTIDY: clang-diagnostic-unused-parameter + [[nodiscard]] virtual const std::string getMetadataValue([[maybe_unused]] const std::string& key) const { + return ""; + } + // Return typed counter values (name, value) for activities with + // floating-point metadata that should not be round-tripped through strings. + [[nodiscard]] virtual const std::vector>& counterValues() const { + static const std::vector> kEmpty; + return kEmpty; + } + + static int64_t nsToUs(int64_t ns) { + // It's important that this conversion is the same everywhere. + // No rounding! + return ns / 1000; + } +}; + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/LoggingAPI.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/LoggingAPI.h new file mode 100644 index 0000000000000000000000000000000000000000..d27484403234139ff0153276b08d1953c6821d37 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/LoggingAPI.h @@ -0,0 +1,19 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +namespace libkineto { +int getLogSeverityLevel(); +void setLogSeverityLevel(int level); +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ThreadUtil.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ThreadUtil.h new file mode 100644 index 0000000000000000000000000000000000000000..efc92dc98be2eba2d151fd9b9cfdbbc2603d3e46 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ThreadUtil.h @@ -0,0 +1,41 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace libkineto { + +int32_t systemThreadId(bool cache = true); +int32_t threadId(); +bool setThreadName(const std::string& name); +std::string getThreadName(); + +int32_t pidNamespace(ino_t& ns); +int32_t processId(bool cache = true); +std::string processName(int32_t pid); + +// Return a list of pids and process names for the current process +// and its parents. +std::vector> pidCommandPairsOfAncestors(); + +// Resets all cached Thread local state, this must be done on +// forks to prevent stale values from being retained. +void resetTLS(); + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/TraceSpan.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/TraceSpan.h new file mode 100644 index 0000000000000000000000000000000000000000..a01ffe27c7833887ae59cdc71fda5f652810c02a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/TraceSpan.h @@ -0,0 +1,40 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace libkineto { + +struct TraceSpan { + TraceSpan() = delete; + TraceSpan(int64_t startTime, int64_t endTime, std::string name) + : startTime(startTime), endTime(endTime), name(std::move(name)) {} + TraceSpan(int opCount, int it, std::string name, std::string prefix) + : opCount(opCount), iteration(it), name(std::move(name)), prefix(std::move(prefix)) {} + + // FIXME: change to duration? + int64_t startTime{0}; + int64_t endTime{0}; + int opCount{0}; + int iteration{-1}; + // Name is used to identify timeline + std::string name; + // Prefix used to distinguish trace spans on the same timeline + std::string prefix; +}; + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/libkineto.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/libkineto.h new file mode 100644 index 0000000000000000000000000000000000000000..b3cde9dc4d0225369f18ea5dad454cca45c7fbd0 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/libkineto.h @@ -0,0 +1,162 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +// Mediator for initialization and profiler control + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ActivityProfilerInterface.h" +#include "ActivityTraceInterface.h" +#include "ActivityType.h" +#include "ClientInterface.h" +#include "GenericTraceActivity.h" +#include "IActivityProfiler.h" +#include "ILoggerObserver.h" +#include "LoggingAPI.h" +#include "TraceSpan.h" + +#include "ThreadUtil.h" + +extern "C" { +void suppressLibkinetoLogMessages(); +int InitializeInjection(void); +void libkineto_init(bool cpuOnly, bool logOnError); +bool hasTestEnvVar(); +} + +namespace libkineto { + +class Config; +class ConfigLoader; + +struct CpuTraceBuffer { + template + void emplace_activity(Args&&... args) { + activities.emplace_back(std::make_unique(std::forward(args)...)); + } + + static GenericTraceActivity& toRef(std::unique_ptr& ref) { + return *ref; + } + + static const GenericTraceActivity& toRef(const std::unique_ptr& ref) { + return *ref; + } + + TraceSpan span{0, 0, "none"}; + int gpuOpCount; + std::deque> activities; +}; + +using ChildActivityProfilerFactory = std::function()>; + +class LibkinetoApi { + public: + explicit LibkinetoApi(ConfigLoader& configLoader) : configLoader_(configLoader) {} + + // Called by client that supports tracing API. + // libkineto can still function without this. + void registerClient(ClientInterface* client); + + // Called by libkineto on init + void registerProfiler(std::unique_ptr profiler) { + activityProfiler_ = std::move(profiler); + initClientIfRegistered(); + } + + ActivityProfilerInterface& activityProfiler() { + return *activityProfiler_; + } + + ClientInterface* client() { + return client_; + } + + void initProfilerIfRegistered() { + static std::once_flag once; + if (activityProfiler_) { + std::call_once(once, [this] { + if (!activityProfiler_->isInitialized()) { + activityProfiler_->init(); + initChildActivityProfilers(); + } + }); + } + } + + [[nodiscard]] bool isProfilerInitialized() const { + return activityProfiler_ && activityProfiler_->isInitialized(); + } + + [[nodiscard]] bool isProfilerRegistered() const { + return activityProfiler_ != nullptr; + } + + void suppressLogMessages() { + suppressLibkinetoLogMessages(); + } + + void resetKinetoTLS() { + resetTLS(); + } + + // Provides access to profier configuration manaegement + ConfigLoader& configLoader() { + return configLoader_; + } + + void registerProfilerFactory(const ChildActivityProfilerFactory& factory) { + if (isProfilerInitialized()) { + activityProfiler_->addChildActivityProfiler(factory()); + } else { + childProfilerFactories_.push_back(factory); + } + } + + private: + void initChildActivityProfilers() { + if (!isProfilerInitialized()) { + return; + } + for (const auto& factory : childProfilerFactories_) { + activityProfiler_->addChildActivityProfiler(factory()); + } + childProfilerFactories_.clear(); + } + + // Client is initialized once both it and libkineto has registered + void initClientIfRegistered(); + + ConfigLoader& configLoader_; + std::unique_ptr activityProfiler_; + ClientInterface* client_{}; + int32_t clientRegisterThread_{0}; + + std::vector childProfilerFactories_; +}; + +// Singleton +LibkinetoApi& api(); + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/output_base.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/output_base.h new file mode 100644 index 0000000000000000000000000000000000000000..e738f1fdb1ab257e8be31e2f7b273f4191219f74 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/output_base.h @@ -0,0 +1,80 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include + +// TODO(T90238193) +// @lint-ignore-every CLANGTIDY facebook-hte-RelativeInclude +#include "GenericTraceActivity.h" +#include "IActivityProfiler.h" +#include "ThreadUtil.h" +#include "TraceSpan.h" + +namespace KINETO_NAMESPACE { +struct ActivityBuffers; +} + +namespace libkineto { + +using namespace KINETO_NAMESPACE; + +// Used by sortIndex to put GPU tracks at the bottom +// of the trace timelines. The largest valid CPU PID is 4,194,304, +// so 5000000 is enough to guarantee that GPU tracks are sorted after CPU. +constexpr int64_t kExceedMaxPid = 5000000; + +class ActivityLogger { + public: + virtual ~ActivityLogger() = default; + + struct OverheadInfo { + explicit OverheadInfo(const std::string& name) : name(name) {} + const std::string name; + }; + + virtual void handleDeviceInfo(const DeviceInfo& info, int64_t time) = 0; + + virtual void handleResourceInfo(const ResourceInfo& info, int64_t time) = 0; + + virtual void handleOverheadInfo(const OverheadInfo& info, int64_t time) = 0; + + virtual void handleTraceSpan(const TraceSpan& span) = 0; + + virtual void handleActivity(const libkineto::ITraceActivity& activity) = 0; + virtual void handleGenericActivity(const libkineto::GenericTraceActivity& activity) = 0; + + virtual void handleTraceStart(const std::unordered_map& metadata, + const std::string& device_properties) = 0; + + void handleTraceStart() { + handleTraceStart(std::unordered_map(), ""); + } + + virtual void finalizeMemoryTrace(const std::string&, const Config&) = 0; + + virtual void finalizeTrace(const Config& config, + std::unique_ptr buffers, + int64_t endTime, + std::unordered_map>& metadata) = 0; + + protected: + ActivityLogger() = default; +}; + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/time_since_epoch.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/time_since_epoch.h new file mode 100644 index 0000000000000000000000000000000000000000..09df0c594663c02a42fa1620cc7e9676f9761501 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/time_since_epoch.h @@ -0,0 +1,24 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace libkineto { +template +inline int64_t timeSinceEpoch(const std::chrono::time_point& t) { + return std::chrono::duration_cast(t.time_since_epoch()).count(); +} + +} // namespace libkineto + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/legacy/ittnotify.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/legacy/ittnotify.h new file mode 100644 index 0000000000000000000000000000000000000000..307580cd0d0faa459abf5452c8a3f273cba55942 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/legacy/ittnotify.h @@ -0,0 +1,1009 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + Copyright (C) 2005-2019 Intel Corporation + + SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause +*/ +#ifndef _LEGACY_ITTNOTIFY_H_ +#define _LEGACY_ITTNOTIFY_H_ + +/** + * @file + * @brief Legacy User API functions and types + */ + +/** @cond exclude_from_documentation */ +#ifndef ITT_OS_WIN +# define ITT_OS_WIN 1 +#endif /* ITT_OS_WIN */ + +#ifndef ITT_OS_LINUX +# define ITT_OS_LINUX 2 +#endif /* ITT_OS_LINUX */ + +#ifndef ITT_OS_MAC +# define ITT_OS_MAC 3 +#endif /* ITT_OS_MAC */ + +#ifndef ITT_OS_FREEBSD +# define ITT_OS_FREEBSD 4 +#endif /* ITT_OS_FREEBSD */ + +#ifndef ITT_OS_OPENBSD +# define ITT_OS_OPENBSD 5 +#endif /* ITT_OS_OPENBSD */ + +#ifndef ITT_OS +# if defined WIN32 || defined _WIN32 +# define ITT_OS ITT_OS_WIN +# elif defined( __APPLE__ ) && defined( __MACH__ ) +# define ITT_OS ITT_OS_MAC +# elif defined( __FreeBSD__ ) +# define ITT_OS ITT_OS_FREEBSD +# elif defined( __OpenBSD__ ) +# define ITT_OS ITT_OS_OPENBSD +# else +# define ITT_OS ITT_OS_LINUX +# endif +#endif /* ITT_OS */ + +#ifndef ITT_PLATFORM_WIN +# define ITT_PLATFORM_WIN 1 +#endif /* ITT_PLATFORM_WIN */ + +#ifndef ITT_PLATFORM_POSIX +# define ITT_PLATFORM_POSIX 2 +#endif /* ITT_PLATFORM_POSIX */ + +#ifndef ITT_PLATFORM_MAC +# define ITT_PLATFORM_MAC 3 +#endif /* ITT_PLATFORM_MAC */ + +#ifndef ITT_PLATFORM_FREEBSD +# define ITT_PLATFORM_FREEBSD 4 +#endif /* ITT_PLATFORM_FREEBSD */ + +#ifndef ITT_PLATFORM_OPENBSD +# define ITT_PLATFORM_OPENBSD 5 +#endif /* ITT_PLATFORM_OPENBSD */ + +#ifndef ITT_PLATFORM +# if ITT_OS==ITT_OS_WIN +# define ITT_PLATFORM ITT_PLATFORM_WIN +# elif ITT_OS==ITT_OS_MAC +# define ITT_PLATFORM ITT_PLATFORM_MAC +# elif ITT_OS==ITT_OS_FREEBSD +# define ITT_PLATFORM ITT_PLATFORM_FREEBSD +# elif ITT_OS==ITT_OS_OPENBSD +# define ITT_PLATFORM ITT_PLATFORM_OPENBSD +# else +# define ITT_PLATFORM ITT_PLATFORM_POSIX +# endif +#endif /* ITT_PLATFORM */ + +#if defined(_UNICODE) && !defined(UNICODE) +#define UNICODE +#endif + +#include +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#include +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#include +#if defined(UNICODE) || defined(_UNICODE) +#include +#endif /* UNICODE || _UNICODE */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef ITTAPI_CDECL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define ITTAPI_CDECL __cdecl +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define ITTAPI_CDECL __attribute__ ((cdecl)) +# else /* _M_IX86 || __i386__ */ +# define ITTAPI_CDECL /* actual only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* ITTAPI_CDECL */ + +#ifndef STDCALL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define STDCALL __stdcall +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define STDCALL __attribute__ ((stdcall)) +# else /* _M_IX86 || __i386__ */ +# define STDCALL /* supported only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* STDCALL */ + +#define ITTAPI ITTAPI_CDECL +#define LIBITTAPI ITTAPI_CDECL + +/* TODO: Temporary for compatibility! */ +#define ITTAPI_CALL ITTAPI_CDECL +#define LIBITTAPI_CALL ITTAPI_CDECL + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +/* use __forceinline (VC++ specific) */ +#if defined(__MINGW32__) && !defined(__cplusplus) +#define ITT_INLINE static __inline__ __attribute__((__always_inline__,__gnu_inline__)) +#else +#define ITT_INLINE static __forceinline +#endif /* __MINGW32__ */ + +#define ITT_INLINE_ATTRIBUTE /* nothing */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/* + * Generally, functions are not inlined unless optimization is specified. + * For functions declared inline, this attribute inlines the function even + * if no optimization level was specified. + */ +#ifdef __STRICT_ANSI__ +#define ITT_INLINE static +#define ITT_INLINE_ATTRIBUTE __attribute__((unused)) +#else /* __STRICT_ANSI__ */ +#define ITT_INLINE static inline +#define ITT_INLINE_ATTRIBUTE __attribute__((always_inline, unused)) +#endif /* __STRICT_ANSI__ */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/** @endcond */ + +/** @cond exclude_from_documentation */ +/* Helper macro for joining tokens */ +#define ITT_JOIN_AUX(p,n) p##n +#define ITT_JOIN(p,n) ITT_JOIN_AUX(p,n) + +#ifdef ITT_MAJOR +#undef ITT_MAJOR +#endif +#ifdef ITT_MINOR +#undef ITT_MINOR +#endif +#define ITT_MAJOR 3 +#define ITT_MINOR 0 + +/* Standard versioning of a token with major and minor version numbers */ +#define ITT_VERSIONIZE(x) \ + ITT_JOIN(x, \ + ITT_JOIN(_, \ + ITT_JOIN(ITT_MAJOR, \ + ITT_JOIN(_, ITT_MINOR)))) + +#ifndef INTEL_ITTNOTIFY_PREFIX +# define INTEL_ITTNOTIFY_PREFIX __itt_ +#endif /* INTEL_ITTNOTIFY_PREFIX */ +#ifndef INTEL_ITTNOTIFY_POSTFIX +# define INTEL_ITTNOTIFY_POSTFIX _ptr_ +#endif /* INTEL_ITTNOTIFY_POSTFIX */ + +#define ITTNOTIFY_NAME_AUX(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) +#define ITTNOTIFY_NAME(n) ITT_VERSIONIZE(ITTNOTIFY_NAME_AUX(ITT_JOIN(n,INTEL_ITTNOTIFY_POSTFIX))) + +#define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n) +#define ITTNOTIFY_DATA(n) (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n) + +#define ITTNOTIFY_VOID_D0(n,d) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d) +#define ITTNOTIFY_VOID_D1(n,d,x) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x) +#define ITTNOTIFY_VOID_D2(n,d,x,y) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y) +#define ITTNOTIFY_VOID_D3(n,d,x,y,z) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z) +#define ITTNOTIFY_VOID_D4(n,d,x,y,z,a) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) +#define ITTNOTIFY_VOID_D5(n,d,x,y,z,a,b) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) +#define ITTNOTIFY_VOID_D6(n,d,x,y,z,a,b,c) (d == NULL) ? (void)0 : (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) +#define ITTNOTIFY_DATA_D0(n,d) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d) +#define ITTNOTIFY_DATA_D1(n,d,x) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x) +#define ITTNOTIFY_DATA_D2(n,d,x,y) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y) +#define ITTNOTIFY_DATA_D3(n,d,x,y,z) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z) +#define ITTNOTIFY_DATA_D4(n,d,x,y,z,a) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) +#define ITTNOTIFY_DATA_D5(n,d,x,y,z,a,b) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) +#define ITTNOTIFY_DATA_D6(n,d,x,y,z,a,b,c) (d == NULL) ? 0 : (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) + +#ifdef ITT_STUB +#undef ITT_STUB +#endif +#ifdef ITT_STUBV +#undef ITT_STUBV +#endif +#define ITT_STUBV(api,type,name,args) \ + typedef type (api* ITT_JOIN(ITTNOTIFY_NAME(name),_t)) args; \ + extern ITT_JOIN(ITTNOTIFY_NAME(name),_t) ITTNOTIFY_NAME(name); +#define ITT_STUB ITT_STUBV +/** @endcond */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup legacy Legacy API + * @{ + * @} + */ + +/** + * @defgroup legacy_control Collection Control + * @ingroup legacy + * General behavior: application continues to run, but no profiling information is being collected + * + * Pausing occurs not only for the current thread but for all process as well as spawned processes + * - Intel(R) Parallel Inspector and Intel(R) Inspector XE: + * - Does not analyze or report errors that involve memory access. + * - Other errors are reported as usual. Pausing data collection in + * Intel(R) Parallel Inspector and Intel(R) Inspector XE + * only pauses tracing and analyzing memory access. + * It does not pause tracing or analyzing threading APIs. + * . + * - Intel(R) VTune(TM) Profiler: + * - Does continue to record when new threads are started. + * . + * - Other effects: + * - Possible reduction of runtime overhead. + * . + * @{ + */ +#ifndef _ITTNOTIFY_H_ +/** @brief Pause collection */ +void ITTAPI __itt_pause(void); +/** @brief Resume collection */ +void ITTAPI __itt_resume(void); +/** @brief Detach collection */ +void ITTAPI __itt_detach(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, pause, (void)) +ITT_STUBV(ITTAPI, void, resume, (void)) +ITT_STUBV(ITTAPI, void, detach, (void)) +#define __itt_pause ITTNOTIFY_VOID(pause) +#define __itt_pause_ptr ITTNOTIFY_NAME(pause) +#define __itt_resume ITTNOTIFY_VOID(resume) +#define __itt_resume_ptr ITTNOTIFY_NAME(resume) +#define __itt_detach ITTNOTIFY_VOID(detach) +#define __itt_detach_ptr ITTNOTIFY_NAME(detach) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_pause() +#define __itt_pause_ptr 0 +#define __itt_resume() +#define __itt_resume_ptr 0 +#define __itt_detach() +#define __itt_detach_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_pause_ptr 0 +#define __itt_resume_ptr 0 +#define __itt_detach_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +#endif /* _ITTNOTIFY_H_ */ +/** @} legacy_control group */ + +/** + * @defgroup legacy_threads Threads + * @ingroup legacy + * Threads group + * @warning Legacy API + * @{ + */ +/** + * @deprecated Legacy API + * @brief Set name to be associated with thread in analysis GUI. + * @return __itt_err upon failure (name or namelen being null,name and namelen mismatched) + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int LIBITTAPI __itt_thr_name_setA(const char *name, int namelen); +int LIBITTAPI __itt_thr_name_setW(const wchar_t *name, int namelen); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_thr_name_set __itt_thr_name_setW +# define __itt_thr_name_set_ptr __itt_thr_name_setW_ptr +#else +# define __itt_thr_name_set __itt_thr_name_setA +# define __itt_thr_name_set_ptr __itt_thr_name_setA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int LIBITTAPI __itt_thr_name_set(const char *name, int namelen); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, int, thr_name_setA, (const char *name, int namelen)) +ITT_STUB(LIBITTAPI, int, thr_name_setW, (const wchar_t *name, int namelen)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, int, thr_name_set, (const char *name, int namelen)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thr_name_setA ITTNOTIFY_DATA(thr_name_setA) +#define __itt_thr_name_setA_ptr ITTNOTIFY_NAME(thr_name_setA) +#define __itt_thr_name_setW ITTNOTIFY_DATA(thr_name_setW) +#define __itt_thr_name_setW_ptr ITTNOTIFY_NAME(thr_name_setW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thr_name_set ITTNOTIFY_DATA(thr_name_set) +#define __itt_thr_name_set_ptr ITTNOTIFY_NAME(thr_name_set) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thr_name_setA(name, namelen) +#define __itt_thr_name_setA_ptr 0 +#define __itt_thr_name_setW(name, namelen) +#define __itt_thr_name_setW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thr_name_set(name, namelen) +#define __itt_thr_name_set_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thr_name_setA_ptr 0 +#define __itt_thr_name_setW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thr_name_set_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Mark current thread as ignored from this point on, for the duration of its existence. + */ +void LIBITTAPI __itt_thr_ignore(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, thr_ignore, (void)) +#define __itt_thr_ignore ITTNOTIFY_VOID(thr_ignore) +#define __itt_thr_ignore_ptr ITTNOTIFY_NAME(thr_ignore) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_thr_ignore() +#define __itt_thr_ignore_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_thr_ignore_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_threads group */ + +/** + * @defgroup legacy_sync Synchronization + * @ingroup legacy + * Synchronization group + * @warning Legacy API + * @{ + */ +/** + * @hideinitializer + * @brief possible value of attribute argument for sync object type + */ +#define __itt_attr_barrier 1 + +/** + * @hideinitializer + * @brief possible value of attribute argument for sync object type + */ +#define __itt_attr_mutex 2 + +/** + * @deprecated Legacy API + * @brief Assign a name to a sync object using char or Unicode string + * @param[in] addr - pointer to the sync object. You should use a real pointer to your object + * to make sure that the values don't clash with other object addresses + * @param[in] objtype - null-terminated object type string. If NULL is passed, the object will + * be assumed to be of generic "User Synchronization" type + * @param[in] objname - null-terminated object name string. If NULL, no name will be assigned + * to the object -- you can use the __itt_sync_rename call later to assign + * the name + * @param[in] attribute - one of [#__itt_attr_barrier, #__itt_attr_mutex] values which defines the + * exact semantics of how prepare/acquired/releasing calls work. + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_sync_set_nameA(void *addr, const char *objtype, const char *objname, int attribute); +void ITTAPI __itt_sync_set_nameW(void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_sync_set_name __itt_sync_set_nameW +# define __itt_sync_set_name_ptr __itt_sync_set_nameW_ptr +#else /* UNICODE */ +# define __itt_sync_set_name __itt_sync_set_nameA +# define __itt_sync_set_name_ptr __itt_sync_set_nameA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_sync_set_name(void *addr, const char* objtype, const char* objname, int attribute); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, sync_set_nameA, (void *addr, const char *objtype, const char *objname, int attribute)) +ITT_STUBV(ITTAPI, void, sync_set_nameW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, sync_set_name, (void *addr, const char *objtype, const char *objname, int attribute)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_set_nameA ITTNOTIFY_VOID(sync_set_nameA) +#define __itt_sync_set_nameA_ptr ITTNOTIFY_NAME(sync_set_nameA) +#define __itt_sync_set_nameW ITTNOTIFY_VOID(sync_set_nameW) +#define __itt_sync_set_nameW_ptr ITTNOTIFY_NAME(sync_set_nameW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_set_name ITTNOTIFY_VOID(sync_set_name) +#define __itt_sync_set_name_ptr ITTNOTIFY_NAME(sync_set_name) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_set_nameA(addr, objtype, objname, attribute) +#define __itt_sync_set_nameA_ptr 0 +#define __itt_sync_set_nameW(addr, objtype, objname, attribute) +#define __itt_sync_set_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_set_name(addr, objtype, objname, attribute) +#define __itt_sync_set_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_set_nameA_ptr 0 +#define __itt_sync_set_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_set_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Assign a name and type to a sync object using char or Unicode string + * @param[in] addr - pointer to the sync object. You should use a real pointer to your object + * to make sure that the values don't clash with other object addresses + * @param[in] objtype - null-terminated object type string. If NULL is passed, the object will + * be assumed to be of generic "User Synchronization" type + * @param[in] objname - null-terminated object name string. If NULL, no name will be assigned + * to the object -- you can use the __itt_sync_rename call later to assign + * the name + * @param[in] typelen, namelen - a length of string for appropriate objtype and objname parameter + * @param[in] attribute - one of [#__itt_attr_barrier, #__itt_attr_mutex] values which defines the + * exact semantics of how prepare/acquired/releasing calls work. + * @return __itt_err upon failure (name or namelen being null,name and namelen mismatched) + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int LIBITTAPI __itt_notify_sync_nameA(void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute); +int LIBITTAPI __itt_notify_sync_nameW(void *addr, const wchar_t *objtype, int typelen, const wchar_t *objname, int namelen, int attribute); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_notify_sync_name __itt_notify_sync_nameW +#else +# define __itt_notify_sync_name __itt_notify_sync_nameA +#endif +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int LIBITTAPI __itt_notify_sync_name(void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, int, notify_sync_nameA, (void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute)) +ITT_STUB(LIBITTAPI, int, notify_sync_nameW, (void *addr, const wchar_t *objtype, int typelen, const wchar_t *objname, int namelen, int attribute)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, int, notify_sync_name, (void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_notify_sync_nameA ITTNOTIFY_DATA(notify_sync_nameA) +#define __itt_notify_sync_nameA_ptr ITTNOTIFY_NAME(notify_sync_nameA) +#define __itt_notify_sync_nameW ITTNOTIFY_DATA(notify_sync_nameW) +#define __itt_notify_sync_nameW_ptr ITTNOTIFY_NAME(notify_sync_nameW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_notify_sync_name ITTNOTIFY_DATA(notify_sync_name) +#define __itt_notify_sync_name_ptr ITTNOTIFY_NAME(notify_sync_name) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_notify_sync_nameA(addr, objtype, typelen, objname, namelen, attribute) +#define __itt_notify_sync_nameA_ptr 0 +#define __itt_notify_sync_nameW(addr, objtype, typelen, objname, namelen, attribute) +#define __itt_notify_sync_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_notify_sync_name(addr, objtype, typelen, objname, namelen, attribute) +#define __itt_notify_sync_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_notify_sync_nameA_ptr 0 +#define __itt_notify_sync_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_notify_sync_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Enter spin loop on user-defined sync object + */ +void LIBITTAPI __itt_notify_sync_prepare(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, notify_sync_prepare, (void *addr)) +#define __itt_notify_sync_prepare ITTNOTIFY_VOID(notify_sync_prepare) +#define __itt_notify_sync_prepare_ptr ITTNOTIFY_NAME(notify_sync_prepare) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_notify_sync_prepare(addr) +#define __itt_notify_sync_prepare_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_notify_sync_prepare_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Quit spin loop without acquiring spin object + */ +void LIBITTAPI __itt_notify_sync_cancel(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, notify_sync_cancel, (void *addr)) +#define __itt_notify_sync_cancel ITTNOTIFY_VOID(notify_sync_cancel) +#define __itt_notify_sync_cancel_ptr ITTNOTIFY_NAME(notify_sync_cancel) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_notify_sync_cancel(addr) +#define __itt_notify_sync_cancel_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_notify_sync_cancel_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Successful spin loop completion (sync object acquired) + */ +void LIBITTAPI __itt_notify_sync_acquired(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, notify_sync_acquired, (void *addr)) +#define __itt_notify_sync_acquired ITTNOTIFY_VOID(notify_sync_acquired) +#define __itt_notify_sync_acquired_ptr ITTNOTIFY_NAME(notify_sync_acquired) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_notify_sync_acquired(addr) +#define __itt_notify_sync_acquired_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_notify_sync_acquired_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Start sync object releasing code. Is called before the lock release call. + */ +void LIBITTAPI __itt_notify_sync_releasing(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, notify_sync_releasing, (void *addr)) +#define __itt_notify_sync_releasing ITTNOTIFY_VOID(notify_sync_releasing) +#define __itt_notify_sync_releasing_ptr ITTNOTIFY_NAME(notify_sync_releasing) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_notify_sync_releasing(addr) +#define __itt_notify_sync_releasing_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_notify_sync_releasing_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_sync group */ + +#ifndef _ITTNOTIFY_H_ +/** + * @defgroup legacy_events Events + * @ingroup legacy + * Events group + * @{ + */ + +/** @brief user event type */ +typedef int __itt_event; + +/** + * @brief Create an event notification + * @note name or namelen being null/name and namelen not matching, user event feature not enabled + * @return non-zero event identifier upon success and __itt_err otherwise + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_event LIBITTAPI __itt_event_createA(const char *name, int namelen); +__itt_event LIBITTAPI __itt_event_createW(const wchar_t *name, int namelen); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_event_create __itt_event_createW +# define __itt_event_create_ptr __itt_event_createW_ptr +#else +# define __itt_event_create __itt_event_createA +# define __itt_event_create_ptr __itt_event_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_event LIBITTAPI __itt_event_create(const char *name, int namelen); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, __itt_event, event_createA, (const char *name, int namelen)) +ITT_STUB(LIBITTAPI, __itt_event, event_createW, (const wchar_t *name, int namelen)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, __itt_event, event_create, (const char *name, int namelen)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA ITTNOTIFY_DATA(event_createA) +#define __itt_event_createA_ptr ITTNOTIFY_NAME(event_createA) +#define __itt_event_createW ITTNOTIFY_DATA(event_createW) +#define __itt_event_createW_ptr ITTNOTIFY_NAME(event_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create ITTNOTIFY_DATA(event_create) +#define __itt_event_create_ptr ITTNOTIFY_NAME(event_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA(name, namelen) (__itt_event)0 +#define __itt_event_createA_ptr 0 +#define __itt_event_createW(name, namelen) (__itt_event)0 +#define __itt_event_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create(name, namelen) (__itt_event)0 +#define __itt_event_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA_ptr 0 +#define __itt_event_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an event occurrence. + * @return __itt_err upon failure (invalid event id/user event feature not enabled) + */ +int LIBITTAPI __itt_event_start(__itt_event event); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(LIBITTAPI, int, event_start, (__itt_event event)) +#define __itt_event_start ITTNOTIFY_DATA(event_start) +#define __itt_event_start_ptr ITTNOTIFY_NAME(event_start) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_event_start(event) (int)0 +#define __itt_event_start_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_event_start_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an event end occurrence. + * @note It is optional if events do not have durations. + * @return __itt_err upon failure (invalid event id/user event feature not enabled) + */ +int LIBITTAPI __itt_event_end(__itt_event event); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(LIBITTAPI, int, event_end, (__itt_event event)) +#define __itt_event_end ITTNOTIFY_DATA(event_end) +#define __itt_event_end_ptr ITTNOTIFY_NAME(event_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_event_end(event) (int)0 +#define __itt_event_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_event_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_events group */ +#endif /* _ITTNOTIFY_H_ */ + +/** + * @defgroup legacy_memory Memory Accesses + * @ingroup legacy + */ + +/** + * @deprecated Legacy API + * @brief Inform the tool of memory accesses on reading + */ +void LIBITTAPI __itt_memory_read(void *addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, memory_read, (void *addr, size_t size)) +#define __itt_memory_read ITTNOTIFY_VOID(memory_read) +#define __itt_memory_read_ptr ITTNOTIFY_NAME(memory_read) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_memory_read(addr, size) +#define __itt_memory_read_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_memory_read_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Inform the tool of memory accesses on writing + */ +void LIBITTAPI __itt_memory_write(void *addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, memory_write, (void *addr, size_t size)) +#define __itt_memory_write ITTNOTIFY_VOID(memory_write) +#define __itt_memory_write_ptr ITTNOTIFY_NAME(memory_write) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_memory_write(addr, size) +#define __itt_memory_write_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_memory_write_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Inform the tool of memory accesses on updating + */ +void LIBITTAPI __itt_memory_update(void *address, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, memory_update, (void *addr, size_t size)) +#define __itt_memory_update ITTNOTIFY_VOID(memory_update) +#define __itt_memory_update_ptr ITTNOTIFY_NAME(memory_update) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_memory_update(addr, size) +#define __itt_memory_update_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_memory_update_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_memory group */ + +/** + * @defgroup legacy_state Thread and Object States + * @ingroup legacy + */ + +/** @brief state type */ +typedef int __itt_state_t; + +/** @cond exclude_from_documentation */ +typedef enum __itt_obj_state { + __itt_obj_state_err = 0, + __itt_obj_state_clr = 1, + __itt_obj_state_set = 2, + __itt_obj_state_use = 3 +} __itt_obj_state_t; + +typedef enum __itt_thr_state { + __itt_thr_state_err = 0, + __itt_thr_state_clr = 1, + __itt_thr_state_set = 2 +} __itt_thr_state_t; + +typedef enum __itt_obj_prop { + __itt_obj_prop_watch = 1, + __itt_obj_prop_ignore = 2, + __itt_obj_prop_sharable = 3 +} __itt_obj_prop_t; + +typedef enum __itt_thr_prop { + __itt_thr_prop_quiet = 1 +} __itt_thr_prop_t; +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief managing thread and object states + */ +__itt_state_t LIBITTAPI __itt_state_get(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_state_t, state_get, (void)) +#define __itt_state_get ITTNOTIFY_DATA(state_get) +#define __itt_state_get_ptr ITTNOTIFY_NAME(state_get) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_state_get(void) (__itt_state_t)0 +#define __itt_state_get_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_state_get_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief managing thread and object states + */ +__itt_state_t LIBITTAPI __itt_state_set(__itt_state_t s); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_state_t, state_set, (__itt_state_t s)) +#define __itt_state_set ITTNOTIFY_DATA(state_set) +#define __itt_state_set_ptr ITTNOTIFY_NAME(state_set) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_state_set(s) (__itt_state_t)0 +#define __itt_state_set_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_state_set_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief managing thread and object modes + */ +__itt_thr_state_t LIBITTAPI __itt_thr_mode_set(__itt_thr_prop_t p, __itt_thr_state_t s); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_thr_state_t, thr_mode_set, (__itt_thr_prop_t p, __itt_thr_state_t s)) +#define __itt_thr_mode_set ITTNOTIFY_DATA(thr_mode_set) +#define __itt_thr_mode_set_ptr ITTNOTIFY_NAME(thr_mode_set) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_thr_mode_set(p, s) (__itt_thr_state_t)0 +#define __itt_thr_mode_set_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_thr_mode_set_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief managing thread and object modes + */ +__itt_obj_state_t LIBITTAPI __itt_obj_mode_set(__itt_obj_prop_t p, __itt_obj_state_t s); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_obj_state_t, obj_mode_set, (__itt_obj_prop_t p, __itt_obj_state_t s)) +#define __itt_obj_mode_set ITTNOTIFY_DATA(obj_mode_set) +#define __itt_obj_mode_set_ptr ITTNOTIFY_NAME(obj_mode_set) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_obj_mode_set(p, s) (__itt_obj_state_t)0 +#define __itt_obj_mode_set_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_obj_mode_set_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_state group */ + +/** + * @defgroup frames Frames + * @ingroup legacy + * Frames group + * @{ + */ +/** + * @brief opaque structure for frame identification + */ +typedef struct __itt_frame_t *__itt_frame; + +/** + * @brief Create a global frame with given domain + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_frame ITTAPI __itt_frame_createA(const char *domain); +__itt_frame ITTAPI __itt_frame_createW(const wchar_t *domain); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_frame_create __itt_frame_createW +# define __itt_frame_create_ptr __itt_frame_createW_ptr +#else /* UNICODE */ +# define __itt_frame_create __itt_frame_createA +# define __itt_frame_create_ptr __itt_frame_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_frame ITTAPI __itt_frame_create(const char *domain); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_frame, frame_createA, (const char *domain)) +ITT_STUB(ITTAPI, __itt_frame, frame_createW, (const wchar_t *domain)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_frame, frame_create, (const char *domain)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_frame_createA ITTNOTIFY_DATA(frame_createA) +#define __itt_frame_createA_ptr ITTNOTIFY_NAME(frame_createA) +#define __itt_frame_createW ITTNOTIFY_DATA(frame_createW) +#define __itt_frame_createW_ptr ITTNOTIFY_NAME(frame_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_frame_create ITTNOTIFY_DATA(frame_create) +#define __itt_frame_create_ptr ITTNOTIFY_NAME(frame_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_frame_createA(domain) +#define __itt_frame_createA_ptr 0 +#define __itt_frame_createW(domain) +#define __itt_frame_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_frame_create(domain) +#define __itt_frame_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_frame_createA_ptr 0 +#define __itt_frame_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_frame_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief Record a frame begin occurrence. */ +void ITTAPI __itt_frame_begin(__itt_frame frame); +/** @brief Record a frame end occurrence. */ +void ITTAPI __itt_frame_end (__itt_frame frame); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, frame_begin, (__itt_frame frame)) +ITT_STUBV(ITTAPI, void, frame_end, (__itt_frame frame)) +#define __itt_frame_begin ITTNOTIFY_VOID(frame_begin) +#define __itt_frame_begin_ptr ITTNOTIFY_NAME(frame_begin) +#define __itt_frame_end ITTNOTIFY_VOID(frame_end) +#define __itt_frame_end_ptr ITTNOTIFY_NAME(frame_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_frame_begin(frame) +#define __itt_frame_begin_ptr 0 +#define __itt_frame_end(frame) +#define __itt_frame_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_frame_begin_ptr 0 +#define __itt_frame_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} frames group */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _LEGACY_ITTNOTIFY_H_ */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libittnotify.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libittnotify.h new file mode 100644 index 0000000000000000000000000000000000000000..cb5190ff7d3c2bfe1685dafaddc7cd744e971fa8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libittnotify.h @@ -0,0 +1,24 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + Copyright (C) 2005-2019 Intel Corporation + + SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause +*/ + +#ifndef _LIBITTNOTIFY_H_ +#define _LIBITTNOTIFY_H_ + +#ifndef __ITT_INTERNAL_INCLUDE +# if defined WIN32 || defined _WIN32 +# pragma message("WARNING!!! Include file libittnotify.h is deprecated and should not be included anymore") +# else /* WIN32 */ +# warning "Include file libittnotify.h is deprecated and should not be included anymore" +# endif /* WIN32 */ +#endif /* __ITT_INTERNAL_INCLUDE */ +#include "legacy/ittnotify.h" + +#endif /* _LIBITTNOTIFY_H_ */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libshm.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libshm.h new file mode 100644 index 0000000000000000000000000000000000000000..58d368dcf7aea4472e91efb60983e58e70c61654 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libshm.h @@ -0,0 +1,51 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include + +#ifdef __cplusplus + +void libshm_init(const char* manager_exec_path); + +// Superclass to run a constructor before at::RefcountedMapAllocator +class THManagedMapAllocatorInit { + protected: + THManagedMapAllocatorInit(const char* manager_handle, const char* filename); + std::string manager_handle_; +}; + +// Like a at::RefcountedMapAllocator, but it also makes use of an external +// shared memory manager process to ensure that shared memory regions actually +// get freed in the end (even if processes lose the memory). +class THManagedMapAllocator : private THManagedMapAllocatorInit, + public at::RefcountedMapAllocator { + public: + THManagedMapAllocator( + const char* manager_handle, + const char* filename, + int flags, + size_t size); + + void close() override; + + ~THManagedMapAllocator() override { + close(); + } + + static at::DataPtr makeDataPtr( + const char* manager_handle, + const char* filename, + int flags, + size_t size); + static THManagedMapAllocator* fromDataPtr(const at::DataPtr& /*dptr*/); + + const char* manager_handle() const { + return manager_handle_.c_str(); + } +}; + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/nnpack.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/nnpack.h new file mode 100644 index 0000000000000000000000000000000000000000..62e785e8c9e9f4a28c50f4f5260bc89dbb2d5c83 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/nnpack.h @@ -0,0 +1,664 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Status code for any NNPACK function call. + */ +enum nnp_status { + /** The call succeeded, and all output arguments now contain valid data. */ + nnp_status_success = 0, + /** NNPACK function was called with batch_size == 0. */ + nnp_status_invalid_batch_size = 2, + /** NNPACK function was called with channels == 0. */ + nnp_status_invalid_channels = 3, + /** NNPACK function was called with input_channels == 0. */ + nnp_status_invalid_input_channels = 4, + /** NNPACK function was called with output_channels == 0. */ + nnp_status_invalid_output_channels = 5, + /** NNPACK function was called with input_size.height == 0 or input_size.width == 0 */ + nnp_status_invalid_input_size = 10, + /** NNPACK function was called with input_stride.height == 0 or input_stride.width == 0 */ + nnp_status_invalid_input_stride = 11, + /** NNPACK function was called with input_padding not less than respective kernel (or pooling) size, i.e.: + * + * - input_padding.left >= kernel_size.width (>= pooling_size.width) + * - input_padding.right >= kernel_size.width (>= pooling_size.width) + * - input_padding.top >= kernel_size.height (>= pooling_size.height) + * - input_padding.bottom >= kernel_size.height (>= pooling_size.height) + */ + nnp_status_invalid_input_padding = 12, + /** NNPACK function was called with kernel_size.height == 0 or kernel_size.width == 0 */ + nnp_status_invalid_kernel_size = 13, + /** NNPACK function was called with pooling_size.height == 0 or pooling_size.width == 0 */ + nnp_status_invalid_pooling_size = 14, + /** NNPACK function was called with pooling_stride.height == 0 or pooling_stride.width == 0 */ + nnp_status_invalid_pooling_stride = 15, + /** NNPACK function was called with convolution algorithm not in nnp_convolution_algorithm enumeration */ + nnp_status_invalid_algorithm = 16, + /** NNPACK function was called with convolution transform strategy not in nnp_convolution_transform_strategy enum */ + nnp_status_invalid_transform_strategy = 17, + /** NNPACK function was called with output_subsampling.height == 0 or output_subsampling.width == 0 */ + nnp_status_invalid_output_subsampling = 13, + /** NNPACK function was called with activation not in nnp_activation enum */ + nnp_status_invalid_activation = 14, + /** NNPACK function was called with invalid activation parameters */ + nnp_status_invalid_activation_parameters = 15, + + /** NNPACK does not support the particular input size for the function */ + nnp_status_unsupported_input_size = 20, + /** NNPACK does not support the particular input stride for the function */ + nnp_status_unsupported_input_stride = 21, + /** NNPACK does not support the particular input padding for the function */ + nnp_status_unsupported_input_padding = 22, + /** NNPACK does not support the particular kernel size for the function */ + nnp_status_unsupported_kernel_size = 23, + /** NNPACK does not support the particular pooling size for the function */ + nnp_status_unsupported_pooling_size = 24, + /** NNPACK does not support the particular pooling stride for the function */ + nnp_status_unsupported_pooling_stride = 25, + /** NNPACK does not support the particular convolution algorithm for the function */ + nnp_status_unsupported_algorithm = 26, + /** NNPACK does not support the particular convolution transform strategy for the algorithm */ + nnp_status_unsupported_transform_strategy = 27, + /** NNPACK does not support the particular activation function for the function */ + nnp_status_unsupported_activation = 28, + /** NNPACK does not support the particular activation function parameters for the function */ + nnp_status_unsupported_activation_parameters = 29, + + /** NNPACK function was called before the library was initialized */ + nnp_status_uninitialized = 50, + /** NNPACK does not implement this function for the host CPU */ + nnp_status_unsupported_hardware = 51, + /** NNPACK failed to allocate memory for temporary buffers */ + nnp_status_out_of_memory = 52, + /** Scratch space buffer is too small */ + nnp_status_insufficient_buffer = 53, + /** Scratch space buffer is not properly aligned */ + nnp_status_misaligned_buffer = 54 +}; + +/** + * @brief Activation applied applied after a convolutional or fully-connected layer. + */ +enum nnp_activation { + /** Identity activation f(x) := x, i.e. no transformation */ + nnp_activation_identity = 0, + /** ReLU activation f(x) := max(0, x) */ + nnp_activation_relu = 1, +}; + +/** + * @brief Algorithm for computing convolutional layers. + */ +enum nnp_convolution_algorithm { + /** Let NNPACK choose the algorithm depending on layer parameters */ + nnp_convolution_algorithm_auto = 0, + /** Tiled convolution based on 2D Fourier transform with 8x8 blocks. Supports kernels up to 8x8. */ + nnp_convolution_algorithm_ft8x8 = 1, + /** Tiled convolution based on 2D Fourier transform with 16x16 blocks. Supports kernels up to 16x16. */ + nnp_convolution_algorithm_ft16x16 = 2, + /** Tiled convolution based on 2D Winograd transform F(3x3, 6x6) with 8x8 blocks. Supports only 3x3 kernels. */ + nnp_convolution_algorithm_wt8x8 = 3, + /** Direct convolution via implicit GEMM. */ + nnp_convolution_algorithm_implicit_gemm = 4, + /** Direct convolution implementation. */ + nnp_convolution_algorithm_direct = 5, + /** + * Tiled convolution based on 2D Winograd transform F(3x3, 6x6) with 8x8 blocks in FP16. + * Supports only 3x3 kernels. Implemented only for new ARM processors (with NEON-HP), + * on non-supported processors falls back to nnp_convolution_algorithm_wt8x8. + */ + nnp_convolution_algorithm_wt8x8_fp16 = 6, +}; + +enum nnp_convolution_transform_strategy { + nnp_convolution_transform_strategy_compute = 1, + nnp_convolution_transform_strategy_precompute = 2, + nnp_convolution_transform_strategy_reuse = 3 +}; + +/* For backward compatibility */ +#define nnp_convolution_transform_strategy_block_based nnp_convolution_transform_strategy_compute +#define nnp_convolution_transform_strategy_tuple_based nnp_convolution_transform_strategy_compute + +/** + * @brief Size of images, kernels, and pooling filters in NNPACK. + */ +struct nnp_size { + /** Width (horizontal size) of an image, kernel, or pooling filter. */ + size_t width; + /** Height (vertical size) of an image, kernel, or pooling filter. */ + size_t height; +}; + +/** + * @brief Padding of images in NNPACK. + */ +struct nnp_padding { + /** Padding above the image data */ + size_t top; + /** Padding on the right of image data */ + size_t right; + /** Padding below the image data */ + size_t bottom; + /** Padding on the left of image data */ + size_t left; +}; + +/** + * @brief Profiling information about time spent in different phases of a function call. + */ +struct nnp_profile { + /** Time spent inside the function call, in seconds. */ + double total; + /** Time spend on transformation of the input or input gradient tensor, in seconds. */ + double input_transform; + /** Time spend on transformation of the kernel or kernel gradient tensor, in seconds. */ + double kernel_transform; + /** Time spend on transformation of the output or output gradient tensor, in seconds. */ + double output_transform; + /** Time spend on multiplication-accumulation of transformed coefficients, in seconds. */ + double block_multiplication; +}; + +enum nnp_status nnp_initialize(void); + +enum nnp_status nnp_deinitialize(void); + +/** + * @brief Computes output of a 2D convolutional layer from input and kernel tensors. + * @details This function targets training of convolutional neural networks and performs forward propagation. + * It is optimized for moderate minibatch sizes (64-128) and can be inefficient on a small minibatch. + * For minibatch size 1, use nnp_convolution_inference for optimal performance. + * @param algorithm The type of algorithm to use for convolution. Possible values are: + * + * - nnp_convolution_algorithm_auto -- let the function choose the algorithm. + * - nnp_convolution_algorithm_ft8x8 -- tiled convolution based on 2D Fourier transform with 8x8 blocks. + * Supports kernels up to 8x8. + * - nnp_convolution_algorithm_ft16x16 -- tiled convolution based on 2D Fourier transform with 16x16 blocks. + * Supports kernels up to 16x16. + * - nnp_convolution_algorithm_wt8x8 -- tiled convolution based on 2D Winograd transform F(3x3, 6x6). + * Supports only 3x3 kernels. + * + * @param batch_size The number of images on the input and output of the convolutional layer. + * @param input_channels The number of channels (AKA features, dimensions) in the input images. + * @param output_channels The number of channels (AKA features, dimensions) in the output images. + * @param input_size Size of input images, excluding implicit zero-padding. + * @param input_padding Implicit zero-padding of input images. + * @param kernel_size Kernel size. + * @param[in] input A 4D tensor input[batch_size][input_channels][input_size.height][input_size.width]. + * @param[in] kernel A 4D tensor kernel[output_channels][input_channels][kernel_size.height][kernel_size.width]. + * @param[in] bias A 1D array bias[output_channels]. + * @param[out] output A 4D tensor output[batch_size][output_channels][output_size.height][output_size.width] where + * output_size.height = (input_padding.top + input_size.height + input_padding.bottom) - + * (kernel_size.height - 1) + * output_size.width = (input_padding.left + input_size.width + input_padding.right) - + * (kernel_size.width - 1) + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + * @param[out] profile An optional pointer to profiling structure. + * If provided, the structure would record time spent in different phases of the computation. + */ + +enum nnp_status nnp_convolution_output( + enum nnp_convolution_algorithm algorithm, + size_t batch_size, + size_t input_channels, + size_t output_channels, + struct nnp_size input_size, + struct nnp_padding input_padding, + struct nnp_size kernel_size, + const float* input, + const float* kernel, + const float* bias, + float* output, + void* workspace_buffer, + size_t* workspace_size, + enum nnp_activation activation, + const void* activation_parameters, + pthreadpool_t threadpool, + struct nnp_profile* profile); + +/** + * @brief Computes gradient of input of a 2D convolutional layer from gradient of output and kernel tensors. + * @details This function targets training of convolutional neural networks and performs backward propagation. + * It is optimized for moderate minibatch sizes (64-128) and can be inefficient on a small minibatch. + * @param algorithm The type of algorithm to use for convolution. Possible values are: + * + * - nnp_convolution_algorithm_auto -- let the function choose the algorithm. + * - nnp_convolution_algorithm_ft8x8 -- tiled convolution based on 2D Fourier transform with 8x8 blocks. + * Supports kernels up to 8x8. + * - nnp_convolution_algorithm_ft16x16 -- tiled convolution based on 2D Fourier transform with 16x16 blocks. + * Supports kernels up to 16x16. + * - nnp_convolution_algorithm_wt8x8 -- tiled convolution based on 2D Winograd transform F(3x3, 6x6). + * Supports only 3x3 kernels. + * + * @param batch_size The number of images (and their gradients) on the input and output of the convolutional layer. + * @param input_channels The number of channels (AKA features, dimensions) in the input images (and gradients). + * @param output_channels The number of channels (AKA features, dimensions) in the output images (and gradients). + * @param input_size Size of input images and their gradients, excluding implicit zero-padding. + * @param input_padding Implicit zero-padding of input images. + * @param kernel_size Kernel size. + * @param[in] grad_output A 4D tensor grad_output[batch_size][output_channels][output_size.height][output_size.width] + * where + * output_size.height = (input_padding.top + input_size.height + input_padding.bottom) - + * (kernel_size.height - 1) + * output_size.width = (input_padding.left + input_size.width + input_padding.right) - + * (kernel_size.width - 1) + * @param[in] kernel A 4D tensor kernel[output_channels][input_channels][kernel_size.height][kernel_size.width]. + * @param[out] grad_input A 4D tensor grad_input[batch_size][input_channels][input_size.height][input_size.width]. + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + * @param[out] profile An optional pointer to profiling structure. + * If provided, the structure would record time spent in different phases of the computation. + */ +enum nnp_status nnp_convolution_input_gradient( + enum nnp_convolution_algorithm algorithm, + size_t batch_size, + size_t input_channels, + size_t output_channels, + struct nnp_size input_size, + struct nnp_padding input_padding, + struct nnp_size kernel_size, + const float* grad_output, + const float* kernel, + float* grad_input, + void* workspace_buffer, + size_t* workspace_size, + enum nnp_activation activation, + const void* activation_parameters, + pthreadpool_t threadpool, + struct nnp_profile* profile); + +/** + * @brief Computes gradient of kernel of a 2D convolutional layer from gradient of output and input tensors. + * @details This function targets training of convolutional neural networks and performs backward propagation. + * It is optimized for moderate minibatch sizes (64-128) and can be inefficient on a small minibatch. + * @param algorithm The type of algorithm to use for convolution. Possible values are: + * + * - nnp_convolution_algorithm_auto -- let the function choose the algorithm. + * - nnp_convolution_algorithm_ft8x8 -- tiled convolution based on 2D Fourier transform with 8x8 blocks. + * Supports kernels up to 8x8. + * - nnp_convolution_algorithm_ft16x16 -- tiled convolution based on 2D Fourier transform with 16x16 blocks. + * Supports kernels up to 16x16. + * + * @param batch_size The number of images (and their gradients) on the input and output of the convolutional layer. + * @param input_channels The number of channels (AKA features, dimensions) in the input images. + * @param output_channels The number of channels (AKA features, dimensions) in the output images (and gradients). + * @param input_size Size of input images and their gradients, excluding implicit zero-padding. + * @param input_padding Implicit zero-padding of input images. + * @param kernel_size Kernel size. + * @param[in] input A 4D tensor input[batch_size][input_channels][input_size.height][input_size.width]. + * @param[in] grad_output A 4D tensor grad_output[batch_size][output_channels][output_size.height][output_size.width] + * where + * output_size.height = (input_padding.top + input_size.height + input_padding.bottom) - + * (kernel_size.height - 1) + * output_size.width = (input_padding.left + input_size.width + input_padding.right) - + * (kernel_size.width - 1) + * @param[out] grad_kernel A 4D tensor + * grad_kernel[output_channels][input_channels][kernel_size.height][kernel_size.width]. + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + * @param[out] profile An optional pointer to profiling structure. + * If provided, the structure would record time spent in different phases of the computation. + */ +enum nnp_status nnp_convolution_kernel_gradient( + enum nnp_convolution_algorithm algorithm, + size_t batch_size, + size_t input_channels, + size_t output_channels, + struct nnp_size input_size, + struct nnp_padding input_padding, + struct nnp_size kernel_size, + const float* input, + const float* grad_output, + float* grad_kernel, + void* workspace_buffer, + size_t* workspace_size, + enum nnp_activation activation, + const void* activation_parameters, + pthreadpool_t threadpool, + struct nnp_profile* profile); + +/** + * @brief Computes output of a 2D convolutional layer for a single input image and a kernel tensor. + * @details This function targets prediction with convolutional neural networks and performs forward propagation. + * @param algorithm The type of algorithm to use for convolution. Possible values are: + * + * - nnp_convolution_algorithm_auto -- let the function choose the algorithm. + * - nnp_convolution_algorithm_ft8x8 -- tiled convolution based on 2D Fourier transform with 8x8 blocks. + * Supports kernels up to 8x8. + * - nnp_convolution_algorithm_ft16x16 -- tiled convolution based on 2D Fourier transform with 16x16 blocks. + * Supports kernels up to 16x16. + * - nnp_convolution_algorithm_wt8x8 -- tiled convolution based on 2D Winograd transform F(3x3, 6x6). + * Supports only 3x3 kernels. + * + * @param transform_strategy A strategy that guides computation of kernel transforms coefficients. + * Possible values are: + * + * - nnp_convolution_transform_strategy_block_based -- do multiplication-accumulations on blocks of transformed + * coefficients. + * - nnp_convolution_transform_strategy_tuple_based -- do multiplication-accumulations on tuples of transformed + * coefficients. + * + * @param input_channels The number of channels (AKA features, dimensions) in the input image. + * @param output_channels The number of channels (AKA features, dimensions) in the output image. + * @param input_size Size of input image, excluding implicit zero-padding. + * @param input_padding Implicit zero-padding of input image. + * @param kernel_size Kernel size. + * @param output_subsampling Subsample region for output, also known as convolution stride. + * @param[in] input A 3D tensor input[input_channels][input_size.height][input_size.width]. + * @param[in] kernel A 4D tensor kernel[output_channels][input_channels][kernel_size.height][kernel_size.width]. + * @param[in] bias A 1D array bias[output_channels]. + * @param[out] output A 3D tensor output[output_channels][output_size.height][output_size.width] where + * output_size.height = (input_padding.top + input_size.height + input_padding.bottom) - + * (kernel_size.height - 1) + * output_size.width = (input_padding.left + input_size.width + input_padding.right) - + * (kernel_size.width - 1) + * @param[in] workspace_buffer Buffer for scratch memory used during computation. Buffer must be aligned on 64 bytes. + * If workspace_buffer is NULL and workspace_size is non-NULL, NNPACK would store the size + * of required workspace memory at the workspace_size location, and exit without + * computations. + * If workspace_buffer is NULL and workspace_size is NULL, NNPACK would allocate memory + * before and deallocate after this computation, potentially at significant runtime cost. + * @param[in,out] workspace_size Pointer to the size of workspace buffer. + * If workspace_buffer is NULL, NNPACK will write the size of required scratch memory to + * the location specified by this pointer. + * If workspace_buffer is non-NULL, NNPACK expects workspace_size to specify the size of + * the buffer, in bytes. + * If workspace_size is NULL, workspace_buffer must be NULL as well. In this case NNPACK + * would allocate memory before and deallocate after this computation, potentially at + * significant runtime cost. + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + * @param[out] profile An optional pointer to profiling structure. + * If provided, the structure would record time spent in different phases of the computation. + */ +enum nnp_status nnp_convolution_inference( + enum nnp_convolution_algorithm algorithm, + enum nnp_convolution_transform_strategy transform_strategy, + size_t input_channels, + size_t output_channels, + struct nnp_size input_size, + struct nnp_padding input_padding, + struct nnp_size kernel_size, + struct nnp_size output_subsampling, + const float* input, + const float* kernel, + const float* bias, + float* output, + void* workspace_buffer, + size_t* workspace_size, + enum nnp_activation activation, + const void* activation_parameters, + pthreadpool_t threadpool, + struct nnp_profile* profile); + +/** + * @brief Computes output of a fully connected layer from input and kernel matrices. + * @details This function targets training of convolutional neural networks and performs forward propagation. + * It is optimized for moderate minibatch sizes (64-128) and can be inefficient on a small minibatch. + * For minibatch size 1, use nnp_fully_connected_inference for optimal performance. + * @param batch_size The number of vectors on the input and output of the fully connected layer. + * @param input_channels The number of channels (AKA features, dimensions) in the input matrix. + * @param output_channels The number of channels (AKA features, dimensions) in the output matrix. + * @param[in] input A 2D matrix input[batch_size][input_channels]. + * @param[in] kernel A 2D matrix kernel[output_channels][input_channels]. + * @param[out] output A 2D matrix output[batch_size][output_channels]. + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + */ +enum nnp_status nnp_fully_connected_output( + size_t batch_size, + size_t input_channels, + size_t output_channels, + const float input[], + const float kernel[], + float output[], + pthreadpool_t threadpool, + struct nnp_profile* profile); + +/** + * @brief Computes output of a fully connected layer for a single input vector and a kernel matrix. + * @details This function targets prediction with convolutional neural networks and performs forward propagation. + * @param input_channels The number of channels (AKA features, dimensions) in the input vector. + * @param output_channels The number of channels (AKA features, dimensions) in the output vector. + * @param[in] input A 1D array input[input_channels] of FP32 elements. + * @param[in] kernel A 2D matrix kernel[output_channels][input_channels] of FP32 elements. + * @param[out] output A 1D array output[output_channels] of FP32 elements. + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + */ +enum nnp_status nnp_fully_connected_inference( + size_t input_channels, + size_t output_channels, + const float* input, + const float* kernel, + float* output, + pthreadpool_t threadpool); + +/** + * @brief Computes output of a fully connected layer for a single input vector and a kernel matrix. + * @details This function targets prediction with convolutional neural networks and performs forward propagation. + * @param input_channels The number of channels (AKA features, dimensions) in the input vector. + * @param output_channels The number of channels (AKA features, dimensions) in the output vector. + * @param[in] input A 1D array input[input_channels] of FP32 elements. + * @param[in] kernel A 2D matrix kernel[output_channels][input_channels] of FP16 (ARM alternative format) elements. + * @param[out] output A 1D array output[output_channels] of FP32 elements. + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + */ +enum nnp_status nnp_fully_connected_inference_f16f32( + size_t input_channels, + size_t output_channels, + const float* input, + const void* kernel, + float* output, + pthreadpool_t threadpool); + +/** + * @brief Computes output of a max-pooling layer for an input tensor. + * @details This function targets both prediction and training of convolutional neural networks and performs forward + * propagation. Is is optimized for both large and small minibatch sizes. + * @param batch_size The number of images on the input and output of the max-pooling layer. + * @param channels The number of channels (AKA features, dimensions) in both input and output images. + * @param input_size Size of input images, excluding implicit zero-padding. + * @param input_padding Implicit padding of input images. The padding pixels are ignored by the pooling filter, but + * affect the output size. + * @param pooling_size Size of the pooling filter. Only 2x2 filter are currently supported. + * @param pooling_stride Stride of the pooling filter. Only 2x2 strides are currently supported. + * @param[in] input A 4D tensor input[batch_size][channels][input_size.height][input_size.width]. + * @param[out] output A 4D tensor output[batch_size][channels][output_size.height][output_size.width] where + * output_size.height = ceil( + * (input_padding.top + input_size.height + input_padding.bottom - pooling_size.height) / + * pooling_stride.height) + 1 + * output_size.width = ceil( + * (input_padding.left + input_size.width + input_padding.right - pooling_size.width) / + * pooling_stride.width) + 1 + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + */ +enum nnp_status nnp_max_pooling_output( + size_t batch_size, + size_t channels, + struct nnp_size input_size, + struct nnp_padding input_padding, + struct nnp_size pooling_size, + struct nnp_size pooling_stride, + const float input[], + float output[], + pthreadpool_t threadpool); + +/** + * @brief Computes output of a softmax layer for an input matrix. + * @details This function targets both prediction and training of convolutional neural networks and performs forward + * propagation. Is is optimized for both large and small minibatch sizes. + * @param batch_size The number of vectors on the input and output of the softmax layer. + * @param channels The number of channels (AKA features, dimensions) in both input and output vectors. + * @param[in] input A 2D matrix input[batch_size][channels]. + * @param[out] output A 2D matrix output[batch_size][channels]. + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + */ +enum nnp_status nnp_softmax_output( + size_t batch_size, + size_t channels, + const float input[], + float output[], + pthreadpool_t threadpool); + +/** + * @brief Computes output of a rectified linear unit (ReLU) layer for an input matrix. + * @details This function targets both prediction and training of convolutional neural networks and performs forward + * propagation. Is is optimized for both large and small minibatch sizes. + * @param batch_size The number of vectors on the input and output of the ReLU layer. + * @param channels The number of channels (AKA features, dimensions) in both input and output matrices. + * @param[in] input A 2D matrix input[batch_size][channels]. + * @param[out] output A 2D matrix output[batch_size][channels]. + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + */ +enum nnp_status nnp_relu_output( + size_t batch_size, + size_t channels, + const float input[], + float output[], + float negative_slope, + pthreadpool_t threadpool); + +/** + * @brief Computes gradient of input of a rectified linear unit (ReLU) layer from gradient of output and input matrices. + * @details This function targets training of convolutional neural networks and performs backward propagation. + * Is is optimized for both large and small minibatch sizes. + * @param batch_size The number of vectors on the input and output of the ReLU layer. + * @param channels The number of channels (AKA features, dimensions) in both input and output matrices. + * @param[in] input A 2D matrix input[batch_size][channels]. + * @param[out] output A 2D matrix output[batch_size][channels]. + * @param threadpool A thread pool for parallelization of the computation. + * If threadpool is NULL, the computation would run on the caller thread without parallelization. + */ +enum nnp_status nnp_relu_input_gradient( + size_t batch_size, + size_t channels, + const float grad_output[], + const float input[], + float grad_input[], + float negative_slope, + pthreadpool_t threadpool); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus +// Backward compatible implementations for nnp_convolution_*, if we are in C++ +// mode. +inline enum nnp_status nnp_convolution_output( + enum nnp_convolution_algorithm algorithm, + size_t batch_size, + size_t input_channels, + size_t output_channels, + struct nnp_size input_size, + struct nnp_padding input_padding, + struct nnp_size kernel_size, + const float input[], + const float kernel[], + const float bias[], + float output[], + pthreadpool_t threadpool, + struct nnp_profile* profile) +{ + return nnp_convolution_output( + algorithm, + batch_size, input_channels, output_channels, + input_size, input_padding, kernel_size, + input, kernel, bias, output, + NULL, NULL, + nnp_activation_identity, NULL, threadpool, profile); +} + +inline enum nnp_status nnp_convolution_input_gradient( + enum nnp_convolution_algorithm algorithm, + size_t batch_size, + size_t input_channels, + size_t output_channels, + struct nnp_size input_size, + struct nnp_padding input_padding, + struct nnp_size kernel_size, + const float grad_output[], + const float kernel[], + float grad_input[], + pthreadpool_t threadpool, + struct nnp_profile* profile) +{ + return nnp_convolution_input_gradient( + algorithm, + batch_size, input_channels, output_channels, + input_size, input_padding, kernel_size, + grad_output, kernel, grad_input, + NULL, NULL, + nnp_activation_identity, NULL, threadpool, profile); +} + +inline enum nnp_status nnp_convolution_kernel_gradient( + enum nnp_convolution_algorithm algorithm, + size_t batch_size, + size_t input_channels, + size_t output_channels, + struct nnp_size input_size, + struct nnp_padding input_padding, + struct nnp_size kernel_size, + const float input[], + const float grad_output[], + float grad_kernel[], + pthreadpool_t threadpool, + struct nnp_profile* profile) +{ + return nnp_convolution_kernel_gradient( + algorithm, + batch_size, input_channels, output_channels, + input_size, input_padding, kernel_size, + input, grad_output, grad_kernel, + NULL, NULL, + nnp_activation_identity, NULL, threadpool, profile); +} + +inline enum nnp_status nnp_convolution_inference( + enum nnp_convolution_algorithm algorithm, + enum nnp_convolution_transform_strategy transform_strategy, + size_t input_channels, + size_t output_channels, + struct nnp_size input_size, + struct nnp_padding input_padding, + struct nnp_size kernel_size, + struct nnp_size output_subsampling, + const float input[], + const float kernel[], + const float bias[], + float output[], + pthreadpool_t threadpool, + struct nnp_profile* profile) { + return nnp_convolution_inference( + algorithm, transform_strategy, + input_channels, output_channels, + input_size, input_padding, kernel_size, output_subsampling, + input, kernel, bias, output, NULL, NULL, + nnp_activation_identity, NULL, + threadpool, profile); +} + +#endif // __cplusplus + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.h new file mode 100644 index 0000000000000000000000000000000000000000..1d944da46c10e4c017273511e2d6e608e8fd9284 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.h @@ -0,0 +1,4236 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// C API + +#ifndef ONEAPI_DNNL_DNNL_H +#define ONEAPI_DNNL_DNNL_H + +#include "oneapi/dnnl/dnnl_common.h" +#include "oneapi/dnnl/dnnl_config.h" +#include "oneapi/dnnl/dnnl_types.h" +#include "oneapi/dnnl/dnnl_version.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_api_primitives +/// @{ + +/// @addtogroup dnnl_api_primitives_common +/// @{ + +/// Changes the primitive descriptor to point to the next available +/// implementation. +/// +/// @param primitive_desc A primitive descriptor to change. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +/// @returns #dnnl_last_impl_reached if no more implementations available, +/// in which case the primitive descriptor itself is kept unchanged. +dnnl_status_t DNNL_API dnnl_primitive_desc_next_impl( + dnnl_primitive_desc_t primitive_desc); + +/// Clones a primitive descriptor. The resulting primitive descriptor must be +/// destroyed separately. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param existing_primitive_desc Primitive descriptor to clone. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_desc_clone( + dnnl_primitive_desc_t *primitive_desc, + const_dnnl_primitive_desc_t existing_primitive_desc); + +/// Returns a constant reference to the attributes of a primitive descriptor. +/// +/// @warning +/// It is an error to destroy the resulting @p attr. +/// +/// @warning +/// The lifetime of an @p attr is the same as that of a @p +/// primitive_desc, so it is an error to use the @p attr once the @p +/// primitive_desc has been destroyed. +/// +/// @param primitive_desc Primitive descriptor. +/// @param attr Output primitive attributes. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_desc_get_attr( + const_dnnl_primitive_desc_t primitive_desc, + const_dnnl_primitive_attr_t *attr); + +/// Destroys a primitive descriptor. +/// +/// @param primitive_desc Primitive descriptor to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_desc_destroy( + dnnl_primitive_desc_t primitive_desc); + +/// Queries a primitive descriptor for various pieces of information. +/// +/// The most common use case is to query a primitive descriptor, created with +/// source, weights, and destination memory descriptors with format tags set +/// to #dnnl_format_tag_any, for the corresponding memory descriptors (in this +/// case the @p what is set to #dnnl_query_src_md, #dnnl_query_weights_md, and +/// #dnnl_query_dst_md respectively) so that it is possible to create memory +/// objects and reorder primitives if necessary. +/// +/// Another typical use case is to query a primitive descriptor for workspace +/// memory descriptor (with @p what set to #dnnl_query_workspace_md). If this +/// query returns #dnnl_not_required status, then workspace memory is not +/// required. +/// +/// @note +/// When querying for a memory descriptor for a scratchpad, a workspace, +/// or an optional parameter, the query will return a pointer to a zero +/// memory descriptor if the parameter is not needed. +/// +/// A few other use cases: +/// - query a primitive descriptor for the implementation information string +/// (#dnnl_query_impl_info_str) +/// - query a primitive descriptor for the number of inputs and outputs +/// (#dnnl_query_num_of_inputs_s32 and #dnnl_query_num_of_outputs_s32 +/// respectively) +/// +/// @sa dnnl_query_t for more options +/// +/// @param primitive_desc Primitive descriptor. +/// @param what Parameter to query. +/// @param index Index of the parameter to query for. +/// @param result Output result. The type depends on the query. For example, +/// it must be a @c dnnl_memory_desc_t* if querying for a memory +/// descriptor. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_desc_query( + const_dnnl_primitive_desc_t primitive_desc, dnnl_query_t what, + int index, void *result); + +/// Queries primitive descriptor for a memory descriptor. +/// +/// @note +/// This function is a convenience version of +/// #dnnl_primitive_desc_query(). +/// +/// @param primitive_desc Primitive descriptor. +/// @param what Kind of memory descriptor parameter to query for. +/// @param index Index of the parameter to query. +/// @returns A pointer to the requested memory descriptor. +/// @returns A pointer to a zero memory descriptor if the parameter is not +/// needed. +/// @returns NULL in case of any error. +/// +const_dnnl_memory_desc_t DNNL_API dnnl_primitive_desc_query_md( + const_dnnl_primitive_desc_t primitive_desc, dnnl_query_t what, + int index); + +/// Queries primitive descriptor for a signed 32bit int. +/// +/// @note +/// This function is a convenience version of +/// #dnnl_primitive_desc_query(). +/// +/// @param primitive_desc Primitive descriptor. +/// @param what Kind of the value to query for. +/// @param index Index of the parameter to query. +/// @returns The requested value. +/// @returns 0 in case of any error (in particular if the queried entity is +/// not of type int32_t). Note that 0 may also be the actual returned +/// value. +int DNNL_API dnnl_primitive_desc_query_s32( + const_dnnl_primitive_desc_t primitive_desc, dnnl_query_t what, + int index); + +/// Creates a primitive. +/// +/// @param primitive Output primitive. +/// @param primitive_desc Primitive descriptor used to create the primitive. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_create(dnnl_primitive_t *primitive, + const_dnnl_primitive_desc_t primitive_desc); + +/// Creates a primitive from a cache blob. +/// +/// @param primitive Output primitive. +/// @param primitive_desc Primitive descriptor used to create the primitive. +/// @param size Size of the cache blob in bytes. +/// @param cache_blob Cache blob of size @p size. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_create_from_cache_blob( + dnnl_primitive_t *primitive, const_dnnl_primitive_desc_t primitive_desc, + size_t size, const uint8_t *cache_blob); + +/// Executes a primitive. +/// +/// @param primitive Primitive to execute. +/// @param stream Stream to use. +/// @param nargs Number of arguments. +/// @param args Array of arguments. Each argument is an +/// pair. The index is one of the `DNNL_ARG_*` +/// values such as `DNNL_ARG_SRC`. Unless runtime shapes are used (see +/// #DNNL_RUNTIME_DIM_VAL), the memory object must have the same memory +/// descriptor as that returned by +/// #dnnl_primitive_desc_query_md(#dnnl_query_exec_arg_md, index). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. + +/// @note If any argument in @p args is padded (padded_dims > +/// dims), the primitive execution will assume properly zero-padded +/// input arguments, and produce zero-padded output arguments. +dnnl_status_t DNNL_API dnnl_primitive_execute(const_dnnl_primitive_t primitive, + dnnl_stream_t stream, int nargs, const dnnl_exec_arg_t *args); + +/// Retrieves a constant reference to the primitive descriptor of a given +/// primitive. +/// +/// @warning +/// It is an error to destroy the returned object. It is owned by the +/// primitive. The @c const qualifier of the returned object prevents +/// such attempts. +/// +/// @param primitive Primitive to query for the primitive descriptor. +/// @param primitive_desc Output primitive descriptor. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_get_primitive_desc( + const_dnnl_primitive_t primitive, + const_dnnl_primitive_desc_t *primitive_desc); + +/// Retrieves a cache blob associated with the given primitive. +/// +/// @param primitive Primitive to query for the cache blob. +/// @param size Size of the cache blob in bytes. +/// @param cache_blob Cache blob of size @p size. If the @p cache_blob is +/// nullptr then the size of the cache blob is returned in @p size. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +/// +/// @note The cache blob can be empty. It's the user's responsibility to check +/// whether it's empty prior to passing it to +/// #dnnl_primitive_create_from_cache_blob(). +dnnl_status_t DNNL_API dnnl_primitive_get_cache_blob( + const_dnnl_primitive_t primitive, size_t *size, uint8_t *cache_blob); + +/// Destroys a primitive. +/// +/// @param primitive The primitive to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_destroy(dnnl_primitive_t primitive); + +/// @} dnnl_api_primitives_common + +/// @addtogroup dnnl_api_attributes +/// @{ + +/// Creates an empty (default) primitive attributes with all the parameters +/// set to their default values. +/// +/// Empty attributes are implied whenever the respective argument is NULL. +/// +/// @param attr Output primitive attributes. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_create(dnnl_primitive_attr_t *attr); + +/// Clones primitive attributes. +/// +/// @param attr Output primitive attributes. +/// @param existing_attr Primitive attributes to clone. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_clone( + dnnl_primitive_attr_t *attr, const_dnnl_primitive_attr_t existing_attr); + +/// Destroys primitive attributes. +/// +/// @param attr Primitive attributes to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_destroy(dnnl_primitive_attr_t attr); + +/// Gets dropout primitive attribute. +/// +/// @param attr Primitive attributes. +/// @param mask_desc Output memory descriptor for dropout masks. If a default +/// memory descriptor is returned, the mask values will not be written to +/// the output memory buffer during the primitive execution. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_dropout( + const_dnnl_primitive_attr_t attr, const_dnnl_memory_desc_t *mask_desc); + +/// Sets dropout primitive attribute. +/// +/// @param attr Primitive attributes. +/// @param mask_desc Memory descriptor for dropout masks. If a default memory +/// descriptor is passed, the mask values will not be written to the output +/// memory buffer during the primitive execution. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_dropout( + dnnl_primitive_attr_t attr, const_dnnl_memory_desc_t mask_desc); + +/// Gets dropout primitive attribute parameters. +/// +/// @param attr Primitive attributes. +/// @param mask_desc Output memory descriptor for dropout masks. If a default +/// memory descriptor is returned, the mask values will not be written to +/// the output memory buffer during the primitive execution. +/// @param seed_dt Output datatype for seed argument. +/// @param use_offset Output boolean. If true, an offset argument must be passed +/// at the execution and will be used in random number generation. +/// @param use_host_scalars Output boolean. If true, probability, seed and +/// offset arguments are passed as host_scalar memory objects. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_dropout_v2( + const_dnnl_primitive_attr_t attr, const_dnnl_memory_desc_t *mask_desc, + dnnl_data_type_t *seed_dt, int *use_offset, int *use_host_scalars); + +/// Sets dropout primitive attribute parameters. +/// +/// @param attr Primitive attributes. +/// @param mask_desc Memory descriptor for dropout masks. If a default memory +/// descriptor is passed, the mask values will not be written to the output +/// memory buffer during the primitive execution. +/// @param seed_dt Datatype for seed argument. +/// @param use_offset If true, an offset argument must be passed at the +/// execution and will be used in random number generation. +/// @param use_host_scalars If true, probability, seed and offset arguments are +/// passed as host_scalar memory objects. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_dropout_v2( + dnnl_primitive_attr_t attr, const_dnnl_memory_desc_t mask_desc, + dnnl_data_type_t seed_dt, int use_offset, int use_host_scalars); + +/// Returns the floating-point math mode primitive attribute. +/// +/// @param attr Primitive attributes. +/// @param mode Output FP math mode. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_fpmath_mode( + const_dnnl_primitive_attr_t attr, dnnl_fpmath_mode_t *mode); + +/// Sets the floating-point math mode primitive attributes. +/// +/// @param attr Primitive attributes. +/// @param mode FP math mode. The possible values are: +/// #dnnl_fpmath_mode_strict (default), +/// #dnnl_fpmath_mode_bf16, +/// #dnnl_fpmath_mode_f16, +/// #dnnl_fpmath_mode_tf32, +/// #dnnl_fpmath_mode_any. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_fpmath_mode( + dnnl_primitive_attr_t attr, dnnl_fpmath_mode_t mode); + +/// Returns the floating-point math mode primitive attribute. +/// +/// @param attr Primitive attributes. +/// @param mode Output FP math mode. +/// @param apply_to_int Output use floating-point arithmetic for integer primitives. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_fpmath_mode_v2( + const_dnnl_primitive_attr_t attr, dnnl_fpmath_mode_t *mode, + int *apply_to_int); + +/// Sets the floating-point math mode primitive attributes. +/// +/// @param attr Primitive attributes. +/// @param mode FP math mode. The possible values are: +/// #dnnl_fpmath_mode_strict (default), +/// #dnnl_fpmath_mode_bf16, +/// #dnnl_fpmath_mode_f16, +/// #dnnl_fpmath_mode_tf32, +/// #dnnl_fpmath_mode_any. +/// @param apply_to_int Boolean. Use of floating-point arithmetic for integer primitives. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_fpmath_mode_v2( + dnnl_primitive_attr_t attr, dnnl_fpmath_mode_t mode, int apply_to_int); + +/// Returns the deterministic primitive attribute value. +/// +/// @param attr Primitive attributes. +/// @param value Output deterministic attribute value +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_deterministic( + const_dnnl_primitive_attr_t attr, int *value); + +/// Sets the deterministic primitive attribute value. +/// +/// @param attr Primitive attributes. +/// @param value Boolean value to set deterministic attribute. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_deterministic( + dnnl_primitive_attr_t attr, int value); + +/// Returns the accumulation mode primitive attribute. +/// +/// @param attr Primitive attributes. +/// @param mode Output accumulation mode. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_accumulation_mode( + const_dnnl_primitive_attr_t attr, dnnl_accumulation_mode_t *mode); + +/// Sets the accumulation mode primitive attribute. +/// +/// @param attr Primitive attributes. +/// @param mode Accumulation mode. The possible values are: +/// #dnnl_accumulation_mode_strict (default), which is s32 for quantized primitives, f32/f64 otherwise +/// #dnnl_accumulation_mode_relaxed, which is same as strict but allows intermediate accumulators to be in src/dst datatype +/// #dnnl_accumulation_mode_any, which allows accumulators to be src/dst datatype or any wider type. +/// #dnnl_accumulation_mode_f32, +/// #dnnl_accumulation_mode_s32, +/// #dnnl_accumulation_mode_f16. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_accumulation_mode( + dnnl_primitive_attr_t attr, dnnl_accumulation_mode_t mode); + +/// Returns the primitive attributes scratchpad mode. +/// +/// @param attr Primitive attributes. +/// @param mode Output scratchpad mode. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_scratchpad_mode( + const_dnnl_primitive_attr_t attr, dnnl_scratchpad_mode_t *mode); + +/// Sets primitive attributes scratchpad mode. +/// +/// @param attr Primitive attributes. +/// @param mode Scratchpad mode. The possible values are: +/// #dnnl_scratchpad_mode_library (default) and +/// #dnnl_scratchpad_mode_user. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_scratchpad_mode( + dnnl_primitive_attr_t attr, dnnl_scratchpad_mode_t mode); + +/// Sets primitive attributes scaling factors for primitive operations for a +/// given memory argument. The scaling factors must be passed at execution time +/// as an argument with index #DNNL_ARG_ATTR_SCALES | arg. +/// +/// @sa dnnl_primitive_attr_set_scales_mask +/// +/// +/// @param attr Primitive attributes. +/// @param arg Parameter argument index as passed to the +/// dnnl_primitive_execute() call. +/// @param mask Scaling factors correspondence mask that defines the +/// correspondence between the tensor dimensions and the @p scales array. +/// The set i-th bit indicates that a dedicated scaling factor is used for +/// each index along that dimension. Set the mask to 0 to use a common +/// scaling factor for the whole output tensor. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_scales_mask( + dnnl_primitive_attr_t attr, int arg, int mask); + +/// Sets primitive attributes scaling factors for primitive operations for a +/// given memory argument. The scaling factors must be passed at execution time +/// as an argument with index #DNNL_ARG_ATTR_SCALES | arg. +/// +/// @sa dnnl_primitive_attr_set_scales +/// +/// +/// @param attr Primitive attributes. +/// @param arg Parameter argument index as passed to the +/// dnnl_primitive_execute() call. +/// @param mask Scaling factors correspondence mask that defines the +/// correspondence between the tensor dimensions and the @p scales array. +/// The set i-th bit indicates that a dedicated scaling factor is used for +/// each index along that dimension. Set the mask to 0 to use a common +/// scaling factor for the whole output tensor. +/// @param group_ndims Number of group dimensions. +/// @param group_dims Scaling factors correspondence groups that define the +/// correspondence between the tensor dimensions and the scales array. +/// The group dimensions should only be provided for each logical dimension +/// that has correspondence mask @p mask set. +/// @param data_type Scaling factors data_type. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_scales( + dnnl_primitive_attr_t attr, int arg, int mask, int group_ndims, + const dnnl_dims_t group_dims, dnnl_data_type_t data_type); + +/// Sets primitive attributes scaling factors for primitive operations for a +/// given memory argument. The scaling factors must be passed at execution time +/// as an argument with index #DNNL_ARG_ATTR_SCALES | arg. +/// If `is_on_host` is true, sets a single host-side scalar scaling factor +/// for the specified memory argument. In this case, the scaling factor must +/// be provided as a host scalar memory object at execution time with index +/// #DNNL_ARG_ATTR_SCALES | arg. +/// +/// @sa dnnl_primitive_attr_set_scales +/// +/// +/// @param attr Primitive attributes. +/// @param arg Parameter argument index as passed to the +/// dnnl_primitive_execute() call. +/// @param mask Scaling factors correspondence mask that defines the +/// correspondence between the tensor dimensions and the @p scales array. +/// The set i-th bit indicates that a dedicated scaling factor is used for +/// each index along that dimension. Set the mask to 0 to use a common +/// scaling factor for the whole output tensor. +/// @param ndims Number of group dimensions. +/// @param group_dims Scaling factors correspondence groups that define the +/// correspondence between the tensor dimensions and the scales array. +/// The group dimensions should only be provided for each logical dimension +/// that has correspondence mask @p mask set. +/// @param data_type Scaling factors data_type. +/// @param is_on_host Indicates whether the zero point is a host-side scalar. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_scales_v2( + dnnl_primitive_attr_t attr, int arg, int mask, int ndims, + const dnnl_dims_t group_dims, dnnl_data_type_t data_type, + int is_on_host); + +/// Sets primitive attributes scaling factors for primitive operations for a +/// given memory argument. The scaling factors must be passed at execution time +/// as an argument with index #DNNL_ARG_ATTR_SCALES | arg. +/// @sa dnnl_primitive_attr_set_scales +/// +/// @param attr Primitive attributes. +/// @param arg Parameter argument index as passed to the +/// dnnl_primitive_execute() call. +/// @param mask Scaling factors correspondence mask that defines the +/// correspondence between the tensor dimensions and the @p scales array. +/// The set i-th bit indicates that a dedicated scaling factor is used for +/// each index along that dimension. Set the mask to 0 to use a common +/// scaling factor for the whole tensor. +/// @param ndims Number of group dimensions. +/// @param group_dims Scaling factors correspondence groups that define the +/// correspondence between the tensor dimensions and the scales array. +/// The group dimensions should only be provided for each logical dimension +/// that has correspondence mask @p mask set. +/// @param data_type Scaling factors data_type. +/// @param is_on_host Indicates whether the scale is a host-side scalar. +/// @param qmode Quantization mode, can be #dnnl_quantization_mode_static_sazp +/// or #dnnl_quantization_mode_dynamic_mx +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_scales_v3( + dnnl_primitive_attr_t attr, int arg, int mask, int ndims, + const dnnl_dims_t group_dims, dnnl_data_type_t data_type, + int is_on_host, dnnl_quantization_mode_t qmode); + +/// Sets primitive attributes zero points for primitive operations for a given +/// memory argument. The zero points must be passed at execution time +/// as an argument with index #DNNL_ARG_ATTR_ZERO_POINTS | arg. +/// +/// @param attr Primitive attributes. +/// @param arg Parameter argument index as passed to the +/// dnnl_primitive_execute() call. +/// @param mask Zero point correspondence mask that defines the +/// correspondence between the tensor dimensions and the @p +/// zero_points array. The set i-th bit indicates that a dedicated +/// zero point is used for each index along that dimension. Set the +/// mask to 0 to use a common zero point for the whole output tensor. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_zero_points_mask( + dnnl_primitive_attr_t attr, int arg, int mask); + +/// Sets primitive attributes zero points for primitive operations for a given +/// memory argument. The zero points must be passed at execution time +/// as an argument with index #DNNL_ARG_ATTR_ZERO_POINTS | arg. +/// +/// @sa dnnl_primitive_attr_set_zero_points +/// +/// +/// @param attr Primitive attributes. +/// @param arg Parameter argument index as passed to the +/// dnnl_primitive_execute() call. +/// @param mask Zero point correspondence mask that defines the +/// correspondence between the tensor dimensions and the +/// zero points array. The set i-th bit indicates that a dedicated +/// zero point is used for each index along that dimension. Set the +/// mask to 0 to use a common zero point for the whole output tensor. +/// @param group_ndims Number of group dimensions. +/// @param group_dims Zero point factors correspondence groups that define the +/// correspondence between the tensor dimensions and the zero points array. +/// The group dimensions should be only provided for each logical dimension +/// that has the bit set correspondence mask @p mask set. +/// @param data_type Zero points factors data_type. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_zero_points( + dnnl_primitive_attr_t attr, int arg, int mask, int group_ndims, + const dnnl_dims_t group_dims, dnnl_data_type_t data_type); + +/// Sets primitive attributes precomputed reductions for primitive operations +/// for a given memory argument. The precomputed reductions must be passed at +/// execution time as an argument with index +/// #DNNL_ARG_ATTR_PRECOMPUTED_REDUCTIONS | arg. +/// +/// @sa dnnl_primitive_attr_set_precomputed_reductions +/// +/// +/// @param attr Primitive attributes. +/// @param arg Parameter argument index as passed to the +/// dnnl_primitive_execute() call. +/// @param mask Precomputed reductions correspondence mask that defines the +/// correspondence between the tensor dimensions and the precomputed +/// reductions array. The set i-th bit indicates that a dedicated +/// precomputed reductions is used for each index along that dimension. +/// @param group_ndims Number of group dimensions. +/// @param group_dims Precomputed reduction factors correspondence groups that +/// define the correspondence between the tensor dimensions and the +/// precomputed reductions array. +/// The group dimensions should be only provided for each logical dimension +/// that has the bit set correspondence mask @p mask set. +/// @param data_type Precomputed reduction factors data_type. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_precomputed_reductions( + dnnl_primitive_attr_t attr, int arg, int mask, int group_ndims, + const dnnl_dims_t group_dims, dnnl_data_type_t data_type); + +/// Sets primitive attributes zero points for primitive operations for a given +/// memory argument. The zero points must be passed at execution time +/// as an argument with index #DNNL_ARG_ATTR_ZERO_POINTS | arg. +/// If `is_on_host` is true, sets a single host-side scalar zero point +/// for the specified memory argument. In this case, the zero point must +/// be provided as a host scalar memory object at execution time with index +/// #DNNL_ARG_ATTR_ZERO_POINTS | arg. +/// +/// @sa dnnl_primitive_attr_set_zero_points +/// +/// @param attr Primitive attributes. +/// @param arg Parameter argument index as passed to the +/// dnnl_primitive_execute() call. +/// @param mask Zero point correspondence mask that defines the +/// correspondence between the tensor dimensions and the @p +/// zero_points array. The set i-th bit indicates that a dedicated +/// zero point is used for each index along that dimension. Set the +/// mask to 0 to use a common zero point for the whole output tensor. +/// @param ndims Number of group dimensions. +/// @param group_dims Zero point factors correspondence groups that define the +/// correspondence between the tensor dimensions and the zero_points array. +/// The group dimensions should be only provided for each logical dimension +/// that has the bit set correspondence mask @p mask set. +/// @param data_type Zero points factors data_type. +/// @param is_on_host Indicates whether the zero point is a host-side scalar. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_zero_points_v2( + dnnl_primitive_attr_t attr, int arg, int mask, int ndims, + const dnnl_dims_t group_dims, dnnl_data_type_t data_type, + int is_on_host); + +/// Sets the rounding mode attribute value for a given argument +/// +/// @param attr Primitive attributes. +/// @param arg Argument for which rounding mode should be set. +/// @param mode Rounding mode to apply to the argument. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_rounding( + dnnl_primitive_attr_t attr, int arg, dnnl_rounding_mode_t mode); + +/// Returns the rounding mode attribute value for a given argument +/// +/// @param attr Primitive attributes. +/// @param arg Argument for which rounding mode query applies. +/// @param mode Output rounding mode. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_rounding( + dnnl_primitive_attr_t attr, int arg, dnnl_rounding_mode_t *mode); + +/// Returns primitive attributes post-ops. +/// +/// @warning +/// The output @p post_ops points to the internal @p attr field, so it is +/// an error to modify or destroy them. The lifetime of @p post_ops is +/// the same as that of the @p attr it belongs to, so it is an error to +/// use @p post_ops after @p attr has been destroyed. +/// +/// @param attr Primitive attributes. +/// @param post_ops Output post-ops. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_post_ops( + const_dnnl_primitive_attr_t attr, const_dnnl_post_ops_t *post_ops); + +/// Sets primitive attributes post-ops. +/// +/// @note +/// There is no way to check whether the post-ops would be supported by +/// the target primitive. Any error will be reported by the +/// dnnl__[propagation kind]_primitive_desc_create() function call. +/// +/// @param attr Primitive attributes. +/// @param post_ops Post-ops to set. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_post_ops( + dnnl_primitive_attr_t attr, const_dnnl_post_ops_t post_ops); + +/// Creates empty post-ops sequence. +/// +/// @param post_ops Output post-ops. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_create(dnnl_post_ops_t *post_ops); + +/// Clones post-ops primitive attribute. +/// +/// @param post_ops Output post-ops primitive attribute. +/// @param existing_post_ops Post-ops primitive attribute to clone. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_clone( + dnnl_post_ops_t *post_ops, const_dnnl_post_ops_t existing_post_ops); + +/// Destroys post-ops. +/// +/// @param post_ops Post-ops to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_destroy(dnnl_post_ops_t post_ops); + +/// Returns the length of post-ops. +/// +/// @param post_ops Post-ops. +/// @returns The number of post-ops entries. +int DNNL_API dnnl_post_ops_len(const_dnnl_post_ops_t post_ops); + +/// Returns the kind of a post-op entry. +/// +/// @param post_ops Post-ops. +/// @param index Post-op entry index. +/// @returns The kind of the post-op with the specified index. +/// @returns #dnnl_undefined_primitive if there is no post-op at the specified +/// index. +dnnl_primitive_kind_t DNNL_API dnnl_post_ops_get_kind( + const_dnnl_post_ops_t post_ops, int index); + +/// Appends an accumulation v3 (sum) to post-ops. Prior to accumulating the +/// result, a zero point is subtracted from the previous value and is +/// multiplied by the scale. +/// +/// The kind of this post-op is #dnnl_sum. +/// +/// This feature may improve performance for cases like dequantize the +/// asymmetrically quantized sum's src1 tensor to f32 domain before performing +/// the sum operation by subtracting the @p zero_point before the scaling. +/// +/// In the simplest case where accumulation is the only post-op, the +/// computations will be: +/// +/// dst[:] <- scale * (dst[:] - zero_point) + op(...) +/// // instead of dst[:] <- op(...) +/// +/// If @p data_type is specified, original dst tensor will be reinterpreted +/// as a tensor with provided data type. Since it is reinterpretation, +/// data_type and dst data type should have the same size. +/// As a result, computations will be: +/// +/// dst[:] <- scale * (as_data_type(dst[:]) - zero_point) + op(...) +/// // instead of dst[:] <- op(...) +/// @note +/// This post-op executes in-place and does not change the +/// destination layout. +/// +/// @param post_ops Post-ops. +/// @param scale Accumulation scaling factor. +/// @param zero_point Single scalar int32_t value of zero point. +/// @param data_type Accumulation data_type. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_append_sum(dnnl_post_ops_t post_ops, + float scale, int32_t zero_point, dnnl_data_type_t data_type); + +/// Returns the parameters of an accumulation (sum) post-op with +/// zero point and data type parameter. +/// +/// @param post_ops Post-ops. +/// @param index Index of the sum post-op. +/// @param scale Output accumulation scaling factor. +/// @param zero_point Zero point. +/// @param data_type Data type for accumulation. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_get_params_sum( + const_dnnl_post_ops_t post_ops, int index, float *scale, + int32_t *zero_point, dnnl_data_type_t *data_type); + +/// Appends an elementwise post-op. +/// +/// The kind of this post operation is #dnnl_eltwise. +/// +/// In the simplest case when the elementwise is the only post operation, the +/// computations would be: +/// +/// dst[:] <- eltwise_op (op(...)) // instead of dst[:] <- op(...) +/// +/// where eltwise_op is configured with the given parameters. +/// +/// @param post_ops Post-ops. +/// @param alg_kind Elementwise algorithm for the post-op. +/// @param alpha Alpha parameter for the elementwise algorithm. +/// @param beta Beta parameter for the elementwise algorithm. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_append_eltwise(dnnl_post_ops_t post_ops, + dnnl_alg_kind_t alg_kind, float alpha, float beta); + +/// Returns the parameters of an elementwise post-op. +/// +/// @param post_ops Post-ops. +/// @param index Index of the elementwise post-op. +/// @param alg_kind Output elementwise algorithm kind. +/// @param alpha Output alpha parameter for the elementwise algorithm. +/// @param beta Output beta parameter for the elementwise algorithm. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +/// @returns #dnnl_invalid_arguments if @p index does not refer to an +/// elementwise post-op. +dnnl_status_t DNNL_API dnnl_post_ops_get_params_eltwise( + const_dnnl_post_ops_t post_ops, int index, dnnl_alg_kind_t *alg_kind, + float *alpha, float *beta); + +/// Appends a depthwise post-op convolution. +/// +/// This post-op can only be fused with a 2D 1x1 convolution (convolution with +/// weights spatial dimensions equal to 1 i.e., kh=kw=1). +/// +/// The kind of this post-op is #dnnl_convolution. +/// +/// The number of outputs for primitive with fusion is one. The output spatial +/// size can be derived as below: +/// +/// output_height = ceil(output_height_1x1_convolution, stride) +/// output_width = ceil(output_width_1x1_convolution, stride) +/// +/// See @ref dev_guide_attributes_post_ops_depthwise and +/// @ref dev_guide_attributes_post_ops_depthwise_fusion for more info. +/// +/// @param post_ops Post-ops. +/// @param weights_data_type Weights data type of depthwise post-op +/// @param bias_data_type Bias data type of depthwise post-op +/// @param dst_data_type Output data type of depthwise post-op +/// @param kernel_size Size of kernel of depthwise post-op +/// @param stride_size Size of stride of depthwise post-op +/// @param padding_l_size Size of left and top paddings of depthwise post-op +/// @returns #dnnl_success on success and a status describing the error +/// otherwise +dnnl_status_t DNNL_API dnnl_post_ops_append_dw(dnnl_post_ops_t post_ops, + dnnl_data_type_t weights_data_type, dnnl_data_type_t bias_data_type, + dnnl_data_type_t dst_data_type, dnnl_dim_t kernel_size, + dnnl_dim_t stride_size, dnnl_dim_t padding_l_size); + +/// Returns the parameters of an depthwise post-op. +/// +/// @param post_ops Post-ops. +/// @param index Index of the elementwise post-op. +/// @param weights_data_type Weights data type of depthwise post-op +/// @param bias_data_type Bias data type of depthwise post-op +/// @param dst_data_type Output data type of depthwise post-op +/// @param kernel_size Size of kernel of depthwise post-op +/// @param stride_size Size of stride of depthwise post-op +/// @param padding_l_size Size of left and top paddings of depthwise post-op +/// @returns #dnnl_success on success and a status describing the error +/// otherwise +dnnl_status_t DNNL_API dnnl_post_ops_get_params_dw( + const_dnnl_post_ops_t post_ops, int index, + dnnl_data_type_t *weights_data_type, dnnl_data_type_t *bias_data_type, + dnnl_data_type_t *dst_data_type, dnnl_dim_t *kernel_size, + dnnl_dim_t *stride_size, dnnl_dim_t *padding_l_size); + +/// Appends a binary post-op. +/// +/// This post operation is categorized as #dnnl_binary. +/// +/// In the simplest case when the binary is the only post operation, the +/// computations would be: +/// +/// dst[:] <- binary_op (dst[:], another_input[:]) +/// +/// where binary_op is configured with the given parameters. binary_op supports +/// broadcast semantics for a second operand. +/// +/// @param post_ops Post-ops. +/// @param alg_kind Binary algorithm for the post-op. +/// @param src1_desc Memory descriptor of a second operand. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_append_binary(dnnl_post_ops_t post_ops, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t src1_desc); + +/// Appends a binary post-op with ternary operators. +/// +/// This post operation is categorized as #dnnl_binary. +/// +/// In the simplest case when the binary is the only post operation, the +/// computations will be: +/// +/// dst[:] <- binary_op (dst[:], another_input1[:], another_input2[:]) +/// +/// where binary_op is configured with the given parameters. binary_op supports +/// broadcast semantics only for the second operand and not for the third +/// operand. +/// +/// @param post_ops Post-ops. +/// @param alg_kind Binary algorithm for the post-op. +/// @param src1_desc Memory descriptor of a second operand. +/// @param src2_desc Memory descriptor of a third operand. If the specificed +/// algorithm is not one that requires a ternary input, src2_desc will be +/// ignored. + +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_append_binary_v2(dnnl_post_ops_t post_ops, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t src1_desc, + const_dnnl_memory_desc_t src2_desc); + +/// Returns the parameters of a binary post-op. +/// +/// @param post_ops Post-ops. +/// @param index Index of the binary post-op. +/// @param alg_kind Output binary algorithm kind. +/// @param src1_desc Output memory descriptor of a second operand. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +/// @returns #dnnl_invalid_arguments if @p index does not refer to a binary +/// post-op. +dnnl_status_t DNNL_API dnnl_post_ops_get_params_binary( + const_dnnl_post_ops_t post_ops, int index, dnnl_alg_kind_t *alg_kind, + const_dnnl_memory_desc_t *src1_desc); + +/// Returns the parameters of a binary post-op with ternary operators. +/// +/// @param post_ops Post-ops. +/// @param index Index of the binary post-op. +/// @param alg_kind Output binary algorithm kind. +/// @param src1_desc Output memory descriptor of a second operand. +/// @param src2_desc Output memory descriptor of a third operand. If the +/// specified algorithm is not one that requires a ternary input, src2_desc +/// will be ignored. + +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +/// @returns #dnnl_invalid_arguments if @p index does not refer to a binary +/// post-op. +dnnl_status_t DNNL_API dnnl_post_ops_get_params_binary_v2( + const_dnnl_post_ops_t post_ops, int index, dnnl_alg_kind_t *alg_kind, + const_dnnl_memory_desc_t *src1_desc, + const_dnnl_memory_desc_t *src2_desc); + +/// Appends a prelu forward post-op. +/// +/// The kind of this post-op is #dnnl::primitive::kind::prelu. +/// +/// The post-op can be defined as: +/// +/// dst[:] <- prelu(dst[:], weights[:]) +/// prelu: +/// dst[:] <- dst[:] if dst[:] > 0 +/// dst[:] <- dst[:] * weights[:] if dst[:] <= 0 +/// +/// +/// @note +/// The order of dimensions does not depend on how elements are laid +/// out in memory. For example: +/// - for a 2D CNN activations tensor the order is always (n, c) +/// - for a 4D CNN activations tensor the order is always (n, c, h, w) +/// - for a 5D CNN weights tensor the order is always +/// (g, oc, ic, kh, kw) +/// +/// Prelu weights tensor is passed in runtime execution phase. Prelu +/// weights tensor data type is implicitly assumed as f32 using plain +/// layout (a, ab, acb, acdb, acdeb) +/// +/// @param post_ops Post-ops. +/// @param mask Defines the correspondence between the output tensor +/// dimensions and the prelu weights tensor. The set i-th bit indicates +/// that a dedicated weights value is used for each index along that +/// dimension. Set the mask to 0 to use a common weights value +/// for the whole output tensor. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_append_prelu( + dnnl_post_ops_t post_ops, int mask); + +/// Returns the parameters of a prelu post-op. +/// +/// @param post_ops Post-ops. +/// @param index Index of the prelu post-op. +/// @param mask Mask of the prelu post-op. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_post_ops_get_params_prelu( + const_dnnl_post_ops_t post_ops, int index, int *mask); + +/// @} dnnl_api_attributes + +/// @} dnnl_api_primitives + +/// @addtogroup dnnl_api_memory +/// @{ + +/// Destroys a memory descriptor. +/// +/// @param memory_desc Memory descriptor to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_destroy(dnnl_memory_desc_t memory_desc); + +/// Clones a memory descriptor. The resulting memory descriptor must be +/// destroyed separately. +/// +/// @param memory_desc Output memory descriptor. +/// @param existing_memory_desc Memory descriptor to clone. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_clone(dnnl_memory_desc_t *memory_desc, + const_dnnl_memory_desc_t existing_memory_desc); + +/// Retrieves a binary blob associated with the given memory descriptor +/// +/// @param blob Output pointer to binary blob. +/// If not nullptr, size bytes of the memory descriptor blob are written. +/// @param size Output pointer to the size of the binary blob in bytes. +/// Size is written if blob is nullptr. +/// @param memory_desc input memory descriptor to serialize +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_get_blob( + uint8_t *blob, size_t *size, const_dnnl_memory_desc_t memory_desc); + +/// Creates a memory descriptor from a memory descriptor binary blob. +/// +/// @param memory_desc Output pointer to a newly allocated memory descriptor. +/// @param blob Pointer to a memory descriptor binary blob. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_create_with_blob( + dnnl_memory_desc_t *memory_desc, const uint8_t *blob); + +/// Creates a memory descriptor using dimensions and strides. +/// +/// @note +/// As always, the logical order of dimensions corresponds to the `abc...` +/// format tag, and the physical meaning of the dimensions depends on both +/// the primitive that consumes the memory and the context of that +/// consumption. +/// +/// @param memory_desc Output memory descriptor. +/// @param ndims Number of dimensions +/// @param dims Array of dimensions. +/// @param data_type Elements data type. +/// @param strides Strides in each dimension. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_create_with_strides( + dnnl_memory_desc_t *memory_desc, int ndims, const dnnl_dims_t dims, + dnnl_data_type_t data_type, const dnnl_dims_t strides); + +/// Creates a memory descriptor using dimensions and memory format tag. +/// +/// @note +/// As always, the logical order of dimensions corresponds to the `abc...` +/// format tag, and the physical meaning of the dimensions depends on both +/// the primitive that consumes the memory and the context of that +/// consumption. +/// +/// @param memory_desc Output memory descriptor. +/// @param ndims Number of dimensions +/// @param dims Array of dimensions. +/// @param data_type Elements data type. +/// @param tag Memory format tag. Can be #dnnl_format_tag_any which would +/// allow a primitive to chose the final memory format. In this case the +/// format_kind field of the memory descriptor would be set to +/// #dnnl_format_kind_any. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_create_with_tag( + dnnl_memory_desc_t *memory_desc, int ndims, const dnnl_dims_t dims, + dnnl_data_type_t data_type, dnnl_format_tag_t tag); + +/// Creates a memory descriptor for CSR encoding. +/// +/// @param memory_desc Output memory descriptor. +/// @param ndims Number of dimensions +/// @param dims Array of dimensions. +/// @param data_type Elements data type. +/// @param nnz Number of non-zero entries. +/// @param indices_dt Data type of indices. +/// @param pointers_dt Data type of pointers. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_create_with_csr_encoding( + dnnl_memory_desc_t *memory_desc, int ndims, const dnnl_dims_t dims, + dnnl_data_type_t data_type, dnnl_dim_t nnz, dnnl_data_type_t indices_dt, + dnnl_data_type_t pointers_dt); + +/// Creates a memory descriptor for COO encoding. +/// +/// The created memory descriptor will describe a memory object that +/// contains n+1 buffers for an n-dimensional tensor. +/// The buffers have the following meaning and assigned numbers (index): +/// - 0: values +/// - 1: indices for dimension 0 +/// - 2: indices for dimension 1 ... +/// - n: indices for dimension n-1 +/// +/// @param memory_desc Output memory descriptor. +/// @param ndims Number of dimensions. +/// @param dims Array of dimensions. +/// @param data_type Elements data type. +/// @param nnz Number of non-zero entries. +/// @param indices_dt Data type of indices. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_create_with_coo_encoding( + dnnl_memory_desc_t *memory_desc, int ndims, const dnnl_dims_t dims, + dnnl_data_type_t data_type, dnnl_dim_t nnz, + dnnl_data_type_t indices_dt); + +/// Creates a memory descriptor for packed sparse encoding. +/// +/// The created memory descriptor cannot be used to create a memory +/// object. It can only be used to create a primitive descriptor to +/// query the actual memory descriptor (similar to the format tag +/// `any`). +/// +/// @warning +/// The meaning and content of the handles of the memory object that +/// is created using the queried memory descriptor are unspecified +/// therefore using the content is an undefined behavior. +/// +/// @param memory_desc Output memory descriptor. +/// @param ndims Number of dimensions +/// @param dims Array of dimensions. +/// @param data_type Elements data type. +/// @param nnz Number of non-zero entries. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +/// @sa @ref dev_guide_sparsity +dnnl_status_t DNNL_API dnnl_memory_desc_create_with_packed_encoding( + dnnl_memory_desc_t *memory_desc, int ndims, const dnnl_dims_t dims, + dnnl_data_type_t data_type, dnnl_dim_t nnz); + +/// Creates a memory descriptor for a scalar value that resides on the host. +/// +/// @param memory_desc Output memory descriptor. +/// @param data_type Elements data type. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_create_host_scalar( + dnnl_memory_desc_t *memory_desc, dnnl_data_type_t data_type); + +/// Creates a memory descriptor for a region inside an area +/// described by an existing memory descriptor. +/// +/// @warning +/// Some combinations of physical memory layout and/or offsets or dims may +/// result in a failure to create a submemory. +// +/// @param memory_desc Output memory descriptor. +/// @param parent_memory_desc An existing memory descriptor. +/// @param dims Sizes of the region. +/// @param offsets Offsets to the region from the encompassing +/// memory object in each dimension +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_create_submemory( + dnnl_memory_desc_t *memory_desc, + const_dnnl_memory_desc_t parent_memory_desc, const dnnl_dims_t dims, + const dnnl_dims_t offsets); + +/// Creates a memory descriptor by reshaping an existing one. The new +/// memory descriptor inherits the data type. This operation is valid only for +/// memory descriptors that have format_kind #dnnl_blocked or +/// #dnnl_format_kind_any. +/// +/// The resulting memory descriptor must be destroyed separately. +/// +/// The operation ensures the transformation of the physical memory format +/// corresponds to the transformation of the logical dimensions. If such +/// transformation is impossible, the function returns #dnnl_invalid_arguments. +/// +/// The reshape operation can be described as a combination of the following +/// basic operations: +/// 1. Add a dimension of size `1`. This is always possible. +/// 2. Remove a dimension of size `1`. This is possible only if the dimension +/// has no padding (i.e. `padded_dims[dim] == dims[dim] && dims[dim] == 1`). +/// 3. Split a dimension into multiple ones. This is possible only if the size +/// of the dimension is exactly equal to the product of the split ones and +/// the dimension does not have padding (i.e. +/// `padded_dims[dim] = dims[dim]`). +/// 4. Joining multiple consecutive dimensions into a single one. As in the +/// cases above, this requires that the dimensions do not have padding and +/// that the memory format is such that in physical memory these dimensions +/// are dense and have the same order as their logical counterparts. This +/// also assumes that these dimensions are not blocked. +/// - Here, dense means: +/// `stride for dim[i] == (stride for dim[i + 1]) * dim[i + 1]`; +/// - And same order means: +/// `i < j` if and only if `stride for dim[j] <= stride for dim[i]`. +/// +/// @warning +/// Some combinations of physical memory layout and/or offsets or +/// dimensions may result in a failure to make a reshape. +/// +/// @param out_memory_desc Output memory descriptor. +/// @param in_memory_desc An existing memory descriptor. Must have format_kind +/// set to #dnnl_blocked or #dnnl_format_kind_any. +/// @param ndims Number of dimensions for the output memory descriptor. +/// @param dims Dimensions for the output memory descriptor. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_reshape( + dnnl_memory_desc_t *out_memory_desc, + const_dnnl_memory_desc_t in_memory_desc, int ndims, + const dnnl_dims_t dims); + +/// Creates a memory descriptor by permuting axes in an existing one. +/// +/// The physical memory layout representation is adjusted accordingly to +/// maintain the consistency between the logical and physical parts of the +/// memory descriptor. +/// +/// The resulting memory descriptor must be destroyed separately. +/// +/// The new memory descriptor inherits the data type. This operation is valid +/// only for memory descriptors that have format_kind set to #dnnl_blocked or +/// #dnnl_format_kind_any. +/// +/// The logical axes will be permuted in the following manner: +/// ``` +/// for (i: 0 .. in_memory_desc->ndims) +/// out_memory_desc->dims[permutation[i]] = in_memory_desc->dims[i]; +/// ``` +/// +/// Example: +/// @code +/// dnnl_memory_desc_t in_md, out_md, expect_out_md; +/// +/// const int permutation[] = {1, 0}; // swap the first and the second axes +/// +/// dnnl_dims_t in_dims = {2, 3}, out_dims = {3, 2}; +/// dnnl_format_tag_t in_tag = dnnl_ab, out_tag = dnnl_ba; +/// +/// dnnl_memory_desc_create_with_tag( +/// &in_md, 2, in_dims, data_type, in_tag); +/// dnnl_memory_desc_create_with_tag( +/// &expect_out_md, 2, out_dims, data_type, out_tag); +/// +/// dnnl_memory_desc_permute_axes(&out_md, in_md, permutation); +/// assert(dnnl_memory_desc_equal(out_md, expect_out_md)); +/// +/// dnnl_memory_desc_destroy(in_md); +/// dnnl_memory_desc_destroy(out_md); +/// dnnl_memory_desc_destroy(expect_out_md); +/// @endcode +/// +/// @param out_memory_desc Output memory descriptor. +/// @param in_memory_desc An existing memory descriptor. Must have format_kind +/// set to #dnnl_blocked or #dnnl_format_kind_any. +/// @param permutation Axes permutation (of size `in_memory_desc->ndims`). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_permute_axes( + dnnl_memory_desc_t *out_memory_desc, + const_dnnl_memory_desc_t in_memory_desc, const int *permutation); + +/// Queries a memory descriptor for various pieces of information. +/// +/// The following information can be queried: +/// - Number of dimensions (#dnnl_query_ndims_s32) +/// - Dimensions (#dnnl_query_dims) in the following order: +/// - CNN data tensors: mini-batch, channel, spatial +/// ({N, C, [[D,] H,] W}) +/// - CNN weight tensors: group (optional), output channel, input channel, +/// spatial ({[G,] O, I, [[D,] H,] W}) +/// - RNN data tensors: time, mini-batch, channels ({T, N, C}) +/// or layers, directions, states, mini-batch, channels +/// ({L, D, S, N, C}) +/// - RNN weight tensor: layers, directions, input channel, gates, output +/// channels ({L, D, I, G, O}) +/// - Data type of the tensor elements (#dnnl_query_data_type) +/// - Padded dimensions (#dnnl_query_padded_dims) - size of the data including +/// padding in each dimension +/// - Padded offsets (#dnnl_query_padded_offsets) - per-dimension offset from +/// the padding to actual data, the top-level tensor with offsets applied +/// must lie within the padding area. +/// - Submemory offset (#dnnl_query_submemory_offset_s64) - offset from memory +/// origin to the current block, non-zero only in a description of a memory +/// sub-block. +/// - Format kind (#dnnl_query_format_kind) - memory format kind +/// +/// @note +/// The order of dimensions does not depend on the memory format, so +/// whether the data is laid out in #dnnl_nchw or #dnnl_nhwc +/// the dims for 4D CN data tensor would be {N, C, H, W}. +/// +/// The following queries are applicable only to format kind #dnnl_blocked. +/// - Strides (#dnnl_query_strides) between the outermost blocks or in case +/// of plain (non-blocked) formats the strides between dimensions +/// - Number of innermost blocks (#dnnl_query_inner_nblks_s32), e.g. +/// `{4, 16, 4}` in case of `OIhw_4i16o4i` +/// - Size of the innermost blocks (#dnnl_query_inner_blks), e.g. 3 in case +/// of `OIhw_4i16o4i_` +/// - Logical indices of the blocks (#dnnl_query_inner_idxs), e.g. `{1, 0, 1}` +/// in case of `4i16o4i`, because `i` is the 1st dim and `o` is the 0st dim +/// +/// @param memory_desc Memory descriptor. +/// @param what Parameter to query. +/// @param result Output result. The type depends on the query. For example, +/// it must be a @c dnnl_dims_t** if querying for a strides. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_desc_query( + const_dnnl_memory_desc_t memory_desc, dnnl_query_t what, void *result); + +/// Queries a memory descriptor for various pieces of information. This version +/// support additional queries #dnnl_query_sparse_encoding, #dnnl_query_nnz_s64 +/// #dnnl_query_num_handles_s32 and #dnnl_query_data_type for a particular +/// buffer. +/// +/// The following information can be queried: +/// - Number of dimensions (#dnnl_query_ndims_s32) +/// - Dimensions (#dnnl_query_dims) in the following order: +/// - CNN data tensors: mini-batch, channel, spatial +/// ({N, C, [[D,] H,] W}) +/// - CNN weight tensors: group (optional), output channel, input channel, +/// spatial ({[G,] O, I, [[D,] H,] W}) +/// - RNN data tensors: time, mini-batch, channels ({T, N, C}) +/// or layers, directions, states, mini-batch, channels +/// ({L, D, S, N, C}) +/// - RNN weight tensor: layers, directions, input channel, gates, output +/// channels ({L, D, I, G, O}) +/// - Data type of the tensor elements (#dnnl_query_data_type) +/// - Padded dimensions (#dnnl_query_padded_dims) - size of the data including +/// padding in each dimension +/// - Padded offsets (#dnnl_query_padded_offsets) - per-dimension offset from +/// the padding to actual data, the top-level tensor with offsets applied +/// must lie within the padding area. +/// - Submemory offset (#dnnl_query_submemory_offset_s64) - offset from memory +/// origin to the current block, non-zero only in a description of a memory +/// sub-block. +/// - Format kind (#dnnl_query_format_kind) - memory format kind +/// +/// @note +/// The order of dimensions does not depend on the memory format, so +/// whether the data is laid out in #dnnl_nchw or #dnnl_nhwc +/// the dims for 4D CN data tensor would be {N, C, H, W}. +/// +/// The following queries are applicable only to format kind #dnnl_blocked. +/// - Strides (#dnnl_query_strides) between the outermost blocks or in case +/// of plain (non-blocked) formats the strides between dimensions +/// - Number of innermost blocks (#dnnl_query_inner_nblks_s32), e.g. +/// `{4, 16, 4}` in case of `OIhw_4i16o4i` +/// - Size of the innermost blocks (#dnnl_query_inner_blks), e.g. 3 in case +/// of `OIhw_4i16o4i_` +/// - Logical indices of the blocks (#dnnl_query_inner_idxs), e.g. `{1, 0, 1}` +/// in case of `4i16o4i`, because `i` is the 1st dim and `o` is the 0st dim +/// +/// @param memory_desc Memory descriptor. +/// @param what Parameter to query. +/// @param index Index of the parameter to query for. It is mostly used with +/// #dnnl_query_data_type to specify which data type is being queried. +/// The main data type (data type of values) has always index 0. For other +/// indices please refer to the API for creating a memory descriptor for +/// sparse encoding. +/// @param result Output result. The type depends on the query. For example, +/// it must be a @c dnnl_dims_t** if querying for a strides. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +/// @sa @ref dev_guide_sparsity +dnnl_status_t DNNL_API dnnl_memory_desc_query_v2( + const_dnnl_memory_desc_t memory_desc, dnnl_query_t what, int index, + void *result); + +/// Compares two memory descriptors. +/// +/// Use this function to identify whether a reorder is required between the +/// two memories +/// +/// @param lhs Left-hand side of the comparison. +/// @param rhs Right-hand side of the comparison. +/// @returns 1 if the descriptors are the same. +/// @returns 0 if the descriptors are different. +int DNNL_API dnnl_memory_desc_equal( + const_dnnl_memory_desc_t lhs, const_dnnl_memory_desc_t rhs); + +/// Returns the size of a memory descriptor. +/// +/// @param memory_desc Memory descriptor. +/// @returns The number of bytes required for memory described by a memory +/// descriptor. +size_t DNNL_API dnnl_memory_desc_get_size(const_dnnl_memory_desc_t memory_desc); + +/// Returns the size of the data that corresponds to the given index. +/// +/// @param memory_desc Memory descriptor. +/// @param index Index of the buffer. +/// +/// @returns The number of bytes required for the requested data. +size_t DNNL_API dnnl_memory_desc_get_size_v2( + const_dnnl_memory_desc_t memory_desc, int index); + +/// Returns the size of data type. +/// +/// @param data_type Data type. +/// @returns The number of bytes occupied by data type. +size_t DNNL_API dnnl_data_type_size(dnnl_data_type_t data_type); + +/// Creates a memory object. +/// +/// Unless @p handle is equal to DNNL_MEMORY_NONE, the constructed memory +/// object will have the underlying buffer set. In this case, the buffer will +/// be initialized as if dnnl_memory_set_data_handle() had been called. +/// +/// @sa dnnl_memory_set_data_handle() +/// +/// @param memory Output memory object. +/// @param memory_desc Memory descriptor. +/// @param engine Engine to use. +/// @param handle Handle of the memory buffer to use as an underlying storage. +/// - A pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer for the memory object. In this case the library +/// owns the buffer. +/// - DNNL_MEMORY_NONE to create dnnl_memory without an underlying buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_create(dnnl_memory_t *memory, + const_dnnl_memory_desc_t memory_desc, dnnl_engine_t engine, + void *handle); + +/// Creates a memory object with multiple handles. +/// +/// @param memory Output memory object. +/// @param memory_desc Memory descriptor. +/// @param engine Engine to use. +/// @param nhandles Number of handles. +/// @param handles Handles of the memory buffers to use as underlying storages. +/// For each element of the @p handles array the following applies: +/// - A pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer for the memory object. In this case the library +/// owns the buffer. +/// - DNNL_MEMORY_NONE Instructs the library to skip allocation of the +/// memory buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_create_v2(dnnl_memory_t *memory, + const_dnnl_memory_desc_t memory_desc, dnnl_engine_t engine, + int nhandles, void **handles); + +/// Creates a memory object for a scalar value located on the host. +/// +/// @note The scalar value is copied from the provided pointer into the newly +/// allocated memory storage, so the user does not need to manage the +/// lifetime of the original scalar data. +/// +/// @param memory Output host-side scalar memory object. +/// @param memory_desc Memory descriptor describing a scalar value residing on the host. +/// @param scalar_ptr Pointer to the scalar value to be copied into the memory +/// object. This should be a host pointer to the scalar data. +/// @returns #dnnl_success on success; otherwise, returns a status code +/// describing the error. +dnnl_status_t DNNL_API dnnl_memory_create_host_scalar(dnnl_memory_t *memory, + const_dnnl_memory_desc_t memory_desc, void *scalar_ptr); + +/// Returns the memory descriptor for a memory object. +/// +/// @param memory Memory object. +/// @param memory_desc Output memory descriptor (a copy). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_get_memory_desc( + const_dnnl_memory_t memory, const_dnnl_memory_desc_t *memory_desc); + +/// Returns the engine of a memory object. +/// +/// @param memory Memory object. +/// @param engine Output engine on which the memory is located. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_get_engine( + const_dnnl_memory_t memory, dnnl_engine_t *engine); + +/// Maps a memory object and returns a host-side pointer to a memory buffer +/// with a copy of its contents. +/// +/// Mapping enables explicit direct access to memory contents for the engines +/// that do not support it implicitly. +/// +/// Mapping is an exclusive operation - a memory object cannot be used in +/// other operations until this memory object is unmapped. +/// +/// @note +/// Any primitives working with @p memory should be completed before +/// the memory is mapped. Use dnnl_stream_wait to synchronize the +/// corresponding execution stream. +/// +/// @note +/// The dnnl_memory_map_data() and dnnl_memory_unmap_data() functions are +/// mainly provided for debug and testing purposes, and their performance +/// may be suboptimal. +/// +/// @param memory Memory object. +/// @param mapped_ptr Output pointer to the mapped buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_map_data( + const_dnnl_memory_t memory, void **mapped_ptr); + +/// Maps a memory object and returns a host-side pointer to a memory buffer +/// with a copy of its contents. The memory buffer corresponds to the given +/// index. +/// +/// Mapping enables explicit direct access to memory contents for the engines +/// that do not support it implicitly. +/// +/// Mapping is an exclusive operation - a memory object cannot be used in +/// other operations until this memory object is unmapped. +/// +/// @note +/// Any primitives working with @p memory should be completed before +/// the memory is mapped. Use dnnl_stream_wait to synchronize the +/// corresponding execution stream. +/// +/// @note +/// The dnnl_memory_map_data() and dnnl_memory_unmap_data() functions are +/// mainly provided for debug and testing purposes, and their performance +/// may be suboptimal. +/// +/// @param memory Memory object. +/// @param mapped_ptr Output pointer to the mapped buffer. +/// @param index Index of the buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_map_data_v2( + const_dnnl_memory_t memory, void **mapped_ptr, int index); + +/// Unmaps a memory object and writes back any changes made to the previously +/// mapped memory buffer. The pointer to the mapped buffer must be obtained +/// via the dnnl_memory_map_data() call. +/// +/// @note +/// The dnnl_memory_map_data() and dnnl_memory_unmap_data() functions are +/// mainly provided for debug and testing purposes, and their performance +/// may be suboptimal. +/// +/// @param memory Memory object. +/// @param mapped_ptr Pointer to the mapped buffer that must have been +/// obtained using the dnnl_memory_map_data() function. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_unmap_data( + const_dnnl_memory_t memory, void *mapped_ptr); + +/// Unmaps a memory object and writes back any changes made to the previously +/// mapped memory buffer. The pointer to the mapped buffer must be obtained +/// via the dnnl_memory_map_data() call. The buffer corresponds to the given +/// index. +/// +/// @note +/// The dnnl_memory_map_data() and dnnl_memory_unmap_data() functions are +/// mainly provided for debug and testing purposes, and their performance +/// may be suboptimal. +/// +/// @param memory Memory object. +/// @param mapped_ptr Pointer to the mapped buffer that must have been +/// obtained using the dnnl_memory_map_data() function. +/// @param index Index of the buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_unmap_data_v2( + const_dnnl_memory_t memory, void *mapped_ptr, int index); + +/// Returns memory object's data handle. +/// +/// @param memory Memory object. +/// @param handle Output data handle. For the CPU engine, the data handle is a +/// pointer to the actual data. For OpenCL it is a cl_mem. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_get_data_handle( + const_dnnl_memory_t memory, void **handle); + +/// Sets the underlying memory buffer. +/// +/// @param memory Memory object. +/// @param handle Data handle. For the CPU engine or when USM is used, the +/// memory buffer is a pointer to the actual data. For OpenCL it is a +/// `cl_mem`. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_set_data_handle( + dnnl_memory_t memory, void *handle); + +/// Returns an underlying memory buffer that corresponds to the given index. +/// +/// @param memory Memory object. +/// @param handle Data handle. For the CPU engine or when USM is used, the +/// memory buffer is a pointer to the actual data. For OpenCL it is a +/// `cl_mem`. +/// @param index Index of the buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_get_data_handle_v2( + const_dnnl_memory_t memory, void **handle, int index); + +/// Sets an underlying memory buffer that corresponds to the given index. +/// +/// @param memory Memory object. +/// @param handle Data handle. For the CPU engine or when USM is used, the +/// memory buffer is a pointer to the actual data. For OpenCL it is a +/// `cl_mem`. +/// @param index Index of the buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_set_data_handle_v2( + dnnl_memory_t memory, void *handle, int index); + +/// Returns the value stored in a scalar memory object as a host pointer. +/// +/// @param memory Host-side scalar memory object. +/// @param value Output pointer to the scalar value. The type of the value +/// depends on the data type of the memory object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_get_host_scalar_value( + const_dnnl_memory_t memory, void *value); + +/// Sets the value of a scalar memory object from a host pointer. +/// +/// @note The value would be copied from the provided pointer into the +/// memory object, so the user does not need to manage the lifetime of the +/// original scalar data. +/// +/// @param memory Host-side scalar memory object. +/// @param value Pointer to the scalar value to be copied into the +/// memory object. The type of the value must match the data type of the +/// memory object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_set_host_scalar_value( + dnnl_memory_t memory, const void *value); + +/// Destroys a memory object. +/// +/// @param memory Memory object to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_memory_destroy(dnnl_memory_t memory); + +/// @} dnnl_api_memory + +/// @addtogroup dnnl_api_primitives +/// @{ + +/// @addtogroup dnnl_api_reorder +/// @{ + +/// Creates a primitive descriptor for a reorder primitive. +/// +/// @param reorder_primitive_desc Output primitive descriptor. +/// @param src_desc Source memory descriptor. +/// @param src_engine Engine on which the source memory object will be +/// located. +/// @param dst_desc Destination memory descriptor. +/// @param dst_engine Engine on which the destination memory object +/// will be located. +/// @param attr Primitive attributes to use (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_reorder_primitive_desc_create( + dnnl_primitive_desc_t *reorder_primitive_desc, + const_dnnl_memory_desc_t src_desc, dnnl_engine_t src_engine, + const_dnnl_memory_desc_t dst_desc, dnnl_engine_t dst_engine, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_reorder + +/// @addtogroup dnnl_api_concat +/// @{ + +/// Creates a primitive descriptor for an out-of-place concatenation +/// primitive. +/// +/// @param concat_primitive_desc Output primitive descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param n Number of source parameters. +/// @param concat_dimension Source tensors will be concatenated over +/// dimension with this index. Note that order of dimensions does +/// not depend on memory format. +/// @param src_descs Array of source memory descriptors with @p n elements. +/// @param attr Primitive attributes to use (can be NULL). +/// @param engine Engine to use. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_concat_primitive_desc_create( + dnnl_primitive_desc_t *concat_primitive_desc, dnnl_engine_t engine, + const_dnnl_memory_desc_t dst_desc, int n, int concat_dimension, + const_dnnl_memory_desc_t const *src_descs, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_concat + +/// @addtogroup dnnl_api_sum +/// @{ + +/// Creates a primitive descriptor for an (out-of-place) sum primitive. +/// +/// @param sum_primitive_desc Output primitive descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param n Number of source parameters. +/// @param scales Vector of scales to multiply data in each source +/// memory by. +/// @param src_descs Array of source memory descriptors having @p n elements. +/// @param attr Primitive attributes to use (can be NULL). +/// @param engine Engine to use. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sum_primitive_desc_create( + dnnl_primitive_desc_t *sum_primitive_desc, dnnl_engine_t engine, + const_dnnl_memory_desc_t dst_desc, int n, const float *scales, + const_dnnl_memory_desc_t const *src_descs, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_sum + +/// @addtogroup dnnl_api_binary +/// @{ + +/// Creates a primitive descriptor for a binary primitive. +/// +/// @note +/// Memory descriptors @p src1_desc and @p dst_desc are allowed to be +/// initialized with #dnnl_format_tag_any or with format_kind set to +/// #dnnl_format_kind_any. +/// +/// @note +/// Both memory descriptors must have the same number of dimensions. +/// Element broadcasting is supported for memory descriptor @p src1_desc +/// and are applied to @p src1_desc dimensions that have size equal to 1. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind Algorithm kind. Valid values are #dnnl_binary_add, +/// #dnnl_binary_mul, #dnnl_binary_max, #dnnl_binary_min, #dnnl_binary_div, +/// #dnnl_binary_sub, #dnnl_binary_ge, #dnnl_binary_gt, #dnnl_binary_le, +/// #dnnl_binary_lt, #dnnl_binary_eq and #dnnl_binary_ne. +/// @param src0_desc Source 0 memory descriptor. +/// @param src1_desc Source 1 memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_binary_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t src0_desc, + const_dnnl_memory_desc_t src1_desc, const_dnnl_memory_desc_t dst_desc, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a binary primitive with support of +/// ternary operators. +/// +/// @note +/// Memory descriptors @p src1_desc, @p src2_desc and @p dst_desc are +/// allowed to be initialized with #dnnl_format_tag_any or with format_kind +/// set to #dnnl_format_kind_any. +/// +/// @note +/// All memory descriptors must have the same number of dimensions. +/// Element broadcasting is supported for memory descriptor @p src1_desc +/// and is applied to @p src1_desc dimensions that have a size equal to 1. +/// There is no broadcasting support for @p src2_desc. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind Algorithm kind. +/// @param src0_desc Source 0 memory descriptor. +/// @param src1_desc Source 1 memory descriptor. +/// @param src2_desc Source memory descriptor for ternary operations. Might +/// be empty. +/// @param dst_desc Destination memory descriptor. +/// @param attr Primitive attributes. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_binary_primitive_desc_create_v2( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t src0_desc, + const_dnnl_memory_desc_t src1_desc, const_dnnl_memory_desc_t src2_desc, + const_dnnl_memory_desc_t dst_desc, const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_binary + +/// @addtogroup dnnl_api_convolution +/// @{ + +/// Creates a primitive descriptor for a convolution forward propagation +/// primitive. +/// +/// @note +/// Memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r contain +/// values for spatial dimensions only and hence must have the same number of +/// elements as there are spatial dimensions. The order of values is the same +/// as in the tensor: depth (for 3D tensors), height (for 3D and 2D tensors), +/// and width. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param alg_kind Convolution algorithm. Possible values are +/// #dnnl_convolution_direct, #dnnl_convolution_winograd, +/// #dnnl_convolution_auto. +/// @param src_desc Source memory descriptor. +/// @param weights_desc Weights memory descriptor. +/// @param bias_desc Bias memory descriptor. Passing NULL, a zero memory +/// descriptor, or a memory descriptor with format_kind set to +/// #dnnl_format_kind_undef disables the bias term. +/// @param dst_desc Destination memory descriptor. +/// @param strides Array of strides for spatial dimension. +/// @param dilates Array of dilations for spatial dimension. A zero value +/// means no dilation in the corresponding dimension. +/// @param padding_l Array of padding values for low indices for each spatial +/// dimension `([[front,] top,] left)`. +/// @param padding_r Array of padding values for high indices for each spatial +/// dimension `([[back,] bottom,] right)`. Can be NULL in which case +/// padding is considered to be symmetrical. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_convolution_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_alg_kind_t alg_kind, + const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t weights_desc, + const_dnnl_memory_desc_t bias_desc, const_dnnl_memory_desc_t dst_desc, + const dnnl_dims_t strides, const dnnl_dims_t dilates, + const dnnl_dims_t padding_l, const dnnl_dims_t padding_r, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a convolution backward propagation +/// primitive. +/// +/// @note +/// Memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r contain +/// values for spatial dimensions only and hence must have the same number of +/// elements as there are spatial dimensions. The order of values is the same +/// as in the tensor: depth (for 3D tensors), height (for 3D and 2D tensors), +/// and width. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind Convolution algorithm. Possible values are +/// #dnnl_convolution_direct, #dnnl_convolution_winograd, +/// #dnnl_convolution_auto. +/// @param diff_src_desc Diff source memory descriptor. +/// @param weights_desc Weights memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param strides Array of strides for spatial dimension. +/// @param dilates Array of dilations for spatial dimension. A zero value +/// means no dilation in the corresponding dimension. +/// @param padding_l Array of padding values for low indices for each spatial +/// dimension `([[front,] top,] left)`. +/// @param padding_r Array of padding values for high indices for each spatial +/// dimension `([[back,] bottom,] right)`. Can be NULL in which case +/// padding is considered to be symmetrical. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_convolution_backward_data_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t weights_desc, + const_dnnl_memory_desc_t diff_dst_desc, const dnnl_dims_t strides, + const dnnl_dims_t dilates, const dnnl_dims_t padding_l, + const dnnl_dims_t padding_r, const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a convolution weights gradient primitive. +/// +/// @note +/// Memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r contain +/// values for spatial dimensions only and hence must have the same number of +/// elements as there are spatial dimensions. The order of values is the same +/// as in the tensor: depth (for 3D tensors), height (for 3D and 2D tensors), +/// and width. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind Convolution algorithm. Possible values are +/// #dnnl_convolution_direct, #dnnl_convolution_winograd, +/// #dnnl_convolution_auto. +/// @param src_desc Source memory descriptor. +/// @param diff_weights_desc Diff weights memory descriptor. +/// @param diff_bias_desc Diff bias memory descriptor. Passing NULL, a zero +/// memory descriptor, or a memory descriptor with format_kind set to +/// #dnnl_format_kind_undef disables the bias term. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param strides Array of strides for spatial dimension. +/// @param dilates Array of dilations for spatial dimension. A zero value +/// means no dilation in the corresponding dimension. +/// @param padding_l Array of padding values for low indices for each spatial +/// dimension `([[front,] top,] left)`. +/// @param padding_r Array of padding values for high indices for each spatial +/// dimension `([[back,] bottom,] right)`. Can be NULL in which case +/// padding is considered to be symmetrical. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_convolution_backward_weights_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t diff_weights_desc, + const_dnnl_memory_desc_t diff_bias_desc, + const_dnnl_memory_desc_t diff_dst_desc, const dnnl_dims_t strides, + const dnnl_dims_t dilates, const dnnl_dims_t padding_l, + const dnnl_dims_t padding_r, const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_convolution + +/// @addtogroup dnnl_api_deconvolution +/// @{ + +/// Creates a primitive descriptor for a deconvolution forward propagation +/// primitive. +/// +/// @note +/// Memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r contain +/// values for spatial dimensions only and hence must have the same number of +/// elements as there are spatial dimensions. The order of values is the same +/// as in the tensor: depth (for 3D tensors), height (for 3D and 2D tensors), +/// and width. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param alg_kind Deconvolution algorithm. Possible values are +/// #dnnl_deconvolution_direct, #dnnl_deconvolution_winograd. +/// @param src_desc Source memory descriptor. +/// @param weights_desc Weights memory descriptor. +/// @param bias_desc Bias memory descriptor. Passing NULL, a zero memory +/// descriptor, or a memory descriptor with format_kind set to +/// #dnnl_format_kind_undef disables the bias term. +/// @param dst_desc Destination memory descriptor. +/// @param strides Array of strides for spatial dimension. +/// @param dilates Array of dilations for spatial dimension. A zero value +/// means no dilation in the corresponding dimension. +/// @param padding_l Array of padding values for low indices for each spatial +/// dimension `([[front,] top,] left)`. +/// @param padding_r Array of padding values for high indices for each spatial +/// dimension `([[back,] bottom,] right)`. Can be NULL in which case +/// padding is considered to be symmetrical. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_deconvolution_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_alg_kind_t alg_kind, + const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t weights_desc, + const_dnnl_memory_desc_t bias_desc, const_dnnl_memory_desc_t dst_desc, + const dnnl_dims_t strides, const dnnl_dims_t dilates, + const dnnl_dims_t padding_l, const dnnl_dims_t padding_r, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a deconvolution backward propagation +/// primitive. +/// +/// @note +/// Memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r contain +/// values for spatial dimensions only and hence must have the same number of +/// elements as there are spatial dimensions. The order of values is the same +/// as in the tensor: depth (for 3D tensors), height (for 3D and 2D tensors), +/// and width. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind Deconvolution algorithm. Possible values are +/// #dnnl_deconvolution_direct, #dnnl_deconvolution_winograd. +/// @param diff_src_desc Diff source memory descriptor. +/// @param weights_desc Weights memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param strides Array of strides for spatial dimension. +/// @param dilates Array of dilations for spatial dimension. A zero value +/// means no dilation in the corresponding dimension. +/// @param padding_l Array of padding values for low indices for each spatial +/// dimension `([[front,] top,] left)`. +/// @param padding_r Array of padding values for high indices for each spatial +/// dimension `([[back,] bottom,] right)`. Can be NULL in which case +/// padding is considered to be symmetrical. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_deconvolution_backward_data_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t weights_desc, + const_dnnl_memory_desc_t diff_dst_desc, const dnnl_dims_t strides, + const dnnl_dims_t dilates, const dnnl_dims_t padding_l, + const dnnl_dims_t padding_r, const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a deconvolution weights gradient +/// primitive. +/// +/// @note +/// Memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r contain +/// values for spatial dimensions only and hence must have the same number of +/// elements as there are spatial dimensions. The order of values is the same +/// as in the tensor: depth (for 3D tensors), height (for 3D and 2D tensors), +/// and width. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind Deconvolution algorithm. Possible values are +/// #dnnl_deconvolution_direct, #dnnl_deconvolution_winograd. +/// @param src_desc Source memory descriptor. +/// @param diff_weights_desc Diff weights memory descriptor. +/// @param diff_bias_desc Diff bias memory descriptor. Passing NULL, a zero +/// memory descriptor, or a memory descriptor with format_kind set to +/// #dnnl_format_kind_undef disables the bias term. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param strides Array of strides for spatial dimension. +/// @param dilates Array of dilations for spatial dimension. A zero value +/// means no dilation in the corresponding dimension. +/// @param padding_l Array of padding values for low indices for each spatial +/// dimension `([[front,] top,] left)`. +/// @param padding_r Array of padding values for high indices for each spatial +/// dimension `([[back,] bottom,] right)`. Can be NULL in which case +/// padding is considered to be symmetrical. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API +dnnl_deconvolution_backward_weights_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t diff_weights_desc, + const_dnnl_memory_desc_t diff_bias_desc, + const_dnnl_memory_desc_t diff_dst_desc, const dnnl_dims_t strides, + const dnnl_dims_t dilates, const dnnl_dims_t padding_l, + const dnnl_dims_t padding_r, const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_deconvolution + +/// @addtogroup dnnl_api_shuffle +/// @{ + +/// Creates a primitive descriptor for a shuffle forward propagation primitive +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param axis The axis along which the data is shuffled. +/// @param group_size Shuffle group size. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_shuffle_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t dst_desc, int axis, dnnl_dim_t group_size, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a shuffle backward propagation primitive +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param axis The axis along which the data is shuffled. +/// @param group_size Shuffle group size. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_shuffle_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, int axis, dnnl_dim_t group_size, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_shuffle + +/// @addtogroup dnnl_api_eltwise +/// @{ + +/// Creates a primitive descriptor for an eltwise forward propagation primitive. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param alg_kind Elementwise algorithm kind. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param alpha The alpha parameter for the elementwise operation. Specific +/// meaning depends on the algorithm. +/// @param beta The beta parameter for the elementwise operation. Specific +/// meaning depends on the algorithm. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_eltwise_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_alg_kind_t alg_kind, + const_dnnl_memory_desc_t src_desc, const_dnnl_memory_desc_t dst_desc, + float alpha, float beta, const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for an eltwise backward propagation +/// primitive. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind Elementwise algorithm kind. +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param data_desc Destination memory descriptor if one of the +/// "use_dst_for_bwd" algorithms are used (such as +/// #dnnl_eltwise_relu_use_dst_for_bwd), source memory descriptor otherwise. +/// @param alpha The alpha parameter for the elementwise operation. Specific +/// meaning depends on the algorithm. +/// @param beta The beta parameter for the elementwise operation. Specific +/// meaning depends on the algorithm. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_eltwise_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_memory_desc_t data_desc, float alpha, float beta, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_eltwise + +/// @addtogroup dnnl_api_softmax +/// @{ + +/// Creates a primitive descriptor for a softmax forward propagation primitive. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param alg_kind Softmax algorithm kind: either #dnnl_softmax_accurate, or +/// #dnnl_softmax_log. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param softmax_axis Axis over which softmax is computed. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_softmax_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_alg_kind_t alg_kind, + const_dnnl_memory_desc_t src_desc, const_dnnl_memory_desc_t dst_desc, + int softmax_axis, const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a softmax backward propagation primitive. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind Softmax algorithm kind: either #dnnl_softmax_accurate, or +/// #dnnl_softmax_log. +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param softmax_axis Axis over which softmax is computed. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_softmax_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_memory_desc_t dst_desc, int softmax_axis, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_softmax + +/// @addtogroup dnnl_api_pooling +/// @{ + +/// Creates a primitive descriptor for a pooling forward propagation +/// primitive. +/// +/// Arrays @p strides, @p kernel, @p dilation, @p padding_l and @p padding_r +/// contain values for spatial dimensions only and hence must have the same +/// number of elements as there are spatial dimensions. The order of values +/// is the same as in the tensor: depth (for 3D tensors), +/// height (for 3D and 2D tensors), and width. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param alg_kind Pooling algorithm kind: either #dnnl_pooling_max, +/// #dnnl_pooling_avg_include_padding, or #dnnl_pooling_avg_exclude_padding. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param strides Array of strides for spatial dimension. +/// @param kernel Array of kernel spatial dimensions. +/// @param dilation Array of dilations for spatial dimension. +/// @param padding_l Array of padding values for low indices for each spatial +/// dimension `([[front,] top,] left)`. +/// @param padding_r Array of padding values for high indices for each spatial +/// dimension `([[back,] bottom,] right)`. Can be NULL in which case +/// padding is considered to be symmetrical. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_pooling_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_alg_kind_t alg_kind, + const_dnnl_memory_desc_t src_desc, const_dnnl_memory_desc_t dst_desc, + const dnnl_dims_t strides, const dnnl_dims_t kernel, + const dnnl_dims_t dilation, const dnnl_dims_t padding_l, + const dnnl_dims_t padding_r, const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a pooling backward propagation +/// primitive. +/// +/// Arrays @p strides, @p kernel, @p dilation, @p padding_l and @p padding_r +/// contain values for spatial dimensions only and hence must have the same +/// number of elements as there are spatial dimensions. The order of values +/// is the same as in the tensor: depth (for 3D tensors), +/// height (for 3D and 2D tensors), and width. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind Pooling algorithm kind: either #dnnl_pooling_max, +/// #dnnl_pooling_avg_include_padding, or #dnnl_pooling_avg_exclude_padding. +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param strides Array of strides for spatial dimension. +/// @param kernel Array of kernel spatial dimensions. +/// @param dilation Array of dilations for spatial dimension. +/// @param padding_l Array of padding values for low indices for each spatial +/// dimension `([[front,] top,] left)`. +/// @param padding_r Array of padding values for high indices for each spatial +/// dimension `([[back,] bottom,] right)`. Can be NULL in which case +/// padding is considered to be symmetrical. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_pooling_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, const dnnl_dims_t strides, + const dnnl_dims_t kernel, const dnnl_dims_t dilation, + const dnnl_dims_t padding_l, const dnnl_dims_t padding_r, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_pooling + +/// @addtogroup dnnl_api_prelu +/// @{ + +/// Creates a primitive descriptor for a PReLU (leaky ReLU with trainable +/// alpha parameter) forward propagation primitive. +/// +/// @note +/// weights descriptor is allowed to be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param src_desc Source memory descriptor. +/// @param weights_desc Alpha parameters memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_prelu_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t weights_desc, + const_dnnl_memory_desc_t dst_desc, const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a PReLU (leaky ReLU with trainable +/// alpha parameter) backward propagation primitive. +/// +/// @note +/// weights descriptor and diff_weights descriptor are allowed +/// to be initialized with #dnnl_format_tag_any or with format_kind +/// set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param src_desc Source memory descriptor. +/// @param weights_desc Alpha parameters memory descriptor. +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_weights_desc Diff alpha parameters memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_prelu_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t weights_desc, + const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_weights_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_prelu + +/// @addtogroup dnnl_api_lrn +/// @{ + +/// Creates a primitive descriptor for an LRN forward propagation primitive. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param alg_kind LRN algorithm kind: either #dnnl_lrn_across_channels or +/// #dnnl_lrn_within_channel. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param local_size Regularization local size. +/// @param alpha The alpha regularization parameter. +/// @param beta The beta regularization parameter. +/// @param k The k regularization parameter. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_lrn_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_alg_kind_t alg_kind, + const_dnnl_memory_desc_t src_desc, const_dnnl_memory_desc_t dst_desc, + dnnl_dim_t local_size, float alpha, float beta, float k, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for an LRN backward propagation primitive. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param alg_kind LRN algorithm kind: either #dnnl_lrn_across_channels or +/// #dnnl_lrn_within_channel. +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param src_desc Source memory descriptor. +/// @param local_size Regularization local size. +/// @param alpha The alpha regularization parameter. +/// @param beta The beta regularization parameter. +/// @param k The k regularization parameter. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_lrn_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_memory_desc_t src_desc, dnnl_dim_t local_size, float alpha, + float beta, float k, const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_lrn + +/// @addtogroup dnnl_api_batch_normalization +/// @{ + +/// Creates a primitive descriptor for a batch normalization forward propagation +/// primitive. +/// +/// @note +/// In-place operation is supported: the dst can refer to the same memory +/// as the src. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param epsilon Batch normalization epsilon parameter. +/// @param flags Batch normalization flags (@ref dnnl_normalization_flags_t). +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_batch_normalization_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t dst_desc, float epsilon, unsigned flags, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a batch normalization backward +/// propagation primitive. +/// +/// @note +/// In-place operation is supported: the diff_dst can refer to the same +/// memory as the diff_src. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_backward_data and #dnnl_backward (diffs for all parameters are +/// computed in this case). +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param src_desc Source memory descriptor. +/// @param epsilon Batch normalization epsilon parameter. +/// @param flags Batch normalization flags (@ref dnnl_normalization_flags_t). +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_batch_normalization_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_memory_desc_t src_desc, float epsilon, unsigned flags, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_batch_normalization + +/// @addtogroup dnnl_api_group_normalization +/// @{ + +/// Creates a primitive descriptor for a group normalization forward propagation +/// primitive. +/// +/// @note +/// In-place operation is supported: the dst can refer to the same memory +/// as the src. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param groups Group normalization groups parameter. +/// @param epsilon Group normalization epsilon parameter. +/// @param flags Group normalization flags (@ref dnnl_normalization_flags_t). +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_group_normalization_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t dst_desc, dnnl_dim_t groups, float epsilon, + unsigned flags, const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a group normalization backward +/// propagation primitive. +/// +/// @note +/// In-place operation is supported: the diff_dst can refer to the same +/// memory as the diff_src. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_backward_data and #dnnl_backward (diffs for all parameters are +/// computed in this case). +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param src_desc Source memory descriptor. +/// @param groups Group normalization groups parameter. +/// @param epsilon Group normalization epsilon parameter. +/// @param flags Group normalization flags (@ref dnnl_normalization_flags_t). +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_group_normalization_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_memory_desc_t src_desc, dnnl_dim_t groups, float epsilon, + unsigned flags, const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_group_normalization + +/// @addtogroup dnnl_api_layer_normalization +/// @{ + +/// Creates a primitive descriptor for a layer normalization forward propagation +/// primitive. +/// +/// @note +/// In-place operation is supported: the dst can refer to the same memory +/// as the src. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param stat_desc Memory descriptor for mean and variance. If this +/// parameter is NULL, a zero memory descriptor, or a memory descriptor +/// with format_kind set to #dnnl_format_kind_undef, then the memory +/// descriptor for stats is derived from @p src_desc by removing the last +/// dimension. +/// @param epsilon Layer normalization epsilon parameter. +/// @param flags Layer normalization flags (@ref dnnl_normalization_flags_t). +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_layer_normalization_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t dst_desc, const_dnnl_memory_desc_t stat_desc, + float epsilon, unsigned flags, const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a layer normalization backward +/// propagation primitive. +/// +/// @note +/// In-place operation is supported: the diff_dst can refer to the same +/// memory as the diff_src. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_backward_data and #dnnl_backward (diffs for all parameters are +/// computed in this case). +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param src_desc Source memory descriptor. +/// @param stat_desc Memory descriptor for mean and variance. If this +/// parameter is NULL, a zero memory descriptor, or a memory descriptor +/// with format_kind set to #dnnl_format_kind_undef, then the memory +/// descriptor for stats is derived from @p src_desc by removing the last +/// dimension. +/// @param epsilon Layer normalization epsilon parameter. +/// @param flags Layer normalization flags (@ref dnnl_normalization_flags_t). +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_layer_normalization_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_memory_desc_t src_desc, const_dnnl_memory_desc_t stat_desc, + float epsilon, unsigned flags, const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a layer normalization forward propagation +/// primitive with a user-provided data type for the scale and shift +/// memory objects. +/// +/// @note +/// In-place operation is supported: the dst can refer to the same memory +/// as the src. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param stat_desc Memory descriptor for mean and variance. If this +/// parameter is NULL, a zero memory descriptor, or a memory descriptor +/// with format_kind set to #dnnl_format_kind_undef, then the memory +/// descriptor for stats is derived from @p src_desc by removing the last +/// dimension. +/// @param scale_shift_data_type Data type of scale and shift memory. If neither scale +/// nor shift flag are specified the parameter is ignored. +/// @param epsilon Layer normalization epsilon parameter. +/// @param flags Layer normalization flags (@ref dnnl_normalization_flags_t). +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API +dnnl_layer_normalization_forward_primitive_desc_create_v2( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t dst_desc, const_dnnl_memory_desc_t stat_desc, + dnnl_data_type_t scale_shift_data_type, float epsilon, unsigned flags, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a layer normalization backward +/// propagation primitive with a user-provided data type for the +/// scale and shift memory objects. +/// +/// @note +/// In-place operation is supported: the diff_dst can refer to the same +/// memory as the diff_src. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_backward_data and #dnnl_backward (diffs for all parameters are +/// computed in this case). +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param src_desc Source memory descriptor. +/// @param stat_desc Memory descriptor for mean and variance. If this +/// parameter is NULL, a zero memory descriptor, or a memory descriptor +/// with format_kind set to #dnnl_format_kind_undef, then the memory +/// descriptor for stats is derived from @p src_desc by removing the last +/// dimension. +/// @param diff_scale_shift_data_type Data type of diff scale and shift memory. If neither scale +/// nor shift flag are specified the parameter is ignored. +/// @param scale_shift_data_type Data type of scale and shift memory. If neither scale +/// nor shift flag are specified the parameter is ignored. +/// @param epsilon Layer normalization epsilon parameter. +/// @param flags Layer normalization flags (@ref dnnl_normalization_flags_t). +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API +dnnl_layer_normalization_backward_primitive_desc_create_v2( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_memory_desc_t src_desc, const_dnnl_memory_desc_t stat_desc, + dnnl_data_type_t diff_scale_shift_data_type, + dnnl_data_type_t scale_shift_data_type, float epsilon, unsigned flags, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_layer_normalization + +/// @addtogroup dnnl_api_inner_product +/// @{ + +/// Creates a primitive descriptor for an inner product forward propagation +/// primitive. +/// +/// @note +/// Memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param src_desc Source memory descriptor. +/// @param weights_desc Weights memory descriptor. +/// @param bias_desc Bias memory descriptor. Passing NULL, a zero memory +/// descriptor, or a memory descriptor with format_kind set to +/// #dnnl_format_kind_undef disables the bias term. +/// @param dst_desc Destination memory descriptor. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_inner_product_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t weights_desc, + const_dnnl_memory_desc_t bias_desc, const_dnnl_memory_desc_t dst_desc, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for an inner product backward propagation +/// primitive. +/// +/// @note +/// Memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param diff_src_desc Diff source memory descriptor. +/// @param weights_desc Weights memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_inner_product_backward_data_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t weights_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for an inner product weights gradient +/// primitive. +/// +/// @note +/// Memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive_descriptor. +/// @param engine Engine to use. +/// @param src_desc Source memory descriptor. +/// @param diff_weights_desc Diff weights memory descriptor. +/// @param diff_bias_desc Diff bias memory descriptor. Passing NULL, a zero +/// memory descriptor, or a memory descriptor with format_kind set to +/// #dnnl_format_kind_undef disables the bias term. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API +dnnl_inner_product_backward_weights_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t diff_weights_desc, + const_dnnl_memory_desc_t diff_bias_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_inner_product + +/// @addtogroup dnnl_api_attributes +/// @{ + +/// Set quantization scale and shift parameters for RNN data tensors. +/// +/// For performance reasons, the low-precision configuration of the RNN +/// primitives expects input activations to have the unsigned 8-bit integer +/// data type. The scale and shift parameters are used to quantize +/// floating-point data to unsigned integer and must be passed to the RNN +/// primitive using attributes. +/// +/// The quantization formula is `scale * data + shift`. +/// +/// @note +/// Quantization scale and shift are common for src_layer, src_iter, +/// dst_iter, and dst_layer. +/// +/// Example usage: +/// @code +/// // RNN parameters +/// int l = 2, t = 2, mb = 32, sic = 32, slc = 32, dic = 32, dlc = 32; +/// // Activations quantization parameters +/// float scale = 63.f, shift = 64.f; +/// +/// dnnl_primitive_attr_t rnn_attr; +/// // Create default attributes +/// dnnl_primitive_attr_create(&rnn_attr); +/// +/// // Set scale and shift for int8 quantization of activation +/// dnnl_primitive_attr_set_rnn_data_qparams(rnn_attr, scale, shift); +/// +/// // Create an RNN primitive descriptor. +/// dnnl_primitive_desc_t rnn_pd; +/// dnnl_vanilla_rnn_forward_primitive_desc_create(&rnn_pd, +/// engine, /* arguments */, attr); +/// @endcode +/// +/// @param attr Primitive attributes. +/// @param scale The value to scale the data by. +/// @param shift The value to shift the data by. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_rnn_data_qparams( + dnnl_primitive_attr_t attr, const float scale, const float shift); + +/// Returns the quantization scale and shift parameters for RNN data tensors. +/// +/// @note +/// Quantization scale and shift are common for src_layer, src_iter, +/// dst_iter, and dst_layer. +/// +/// @param attr Primitive attributes. +/// @param scale The value to scale the data by. +/// @param shift The value to shift the data by. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_rnn_data_qparams( + const_dnnl_primitive_attr_t attr, float *scale, float *shift); + +/// Sets quantization scaling factors for RNN weights tensors. The +/// low-precision configuration of the RNN primitives expects input weights to +/// use the signed 8-bit integer data type. The scaling factors are used to +/// quantize floating-point data to signed integer and must be passed to RNN +/// primitives using attributes. +/// +/// @note +/// The dimension order is always native and does not depend on the actual +/// layout used. For example, five-dimensional weights always have (l, d, +/// i, g, o) logical dimension ordering. +/// +/// @note +/// Quantization scales are common for weights_layer and weights_iteration +/// +/// @param attr Primitive attributes. +/// @param count Number of elements in the @p scales array. +/// @param mask Scaling factors correspondence mask that defines the +/// correspondence between the output tensor dimensions and the @p +/// scales vector. The set i-th bit indicates that a dedicated scaling +/// factor should be used for each index along that dimension. Set the +/// mask to 0 to use a common scaling factor for the whole output +/// tensor. +/// @param scales Array of output scaling factors that must contain @p count +/// values and the following equality must hold: +/// \f[count = \prod\limits_{d \in mask} weights.dims[d].\f] +/// Violations can only be detected when the attributes are used to create +/// a primitive descriptor. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_rnn_weights_qparams( + dnnl_primitive_attr_t attr, dnnl_dim_t count, int mask, + const float *scales); + +/// Returns the quantization scaling factors for RNN weights tensors. +/// +/// @param attr Primitive attributes. +/// @param count Number of elements in the @p scales array. +/// @param mask Scaling factors correspondence mask that defines the +/// correspondence between the output tensor dimensions and the @p +/// scales vector. The set i-th bit indicates that a dedicated scaling +/// factor should be used for each index along that dimension. Set the +/// mask to 0 to use a common scaling factor for the whole output +/// tensor. +/// @param scales Array of output scaling factors that contain @p count +/// values and the following equality must hold: +/// \f[count = \prod\limits_{d \in mask} weights.dims[d].\f] +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_rnn_weights_qparams( + const_dnnl_primitive_attr_t attr, dnnl_dim_t *count, int *mask, + const float **scales); + +/// Sets quantization scaling factors for RNN projection weights tensors. The +/// low-precision configuration of the RNN primitives expects input weights to +/// use the signed 8-bit integer data type. The scaling factors are used to +/// quantize floating-point data to signed integer and must be passed to RNN +/// primitives using attributes. +/// +/// @note +/// The dimension order is always native and does not depend on the actual +/// layout used. For example, five-dimensional weights always have (l, d, +/// i, g, o) logical dimension ordering. +/// +/// @param attr Primitive attributes. +/// @param count Number of elements in the @p scales array. +/// @param mask Scaling factors correspondence mask that defines the +/// correspondence between the output tensor dimensions and the @p +/// scales vector. The set i-th bit indicates that a dedicated scaling +/// factor should be used for each index along that dimension. Set the +/// mask to 0 to use a common scaling factor for the whole output +/// tensor. +/// @param scales Array of output scaling factors that must contain @p count +/// values and the following equality must hold: +/// \f[count = \prod\limits_{d \in mask} weights.dims[d].\f] +/// Violations can only be detected when the attributes are used to create +/// a primitive descriptor. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_set_rnn_weights_projection_qparams( + dnnl_primitive_attr_t attr, dnnl_dim_t count, int mask, + const float *scales); + +/// Returns the quantization scaling factors for RNN projection weights tensors. +/// +/// @param attr Primitive attributes. +/// @param count Number of elements in the @p scales array. +/// @param mask Scaling factors correspondence mask that defines the +/// correspondence between the output tensor dimensions and the @p +/// scales vector. The set i-th bit indicates that a dedicated scaling +/// factor should be used for each index along that dimension. Set the +/// mask to 0 to use a common scaling factor for the whole output +/// tensor. +/// @param scales Array of output scaling factors that contain @p count +/// values and the following equality must hold: +/// \f[count = \prod\limits_{d \in mask} weights.dims[d].\f] +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_primitive_attr_get_rnn_weights_projection_qparams( + const_dnnl_primitive_attr_t attr, dnnl_dim_t *count, int *mask, + const float **scales); + +/// @} dnnl_api_attributes + +/// @addtogroup dnnl_api_rnn +/// @{ + +/// Creates a primitive descriptor for vanilla RNN forward propagation +/// primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc, +/// - @p bias_desc, +/// - @p dst_iter_desc. +/// +/// This would then indicate that the RNN forward propagation primitive should +/// not use them and should default to zero values instead. +/// +/// @note +/// All memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param activation Activation kind. Possible values are #dnnl_eltwise_relu, +/// #dnnl_eltwise_tanh or #dnnl_eltwise_logistic. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param flags Unused. +/// @param alpha Negative slope if activation is #dnnl_eltwise_relu. +/// @param beta Unused. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_vanilla_rnn_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const dnnl_alg_kind_t activation, + const dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, unsigned flags, float alpha, + float beta, const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for vanilla RNN backward propagation +/// primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc together with @p diff_src_iter_desc, +/// - @p bias_desc together with @p diff_bias_desc, +/// - @p dst_iter_desc together with @p diff_dst_iter_desc. +/// +/// This would then indicate that the RNN backward propagation primitive should +/// not use the respective data and should use zero values instead. +/// +/// @note +/// All memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Must be #dnnl_backward. +/// @param activation Activation kind. Possible values are #dnnl_eltwise_relu, +/// #dnnl_eltwise_tanh or #dnnl_eltwise_logistic. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param diff_src_layer_desc Memory descriptor for the diff of input vector. +/// @param diff_src_iter_desc Memory descriptor for the diff of input recurrent +/// hidden state vector. +/// @param diff_weights_layer_desc Memory descriptor for the diff of weights +/// applied to the layer input. +/// @param diff_weights_iter_desc Memory descriptor for the diff of weights +/// applied to the recurrent input. +/// @param diff_bias_desc Diff bias memory descriptor. +/// @param diff_dst_layer_desc Memory descriptor for the diff of output +/// vector. +/// @param diff_dst_iter_desc Memory descriptor for the diff of output +/// recurrent hidden state vector. +/// @param flags Unused. +/// @param alpha Negative slope if activation is #dnnl_eltwise_relu. +/// @param beta Unused. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_vanilla_rnn_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, const dnnl_alg_kind_t activation, + const dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, + const_dnnl_memory_desc_t diff_src_layer_desc, + const_dnnl_memory_desc_t diff_src_iter_desc, + const_dnnl_memory_desc_t diff_weights_layer_desc, + const_dnnl_memory_desc_t diff_weights_iter_desc, + const_dnnl_memory_desc_t diff_bias_desc, + const_dnnl_memory_desc_t diff_dst_layer_desc, + const_dnnl_memory_desc_t diff_dst_iter_desc, unsigned flags, + float alpha, float beta, const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for an LSTM forward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc together with @p src_iter_c_desc, +/// - @p weights_peephole_desc, +/// - @p bias_desc, +/// - @p dst_iter_desc together with @p dst_iter_c_desc. +/// +/// This would then indicate that the LSTM forward propagation primitive should +/// not use them and should default to zero values instead. +/// +/// The @p weights_projection_desc could either be @c NULL or point to a zero +/// memory descriptor. This would then indicate that the LSTM doesn't have +/// recurrent projection layer. +/// +/// @note +/// All memory descriptors can be initialized with #dnnl_format_tag_any or +/// with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param src_iter_c_desc Memory descriptor for the input recurrent cell +/// state vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param weights_peephole_desc Memory descriptor for the weights applied to +/// the cell states (according to the Peephole LSTM formula). +/// @param weights_projection_desc Memory descriptor for the weights applied to +/// the hidden states to get the recurrent projection (according to the +/// Projection LSTM formula). +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param dst_iter_c_desc Memory descriptor for the output recurrent cell +/// state vector. +/// @param flags Unused. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_lstm_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t src_iter_c_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t weights_peephole_desc, + const_dnnl_memory_desc_t weights_projection_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, + const_dnnl_memory_desc_t dst_iter_c_desc, unsigned flags, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for an LSTM backward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc together with @p src_iter_c_desc, @p diff_src_iter_desc, +/// and @p diff_src_iter_c_desc, +/// - @p weights_peephole_desc together with @p diff_weights_peephole_desc, +/// - @p bias_desc together with @p diff_bias_desc, +/// - @p dst_iter_desc together with @p dst_iter_c_desc, @p diff_dst_iter_desc, +/// and @p diff_dst_iter_c_desc. +/// +/// This would then indicate that the LSTM backward propagation primitive +/// should not use them and should default to zero values instead. +/// +/// The @p weights_projection_desc together with @p +/// diff_weights_projection_desc could either be @c NULL or point to a zero +/// memory descriptor. This would then indicate that the LSTM doesn't have +/// recurrent projection layer. +/// +/// @note +/// All memory descriptors can be initialized with #dnnl_format_tag_any or +/// with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Must be #dnnl_backward. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param src_iter_c_desc Memory descriptor for the input recurrent cell +/// state vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param weights_peephole_desc Memory descriptor for the weights applied to +/// the cell states (according to the Peephole LSTM formula). +/// @param weights_projection_desc Memory descriptor for the weights applied to +/// the hidden states to get the recurrent projection (according to the +/// Projection LSTM formula). +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param dst_iter_c_desc Memory descriptor for the output recurrent cell +/// state vector. +/// @param diff_src_layer_desc Memory descriptor for the diff of input vector. +/// @param diff_src_iter_desc Memory descriptor for the diff of input recurrent +/// hidden state vector. +/// @param diff_src_iter_c_desc Memory descriptor for the diff of input +/// recurrent cell state vector. +/// @param diff_weights_layer_desc Memory descriptor for the diff of weights +/// applied to the layer input. +/// @param diff_weights_iter_desc Memory descriptor for the diff of weights +/// applied to the recurrent input. +/// @param diff_weights_peephole_desc Memory descriptor for the diff of weights +/// applied to the cell states (according to the Peephole LSTM formula). +/// @param diff_weights_projection_desc Memory descriptor for the diff of +/// weights applied to the hidden states to get the recurrent projection +/// (according to the Projection LSTM formula). +/// @param diff_bias_desc Diff bias memory descriptor. +/// @param diff_dst_layer_desc Memory descriptor for the diff of output +/// vector. +/// @param diff_dst_iter_desc Memory descriptor for the diff of output +/// recurrent hidden state vector. +/// @param diff_dst_iter_c_desc Memory descriptor for the diff of output +/// recurrent cell state vector. +/// @param flags Unused. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_lstm_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t src_iter_c_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t weights_peephole_desc, + const_dnnl_memory_desc_t weights_projection_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, + const_dnnl_memory_desc_t dst_iter_c_desc, + const_dnnl_memory_desc_t diff_src_layer_desc, + const_dnnl_memory_desc_t diff_src_iter_desc, + const_dnnl_memory_desc_t diff_src_iter_c_desc, + const_dnnl_memory_desc_t diff_weights_layer_desc, + const_dnnl_memory_desc_t diff_weights_iter_desc, + const_dnnl_memory_desc_t diff_weights_peephole_desc, + const_dnnl_memory_desc_t diff_weights_projection_desc, + const_dnnl_memory_desc_t diff_bias_desc, + const_dnnl_memory_desc_t diff_dst_layer_desc, + const_dnnl_memory_desc_t diff_dst_iter_desc, + const_dnnl_memory_desc_t diff_dst_iter_c_desc, unsigned flags, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for GRU forward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc, +/// - @p bias_desc, +/// - @p dst_iter_desc. +/// +/// This would then indicate that the GRU forward propagation primitive should +/// not use them and should default to zero values instead. +/// +/// @note +/// All memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param flags Unused. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_gru_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, unsigned flags, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for GRU backward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc together with @p diff_src_iter_desc, +/// - @p bias_desc together with @p diff_bias_desc, +/// - @p dst_iter_desc together with @p diff_dst_iter_desc. +/// +/// This would then indicate that the GRU backward propagation primitive +/// should not use them and should default to zero values instead. +/// +/// @note +/// All memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Must be #dnnl_backward. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param diff_src_layer_desc Memory descriptor for the diff of input vector. +/// @param diff_src_iter_desc Memory descriptor for the diff of input recurrent +/// hidden state vector. +/// @param diff_weights_layer_desc Memory descriptor for the diff of weights +/// applied to the layer input. +/// @param diff_weights_iter_desc Memory descriptor for the diff of weights +/// applied to the recurrent input. +/// @param diff_bias_desc Diff bias memory descriptor. +/// @param diff_dst_layer_desc Memory descriptor for the diff of output +/// vector. +/// @param diff_dst_iter_desc Memory descriptor for the diff of output +/// recurrent hidden state vector. +/// @param flags Unused. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_gru_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, + const_dnnl_memory_desc_t diff_src_layer_desc, + const_dnnl_memory_desc_t diff_src_iter_desc, + const_dnnl_memory_desc_t diff_weights_layer_desc, + const_dnnl_memory_desc_t diff_weights_iter_desc, + const_dnnl_memory_desc_t diff_bias_desc, + const_dnnl_memory_desc_t diff_dst_layer_desc, + const_dnnl_memory_desc_t diff_dst_iter_desc, unsigned flags, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// Creates a descriptor for LBR GRU forward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc, +/// - @p bias_desc, +/// - @p dst_iter_desc. +/// +/// This would then indicate that the LBR GRU forward propagation primitive +/// should not use them and should default to zero values instead. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param flags Unused. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_lbr_gru_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, unsigned flags, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for LBR GRU backward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc together with @p diff_src_iter_desc, +/// - @p bias_desc together with @p diff_bias_desc, +/// - @p dst_iter_desc together with @p diff_dst_iter_desc. +/// +/// This would then indicate that the LBR GRU backward propagation primitive +/// should not use them and should default to zero values instead. +/// +/// @note +/// All memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Must be #dnnl_backward. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param diff_src_layer_desc Memory descriptor for the diff of input vector. +/// @param diff_src_iter_desc Memory descriptor for the diff of input recurrent +/// hidden state vector. +/// @param diff_weights_layer_desc Memory descriptor for the diff of weights +/// applied to the layer input. +/// @param diff_weights_iter_desc Memory descriptor for the diff of weights +/// applied to the recurrent input. +/// @param diff_bias_desc Diff bias memory descriptor. +/// @param diff_dst_layer_desc Memory descriptor for the diff of output +/// vector. +/// @param diff_dst_iter_desc Memory descriptor for the diff of output +/// recurrent hidden state vector. +/// @param flags Unused. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_lbr_gru_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, + const_dnnl_memory_desc_t diff_src_layer_desc, + const_dnnl_memory_desc_t diff_src_iter_desc, + const_dnnl_memory_desc_t diff_weights_layer_desc, + const_dnnl_memory_desc_t diff_weights_iter_desc, + const_dnnl_memory_desc_t diff_bias_desc, + const_dnnl_memory_desc_t diff_dst_layer_desc, + const_dnnl_memory_desc_t diff_dst_iter_desc, unsigned flags, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for AUGRU forward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc, +/// - @p bias_desc, +/// - @p dst_iter_desc. +/// +/// This would then indicate that the AUGRU forward propagation primitive should +/// not use them and should default to zero values instead. +/// +/// @note +/// All memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param attention_desc Memory descriptor for the attention vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param flags Unused. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_augru_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t attention_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, unsigned flags, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for AUGRU backward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc together with @p diff_src_iter_desc, +/// - @p bias_desc together with @p diff_bias_desc, +/// - @p dst_iter_desc together with @p diff_dst_iter_desc. +/// +/// This would then indicate that the AUGRU backward propagation primitive +/// should not use them and should default to zero values instead. +/// +/// @note +/// All memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Must be #dnnl_backward. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param attention_desc Memory descriptor for the attention vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param diff_src_layer_desc Memory descriptor for the diff of input vector. +/// @param diff_src_iter_desc Memory descriptor for the diff of input recurrent +/// hidden state vector. +/// @param diff_attention_desc Memory descriptor for the diff of attention vector. +/// @param diff_weights_layer_desc Memory descriptor for the diff of weights +/// applied to the layer input. +/// @param diff_weights_iter_desc Memory descriptor for the diff of weights +/// applied to the recurrent input. +/// @param diff_bias_desc Diff bias memory descriptor. +/// @param diff_dst_layer_desc Memory descriptor for the diff of output +/// vector. +/// @param diff_dst_iter_desc Memory descriptor for the diff of output +/// recurrent hidden state vector. +/// @param flags Unused. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_augru_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t attention_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, + const_dnnl_memory_desc_t diff_src_layer_desc, + const_dnnl_memory_desc_t diff_src_iter_desc, + const_dnnl_memory_desc_t diff_attention_desc, + const_dnnl_memory_desc_t diff_weights_layer_desc, + const_dnnl_memory_desc_t diff_weights_iter_desc, + const_dnnl_memory_desc_t diff_bias_desc, + const_dnnl_memory_desc_t diff_dst_layer_desc, + const_dnnl_memory_desc_t diff_dst_iter_desc, unsigned flags, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for LBR AUGRU forward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc, +/// - @p bias_desc, +/// - @p dst_iter_desc. +/// +/// This would then indicate that the LBR AUGRU forward propagation primitive +/// should not use them and should default to zero values instead. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param attention_desc Memory descriptor for the attention vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param flags Unused. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_lbr_augru_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t attention_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, unsigned flags, + const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for LBR AUGRU backward propagation primitive. +/// +/// The following arguments may either be @c NULL or point to a zero memory +/// descriptor: +/// - @p src_iter_desc together with @p diff_src_iter_desc, +/// - @p bias_desc together with @p diff_bias_desc, +/// - @p dst_iter_desc together with @p diff_dst_iter_desc. +/// +/// This would then indicate that the LBR AUGRU backward propagation primitive +/// should not use them and should default to zero values instead. +/// +/// @note +/// All memory descriptors can be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Must be #dnnl_backward. +/// @param direction RNN direction. See @ref dnnl_rnn_direction_t for more +/// info. +/// @param src_layer_desc Memory descriptor for the input vector. +/// @param src_iter_desc Memory descriptor for the input recurrent hidden +/// state vector. +/// @param attention_desc Memory descriptor for the attention vector. +/// @param weights_layer_desc Memory descriptor for the weights applied to the +/// layer input. +/// @param weights_iter_desc Memory descriptor for the weights applied to the +/// recurrent input. +/// @param bias_desc Bias memory descriptor. +/// @param dst_layer_desc Memory descriptor for the output vector. +/// @param dst_iter_desc Memory descriptor for the output recurrent hidden +/// state vector. +/// @param diff_src_layer_desc Memory descriptor for the diff of input vector. +/// @param diff_src_iter_desc Memory descriptor for the diff of input recurrent +/// hidden state vector. +/// @param diff_attention_desc Memory descriptor for the diff of attention vector. +/// @param diff_weights_layer_desc Memory descriptor for the diff of weights +/// applied to the layer input. +/// @param diff_weights_iter_desc Memory descriptor for the diff of weights +/// applied to the recurrent input. +/// @param diff_bias_desc Diff bias memory descriptor. +/// @param diff_dst_layer_desc Memory descriptor for the diff of output +/// vector. +/// @param diff_dst_iter_desc Memory descriptor for the diff of output +/// recurrent hidden state vector. +/// @param flags Unused. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_lbr_augru_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_rnn_direction_t direction, + const_dnnl_memory_desc_t src_layer_desc, + const_dnnl_memory_desc_t src_iter_desc, + const_dnnl_memory_desc_t attention_desc, + const_dnnl_memory_desc_t weights_layer_desc, + const_dnnl_memory_desc_t weights_iter_desc, + const_dnnl_memory_desc_t bias_desc, + const_dnnl_memory_desc_t dst_layer_desc, + const_dnnl_memory_desc_t dst_iter_desc, + const_dnnl_memory_desc_t diff_src_layer_desc, + const_dnnl_memory_desc_t diff_src_iter_desc, + const_dnnl_memory_desc_t diff_attention_desc, + const_dnnl_memory_desc_t diff_weights_layer_desc, + const_dnnl_memory_desc_t diff_weights_iter_desc, + const_dnnl_memory_desc_t diff_bias_desc, + const_dnnl_memory_desc_t diff_dst_layer_desc, + const_dnnl_memory_desc_t diff_dst_iter_desc, unsigned flags, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_rnn + +/// @addtogroup dnnl_api_matmul +/// @{ + +/// Creates a primitive descriptor for a matrix multiplication primitive. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param src_desc Source memory descriptor (matrix A) +/// @param weights_desc Weights memory descriptor (matrix B) +/// @param bias_desc Bias memory descriptor. Passing NULL, a zero memory +/// descriptor, or a memory descriptor with format_kind set to +/// #dnnl_format_kind_undef disables the bias term. +/// @param dst_desc Destination memory descriptor (matrix C). +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_matmul_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t weights_desc, + const_dnnl_memory_desc_t bias_desc, const_dnnl_memory_desc_t dst_desc, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_matmul + +/// @addtogroup dnnl_api_resampling Resampling +/// @{ + +/// Creates a primitive descriptor for a resampling forward propagation +/// primitive. +/// +/// @note +/// Destination memory descriptor is allowed to be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param prop_kind Propagation kind. Possible values are +/// #dnnl_forward_training and #dnnl_forward_inference. +/// @param alg_kind resampling algorithm kind: either #dnnl_resampling_nearest, +/// or #dnnl_resampling_linear. +/// @param factors Array of scaling factors for spatial dimension. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_resampling_forward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_prop_kind_t prop_kind, dnnl_alg_kind_t alg_kind, + const float *factors, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t dst_desc, const_dnnl_primitive_attr_t attr); + +/// Creates a primitive descriptor for a resampling backward propagation +/// primitive. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind resamplinging algorithm kind: either +/// #dnnl_resampling_nearest, or #dnnl_resampling_linear. +/// @param diff_src_desc Diff source memory descriptor. +/// @param diff_dst_desc Diff destination memory descriptor. +/// @param factors Array of scaling factors for spatial dimension. +/// @param hint_fwd_pd Primitive descriptor for a respective forward propagation +/// primitive. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +/// +dnnl_status_t DNNL_API dnnl_resampling_backward_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const float *factors, + const_dnnl_memory_desc_t diff_src_desc, + const_dnnl_memory_desc_t diff_dst_desc, + const_dnnl_primitive_desc_t hint_fwd_pd, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_resampling + +/// @addtogroup dnnl_api_reduction Reduction +/// @{ + +/// Creates a primitive descriptor for a reduction primitive. +/// +/// @note +/// Destination memory descriptor is allowed to be initialized with +/// #dnnl_format_tag_any or with format_kind set to #dnnl_format_kind_any. +/// +/// @param primitive_desc Output primitive descriptor. +/// @param engine Engine to use. +/// @param alg_kind reduction algorithm kind. Possible values: +/// #dnnl_reduction_max, #dnnl_reduction_min, #dnnl_reduction_sum, +/// #dnnl_reduction_mul, #dnnl_reduction_mean, #dnnl_reduction_norm_lp_max, +/// #dnnl_reduction_norm_lp_sum, #dnnl_reduction_norm_lp_power_p_max, +/// #dnnl_reduction_norm_lp_power_p_sum. +/// @param p Algorithm specific parameter. For Lp-norm algorithms, must be a +/// finite value >= 1.0. +/// @param eps Algorithm specific parameter. +/// @param src_desc Source memory descriptor. +/// @param dst_desc Destination memory descriptor. +/// @param attr Primitive attributes (can be NULL). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_reduction_primitive_desc_create( + dnnl_primitive_desc_t *primitive_desc, dnnl_engine_t engine, + dnnl_alg_kind_t alg_kind, const_dnnl_memory_desc_t src_desc, + const_dnnl_memory_desc_t dst_desc, float p, float eps, + const_dnnl_primitive_attr_t attr); + +/// @} dnnl_api_reduction + +/// @} dnnl_api_primitives + +/// @addtogroup dnnl_api_primitive_cache +/// @{ + +/// Returns the number of primitives that can be held in the primitive cache +/// at the same time. +/// +/// @param capacity Primitive cache capacity to query. Concurrently +/// accessing @p capacity is safe. +/// @returns #dnnl_invalid_arguments/#dnnl::status::invalid_arguments if the +/// @p capacity value is invalid, and #dnnl_success/#dnnl::status::success on +/// success. +dnnl_status_t DNNL_API dnnl_get_primitive_cache_capacity(int *capacity); + +/// Sets a number of primitives that can be held in the primitive cache +/// at a time. +/// +/// @param capacity Primitive cache capacity to set. If a new @p capacity is +/// less than a number of primitives that the primitive cache already has +/// then the excess entries will be evicted. Setting the @p capacity to 0 +/// clears the primitive cache and disables it. Concurrently modifying +/// @p capacity is safe. +/// @returns #dnnl_invalid_arguments/#dnnl::status::invalid_arguments if the +/// @p capacity value is invalid, and #dnnl_success/#dnnl::status::success on +/// success. +dnnl_status_t DNNL_API dnnl_set_primitive_cache_capacity(int capacity); + +/// @} dnnl_api_primitive_cache + +/// @addtogroup dnnl_api_service +/// @{ + +/// Configures dumping of JIT-generated code. +/// +/// @note +/// This setting overrides the DNNL_JIT_DUMP environment variable. +/// +/// @param enable Flag value. Set to 0 to disable and set to 1 to enable. +/// @returns #dnnl_invalid_arguments/#dnnl::status::invalid_arguments if the +/// @p flag value is invalid, and #dnnl_success/#dnnl::status::success on +/// success. +dnnl_status_t DNNL_API dnnl_set_jit_dump(int enable); + +/// Sets library profiling flags. The flags define which profilers are +/// supported. +/// +/// @note +/// This setting overrides DNNL_JIT_PROFILE environment variable. +/// +/// @sa @ref dev_guide_profilers +/// +/// @param flags Profiling flags that can contain the following bits: +/// - @ref DNNL_JIT_PROFILE_VTUNE -- integration with VTune Profiler +/// (on by default) +/// - @ref DNNL_JIT_PROFILE_LINUX_JITDUMP -- produce Linux-specific +/// jit-pid.dump output (off by default). The location of the output +/// is controlled via JITDUMPDIR environment variable or via +/// dnnl_set_jit_profiling_jitdumpdir() function. +/// - @ref DNNL_JIT_PROFILE_LINUX_PERFMAP -- produce Linux-specific +/// perf-pid.map output (off by default). The output is always placed +/// into /tmp. +/// +/// Passing @ref DNNL_JIT_PROFILE_NONE disables profiling completely. +/// +/// @returns #dnnl_invalid_arguments/#dnnl::status::invalid_arguments if the +/// @p flags value is invalid, and #dnnl_success/#dnnl::status::success on +/// success. +dnnl_status_t DNNL_API dnnl_set_jit_profiling_flags(unsigned flags); + +/// Sets JIT dump output path. Only applicable to Linux and is only +/// used when profiling flags have DNNL_JIT_PROFILE_LINUX_PERF bit set. +/// +/// After the first JIT kernel is generated, the jitdump output will be placed +/// into temporary directory created using the mkdtemp template +/// 'dir/.debug/jit/dnnl.XXXXXX'. +/// +/// @sa @ref dev_guide_profilers +/// +/// @note +/// This setting overrides JITDUMPDIR environment variable. If +/// JITDUMPDIR is not set, and this function is never called, the path +/// defaults to HOME. Passing NULL reverts the value to default. +/// +/// @note +/// The directory is accessed only when the first JIT kernel is being +/// created. JIT profiling will be disabled in case of any errors +/// accessing or creating this directory. +/// +/// @param dir JIT dump output path. +/// @returns #dnnl_success/#dnnl::status::success if the +/// output directory was set correctly and an error status otherwise. +/// @returns #dnnl_unimplemented/#dnnl::status::unimplemented on Windows. +dnnl_status_t DNNL_API dnnl_set_jit_profiling_jitdumpdir(const char *dir); + +/// Sets the maximal ISA the library can dispatch to on the CPU. See +/// #dnnl_cpu_isa_t and #dnnl::cpu_isa for the list of the values accepted by +/// the C and C++ API functions respectively. +/// +/// This function has effect only once, and returns an error on subsequent +/// calls. It should also be invoked before any other oneDNN API call, otherwise +/// it may return an error. +/// +/// This function overrides the DNNL_MAX_CPU_ISA environment variable. The +/// environment variable can be set to the desired maximal ISA name in upper +/// case and with dnnl_cpu_isa prefix removed. For example: +/// `DNNL_MAX_CPU_ISA=AVX2`. +/// +/// @note +/// The ISAs are only partially ordered: +/// - SSE41 < AVX < AVX2 < AVX2_VNNI < AVX2_VNNI_2, +/// - AVX2 < AVX512_CORE < AVX512_CORE_VNNI < AVX512_CORE_BF16 +/// < AVX10_1_512 < AVX10_2_512, +/// - AVX10_1_512 < AVX10_1_512_AMX < AVX10_1_512_AMX_FP16 +/// < AVX10_2_512_AMX_2, +/// - AVX2_VNNI < AVX10_1_512, +/// - AVX10_2_512 < AVX10_2_512_AMX_2 +/// +/// Aliases: +/// - AVX512_CORE_FP16 = AVX10_1_512 +/// - AVX512_CORE_AMX = AVX10_1_512_AMX +/// - AVX512_CORE_AMX_FP16 = AVX10_1_512_AMX_FP16 +/// +/// @sa @ref dev_guide_cpu_dispatcher_control for more details +/// +/// @param isa Maximal ISA the library should dispatch to. Pass +/// #dnnl_cpu_isa_default/#dnnl::cpu_isa::isa_default to remove ISA restrictions +/// (except for ISAs with initial support in the library). +/// @returns #dnnl_success/#dnnl::status::success on success and a +/// #dnnl_invalid_arguments/#dnnl::status::invalid_arguments if the @p isa +/// parameter is invalid or the ISA cannot be changed at this time. +/// @returns #dnnl_unimplemented/#dnnl::status::unimplemented if the feature +/// was disabled at build time (see @ref dev_guide_build_options for more +/// details). +dnnl_status_t DNNL_API dnnl_set_max_cpu_isa(dnnl_cpu_isa_t isa); + +/// Gets the maximal ISA the library can dispatch to on the CPU. See +/// #dnnl_cpu_isa_t and #dnnl::cpu_isa for the list of the values returned by +/// the C and C++ API functions respectively. +/// +/// @sa @ref dev_guide_cpu_dispatcher_control for more details +/// +/// @returns #dnnl_cpu_isa_t value reflecting the maximal ISA the library may +/// dispatch to. +dnnl_cpu_isa_t DNNL_API dnnl_get_effective_cpu_isa(void); + +/// Sets the hints flag for the CPU ISA. See #dnnl_cpu_isa_hints_t and +/// #dnnl::cpu_isa_hints for the list of the values accepted by the C and C++ +/// API functions respectively. +/// +/// This function has effect only once, and returns an error on subsequent +/// calls. It should also be invoked before any other oneDNN API call, otherwise +/// it may return an error. +/// +/// This function overrides the DNNL_CPU_ISA_HINTS environment variable. +/// @sa @ref dev_guide_cpu_isa_hints for more details +/// +/// @param isa_hints CPU ISA hints to be passed over to the implementation. +/// Pass #dnnl_cpu_isa_no_hints/#dnnl::cpu_isa_hints::no_hints to use +/// default features i.e. no hints. +/// @returns #dnnl_success/#dnnl::status::success on success and a +/// #dnnl_runtime_error/#dnnl::status::runtime_error if the ISA hints cannot +/// be specified at the current time. +/// @returns #dnnl_unimplemented/#dnnl::status::unimplemented if the feature +/// was disabled at build time (see @ref dev_guide_build_options for more +/// details). +dnnl_status_t DNNL_API dnnl_set_cpu_isa_hints(dnnl_cpu_isa_hints_t isa_hints); + +/// Gets the ISA specific hints that library can follow. See +/// #dnnl_cpu_isa_hints_t and #dnnl::cpu_isa_hints for the list of the values +/// returned by the C and C++ API functions respectively. +/// +/// @sa @ref dev_guide_cpu_isa_hints for more details +/// +/// @returns #dnnl_cpu_isa_hints_t value reflecting the ISA specific hints the +/// library can follow. +dnnl_cpu_isa_hints_t DNNL_API dnnl_get_cpu_isa_hints(void); + +/// @} dnnl_api_service + +#ifdef DNNL_EXPERIMENTAL_PROFILING + +/// @addtogroup dnnl_api_profiling Profiling +/// @{ + +/// Resets a profiler's state. +/// +/// @param stream Stream associated with the profiler. +/// +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_reset_profiling(dnnl_stream_t stream); + +/// Queries profiling data. The profiling data accumulates for each primitive +/// execution. The @p num_entries will be equal to the number of executions +/// since the last `dnnl_reset_profiling` call. In order to query the +/// @p num_entries the @p data parameter should be NULL. When @p data is NULL +/// then the @p data_kind parameter is ignored. +/// +/// The profiling data can be reset by calling #dnnl_reset_profiling. +/// +/// @note +/// It is required to wait for all submitted primitives to complete +/// using #dnnl_stream_wait prior to querying profiling data. +/// +/// @param stream Stream that was used for executing a primitive that +/// is being profiled. +/// @param data_kind Profiling data kind to query. +/// @param num_entries Number of profiling data entries. +/// @param data Profiling data. +/// +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_query_profiling_data(dnnl_stream_t stream, + dnnl_profiling_data_kind_t data_kind, int *num_entries, uint64_t *data); + +/// @} dnnl_api_profiling +#endif + +/// @addtogroup dnnl_api_blas +/// @{ + +/// Performs single-precision matrix-matrix multiply. +/// +/// The operation is defined as: +/// +/// `C := alpha * op( A ) * op( B ) + beta * C` +/// +/// where +/// - `op( X ) = X` or `op( X ) = X**T`, +/// - `alpha` and `beta` are scalars, and +/// - `A`, `B`, and `C` are matrices: +/// - `op( A )` is an `MxK` matrix, +/// - `op( B )` is an `KxN` matrix, +/// - `C` is an `MxN` matrix. +/// +/// The matrices are assumed to be stored in row-major order (the elements in +/// each of the matrix rows are contiguous in memory). +/// +/// @note +/// This API does not support XERBLA. Instead, unlike the standard BLAS +/// functions, this one returns a dnnl_status_t value to allow error +/// handling. +/// +/// @param transa Transposition flag for matrix A: 'N' or 'n' means A is not +/// transposed, and 'T' or 't' means that A is transposed. +/// @param transb Transposition flag for matrix B: 'N' or 'n' means B is not +/// transposed, and 'T' or 't' means that B is transposed. +/// @param M The M dimension. +/// @param N The N dimension. +/// @param K The K dimension. +/// @param alpha The alpha parameter that is used to scale the product of +/// matrices A and B. +/// @param A A pointer to the A matrix data. +/// @param lda The leading dimension for the matrix A. +/// @param B A pointer to the B matrix data. +/// @param ldb The leading dimension for the matrix B. +/// @param beta The beta parameter that is used to scale the matrix C. +/// @param C A pointer to the C matrix data. +/// @param ldc The leading dimension for the matrix C. +/// @returns #dnnl_success/#dnnl::status::success on success and a status +/// describing the error otherwise. +dnnl_status_t DNNL_API dnnl_sgemm(char transa, char transb, dnnl_dim_t M, + dnnl_dim_t N, dnnl_dim_t K, float alpha, const float *A, dnnl_dim_t lda, + const float *B, dnnl_dim_t ldb, float beta, float *C, dnnl_dim_t ldc); + +/// Performs integer matrix-matrix multiply on 8-bit unsigned matrix A, 8-bit +/// signed matrix B, and 32-bit signed resulting matrix C. +/// +/// The operation is defined as: +/// +/// `C := alpha * (op(A) - A_offset) * (op(B) - B_offset) + beta * C + C_offset` +/// +/// where +/// - `op( X ) = X` or `op( X ) = X**T`, +/// - `alpha` and `beta` are scalars, and +/// - `A`, `B`, and `C` are matrices: +/// - `op( A )` is an `MxK` matrix, +/// - `op( B )` is an `KxN` matrix, +/// - `C` is an `MxN` matrix. +/// - `A_offset` is an `MxK` matrix with every element equal the `ao` value, +/// - `B_offset` is an `KxN` matrix with every element equal the `bo` value, +/// - `C_offset` is an `MxN` matrix which is defined by the `co` array of size `len`: +/// - if `offsetc = F`: the `len` must be at least `1`, +/// - if `offsetc = C`: the `len` must be at least `max(1, m)`, +/// - if `offsetc = R`: the `len` must be at least `max(1, n)`, +/// +/// The matrices are assumed to be stored in row-major order (the elements in +/// each of the matrix rows are contiguous in memory). +/// +/// @note +/// This API does not support XERBLA. Instead, unlike the standard BLAS +/// functions, this one returns a dnnl_status_t value to allow error +/// handling. +/// +/// @warning +/// On some architectures saturation may happen during intermediate +/// computations, which would lead to unexpected results. For more +/// details, refer to @ref dev_guide_int8_computations. +/// +/// @param transa Transposition flag for matrix A: 'N' or 'n' means A is not +/// transposed, and 'T' or 't' means that A is transposed. +/// @param transb Transposition flag for matrix B: 'N' or 'n' means B is not +/// transposed, and 'T' or 't' means that B is transposed. +/// @param offsetc Flag specifying how offsets should be applied to matrix C: +/// - 'F' means that the same offset will be applied to each element of +/// the matrix C, +/// - 'C' means that individual offset will be applied to each element +/// within each column, +/// - 'R' means that individual offset will be applied to each element +/// within each row. +/// @param M The M dimension. +/// @param N The N dimension. +/// @param K The K dimension. +/// @param alpha The alpha parameter that is used to scale the product of +/// matrices A and B. +/// @param A A pointer to the A matrix data. +/// @param lda The leading dimension for the matrix A. +/// @param ao The offset value for the matrix A. +/// @param B A pointer to the B matrix data. +/// @param ldb The leading dimension for the matrix B. +/// @param bo The offset value for the matrix B. +/// @param beta The beta parameter that is used to scale the matrix C. +/// @param C A pointer to the C matrix data. +/// @param ldc The leading dimension for the matrix C. +/// @param co An array of offset values for the matrix C. The number of +/// elements in the array depends on the value of @p offsetc. +/// @returns #dnnl_success/#dnnl::status::success on success and a status +/// describing the error otherwise. +dnnl_status_t DNNL_API dnnl_gemm_u8s8s32(char transa, char transb, char offsetc, + dnnl_dim_t M, dnnl_dim_t N, dnnl_dim_t K, float alpha, const uint8_t *A, + dnnl_dim_t lda, uint8_t ao, const int8_t *B, dnnl_dim_t ldb, int8_t bo, + float beta, int32_t *C, dnnl_dim_t ldc, const int32_t *co); + +/// Performs integer matrix-matrix multiply on 8-bit signed matrix A, 8-bit +/// signed matrix B, and 32-bit signed resulting matrix C. +/// +/// The operation is defined as: +/// +/// `C := alpha * (op(A) - A_offset) * (op(B) - B_offset) + beta * C + C_offset` +/// +/// where +/// - `op( X ) = X` or `op( X ) = X**T`, +/// - `alpha` and `beta` are scalars, and +/// - `A`, `B`, and `C` are matrices: +/// - `op( A )` is an `MxK` matrix, +/// - `op( B )` is an `KxN` matrix, +/// - `C` is an `MxN` matrix. +/// - `A_offset` is an `MxK` matrix with every element equal the `ao` value, +/// - `B_offset` is an `KxN` matrix with every element equal the `bo` value, +/// - `C_offset` is an `MxN` matrix which is defined by the `co` array of size `len`: +/// - if `offsetc = F`: the `len` must be at least `1`, +/// - if `offsetc = C`: the `len` must be at least `max(1, m)`, +/// - if `offsetc = R`: the `len` must be at least `max(1, n)`, +/// +/// The matrices are assumed to be stored in row-major order (the elements in +/// each of the matrix rows are contiguous in memory). +/// +/// @note +/// This API does not support XERBLA. Instead, unlike the standard BLAS +/// functions, this one returns a dnnl_status_t value to allow error +/// handling. +/// +/// @warning +/// On some architectures saturation may happen during intermediate +/// computations, which would lead to unexpected results. For more +/// details, refer to @ref dev_guide_int8_computations. +/// +/// @param transa Transposition flag for matrix A: 'N' or 'n' means A is not +/// transposed, and 'T' or 't' means that A is transposed. +/// @param transb Transposition flag for matrix B: 'N' or 'n' means B is not +/// transposed, and 'T' or 't' means that B is transposed. +/// @param offsetc Flag specifying how offsets should be applied to matrix C: +/// - 'F' means that the same offset will be applied to each element of +/// the matrix C, +/// - 'C' means that individual offset will be applied to each element +/// within each column, +/// - 'R' means that individual offset will be applied to each element +/// within each row. +/// @param M The M dimension. +/// @param N The N dimension. +/// @param K The K dimension. +/// @param alpha The alpha parameter that is used to scale the product of +/// matrices A and B. +/// @param A A pointer to the A matrix data. +/// @param lda The leading dimension for the matrix A. +/// @param ao The offset value for the matrix A. +/// @param B A pointer to the B matrix data. +/// @param ldb The leading dimension for the matrix B. +/// @param bo The offset value for the matrix B. +/// @param beta The beta parameter that is used to scale the matrix C. +/// @param C A pointer to the C matrix data. +/// @param ldc The leading dimension for the matrix C. +/// @param co An array of offset values for the matrix C. The number of +/// elements in the array depends on the value of @p offsetc. +/// @returns #dnnl_success/#dnnl::status::success on success and a status +/// describing the error otherwise. +dnnl_status_t DNNL_API dnnl_gemm_s8s8s32(char transa, char transb, char offsetc, + dnnl_dim_t M, dnnl_dim_t N, dnnl_dim_t K, float alpha, const int8_t *A, + dnnl_dim_t lda, int8_t ao, const int8_t *B, dnnl_dim_t ldb, int8_t bo, + float beta, int32_t *C, dnnl_dim_t ldc, const int32_t *co); + +/// @} dnnl_api_blas + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif /* ONEAPI_DNNL_DNNL_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..86aebc57cbfa58d76ed436954f319f7d6e6024ac --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.hpp @@ -0,0 +1,14305 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2016 Intel Corporation +* Copyright 2024-2025 FUJITSU LIMITED +* Copyright 2025 Arm Ltd. and affiliates +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// C++ API + +#ifndef ONEAPI_DNNL_DNNL_HPP +#define ONEAPI_DNNL_DNNL_HPP +// NOLINTBEGIN(readability-identifier-naming) + +#include "oneapi/dnnl/dnnl_config.h" + +/// @cond DO_NOT_DOCUMENT_THIS +#include +#include +#include +#include +#include +#include +#include + +#include "oneapi/dnnl/dnnl.h" +#include "oneapi/dnnl/dnnl_common.hpp" + +/// @endcond + +/// @addtogroup dnnl_api oneDNN API +/// @{ + +/// oneDNN namespace +namespace dnnl { + +/// @addtogroup dnnl_api_utils Utilities +/// Utility types and definitions. +/// @{ + +/// @cond DO_NOT_DOCUMENT_THIS +template +void validate_container_size(const T &v, const char *error_message, + int min_size = 1, int max_size = -1) { + const int size = (int)v.size(); + if (size < min_size || (max_size >= 0 && size > max_size)) + DNNL_THROW_ERROR(dnnl_invalid_arguments, error_message); +} +/// @endcond + +/// @cond DO_NOT_DOCUMENT_THIS +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_memory_desc_t p) { + return dnnl_memory_desc_destroy(p); + } +}; + +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_memory_t p) { + return dnnl_memory_destroy(p); + } +}; + +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_primitive_desc_t p) { + return dnnl_primitive_desc_destroy(p); + } +}; + +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_primitive_t p) { + return dnnl_primitive_destroy(p); + } +}; + +/// @endcond + +/// @} dnnl_api_utils + +struct stream; +struct memory; +struct primitive_desc; + +/// @addtogroup dnnl_api_primitives Primitives +/// Compute primitives +/// @sa @ref dev_guide_basic_concepts +/// @{ + +/// @addtogroup dnnl_api_primitives_common Common +/// Common operations to create, destroy and inspect primitives +/// @{ + +/// Base class for all computational primitives. +struct primitive : public handle { + /// Kinds of primitives supported by the library. + enum class kind { + /// Undefined primitive + undef = dnnl_undefined_primitive, + /// A reorder primitive. + reorder = dnnl_reorder, + /// A shuffle primitive. + shuffle = dnnl_shuffle, + /// A (out-of-place) tensor concatenation primitive. + concat = dnnl_concat, + /// A summation primitive. + sum = dnnl_sum, + /// A convolution primitive. + convolution = dnnl_convolution, + /// A deconvolution primitive. + deconvolution = dnnl_deconvolution, + /// An element-wise primitive. + eltwise = dnnl_eltwise, + /// An LRN primitive. + lrn = dnnl_lrn, + /// A batch normalization primitive. + batch_normalization = dnnl_batch_normalization, + /// An inner product primitive. + inner_product = dnnl_inner_product, + /// An RNN primitive. + rnn = dnnl_rnn, + /// A binary primitive. + binary = dnnl_binary, + /// A matmul (matrix multiplication) primitive. + matmul = dnnl_matmul, + /// A resampling primitive. + resampling = dnnl_resampling, + /// A pooling primitive. + pooling = dnnl_pooling, + /// A reduction primitive. + reduction = dnnl_reduction, + /// A PReLU primitive. + prelu = dnnl_prelu, + /// A softmax primitive. + softmax = dnnl_softmax, + /// A layer normalization primitive. + layer_normalization = dnnl_layer_normalization, + /// A group normalization primitive + group_normalization = dnnl_group_normalization, + }; + + using handle::handle; + + /// Default constructor. Constructs an empty object. + primitive() = default; + + /// Constructs a primitive from a C API primitive descriptor. + /// + /// @param c_pd C API primitive descriptor. + primitive(const_dnnl_primitive_desc_t c_pd); + + /// Constructs a primitive from a C API primitive descriptor and a cache blob. + /// + /// @param c_pd C API primitive descriptor. + /// @param cache_blob Cache blob. + primitive(const_dnnl_primitive_desc_t c_pd, + const std::vector &cache_blob); + + /// Constructs a primitive from a primitive descriptor. + /// + /// @param pd Primitive descriptor. + primitive(const primitive_desc &pd); + + /// Constructs a primitive from a primitive descriptor and a cache blob. + /// + /// @param pd Primitive descriptor. + /// @param cache_blob Cache blob. + primitive(const primitive_desc &pd, const std::vector &cache_blob); + + /// Returns the C API primitive descriptor of the underlying C API + /// primitive. + /// + /// @returns The underlying C API primitive descriptor. + inline const_dnnl_primitive_desc_t get_primitive_desc() const; + + /// Returns the kind of the primitive. + /// + /// @returns The primitive kind. + inline kind get_kind() const; + + /// Returns a cache blob for the primitive. + /// + /// @returns Vector containing the cache blob. + /// + /// @note The cache blob can be empty. It's the user's responsibility to + /// check whether it's empty prior to passing it to the primitive + /// constructor. + inline std::vector get_cache_blob() const; + + /// Executes computations specified by the primitive in a specified stream. + /// + /// Arguments are passed via an arguments map containing pairs. The index must be one of the `DNNL_ARG_*` values + /// such as `DNNL_ARG_SRC`, and the memory must have a memory descriptor + /// matching the one returned by + /// primitive_desc::query_md(#query::exec_arg_md, index) unless using + /// dynamic shapes (see #DNNL_RUNTIME_DIM_VAL). + /// + /// @param astream Stream object. The stream must belong to the same engine + /// as the primitive. + /// @param args Arguments map. + void execute(const stream &astream, + const std::unordered_map &args) const; +}; + +/// Converts primitive kind enum value from C++ API to C API type. +/// +/// @param akind C++ API primitive kind enum value. +/// @returns Corresponding C API primitive kind enum value. +inline dnnl_primitive_kind_t convert_to_c(primitive::kind akind) { + return static_cast(akind); +} + +const_dnnl_primitive_desc_t primitive::get_primitive_desc() const { + const_dnnl_primitive_desc_t pd; + error::wrap_c_api(dnnl_primitive_get_primitive_desc(get(), &pd), + "could not get a primitive descriptor from a primitive"); + return pd; +} + +dnnl::primitive::kind primitive::get_kind() const { + const_dnnl_primitive_desc_t pd = get_primitive_desc(); + // TODO (Roma): the code below is only needed because get_primitive_desc + // returns a C type. + dnnl_primitive_kind_t kind; + error::wrap_c_api(dnnl_primitive_desc_query( + pd, dnnl_query_primitive_kind, 0, (void *)&kind), + "could not get a primitive kind from a primitive descriptor"); + return static_cast(kind); +} + +std::vector primitive::get_cache_blob() const { + size_t size; + error::wrap_c_api(dnnl_primitive_get_cache_blob(get(), &size, nullptr), + "could not get cache blob size from a primitive"); + + std::vector cache_blob(size); + error::wrap_c_api( + dnnl_primitive_get_cache_blob(get(), &size, cache_blob.data()), + "could not get a cache blob from a primitive"); + return cache_blob; +} + +/// @} dnnl_api_primitives_common + +/// @addtogroup dnnl_api_attributes +/// +/// A container for parameters that extend primitives behavior. +/// +/// Attributes can also contain Post-ops, which are computations executed +/// after the primitive. +/// +/// @sa @ref dev_guide_attributes +/// @sa @ref dev_guide_attributes_post_ops +/// +/// @{ + +/// Scratchpad mode +enum class scratchpad_mode { + /// The library manages the scratchpad allocation according to the policy + /// specified by the `DNNL_ENABLE_CONCURRENT_EXEC` + /// [build option](@ref dev_guide_build_options) (default). + /// + /// When `DNNL_ENABLE_CONCURRENT_EXEC=OFF` (default), the library + /// scratchpad is common to all primitives to reduce the memory footprint. + /// This configuration comes with limited thread-safety properties, namely + /// primitives can be created and executed in parallel but cannot migrate + /// between threads (in other words, each primitive should be executed in + /// the same thread it was created in). + /// + /// When `DNNL_ENABLE_CONCURRENT_EXEC=ON`, the library scratchpad is + /// private to each primitive. The memory footprint is larger than when + /// using `DNNL_ENABLE_CONCURRENT_EXEC=OFF` but different primitives can be + /// created and run concurrently (the same primitive cannot be run + /// concurrently from two different threads though). + library = dnnl_scratchpad_mode_library, + /// The user manages the scratchpad allocation by querying and providing + /// the scratchpad memory to primitives. This mode is thread-safe as long + /// as the scratchpad buffers are not used concurrently by two primitive + /// executions. + user = dnnl_scratchpad_mode_user, +}; + +/// Converts a scratchpad mode enum value from C++ API to C API type. +/// +/// @param mode C++ API scratchpad mode enum value. +/// @returns Corresponding C API scratchpad mode enum value. +inline dnnl_scratchpad_mode_t convert_to_c(scratchpad_mode mode) { + return static_cast(mode); +} + +/// Rounding mode +enum class rounding_mode { + /// rounding mode dictated by the floating-point environment + environment = dnnl_rounding_mode_environment, + /// stochastic rounding mode where a random bias is added to the + /// trailing mantissa bits before conversion. + stochastic = dnnl_rounding_mode_stochastic +}; + +/// Converts a rounding mode enum value from C++ API to C API type. +/// +/// @param mode C++ API rounding mode enum value. +/// @returns Corresponding C API rounding mode enum value. +inline dnnl_rounding_mode_t convert_to_c(rounding_mode mode) { + return static_cast(mode); +} + +/// Quantization kind +enum class quantization_mode { + /// used for unspecified quantization kind + undef = dnnl_quantization_mode_undef, + /// static quantization mode: quantization parameter is computed + /// ahead of time and passed to oneDNN as an input. + static_sazp = dnnl_quantization_mode_static_sazp, + /// dynamic quantization mode following OCP MX spec: quantization + /// parameter is computed by oneDNN following the OCP MX spec + /// formula and written as an output. + dynamic_mx = dnnl_quantization_mode_dynamic_mx, + /// dynamic quantization mode where quantization parameter is computed by + /// oneDNN as \f$scale\_dt(amax(X) / max(dst\_dt))\f$ in `f32` then + /// converted to a scale type and written as an output. + dynamic_fp = dnnl_quantization_mode_dynamic_fp, +}; + +/// Converts a quantization kind enum value from C++ API to C API type. +/// +/// @param qmode C++ API quantization kind enum value. +/// @returns Corresponding C API quantization kind enum value. +inline dnnl_quantization_mode_t convert_to_c(quantization_mode qmode) { + return static_cast(qmode); +} + +/// Propagation kind. +enum class prop_kind { + /// Undefined propagation kind. + undef = dnnl_prop_kind_undef, + /// Forward data propagation (training mode). In this mode, primitives + /// perform computations necessary for subsequent backward propagation. + forward_training = dnnl_forward_training, + /// Forward data propagation (inference mode). In this mode, primitives + /// perform only computations that are necessary for inference and omit + /// computations that are necessary only for backward propagation. + forward_inference = dnnl_forward_inference, + /// Forward data propagation, + /// alias for #dnnl::prop_kind::forward_training. + forward = dnnl_forward, + /// Backward propagation (with respect to all parameters). + backward = dnnl_backward, + /// Backward data propagation. + backward_data = dnnl_backward_data, + /// Backward weights propagation. + backward_weights = dnnl_backward_weights, + /// Backward bias propagation. + backward_bias = dnnl_backward_bias +}; + +/// Converts propagation kind enum value from C++ API to C API type. +/// +/// @param akind C++ API propagation kind enum value. +/// @returns Corresponding C API propagation kind enum value. +inline dnnl_prop_kind_t convert_to_c(prop_kind akind) { + return static_cast(akind); +} + +/// Kinds of algorithms. +enum class algorithm { + /// Undefined algorithm + undef = dnnl_alg_kind_undef, + /// Convolution algorithm that is chosen to be either direct or Winograd + /// automatically + convolution_auto = dnnl_convolution_auto, + /// Direct convolution + convolution_direct = dnnl_convolution_direct, + /// Winograd convolution + convolution_winograd = dnnl_convolution_winograd, + /// Direct deconvolution + deconvolution_direct = dnnl_deconvolution_direct, + /// Winograd deconvolution + deconvolution_winograd = dnnl_deconvolution_winograd, + /// Elementwise: rectified linear unit (ReLU) + eltwise_relu = dnnl_eltwise_relu, + /// Elementwise: hyperbolic tangent non-linearity (tanh) + eltwise_tanh = dnnl_eltwise_tanh, + /// Elementwise: exponential linear unit (ELU) + eltwise_elu = dnnl_eltwise_elu, + /// Elementwise: square + eltwise_square = dnnl_eltwise_square, + /// Elementwise: abs + eltwise_abs = dnnl_eltwise_abs, + /// Elementwise: square root + eltwise_sqrt = dnnl_eltwise_sqrt, + /// Elementwise: swish (\f$x \cdot sigmoid(a \cdot x)\f$) + eltwise_swish = dnnl_eltwise_swish, + /// Elementwise: linear + eltwise_linear = dnnl_eltwise_linear, + /// Elementwise: soft_relu + eltwise_soft_relu = dnnl_eltwise_soft_relu, + /// Elementwise: mish + eltwise_mish = dnnl_eltwise_mish, + /// Elementwise: logistic + eltwise_logistic = dnnl_eltwise_logistic, + /// Elementwise: exponent + eltwise_exp = dnnl_eltwise_exp, + /// Elementwise: tanh-based gelu + eltwise_gelu_tanh = dnnl_eltwise_gelu_tanh, + /// Elementwise: erf-based gelu + eltwise_gelu_erf = dnnl_eltwise_gelu_erf, + /// Elementwise: natural logarithm + eltwise_log = dnnl_eltwise_log, + /// Elementwise: clip + eltwise_clip = dnnl_eltwise_clip, + /// Eltwise: clip version 2 + eltwise_clip_v2 = dnnl_eltwise_clip_v2, + /// Elementwise: pow + eltwise_pow = dnnl_eltwise_pow, + /// Elementwise: round + eltwise_round = dnnl_eltwise_round, + /// Elementwise: hardswish + eltwise_hardswish = dnnl_eltwise_hardswish, + /// Elementwise: hardsigmoid + eltwise_hardsigmoid = dnnl_eltwise_hardsigmoid, + /// Elementwise: rectified linar unit (ReLU) (dst for backward) + eltwise_relu_use_dst_for_bwd = dnnl_eltwise_relu_use_dst_for_bwd, + /// Elementwise: hyperbolic tangent non-linearity (tanh) (dst for backward) + eltwise_tanh_use_dst_for_bwd = dnnl_eltwise_tanh_use_dst_for_bwd, + /// Elementwise: exponential linear unit (ELU) (dst for backward) + eltwise_elu_use_dst_for_bwd = dnnl_eltwise_elu_use_dst_for_bwd, + /// Elementwise: square root (dst for backward) + eltwise_sqrt_use_dst_for_bwd = dnnl_eltwise_sqrt_use_dst_for_bwd, + /// Elementwise: logistic (dst for backward) + eltwise_logistic_use_dst_for_bwd = dnnl_eltwise_logistic_use_dst_for_bwd, + /// Elementwise: exponent (dst for backward) + eltwise_exp_use_dst_for_bwd = dnnl_eltwise_exp_use_dst_for_bwd, + /// Elementwise: clip version 2 (dst for backward) + eltwise_clip_v2_use_dst_for_bwd = dnnl_eltwise_clip_v2_use_dst_for_bwd, + /// Local response normalization (LRN) across multiple channels + lrn_across_channels = dnnl_lrn_across_channels, + /// LRN within a single channel + lrn_within_channel = dnnl_lrn_within_channel, + /// Max pooling + pooling_max = dnnl_pooling_max, + /// Average pooling include padding + pooling_avg_include_padding = dnnl_pooling_avg_include_padding, + /// Average pooling exclude padding + pooling_avg_exclude_padding = dnnl_pooling_avg_exclude_padding, + /// RNN cell + vanilla_rnn = dnnl_vanilla_rnn, + /// LSTM cell + vanilla_lstm = dnnl_vanilla_lstm, + /// GRU cell + vanilla_gru = dnnl_vanilla_gru, + /// GRU cell with linear before reset. Differs from the vanilla GRU + /// in how the new memory gate is calculated: + /// \f$c_t = tanh(W_c*x_t + b_{c_x} + r_t*(U_c*h_{t-1}+b_{c_h})) \f$ + /// LRB GRU expects 4 bias tensors on input: + /// \f$[b_{u}, b_{r}, b_{c_x}, b_{c_h}]\f$ + lbr_gru = dnnl_lbr_gru, + /// AUGRU cell + vanilla_augru = dnnl_vanilla_augru, + /// AUGRU cell with linear before reset + lbr_augru = dnnl_lbr_augru, + /// Binary add + binary_add = dnnl_binary_add, + /// Binary mul + binary_mul = dnnl_binary_mul, + /// Binary max + binary_max = dnnl_binary_max, + /// Binary min + binary_min = dnnl_binary_min, + /// Binary div + binary_div = dnnl_binary_div, + /// Binary sub + binary_sub = dnnl_binary_sub, + /// Binary greater than or equal + binary_ge = dnnl_binary_ge, + /// Binary greater than + binary_gt = dnnl_binary_gt, + /// Binary less than or equal + binary_le = dnnl_binary_le, + /// Binary less than + binary_lt = dnnl_binary_lt, + /// Binary equal + binary_eq = dnnl_binary_eq, + /// Binary not equal + binary_ne = dnnl_binary_ne, + /// Binary select + binary_select = dnnl_binary_select, + /// Nearest Neighbor resampling method + resampling_nearest = dnnl_resampling_nearest, + /// Linear (Bilinear, Trilinear) resampling method + resampling_linear = dnnl_resampling_linear, + /// Reduction using max operation + reduction_max = dnnl_reduction_max, + /// Reduction using min operation + reduction_min = dnnl_reduction_min, + /// Reduction using sum operation + reduction_sum = dnnl_reduction_sum, + /// Reduction using mul operation + reduction_mul = dnnl_reduction_mul, + /// Reduction using mean operation + reduction_mean = dnnl_reduction_mean, + /// Reduction using norm_lp_max operation + reduction_norm_lp_max = dnnl_reduction_norm_lp_max, + /// Reduction using norm_lp_sum operation + reduction_norm_lp_sum = dnnl_reduction_norm_lp_sum, + /// Reduction using norm_lp_power_p_max operation + reduction_norm_lp_power_p_max = dnnl_reduction_norm_lp_power_p_max, + /// Reduction using norm_lp_power_p_sum operation + reduction_norm_lp_power_p_sum = dnnl_reduction_norm_lp_power_p_sum, + /// Softmax, numerically stable + softmax_accurate = dnnl_softmax_accurate, + /// LogSoftmax, numerically stable + softmax_log = dnnl_softmax_log, +}; + +/// Converts algorithm kind enum value from C++ API to C API type. +/// @param aalgorithm C++ API algorithm kind enum value. +/// @returns Corresponding C API algorithm kind enum value. +inline dnnl_alg_kind_t convert_to_c(algorithm aalgorithm) { + return static_cast(aalgorithm); +} + +/// @} dnnl_api_attributes + +/// @addtogroup dnnl_api_primitives_common +/// @{ + +/// Flags for normalization primitives. +enum class normalization_flags : unsigned { + /// Use no normalization flags. If specified, the library computes mean and + /// variance on forward propagation for training and inference, outputs + /// them on forward propagation for training, and computes the respective + /// derivatives on backward propagation. + /// + /// @note + /// Backward propagation of type #dnnl::prop_kind::backward_data has + /// the same behavior as #dnnl::prop_kind::backward. + none = dnnl_normalization_flags_none, + + /// Use global statistics. If specified, the library uses mean and + /// variance provided by the user as an input on forward propagation and + /// does not compute their derivatives on backward propagation. Otherwise, + /// the library computes mean and variance on forward propagation for + /// training and inference, outputs them on forward propagation for + /// training, and computes the respective derivatives on backward + /// propagation. + use_global_stats = dnnl_use_global_stats, + + /// Use scale parameter. If specified, the user is expected to pass scale as + /// input on forward propagation. On backward propagation of type + /// #dnnl::prop_kind::backward, the library computes its derivative. + use_scale = dnnl_use_scale, + + /// Use shift parameter. If specified, the user is expected to pass shift as + /// input on forward propagation. On backward propagation of type + /// #dnnl::prop_kind::backward, the library computes its derivative. + use_shift = dnnl_use_shift, + + /// Fuse normalization with ReLU. On training, normalization will require + /// the workspace to implement backward propagation. On inference, the + /// workspace is not required and behavior is the same as when normalization + /// is fused with ReLU using the post-ops API. + /// + /// @note + /// The flag implies negative slope being 0. On training this is the only + /// configuration supported. For inference, to use non-zero negative slope + /// consider using @ref dev_guide_attributes_post_ops. + fuse_norm_relu = dnnl_fuse_norm_relu, + + /// Fuse normalization with an elementwise binary Add operation + /// followed by ReLU. + /// During training, normalization will require a workspace to implement + /// backward propagation. For inference, the workspace is not needed. + /// On forward propagation, an elementwise binary Add operation is applied + /// to the normalization results with an additional input tensor, followed + /// by ReLU with a negative slope of 0. + /// On backward propagation, the result of the backward ReLU operation + /// with the input tensor and workspace from the forward pass is saved + /// to an extra output tensor, and backward normalization is performed. + fuse_norm_add_relu = dnnl_fuse_norm_add_relu, + + /// Use Root Mean Square (RMS) Normalization. In forward propagation, + /// the mean is considered zero, and RMS norm is used instead of variance + /// for scaling. Only the RMS norm is output during forward propagation for + /// training. In backward propagation, the library calculates the derivative + /// with respect to the RMS norm only, assuming the mean is zero. + /// + /// @note + /// When used with #dnnl::normalization_flags::use_global_stats, + /// only RMS norm is required to be provided as input. + rms_norm = dnnl_rms_norm, +}; + +/// Converts normalization flags enum value from C++ API to C API type. +/// @param flags C++ API normalization flags enum value. +/// @returns Corresponding C API normalization flags enum value. +inline dnnl_normalization_flags_t convert_to_c(normalization_flags flags) { + return static_cast(flags); +} + +/// @} dnnl_api_primitives_common + +/// @addtogroup dnnl_api_rnn +/// @{ + +/// RNN cell flags. +enum class rnn_flags : unsigned { + /// Undefined RNN flags + undef = dnnl_rnn_flags_undef, + /// Do not add weights gradient to existing diff_weights memory + diff_weights_overwrite = dnnl_rnn_flags_diff_weights_overwrite, +}; + +/// Converts RNN cell flags enum value from C++ API to C API type. +/// @param flags C++ API RNN cell flags enum value. +/// @returns Corresponding C API RNN cell flags enum value. +inline dnnl_rnn_flags_t convert_to_c(rnn_flags flags) { + return static_cast(flags); +} + +DNNL_DEFINE_BITMASK_OPS(normalization_flags) +DNNL_DEFINE_BITMASK_OPS(rnn_flags) + +/// A direction of RNN primitive execution +enum class rnn_direction { + /// Undefined RNN direction. + undef = dnnl_rnn_direction_undef, + /// Unidirectional execution of RNN primitive from left to right. + unidirectional_left2right = dnnl_unidirectional_left2right, + /// Unidirectional execution of RNN primitive from right to left. + unidirectional_right2left = dnnl_unidirectional_right2left, + /// Bidirectional execution of RNN primitive with concatenation of the + /// results. + bidirectional_concat = dnnl_bidirectional_concat, + /// Bidirectional execution of RNN primitive with summation of the + /// results. + bidirectional_sum = dnnl_bidirectional_sum, +}; + +/// Converts RNN direction enum value from C++ API to C API type. +/// @param dir C++ API RNN direction enum value. +/// @returns Corresponding C API RNN direction enum value. +inline dnnl_rnn_direction_t convert_to_c(rnn_direction dir) { + return static_cast(dir); +} + +/// @} dnnl_api_rnn + +/// @addtogroup dnnl_api_primitives_common +/// @{ + +/// Primitive descriptor query specification. +/// +/// In general, queries are not used with the C++ API because most queries are +/// implemented as class members. +/// +/// See @ref dnnl_query_t for more information. +enum class query { + /// no query + undef = dnnl_query_undef, + + /// execution engine + engine = dnnl_query_engine, + /// primitive kind + primitive_kind = dnnl_query_primitive_kind, + + /// number of inputs expected + num_of_inputs_s32 = dnnl_query_num_of_inputs_s32, + /// number of outputs expected + num_of_outputs_s32 = dnnl_query_num_of_outputs_s32, + + /// runtime estimation (seconds), unimplemented + time_estimate_f64 = dnnl_query_time_estimate_f64, + /// memory required for scratchpad (bytes) + /// + /// @sa @ref dev_guide_attributes_scratchpad + memory_consumption_s64 = dnnl_query_memory_consumption_s64, + + /// scratchpad engine + /// + /// engine to be used for creating scratchpad memory + scratchpad_engine = dnnl_query_scratchpad_engine, + + /// reorder source engine + reorder_src_engine = dnnl_query_reorder_src_engine, + /// reorder destination engine + reorder_dst_engine = dnnl_query_reorder_dst_engine, + + /// implementation name + impl_info_str = dnnl_query_impl_info_str, + + /// propagation kind + prop_kind = dnnl_query_prop_kind, + + /// size of cache blob ID in bytes + cache_blob_id_size_s64 = dnnl_query_cache_blob_id_size_s64, + + /// cache blob ID (pointer to array) + cache_blob_id = dnnl_query_cache_blob_id, + + /// strides + strides = dnnl_query_strides, + /// dilations + dilations = dnnl_query_dilations, + /// left padding + padding_l = dnnl_query_padding_l, + /// right padding + padding_r = dnnl_query_padding_r, + /// epsilon + epsilon_f32 = dnnl_query_epsilon_f32, + /// flags + flags = dnnl_query_flags, + /// algorithm kind + alg_kind = dnnl_query_alg_kind, + /// alpha + alpha_f32 = dnnl_query_alpha_f32, + /// beta + beta_f32 = dnnl_query_beta_f32, + /// axis + axis_s32 = dnnl_query_axis_s32, + /// LRN parameter local size + local_size_s64 = dnnl_query_local_size_s64, + /// LRN parameter K + k_f32 = dnnl_query_k_f32, + /// Reduction parameter P + p_f32 = dnnl_query_p_f32, + /// Resampling parameter factors + factors = dnnl_query_factors, + /// RNN parameter cell kind + cell_kind = dnnl_query_cell_kind, + /// RNN parameter direction + direction = dnnl_query_direction, + /// RNN parameter activation kind + activation_kind = dnnl_query_activation_kind, + /// Pooling parameter kernel + kernel = dnnl_query_kernel, + /// Shuffle parameter group size + group_size_s64 = dnnl_query_group_size_s64, + + /// source memory desc + src_md = dnnl_query_src_md, + /// source gradient (diff) memory desc + diff_src_md = dnnl_query_diff_src_md, + /// weights memory descriptor desc + weights_md = dnnl_query_weights_md, + /// weights gradient (diff) memory desc + diff_weights_md = dnnl_query_diff_weights_md, + /// destination memory desc + dst_md = dnnl_query_dst_md, + /// destination gradient (diff) memory desc + diff_dst_md = dnnl_query_diff_dst_md, + /// workspace memory desc + workspace_md = dnnl_query_workspace_md, + /// scratchpad memory desc + scratchpad_md = dnnl_query_scratchpad_md, + /// memory desc of an execute argument + exec_arg_md = dnnl_query_exec_arg_md, + + /// number of dimensions + ndims_s32 = dnnl_query_ndims_s32, + /// vector of dimensions + dims = dnnl_query_dims, + /// data type + data_type = dnnl_query_data_type, + /// submemory offset + submemory_offset_s64 = dnnl_query_submemory_offset_s64, + /// vector of padded dimensions + padded_dims = dnnl_query_padded_dims, + /// vector of padded offsets + padded_offsets = dnnl_query_padded_offsets, + /// format kind + format_kind = dnnl_query_format_kind, + /// number of innermost blocks + inner_nblks_s32 = dnnl_query_inner_nblks_s32, + /// vector of sizes of the innermost blocks + inner_blks = dnnl_query_inner_blks, + /// vector of logical indices of the blocks + inner_idxs = dnnl_query_inner_idxs, + /// Sparse encoding + sparse_encoding = dnnl_query_sparse_encoding, + /// Number of non-zero entries + nnz_s64 = dnnl_query_nnz_s64, + /// Number of buffers required for a memory descriptor + num_handles_s32 = dnnl_query_num_handles_s32, +}; + +/// Converts query enum value from C++ API to C API type. +/// @param aquery C++ API query enum value. +/// @returns Corresponding C API query enum value. +inline dnnl_query_t convert_to_c(query aquery) { + return static_cast(aquery); +} + +/// @} dnnl_api_primitives_common + +/// @} dnnl_api_primitives + +/// @addtogroup dnnl_api_memory Memory +/// +/// A container that describes and stores data. Memory objects can contain +/// data of various types and formats. There are two levels of abstraction: +/// +/// 1. **Memory descriptor** -- engine-agnostic logical description of data +/// (number of dimensions, dimension sizes, and data type), and, +/// optionally, the information about the physical format of data in +/// memory. If this information is not known yet, a memory descriptor can +/// be created with #dnnl::memory::format_tag::any. This allows +/// compute-intensive primitives to choose the best format for +/// computation. The user is responsible for reordering the data into the +/// chosen format when formats do not match. +/// +/// A memory descriptor can be initialized either by specifying dimensions +/// and a memory format tag or strides for each of them, or by +/// manipulating the dnnl_memory_desc_t structure directly. +/// +/// @warning +/// The latter approach requires understanding how the physical data +/// representation is mapped to the structure and is discouraged. This +/// topic is discussed in @ref dev_guide_understanding_memory_formats. +/// +/// The user can query the amount of memory required by a memory +/// descriptor using the #dnnl::memory::desc::get_size() function. The +/// size of data in general cannot be computed as the product of +/// dimensions multiplied by the size of the data type. So users are +/// required to use this function for better code portability. +/// +/// Two memory descriptors can be compared using the equality and +/// inequality operators. The comparison is especially useful when +/// checking whether it is necessary to reorder data from the user's data +/// format to a primitive's format. +/// +/// 2. **Memory object** -- an engine-specific object that handles the memory +/// buffer and its description (a memory descriptor). For the CPU engine or +/// with USM, the memory buffer handle is simply a pointer to @c void. The +/// memory buffer can be queried using #dnnl::memory::get_data_handle() and +/// set using #dnnl::memory::set_data_handle(). The underlying SYCL buffer, +/// when used, can be queried using #dnnl::sycl_interop::get_buffer and set +/// using #dnnl::sycl_interop::set_buffer. A memory object can also be +/// queried for the underlying memory descriptor and for its engine using +/// #dnnl::memory::get_desc() and dnnl::memory::get_engine(). +/// +/// Along with ordinary memory descriptors with all dimensions being positive, +/// the library supports *zero-volume* memory descriptors with one or more +/// dimensions set to zero. This is used to support the NumPy\* convention. +/// If a zero-volume memory is passed to a primitive, the primitive typically +/// does not perform any computations with this memory. For example: +/// +/// - A concatenation primitive would ignore all memory object with zeroes in +/// the concat dimension / axis. +/// +/// - A forward convolution with a source memory object with zero in the +/// minibatch dimension would always produce a destination memory object +/// with a zero in the minibatch dimension and perform no computations. +/// +/// - However, a forward convolution with a zero in one of the weights +/// dimensions is ill-defined and is considered to be an error by the +/// library because there is no clear definition of what the output values +/// should be. +/// +/// Memory buffer of a zero-volume memory is never accessed. +/// +/// @{ + +/// Memory object. +/// +/// A memory object encapsulates a handle to a memory buffer allocated on a +/// specific engine, tensor dimensions, data type, and memory format, which is +/// the way tensor indices map to offsets in linear memory space. Memory +/// objects are passed to primitives during execution. +struct memory : public handle { + using handle::handle; + + /// Integer type for representing dimension sizes and indices. + using dim = dnnl_dim_t; + /// Vector of dimensions. Implementations are free to force a limit on the + /// vector's length. + using dims = std::vector; + + /// Helper function that validates that an `std::vector` of dimensions can + /// be safely converted to the C API array ::dnnl_dims_t. Throws if + /// validation fails. + /// + /// @param v Vector of dimensions. + /// @param min_size Minimum expected size of the vector. + template + static void validate_dims(const std::vector &v, int min_size = 0) { + validate_container_size( + v, "dimensions are invalid", min_size, DNNL_MAX_NDIMS); + } + + /// Data type specification. + enum class data_type { + /// Undefined data type (used for empty memory descriptors). + undef = dnnl_data_type_undef, + /// 4-bit float data type with 3-bit exponent and 0 bit mantissa. + f4_e3m0 = dnnl_f4_e3m0, + /// [MX-compliant 4-bit float data type](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf) with 2-bit exponent and 1 bit mantissa. + f4_e2m1 = dnnl_f4_e2m1, + /// [MX-compliant 8-bit compliant scale data type](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf) with 8-bit exponent. + e8m0 = dnnl_e8m0, + /// [OFP8 standard 8-bit floating-point](https://www.opencompute.org/documents/ocp-8-bit-floating-point-specification-ofp8-revision-1-0-2023-06-20-pdf) + /// with a 5-bit exponent and a 2-bit mantissa. + f8_e5m2 = dnnl_f8_e5m2, + /// [OFP8 standard 8-bit floating-point](https://www.opencompute.org/documents/ocp-8-bit-floating-point-specification-ofp8-revision-1-0-2023-06-20-pdf) + /// with a 4-bit exponent and a 3-bit mantissa. + f8_e4m3 = dnnl_f8_e4m3, + /// [16-bit/half-precision floating point](https://en.wikipedia.org/wiki/Half-precision_floating-point_format). + f16 = dnnl_f16, + /// non-standard + /// [16-bit floating point with 7-bit mantissa](https://en.wikipedia.org/wiki/Bfloat16_floating-point_format). + bf16 = dnnl_bf16, + /// [32-bit/single-precision floating point](https://en.wikipedia.org/wiki/Single-precision_floating-point_format). + f32 = dnnl_f32, + //// [64-bit/double-precision floating point](https://en.wikipedia.org/wiki/Double-precision_floating-point_format). + f64 = dnnl_f64, + /// 32-bit signed integer. + s32 = dnnl_s32, + /// 8-bit signed integer. + s8 = dnnl_s8, + /// 8-bit unsigned integer. + u8 = dnnl_u8, + /// 4-bit signed integer. + s4 = dnnl_s4, + /// 4-bit unsigned integer. + u4 = dnnl_u4, + }; + + /// Returns size of data type in bytes. + /// @returns The number of bytes occupied by data type. + static size_t data_type_size(data_type adata_type) { + return dnnl_data_type_size(convert_to_c(adata_type)); + } + + /// Memory format kind + enum class format_kind { + /// Undefined memory format kind, used for empty memory descriptors. + undef = dnnl_format_kind_undef, + /// A special format kind that indicates that the actual format will be + /// selected by a primitive automatically. + any = dnnl_format_kind_any, + /// A tensor in a generic format described by the stride and blocking + /// values in each dimension. + blocked = dnnl_blocked, + /// Format kind for sparse tensors. + sparse = dnnl_format_kind_sparse, + /// Format kind for host scalars. + host_scalar = dnnl_format_kind_host_scalar, + /// A special format kind that indicates that tensor format is opaque. + opaque = dnnl_format_kind_opaque, + }; + + /// Sparse encodings. + /// @sa @ref dev_guide_sparsity + enum class sparse_encoding { + /// Undefined sparse encoding kind, used for empty memory descriptors. + undef = dnnl_sparse_encoding_undef, + /// Compressed Sparse Row (CSR) encoding. + csr = dnnl_csr, + /// An encoding that is used for an opaque storage schema for + /// tensors with unstructured sparsity. A memory descriptor with the + /// packed encoding cannot be used to create a memory object. It can + /// only be used to create a primitive descriptor to query the + /// actual memory descriptor (similar to the format tag `any`). + packed = dnnl_packed, + /// Coordinate Sparse (COO) encoding. + coo = dnnl_coo, + }; + + /// Memory format tag specification. + /// + /// Memory format tags can be further divided into two categories: + /// + /// - Domain-agnostic names, i.e. names that do not depend on the tensor + /// usage in the specific primitive. These names use letters from `a` + /// to `f` to denote logical dimensions and form the order in which the + /// dimensions are laid in memory. For example, + /// #dnnl::memory::format_tag::ab is used to denote a 2D tensor where the + /// second logical dimension (denoted as `b`) is the innermost, i.e. + /// has stride = 1, and the first logical dimension (`a`) is laid out in + /// memory with stride equal to the size of the second dimension. On the + /// other hand, #dnnl::memory::format_tag::ba is the transposed version + /// of the same tensor: the outermost dimension (`a`) becomes the + /// innermost one. + /// + /// - Domain-specific names, i.e. names that make sense only in the + /// context of a certain domain, such as CNN. These names are + /// aliases to the corresponding domain-agnostic tags and used mostly + /// for convenience. For example, #dnnl::memory::format_tag::nc + /// is used to denote 2D CNN activations tensor memory format, where + /// the channels dimension is the innermost one and the batch dimension + /// is the outermost one. Moreover, #dnnl::memory::format_tag::nc is + /// an alias for #dnnl::memory::format_tag::ab, because for + /// CNN primitives the logical dimensions of activations tensors come + /// in order: batch, channels, spatial. In other words, batch + /// corresponds to the first logical dimension (`a`), and channels + /// correspond to the second one (`b`). + /// + /// The following domain-specific notation applies to memory format tags: + /// - @c 'n' denotes the mini-batch dimension + /// - @c 'c' denotes a channels dimension + /// - When there are multiple channel dimensions (for example, + /// in convolution weights tensor), @c 'i' and @c 'o' denote dimensions + /// of input and output channels + /// - @c 'g' denotes a groups dimension for convolution weights + /// - @c 'd', @c 'h', and @c 'w' denote spatial depth, height, and width + /// respectively + /// + /// See @ref dnnl_format_tag_t for a detailed description. + enum class format_tag { + /// Undefined memory format tag + undef = dnnl_format_tag_undef, + /// Placeholder memory format tag. Used to instruct the primitive to + /// select a format automatically. + any = dnnl_format_tag_any, + + /// plain 1D tensor + a = dnnl_a, + + /// plain 2D tensor + ab = dnnl_ab, + /// permuted 2D tensor + ba = dnnl_ba, + + /// plain 3D tensor + abc = dnnl_abc, + /// permuted 3D tensor + acb = dnnl_acb, + /// permuted 3D tensor + bac = dnnl_bac, + /// permuted 3D tensor + bca = dnnl_bca, + /// permuted 3D tensor + cba = dnnl_cba, + + /// plain 4D tensor + abcd = dnnl_abcd, + /// permuted 4D tensor + abdc = dnnl_abdc, + /// permuted 4D tensor + acbd = dnnl_acbd, + /// permuted 4D tensor + acdb = dnnl_acdb, + /// permuted 4D tensor + adbc = dnnl_adbc, + /// permuted 4D tensor + bacd = dnnl_bacd, + /// permuted 4D tensor + bcda = dnnl_bcda, + /// permuted 4D tensor + cdba = dnnl_cdba, + /// permuted 4D tensor + dcab = dnnl_dcab, + + /// plain 5D tensor + abcde = dnnl_abcde, + /// permuted 5D tensor + abdec = dnnl_abdec, + /// permuted 5D tensor + acbde = dnnl_acbde, + /// permuted 5D tensor + acdeb = dnnl_acdeb, + /// permuted 5D tensor + bacde = dnnl_bacde, + /// permuted 5D tensor + bcdea = dnnl_bcdea, + /// permuted 5D tensor + cdeba = dnnl_cdeba, + /// permuted 5D tensor + decab = dnnl_decab, + /// permuted 5D tensor + abced = dnnl_abced, + + /// plain 6D tensor + abcdef = dnnl_abcdef, + /// permuted 6D tensor + abdfce = dnnl_abdfce, + /// permuted 6D tensor + acbdef = dnnl_acbdef, + /// permuted 6D tensor + abdefc = dnnl_abdefc, + /// permuted 6D tensor + defcab = dnnl_defcab, + /// permuted 6D tensor + abcdfe = dnnl_abcdfe, + + /// plain 7D tensor + abcdefg = dnnl_abcdefg, + /// permuted 7D tensor + abcdegf = dnnl_abcdegf, + + /// plain 8D tensor + abcdefgh = dnnl_abcdefgh, + /// permuted 8D tensor + abcdefhg = dnnl_abcdefhg, + + /// plain 9D tensor + abcdefghi = dnnl_abcdefghi, + /// permuted 9D tensor + abcdefgih = dnnl_abcdefgih, + + /// plain 10D tensor + abcdefghij = dnnl_abcdefghij, + /// permuted 10D tensor + abcdefghji = dnnl_abcdefghji, + + /// plain 11D tensor + abcdefghijk = dnnl_abcdefghijk, + /// permuted 11D tensor + abcdefghikj = dnnl_abcdefghikj, + + /// plain 12D tensor + abcdefghijkl = dnnl_abcdefghijkl, + /// permuted 12D tensor + abcdefghijlk = dnnl_abcdefghijlk, + + /// 1D tensor; an alias for #dnnl::memory::format_tag::a + x = a, + /// 2D CNN activations tensor; an alias for #dnnl::memory::format_tag::ab + nc = ab, + /// 2D CNN activations tensor; an alias for #dnnl::memory::format_tag::ba + cn = ba, + /// 2D RNN statistics tensor; an alias for #dnnl::memory::format_tag::ab + tn = ab, + /// 2D RNN statistics tensor; an alias for #dnnl::memory::format_tag::ba + nt = ba, + /// 3D CNN activations tensor; an alias for #dnnl::memory::format_tag::abc + ncw = abc, + /// 3D CNN activations tensor; an alias for #dnnl::memory::format_tag::acb + nwc = acb, + /// 4D CNN activations tensor; an alias for #dnnl::memory::format_tag::abcd + nchw = abcd, + /// 4D CNN activations tensor; an alias for #dnnl::memory::format_tag::acdb + nhwc = acdb, + /// 4D CNN activations tensor; an alias for #dnnl::memory::format_tag::bcda + chwn = bcda, + /// 5D CNN activations tensor; an alias for #dnnl::memory::format_tag::abcde + ncdhw = abcde, + /// 5D CNN activations tensor; an alias for #dnnl::memory::format_tag::acdeb + ndhwc = acdeb, + + /// 2D CNN weights tensor; an alias for #dnnl::memory::format_tag::ab + oi = ab, + /// 2D CNN weights tensor; an alias for #dnnl::memory::format_tag::ba + io = ba, + /// 3D CNN weights tensor; an alias for #dnnl::memory::format_tag::abc + oiw = abc, + /// 3D CNN weights tensor; an alias for #dnnl::memory::format_tag::acb + owi = acb, + /// 3D CNN weights tensor; an alias for #dnnl::memory::format_tag::cba + wio = cba, + /// 3D CNN weights tensor; an alias for #dnnl::memory::format_tag::bca + iwo = bca, + /// 4D CNN weights tensor; an alias for #dnnl::memory::format_tag::abcd + oihw = abcd, + /// 4D CNN weights tensor; an alias for #dnnl::memory::format_tag::cdba + hwio = cdba, + /// 4D CNN weights tensor; an alias for #dnnl::memory::format_tag::acdb + ohwi = acdb, + /// 4D CNN weights tensor; an alias for #dnnl::memory::format_tag::bcda + ihwo = bcda, + /// 4D CNN weights tensor; an alias for #dnnl::memory::format_tag::bacd + iohw = bacd, + /// 5D CNN weights tensor; an alias for #dnnl::memory::format_tag::abcde + oidhw = abcde, + /// 5D CNN weights tensor; an alias for #dnnl::memory::format_tag::cdeba + dhwio = cdeba, + /// 5D CNN weights tensor; an alias for #dnnl::memory::format_tag::acdeb + odhwi = acdeb, + /// 5D CNN weights tensor; an alias for #dnnl::memory::format_tag::bacde + iodhw = bacde, + /// 5D CNN weights tensor; an alias for #dnnl::memory::format_tag::bcdea + idhwo = bcdea, + + /// 4D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::abcd + goiw = abcd, + /// 4D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::abdc + gowi = abdc, + /// 4D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::dcab + wigo = dcab, + /// 5D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::abdec + gohwi = abdec, + /// 5D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::abcde + goihw = abcde, + /// 5D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::decab + hwigo = decab, + /// 5D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::acbde + giohw = acbde, + /// 6D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::abcdef + goidhw = abcdef, + /// 6D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::abcdef + giodhw = acbdef, + /// 6D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::abdefc + godhwi = abdefc, + /// 6D CNN weights tensor with groups; an alias for #dnnl::memory::format_tag::defcab + dhwigo = defcab, + + /// 3D RNN data tensor in the format (seq_length, batch, input + /// channels); an alias for #dnnl::memory::format_tag::abc. + tnc = abc, + /// 3D RNN data tensor in the format (batch, seq_length, input + /// channels); an alias for #dnnl::memory::format_tag::bac. + ntc = bac, + /// 4D RNN states tensor in the format (num_layers, num_directions, + /// batch, state channels); an alias for #dnnl::memory::format_tag::abcd. + ldnc = abcd, + /// 5D RNN weights tensor in the format (num_layers, num_directions, + /// input_channels, num_gates, output_channels); + /// an alias for #dnnl::memory::format_tag::abcde. + /// + /// - For LSTM cells, the gates order is input, forget, candidate + /// and output gate. + /// - For GRU cells, the gates order is update, reset and output gate. + ldigo = abcde, + /// 5D RNN weights tensor in the format (num_layers, num_directions, + /// num_gates, output_channels, input_channels); + /// an alias for #dnnl::memory::format_tag::abdec. + /// + /// - For LSTM cells, the gates order is input, forget, candidate + /// and output gate. + /// - For GRU cells, the gates order is update, reset and output gate. + ldgoi = abdec, + /// 4D LSTM projection tensor in the format (num_layers, num_directions, + /// num_channels_in_hidden_state, num_channels_in_recurrent_projection); + /// an alias for #dnnl::memory::format_tag::abcd. + ldio = abcd, + /// 4D LSTM projection tensor in the format (num_layers, num_directions, + /// num_channels_in_recurrent_projection, num_channels_in_hidden_state); + /// an alias for #dnnl::memory::format_tag::abdc. + ldoi = abdc, + /// 4D RNN bias tensor in the format (num_layers, num_directions, + /// num_gates, output_channels); + /// an alias for #dnnl::memory::format_tag::abcd. + /// + /// - For LSTM cells, the gates order is input, forget, candidate + /// and output gate. + /// - For GRU cells, the gates order is update, reset and output gate. + ldgo = abcd, + + // Opaque blocked formats + + AB16b16a = dnnl_AB16b16a, + AB16b32a = dnnl_AB16b32a, + AB16b48a = dnnl_AB16b48a, + AB16b64a = dnnl_AB16b64a, + AB8b16a2b = dnnl_AB8b16a2b, + AB8b32a2b = dnnl_AB8b32a2b, + AB8b64a2b = dnnl_AB8b64a2b, + AB4b16a4b = dnnl_AB4b16a4b, + AB4b32a4b = dnnl_AB4b32a4b, + AB4b64a4b = dnnl_AB4b64a4b, + AB16b16a4b = dnnl_AB16b16a4b, + AB16b32a4b = dnnl_AB16b32a4b, + AB16b48a4b = dnnl_AB16b48a4b, + AB16b64a4b = dnnl_AB16b64a4b, + AB16b16a2b = dnnl_AB16b16a2b, + AB16b32a2b = dnnl_AB16b32a2b, + AB16b48a2b = dnnl_AB16b48a2b, + AB16b64a2b = dnnl_AB16b64a2b, + Ab4a = dnnl_Ab4a, + Ab8a = dnnl_Ab8a, + Ab32a = dnnl_Ab32a, + Abc16a = dnnl_Abc16a, + ABc16a16b = dnnl_ABc16a16b, + ABc4a4b = dnnl_ABc4a4b, + aBc16b = dnnl_aBc16b, + aBc32b = dnnl_aBc32b, + ABc16b16a = dnnl_ABc16b16a, + AcB16b16a = dnnl_AcB16b16a, + ABc16b32a = dnnl_ABc16b32a, + AcB16b32a = dnnl_AcB16b32a, + ABc16b48a = dnnl_ABc16b48a, + AcB16b48a = dnnl_AcB16b48a, + ABc16b64a = dnnl_ABc16b64a, + AcB16b64a = dnnl_AcB16b64a, + Abc4a = dnnl_Abc4a, + aBc4b = dnnl_aBc4b, + ABc4b16a4b = dnnl_ABc4b16a4b, + AcB4b16a4b = dnnl_AcB4b16a4b, + ABc4b32a4b = dnnl_ABc4b32a4b, + AcB4b32a4b = dnnl_AcB4b32a4b, + ABc4b64a4b = dnnl_ABc4b64a4b, + AcB4b64a4b = dnnl_AcB4b64a4b, + ABc2b8a4b = dnnl_ABc2b8a4b, + ABc16a16b2a = dnnl_ABc16a16b2a, + ABc16b16a4b = dnnl_ABc16b16a4b, + ABc16b32a4b = dnnl_ABc16b32a4b, + ABc16b48a4b = dnnl_ABc16b48a4b, + ABc16b64a4b = dnnl_ABc16b64a4b, + ABc16b16a2b = dnnl_ABc16b16a2b, + ABc16b32a2b = dnnl_ABc16b32a2b, + ABc16b48a2b = dnnl_ABc16b48a2b, + ABc16b64a2b = dnnl_ABc16b64a2b, + ABc4b4a = dnnl_ABc4b4a, + ABc8a16b2a = dnnl_ABc8a16b2a, + ABc8a8b = dnnl_ABc8a8b, + ABc8a4b = dnnl_ABc8a4b, + aBc8b = dnnl_aBc8b, + ABc8b16a2b = dnnl_ABc8b16a2b, + AcB8b16a2b = dnnl_AcB8b16a2b, + ABc8b32a2b = dnnl_ABc8b32a2b, + AcB8b32a2b = dnnl_AcB8b32a2b, + ABc8b64a2b = dnnl_ABc8b64a2b, + AcB8b64a2b = dnnl_AcB8b64a2b, + ABc8b8a = dnnl_ABc8b8a, + AcB8b8a = dnnl_AcB8b8a, + Abcd8a = dnnl_Abcd8a, + Abcd16a = dnnl_Abcd16a, + Abcd32a = dnnl_Abcd32a, + ABcd16a16b = dnnl_ABcd16a16b, + aBcd16b = dnnl_aBcd16b, + aBcd32b = dnnl_aBcd32b, + ABcd16b16a = dnnl_ABcd16b16a, + AcdB16b16a = dnnl_AcdB16b16a, + ABcd16b32a = dnnl_ABcd16b32a, + AcdB16b32a = dnnl_AcdB16b32a, + ABcd16b48a = dnnl_ABcd16b48a, + AcdB16b48a = dnnl_AcdB16b48a, + ABcd16b64a = dnnl_ABcd16b64a, + AcdB16b64a = dnnl_AcdB16b64a, + aBCd16b16c = dnnl_aBCd16b16c, + aBCd16c16b = dnnl_aBCd16c16b, + Abcd4a = dnnl_Abcd4a, + aBcd4b = dnnl_aBcd4b, + ABcd4b16a4b = dnnl_ABcd4b16a4b, + AcdB4b16a4b = dnnl_AcdB4b16a4b, + ABcd4b32a4b = dnnl_ABcd4b32a4b, + AcdB4b32a4b = dnnl_AcdB4b32a4b, + ABcd4b64a4b = dnnl_ABcd4b64a4b, + AcdB4b64a4b = dnnl_AcdB4b64a4b, + ABcd2b8a4b = dnnl_ABcd2b8a4b, + ABcd4b4a = dnnl_ABcd4b4a, + ABcd4a4b = dnnl_ABcd4a4b, + aBCd4c16b4c = dnnl_aBCd4c16b4c, + aBCd2c8b4c = dnnl_aBCd2c8b4c, + ABcd16a16b2a = dnnl_ABcd16a16b2a, + ABcd16b16a4b = dnnl_ABcd16b16a4b, + ABcd16b32a4b = dnnl_ABcd16b32a4b, + ABcd16b48a4b = dnnl_ABcd16b48a4b, + ABcd16b64a4b = dnnl_ABcd16b64a4b, + ABcd16b16a2b = dnnl_ABcd16b16a2b, + ABcd16b32a2b = dnnl_ABcd16b32a2b, + ABcd16b48a2b = dnnl_ABcd16b48a2b, + ABcd16b64a2b = dnnl_ABcd16b64a2b, + aBCd16b16c2b = dnnl_aBCd16b16c2b, + aBCd16c16b4c = dnnl_aBCd16c16b4c, + aBCd16c16b2c = dnnl_aBCd16c16b2c, + aBCd4c4b = dnnl_aBCd4c4b, + aBCd4b4c = dnnl_aBCd4b4c, + ABcd8a16b2a = dnnl_ABcd8a16b2a, + ABcd8a8b = dnnl_ABcd8a8b, + ABcd8a4b = dnnl_ABcd8a4b, + ABcd8a2b = dnnl_ABcd8a2b, + /// 4D tensor blocked by 2nd dimension with block size 8 + aBcd8b = dnnl_aBcd8b, + ABcd8b16a2b = dnnl_ABcd8b16a2b, + AcdB8b16a2b = dnnl_AcdB8b16a2b, + ABcd8b32a2b = dnnl_ABcd8b32a2b, + AcdB8b32a2b = dnnl_AcdB8b32a2b, + ABcd8b64a2b = dnnl_ABcd8b64a2b, + AcdB8b64a2b = dnnl_AcdB8b64a2b, + aBCd8b16c2b = dnnl_aBCd8b16c2b, + /// 4D tensor blocked by 1st and 2nd dimension with block size 8 + ABcd8b8a = dnnl_ABcd8b8a, + AcdB8b8a = dnnl_AcdB8b8a, + aBCd8b8c = dnnl_aBCd8b8c, + aBCd8b4c = dnnl_aBCd8b4c, + aBCd8c16b2c = dnnl_aBCd8c16b2c, + aBCd8c8b = dnnl_aBCd8c8b, + Abcde16a = dnnl_Abcde16a, + Abcde32a = dnnl_Abcde32a, + ABcde16a16b = dnnl_ABcde16a16b, + aBcde16b = dnnl_aBcde16b, + aBcde32b = dnnl_aBcde32b, + ABcde16b16a = dnnl_ABcde16b16a, + AcdeB16b16a = dnnl_AcdeB16b16a, + ABcde16b32a = dnnl_ABcde16b32a, + AcdeB16b32a = dnnl_AcdeB16b32a, + ABcde16b48a = dnnl_ABcde16b48a, + AcdeB16b48a = dnnl_AcdeB16b48a, + ABcde16b64a = dnnl_ABcde16b64a, + AcdeB16b64a = dnnl_AcdeB16b64a, + aBCde16b16c = dnnl_aBCde16b16c, + aBCde16c16b = dnnl_aBCde16c16b, + aBCde2c8b4c = dnnl_aBCde2c8b4c, + Abcde4a = dnnl_Abcde4a, + aBcde4b = dnnl_aBcde4b, + ABcde4b4a = dnnl_ABcde4b4a, + ABcde4a4b = dnnl_ABcde4a4b, + aBCde4b4c = dnnl_aBCde4b4c, + aBCde4c16b4c = dnnl_aBCde4c16b4c, + aBCde16b16c2b = dnnl_aBCde16b16c2b, + aBCde16c16b4c = dnnl_aBCde16c16b4c, + aBCde16c16b2c = dnnl_aBCde16c16b2c, + aBCdef16c16b2c = dnnl_aBCdef16c16b2c, + aBCde4c4b = dnnl_aBCde4c4b, + Abcde8a = dnnl_Abcde8a, + ABcde8a8b = dnnl_ABcde8a8b, + ABcde8a4b = dnnl_ABcde8a4b, + aBcde8b = dnnl_aBcde8b, + ABcde8b16a2b = dnnl_ABcde8b16a2b, + AcdeB8b16a2b = dnnl_AcdeB8b16a2b, + ABcde8b32a2b = dnnl_ABcde8b32a2b, + AcdeB8b32a2b = dnnl_AcdeB8b32a2b, + ABcde8b64a2b = dnnl_ABcde8b64a2b, + AcdeB8b64a2b = dnnl_AcdeB8b64a2b, + ABcde4b16a4b = dnnl_ABcde4b16a4b, + AcdeB4b16a4b = dnnl_AcdeB4b16a4b, + ABcde4b32a4b = dnnl_ABcde4b32a4b, + AcdeB4b32a4b = dnnl_AcdeB4b32a4b, + ABcde4b64a4b = dnnl_ABcde4b64a4b, + AcdeB4b64a4b = dnnl_AcdeB4b64a4b, + ABcde16b16a4b = dnnl_ABcde16b16a4b, + ABcde16b32a4b = dnnl_ABcde16b32a4b, + ABcde16b48a4b = dnnl_ABcde16b48a4b, + ABcde16b64a4b = dnnl_ABcde16b64a4b, + ABcde16b16a2b = dnnl_ABcde16b16a2b, + ABcde16b32a2b = dnnl_ABcde16b32a2b, + ABcde16b48a2b = dnnl_ABcde16b48a2b, + ABcde16b64a2b = dnnl_ABcde16b64a2b, + ABcde2b8a4b = dnnl_ABcde2b8a4b, + aBCde8b16c2b = dnnl_aBCde8b16c2b, + ABcde8b8a = dnnl_ABcde8b8a, + AcdeB8b8a = dnnl_AcdeB8b8a, + aBCde8b8c = dnnl_aBCde8b8c, + aBCde8b4c = dnnl_aBCde8b4c, + ABcd4a8b8a4b = dnnl_ABcd4a8b8a4b, + ABcd2a8b8a2b = dnnl_ABcd2a8b8a2b, + aBCde4b8c8b4c = dnnl_aBCde4b8c8b4c, + aBCde2b8c8b2c = dnnl_aBCde2b8c8b2c, + aBCde8c16b2c = dnnl_aBCde8c16b2c, + aBCde8c8b = dnnl_aBCde8c8b, + aBcdef16b = dnnl_aBcdef16b, + aBCdef16b16c = dnnl_aBCdef16b16c, + aBCdef16c16b = dnnl_aBCdef16c16b, + aBcdef4b = dnnl_aBcdef4b, + aBCdef2c8b4c = dnnl_aBCdef2c8b4c, + aBCdef4c4b = dnnl_aBCdef4c4b, + aBCdef4b4c = dnnl_aBCdef4b4c, + aBCdef8b8c = dnnl_aBCdef8b8c, + aBCdef8b4c = dnnl_aBCdef8b4c, + aBCdef8c16b2c = dnnl_aBCdef8c16b2c, + aBCdef4c16b4c = dnnl_aBCdef4c16b4c, + aBCdef8c8b = dnnl_aBCdef8c8b, + aBdc16b = dnnl_aBdc16b, + aBdc4b = dnnl_aBdc4b, + aBdc8b = dnnl_aBdc8b, + aBdC8b2c = dnnl_aBdC8b2c, + aBdC8b4c = dnnl_aBdC8b4c, + aBdec16b = dnnl_aBdec16b, + aBdec4b = dnnl_aBdec4b, + aBdec8b = dnnl_aBdec8b, + aBdeC8b2c = dnnl_aBdeC8b2c, + aBdeC8b4c = dnnl_aBdeC8b4c, + aBdefc16b = dnnl_aBdefc16b, + aCBdef16c16b = dnnl_aCBdef16c16b, + aCBdef8b8c = dnnl_aCBdef8b8c, + aCBdef16b16c = dnnl_aCBdef16b16c, + aBdefc4b = dnnl_aBdefc4b, + aBdefc8b = dnnl_aBdefc8b, + aBdefC8b2c = dnnl_aBdefC8b2c, + aBdefC8b4c = dnnl_aBdefC8b4c, + Acb16a = dnnl_Acb16a, + Acb4a = dnnl_Acb4a, + Acb8a = dnnl_Acb8a, + AcB8a2b = dnnl_AcB8a2b, + AcB8a4b = dnnl_AcB8a4b, + aCBd8b8c = dnnl_aCBd8b8c, + aCBd16b16c = dnnl_aCBd16b16c, + aCBd16c16b = dnnl_aCBd16c16b, + aCBde8b8c = dnnl_aCBde8b8c, + aCBde16b16c = dnnl_aCBde16b16c, + aCBde16c16b = dnnl_aCBde16c16b, + Acdb16a = dnnl_Acdb16a, + Acdb4a = dnnl_Acdb4a, + Acdb8a = dnnl_Acdb8a, + AcdB8a2b = dnnl_AcdB8a2b, + AcdB8a4b = dnnl_AcdB8a4b, + Acdeb16a = dnnl_Acdeb16a, + Acdeb4a = dnnl_Acdeb4a, + Acdeb8a = dnnl_Acdeb8a, + AcdeB8a2b = dnnl_AcdeB8a2b, + AcdeB8a4b = dnnl_AcdeB8a4b, + BAc8a8b = dnnl_BAc8a8b, + BAc16a16b = dnnl_BAc16a16b, + BAc16b16a = dnnl_BAc16b16a, + BAcd8a8b = dnnl_BAcd8a8b, + BAcd16a16b = dnnl_BAcd16a16b, + BAcd16b16a = dnnl_BAcd16b16a, + ABcd32a32b = dnnl_ABcd32a32b, + BAcde16b16a = dnnl_BAcde16b16a, + BAcde8a8b = dnnl_BAcde8a8b, + BAcde16a16b = dnnl_BAcde16a16b, + aBdec32b = dnnl_aBdec32b, + Abcdef16a = dnnl_Abcdef16a, + Abcdef32a = dnnl_Abcdef32a, + Acdb32a = dnnl_Acdb32a, + aBCd2b4c2b = dnnl_aBCd2b4c2b, + aBCde2b4c2b = dnnl_aBCde2b4c2b, + aBCdef2b4c2b = dnnl_aBCdef2b4c2b, + aBCd2c4b2c = dnnl_aBCd2c4b2c, + aBCde2c4b2c = dnnl_aBCde2c4b2c, + aBCdef2c4b2c = dnnl_aBCdef2c4b2c, + aBCd4b8c2b = dnnl_aBCd4b8c2b, + aBCde4b8c2b = dnnl_aBCde4b8c2b, + aBCdef4b8c2b = dnnl_aBCdef4b8c2b, + aBCd4c8b2c = dnnl_aBCd4c8b2c, + aBCde4c8b2c = dnnl_aBCde4c8b2c, + aBCdef4c8b2c = dnnl_aBCdef4c8b2c, + AB32a32b8a4b = dnnl_AB32a32b8a4b, + AB32a32b8a2b = dnnl_AB32a32b8a2b, + AB8a4b = dnnl_AB8a4b, + AB8a2b = dnnl_AB8a2b, + abDc16d = dnnl_abDc16d, + abDc32d = dnnl_abDc32d, + abDC16d4c = dnnl_abDC16d4c, + abDC32d4c = dnnl_abDC32d4c, + abCd32c = dnnl_abCd32c, + abdEc16e = dnnl_abdEc16e, + abdEc32e = dnnl_abdEc32e, + abdEC16e4c = dnnl_abdEC16e4c, + abdEC32e2c = dnnl_abdEC32e2c, + abdEC32e4c = dnnl_abdEC32e4c, + abdCe16c = dnnl_abdCe16c, + abdCe32c = dnnl_abdCe32c, + abdCE32c2e = dnnl_abdCE32c2e, + aBCdef16c16b4c = dnnl_aBCdef16c16b4c, + aBdC16b4c = dnnl_aBdC16b4c, + aBdeC16b4c = dnnl_aBdeC16b4c, + AcB16a4b = dnnl_AcB16a4b, + AcdB16a2b = dnnl_AcdB16a2b, + aBdefC16b4c = dnnl_aBdefC16b4c, + AcdeB16a4b = dnnl_AcdeB16a4b, + + Acb32a = dnnl_Acb32a, + AcB32a2b = dnnl_AcB32a2b, + AcB32a4b = dnnl_AcB32a4b, + Acb48a = dnnl_Acb48a, + AcB48a2b = dnnl_AcB48a2b, + AcB48a4b = dnnl_AcB48a4b, + Acb64a = dnnl_Acb64a, + AcB64a2b = dnnl_AcB64a2b, + AcB64a4b = dnnl_AcB64a4b, + cBa2b = dnnl_cBa2b, + cBa4b = dnnl_cBa4b, + aBdc32b = dnnl_aBdc32b, + aBdC32b2c = dnnl_aBdC32b2c, + aBdC32b4c = dnnl_aBdC32b4c, + aBdc48b = dnnl_aBdc48b, + aBdC48b2c = dnnl_aBdC48b2c, + aBdC48b4c = dnnl_aBdC48b4c, + aBdc64b = dnnl_aBdc64b, + aBdC64b2c = dnnl_aBdC64b2c, + aBdC64b4c = dnnl_aBdC64b4c, + adcb = dnnl_adcb, + adCb2c = dnnl_adCb2c, + adCb4c = dnnl_adCb4c, + AcdB32a2b = dnnl_AcdB32a2b, + AcdB32a4b = dnnl_AcdB32a4b, + Acdb48a = dnnl_Acdb48a, + AcdB48a2b = dnnl_AcdB48a2b, + AcdB48a4b = dnnl_AcdB48a4b, + Acdb64a = dnnl_Acdb64a, + AcdB64a2b = dnnl_AcdB64a2b, + AcdB64a4b = dnnl_AcdB64a4b, + cdBa2b = dnnl_cdBa2b, + cdBa4b = dnnl_cdBa4b, + aBdeC32b2c = dnnl_aBdeC32b2c, + aBdeC32b4c = dnnl_aBdeC32b4c, + aBdec48b = dnnl_aBdec48b, + aBdeC48b2c = dnnl_aBdeC48b2c, + aBdeC48b4c = dnnl_aBdeC48b4c, + aBdec64b = dnnl_aBdec64b, + aBdeC64b2c = dnnl_aBdeC64b2c, + aBdeC64b4c = dnnl_aBdeC64b4c, + adecb = dnnl_adecb, + adeCb2c = dnnl_adeCb2c, + adeCb4c = dnnl_adeCb4c, + Acdeb32a = dnnl_Acdeb32a, + AcdeB32a2b = dnnl_AcdeB32a2b, + AcdeB32a4b = dnnl_AcdeB32a4b, + Acdeb48a = dnnl_Acdeb48a, + AcdeB48a2b = dnnl_AcdeB48a2b, + AcdeB48a4b = dnnl_AcdeB48a4b, + Acdeb64a = dnnl_Acdeb64a, + AcdeB64a2b = dnnl_AcdeB64a2b, + AcdeB64a4b = dnnl_AcdeB64a4b, + cdeBa2b = dnnl_cdeBa2b, + cdeBa4b = dnnl_cdeBa4b, + aBdefc32b = dnnl_aBdefc32b, + aBdefC32b2c = dnnl_aBdefC32b2c, + aBdefC32b4c = dnnl_aBdefC32b4c, + aBdefc48b = dnnl_aBdefc48b, + aBdefC48b2c = dnnl_aBdefC48b2c, + aBdefC48b4c = dnnl_aBdefC48b4c, + aBdefc64b = dnnl_aBdefc64b, + aBdefC64b2c = dnnl_aBdefC64b2c, + aBdefC64b4c = dnnl_aBdefC64b4c, + adefcb = dnnl_adefcb, + adefCb2c = dnnl_adefCb2c, + adefCb4c = dnnl_adefCb4c, + ABc32a32b = dnnl_ABc32a32b, + BAc8a16b2a = dnnl_BAc8a16b2a, + BAcd8a16b2a = dnnl_BAcd8a16b2a, + ABcde8a16b2a = dnnl_ABcde8a16b2a, + aCBd8b16c2b = dnnl_aCBd8b16c2b, + BAcde8a16b2a = dnnl_BAcde8a16b2a, + aCBde8b16c2b = dnnl_aCBde8b16c2b, + ABcde32a32b = dnnl_ABcde32a32b, + ABc4a8b8a4b = dnnl_ABc4a8b8a4b, + ABcde4a8b8a4b = dnnl_ABcde4a8b8a4b, + BAc4b8a8b4a = dnnl_BAc4b8a8b4a, + BAcd4b8a8b4a = dnnl_BAcd4b8a8b4a, + BAcde4b8a8b4a = dnnl_BAcde4b8a8b4a, + aBCd4b8c8b4c = dnnl_aBCd4b8c8b4c, + aBCdef4b8c8b4c = dnnl_aBCdef4b8c8b4c, + aBCdef8b16c2b = dnnl_aBCdef8b16c2b, + aCBdef8b16c2b = dnnl_aCBdef8b16c2b, + aBdC16b2c = dnnl_aBdC16b2c, + aBdeC16b2c = dnnl_aBdeC16b2c, + aBdefC16b2c = dnnl_aBdefC16b2c, + aBedc16b = dnnl_aBedc16b, + AcB16a2b = dnnl_AcB16a2b, + AcdB16a4b = dnnl_AcdB16a4b, + AcdeB16a2b = dnnl_AcdeB16a2b, + Adcb16a = dnnl_Adcb16a, + aCBd4c8b8c4b = dnnl_aCBd4c8b8c4b, + aCBde4c8b8c4b = dnnl_aCBde4c8b8c4b, + aCBdef4c8b8c4b = dnnl_aCBdef4c8b8c4b, + ABc32a16b = dnnl_ABc32a16b, + ABcd16a32b = dnnl_ABcd16a32b, + ABcd32a16b = dnnl_ABcd32a16b, + ABcde32a16b = dnnl_ABcde32a16b, + AB48a16b = dnnl_AB48a16b, + AB48a32b = dnnl_AB48a32b, + ABc40a16b = dnnl_ABc40a16b, + ABc40a32b = dnnl_ABc40a32b, + aBC48b16c = dnnl_aBC48b16c, + aBC48b32c = dnnl_aBC48b32c, + ABcd40a16b = dnnl_ABcd40a16b, + ABcd40a32b = dnnl_ABcd40a32b, + BA16a16b = dnnl_BA16a16b, + BA16a32b = dnnl_BA16a32b, + BA16a48b = dnnl_BA16a48b, + BA16a64b = dnnl_BA16a64b, + BA16a16b2a = dnnl_BA16a16b2a, + BA16a32b2a = dnnl_BA16a32b2a, + BA16a48b2a = dnnl_BA16a48b2a, + BA16a64b2a = dnnl_BA16a64b2a, + BA16a16b4a = dnnl_BA16a16b4a, + BA16a32b4a = dnnl_BA16a32b4a, + BA16a48b4a = dnnl_BA16a48b4a, + BA16a64b4a = dnnl_BA16a64b4a, + BA24b8a = dnnl_BA24b8a, + aCB24c8b = dnnl_aCB24c8b, + abDC24d8c = dnnl_abDC24d8c, + decbA16a = dnnl_decbA16a, + decbA8a = dnnl_decbA8a, + defcbA16a = dnnl_defcbA16a, + defcbA8a = dnnl_defcbA8a, + aCB16b16c = dnnl_aCB16b16c, + aCB16b32c = dnnl_aCB16b32c, + aCB16b48c = dnnl_aCB16b48c, + aCB16b64c = dnnl_aCB16b64c, + aCB16b16c2b = dnnl_aCB16b16c2b, + aCB16b32c2b = dnnl_aCB16b32c2b, + aCB16b48c2b = dnnl_aCB16b48c2b, + aCB16b64c2b = dnnl_aCB16b64c2b, + aCB16b16c4b = dnnl_aCB16b16c4b, + aCB16b32c4b = dnnl_aCB16b32c4b, + aCB16b48c4b = dnnl_aCB16b48c4b, + aCB16b64c4b = dnnl_aCB16b64c4b, + Acb24a = dnnl_Acb24a, + Acdb24a = dnnl_Acdb24a, + Acdeb24a = dnnl_Acdeb24a, + aBdc24b = dnnl_aBdc24b, + aBdec24b = dnnl_aBdec24b, + aBdefc24b = dnnl_aBdefc24b, + AcB24a2b = dnnl_AcB24a2b, + AcdB24a2b = dnnl_AcdB24a2b, + AcdeB24a2b = dnnl_AcdeB24a2b, + aBdC24b2c = dnnl_aBdC24b2c, + aBdeC24b2c = dnnl_aBdeC24b2c, + aBdefC24b2c = dnnl_aBdefC24b2c, + AcB24a4b = dnnl_AcB24a4b, + AcdB24a4b = dnnl_AcdB24a4b, + AcdeB24a4b = dnnl_AcdeB24a4b, + aBdC24b4c = dnnl_aBdC24b4c, + aBdeC24b4c = dnnl_aBdeC24b4c, + aBdefC24b4c = dnnl_aBdefC24b4c, + AB8b32a = dnnl_AB8b32a, + ABc8b32a = dnnl_ABc8b32a, + AcB8b32a = dnnl_AcB8b32a, + ABcd8b32a = dnnl_ABcd8b32a, + AcdB8b32a = dnnl_AcdB8b32a, + ABcde8b32a = dnnl_ABcde8b32a, + AcdeB8b32a = dnnl_AcdeB8b32a, + AB8b24a = dnnl_AB8b24a, + ABc8b24a = dnnl_ABc8b24a, + AcB8b24a = dnnl_AcB8b24a, + ABcd8b24a = dnnl_ABcd8b24a, + AcdB8b24a = dnnl_AcdB8b24a, + ABcde8b24a = dnnl_ABcde8b24a, + AcdeB8b24a = dnnl_AcdeB8b24a, + AB8b16a = dnnl_AB8b16a, + ABc8b16a = dnnl_ABc8b16a, + AcB8b16a = dnnl_AcB8b16a, + ABcd8b16a = dnnl_ABcd8b16a, + AcdB8b16a = dnnl_AcdB8b16a, + ABcde8b16a = dnnl_ABcde8b16a, + AcdeB8b16a = dnnl_AcdeB8b16a, + AB8b8a = dnnl_AB8b8a, + abDC8d8c = dnnl_abDC8d8c, + abDC16d8c = dnnl_abDC16d8c, + aCB8c8b = dnnl_aCB8c8b, + aCB16c8b = dnnl_aCB16c8b, + BA8b8a = dnnl_BA8b8a, + BA16b8a = dnnl_BA16b8a, + AB2a4b = dnnl_AB2a4b, + + format_tag_last = dnnl_format_tag_last, + + nCdhw16c = dnnl_nCdhw16c, + nCdhw4c = dnnl_nCdhw4c, + nCdhw8c = dnnl_nCdhw8c, + nChw16c = dnnl_nChw16c, + nChw4c = dnnl_nChw4c, + nChw8c = dnnl_nChw8c, + nCw16c = dnnl_nCw16c, + nCw4c = dnnl_nCw4c, + nCw8c = dnnl_nCw8c, + NCw16n16c = dnnl_NCw16n16c, + NChw16n16c = dnnl_NChw16n16c, + NCdhw16n16c = dnnl_NCdhw16n16c, + NCdhw32n32c = dnnl_NCdhw32n32c, + NChw32n32c = dnnl_NChw32n32c, + IOhw16i16o = dnnl_IOhw16i16o, + OI16i16o = dnnl_OI16i16o, + OI16i32o = dnnl_OI16i32o, + OI16i48o = dnnl_OI16i48o, + OI16i64o = dnnl_OI16i64o, + OI8i16o2i = dnnl_OI8i16o2i, + OI8i32o2i = dnnl_OI8i32o2i, + OI8i64o2i = dnnl_OI8i64o2i, + OI4i8o4i = dnnl_OI4i8o4i, + OI4i16o4i = dnnl_OI4i16o4i, + OI4i24o4i = dnnl_OI4i24o4i, + OI4i32o4i = dnnl_OI4i32o4i, + OI4i64o4i = dnnl_OI4i64o4i, + Ohwi32o = dnnl_Ohwi32o, + IOdhw16i16o = dnnl_IOdhw16i16o, + gIOhw16i16o = dnnl_gIOhw16i16o, + gOhwi32o = dnnl_gOhwi32o, + Goidhw16g = dnnl_Goidhw16g, + IOw8o8i = dnnl_IOw8o8i, + IOw16o16i = dnnl_IOw16o16i, + OIw16i16o = dnnl_OIw16i16o, + OwI16i16o = dnnl_OwI16i16o, + OIw16i32o = dnnl_OIw16i32o, + OwI16i32o = dnnl_OwI16i32o, + OIw16i48o = dnnl_OIw16i48o, + OwI16i48o = dnnl_OwI16i48o, + OIw16i64o = dnnl_OIw16i64o, + OwI16i64o = dnnl_OwI16i64o, + IOw16i16o = dnnl_IOw16i16o, + gIOw16i16o = dnnl_gIOw16i16o, + OIw16o16i = dnnl_OIw16o16i, + Oiw16o = dnnl_Oiw16o, + OIw4i8o4i = dnnl_OIw4i8o4i, + OwI4i8o4i = dnnl_OwI4i8o4i, + OIw4i16o4i = dnnl_OIw4i16o4i, + OwI4i16o4i = dnnl_OwI4i16o4i, + OIw4i24o4i = dnnl_OIw4i24o4i, + OwI4i24o4i = dnnl_OwI4i24o4i, + OIw4i32o4i = dnnl_OIw4i32o4i, + OwI4i32o4i = dnnl_OwI4i32o4i, + OIw4i64o4i = dnnl_OIw4i64o4i, + OwI4i64o4i = dnnl_OwI4i64o4i, + OIw2i8o4i = dnnl_OIw2i8o4i, + OIw4i4o = dnnl_OIw4i4o, + OIw4o4i = dnnl_OIw4o4i, + Oiw4o = dnnl_Oiw4o, + OIw8i16o2i = dnnl_OIw8i16o2i, + OwI8i16o2i = dnnl_OwI8i16o2i, + OIw8i32o2i = dnnl_OIw8i32o2i, + OwI8i32o2i = dnnl_OwI8i32o2i, + OIw8i64o2i = dnnl_OIw8i64o2i, + OwI8i64o2i = dnnl_OwI8i64o2i, + OIw8i8o = dnnl_OIw8i8o, + OwI8i8o = dnnl_OwI8i8o, + OIw8o16i2o = dnnl_OIw8o16i2o, + OIw8o8i = dnnl_OIw8o8i, + OIw8o4i = dnnl_OIw8o4i, + OIw16i16o4i = dnnl_OIw16i16o4i, + OIw16i32o4i = dnnl_OIw16i32o4i, + OIw16i48o4i = dnnl_OIw16i48o4i, + OIw16i64o4i = dnnl_OIw16i64o4i, + OIw16i16o2i = dnnl_OIw16i16o2i, + OIw16i32o2i = dnnl_OIw16i32o2i, + OIw16i48o2i = dnnl_OIw16i48o2i, + OIw16i64o2i = dnnl_OIw16i64o2i, + OIw16o16i2o = dnnl_OIw16o16i2o, + Owi16o = dnnl_Owi16o, + OwI16o2i = dnnl_OwI16o2i, + Iwo16i = dnnl_Iwo16i, + IwO16i2o = dnnl_IwO16i2o, + IwO16i4o = dnnl_IwO16i4o, + Owi4o = dnnl_Owi4o, + Owi8o = dnnl_Owi8o, + OwI8o2i = dnnl_OwI8o2i, + OwI8o4i = dnnl_OwI8o4i, + IOhw8o8i = dnnl_IOhw8o8i, + IOhw16o16i = dnnl_IOhw16o16i, + Ohwi16o = dnnl_Ohwi16o, + OhwI16o2i = dnnl_OhwI16o2i, + Ihwo16i = dnnl_Ihwo16i, + IhwO16i2o = dnnl_IhwO16i2o, + IhwO16i4o = dnnl_IhwO16i4o, + Ohwi4o = dnnl_Ohwi4o, + Ohwi8o = dnnl_Ohwi8o, + OhwI8o2i = dnnl_OhwI8o2i, + OhwI8o4i = dnnl_OhwI8o4i, + OIhw16i16o = dnnl_OIhw16i16o, + OhwI16i16o = dnnl_OhwI16i16o, + OIhw16i32o = dnnl_OIhw16i32o, + OhwI16i32o = dnnl_OhwI16i32o, + OIhw16i48o = dnnl_OIhw16i48o, + OhwI16i48o = dnnl_OhwI16i48o, + OIhw16i64o = dnnl_OIhw16i64o, + OhwI16i64o = dnnl_OhwI16i64o, + OIhw16o16i = dnnl_OIhw16o16i, + Oihw16o = dnnl_Oihw16o, + OIhw4i8o4i = dnnl_OIhw4i8o4i, + OhwI4i8o4i = dnnl_OhwI4i8o4i, + OIhw4i16o4i = dnnl_OIhw4i16o4i, + OhwI4i16o4i = dnnl_OhwI4i16o4i, + OIhw4i24o4i = dnnl_OIhw4i24o4i, + OhwI4i24o4i = dnnl_OhwI4i24o4i, + OIhw4i32o4i = dnnl_OIhw4i32o4i, + OhwI4i32o4i = dnnl_OhwI4i32o4i, + OIhw4i64o4i = dnnl_OIhw4i64o4i, + OhwI4i64o4i = dnnl_OhwI4i64o4i, + OIhw4i4o = dnnl_OIhw4i4o, + OIhw4o4i = dnnl_OIhw4o4i, + Oihw4o = dnnl_Oihw4o, + OIhw8i16o2i = dnnl_OIhw8i16o2i, + OhwI8i16o2i = dnnl_OhwI8i16o2i, + OIhw8i32o2i = dnnl_OIhw8i32o2i, + OhwI8i32o2i = dnnl_OhwI8i32o2i, + OIhw8i64o2i = dnnl_OIhw8i64o2i, + OhwI8i64o2i = dnnl_OhwI8i64o2i, + OIhw8i8o = dnnl_OIhw8i8o, + OhwI8i8o = dnnl_OhwI8i8o, + OIhw8o16i2o = dnnl_OIhw8o16i2o, + OIhw8o8i = dnnl_OIhw8o8i, + OIhw8o4i = dnnl_OIhw8o4i, + OIhw2i8o4i = dnnl_OIhw2i8o4i, + IOdhw8o8i = dnnl_IOdhw8o8i, + IOdhw16o16i = dnnl_IOdhw16o16i, + Odhwi16o = dnnl_Odhwi16o, + OdhwI16o2i = dnnl_OdhwI16o2i, + Idhwo16i = dnnl_Idhwo16i, + IdhwO16i2o = dnnl_IdhwO16i2o, + IdhwO16i4o = dnnl_IdhwO16i4o, + Odhwi4o = dnnl_Odhwi4o, + Odhwi8o = dnnl_Odhwi8o, + OdhwI8o2i = dnnl_OdhwI8o2i, + OdhwI8o4i = dnnl_OdhwI8o4i, + OIdhw16i16o = dnnl_OIdhw16i16o, + OdhwI16i16o = dnnl_OdhwI16i16o, + OIdhw16i32o = dnnl_OIdhw16i32o, + OdhwI16i32o = dnnl_OdhwI16i32o, + OIdhw16i48o = dnnl_OIdhw16i48o, + OdhwI16i48o = dnnl_OdhwI16i48o, + OIdhw16i64o = dnnl_OIdhw16i64o, + OdhwI16i64o = dnnl_OdhwI16i64o, + OIdhw16o16i = dnnl_OIdhw16o16i, + OIdhw16o16i2o = dnnl_OIdhw16o16i2o, + Oidhw16o = dnnl_Oidhw16o, + OIdhw4i4o = dnnl_OIdhw4i4o, + OIdhw4o4i = dnnl_OIdhw4o4i, + Oidhw4o = dnnl_Oidhw4o, + OIdhw8i16o2i = dnnl_OIdhw8i16o2i, + OdhwI8i16o2i = dnnl_OdhwI8i16o2i, + OIdhw8i32o2i = dnnl_OIdhw8i32o2i, + OdhwI8i32o2i = dnnl_OdhwI8i32o2i, + OIdhw8i64o2i = dnnl_OIdhw8i64o2i, + OdhwI8i64o2i = dnnl_OdhwI8i64o2i, + OIdhw4i8o4i = dnnl_OIdhw4i8o4i, + OdhwI4i8o4i = dnnl_OdhwI4i8o4i, + OIdhw4i16o4i = dnnl_OIdhw4i16o4i, + OdhwI4i16o4i = dnnl_OdhwI4i16o4i, + OIdhw16i16o4i = dnnl_OIdhw16i16o4i, + OIdhw16i32o4i = dnnl_OIdhw16i32o4i, + OIdhw16i48o4i = dnnl_OIdhw16i48o4i, + OIdhw16i64o4i = dnnl_OIdhw16i64o4i, + OIdhw16i16o2i = dnnl_OIdhw16i16o2i, + OIdhw16i32o2i = dnnl_OIdhw16i32o2i, + OIdhw16i48o2i = dnnl_OIdhw16i48o2i, + OIdhw16i64o2i = dnnl_OIdhw16i64o2i, + OIdhw4i24o4i = dnnl_OIdhw4i24o4i, + OdhwI4i24o4i = dnnl_OdhwI4i24o4i, + OIdhw4i32o4i = dnnl_OIdhw4i32o4i, + OdhwI4i32o4i = dnnl_OdhwI4i32o4i, + OIdhw4i64o4i = dnnl_OIdhw4i64o4i, + OdhwI4i64o4i = dnnl_OdhwI4i64o4i, + OIdhw2i8o4i = dnnl_OIdhw2i8o4i, + OIdhw8i8o = dnnl_OIdhw8i8o, + OdhwI8i8o = dnnl_OdhwI8i8o, + OIdhw8o8i = dnnl_OIdhw8o8i, + OIdhw8o4i = dnnl_OIdhw8o4i, + gIOw8o8i = dnnl_gIOw8o8i, + gIOw16o16i = dnnl_gIOw16o16i, + gOIw16i16o = dnnl_gOIw16i16o, + gOIw16o16i = dnnl_gOIw16o16i, + gOiw16o = dnnl_gOiw16o, + gOIw4i16o4i = dnnl_gOIw4i16o4i, + gOIw2i8o4i = dnnl_gOIw2i8o4i, + gOIw4i4o = dnnl_gOIw4i4o, + gOIw4o4i = dnnl_gOIw4o4i, + gOiw4o = dnnl_gOiw4o, + gOIw8i16o2i = dnnl_gOIw8i16o2i, + gOIw8i8o = dnnl_gOIw8i8o, + gOIw8o16i2o = dnnl_gOIw8o16i2o, + gOIw8o8i = dnnl_gOIw8o8i, + gOIw8o4i = dnnl_gOIw8o4i, + gOIw16i16o4i = dnnl_gOIw16i16o4i, + gOIw16i16o2i = dnnl_gOIw16i16o2i, + gOIw16o16i2o = dnnl_gOIw16o16i2o, + gOwi16o = dnnl_gOwi16o, + gOwI16o2i = dnnl_gOwI16o2i, + gIwo16i = dnnl_gIwo16i, + gIwO16i2o = dnnl_gIwO16i2o, + gIwO16i4o = dnnl_gIwO16i4o, + gOwi4o = dnnl_gOwi4o, + gOwi8o = dnnl_gOwi8o, + gOwI8o2i = dnnl_gOwI8o2i, + gOwI8o4i = dnnl_gOwI8o4i, + Goiw8g = dnnl_Goiw8g, + Goiw16g = dnnl_Goiw16g, + gIOhw8o8i = dnnl_gIOhw8o8i, + gIOhw16o16i = dnnl_gIOhw16o16i, + gOhwi16o = dnnl_gOhwi16o, + gOhwI16o2i = dnnl_gOhwI16o2i, + gIhwo16i = dnnl_gIhwo16i, + gIhwO16i2o = dnnl_gIhwO16i2o, + gIhwO16i4o = dnnl_gIhwO16i4o, + gOhwi4o = dnnl_gOhwi4o, + gOhwi8o = dnnl_gOhwi8o, + gOhwI8o2i = dnnl_gOhwI8o2i, + gOhwI8o4i = dnnl_gOhwI8o4i, + Goihw16g = dnnl_Goihw16g, + gOIhw16i16o = dnnl_gOIhw16i16o, + gOIhw16o16i = dnnl_gOIhw16o16i, + gOihw16o = dnnl_gOihw16o, + gOIhw4i16o4i = dnnl_gOIhw4i16o4i, + gOIhw2i8o4i = dnnl_gOIhw2i8o4i, + gOIhw4i4o = dnnl_gOIhw4i4o, + gOIhw4o4i = dnnl_gOIhw4o4i, + gOihw4o = dnnl_gOihw4o, + Goihw8g = dnnl_Goihw8g, + gOIhw8i16o2i = dnnl_gOIhw8i16o2i, + gOIhw8i8o = dnnl_gOIhw8i8o, + gOIhw8o16i2o = dnnl_gOIhw8o16i2o, + OIw4o8i8o4i = dnnl_OIw4o8i8o4i, + OIdhw4o8i8o4i = dnnl_OIdhw4o8i8o4i, + OIhw4o8i8o4i = dnnl_OIhw4o8i8o4i, + OIhw2o8i8o2i = dnnl_OIhw2o8i8o2i, + gOIw4o8i8o4i = dnnl_gOIw4o8i8o4i, + gOIdhw4o8i8o4i = dnnl_gOIdhw4o8i8o4i, + gOIhw4o8i8o4i = dnnl_gOIhw4o8i8o4i, + gOIhw2o8i8o2i = dnnl_gOIhw2o8i8o2i, + OIhw16i16o4i = dnnl_OIhw16i16o4i, + OIhw16i32o4i = dnnl_OIhw16i32o4i, + OIhw16i48o4i = dnnl_OIhw16i48o4i, + OIhw16i64o4i = dnnl_OIhw16i64o4i, + OIhw16i16o2i = dnnl_OIhw16i16o2i, + OIhw16i32o2i = dnnl_OIhw16i32o2i, + OIhw16i48o2i = dnnl_OIhw16i48o2i, + OIhw16i64o2i = dnnl_OIhw16i64o2i, + OIhw16o16i2o = dnnl_OIhw16o16i2o, + gOIhw16i16o4i = dnnl_gOIhw16i16o4i, + gOIhw16i16o2i = dnnl_gOIhw16i16o2i, + gOIhw16o16i2o = dnnl_gOIhw16o16i2o, + gOIhw8o8i = dnnl_gOIhw8o8i, + gOIhw8o4i = dnnl_gOIhw8o4i, + gIOdhw16i16o = dnnl_gIOdhw16i16o, + gIOdhw8o8i = dnnl_gIOdhw8o8i, + gIOdhw16o16i = dnnl_gIOdhw16o16i, + gOdhwi16o = dnnl_gOdhwi16o, + gOdhwI16o2i = dnnl_gOdhwI16o2i, + gIdhwo16i = dnnl_gIdhwo16i, + gIdhwO16i2o = dnnl_gIdhwO16i2o, + gIdhwO16i4o = dnnl_gIdhwO16i4o, + gOdhwi4o = dnnl_gOdhwi4o, + gOdhwi8o = dnnl_gOdhwi8o, + gOdhwI8o2i = dnnl_gOdhwI8o2i, + gOdhwI8o4i = dnnl_gOdhwI8o4i, + gOIdhw16i16o = dnnl_gOIdhw16i16o, + gOIdhw16o16i = dnnl_gOIdhw16o16i, + gOIdhw16o16i2o = dnnl_gOIdhw16o16i2o, + gOidhw16o = dnnl_gOidhw16o, + gOIdhw4i4o = dnnl_gOIdhw4i4o, + gOIdhw4o4i = dnnl_gOIdhw4o4i, + gOidhw4o = dnnl_gOidhw4o, + gOIdhw8i16o2i = dnnl_gOIdhw8i16o2i, + gOIdhw4i16o4i = dnnl_gOIdhw4i16o4i, + gOIdhw16i16o4i = dnnl_gOIdhw16i16o4i, + gOIdhw16i16o2i = dnnl_gOIdhw16i16o2i, + gOIdhw2i8o4i = dnnl_gOIdhw2i8o4i, + gOIdhw8i8o = dnnl_gOIdhw8i8o, + gOIdhw8o8i = dnnl_gOIdhw8o8i, + gOIdhw8o4i = dnnl_gOIdhw8o4i, + gOIw2i4o2i = dnnl_gOIw2i4o2i, + gOIhw2i4o2i = dnnl_gOIhw2i4o2i, + gOIdhw2i4o2i = dnnl_gOIdhw2i4o2i, + gOIw2o4i2o = dnnl_gOIw2o4i2o, + gOIhw2o4i2o = dnnl_gOIhw2o4i2o, + gOIdhw2o4i2o = dnnl_gOIdhw2o4i2o, + gOIw4i8o2i = dnnl_gOIw4i8o2i, + gOIhw4i8o2i = dnnl_gOIhw4i8o2i, + gOIdhw4i8o2i = dnnl_gOIdhw4i8o2i, + gOIw4o8i2o = dnnl_gOIw4o8i2o, + gOIhw4o8i2o = dnnl_gOIhw4o8i2o, + gOIdhw4o8i2o = dnnl_gOIdhw4o8i2o, + + ldOi16o = abDc16d, + ldOi32o = abDc32d, + ldOI16o4i = abDC16d4c, + ldOI32o4i = abDC32d4c, + ldgOi16o = abdEc16e, + ldgOI16o4i = abdEC16e4c, + ldgOi32o = abdEc32e, + ldgOI32o2i = abdEC32e2c, + ldgOI32o4i = abdEC32e4c, + OwI16o4i = dnnl_OwI16o4i, + OhwI16o4i = dnnl_OhwI16o4i, + gOwI16o4i = dnnl_gOwI16o4i, + gOhwI16o4i = dnnl_gOhwI16o4i, + OdhwI16o4i = dnnl_OdhwI16o4i, + gOdhwI16o4i = dnnl_gOdhwI16o4i, + + Owi32o = dnnl_Owi32o, + OwI32o2i = dnnl_OwI32o2i, + OwI32o4i = dnnl_OwI32o4i, + Owi48o = dnnl_Owi48o, + OwI48o2i = dnnl_OwI48o2i, + OwI48o4i = dnnl_OwI48o4i, + Owi64o = dnnl_Owi64o, + OwI64o2i = dnnl_OwI64o2i, + OwI64o4i = dnnl_OwI64o4i, + Iwo32i = dnnl_Iwo32i, + IwO32i2o = dnnl_IwO32i2o, + IwO32i4o = dnnl_IwO32i4o, + Iwo48i = dnnl_Iwo48i, + IwO48i2o = dnnl_IwO48i2o, + IwO48i4o = dnnl_IwO48i4o, + Iwo64i = dnnl_Iwo64i, + IwO64i2o = dnnl_IwO64i2o, + IwO64i4o = dnnl_IwO64i4o, + wIo2i = dnnl_wIo2i, + wIo4i = dnnl_wIo4i, + gOwi32o = dnnl_gOwi32o, + gOwI32o2i = dnnl_gOwI32o2i, + gOwI32o4i = dnnl_gOwI32o4i, + gOwi48o = dnnl_gOwi48o, + gOwI48o2i = dnnl_gOwI48o2i, + gOwI48o4i = dnnl_gOwI48o4i, + gOwi64o = dnnl_gOwi64o, + gOwI64o2i = dnnl_gOwI64o2i, + gOwI64o4i = dnnl_gOwI64o4i, + gIwo32i = dnnl_gIwo32i, + gIwO32i2o = dnnl_gIwO32i2o, + gIwO32i4o = dnnl_gIwO32i4o, + gIwo48i = dnnl_gIwo48i, + gIwO48i2o = dnnl_gIwO48i2o, + gIwO48i4o = dnnl_gIwO48i4o, + gIwo64i = dnnl_gIwo64i, + gIwO64i2o = dnnl_gIwO64i2o, + gIwO64i4o = dnnl_gIwO64i4o, + gwio = dnnl_gwio, + gwIo2i = dnnl_gwIo2i, + gwIo4i = dnnl_gwIo4i, + OhwI32o = dnnl_OhwI32o, + OhwI32o2i = dnnl_OhwI32o2i, + OhwI32o4i = dnnl_OhwI32o4i, + Ohwi48o = dnnl_Ohwi48o, + OhwI48o2i = dnnl_OhwI48o2i, + OhwI48o4i = dnnl_OhwI48o4i, + Ohwi64o = dnnl_Ohwi64o, + OhwI64o2i = dnnl_OhwI64o2i, + OhwI64o4i = dnnl_OhwI64o4i, + Ihwo32i = dnnl_Ihwo32i, + IhwO32i2o = dnnl_IhwO32i2o, + IhwO32i4o = dnnl_IhwO32i4o, + Ihwo48i = dnnl_Ihwo48i, + IhwO48i2o = dnnl_IhwO48i2o, + IhwO48i4o = dnnl_IhwO48i4o, + Ihwo64i = dnnl_Ihwo64i, + IhwO64i2o = dnnl_IhwO64i2o, + IhwO64i4o = dnnl_IhwO64i4o, + hwIo2i = dnnl_hwIo2i, + hwIo4i = dnnl_hwIo4i, + gOhwI32o = dnnl_gOhwI32o, + gOhwI32o2i = dnnl_gOhwI32o2i, + gOhwI32o4i = dnnl_gOhwI32o4i, + gOhwi48o = dnnl_gOhwi48o, + gOhwI48o2i = dnnl_gOhwI48o2i, + gOhwI48o4i = dnnl_gOhwI48o4i, + gOhwi64o = dnnl_gOhwi64o, + gOhwI64o2i = dnnl_gOhwI64o2i, + gOhwI64o4i = dnnl_gOhwI64o4i, + gIhwo32i = dnnl_gIhwo32i, + gIhwO32i2o = dnnl_gIhwO32i2o, + gIhwO32i4o = dnnl_gIhwO32i4o, + gIhwo48i = dnnl_gIhwo48i, + gIhwO48i2o = dnnl_gIhwO48i2o, + gIhwO48i4o = dnnl_gIhwO48i4o, + gIhwo64i = dnnl_gIhwo64i, + gIhwO64i2o = dnnl_gIhwO64i2o, + gIhwO64i4o = dnnl_gIhwO64i4o, + ghwio = dnnl_ghwio, + ghwIo2i = dnnl_ghwIo2i, + ghwIo4i = dnnl_ghwIo4i, + Odhwi32o = dnnl_Odhwi32o, + OdhwI32o2i = dnnl_OdhwI32o2i, + OdhwI32o4i = dnnl_OdhwI32o4i, + Odhwi48o = dnnl_Odhwi48o, + OdhwI48o2i = dnnl_OdhwI48o2i, + OdhwI48o4i = dnnl_OdhwI48o4i, + Odhwi64o = dnnl_Odhwi64o, + OdhwI64o2i = dnnl_OdhwI64o2i, + OdhwI64o4i = dnnl_OdhwI64o4i, + Idhwo32i = dnnl_Idhwo32i, + IdhwO32i2o = dnnl_IdhwO32i2o, + IdhwO32i4o = dnnl_IdhwO32i4o, + Idhwo48i = dnnl_Idhwo48i, + IdhwO48i2o = dnnl_IdhwO48i2o, + IdhwO48i4o = dnnl_IdhwO48i4o, + Idhwo64i = dnnl_Idhwo64i, + IdhwO64i2o = dnnl_IdhwO64i2o, + IdhwO64i4o = dnnl_IdhwO64i4o, + dhwIo2i = dnnl_dhwIo2i, + dhwIo4i = dnnl_dhwIo4i, + gOdhwi32o = dnnl_gOdhwi32o, + gOdhwI32o2i = dnnl_gOdhwI32o2i, + gOdhwI32o4i = dnnl_gOdhwI32o4i, + gOdhwi48o = dnnl_gOdhwi48o, + gOdhwI48o2i = dnnl_gOdhwI48o2i, + gOdhwI48o4i = dnnl_gOdhwI48o4i, + gOdhwi64o = dnnl_gOdhwi64o, + gOdhwI64o2i = dnnl_gOdhwI64o2i, + gOdhwI64o4i = dnnl_gOdhwI64o4i, + gIdhwo32i = dnnl_gIdhwo32i, + gIdhwO32i2o = dnnl_gIdhwO32i2o, + gIdhwO32i4o = dnnl_gIdhwO32i4o, + gIdhwo48i = dnnl_gIdhwo48i, + gIdhwO48i2o = dnnl_gIdhwO48i2o, + gIdhwO48i4o = dnnl_gIdhwO48i4o, + gIdhwo64i = dnnl_gIdhwo64i, + gIdhwO64i2o = dnnl_gIdhwO64i2o, + gIdhwO64i4o = dnnl_gIdhwO64i4o, + gdhwio = dnnl_gdhwio, + gdhwIo2i = dnnl_gdhwIo2i, + gdhwIo4i = dnnl_gdhwIo4i, + ldIo32i = dnnl_ldIo32i, + ldgIo16i = dnnl_ldgIo16i, + ldgIo32i = dnnl_ldgIo32i, + ldgIO32i2o = dnnl_ldgIO32i2o, + nCdhw32c = dnnl_nCdhw32c, + nChw32c = dnnl_nChw32c, + nCw32c = dnnl_nCw32c, + NCw32n16c = dnnl_NCw32n16c, + NChw32n16c = dnnl_NChw32n16c, + NCdhw32n16c = dnnl_NCdhw32n16c, + NCw32n32c = dnnl_NCw32n32c, + OI16i16o4i = dnnl_OI16i16o4i, + IOw8o16i2o = dnnl_IOw8o16i2o, + IOhw8o16i2o = dnnl_IOhw8o16i2o, + Owhi16o = dnnl_Owhi16o, + OIdhw8o16i2o = dnnl_OIdhw8o16i2o, + IOdhw8o16i2o = dnnl_IOdhw8o16i2o, + Goiw4g = dnnl_Goiw4g, + gIOw8o16i2o = dnnl_gIOw8o16i2o, + Goiw32g = dnnl_Goiw32g, + Goihw4g = dnnl_Goihw4g, + gIOhw8o16i2o = dnnl_gIOhw8o16i2o, + Goihw32g = dnnl_Goihw32g, + gOwhi16o = dnnl_gOwhi16o, + IOw4i8o8i4o = dnnl_IOw4i8o8i4o, + IOhw4i8o8i4o = dnnl_IOhw4i8o8i4o, + IOdhw4i8o8i4o = dnnl_IOdhw4i8o8i4o, + gIOw4i8o8i4o = dnnl_gIOw4i8o8i4o, + gIOhw4i8o8i4o = dnnl_gIOhw4i8o8i4o, + gIOdhw4i8o8i4o = dnnl_gIOdhw4i8o8i4o, + gOIdhw8o16i2o = dnnl_gOIdhw8o16i2o, + gIOdhw8o16i2o = dnnl_gIOdhw8o16i2o, + Goidhw32g = dnnl_Goidhw32g, + OI16i32o4i = dnnl_OI16i32o4i, + OI16i48o4i = dnnl_OI16i48o4i, + OI16i64o4i = dnnl_OI16i64o4i, + OI16i16o2i = dnnl_OI16i16o2i, + OI16i32o2i = dnnl_OI16i32o2i, + OI16i48o2i = dnnl_OI16i48o2i, + OI16i64o2i = dnnl_OI16i64o2i, + aBdeC16c16b4c = dnnl_aBdeC16c16b4c, + AcB16b16a2b = dnnl_AcB16b16a2b, + aBdC16c16b2c = dnnl_aBdC16c16b2c, + AcB16b16a4b = dnnl_AcB16b16a4b, + aBdC16c16b4c = dnnl_aBdC16c16b4c, + AcdB16b16a2b = dnnl_AcdB16b16a2b, + aBdefC16c16b4c = dnnl_aBdefC16c16b4c, + AcdeB16b16a4b = dnnl_AcdeB16b16a4b, + AcB16b32a2b = dnnl_AcB16b32a2b, + AcB16b32a4b = dnnl_AcB16b32a4b, + AcB16b48a2b = dnnl_AcB16b48a2b, + AcB16b48a4b = dnnl_AcB16b48a4b, + AcB16b64a2b = dnnl_AcB16b64a2b, + AcB16b64a4b = dnnl_AcB16b64a4b, + aBdC16c32b2c = dnnl_aBdC16c32b2c, + aBdC16c32b4c = dnnl_aBdC16c32b4c, + aBdC16c48b2c = dnnl_aBdC16c48b2c, + aBdC16c48b4c = dnnl_aBdC16c48b4c, + aBdC16c64b2c = dnnl_aBdC16c64b2c, + aBdC16c64b4c = dnnl_aBdC16c64b4c, + AcdB16b32a2b = dnnl_AcdB16b32a2b, + AcdB16b32a4b = dnnl_AcdB16b32a4b, + AcdB16b48a2b = dnnl_AcdB16b48a2b, + AcdB16b48a4b = dnnl_AcdB16b48a4b, + AcdB16b64a2b = dnnl_AcdB16b64a2b, + AcdB16b64a4b = dnnl_AcdB16b64a4b, + aBdeC16c32b2c = dnnl_aBdeC16c32b2c, + aBdeC16c32b4c = dnnl_aBdeC16c32b4c, + aBdeC16c48b2c = dnnl_aBdeC16c48b2c, + aBdeC16c48b4c = dnnl_aBdeC16c48b4c, + aBdeC16c64b2c = dnnl_aBdeC16c64b2c, + aBdeC16c64b4c = dnnl_aBdeC16c64b4c, + AcdeB16b32a2b = dnnl_AcdeB16b32a2b, + AcdeB16b32a4b = dnnl_AcdeB16b32a4b, + AcdeB16b48a2b = dnnl_AcdeB16b48a2b, + AcdeB16b48a4b = dnnl_AcdeB16b48a4b, + AcdeB16b64a2b = dnnl_AcdeB16b64a2b, + AcdeB16b64a4b = dnnl_AcdeB16b64a4b, + aBdefC16c32b2c = dnnl_aBdefC16c32b2c, + aBdefC16c32b4c = dnnl_aBdefC16c32b4c, + aBdefC16c48b2c = dnnl_aBdefC16c48b2c, + aBdefC16c48b4c = dnnl_aBdefC16c48b4c, + aBdefC16c64b2c = dnnl_aBdefC16c64b2c, + aBdefC16c64b4c = dnnl_aBdefC16c64b4c, + OwI16i16o2i = dnnl_OwI16i16o2i, + gOwI16i16o2i = dnnl_gOwI16i16o2i, + OhwI16i16o2i = dnnl_OhwI16i16o2i, + gOhwI16i16o2i = dnnl_gOhwI16i16o2i, + OdhwI16i16o2i = dnnl_OdhwI16i16o2i, + gOdhwI16i16o2i = dnnl_gOdhwI16i16o2i, + OwI16i16o4i = dnnl_OwI16i16o4i, + gOwI16i16o4i = dnnl_gOwI16i16o4i, + OhwI16i16o4i = dnnl_OhwI16i16o4i, + gOhwI16i16o4i = dnnl_gOhwI16i16o4i, + OdhwI16i16o4i = dnnl_OdhwI16i16o4i, + gOdhwI16i16o4i = dnnl_gOdhwI16i16o4i, + OwI16i32o2i = dnnl_OwI16i32o2i, + OwI16i32o4i = dnnl_OwI16i32o4i, + OwI16i48o2i = dnnl_OwI16i48o2i, + OwI16i48o4i = dnnl_OwI16i48o4i, + OwI16i64o2i = dnnl_OwI16i64o2i, + OwI16i64o4i = dnnl_OwI16i64o4i, + gOwI16i32o2i = dnnl_gOwI16i32o2i, + gOwI16i32o4i = dnnl_gOwI16i32o4i, + gOwI16i48o2i = dnnl_gOwI16i48o2i, + gOwI16i48o4i = dnnl_gOwI16i48o4i, + gOwI16i64o2i = dnnl_gOwI16i64o2i, + gOwI16i64o4i = dnnl_gOwI16i64o4i, + OhwI16i32o2i = dnnl_OhwI16i32o2i, + OhwI16i32o4i = dnnl_OhwI16i32o4i, + OhwI16i48o2i = dnnl_OhwI16i48o2i, + OhwI16i48o4i = dnnl_OhwI16i48o4i, + OhwI16i64o2i = dnnl_OhwI16i64o2i, + OhwI16i64o4i = dnnl_OhwI16i64o4i, + gOhwI16i32o2i = dnnl_gOhwI16i32o2i, + gOhwI16i32o4i = dnnl_gOhwI16i32o4i, + gOhwI16i48o2i = dnnl_gOhwI16i48o2i, + gOhwI16i48o4i = dnnl_gOhwI16i48o4i, + gOhwI16i64o2i = dnnl_gOhwI16i64o2i, + gOhwI16i64o4i = dnnl_gOhwI16i64o4i, + OdhwI16i32o2i = dnnl_OdhwI16i32o2i, + OdhwI16i32o4i = dnnl_OdhwI16i32o4i, + OdhwI16i48o2i = dnnl_OdhwI16i48o2i, + OdhwI16i48o4i = dnnl_OdhwI16i48o4i, + OdhwI16i64o2i = dnnl_OdhwI16i64o2i, + OdhwI16i64o4i = dnnl_OdhwI16i64o4i, + IdhwO16o32i2o = dnnl_IdhwO16o32i2o, + IdhwO16o32i4o = dnnl_IdhwO16o32i4o, + IdhwO16o48i2o = dnnl_IdhwO16o48i2o, + IdhwO16o48i4o = dnnl_IdhwO16o48i4o, + IdhwO16o64i2o = dnnl_IdhwO16o64i2o, + IdhwO16o64i4o = dnnl_IdhwO16o64i4o, + gOdhwI16i32o2i = dnnl_gOdhwI16i32o2i, + gOdhwI16i32o4i = dnnl_gOdhwI16i32o4i, + gOdhwI16i48o2i = dnnl_gOdhwI16i48o2i, + gOdhwI16i48o4i = dnnl_gOdhwI16i48o4i, + gOdhwI16i64o2i = dnnl_gOdhwI16i64o2i, + gOdhwI16i64o4i = dnnl_gOdhwI16i64o4i, + gIdhwO16o32i2o = dnnl_gIdhwO16o32i2o, + gIdhwO16o32i4o = dnnl_gIdhwO16o32i4o, + gIdhwO16o48i2o = dnnl_gIdhwO16o48i2o, + gIdhwO16o48i4o = dnnl_gIdhwO16o48i4o, + gIdhwO16o64i2o = dnnl_gIdhwO16o64i2o, + gIdhwO16o64i4o = dnnl_gIdhwO16o64i4o, + IwO16o16i2o = dnnl_IwO16o16i2o, + IwO16o16i4o = dnnl_IwO16o16i4o, + IhwO16o16i2o = dnnl_IhwO16o16i2o, + IhwO16o16i4o = dnnl_IhwO16o16i4o, + IdhwO16o16i2o = dnnl_IdhwO16o16i2o, + IdhwO16o16i4o = dnnl_IdhwO16o16i4o, + gIwO16o16i2o = dnnl_gIwO16o16i2o, + gIwO16o16i4o = dnnl_gIwO16o16i4o, + gIhwO16o16i2o = dnnl_gIhwO16o16i2o, + gIhwO16o16i4o = dnnl_gIhwO16o16i4o, + gIdhwO16o16i2o = dnnl_gIdhwO16o16i2o, + gIdhwO16o16i4o = dnnl_gIdhwO16o16i4o, + IwO16o32i2o = dnnl_IwO16o32i2o, + IwO16o32i4o = dnnl_IwO16o32i4o, + IwO16o48i2o = dnnl_IwO16o48i2o, + IwO16o48i4o = dnnl_IwO16o48i4o, + IwO16o64i2o = dnnl_IwO16o64i2o, + IwO16o64i4o = dnnl_IwO16o64i4o, + gIwO16o32i2o = dnnl_gIwO16o32i2o, + gIwO16o32i4o = dnnl_gIwO16o32i4o, + gIwO16o48i2o = dnnl_gIwO16o48i2o, + gIwO16o48i4o = dnnl_gIwO16o48i4o, + gIwO16o64i2o = dnnl_gIwO16o64i2o, + gIwO16o64i4o = dnnl_gIwO16o64i4o, + IhwO16o32i2o = dnnl_IhwO16o32i2o, + IhwO16o32i4o = dnnl_IhwO16o32i4o, + IhwO16o48i2o = dnnl_IhwO16o48i2o, + IhwO16o48i4o = dnnl_IhwO16o48i4o, + IhwO16o64i2o = dnnl_IhwO16o64i2o, + IhwO16o64i4o = dnnl_IhwO16o64i4o, + gIhwO16o32i2o = dnnl_gIhwO16o32i2o, + gIhwO16o32i4o = dnnl_gIhwO16o32i4o, + gIhwO16o48i2o = dnnl_gIhwO16o48i2o, + gIhwO16o48i4o = dnnl_gIhwO16o48i4o, + gIhwO16o64i2o = dnnl_gIhwO16o64i2o, + gIhwO16o64i4o = dnnl_gIhwO16o64i4o, + aBdeC16c16b2c = dnnl_aBdeC16c16b2c, + aBdefC16c16b2c = dnnl_aBdefC16c16b2c, + AcdB16b16a4b = dnnl_AcdB16b16a4b, + AcdeB16b16a2b = dnnl_AcdeB16b16a2b, + hwioG16g = dnnl_hwioG16g, + hwioG8g = dnnl_hwioG8g, + dhwioG16g = dnnl_dhwioG16g, + dhwioG8g = dnnl_dhwioG8g, + ABc4a2b = dnnl_ABc4a2b, + ABc8a2b = dnnl_ABc8a2b, + ABcd4a2b = dnnl_ABcd4a2b, + ABcde4a2b = dnnl_ABcde4a2b, + ABcde8a2b = dnnl_ABcde8a2b, + ABcd4a8b8a2b = dnnl_ABcd4a8b8a2b, + NCdhw40n32c = dnnl_NCdhw40n32c, + NChw40n32c = dnnl_NChw40n32c, + NCw40n32c = dnnl_NCw40n32c, + OIdhw4o8i8o2i = dnnl_OIdhw4o8i8o2i, + OIhw4o8i8o2i = dnnl_OIhw4o8i8o2i, + OIw4o8i8o2i = dnnl_OIw4o8i8o2i, + gOIdhw4o8i8o2i = dnnl_gOIdhw4o8i8o2i, + gOIhw4o8i8o2i = dnnl_gOIhw4o8i8o2i, + gOIw4o8i8o2i = dnnl_gOIw4o8i8o2i, + IOdhw4i8o8i2o = dnnl_IOdhw4i8o8i2o, + IOhw4i8o8i2o = dnnl_IOhw4i8o8i2o, + IOw4i8o8i2o = dnnl_IOw4i8o8i2o, + gIOdhw4i8o8i2o = dnnl_gIOdhw4i8o8i2o, + gIOhw4i8o8i2o = dnnl_gIOhw4i8o8i2o, + gIOw4i8o8i2o = dnnl_gIOw4i8o8i2o, + aBCd8b2c = dnnl_aBCd8b2c, + ABcde40a16b = dnnl_ABcde40a16b, + ABcde40a32b = dnnl_ABcde40a32b, + aBCde8b2c = dnnl_aBCde8b2c, + ABcde4a8b8a2b = dnnl_ABcde4a8b8a2b, + ABc4a8b8a2b = dnnl_ABc4a8b8a2b, + aBCdef4b8c8b2c = dnnl_aBCdef4b8c8b2c, + aBCde4b8c8b2c = dnnl_aBCde4b8c8b2c, + aBCd4b8c8b2c = dnnl_aBCd4b8c8b2c, + BAcde4b8a8b2a = dnnl_BAcde4b8a8b2a, + BAcd4b8a8b2a = dnnl_BAcd4b8a8b2a, + BAc4b8a8b2a = dnnl_BAc4b8a8b2a, + aCBdef4c8b8c2b = dnnl_aCBdef4c8b8c2b, + aCBde4c8b8c2b = dnnl_aCBde4c8b8c2b, + aCBd4c8b8c2b = dnnl_aCBd4c8b8c2b, + aBCdef8b2c = dnnl_aBCdef8b2c, + AB32a16b = dnnl_AB32a16b, + AB32a32b = dnnl_AB32a32b, + BA4b8a8b2a = dnnl_BA4b8a8b2a, + BA4b8a8b4a = dnnl_BA4b8a8b4a, + aBC32b16c = dnnl_aBC32b16c, + aBC32b32c = dnnl_aBC32b32c, + aCB4c8b8c2b = dnnl_aCB4c8b8c2b, + aCB4c8b8c4b = dnnl_aCB4c8b8c4b, + ABc2b8a16b4a = dnnl_ABc2b8a16b4a, + ABcd2b8a16b4a = dnnl_ABcd2b8a16b4a, + ABcde2b8a16b4a = dnnl_ABcde2b8a16b4a, + ABc2a8b16a4b = dnnl_ABc2a8b16a4b, + ABc2a8b16a2b = dnnl_ABc2a8b16a2b, + ABc2b32a8b = dnnl_ABc2b32a8b, + ABcd2a8b16a4b = dnnl_ABcd2a8b16a4b, + ABcd2a8b16a2b = dnnl_ABcd2a8b16a2b, + aCBd2c8b16c2b = dnnl_aCBd2c8b16c2b, + ABcd2b32a8b = dnnl_ABcd2b32a8b, + aBCd2c8b16c2b = dnnl_aBCd2c8b16c2b, + ABcde2a8b16a4b = dnnl_ABcde2a8b16a4b, + ABcde2a8b16a2b = dnnl_ABcde2a8b16a2b, + aCBde2c8b16c2b = dnnl_aCBde2c8b16c2b, + ABcde2b32a8b = dnnl_ABcde2b32a8b, + aBC2b8c16b2c = dnnl_aBC2b8c16b2c, + aBCd2b8c16b2c = dnnl_aBCd2b8c16b2c, + aBCde2b8c16b2c = dnnl_aBCde2b8c16b2c, + aBCdef2b8c16b2c = dnnl_aBCdef2b8c16b2c, + BAcde2b8a16b4a = dnnl_BAcde2b8a16b4a, + BAcd2b8a16b4a = dnnl_BAcd2b8a16b4a, + BAc2b8a16b4a = dnnl_BAc2b8a16b4a, + BAcde2b8a16b2a = dnnl_BAcde2b8a16b2a, + BAcd2b8a16b2a = dnnl_BAcd2b8a16b2a, + BAc2b8a16b2a = dnnl_BAc2b8a16b2a, + aBCde2c8b16c2b = dnnl_aBCde2c8b16c2b, + aBCdef2c8b16c2b = dnnl_aBCdef2c8b16c2b, + aCBdef2c8b16c2b = dnnl_aCBdef2c8b16c2b, + aBCd2b8c16b4c = dnnl_aBCd2b8c16b4c, + aBCde2b8c16b4c = dnnl_aBCde2b8c16b4c, + NCdhw40n16c = dnnl_NCdhw40n16c, + NCw40n16c = dnnl_NCw40n16c, + NChw40n16c = dnnl_NChw40n16c, + NCw2c32n8c = dnnl_NCw2c32n8c, + NChw2c32n8c = dnnl_NChw2c32n8c, + NCdhw2c32n8c = dnnl_NCdhw2c32n8c, + OIw2i8o16i4o = dnnl_OIw2i8o16i4o, + OIhw2i8o16i4o = dnnl_OIhw2i8o16i4o, + OIdhw2i8o16i4o = dnnl_OIdhw2i8o16i4o, + OIw2o8i16o4i = dnnl_OIw2o8i16o4i, + OIw2o8i16o2i = dnnl_OIw2o8i16o2i, + IOw2i8o16i4o = dnnl_IOw2i8o16i4o, + IOw2i8o16i2o = dnnl_IOw2i8o16i2o, + OIhw2o8i16o4i = dnnl_OIhw2o8i16o4i, + OIhw2o8i16o2i = dnnl_OIhw2o8i16o2i, + IOhw2i8o16i4o = dnnl_IOhw2i8o16i4o, + IOhw2i8o16i2o = dnnl_IOhw2i8o16i2o, + OIdhw2o8i16o4i = dnnl_OIdhw2o8i16o4i, + OIdhw2o8i16o2i = dnnl_OIdhw2o8i16o2i, + IOdhw2i8o16i4o = dnnl_IOdhw2i8o16i4o, + IOdhw2i8o16i2o = dnnl_IOdhw2i8o16i2o, + gOIw2o8i16o2i = dnnl_gOIw2o8i16o2i, + gIOw2i8o16i2o = dnnl_gIOw2i8o16i2o, + gIOhw2i8o16i2o = dnnl_gIOhw2i8o16i2o, + gIOdhw2i8o16i2o = dnnl_gIOdhw2i8o16i2o, + gOIhw2o8i16o2i = dnnl_gOIhw2o8i16o2i, + gOIdhw2o8i16o2i = dnnl_gOIdhw2o8i16o2i, + gOIw2o8i16o4i = dnnl_gOIw2o8i16o4i, + gOIhw2o8i16o4i = dnnl_gOIhw2o8i16o4i, + BA4b8a16b2a = dnnl_BA4b8a16b2a, + BA4b8a16b4a = dnnl_BA4b8a16b4a, + aCB4c8b16c2b = dnnl_aCB4c8b16c2b, + aCB4c8b16c4b = dnnl_aCB4c8b16c4b, + aCB16c2b = dnnl_aCB16c2b, + aCB16c4b = dnnl_aCB16c4b, + BA16b2a = dnnl_BA16b2a, + BA16b4a = dnnl_BA16b4a, + BA4b4a = dnnl_BA4b4a, + BA8b4a = dnnl_BA8b4a, + aBC16b16c = dnnl_aBC16b16c, + aBC16b32c = dnnl_aBC16b32c, + AB16a16b = dnnl_AB16a16b, + AB16a32b = dnnl_AB16a32b, + ABcde16a16b2a = dnnl_ABcde16a16b2a, + aBCdef16b16c2b = dnnl_aBCdef16b16c2b, + Acedb16a = dnnl_Acedb16a, + aBdfec16b = dnnl_aBdfec16b, + Odwhi16o = dnnl_Odwhi16o, + gOdwhi16o = dnnl_gOdwhi16o, + abdEC64e2c = dnnl_abdEC64e2c, + abdEC64e4c = dnnl_abdEC64e4c, + ldgOI64o2i = abdEC64e2c, + ldgOI64o4i = abdEC64e4c, + abCd4c = dnnl_abCd4c, + abCde4c = dnnl_abCde4c, + abCdef4c = dnnl_abCdef4c, + abCde32c = dnnl_abCde32c, + abCdef32c = dnnl_abCdef32c, + aCdefB16b32c2b = dnnl_aCdefB16b32c2b, + aCdefB16b32c4b = dnnl_aCdefB16b32c4b, + aCdefB16b48c2b = dnnl_aCdefB16b48c2b, + aCdefB16b48c4b = dnnl_aCdefB16b48c4b, + aCdefB16b64c2b = dnnl_aCdefB16b64c2b, + aCdefB16b64c4b = dnnl_aCdefB16b64c4b, + BcdeA16a32b2a = dnnl_BcdeA16a32b2a, + BcdeA16a32b4a = dnnl_BcdeA16a32b4a, + BcdeA16a48b2a = dnnl_BcdeA16a48b2a, + BcdeA16a48b4a = dnnl_BcdeA16a48b4a, + BcdeA16a64b2a = dnnl_BcdeA16a64b2a, + BcdeA16a64b4a = dnnl_BcdeA16a64b4a, + aCdefb32c = dnnl_aCdefb32c, + aCdefB32c2b = dnnl_aCdefB32c2b, + aCdefB32c4b = dnnl_aCdefB32c4b, + aCdefb48c = dnnl_aCdefb48c, + aCdefB48c2b = dnnl_aCdefB48c2b, + aCdefB48c4b = dnnl_aCdefB48c4b, + aCdefb64c = dnnl_aCdefb64c, + aCdefB64c2b = dnnl_aCdefB64c2b, + aCdefB64c4b = dnnl_aCdefB64c4b, + Bcdea32b = dnnl_Bcdea32b, + BcdeA32b2a = dnnl_BcdeA32b2a, + BcdeA32b4a = dnnl_BcdeA32b4a, + Bcdea48b = dnnl_Bcdea48b, + BcdeA48b2a = dnnl_BcdeA48b2a, + BcdeA48b4a = dnnl_BcdeA48b4a, + Bcdea64b = dnnl_Bcdea64b, + BcdeA64b2a = dnnl_BcdeA64b2a, + BcdeA64b4a = dnnl_BcdeA64b4a, + Bca32b = dnnl_Bca32b, + BcA32b2a = dnnl_BcA32b2a, + BcA32b4a = dnnl_BcA32b4a, + Bca48b = dnnl_Bca48b, + BcA48b2a = dnnl_BcA48b2a, + BcA48b4a = dnnl_BcA48b4a, + Bca64b = dnnl_Bca64b, + BcA64b2a = dnnl_BcA64b2a, + BcA64b4a = dnnl_BcA64b4a, + aCdb32c = dnnl_aCdb32c, + aCdB32c2b = dnnl_aCdB32c2b, + aCdB32c4b = dnnl_aCdB32c4b, + aCdb48c = dnnl_aCdb48c, + aCdB48c2b = dnnl_aCdB48c2b, + aCdB48c4b = dnnl_aCdB48c4b, + aCdb64c = dnnl_aCdb64c, + aCdB64c2b = dnnl_aCdB64c2b, + aCdB64c4b = dnnl_aCdB64c4b, + BcA16a16b2a = dnnl_BcA16a16b2a, + BcA16a16b4a = dnnl_BcA16a16b4a, + BcdA16a16b2a = dnnl_BcdA16a16b2a, + BcdA16a16b4a = dnnl_BcdA16a16b4a, + BcdeA16a16b2a = dnnl_BcdeA16a16b2a, + BcdeA16a16b4a = dnnl_BcdeA16a16b4a, + aCdB16b16c2b = dnnl_aCdB16b16c2b, + aCdB16b16c4b = dnnl_aCdB16b16c4b, + aCdeB16b16c2b = dnnl_aCdeB16b16c2b, + aCdeB16b16c4b = dnnl_aCdeB16b16c4b, + aCdefB16b16c2b = dnnl_aCdefB16b16c2b, + aCdefB16b16c4b = dnnl_aCdefB16b16c4b, + BcA16a32b2a = dnnl_BcA16a32b2a, + BcA16a32b4a = dnnl_BcA16a32b4a, + BcA16a48b2a = dnnl_BcA16a48b2a, + BcA16a48b4a = dnnl_BcA16a48b4a, + BcA16a64b2a = dnnl_BcA16a64b2a, + BcA16a64b4a = dnnl_BcA16a64b4a, + aCdB16b32c2b = dnnl_aCdB16b32c2b, + aCdB16b32c4b = dnnl_aCdB16b32c4b, + aCdB16b48c2b = dnnl_aCdB16b48c2b, + aCdB16b48c4b = dnnl_aCdB16b48c4b, + aCdB16b64c2b = dnnl_aCdB16b64c2b, + aCdB16b64c4b = dnnl_aCdB16b64c4b, + BcdA16a32b2a = dnnl_BcdA16a32b2a, + BcdA16a32b4a = dnnl_BcdA16a32b4a, + BcdA16a48b2a = dnnl_BcdA16a48b2a, + BcdA16a48b4a = dnnl_BcdA16a48b4a, + BcdA16a64b2a = dnnl_BcdA16a64b2a, + BcdA16a64b4a = dnnl_BcdA16a64b4a, + aCdeB16b32c2b = dnnl_aCdeB16b32c2b, + aCdeB16b32c4b = dnnl_aCdeB16b32c4b, + aCdeB16b48c2b = dnnl_aCdeB16b48c2b, + aCdeB16b48c4b = dnnl_aCdeB16b48c4b, + aCdeB16b64c2b = dnnl_aCdeB16b64c2b, + aCdeB16b64c4b = dnnl_aCdeB16b64c4b, + Bca16b = dnnl_Bca16b, + BcA16b2a = dnnl_BcA16b2a, + BcA16b4a = dnnl_BcA16b4a, + Bcda16b = dnnl_Bcda16b, + BcdA16b2a = dnnl_BcdA16b2a, + BcdA16b4a = dnnl_BcdA16b4a, + Bcdea16b = dnnl_Bcdea16b, + BcdeA16b2a = dnnl_BcdeA16b2a, + BcdeA16b4a = dnnl_BcdeA16b4a, + aCdb16c = dnnl_aCdb16c, + aCdB16c2b = dnnl_aCdB16c2b, + aCdB16c4b = dnnl_aCdB16c4b, + aCdeb16c = dnnl_aCdeb16c, + aCdeB16c2b = dnnl_aCdeB16c2b, + aCdeB16c4b = dnnl_aCdeB16c4b, + aCdefb16c = dnnl_aCdefb16c, + aCdefB16c2b = dnnl_aCdefB16c2b, + aCdefB16c4b = dnnl_aCdefB16c4b, + Bcda32b = dnnl_Bcda32b, + BcdA32b2a = dnnl_BcdA32b2a, + BcdA32b4a = dnnl_BcdA32b4a, + Bcda48b = dnnl_Bcda48b, + BcdA48b2a = dnnl_BcdA48b2a, + BcdA48b4a = dnnl_BcdA48b4a, + Bcda64b = dnnl_Bcda64b, + BcdA64b2a = dnnl_BcdA64b2a, + BcdA64b4a = dnnl_BcdA64b4a, + aCdeb32c = dnnl_aCdeb32c, + aCdeB32c2b = dnnl_aCdeB32c2b, + aCdeB32c4b = dnnl_aCdeB32c4b, + aCdeb48c = dnnl_aCdeb48c, + aCdeB48c2b = dnnl_aCdeB48c2b, + aCdeB48c4b = dnnl_aCdeB48c4b, + aCdeb64c = dnnl_aCdeb64c, + aCdeB64c2b = dnnl_aCdeB64c2b, + aCdeB64c4b = dnnl_aCdeB64c4b, + NChw16n32c = dnnl_NChw16n32c, + goIw4i = dnnl_goIw4i, + goIw32i = dnnl_goIw32i, + goIhw4i = dnnl_goIhw4i, + goIhw32i = dnnl_goIhw32i, + goIdhw4i = dnnl_goIdhw4i, + goIdhw32i = dnnl_goIdhw32i, + cab = dnnl_cab, + cdab = dnnl_cdab, + cdeab = dnnl_cdeab, + woi = dnnl_woi, + hwoi = dnnl_hwoi, + dhwoi = dnnl_dhwoi, + Owi24o = dnnl_Owi24o, + Ohwi24o = dnnl_Ohwi24o, + Odhwi24o = dnnl_Odhwi24o, + gOwi24o = dnnl_gOwi24o, + gOhwi24o = dnnl_gOhwi24o, + gOdhwi24o = dnnl_gOdhwi24o, + OwI24o2i = dnnl_OwI24o2i, + OhwI24o2i = dnnl_OhwI24o2i, + OdhwI24o2i = dnnl_OdhwI24o2i, + gOwI24o2i = dnnl_gOwI24o2i, + gOhwI24o2i = dnnl_gOhwI24o2i, + gOdhwI24o2i = dnnl_gOdhwI24o2i, + OwI24o4i = dnnl_OwI24o4i, + OhwI24o4i = dnnl_OhwI24o4i, + OdhwI24o4i = dnnl_OdhwI24o4i, + gOwI24o4i = dnnl_gOwI24o4i, + gOhwI24o4i = dnnl_gOhwI24o4i, + gOdhwI24o4i = dnnl_gOdhwI24o4i, + OI8i32o = dnnl_OI8i32o, + OIw8i32o = dnnl_OIw8i32o, + OwI8i32o = dnnl_OwI8i32o, + OIhw8i32o = dnnl_OIhw8i32o, + OhwI8i32o = dnnl_OhwI8i32o, + OIdhw8i32o = dnnl_OIdhw8i32o, + OdhwI8i32o = dnnl_OdhwI8i32o, + OI8i24o = dnnl_OI8i24o, + OIw8i24o = dnnl_OIw8i24o, + OwI8i24o = dnnl_OwI8i24o, + OIhw8i24o = dnnl_OIhw8i24o, + OhwI8i24o = dnnl_OhwI8i24o, + OIdhw8i24o = dnnl_OIdhw8i24o, + OdhwI8i24o = dnnl_OdhwI8i24o, + OI8i16o = dnnl_OI8i16o, + OIw8i16o = dnnl_OIw8i16o, + OwI8i16o = dnnl_OwI8i16o, + OIhw8i16o = dnnl_OIhw8i16o, + OhwI8i16o = dnnl_OhwI8i16o, + OIdhw8i16o = dnnl_OIdhw8i16o, + OdhwI8i16o = dnnl_OdhwI8i16o, + OI8i8o = dnnl_OI8i8o, + AB4b8a4b = dnnl_AB4b8a4b, + AB4b24a4b = dnnl_AB4b24a4b, + ABc4b8a4b = dnnl_ABc4b8a4b, + AcB4b8a4b = dnnl_AcB4b8a4b, + ABc4b24a4b = dnnl_ABc4b24a4b, + AcB4b24a4b = dnnl_AcB4b24a4b, + ABcd4b8a4b = dnnl_ABcd4b8a4b, + AcdB4b8a4b = dnnl_AcdB4b8a4b, + ABcd4b24a4b = dnnl_ABcd4b24a4b, + AcdB4b24a4b = dnnl_AcdB4b24a4b, + ABcde4b8a4b = dnnl_ABcde4b8a4b, + AcdeB4b8a4b = dnnl_AcdeB4b8a4b, + ABcde4b24a4b = dnnl_ABcde4b24a4b, + AcdeB4b24a4b = dnnl_AcdeB4b24a4b, + Bca8b = dnnl_Bca8b, + BcA8b2a = dnnl_BcA8b2a, + Bcda8b = dnnl_Bcda8b, + BcdA8b2a = dnnl_BcdA8b2a, + Bcdea8b = dnnl_Bcdea8b, + BcdeA8b2a = dnnl_BcdeA8b2a, + aCdb8c = dnnl_aCdb8c, + aCdB8c2b = dnnl_aCdB8c2b, + aCdeb8c = dnnl_aCdeb8c, + aCdeB8c2b = dnnl_aCdeB8c2b, + aCdefb8c = dnnl_aCdefb8c, + aCdefB8c2b = dnnl_aCdefB8c2b, + Bca24b = dnnl_Bca24b, + BcA24b2a = dnnl_BcA24b2a, + Bcda24b = dnnl_Bcda24b, + BcdA24b2a = dnnl_BcdA24b2a, + Bcdea24b = dnnl_Bcdea24b, + BcdeA24b2a = dnnl_BcdeA24b2a, + aCdb24c = dnnl_aCdb24c, + aCdB24c2b = dnnl_aCdB24c2b, + aCdeb24c = dnnl_aCdeb24c, + aCdeB24c2b = dnnl_aCdeB24c2b, + aCdefb24c = dnnl_aCdefb24c, + aCdefB24c2b = dnnl_aCdefB24c2b, + Iwo8i = dnnl_Iwo8i, + IwO8i2o = dnnl_IwO8i2o, + Iwo24i = dnnl_Iwo24i, + IwO24i2o = dnnl_IwO24i2o, + Ihwo8i = dnnl_Ihwo8i, + IhwO8i2o = dnnl_IhwO8i2o, + Ihwo24i = dnnl_Ihwo24i, + IhwO24i2o = dnnl_IhwO24i2o, + Idhwo8i = dnnl_Idhwo8i, + IdhwO8i2o = dnnl_IdhwO8i2o, + Idhwo24i = dnnl_Idhwo24i, + IdhwO24i2o = dnnl_IdhwO24i2o, + gIwo8i = dnnl_gIwo8i, + gIwO8i2o = dnnl_gIwO8i2o, + gIwo24i = dnnl_gIwo24i, + gIwO24i2o = dnnl_gIwO24i2o, + gIhwo8i = dnnl_gIhwo8i, + gIhwO8i2o = dnnl_gIhwO8i2o, + gIhwo24i = dnnl_gIhwo24i, + gIhwO24i2o = dnnl_gIhwO24i2o, + gIdhwo8i = dnnl_gIdhwo8i, + gIdhwO8i2o = dnnl_gIdhwO8i2o, + gIdhwo24i = dnnl_gIdhwo24i, + gIdhwO24i2o = dnnl_gIdhwO24i2o, + OhwI24o = dnnl_OhwI24o, + gOhwI24o = dnnl_gOhwI24o, + AB8b24a2b = dnnl_AB8b24a2b, + ABc8b24a2b = dnnl_ABc8b24a2b, + AcB8b24a2b = dnnl_AcB8b24a2b, + ABcd8b24a2b = dnnl_ABcd8b24a2b, + AcdB8b24a2b = dnnl_AcdB8b24a2b, + ABcde8b24a2b = dnnl_ABcde8b24a2b, + AcdeB8b24a2b = dnnl_AcdeB8b24a2b, + AB8b8a2b = dnnl_AB8b8a2b, + ABc8b8a2b = dnnl_ABc8b8a2b, + AcB8b8a2b = dnnl_AcB8b8a2b, + ABcd8b8a2b = dnnl_ABcd8b8a2b, + AcdB8b8a2b = dnnl_AcdB8b8a2b, + ABcde8b8a2b = dnnl_ABcde8b8a2b, + AcdeB8b8a2b = dnnl_AcdeB8b8a2b, + OI8i8o2i = dnnl_OI8i8o2i, + OI8i24o2i = dnnl_OI8i24o2i, + OIw8i8o2i = dnnl_OIw8i8o2i, + OwI8i8o2i = dnnl_OwI8i8o2i, + OIw8i24o2i = dnnl_OIw8i24o2i, + OwI8i24o2i = dnnl_OwI8i24o2i, + OIhw8i8o2i = dnnl_OIhw8i8o2i, + OhwI8i8o2i = dnnl_OhwI8i8o2i, + OIhw8i24o2i = dnnl_OIhw8i24o2i, + OhwI8i24o2i = dnnl_OhwI8i24o2i, + OIdhw8i8o2i = dnnl_OIdhw8i8o2i, + OdhwI8i8o2i = dnnl_OdhwI8i8o2i, + OIdhw8i24o2i = dnnl_OIdhw8i24o2i, + OdhwI8i24o2i = dnnl_OdhwI8i24o2i, + BcA8b4a = dnnl_BcA8b4a, + BcdA8b4a = dnnl_BcdA8b4a, + BcdeA8b4a = dnnl_BcdeA8b4a, + aCdB8c4b = dnnl_aCdB8c4b, + aCdeB8c4b = dnnl_aCdeB8c4b, + aCdefB8c4b = dnnl_aCdefB8c4b, + BcA24b4a = dnnl_BcA24b4a, + BcdA24b4a = dnnl_BcdA24b4a, + BcdeA24b4a = dnnl_BcdeA24b4a, + aCdB24c4b = dnnl_aCdB24c4b, + aCdeB24c4b = dnnl_aCdeB24c4b, + aCdefB24c4b = dnnl_aCdefB24c4b, + ABc16a4b = dnnl_ABc16a4b, + ABcd16a4b = dnnl_ABcd16a4b, + ABcde16a4b = dnnl_ABcde16a4b, + IwO8i4o = dnnl_IwO8i4o, + IwO24i4o = dnnl_IwO24i4o, + IhwO8i4o = dnnl_IhwO8i4o, + IhwO24i4o = dnnl_IhwO24i4o, + IdhwO8i4o = dnnl_IdhwO8i4o, + IdhwO24i4o = dnnl_IdhwO24i4o, + gIwO8i4o = dnnl_gIwO8i4o, + gIwO24i4o = dnnl_gIwO24i4o, + gIhwO8i4o = dnnl_gIhwO8i4o, + gIhwO24i4o = dnnl_gIhwO24i4o, + gIdhwO8i4o = dnnl_gIdhwO8i4o, + gIdhwO24i4o = dnnl_gIdhwO24i4o, + BA2a24b = dnnl_BA2a24b, + aCB2b24c = dnnl_aCB2b24c, + BA2a8b = dnnl_BA2a8b, + aCB2b8c = dnnl_aCB2b8c, + BA8a24b = dnnl_BA8a24b, + aCB8b24c = dnnl_aCB8b24c, + BA8a16b = dnnl_BA8a16b, + aCB8b16c = dnnl_aCB8b16c, + BA8a8b = dnnl_BA8a8b, + aCB8b8c = dnnl_aCB8b8c, + bcad = dnnl_bcad, + cabd = dnnl_cabd, + dabc = dnnl_dabc, + decbA4a = dnnl_decbA4a, + defcbA4a = dnnl_defcbA4a, + hwioG4g = dnnl_hwioG4g, + dhwioG4g = dnnl_dhwioG4g, + aCBd4b4c = dnnl_aCBd4b4c, + aCBde4b4c = dnnl_aCBde4b4c, + aCBdef4b4c = dnnl_aCBdef4b4c, + BAc4a4b = dnnl_BAc4a4b, + BAcd4a4b = dnnl_BAcd4a4b, + BAcde4a4b = dnnl_BAcde4a4b, + IOw4o4i = dnnl_IOw4o4i, + IOhw4o4i = dnnl_IOhw4o4i, + IOdhw4o4i = dnnl_IOdhw4o4i, + gIOw4o4i = dnnl_gIOw4o4i, + gIOhw4o4i = dnnl_gIOhw4o4i, + gIOdhw4o4i = dnnl_gIOdhw4o4i, + }; + + /// A memory descriptor. + struct desc : public handle { + using handle::handle; + + friend struct memory; + + /// Constructs a zero (empty) memory descriptor. Such a memory + /// descriptor can be used to indicate absence of an argument. + desc() { + dnnl_memory_desc_t zero_md = nullptr; + error::wrap_c_api( + dnnl_memory_desc_create_with_tag(&zero_md, 0, nullptr, + dnnl_data_type_undef, dnnl_format_tag_undef), + "could not create a zero memory descriptor"); + reset(zero_md); + } + + /// Constructs a memory descriptor. + /// + /// @note + /// The logical order of dimensions corresponds to the `abc...` + /// format tag, and the physical meaning of the dimensions depends + /// both on the primitive that would operate on this memory and + /// the operation context. + /// + /// @param adims Tensor dimensions. + /// @param adata_type Data precision/type. + /// @param aformat_tag Memory format tag. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case a + /// zero memory descriptor will be constructed. This flag is + /// optional and defaults to false. + desc(const dims &adims, data_type adata_type, format_tag aformat_tag, + bool allow_empty = false) { + validate_dims(adims); + dnnl_memory_desc_t md = nullptr; + dnnl_status_t status = dnnl_memory_desc_create_with_tag(&md, + (int)adims.size(), adims.data(), convert_to_c(adata_type), + convert_to_c(aformat_tag)); + if (!allow_empty) + error::wrap_c_api(status, + "could not construct a memory descriptor using a " + "format tag"); + reset(md); + } + + /// Constructs a memory descriptor by strides. + /// + /// @note + /// The logical order of dimensions corresponds to the `abc...` + /// format tag, and the physical meaning of the dimensions depends + /// both on the primitive that would operate on this memory and + /// the operation context. + /// + /// @param adims Tensor dimensions. + /// @param adata_type Data precision/type. + /// @param strides Strides for each dimension. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case a + /// zero memory descriptor will be constructed. This flag is + /// optional and defaults to false. + desc(const dims &adims, data_type adata_type, const dims &strides, + bool allow_empty = false) { + validate_dims(adims); + if (!strides.empty()) validate_dims(strides, (int)adims.size()); + dnnl_memory_desc_t md = nullptr; + dnnl_status_t status = dnnl_memory_desc_create_with_strides(&md, + (int)adims.size(), adims.data(), convert_to_c(adata_type), + strides.empty() ? nullptr : &strides[0]); + if (!allow_empty) + error::wrap_c_api(status, + "could not construct a memory descriptor using " + "strides"); + reset(md); + } + + /// Function for creating a memory descriptor for CSR sparse encoding. + /// + /// The created memory descriptor will describe a memory object that + /// contains 3 buffers. The buffers have the following meaning and + /// assigned numbers (index): + /// - 0: values + /// - 1: indices + /// - 2: pointers + /// + /// @param adims Tensor dimensions. + /// @param adata_type Data precision/type. + /// @param nnz Number of non-zero entries. + /// @param index_dt Data type of indices. + /// @param pointer_dt Data type of pointers. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case a + /// zero memory descriptor will be constructed. This flag is + /// optional and defaults to false. + /// @sa @ref dev_guide_sparsity + static desc csr(const dims &adims, data_type adata_type, dim nnz, + data_type index_dt, data_type pointer_dt, + bool allow_empty = false) { + validate_dims(adims); + dnnl_memory_desc_t md = nullptr; + dnnl_status_t status = dnnl_memory_desc_create_with_csr_encoding( + &md, (int)adims.size(), adims.data(), + convert_to_c(adata_type), nnz, convert_to_c(index_dt), + convert_to_c(pointer_dt)); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a memory descriptor for CSR sparse " + "encoding"); + return desc {md}; + } + + /// Function for creating a memory descriptor for COO sparse encodings. + /// + /// The created memory descriptor will describe a memory object that + /// contains n+1 buffers for an n-dimensional tensor. + /// The buffers have the following meaning and assigned numbers (index): + /// - 0: values + /// - 1: indices for dimension 0 + /// - 2: indices for dimension 1 ... + /// - n: indices for dimension n-1 + /// + /// @param adims Tensor dimensions. + /// @param adata_type Data precision/type. + /// @param nnz Number of non-zero entries. + /// @param index_dt Data type of indices. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case a + /// zero memory descriptor will be constructed. This flag is + /// optional and defaults to false. + /// @sa @ref dev_guide_sparsity + static desc coo(const dims &adims, data_type adata_type, dim nnz, + data_type index_dt, bool allow_empty = false) { + validate_dims(adims); + dnnl_memory_desc_t md = nullptr; + dnnl_status_t status = dnnl_memory_desc_create_with_coo_encoding( + &md, (int)adims.size(), adims.data(), + convert_to_c(adata_type), nnz, convert_to_c(index_dt)); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a memory descriptor for COO sparse " + "encoding"); + return desc {md}; + } + + /// Function for creating a memory descriptor for packed sparse + /// encoding. + /// + /// The created memory descriptor cannot be used to create a memory + /// object. It can only be used to create a primitive descriptor to + /// query the actual memory descriptor (similar to the format tag + /// `any`). + /// + /// @warning + /// The meaning and content of the handles of the memory object that + /// is created using the queried memory descriptor are unspecified + /// therefore using the content is an undefined behavior. + /// + /// @param adims Tensor dimensions. + /// @param adata_type Data precision/type. + /// @param nnz Number of non-zero entries. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case a + /// zero memory descriptor will be constructed. This flag is + /// optional and defaults to false. + /// @sa @ref dev_guide_sparsity + static desc packed(const dims &adims, data_type adata_type, dim nnz, + bool allow_empty = false) { + validate_dims(adims); + dnnl_memory_desc_t md = nullptr; + dnnl_status_t status = dnnl_memory_desc_create_with_packed_encoding( + &md, (int)adims.size(), adims.data(), + convert_to_c(adata_type), nnz); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a memory descriptor for packed " + "sparse encoding"); + return desc {md}; + } + + /// Creates a memory descriptor for a scalar value that resides on the host. + /// + /// @param adata_type Data type of the scalar. + /// @returns A memory descriptor for host-side scalar input. + static desc host_scalar(data_type adata_type) { + dnnl_memory_desc_t md = nullptr; + error::wrap_c_api(dnnl_memory_desc_create_host_scalar( + &md, convert_to_c(adata_type)), + "could not create a memory descriptor describing host side " + "scalar"); + return desc {md}; + } + + /// Construct a memory descriptor from a C API ::dnnl_memory_desc_t + /// handle. The resulting handle is not weak and the C handle will be + /// destroyed during the destruction of the C++ object. + /// + /// @param md The C API memory descriptor. + desc(dnnl_memory_desc_t md) : handle(md) {} + + /// Construct a memory descriptor from a binary blob. + /// + /// @param blob A binary blob previously queried from a memory descriptor. + desc(const std::vector &blob) { + dnnl_memory_desc_t md = nullptr; + error::wrap_c_api( + dnnl_memory_desc_create_with_blob(&md, blob.data()), + "could not create a memory descriptor from blob"); + reset(md); + } + + /// Constructs a memory descriptor for a region inside an area + /// described by this memory descriptor. + // + /// @param adims Sizes of the region. + /// @param offsets Offsets to the region from the encompassing + /// memory object in each dimension. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case a + /// zero memory descriptor will be returned. This flag is optional + /// and defaults to false. + /// @returns A memory descriptor for the region. + desc submemory_desc(const dims &adims, const dims &offsets, + bool allow_empty = false) const { + validate_dims(adims, get_ndims()); + validate_dims(offsets, get_ndims()); + dnnl_memory_desc_t sub_md = nullptr; + dnnl_status_t status = dnnl_memory_desc_create_submemory( + &sub_md, get(), adims.data(), offsets.data()); + if (!allow_empty) + error::wrap_c_api(status, "could not construct a sub-memory"); + return desc(sub_md); + } + + /// Constructs a memory descriptor by reshaping an existing one. The + /// new memory descriptor inherits the data type. This operation is + /// valid only for memory descriptors that have format_kind set to + /// #dnnl::memory::format_kind::blocked or + /// #dnnl::memory::format_kind::any. + /// + /// The operation ensures that the transformation of the physical memory + /// format corresponds to the transformation of the logical dimensions. + /// If such transformation is impossible, the function either throws an + /// exception (default) or returns a zero memory descriptor depending on + /// the `allow_empty` flag. + /// + /// The reshape operation can be described as a combination of the + /// following basic operations: + /// 1. Add a dimension of size `1`. This is always possible. + /// 2. Remove a dimension of size `1`. This is possible only if the + /// dimension has no padding (i.e. + /// `padded_dims[dim] == dims[dim] && dims[dim] == 1`). + /// 3. Split a dimension into multiple ones. This is possible only if + /// the product of all tensor dimensions stays constant and the + /// dimension being split does not have padding (i.e. + /// `padded_dims[dim] = dims[dim]`). + /// 4. Join multiple consecutive dimensions into a single one. As in + /// the cases above, this requires that the dimensions do not have + /// padding and that the memory format is such that in physical + /// memory these dimensions are dense and have the same order as + /// their logical counterparts. This also assumes that these + /// dimensions are not blocked. + /// - Here, 'dense' means: + /// `stride for dim[i] == (stride for dim[i + 1]) * dim[i + 1]`; + /// - And 'same order' means: + /// `i < j` if and only if `stride for dim[j] <= stride for dim[i]`. + /// + /// @warning + /// Some combinations of physical memory layout and/or offsets or + /// dimensions may result in a failure to make a reshape. + /// + /// @param adims New dimensions. The product of dimensions must + /// remain constant. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case a + /// zero memory descriptor will be returned. This flag is optional + /// and defaults to false. + /// @returns A new memory descriptor with new dimensions. + desc reshape(const dims &adims, bool allow_empty = false) const { + if (get_ndims()) validate_dims(adims, 1); + dnnl_memory_desc_t out_md = nullptr; + dnnl_status_t status = dnnl_memory_desc_reshape( + &out_md, get(), (int)adims.size(), adims.data()); + if (!allow_empty) + error::wrap_c_api( + status, "could not reshape a memory descriptor"); + return desc(out_md); + } + + /// Constructs a memory descriptor by permuting axes in an existing + /// one. + /// + /// The physical memory layout representation is adjusted accordingly + /// to maintain the consistency between the logical and physical parts + /// of the memory descriptor. The new memory descriptor inherits the + /// data type. + /// + /// The new memory descriptor inherits the data type. This operation is + /// valid only for memory descriptors that have format_kind set to + /// #dnnl::memory::format_kind::blocked or + /// #dnnl::memory::format_kind::any. + /// + /// The logical axes will be permuted in the following manner: + /// @code + /// for (i = 0; i < get_ndims(); i++) + /// new_desc.dims()[permutation[i]] = dims()[i]; + /// @endcode + /// + /// Example: + /// @code + /// std::vector permutation = {1, 0}; // swap the first and + /// // the second axes + /// dnnl::memory::desc in_md( + /// {2, 3}, data_type, memory::format_tag::ab); + /// dnnl::memory::desc expect_out_md( + /// {3, 2}, data_type, memory::format_tag::ba); + /// + /// assert(in_md.permute_axes(permutation) == expect_out_md); + /// @endcode + /// + /// @param permutation Axes permutation. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case a + /// zero memory descriptor will be returned. This flag is optional + /// and defaults to false. + /// @returns A new memory descriptor with new dimensions. + desc permute_axes(const std::vector &permutation, + bool allow_empty = false) const { + validate_dims(permutation, get_ndims()); + dnnl_memory_desc_t out_md = nullptr; + dnnl_status_t status = dnnl_memory_desc_permute_axes( + &out_md, get(), permutation.data()); + if (!allow_empty) + error::wrap_c_api(status, + "could not permute axes of a memory descriptor"); + return desc(out_md); + } + + /// Returns a number of dimensions of the memory descriptor. + /// + /// @returns A number of dimensions. + int get_ndims() const { return query_s32(query::ndims_s32); } + + /// Returns padded dimensions of the memory descriptor. + /// + /// @returns A copy of the padded dimensions vector. + memory::dims get_padded_dims() const { + return query_dims(query::padded_dims); + } + + /// Returns padded offsets of the memory descriptor. + /// + /// @returns A copy of the padded offsets vector. + memory::dims get_padded_offsets() const { + return query_dims(query::padded_offsets); + } + + /// Returns a submemory offset of the memory descriptor. + /// + /// @returns A submemory offset. + memory::dim get_submemory_offset() const { + dnnl_dim_t submemory_offset; + dnnl_status_t status = dnnl_memory_desc_query( + get(), dnnl_query_submemory_offset_s64, &submemory_offset); + return status == dnnl_success ? submemory_offset : 0; + } + + /// Returns strides of the memory descriptor. + /// + /// @note + /// This API is only applicable to memory descriptors with format + /// kind #dnnl_blocked. + /// + /// @returns A copy of the strides vector. + /// @returns An empty #dnnl::memory::dims if the memory descriptor + /// does not have strides. + memory::dims get_strides() const { return query_dims(query::strides); } + + /// Returns a number of inner blocks of the memory descriptor. + /// + /// @note + /// This API is only applicable to memory descriptors with format + /// kind #dnnl_blocked. + /// + /// @returns A number of inner blocks. + int get_inner_nblks() const { + return query_s32(query::inner_nblks_s32); + } + + /// Returns inner blocks of the memory descriptor. + /// + /// @note + /// This API is only applicable to memory descriptors with format + /// kind #dnnl_blocked. + /// + /// @returns A copy of the inner blocks vector. + /// @returns An empty #dnnl::memory::dims if the memory descriptor + /// does not have inner blocks. + memory::dims get_inner_blks() const { + return query_dims(query::inner_blks); + } + + /// Returns inner indices of the memory descriptor. + /// + /// @note + /// This API is only applicable to memory descriptors with format + /// kind #dnnl_blocked. + /// + /// @returns A copy of the inner indices vector. + /// @returns An empty #dnnl::memory::dims if the memory descriptor + /// does not have inner indices. + memory::dims get_inner_idxs() const { + return query_dims(query::inner_idxs); + } + + /// Returns number of handles. + /// + /// @returns A number of handles. + int get_num_handles() const { + int nhandles; + dnnl_status_t status = dnnl_memory_desc_query_v2( + get(), dnnl_query_num_handles_s32, 0, &nhandles); + return status == dnnl_success ? nhandles : 0; + } + + /// Returns a number of non-zero entries of the memory descriptor. + /// + /// @returns A number non-zero entries. + dim get_nnz() const { + dnnl_dim_t nnz; + dnnl_status_t status = dnnl_memory_desc_query_v2( + get(), dnnl_query_nnz_s64, 0, &nnz); + return status == dnnl_success ? nnz : 0; + } + + /// Returns the sparse encoding of the memory descriptor. + /// + /// @returns the sparse encoding kind. + /// @sa @ref dev_guide_sparsity + memory::sparse_encoding get_sparse_encoding() const { + dnnl_sparse_encoding_t sparse_encoding; + dnnl_status_t status = dnnl_memory_desc_query_v2( + get(), dnnl_query_sparse_encoding, 0, &sparse_encoding); + return status == dnnl_success + ? static_cast( + sparse_encoding) + : dnnl::memory::sparse_encoding::undef; + } + + /// Returns the data type of the memory descriptor. + /// + /// @returns The data type. + memory::data_type get_data_type(int index = 0) const { + return query_data_type(query::data_type, index); + } + + /// Returns the format kind of the memory descriptor. + /// + /// @returns the format kind. + memory::format_kind get_format_kind() const { + dnnl_format_kind_t format_kind; + dnnl_status_t status = dnnl_memory_desc_query( + get(), dnnl_query_format_kind, &format_kind); + return status == dnnl_success + ? static_cast(format_kind) + : dnnl::memory::format_kind::undef; + } + + /// Returns dimensions of the memory descriptor. + /// + /// Potentially expensive due to the data copy involved. + /// @returns A copy of the dimensions vector. + memory::dims get_dims() const { return query_dims(query::dims); } + + /// Returns size of the memory descriptor in bytes. + /// @param index Data index. Defaults to 0. + /// @returns The number of bytes required to allocate a memory buffer + /// for data with a particular @p index described by this memory + /// descriptor including the padding area. + size_t get_size(int index = 0) const { + return dnnl_memory_desc_get_size_v2(get(), index); + } + + /// Returns a binary blob associated with the given memory descriptor + /// @returns The memory descriptor blob associated with the memory descriptor + std::vector get_blob() { + size_t size; + dnnl_status_t status + = dnnl_memory_desc_get_blob(nullptr, &size, get()); + error::wrap_c_api( + status, "could not get memory descriptor blob size"); + + std::vector out_blob(size); + status = dnnl_memory_desc_get_blob(out_blob.data(), &size, get()); + error::wrap_c_api(status, "could not get memory descriptor blob"); + return out_blob; + } + + /// Checks whether the memory descriptor is zero (empty). + /// @returns @c true if the memory descriptor describes an empty + /// memory and @c false otherwise. + bool is_zero() const { return get_ndims() == 0; } + + /// An equality operator. + /// @param other Another memory descriptor. + /// @returns Whether this and the other memory descriptors have + /// the same format tag, dimensions, strides, blocking, etc. + bool operator==(const desc &other) const { + return dnnl_memory_desc_equal(get(), other.get()) != 0; + } + + /// An inequality operator. + /// @param other Another memory descriptor. + /// @returns Whether this and the other memory descriptors describe + /// different memory. + bool operator!=(const desc &other) const { return !operator==(other); } + + private: + memory::data_type query_data_type(query what, int index) const { + dnnl_data_type_t data_type; + dnnl_status_t status = dnnl_memory_desc_query_v2( + get(), dnnl::convert_to_c(what), index, &data_type); + return status == dnnl_success + ? static_cast(data_type) + : dnnl::memory::data_type::undef; + } + + int query_s32(query what) const { + int res; + dnnl_status_t status = dnnl_memory_desc_query( + get(), dnnl::convert_to_c(what), &res); + return status == dnnl_success ? res : 0; + } + + memory::dims query_dims(query what) const { + dnnl_dims_t *c_dims; + dnnl_status_t status = dnnl_memory_desc_query( + get(), dnnl::convert_to_c(what), &c_dims); + + const int ndims + = (what == query::inner_idxs || what == query::inner_blks) + ? get_inner_nblks() + : get_ndims(); + + return status == dnnl_success + ? memory::dims(*c_dims, *c_dims + ndims) + : memory::dims {}; + } + }; + + /// Default constructor. + /// + /// Constructs an empty memory object, which can be used to indicate + /// absence of a parameter. + memory() = default; + + /// Constructs a memory object. + /// + /// Unless @p handle is equal to #DNNL_MEMORY_NONE, the constructed memory + /// object will have the underlying buffer set. In this case, the buffer + /// will be initialized as if #dnnl::memory::set_data_handle() had been + /// called. + /// + /// @sa memory::set_data_handle() + /// + /// @param md Memory descriptor. + /// @param aengine Engine to store the data on. + /// @param handle Handle of the memory buffer to use. + /// - A pointer to the user-allocated buffer. In this case the library + /// doesn't own the buffer. + /// - The #DNNL_MEMORY_ALLOCATE special value. Instructs the library to + /// allocate the buffer for the memory object. In this case the + /// library owns the buffer. + /// - #DNNL_MEMORY_NONE to create dnnl::memory without an underlying + /// buffer. + memory(const desc &md, const engine &aengine, void *handle) + : memory(md, aengine, std::vector {handle}) {} + + /// Constructs a memory object with multiple handles. + /// + /// Unless @p handle is equal to #DNNL_MEMORY_NONE, the constructed memory + /// object will have the underlying buffer set. In this case, the buffer + /// will be initialized as if #dnnl::memory::set_data_handle() had been + /// called. + /// + /// @sa memory::set_data_handle() + /// + /// @param md Memory descriptor. + /// @param aengine Engine to store the data on. + /// @param handles Handles of the memory buffers to use. + /// For each element of the @p handles vector the following applies: + /// - A pointer to the user-allocated buffer. In this case the library + /// doesn't own the buffer. + /// - The #DNNL_MEMORY_ALLOCATE special value. Instructs the library to + /// allocate the buffer for the memory object. In this case the + /// library owns the buffer. + /// - #DNNL_MEMORY_NONE Instructs the library to skip allocation of the + /// memory buffer. + memory(const desc &md, const engine &aengine, std::vector handles) { + dnnl_memory_t result; + dnnl_status_t status = dnnl_memory_create_v2(&result, md.get(), + aengine.get(), (int)handles.size(), handles.data()); + error::wrap_c_api(status, "could not create a memory object"); + reset(result); + } + + /// Constructs a memory object. + /// + /// The underlying buffer(s) for the memory will be allocated by the + /// library. + /// @param md Memory descriptor. + /// @param aengine Engine to store the data on. + memory(const desc &md, const engine &aengine) { + dnnl_status_t status; + dnnl_memory_t result; + const int nhandles = md.get_num_handles(); + + std::vector handles(nhandles, DNNL_MEMORY_ALLOCATE); + status = dnnl_memory_create_v2(&result, md.get(), aengine.get(), + (int)handles.size(), handles.data()); + + error::wrap_c_api(status, "could not create a memory object"); + reset(result); + } + + /// Constructs a memory object that wraps a host-side scalar value. + /// + /// @note The scalar value is copied into the newly allocated memory storage, + /// so the user does not need to manage the lifetime of the original scalar data. + /// + /// @tparam T Type of the scalar value. + /// @param md Memory descriptor describing a scalar value residing on the host. + /// @param value The scalar value to be wrapped by the memory object. + /// + /// @throws error if the memory object could not be created. + template + memory(const desc &md, const T value) { + dnnl_memory_t result; + // Check that the data type of T matches the memory descriptor's data type + // For host-side scalars, md.get_size() is data_type size + if (sizeof(T) != md.get_size()) { + DNNL_THROW_ERROR(dnnl_invalid_arguments, + "scalar type size does not match memory descriptor data " + "type size"); + } else { + dnnl_status_t status = dnnl_memory_create_host_scalar( + &result, md.get(), (void *)&value); + error::wrap_c_api(status, "could not create a memory object"); + } + reset(result); + } + + /// Returns the associated memory descriptor. + desc get_desc() const { + const_dnnl_memory_desc_t cdesc; + error::wrap_c_api(dnnl_memory_get_memory_desc(get(), &cdesc), + "could not get a memory descriptor from a memory object"); + dnnl_memory_desc_t cloned_md = nullptr; + error::wrap_c_api(dnnl_memory_desc_clone(&cloned_md, cdesc), + "could not clone a memory descriptor"); + return desc(cloned_md); + } + + /// Returns the associated engine. + engine get_engine() const { + dnnl_engine_t c_engine; + error::wrap_c_api(dnnl_memory_get_engine(get(), &c_engine), + "could not get an engine from a memory object"); + return engine(c_engine, true); + } + + /// Returns an underlying memory buffer that corresponds to the given index. + /// + /// On the CPU engine, or when using USM, this is a pointer to the + /// allocated memory. + void *get_data_handle(int index = 0) const { + void *handle; + error::wrap_c_api(dnnl_memory_get_data_handle_v2(get(), &handle, index), + "could not get a native handle from a memory object"); + return handle; + } + + /// Sets an underlying memory buffer that corresponds to the given index. + /// + /// @param handle Memory buffer to use. On the CPU engine or when USM is + /// used, the memory buffer is a pointer to the actual data. For OpenCL + /// it is a cl_mem. It must have at least + /// #dnnl::memory::desc::get_size() bytes allocated. + /// @param index Memory index to attach the buffer. Defaults to 0. + void set_data_handle(void *handle, int index = 0) const { + error::wrap_c_api(dnnl_memory_set_data_handle_v2(get(), handle, index), + "could not set native handle of a memory object"); + } + + /// Returns the scalar value stored in the memory object as type T. + /// + /// @tparam T Type to cast the scalar value to. + template + T get_host_scalar_value() const { + const_dnnl_memory_desc_t cdesc; + error::wrap_c_api(dnnl_memory_get_memory_desc(get(), &cdesc), + "could not get memory descriptor"); + + if (sizeof(T) != dnnl_memory_desc_get_size_v2(cdesc, 0)) { + DNNL_THROW_ERROR(dnnl_invalid_arguments, + "scalar type size does not match memory descriptor data " + "type size"); + } + + T value; + error::wrap_c_api(dnnl_memory_get_host_scalar_value(get(), &value), + "could not get host scalar value from a memory object"); + return value; + } + + /// Sets the scalar value stored in the memory object. + /// + /// @note The scalar value is copied into the memory storage, so the user + /// does not need to manage the lifetime of the original scalar data. + /// + /// @param value Pointer to the scalar value to set. + template + void set_host_scalar_value(const T value) const { + const_dnnl_memory_desc_t cdesc; + error::wrap_c_api(dnnl_memory_get_memory_desc(get(), &cdesc), + "could not get memory descriptor from a memory object"); + + if (sizeof(T) != dnnl_memory_desc_get_size_v2(cdesc, 0)) { + DNNL_THROW_ERROR(dnnl_invalid_arguments, + "scalar type size does not match memory descriptor data " + "type size"); + } + + error::wrap_c_api(dnnl_memory_set_host_scalar_value(get(), &value), + "could not set host scalar value to a memory object"); + } + + /// Maps a memory object and returns a host-side pointer to a memory + /// buffer with a copy of its contents. The memory buffer corresponds to + /// the given index. + /// + /// Mapping enables read/write directly from/to the memory contents for + /// engines that do not support direct memory access. + /// + /// Mapping is an exclusive operation - a memory object cannot be used in + /// other operations until it is unmapped via #dnnl::memory::unmap_data() + /// call. + /// + /// @note + /// Any primitives working with the memory should be completed before + /// the memory is mapped. Use #dnnl::stream::wait() to synchronize the + /// corresponding execution stream. + /// + /// @note + /// The map_data and unmap_data functions are provided mainly for + /// debug and testing purposes and their performance may be suboptimal. + /// + /// @tparam T Data type to return a pointer to. + /// @param index Index of the buffer. Defaults to 0. + /// @returns Pointer to the mapped memory. + template + T *map_data(int index = 0) const { + void *mapped_ptr; + error::wrap_c_api(dnnl_memory_map_data_v2(get(), &mapped_ptr, index), + "could not map memory object data"); + return static_cast(mapped_ptr); + } + + /// Unmaps a memory object and writes back any changes made to the + /// previously mapped memory buffer. The memory buffer corresponds to + /// the given index. + /// + /// @note + /// The map_data and unmap_data functions are provided mainly for + /// debug and testing purposes and their performance may be + /// suboptimal. + /// + /// @param mapped_ptr A pointer previously returned by + /// #dnnl::memory::map_data(). + /// @param index Index of the buffer. Defaults to 0. + void unmap_data(void *mapped_ptr, int index = 0) const { + error::wrap_c_api(dnnl_memory_unmap_data_v2(get(), mapped_ptr, index), + "could not unmap memory object data"); + } + + static dnnl_data_type_t convert_to_c(data_type adata_type) { + return static_cast(adata_type); + } + static dnnl_format_tag_t convert_to_c(format_tag format) { + return static_cast(format); + } +}; + +inline bool operator==(dnnl_data_type_t a, memory::data_type b) { + return a == memory::convert_to_c(b); +} +inline bool operator!=(dnnl_data_type_t a, memory::data_type b) { + return !(a == b); +} +inline bool operator==(memory::data_type a, dnnl_data_type_t b) { + return b == a; +} +inline bool operator!=(memory::data_type a, dnnl_data_type_t b) { + return !(a == b); +} + +inline bool operator==(dnnl_format_tag_t a, memory::format_tag b) { + return a == memory::convert_to_c(b); +} +inline bool operator!=(dnnl_format_tag_t a, memory::format_tag b) { + return !(a == b); +} +inline bool operator==(memory::format_tag a, dnnl_format_tag_t b) { + return b == a; +} +inline bool operator!=(memory::format_tag a, dnnl_format_tag_t b) { + return !(a == b); +} + +/// @} dnnl_api_memory + +/// @addtogroup dnnl_api_primitives +/// @{ +/// @addtogroup dnnl_api_attributes Attributes +/// +/// A container for parameters that extend primitives behavior. +/// +/// @{ + +/// @cond DO_NOT_DOCUMENT_THIS +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_post_ops_t p) { + return dnnl_post_ops_destroy(p); + } +}; +/// @endcond + +/// Post-ops. +/// +/// Post-ops are computations executed after the main primitive computations +/// and are attached to the primitive via primitive attributes. +/// +/// @sa @ref dev_guide_attributes_post_ops +/// +struct post_ops : public handle { + using handle::handle; + + /// Constructs an empty sequence of post-ops. + post_ops() { + dnnl_post_ops_t result; + error::wrap_c_api( + dnnl_post_ops_create(&result), "could not create post-ops"); + reset(result); + } + + /// Creates post-ops primitive attribute from a C API ::dnnl_post_ops_t + /// handle. The resulting handle is not weak and the C handle will be + /// destroyed during the destruction of the C++ object. + /// + /// @param post_ops The C API post-ops primitive attribute. + post_ops(dnnl_post_ops_t post_ops) : handle(post_ops) {} + + /// Returns the number of post-ops entries. + int len() const { return dnnl_post_ops_len(get()); } + + /// Returns the primitive kind of post-op at entry with a certain index. + /// @param index Index of the post-op to return the kind for. + /// @returns Primitive kind of the post-op at the specified index. + primitive::kind kind(int index) const { + error::wrap_c_api(index < len() ? dnnl_success : dnnl_invalid_arguments, + "post-ops index is out of range"); + return static_cast( + dnnl_post_ops_get_kind(get(), index)); + } + + /// Appends an accumulation (sum) post-op. Prior to accumulating the + /// result, the previous value will be will be reduced by zero point + /// @p zero_point and multiplied by a scaling factor @p scale. + /// + /// The kind of this post-op is #dnnl::primitive::kind::sum. + /// + /// This feature may improve performance for cases like dequantize the + /// asymmetrically quantized sum's src1 tensor to f32 domain before + /// performing the sum operation by subtracting @p zero_point before the + /// scaling. + /// + /// In the simplest case when the accumulation is the only post-op, + /// the computations will be `dst[:] := scale * (dst[:] - zero_point) + + /// op(...)` instead of `dst[:] := op(...)`. + /// + /// If @p data_type is specified, the original dst tensor will be + /// reinterpreted as a tensor with the provided data type. Because it is a + /// reinterpretation, data_type and dst data type should have the same size. + /// As a result, computations will be `dst[:] <- scale * + /// (as_data_type(dst[:]) - zero_point) + op(...)` instead of + /// `dst[:] <- op(...)`. + /// + /// @note + /// This post-op executes in-place and does not change the + /// destination layout. + /// + /// @param scale Scaling factor. + /// @param zero_point Zero point. + /// @param data_type Data type. + void append_sum(float scale = 1.f, int32_t zero_point = 0, + memory::data_type data_type = memory::data_type::undef) { + error::wrap_c_api(dnnl_post_ops_append_sum(get(), scale, zero_point, + memory::convert_to_c(data_type)), + "could not append a sum post-op"); + } + + /// Returns the parameters of an accumulation (sum) post-op. + /// + /// @param index Index of the sum post-op. + /// @param scale Scaling factor of the sum post-op. + void get_params_sum(int index, float &scale) const { + error::wrap_c_api(dnnl_post_ops_get_params_sum( + get(), index, &scale, nullptr, nullptr), + "could not get parameters of a sum post-op"); + } + + /// Returns the parameters of an accumulation (sum) post-op. + /// + /// @param index Index of the sum post-op. + /// @param scale Scaling factor of the sum post-op. + /// @param data_type Data type of the sum post-op. + void get_params_sum( + int index, float &scale, memory::data_type &data_type) const { + dnnl_data_type_t c_data_type; + error::wrap_c_api(dnnl_post_ops_get_params_sum( + get(), index, &scale, nullptr, &c_data_type), + "could not get parameters of a sum post-op"); + data_type = static_cast(c_data_type); + } + + /// Returns the parameters of an accumulation (sum) post-op. + /// + /// @param index Index of the sum post-op. + /// @param scale Scaling factor of the sum post-op. + /// @param zero_point Single scalar int32_t value of zeropoint. + /// @param data_type Data type of the sum post-op. + void get_params_sum(int index, float &scale, int32_t &zero_point, + memory::data_type &data_type) const { + dnnl_data_type_t c_data_type; + error::wrap_c_api(dnnl_post_ops_get_params_sum(get(), index, &scale, + &zero_point, &c_data_type), + "could not get parameters of a sum post-op"); + data_type = static_cast(c_data_type); + } + + /// Appends an elementwise post-op. + /// + /// The kind of this post-op is #dnnl::primitive::kind::eltwise. + /// + /// In the simplest case when the elementwise is the only post-op, the + /// computations would be `dst[:] := eltwise_op (op(...))` instead + /// of `dst[:] <- op(...)`, where eltwise_op is configured with the given + /// parameters. + /// + /// @param aalgorithm Elementwise algorithm. + /// @param alpha Alpha parameter for the elementwise algorithm. + /// @param beta Beta parameter for the elementwise algorithm. + void append_eltwise(algorithm aalgorithm, float alpha, float beta) { + error::wrap_c_api(dnnl_post_ops_append_eltwise( + get(), convert_to_c(aalgorithm), alpha, beta), + "could not append an elementwise post-op"); + } + + /// Returns parameters of an elementwise post-op. + /// + /// @param index Index of the post-op. + /// @param aalgorithm Output elementwise algorithm kind. + /// @param alpha Output alpha parameter for the elementwise algorithm. + /// @param beta Output beta parameter for the elementwise algorithm. + void get_params_eltwise( + int index, algorithm &aalgorithm, float &alpha, float &beta) const { + dnnl_alg_kind_t c_alg; + error::wrap_c_api(dnnl_post_ops_get_params_eltwise( + get(), index, &c_alg, &alpha, &beta), + "could not get parameters of an elementwise post-op"); + aalgorithm = static_cast(c_alg); + } + + /// Appends a depthwise post-op convolution. + /// + /// This post-op can only be fused with a 2D 1x1 convolution (convolution + /// with weights spatial dimension equal to 1 i.e., kh=kw=1). + /// + /// The kind of this post-op is #dnnl_convolution. + /// + /// The number of outputs for primitive remain same as before. The output + /// spatial size can be derived as below: + /// + /// output_height = ceil(output_height_1x1_convolution, stride) + /// output_width = ceil(output_width_1x1_convolution, stride) + /// + /// See @ref dev_guide_attributes_post_ops_depthwise and + /// @ref dev_guide_attributes_post_ops_depthwise_fusion for more info. + /// + /// @param weights_data_type Weights data type of depthwise post-op + /// @param bias_data_type Bias data type of depthwise post-op + /// @param dst_data_type Output data type of depthwise post-op + /// @param kernel_size Size of kernel of depthwise post-op + /// @param stride_size Size of stride of depthwise post-op + /// @param padding_l_size Size of left and top paddings of depthwise post-op + void append_dw(memory::data_type weights_data_type, + memory::data_type bias_data_type, memory::data_type dst_data_type, + memory::dim kernel_size, memory::dim stride_size, + memory::dim padding_l_size) { + + error::wrap_c_api(dnnl_post_ops_append_dw(get(), + memory::convert_to_c(weights_data_type), + memory::convert_to_c(bias_data_type), + memory::convert_to_c(dst_data_type), + kernel_size, stride_size, padding_l_size), + "could not append depthwise post-op"); + } + + /// Returns the parameters of an depthwise post-op. + /// + /// @param index Index of the elementwise post-op. + /// @param weights_data_type Weights data type of depthwise post-op + /// @param bias_data_type Bias data type of depthwise post-op + /// @param dst_data_type Output data type of depthwise post-op + /// @param kernel_size Size of kernel of depthwise post-op + /// @param stride_size Size of stride of depthwise post-op + /// @param padding_l_size Size of left and top paddings of depthwise post-op + void get_params_dw(int index, memory::data_type &weights_data_type, + memory::data_type &bias_data_type, memory::data_type &dst_data_type, + memory::dim &kernel_size, memory::dim &stride_size, + memory::dim &padding_l_size) const { + + dnnl_data_type_t c_weights_data_type; + dnnl_data_type_t c_bias_data_type; + dnnl_data_type_t c_dst_data_type; + dnnl_dim_t c_kernel_size; + dnnl_dim_t c_stride_size; + dnnl_dim_t c_padding_l_size; + error::wrap_c_api( + dnnl_post_ops_get_params_dw(get(), index, &c_weights_data_type, + &c_bias_data_type, &c_dst_data_type, &c_kernel_size, + &c_stride_size, &c_padding_l_size), + "could not get parameters of depthwise post-op"); + + weights_data_type = static_cast(c_weights_data_type); + bias_data_type = static_cast(c_bias_data_type); + dst_data_type = static_cast(c_dst_data_type); + kernel_size = c_kernel_size; + stride_size = c_stride_size; + padding_l_size = c_padding_l_size; + } + + /// Appends a binary post-op. + /// + /// This post operation is categorized as #dnnl_binary. + /// + /// In the simplest case when the binary is the only post operation, the + /// computations will be: + /// + /// dst[:] <- binary_op (dst[:], another_input[:]) + /// + /// where binary_op is configured with the given parameters. binary_op + /// supports broadcast semantics for a second operand. + /// + /// @param aalgorithm Binary algorithm for the post-op. + /// @param src1_desc Memory descriptor of a second operand. + void append_binary(algorithm aalgorithm, const memory::desc &src1_desc) { + error::wrap_c_api(dnnl_post_ops_append_binary(get(), + convert_to_c(aalgorithm), src1_desc.get()), + "could not append a binary post-op"); + } + + /// Appends a binary post-op with ternary operators. + /// + /// This post operation is categorized as #dnnl_binary. + /// + /// In the simplest case when this is the only post operation, the + /// computations will be: + /// + /// dst[:] <- binary_op (dst[:], another_input1[:], another_input2[:]) + /// + /// where binary_op is configured with the given parameters. binary_op + /// supports broadcast semantics only for the second operand and not for the + /// third operand. + /// + /// @param aalgorithm Binary algorithm for the post-op. + /// @param src1_desc Memory descriptor of the second operand. + /// @param src2_desc Memory descriptor of the third operand. If the specified + /// algorithm is not one that requires a ternary input, src2_desc will be + /// ignored. + void append_binary(algorithm aalgorithm, const memory::desc &src1_desc, + const memory::desc &src2_desc) { + error::wrap_c_api( + dnnl_post_ops_append_binary_v2(get(), convert_to_c(aalgorithm), + src1_desc.get(), src2_desc.get()), + "could not append a binary post-op with ternary operators"); + } + + /// Returns the parameters of a binary post-op. + /// + /// @param index Index of the binary post-op. + /// @param aalgorithm Output binary algorithm kind. + /// @param src1_desc Output memory descriptor of a second operand. + void get_params_binary( + int index, algorithm &aalgorithm, memory::desc &src1_desc) const { + dnnl_alg_kind_t c_alg; + const_dnnl_memory_desc_t cdesc; + error::wrap_c_api( + dnnl_post_ops_get_params_binary(get(), index, &c_alg, &cdesc), + "could not get parameters of a binary post-op"); + aalgorithm = static_cast(c_alg); + dnnl_memory_desc_t cloned_md = nullptr; + error::wrap_c_api(dnnl_memory_desc_clone(&cloned_md, cdesc), + "could not clone a memory descriptor"); + src1_desc = memory::desc(cloned_md); + } + + /// Returns the parameters of a binary post-op with ternary operators. + /// + /// @param index Index of the binary post-op. + /// @param aalgorithm Output binary algorithm kind. + /// @param src1_desc Output memory descriptor of the second operand. + /// @param src2_desc Output memory descriptor of the third operand. + void get_params_binary(int index, algorithm &aalgorithm, + memory::desc &src1_desc, memory::desc &src2_desc) const { + dnnl_alg_kind_t c_alg; + const_dnnl_memory_desc_t cdesc1, cdesc2; + error::wrap_c_api(dnnl_post_ops_get_params_binary_v2( + get(), index, &c_alg, &cdesc1, &cdesc2), + "could not get parameters of a binary post-op with ternary " + "operators"); + aalgorithm = static_cast(c_alg); + dnnl_memory_desc_t cloned_md1 = nullptr; + dnnl_memory_desc_t cloned_md2 = nullptr; + + error::wrap_c_api(dnnl_memory_desc_clone(&cloned_md1, cdesc1), + "could not clone a memory descriptor"); + src1_desc = memory::desc(cloned_md1); + + error::wrap_c_api(dnnl_memory_desc_clone(&cloned_md2, cdesc2), + "could not clone a memory descriptor"); + src2_desc = memory::desc(cloned_md2); + } + + /// Appends a prelu forward post-op. + /// + /// The kind of this post-op is #dnnl::primitive::kind::prelu. + /// + /// The post-op can be defined as: + /// + /// dst[:] <- prelu(dst[:], weights[:]) + /// prelu: + /// dst[:] <- dst[:] if dst[:] > 0 + /// dst[:] <- dst[:] * weights[:] if dst[:] <= 0 + /// + /// + /// Example usage: + /// @code + /// int mb = 32, oc = 32, + /// oh = 14, ow = 14; // convolution output params + /// // unique weights per output channel + /// vector weights = { ... }; + /// int oc_dim = 1; // mb_dim = 0, channel_dim = 1, height_dim = 2, ... + /// + /// // construct a convolution descriptor + /// dnnl::convolution::desc conv_d; + /// + /// dnnl::primitive_attr attr; + /// attr.append_prelu(1 << oc_dim); + /// + /// dnnl::primitive_desc conv_pd(conv_d, attr, engine); + /// memory prelu_weights({{1}, dt::f32, {1}}, eng, weights.data()); + /// + /// std::unordered_map conv_args; + /// + /// conv_args.insert( + /// {DNNL_ARG_ATTR_MULTIPLE_POST_OP(0) | DNNL_ARG_WEIGHTS, prelu_weights}) + /// @endcode + /// + /// @note + /// The order of dimensions does not depend on how elements are laid + /// out in memory. For example: + /// - for a 2D CNN activations tensor the order is always (n, c) + /// - for a 4D CNN activations tensor the order is always (n, c, h, w) + /// - for a 5D CNN weights tensor the order is always + /// (g, oc, ic, kh, kw) + /// + /// Prelu weights tensor is passed in runtime execution phase. Prelu + /// weights tensor data type is implicitly assumed as f32 using plain + /// layout (a, ab, acb, acdb, acdeb). + /// + /// @param mask Defines the correspondence between the output tensor + /// dimensions and the prelu weights tensor. The set i-th bit indicates + /// that a dedicated weights value is used for each index along that + /// dimension. Set the mask to 0 to use a common weights value + /// for the whole output tensor. + void append_prelu(int mask) { + error::wrap_c_api(dnnl_post_ops_append_prelu(get(), mask), + "could not append a prelu post-op"); + } + + /// Returns the parameters of a prelu post-op. + /// + /// @param index Index of the prelu post-op. + /// @param mask Weights mask of prelu post-op. + void get_params_prelu(int index, int &mask) const { + error::wrap_c_api(dnnl_post_ops_get_params_prelu(get(), index, &mask), + "could not get parameters of a binary post-op"); + } +}; + +/// @cond DO_NOT_DOCUMENT_THIS +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_primitive_attr_t p) { + return dnnl_primitive_attr_destroy(p); + } +}; +/// @endcond + +/// Primitive attributes. +/// +/// @sa @ref dev_guide_attributes +struct primitive_attr : public handle { + using handle::handle; + + /// Constructs default (empty) primitive attributes. + primitive_attr() { + dnnl_primitive_attr_t result; + error::wrap_c_api(dnnl_primitive_attr_create(&result), + "could not create primitive attribute"); + reset(result); + } + + /// Creates primitive attributes from a C API ::dnnl_primitive_attr_t + /// handle. The resulting handle is not weak and the C handle will be + /// destroyed during the destruction of the C++ object. + /// + /// @param attr The C API primitive attributes. + primitive_attr(dnnl_primitive_attr_t attr) + : handle(attr) {} + + /// Returns the parameters of a dropout attribute. + /// + /// @param mask_desc Output memory descriptor for dropout masks. If a + /// default memory descriptor is returned, the mask values will not be + /// written to the output memory buffer during the primitive execution. + void get_dropout(memory::desc &mask_desc) const { + const_dnnl_memory_desc_t cdesc; + error::wrap_c_api(dnnl_primitive_attr_get_dropout(get(), &cdesc), + "could not get parameters of a dropout attribute"); + dnnl_memory_desc_t cloned_md = nullptr; + error::wrap_c_api(dnnl_memory_desc_clone(&cloned_md, cdesc), + "could not clone a memory descriptor"); + mask_desc = memory::desc(cloned_md); + } + + /// Returns the parameters of a dropout attribute. + /// + /// @param mask_desc Output memory descriptor for dropout masks. If a + /// default memory descriptor is returned, the mask values will not be + /// written to the output memory buffer during the primitive execution. + /// @param seed_dt Output datatype for seed argument. + /// @param use_offset Output boolean. If true, an offset argument must be + /// passed at the execution and will be used in random number + /// generation. + /// @param use_host_scalars Output boolean. If true, probability, seed and + /// offset arguments are passed as host_scalar memory objects. + void get_dropout(memory::desc &mask_desc, memory::data_type &seed_dt, + bool &use_offset, bool &use_host_scalars) const { + const_dnnl_memory_desc_t cdesc; + dnnl_data_type_t c_seed_dt; + int c_use_offset; + int c_use_host_scalars; + error::wrap_c_api( + dnnl_primitive_attr_get_dropout_v2(get(), &cdesc, &c_seed_dt, + &c_use_offset, &c_use_host_scalars), + "could not get parameters of a dropout attribute"); + dnnl_memory_desc_t cloned_md = nullptr; + error::wrap_c_api(dnnl_memory_desc_clone(&cloned_md, cdesc), + "could not clone a memory descriptor"); + mask_desc = memory::desc(cloned_md); + seed_dt = static_cast(c_seed_dt); + use_offset = c_use_offset; + use_host_scalars = c_use_host_scalars; + } + + /// Sets dropout probability. + /// + /// @param mask_desc Memory descriptor for dropout masks. If a default + /// memory descriptor is passed, the mask values will not be written to + /// the output memory buffer during the primitive execution. + void set_dropout(const memory::desc &mask_desc) { + error::wrap_c_api( + dnnl_primitive_attr_set_dropout(get(), mask_desc.get()), + "could not set dropout primitive attribute"); + } + + /// Sets dropout probability. + /// + /// @param mask_desc Memory descriptor for dropout masks. If a default + /// memory descriptor is passed, the mask values will not be written to + /// the output memory buffer during the primitive execution. + /// @param seed_dt Datatype for seed argument. + /// @param use_offset If true, an offset argument must be passed at the + /// execution and will be used in random number generation. + /// @param use_host_scalars If true, probability, seed and offset arguments + /// are passed as host_scalar memory objects. + void set_dropout(const memory::desc &mask_desc, memory::data_type seed_dt, + bool use_offset, bool use_host_scalars) { + error::wrap_c_api( + dnnl_primitive_attr_set_dropout_v2(get(), mask_desc.get(), + memory::convert_to_c(seed_dt), use_offset, + use_host_scalars), + "could not set dropout primitive attribute"); + } + + /// Returns the fpmath mode + fpmath_mode get_fpmath_mode() const { + dnnl_fpmath_mode_t result; + error::wrap_c_api(dnnl_primitive_attr_get_fpmath_mode(get(), &result), + "could not get fpmath mode primitive attribute"); + return fpmath_mode(result); + } + + /// Returns the fpmath mode + /// + /// @param mode Specified fpmath mode. + /// @param apply_to_int Use floating-point arithmetic for integer primitives. + void get_fpmath_mode(fpmath_mode &mode, bool &apply_to_int) const { + dnnl_fpmath_mode_t c_mode; + int c_apply_to_int; + error::wrap_c_api(dnnl_primitive_attr_get_fpmath_mode_v2( + get(), &c_mode, &c_apply_to_int), + "could not get fpmath mode primitive attribute"); + mode = fpmath_mode(c_mode); + apply_to_int = static_cast(c_apply_to_int); + } + + /// Sets fpmath mode. + /// + /// @param mode Specified fpmath mode. + /// @param apply_to_int Boolean. Use of floating-point arithmetic for integer primitives. + void set_fpmath_mode(fpmath_mode mode, bool apply_to_int = false) { + error::wrap_c_api(dnnl_primitive_attr_set_fpmath_mode_v2(get(), + dnnl::convert_to_c(mode), apply_to_int), + "could not set fpmath mode primitive attribute"); + } + + /// Returns the accumulation mode + accumulation_mode get_accumulation_mode() const { + dnnl_accumulation_mode_t result; + error::wrap_c_api( + dnnl_primitive_attr_get_accumulation_mode(get(), &result), + "could not get accumulation mode primitive attribute"); + return accumulation_mode(result); + } + + /// Sets accumulation mode. + /// + /// @param mode Specified accumulation mode. + void set_accumulation_mode(accumulation_mode mode) { + error::wrap_c_api(dnnl_primitive_attr_set_accumulation_mode( + get(), dnnl::convert_to_c(mode)), + "could not set accumulation mode primitive attribute"); + } + + /// Returns the deterministic attribute value + bool get_deterministic() const { + int result; + error::wrap_c_api(dnnl_primitive_attr_get_deterministic(get(), &result), + "could not get deterministic primitive attribute"); + return static_cast(result); + } + + /// Sets deterministic attribute value + /// + /// @param value Specified deterministic mode. + void set_deterministic(bool value) { + error::wrap_c_api(dnnl_primitive_attr_set_deterministic( + get(), static_cast(value)), + "could not set deterministic primitive attribute"); + } + + /// Returns the rounding mode attribute value + /// + /// @param arg Argument for which rounding mode query applies. + /// @returns The rounding mode applied to the specified argument. + rounding_mode get_rounding_mode(int arg) const { + dnnl_rounding_mode_t result; + error::wrap_c_api(dnnl_primitive_attr_get_rounding(get(), arg, &result), + "could not get rounding mode primitive attribute"); + return rounding_mode(result); + } + + /// Sets the rounding mode attribute value for a given argument + /// + /// @param arg Argument for which to set rounding mode. + /// @param mode Rounding mode to apply. + void set_rounding_mode(int arg, rounding_mode mode) { + error::wrap_c_api(dnnl_primitive_attr_set_rounding( + get(), arg, convert_to_c(mode)), + "could not set rounding mode primitive attribute"); + } + + /// Returns the scratchpad mode. + scratchpad_mode get_scratchpad_mode() const { + dnnl_scratchpad_mode_t result; + error::wrap_c_api( + dnnl_primitive_attr_get_scratchpad_mode(get(), &result), + "could not get scratchpad mode primitive attribute"); + return scratchpad_mode(result); + } + + /// Sets scratchpad mode. + /// + /// @param mode Specified scratchpad mode. + void set_scratchpad_mode(scratchpad_mode mode) { + error::wrap_c_api(dnnl_primitive_attr_set_scratchpad_mode( + get(), dnnl::convert_to_c(mode)), + "could not set scratchpad mode primitive attribute"); + } + + /// Sets scaling factors for primitive operations for a given memory + /// argument. The scaling factors must be passed at execution time + /// as an argument with index #DNNL_ARG_ATTR_SCALES | arg. + /// + /// @sa dnnl_primitive_attr_set_scales_mask + /// + /// @param arg Parameter argument index as passed to the + /// primitive::execute() call. + /// @param mask Scaling factors correspondence mask that defines the + /// correspondence between the tensor dimensions and the @p scales + /// vector. The set i-th bit indicates that a dedicated scaling factor + /// is used for each index along that dimension. Set the mask to 0 to + /// use a common scaling factor for the whole output tensor. + void set_scales_mask(int arg, int mask) { + error::wrap_c_api(dnnl_primitive_attr_set_scales_mask(get(), arg, mask), + "could not set scales primitive attribute"); + } + + /// Sets primitive attributes scaling factors for a given memory + /// argument. The scaling factors must be passed at execution time as + /// an argument with index #DNNL_ARG_ATTR_SCALES | arg. + /// + /// @sa dnnl_primitive_attr_set_scales_v3 + /// + /// @param arg Parameter argument index as passed to the + /// primitive execute() call. + /// @param mask Scaling factors correspondence mask that defines the + /// correspondence between the tensor dimensions and the @p scales array. + /// The set i-th bit indicates that a dedicated scaling factor is used for + /// each index along that dimension. Set the mask to 0 to use a common + /// scaling factor for the whole tensor. + /// @param groups Scaling factors correspondence groups that define the + /// correspondence between the tensor dimensions and the scales array. + /// The group dimensions should only be provided for each logical dimension + /// that has correspondence mask @p mask set. + /// @param data_type Scaling factors data_type. + /// @param is_on_host Indicates whether the scaling factor is a host-side scalar. + /// @param qmode Quantization mode, can be #quantization_mode::static_sazp + /// or #quantization_mode::dynamic_mx + void set_scales(int arg, int mask, const memory::dims &groups, + memory::data_type data_type = memory::data_type::f32, + bool is_on_host = false, + quantization_mode qmode = quantization_mode::static_sazp) { + error::wrap_c_api(dnnl_primitive_attr_set_scales_v3(get(), arg, mask, + (int)groups.size(), groups.data(), + memory::convert_to_c(data_type), is_on_host, + convert_to_c(qmode)), + "could not set scales primitive attribute"); + } + + /// Sets a single host-side scalar scaling + /// factor for the specified memory argument. The scaling factor should be + /// passed as a host scalar memory object at execution time with index + /// #DNNL_ARG_ATTR_SCALES | arg. + /// + /// @note Using this API to set the scaling factor implies that the scales + /// attribute has `mask == 0` and an empty groups vector. + /// + /// @sa dnnl_primitive_attr_set_scales_v2 + /// + /// @param arg Parameter argument index as passed to the + /// primitive::execute() call. + /// @param data_type Scaling factors data_type. + void set_host_scale( + int arg, memory::data_type data_type = memory::data_type::f32) { + error::wrap_c_api(dnnl_primitive_attr_set_scales_v3(get(), arg, 0, 0, + nullptr, memory::convert_to_c(data_type), 1, + dnnl_quantization_mode_static_sazp), + "could not set scales primitive attribute"); + } + + /// Sets zero points for primitive operations for a given memory argument. + /// The zero points must be passed at execution time as an argument with + /// index #DNNL_ARG_ATTR_ZERO_POINTS | arg. + /// + /// @sa dnnl_primitive_attr_set_zero_points_mask + /// + /// @param arg Parameter argument index as passed to the + /// primitive::execute() call. + /// @param mask Zero point correspondence mask that defines the + /// correspondence between the tensor dimensions and the @p + /// zero_points vector. The set i-th bit indicates that a dedicated + /// zero point is used for each index along that dimension. Set the + /// mask to 0 to use a common zero point for the whole output tensor. + void set_zero_points_mask(int arg, int mask) { + error::wrap_c_api( + dnnl_primitive_attr_set_zero_points_mask(get(), arg, mask), + "could not set zero points primitive attribute"); + } + + /// Sets zero points for primitive operations for a given memory argument. + /// The zero points must be passed at execution time as an argument with + /// index #DNNL_ARG_ATTR_ZERO_POINTS | arg. + /// + /// @note If `is_on_host` is true, sets a single host-side zero point + /// for the specified memory argument. The zero point should be + /// passed as a host scalar memory object at execution time with index + /// #DNNL_ARG_ATTR_ZERO_POINTS | arg. + /// + /// @sa dnnl_primitive_attr_set_zero_points + /// + /// @param arg Parameter argument index as passed to the + /// primitive::execute() call. + /// @param mask Zero point correspondence mask that defines the + /// correspondence between the tensor dimensions and the zero points + /// vector. The set i-th bit indicates that a dedicated zero point is + /// used for each index along that dimension. Set the mask to 0 to use + /// a common zero point for the whole output tensor. + /// @param groups Zero point factors correspondence groups that define the + /// correspondence between the tensor dimensions and the zero points + /// array. + /// The set i-th dimension indicates a number of groups of zero point + /// factors used for that logical dimension in a memory indicated by + /// @p arg. + /// @param data_type Zero point factors data_type. + /// @param is_on_host Indicates whether the zero point is a host-side scalar. + void set_zero_points(int arg, int mask, const memory::dims &groups, + memory::data_type data_type = memory::data_type::s32, + bool is_on_host = false) { + error::wrap_c_api(dnnl_primitive_attr_set_zero_points_v2(get(), arg, + mask, (int)groups.size(), groups.data(), + memory::convert_to_c(data_type), is_on_host), + "could not set zero points primitive attribute"); + } + + /// Sets a single host-side zero point for the specified memory argument. + /// The zero point should be passed as a host scalar memory object at + /// execution time with index #DNNL_ARG_ATTR_ZERO_POINTS | arg. + /// + /// @note Using this API to set the zero point implies that the zero + /// point attribute has `mask == 0` and an empty groups vector. + /// + /// @sa dnnl_primitive_attr_set_zero_points_v2 + /// + /// @param arg Parameter argument index as passed to the + /// primitive::execute() call. + /// @param data_type Zero point data type. + void set_host_zero_point( + int arg, memory::data_type data_type = memory::data_type::s32) { + error::wrap_c_api( + dnnl_primitive_attr_set_zero_points_v2(get(), arg, 0, 0, + nullptr, memory::convert_to_c(data_type), 1), + "could not set zero points primitive attribute"); + } + + /// Sets precomputed reductions for primitive operations for a given memory + /// argument. The precomputed reductions must be passed at execution time as + /// an argument with index #DNNL_ARG_ATTR_PRECOMPUTED_REDUCTIONS | arg. + /// + /// @sa dnnl_primitive_attr_set_precomputed_reductions + /// + /// @param arg Parameter argument index as passed to the + /// primitive::execute() call. + /// @param mask Precomputed reductions correspondence mask that defines the + /// correspondence between the tensor dimensions and the precomputed + /// reductions vector. The set i-th bit indicates that a dedicated + /// precomputed reduction point is used for each index along that + /// dimension. + /// @param groups Precomputed reduction factors correspondence groups that + /// define the correspondence between the tensor dimensions and the + /// precomputed reductions array. + /// The set i-th dimension indicates a number of groups of precomputed + /// reduction factors used for that logical dimension in a memory + /// indicated by @p arg. + /// @param data_type Precomputed reduction factors data_type. + void set_precomputed_reductions(int arg, int mask, + const memory::dims &groups, + memory::data_type data_type = memory::data_type::s32) { + error::wrap_c_api(dnnl_primitive_attr_set_precomputed_reductions(get(), + arg, mask, (int)groups.size(), groups.data(), + memory::convert_to_c(data_type)), + "could not set precomputed reductions primitive attribute"); + } + + /// Returns post-ops previously set via set_post_ops(). + /// + /// @returns Post-ops. + post_ops get_post_ops() const { + const_dnnl_post_ops_t const_c_post_ops; + error::wrap_c_api( + dnnl_primitive_attr_get_post_ops(get(), &const_c_post_ops), + "could not get post-ops primitive attribute"); + dnnl_post_ops_t c_post_ops; + error::wrap_c_api(dnnl_post_ops_clone(&c_post_ops, const_c_post_ops), + "could not clone post-ops primitive attribute"); + return post_ops(c_post_ops); + } + + /// Sets post-ops. + /// + /// @note + /// There is no way to check whether the post-ops would be supported + /// by the target primitive. Any error will be reported + /// by the respective primitive descriptor constructor. + /// + /// @param ops Post-ops object to copy post-ops from. + void set_post_ops(const post_ops &ops) { + error::wrap_c_api(dnnl_primitive_attr_set_post_ops(get(), ops.get()), + "could not set post-ops primitive attribute"); + } + + /// Sets quantization scale and shift parameters for RNN data tensors. + /// + /// For performance reasons, the low-precision configuration of the RNN + /// primitives expect input activations to have the unsigned 8-bit integer + /// data type. The scale and shift parameters are used to quantize + /// floating-point data to unsigned integer and must be passed to the RNN + /// primitive using attributes. + /// + /// The quantization formula is `scale * data + shift`. + /// + /// Example usage: + /// @code + /// // RNN parameters + /// int l = 2, t = 2, mb = 32, sic = 32, slc = 32, dic = 32, dlc = 32; + /// // Activations quantization parameters + /// float scale = 63.f, shift = 64.f; + /// + /// primitive_attr attr; + /// + /// // Set scale and shift for int8 quantization of activation + /// attr.set_rnn_data_qparams(scale, shift); + /// + /// // Create an RNN primitive descriptor. + /// vanilla_rnn_forward::primitive_desc rnn_d( + /// engine, /* arguments */, attr); + /// @endcode + /// + /// @note + /// Quantization scale and shift are common for src_layer, src_iter, + /// dst_iter, and dst_layer. + /// + /// @param scale The value to scale the data by. + /// @param shift The value to shift the data by. + void set_rnn_data_qparams(float scale, float shift) { + error::wrap_c_api( + dnnl_primitive_attr_set_rnn_data_qparams(get(), scale, shift), + "could not set RNN data quantization parameters primitive " + "attribute"); + } + + /// Returns the quantization scale and shift parameters for RNN data + /// tensors. + /// + /// @note + /// Quantization scale and shift are common for src_layer, src_iter, + /// dst_iter, and dst_layer. + /// + /// @param scale The value to scale the data by. + /// @param shift The value to shift the data by. + void get_rnn_data_qparams(float &scale, float &shift) { + float c_scale, c_shift; + error::wrap_c_api(dnnl_primitive_attr_get_rnn_data_qparams( + get(), &c_scale, &c_shift), + "could not set RNN data quantization parameters primitive " + "attribute"); + scale = c_scale; + shift = c_shift; + } + + /// Sets quantization scaling factors for RNN weights tensors. The + /// low-precision configuration of the RNN primitives expect input weights + /// to use the signed 8-bit integer data type. The scaling factors are + /// used to quantize floating-point data to signed integer and must be + /// passed to RNN primitives using attributes. + /// + /// @note + /// The dimension order is always native and does not depend on the + /// actual layout used. For example, five-dimensional weights always + /// have (l, d, i, g, o) logical dimension ordering. + /// + /// @note + /// Quantization scales are common for weights_layer and + /// weights_iteration + /// + /// @param mask Scaling factors correspondence mask that defines the + /// correspondence between the output tensor dimensions and the @p + /// scales vector. The set i-th bit indicates that a dedicated scaling + /// factor should be used each index along that dimension. Set the + /// mask to 0 to use a common scaling factor for the whole output + /// tensor. + /// @param scales Constant vector of output scaling factors. The following + /// equality must hold: + /// \f$scales.size() = \prod\limits_{d \in mask} weights.dims[d].\f$ + /// Violations can only be detected when the attributes are used to + /// create a primitive descriptor. + void set_rnn_weights_qparams(int mask, const std::vector &scales) { + error::wrap_c_api(dnnl_primitive_attr_set_rnn_weights_qparams(get(), + (int)scales.size(), mask, scales.data()), + "could not set RNN weights quantization parameters primitive " + "attribute"); + } + + /// Returns the quantization scaling factors for RNN projection weights + /// tensors. + /// + /// @note + /// The dimension order is always native and does not depend on the + /// actual layout used. For example, five-dimensional weights always + /// have (l, d, i, g, o) logical dimension ordering. + /// + /// @param mask Scaling factors correspondence mask that defines the + /// correspondence between the output tensor dimensions and the @p + /// scales vector. The set i-th bit indicates that a dedicated scaling + /// factor should be used each index along that dimension. Set the + /// mask to 0 to use a common scaling factor for the whole output + /// tensor. + /// @param scales Constant vector of output scaling factors. The following + /// equality must hold: + /// \f$scales.size() = \prod\limits_{d \in mask} weights.dims[d].\f$ + /// Violations can only be detected when the attributes are used to + /// create a primitive descriptor. + void get_rnn_weights_qparams(int &mask, std::vector &scales) { + dnnl_dim_t count; + int c_mask; + const float *c_scales; + error::wrap_c_api(dnnl_primitive_attr_get_rnn_weights_qparams( + get(), &count, &c_mask, &c_scales), + "could not get primitive RNN weights quantization " + "parameters attributes"); + scales.resize(count); + + mask = c_mask; + for (dnnl_dim_t c = 0; c < count; c++) + scales[c] = c_scales[c]; + } + + /// Sets quantization scaling factors for RNN projection weights tensors. + // The low-precision configuration of the RNN primitives expect input + // weights to use the signed 8-bit integer data type. The scaling factors + // are used to quantize floating-point data to signed integer and must be + /// passed to RNN primitives using attributes. + /// + /// @note + /// The dimension order is always native and does not depend on the + /// actual layout used. For example, five-dimensional weights always + /// have (l, d, i, g, o) logical dimension ordering. + /// + /// @note + /// Quantization scales are common for weights_layer and + /// weights_iteration + /// + /// @param mask Scaling factors correspondence mask that defines the + /// correspondence between the output tensor dimensions and the @p + /// scales vector. The set i-th bit indicates that a dedicated scaling + /// factor should be used each index along that dimension. Set the + /// mask to 0 to use a common scaling factor for the whole output + /// tensor. + /// @param scales Constant vector of output scaling factors. The following + /// equality must hold: + /// \f$scales.size() = \prod\limits_{d \in mask} weights.dims[d].\f$ + /// Violations can only be detected when the attributes are used to + /// create a primitive descriptor. + void set_rnn_weights_projection_qparams( + int mask, const std::vector &scales) { + error::wrap_c_api( + dnnl_primitive_attr_set_rnn_weights_projection_qparams( + get(), (int)scales.size(), mask, scales.data()), + "could not set primitive RNN weights projection quantization " + "parameters attributes"); + } + + /// Returns the quantization scaling factors for RNN projection weights + /// tensors. + /// + /// @note + /// The dimension order is always native and does not depend on the + /// actual layout used. For example, five-dimensional weights always + /// have (l, d, i, g, o) logical dimension ordering. + /// + /// @param mask Scaling factors correspondence mask that defines the + /// correspondence between the output tensor dimensions and the @p + /// scales vector. The set i-th bit indicates that a dedicated scaling + /// factor should be used each index along that dimension. Set the + /// mask to 0 to use a common scaling factor for the whole output + /// tensor. + /// @param scales Constant vector of output scaling factors. The following + /// equality must hold: + /// \f$scales.size() = \prod\limits_{d \in mask} weights.dims[d].\f$ + /// Violations can only be detected when the attributes are used to + /// create a primitive descriptor. + void get_rnn_weights_projection_qparams( + int &mask, std::vector &scales) { + dnnl_dim_t count; + int c_mask; + const float *c_scales; + error::wrap_c_api( + dnnl_primitive_attr_get_rnn_weights_projection_qparams( + get(), &count, &c_mask, &c_scales), + "could not get primitive RNN weights projection quantization " + "parameters attributes"); + scales.resize(count); + + mask = c_mask; + for (dnnl_dim_t c = 0; c < count; c++) + scales[c] = c_scales[c]; + } +}; + +/// @} dnnl_api_attributes + +/// @addtogroup dnnl_api_primitives_common +/// @{ + +/// Base class for all primitive descriptors. +struct primitive_desc_base : public handle { + using handle::handle; + + /// Default constructor. Produces an empty object. + primitive_desc_base() = default; + + /// Returns the engine of the primitive descriptor. + /// @returns The engine of the primitive descriptor. + engine get_engine() const { return query_engine(query::engine); } + + /// Returns implementation name. + /// @returns The implementation name. + const char *impl_info_str() const { + const char *res; + error::wrap_c_api(dnnl_primitive_desc_query( + get(), dnnl_query_impl_info_str, 0, &res), + "could not retrieve implementation info string from a " + "primitive descriptor"); + return res; + } + + /// Returns a memory::dim value (same as int64_t). + /// @param what The value to query. + /// @returns The result of the query. + memory::dim query_s64(query what) const { + memory::dim res; + dnnl_status_t status = dnnl_primitive_desc_query( + get(), dnnl::convert_to_c(what), 0, &res); + return status == dnnl_success ? res : 0; + } + + /// Returns strides. + /// @returns Strides. + /// @returns An empty #dnnl::memory::dims if the primitive does not have + /// a strides parameter. + memory::dims get_strides() const { return query_dims(query::strides); } + + /// Returns dilations. + /// @returns Dilations. + /// @returns An empty #dnnl::memory::dims if the primitive does not have + /// a dilations parameter. + memory::dims get_dilations() const { return query_dims(query::dilations); } + + /// Returns a left padding. + /// @returns A left padding. + /// @returns An empty #dnnl::memory::dims if the primitive does not have + /// a left padding parameter. + memory::dims get_padding_l() const { return query_dims(query::padding_l); } + + /// Returns a right padding. + /// @returns A right padding. + /// @returns An empty #dnnl::memory::dims if the primitive does not have + /// a right padding parameter. + memory::dims get_padding_r() const { return query_dims(query::padding_r); } + + /// Returns an epsilon. + /// @returns An epsilon. + /// @returns Zero if the primitive does not have an epsilon parameter. + float get_epsilon() const { return query_f32(query::epsilon_f32); } + + /// Returns flags. + /// @tparam T Flags enumeration type. + /// @returns Flags. + /// @returns Zero if the primitive does not have a flags parameter. + template + T get_flags() const { + unsigned res; + dnnl_status_t status + = dnnl_primitive_desc_query(get(), dnnl_query_flags, 0, &res); + return static_cast(status == dnnl_success ? res : 0x0U); + } + + /// Returns an algorithm kind. + /// @returns An algorithm kind. + /// @returns #dnnl::algorithm::undef if the primitive does not have an + /// algorithm parameter. + dnnl::algorithm get_algorithm() const { return query_alg(query::alg_kind); } + + /// Returns an alpha. + /// @returns An alpha. + /// @returns Zero if the primitive does not have an alpha parameter. + float get_alpha() const { return query_f32(query::alpha_f32); } + + /// Returns a beta. + /// @returns A beta. + /// @returns Zero if the primitive does not have a beta parameter. + float get_beta() const { return query_f32(query::beta_f32); } + + /// Returns an axis. + /// @returns An axis. + /// @returns A negative number if the primitive does not have an axis + /// parameter. + int get_axis() const { + int res; + dnnl_status_t status = dnnl_primitive_desc_query( + get(), dnnl_query_axis_s32, 0, &res); + return status == dnnl_success ? res : -1; + } + + /// Returns an LRN local size parameter. + /// @returns An LRN local size parameter. + /// @returns Zero if the primitive does not have an LRN local size + /// parameter. + memory::dim get_local_size() const { + return query_s64(query::local_size_s64); + } + + /// Returns an LRN K parameter. + /// @returns An LRN K parameter. + /// @returns Zero if the primitive does not have an LRN K parameter. + float get_k() const { return query_f32(query::k_f32); } + + /// Returns a reduction P parameter. + /// @returns A reduction P parameter. + /// @returns Zero if the primitive does not have a reduction P parameter. + float get_p() const { return query_f32(query::p_f32); } + + /// Returns a resampling factors parameters. + /// @returns A vector of factors. + /// @returns An empty vector if the primitive does not have a resampling + /// factors parameter. + std::vector get_factors() const { + float *factors; + dnnl_status_t status = dnnl_primitive_desc_query( + get(), dnnl_query_factors, 0, &factors); + + const bool is_backward = get_prop_kind() != prop_kind::forward_training + && get_prop_kind() != prop_kind::forward_inference; + const_dnnl_memory_desc_t md = dnnl_primitive_desc_query_md(get(), + is_backward ? dnnl_query_diff_dst_md : dnnl_query_dst_md, 0); + + int ndims; + error::wrap_c_api( + dnnl_memory_desc_query(md, dnnl_query_ndims_s32, &ndims), + "could not query ndims from a memory descriptor"); + + return status == dnnl_success + ? std::vector(factors, factors + (ndims - 2)) + : std::vector {}; + } + + /// Returns an RNN cell kind parameter. + /// @returns An RNN cell kind parameter. + /// @returns #dnnl::algorithm::undef if the primitive does not have an + /// RNN cell kind parameter. + dnnl::algorithm get_cell_kind() const { + return query_alg(query::cell_kind); + } + + /// Returns an RNN direction parameter. + /// @returns An RNN direction parameter. + /// @returns #dnnl::rnn_direction::undef if the primitive does not have + /// an RNN direction parameter. + dnnl::rnn_direction get_direction() const { + dnnl_rnn_direction_t direction; + dnnl_status_t status = dnnl_primitive_desc_query( + get(), dnnl_query_direction, 0, &direction); + return status == dnnl_success + ? static_cast(direction) + : dnnl::rnn_direction::undef; + } + + /// Returns an RNN activation kind parameter. + /// @returns An RNN activation kind parameter. + /// @returns #dnnl::algorithm::undef if the primitive does not have an + /// RNN activation kind parameter. + dnnl::algorithm get_activation_kind() const { + return query_alg(query::activation_kind); + } + + /// Returns a pooling kernel parameter. + /// @returns A pooling kernel parameter. + /// @returns An empty #dnnl::memory::dims if the primitive does not have + /// a pooling kernel parameter. + memory::dims get_kernel() const { return query_dims(query::kernel); } + + /// Returns a group size parameter. + /// @returns A group size parameter. + /// @returns Zero if the primitive does not have a group size + /// parameter. + memory::dim get_group_size() const { + return query_s64(query::group_size_s64); + } + + /// Returns a propagation kind. + /// @returns A propagation kind. + /// @returns #dnnl::prop_kind::undef if the primitive does not have + /// a propagation parameter. + dnnl::prop_kind get_prop_kind() const { + dnnl_prop_kind_t prop_kind; + dnnl_status_t status = dnnl_primitive_desc_query( + get(), dnnl_query_prop_kind, 0, &prop_kind); + return status == dnnl_success ? static_cast(prop_kind) + : dnnl::prop_kind::undef; + } + + /// Returns a memory descriptor. + /// + /// @note + /// There are also convenience methods + /// #dnnl::primitive_desc_base::src_desc(), + /// #dnnl::primitive_desc_base::dst_desc(), and others. + /// + /// @param what The kind of parameter to query; can be + /// #dnnl::query::src_md, #dnnl::query::dst_md, etc. + /// @param idx Index of the parameter. For example, convolution bias can + /// be queried with what = #dnnl::query::weights_md and idx = 1. + /// @returns The requested memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// parameter of the specified kind or index. + memory::desc query_md(query what, int idx = 0) const { + std::vector valid_q {query::src_md, query::diff_src_md, + query::weights_md, query::diff_weights_md, query::dst_md, + query::diff_dst_md, query::workspace_md, query::scratchpad_md, + query::exec_arg_md}; + if (!std::any_of(valid_q.cbegin(), valid_q.cend(), + [=](query q) { return what == q; })) + DNNL_THROW_ERROR(dnnl_invalid_arguments, + "memory descriptor query is invalid"); + + const_dnnl_memory_desc_t cdesc = dnnl_primitive_desc_query_md( + get(), dnnl::convert_to_c(what), idx); + if (!cdesc) return memory::desc(); + + dnnl_memory_desc_t cloned_md = nullptr; + error::wrap_c_api(dnnl_memory_desc_clone(&cloned_md, cdesc), + "could not clone a memory descriptor"); + + return memory::desc(cloned_md); + } + + /// Returns a source memory descriptor. + /// @param idx Source index. + /// @returns Source memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// source parameter with index @p idx. + memory::desc src_desc(int idx) const { + return query_md(query::src_md, idx); + } + + /// Returns a destination memory descriptor. + /// @param idx Destination index. + /// @returns Destination memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// destination parameter with index @p idx. + memory::desc dst_desc(int idx) const { + return query_md(query::dst_md, idx); + } + + /// Returns a weights memory descriptor. + /// @param idx Weights index. + /// @returns Weights memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// weights parameter with index @p idx. + memory::desc weights_desc(int idx) const { + return query_md(query::weights_md, idx); + } + + /// Returns a diff source memory descriptor. + /// @param idx Diff source index. + /// @returns Diff source memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// diff source parameter with index @p idx. + memory::desc diff_src_desc(int idx) const { + return query_md(query::diff_src_md, idx); + } + + /// Returns a diff destination memory descriptor. + /// @param idx Diff destination index. + /// @returns Diff destination memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// diff destination parameter with index @p idx. + memory::desc diff_dst_desc(int idx) const { + return query_md(query::diff_dst_md, idx); + } + + /// Returns a diff weights memory descriptor. + /// @param idx Diff weights index. + /// @returns Diff weights memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// diff weights parameter with index @p idx. + memory::desc diff_weights_desc(int idx) const { + return query_md(query::diff_weights_md, idx); + } + + // Separate versions without the index argument for documentation + // purposes. + + /// Returns a source memory descriptor. + /// @returns Source memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// source parameter. + memory::desc src_desc() const { return src_desc(0); } + + /// Returns a destination memory descriptor. + /// @returns Destination memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// destination parameter. + memory::desc dst_desc() const { return dst_desc(0); } + + /// Returns a weights memory descriptor. + /// @returns Weights memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// weights parameter. + memory::desc weights_desc() const { return weights_desc(0); } + + /// Returns a diff source memory descriptor. + /// @returns Diff source memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// diff source memory with. + memory::desc diff_src_desc() const { return diff_src_desc(0); } + + /// Returns a diff destination memory descriptor. + /// @returns Diff destination memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// diff destination parameter. + memory::desc diff_dst_desc() const { return diff_dst_desc(0); } + + /// Returns a diff weights memory descriptor. + /// @returns Diff weights memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// diff weights parameter. + memory::desc diff_weights_desc() const { return diff_weights_desc(0); } + + /// Returns the workspace memory descriptor. + /// @returns Workspace memory descriptor. + /// @returns A zero memory descriptor if the primitive does not require + /// workspace parameter. + memory::desc workspace_desc() const { + return query_md(query::workspace_md, 0); + } + + /// Returns the scratchpad memory descriptor. + /// @returns scratchpad memory descriptor. + /// @returns A zero memory descriptor if the primitive does not require + /// scratchpad parameter. + /// @sa @ref dev_guide_attributes_scratchpad + memory::desc scratchpad_desc() const { + return query_md(query::scratchpad_md, 0); + } + + /// Returns the engine on which the scratchpad memory is located. + /// @returns The engine on which the scratchpad memory is located. + engine scratchpad_engine() const { + dnnl_engine_t c_engine; + error::wrap_c_api(dnnl_primitive_desc_query(get(), + dnnl::convert_to_c(query::scratchpad_engine), + 0, &c_engine), + "could not retrieve scratchpad engine from a primitive " + "descriptor"); + return engine(c_engine, true); + } + + /// Returns the primitive attributes. + /// @returns The primitive attributes. + primitive_attr get_primitive_attr() const { + const_dnnl_primitive_attr_t const_c_attr; + error::wrap_c_api(dnnl_primitive_desc_get_attr(get(), &const_c_attr), + "could not get attributes from a primitive descriptor"); + dnnl_primitive_attr_t c_attr; + error::wrap_c_api(dnnl_primitive_attr_clone(&c_attr, const_c_attr), + "could not clone primitive attributes"); + return primitive_attr(c_attr); + } + + /// Returns the kind of the primitive descriptor. + /// @returns The kind of the primitive descriptor. + dnnl::primitive::kind get_kind() const { + dnnl_primitive_kind_t kind; + error::wrap_c_api(dnnl_primitive_desc_query(get(), + dnnl_query_primitive_kind, 0, (void *)&kind), + "could not get primitive kind from a primitive descriptor"); + return static_cast(kind); + } + + /// Returns the cache blob ID of the primitive descriptor. + /// @returns The cache blob ID of the primitive descriptor. + std::vector get_cache_blob_id() const { + dnnl_dim_t count; + const uint8_t *c_id; + error::wrap_c_api( + dnnl_primitive_desc_query(get(), + dnnl::convert_to_c(query::cache_blob_id_size_s64), 0, + (void *)&count), + "could not get size of cache blob ID from a primitive " + "descriptor"); + error::wrap_c_api(dnnl_primitive_desc_query(get(), + dnnl::convert_to_c(query::cache_blob_id), 0, + (void **)&c_id), + "could not get cache blob ID from a primitive descriptor"); + std::vector id(c_id, c_id + count); + return id; + } + +protected: + /// Returns a float value. + /// @param what The value to query. + /// @returns The result of the query. + /// @returns Zero if the primitive doesn't support the query. + float query_f32(query what) const { + float res; + dnnl_status_t status = dnnl_primitive_desc_query( + get(), dnnl::convert_to_c(what), 0, &res); + return status == dnnl_success ? res : 0.0f; + } + + /// Returns an #dnnl::algorithm value. + /// @param what The value to query. + /// @returns The result of the query. + /// @returns #dnnl::algorithm::undef if the primitive doesn't support + /// the query. + algorithm query_alg(query what) const { + dnnl_alg_kind_t res; + dnnl_status_t status = dnnl_primitive_desc_query( + get(), dnnl::convert_to_c(what), 0, &res); + return status == dnnl_success ? static_cast(res) + : algorithm::undef; + } + + /// Returns a memory::dims value. + /// @param what The value to query. + /// @returns The result of the query. + /// @returns An empty #dnnl::memory::dims if the primitive doesn't support + /// the query. + memory::dims query_dims(query what) const { + const bool is_backward = get_prop_kind() != prop_kind::forward_training + && get_prop_kind() != prop_kind::forward_inference; + const_dnnl_memory_desc_t md = dnnl_primitive_desc_query_md(get(), + is_backward ? dnnl_query_diff_dst_md : dnnl_query_dst_md, 0); + + int nspatial_dims = 0; + if (md) { + int ndims; + error::wrap_c_api( + dnnl_memory_desc_query(md, dnnl_query_ndims_s32, &ndims), + "could not query ndims from a memory descriptor"); + nspatial_dims = ndims - 2; + } + + dnnl_dims_t *c_dims; + dnnl_status_t status = dnnl_primitive_desc_query( + get(), dnnl::convert_to_c(what), 0, &c_dims); + return status == dnnl_success + ? memory::dims(*c_dims, *c_dims + nspatial_dims) + : memory::dims {}; + } + + /// Returns an #dnnl::engine value. + /// @param what The value to query. + /// @returns The result of the query. + /// @returns A weak handle to the engine that the primitive descriptor was + /// created with. + engine query_engine(query what) const { + dnnl_engine_t c_engine; + error::wrap_c_api(dnnl_primitive_desc_query(get(), + dnnl::convert_to_c(what), 0, &c_engine), + "could not get an engine from a primitive_desc"); + return engine(c_engine, true); + } + + /// Resets the value of the handle to a clone of a C API primitive + /// descriptor. + /// @param pd A C API primitive descriptor to clone. + void reset_with_clone(const_dnnl_primitive_desc_t pd) { + dnnl_primitive_desc_t new_pd; + error::wrap_c_api(dnnl_primitive_desc_clone(&new_pd, pd), + "could not clone a primitive descriptor"); + reset(new_pd); + } + + /// Constructs a primitive descriptor base object from a clone of a C API + /// primitive descriptor after verifying that it is what the caller + /// expects. + /// + /// @note + /// The @p prim_kind should map to a primitive that does not have + /// different values of propagation kind (e.g. #dnnl::binary). + /// @note + /// Primitive descriptor base constructed this way does not support + /// next_impl() (will throw). + /// + /// @param pd C API primitive descriptor to clone. + /// @param prim_kind Expected primitive kind. + primitive_desc_base( + dnnl_primitive_desc_t pd, dnnl::primitive::kind prim_kind) + : primitive_desc_base(pd, prim_kind, dnnl::prop_kind::undef) {} + + /// Constructs a primitive descriptor base object from a clone of a C API + /// primitive descriptor after verifying that it is what the caller + /// expects. + /// + /// @note + /// Primitive descriptor base constructed this way does not support + /// next_impl() (will throw). + /// + /// @param pd C API primitive descriptor to clone. + /// @param prim_kind Expected primitive kind. + /// @param aprop_kind Expected propagation kind. + primitive_desc_base(dnnl_primitive_desc_t pd, + dnnl::primitive::kind prim_kind, dnnl::prop_kind aprop_kind) + : primitive_desc_base(pd, prim_kind, aprop_kind, aprop_kind) {} + + /// Constructs a primitive descriptor base object from a clone of a C API + /// primitive descriptor after verifying that it is what the caller + /// expects. + /// + /// @note + /// Primitive descriptor base constructed this way does not support + /// next_impl() (will throw). + /// + /// @param pd C API primitive descriptor to clone. + /// @param prim_kind Expected primitive kind. + /// @param prop_kind1 Expected propagation kind (option 1). + /// @param prop_kind2 Expected propagation kind (option 2). This value is + /// checked if the check with @p prop_kind1 fails. + primitive_desc_base(dnnl_primitive_desc_t pd, + dnnl::primitive::kind prim_kind, dnnl::prop_kind prop_kind1, + dnnl::prop_kind prop_kind2) { + // It is OK to pass an empty primitive descriptor + if (pd == nullptr) return; + + dnnl_status_t rc; + + dnnl_primitive_kind_t c_prim_kind = convert_to_c(prim_kind); + dnnl_prop_kind_t c_prop_kind1 = convert_to_c(prop_kind1); + dnnl_prop_kind_t c_prop_kind2 = convert_to_c(prop_kind2); + + // Check that primitive kind matches + dnnl_primitive_kind_t pd_kind; + rc = dnnl_primitive_desc_query( + pd, dnnl_query_primitive_kind, 0, (void *)&pd_kind); + error::wrap_c_api( + rc, "could not get primitive kind from a primitive descriptor"); + if (pd_kind != c_prim_kind) + DNNL_THROW_ERROR(dnnl_invalid_arguments, + "primitive descriptor operation kind mismatch"); + + // Check that propagation kind matches + dnnl_prop_kind_t pd_prop_kind; + rc = dnnl_primitive_desc_query( + pd, dnnl_query_prop_kind, 0, (void *)&pd_prop_kind); + + // Something went wrong + if (rc != dnnl_success && rc != dnnl_unimplemented) + DNNL_THROW_ERROR(dnnl_invalid_arguments, + "could not get propagation kind from the primitive " + "descriptor"); + + // Everything is fine + if ((rc == dnnl_unimplemented && c_prop_kind1 == dnnl_prop_kind_undef) + || (rc == dnnl_success + && (pd_prop_kind == c_prop_kind1 + || pd_prop_kind == c_prop_kind2))) { + reset_with_clone(pd); + return; + } + + // We could get the propagation kind but there is a mismatch + DNNL_THROW_ERROR(dnnl_invalid_arguments, + "primitive descriptor propagation kind mismatch"); + } + + /// Returns a constant reference to a static instance of default constructed + /// primitive attributes + static const primitive_attr &default_attr() { + static const primitive_attr attr; + return attr; + } + + const_dnnl_memory_desc_t optional_arg(const memory::desc *md) { + return md ? md->get() : nullptr; + } + + const dnnl_dim_t *optional_arg(const memory::dims *dims) { + return dims ? dims->data() : nullptr; + } + + const float *optional_arg(const std::vector *arg) { + return arg ? arg->data() : nullptr; + } + + using base = primitive_desc_base; +}; + +/// @} dnnl_api_primitives_common + +/// @addtogroup dnnl_api_reorder Reorder +/// +/// A primitive to copy data between two memory objects. This primitive is +/// typically used to change the way the data is laid out in memory. +/// +/// @sa @ref dev_guide_reorder in developer guide +/// +/// @{ + +/// Reorder primitive. +struct reorder : public primitive { + /// Primitive descriptor for a reorder primitive. + struct primitive_desc : public primitive_desc_base { + using primitive_desc_base::primitive_desc_base; + + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for reorder primitive. + /// + /// @note + /// If @p allow_empty is true, the constructor does not throw if a + /// primitive descriptor cannot be created. + /// + /// @param src_engine Engine on which the source memory object will be + /// located. + /// @param src_md Source memory descriptor. + /// @param dst_engine Engine on which the destination memory object + /// will be located. + /// @param dst_md Destination memory descriptor. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is allowed + /// to fail without throwing an exception. In this case an empty + /// object will be produced. This flag is optional and defaults to + /// false. + primitive_desc(const engine &src_engine, const memory::desc &src_md, + const engine &dst_engine, const memory::desc &dst_md, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + dnnl_primitive_desc_t result; + dnnl_status_t status = dnnl_reorder_primitive_desc_create(&result, + src_md.get(), src_engine.get(), dst_md.get(), + dst_engine.get(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the reorder primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(status == dnnl_success ? result : dnnl_primitive_desc_t()); + } + + /// Constructs a primitive descriptor for reorder primitive. + /// + /// @param src Source memory object. It is used to obtain the source + /// memory descriptor and engine. + /// @param dst Destination memory object. It is used to obtain the + /// destination memory descriptor and engine. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is allowed + /// to fail without throwing an exception. In this case an empty + /// object will be produced. This flag is optional and defaults to + /// false. + primitive_desc(const memory &src, const memory &dst, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + dnnl_primitive_desc_t result; + auto src_md = src.get_desc(); + auto dst_md = dst.get_desc(); + dnnl_status_t status = dnnl_reorder_primitive_desc_create(&result, + src_md.get(), src.get_engine().get(), dst_md.get(), + dst.get_engine().get(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the reorder primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(status == dnnl_success ? result : dnnl_primitive_desc_t()); + } + + /// Constructs a primitive descriptor for reorder primitive from a C + /// API primitive descriptor which must have a matching kind. + /// + /// @param pd C API primitive descriptor for reorder primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : primitive_desc_base(pd, dnnl::primitive::kind::reorder) {} + + /// Returns the engine on which the source memory is allocated. + /// @returns The engine on which the source memory is allocated. + engine get_src_engine() const { + return query_engine(dnnl::query::reorder_src_engine); + } + + /// Returns the engine on which the destination memory is allocated. + /// @returns The engine on which the destination memory is allocated. + engine get_dst_engine() const { + return query_engine(dnnl::query::reorder_dst_engine); + } + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + }; + + /// Default constructor. Produces an empty object. + reorder() = default; + + /// Constructs a reorder primitive. + /// @param pd Primitive descriptor for reorder primitive. + reorder(const primitive_desc &pd) : primitive(pd.get()) {} + + /// Constructs a reorder primitive from a cache blob. + /// @param pd Primitive descriptor for reorder primitive. + /// @param cache_blob Cache blob. + reorder(const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd.get(), cache_blob) {} + + /// Constructs a reorder primitive that would reorder data between memory + /// objects having the same memory descriptors as memory objects @p src and + /// @p dst. + /// + /// @param src Source memory object. + /// @param dst Destination memory object. + /// @param attr Primitive attributes to use (optional). + reorder(const memory &src, const memory &dst, + const primitive_attr &attr = primitive_attr()) + : primitive(primitive_desc(src, dst, attr).get()) {} + + using primitive::execute; + + /// Executes the reorder primitive. + /// + /// @param astream Stream object. The stream must belong to the same engine + /// as the primitive. + /// @param src Source memory object. + /// @param dst Destination memory object. + void execute(const stream &astream, memory &src, memory &dst) const { + primitive::execute(astream, {{DNNL_ARG_FROM, src}, {DNNL_ARG_TO, dst}}); + } +}; + +/// @} dnnl_api_reorder + +/// @addtogroup dnnl_api_concat Concat +/// +/// A primitive to concatenate data by arbitrary dimension. +/// +/// @sa @ref dev_guide_concat in developer guide +/// +/// @{ + +/// @cond DO_NOT_DOCUMENT_THIS +inline std::vector convert_to_c( + const std::vector &mds) { + std::vector c_mds; + c_mds.reserve(mds.size()); + for (const auto &md : mds) + c_mds.push_back(md.get()); + return c_mds; +} +/// @endcond + +/// Tensor concatenation (concat) primitive. +struct concat : public primitive { + /// Primitive descriptor for a concat primitive. + struct primitive_desc : public primitive_desc_base { + using primitive_desc_base::primitive_desc_base; + + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an out-of-place concatenation + /// primitive. + /// + /// @param aengine Engine to perform the operation on. + /// @param dst Destination memory descriptor. + /// @param concat_dimension Source tensors will be concatenated over + /// dimension with this index. Note that order of dimensions does + /// not depend on memory format. + /// @param srcs Vector of source memory descriptors. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const memory::desc &dst, + int concat_dimension, const std::vector &srcs, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + auto c_srcs = convert_to_c(srcs); + + dnnl_primitive_desc_t result; + dnnl_status_t status = dnnl_concat_primitive_desc_create(&result, + aengine.get(), dst.get(), (int)c_srcs.size(), + concat_dimension, c_srcs.data(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the concat primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(status == dnnl_success ? result : dnnl_primitive_desc_t()); + } + + /// Constructs a primitive descriptor for an out-of-place concatenation + /// primitive. + /// + /// This version derives the destination memory descriptor + /// automatically. + /// + /// @param aengine Engine to perform the operation on. + /// @param concat_dimension Source tensors will be concatenated over + /// dimension with this index. Note that order of dimensions does + /// not depend on memory format. + /// @param srcs Vector of source memory descriptors. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, int concat_dimension, + const std::vector &srcs, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + auto c_api_srcs = convert_to_c(srcs); + + dnnl_primitive_desc_t result; + dnnl_status_t status = dnnl_concat_primitive_desc_create(&result, + aengine.get(), nullptr, (int)c_api_srcs.size(), + concat_dimension, c_api_srcs.data(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the concat primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(status == dnnl_success ? result : dnnl_primitive_desc_t()); + } + + /// Constructs a primitive descriptor for concat primitive from a C + /// API primitive descriptor which must have a matching kind. + /// + /// @param pd C API primitive descriptor for concat primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : primitive_desc_base(pd, dnnl::primitive::kind::concat) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc(int)const + memory::desc src_desc(int idx = 0) const { return base::src_desc(idx); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + }; + + /// Default constructor. Produces an empty object. + concat() = default; + + /// Constructs a concatenation primitive. + /// @param pd Primitive descriptor for concatenation primitive. + concat(const primitive_desc &pd) : primitive(pd.get()) {} + + /// Constructs a concatenation primitive from a cache blob. + /// @param pd Primitive descriptor for concatenation primitive. + /// @param cache_blob Cache blob. + concat(const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd.get(), cache_blob) {} +}; + +/// @} dnnl_api_concat + +/// @addtogroup dnnl_api_sum Sum +/// +/// A primitive to sum multiple tensors. +/// +/// @sa @ref dev_guide_sum in developer guide +/// +/// @{ + +/// Out-of-place summation (sum) primitive. +struct sum : public primitive { + /// Primitive descriptor for a sum primitive. + struct primitive_desc : public primitive_desc_base { + using primitive_desc_base::primitive_desc_base; + + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a sum primitive. + /// + /// @param aengine Engine to perform the operation on. + /// @param dst Destination memory descriptor. + /// @param scales Vector of scales to multiply data in each source + /// memory by. + /// @param srcs Vector of source memory descriptors. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const memory::desc &dst, + const std::vector &scales, + const std::vector &srcs, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + validate_container_size(scales, + "counts of scales and sources are not equal", + (int)srcs.size(), (int)srcs.size()); + + auto c_api_srcs = convert_to_c(srcs); + + dnnl_primitive_desc_t result; + dnnl_status_t status = dnnl_sum_primitive_desc_create(&result, + aengine.get(), dst.get(), (int)c_api_srcs.size(), + scales.data(), c_api_srcs.data(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the sum primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(status == dnnl_success ? result : dnnl_primitive_desc_t()); + } + + /// Constructs a primitive descriptor for a sum primitive. + /// + /// This version derives the destination memory descriptor + /// automatically. + /// + /// @param aengine Engine on which to perform the operation. + /// @param scales Vector of scales by which to multiply data in each + /// source memory object. + /// @param srcs Vector of source memory descriptors. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const std::vector &scales, + const std::vector &srcs, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + validate_container_size(scales, + "counts of scales and sources are not equal", + (int)srcs.size(), (int)srcs.size()); + + auto c_api_srcs = convert_to_c(srcs); + dnnl_primitive_desc_t result; + dnnl_status_t status = dnnl_sum_primitive_desc_create(&result, + aengine.get(), nullptr, (int)c_api_srcs.size(), + scales.data(), c_api_srcs.data(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the sum primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(status == dnnl_success ? result : dnnl_primitive_desc_t()); + } + + /// Constructs a primitive descriptor for sum primitive from a C API + /// primitive descriptor which must have a matching kind. + /// + /// @param pd C API primitive descriptor for sum primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : primitive_desc_base(pd, dnnl::primitive::kind::sum) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc(int)const + memory::desc src_desc(int idx = 0) const { return base::src_desc(idx); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + }; + + /// Default constructor. Produces an empty object. + sum() = default; + + /// Constructs a sum primitive. + /// @param pd Primitive descriptor for sum primitive. + sum(const primitive_desc &pd) : primitive(pd.get()) {} + + /// Constructs a sum primitive from a cache blob. + /// @param pd Primitive descriptor for sum primitive. + /// @param cache_blob Cache blob. + sum(const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd.get(), cache_blob) {} +}; + +/// @} dnnl_api_sum + +/// @addtogroup dnnl_api_primitives_common +/// @{ + +/// A base class for descriptors of all primitives that support iteration +/// over multiple implementations. +struct primitive_desc : public primitive_desc_base { + using primitive_desc_base::primitive_desc_base; + + primitive_desc() = default; + + /// Changes the primitive descriptor to point to the next available + /// implementation. + /// + /// @returns @c true on success and @c false if the last available + /// implementation has already been reached. In the latter case, the + /// primitive descriptor itself is kept unchanged. + bool next_impl() { + dnnl_status_t status = dnnl_primitive_desc_next_impl(get()); + if (status == dnnl_last_impl_reached) return false; + error::wrap_c_api(status, "last available implementation is reached"); + return true; + } +}; + +/// @} dnnl_api_primitives_common + +/// @addtogroup dnnl_api_convolution Convolution +/// +/// A primitive to perform 1D, 2D or 3D convolution. Supported variants are +/// forward propagation, backward propagation, and weights gradient with or +/// without bias. +/// +/// @sa @ref dev_guide_convolution in developer guide +/// +/// @{ + +/// Convolution forward propagation primitive. +struct convolution_forward : public primitive { + /// Primitive descriptor for a convolution forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a convolution forward + /// propagation primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param src_desc Source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param bias_desc Bias memory descriptor. Passing zero memory + /// descriptor disables the bias term. + /// @param dst_desc Destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &bias_desc, + const memory::desc &dst_desc, const memory::dims &strides, + const memory::dims &padding_l, const memory::dims &padding_r, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + weights_desc, &bias_desc, dst_desc, strides, nullptr, + padding_l, padding_r, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution forward + /// propagation primitive without bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param src_desc Source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &dst_desc, + const memory::dims &strides, const memory::dims &padding_l, + const memory::dims &padding_r, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + weights_desc, nullptr, dst_desc, strides, nullptr, + padding_l, padding_r, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution forward + /// propagation primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param src_desc Source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param bias_desc Bias memory descriptor. Passing zero memory + /// descriptor disables the bias term. + /// @param dst_desc Destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &bias_desc, + const memory::desc &dst_desc, const memory::dims &strides, + const memory::dims &dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + weights_desc, &bias_desc, dst_desc, strides, &dilates, + padding_l, padding_r, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution forward + /// propagation primitive without bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param src_desc Source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &dst_desc, + const memory::dims &strides, const memory::dims &dilates, + const memory::dims &padding_l, const memory::dims &padding_r, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + weights_desc, nullptr, dst_desc, strides, &dilates, + padding_l, padding_r, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution forward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a convolution forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::convolution, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// Returns the bias memory descriptor. + /// @returns The bias memory descriptor. + /// @returns A zero memory descriptor of the primitive does not have a + /// bias parameter. + memory::desc bias_desc() const { return base::weights_desc(1); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_strides()const + memory::dims get_strides() const { return base::get_strides(); } + + /// @copydoc dnnl::primitive_desc_base::get_dilations()const + memory::dims get_dilations() const { return base::get_dilations(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_l()const + memory::dims get_padding_l() const { return base::get_padding_l(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_r()const + memory::dims get_padding_r() const { return base::get_padding_r(); } + + private: + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc *bias_desc, + const memory::desc &dst_desc, const memory::dims &strides, + const memory::dims *dilates, const memory::dims &padding_l, + const memory::dims &padding_r, const primitive_attr &attr, + bool allow_empty) { + + memory::validate_dims(strides, src_desc.get_ndims() - 2); + memory::validate_dims(padding_l, src_desc.get_ndims() - 2); + memory::validate_dims(padding_r, src_desc.get_ndims() - 2); + + if (dilates) + memory::validate_dims(*dilates, src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_convolution_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + convert_to_c(aalgorithm), src_desc.get(), + weights_desc.get(), optional_arg(bias_desc), + dst_desc.get(), &strides[0], optional_arg(dilates), + &padding_l[0], &padding_r[0], attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the convolution forward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + convolution_forward() = default; + + /// Constructs a convolution forward propagation primitive. + /// @param pd Primitive descriptor for a convolution forward propagation + /// primitive. + convolution_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a convolution forward propagation primitive from a cache + /// blob. + /// @param pd Primitive descriptor for a convolution forward propagation + /// primitive. + /// @param cache_blob Cache blob. + convolution_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Convolution backward propagation primitive. +struct convolution_backward_data : public primitive { + /// Primitive descriptor for a convolution backward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a convolution backward + /// propagation primitive. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param diff_src_desc Diff source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a convolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &padding_l, const memory::dims &padding_r, + const convolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, diff_src_desc, weights_desc, + diff_dst_desc, strides, nullptr, padding_l, padding_r, + hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution backward + /// propagation primitive. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param diff_src_desc Diff source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a convolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const convolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, diff_src_desc, weights_desc, + diff_dst_desc, strides, &dilates, padding_l, padding_r, + hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a convolution backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::convolution, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_strides()const + memory::dims get_strides() const { return base::get_strides(); } + + /// @copydoc dnnl::primitive_desc_base::get_dilations()const + memory::dims get_dilations() const { return base::get_dilations(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_l()const + memory::dims get_padding_l() const { return base::get_padding_l(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_r()const + memory::dims get_padding_r() const { return base::get_padding_r(); } + + private: + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims *dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const convolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr, bool allow_empty) { + + memory::validate_dims(strides, diff_src_desc.get_ndims() - 2); + memory::validate_dims(padding_l, diff_src_desc.get_ndims() - 2); + memory::validate_dims(padding_r, diff_src_desc.get_ndims() - 2); + + if (dilates) + memory::validate_dims(*dilates, diff_src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_convolution_backward_data_primitive_desc_create(&pd, + aengine.get(), convert_to_c(aalgorithm), + diff_src_desc.get(), weights_desc.get(), + diff_dst_desc.get(), &strides[0], + optional_arg(dilates), &padding_l[0], &padding_r[0], + hint_fwd_pd.get(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the convolution backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + convolution_backward_data() = default; + + /// Constructs a convolution backward propagation primitive. + /// @param pd Primitive descriptor for a convolution backward propagation + /// primitive. + convolution_backward_data(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a convolution backward propagation primitive from a cache + /// blob. + /// @param pd Primitive descriptor for a convolution backward propagation + /// primitive. + /// @param cache_blob Cache blob. + convolution_backward_data( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Convolution weights gradient primitive. +struct convolution_backward_weights : public primitive { + /// Primitive descriptor for a convolution weights gradient primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a convolution weights gradient + /// primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param src_desc Source memory descriptor. + /// @param diff_weights_desc Diff weights memory descriptor. + /// @param diff_bias_desc Diff bias memory descriptor. Passing zero + /// memory descriptor disables the bias term. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a convolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &padding_l, const memory::dims &padding_r, + const convolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, src_desc, diff_weights_desc, + &diff_bias_desc, diff_dst_desc, strides, nullptr, + padding_l, padding_r, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution weights gradient + /// primitive without bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param src_desc Source memory descriptor. + /// @param diff_weights_desc Diff weights memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a convolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &padding_l, const memory::dims &padding_r, + const convolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, src_desc, diff_weights_desc, + nullptr, diff_dst_desc, strides, nullptr, padding_l, + padding_r, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution weights + /// gradient primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param src_desc Source memory descriptor. + /// @param diff_weights_desc Diff weights memory descriptor. + /// @param diff_bias_desc Diff bias memory descriptor. Passing zero + /// memory descriptor disables the bias term. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a convolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const convolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, src_desc, diff_weights_desc, + &diff_bias_desc, diff_dst_desc, strides, &dilates, + padding_l, padding_r, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution weights + /// gradient primitive without bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Convolution algorithm. Possible values are + /// #dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd, and + /// #dnnl::algorithm::convolution_auto. + /// @param src_desc Source memory descriptor. + /// @param diff_weights_desc Diff weights memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a convolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const convolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, src_desc, diff_weights_desc, + nullptr, diff_dst_desc, strides, &dilates, padding_l, + padding_r, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a convolution weights gradient + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for a convolution weights + /// gradient primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::convolution, + dnnl::prop_kind::backward_weights) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_weights_desc()const + memory::desc diff_weights_desc() const { + return base::diff_weights_desc(0); + } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// Returns the diff bias memory descriptor. + /// @returns The diff bias memory descriptor. + /// @returns A zero memory descriptor of the primitive does not have a + /// diff bias parameter. + memory::desc diff_bias_desc() const { + return base::diff_weights_desc(1); + } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_strides()const + memory::dims get_strides() const { return base::get_strides(); } + + /// @copydoc dnnl::primitive_desc_base::get_dilations()const + memory::dims get_dilations() const { return base::get_dilations(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_l()const + memory::dims get_padding_l() const { return base::get_padding_l(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_r()const + memory::dims get_padding_r() const { return base::get_padding_r(); } + + private: + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc *diff_bias_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims *dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const convolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr, bool allow_empty) { + + memory::validate_dims(strides, src_desc.get_ndims() - 2); + memory::validate_dims(padding_l, src_desc.get_ndims() - 2); + memory::validate_dims(padding_r, src_desc.get_ndims() - 2); + + if (dilates) + memory::validate_dims(*dilates, src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_convolution_backward_weights_primitive_desc_create( + &pd, aengine.get(), convert_to_c(aalgorithm), + src_desc.get(), diff_weights_desc.get(), + optional_arg(diff_bias_desc), diff_dst_desc.get(), + &strides[0], optional_arg(dilates), &padding_l[0], + &padding_r[0], hint_fwd_pd.get(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the convolution weights update primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + convolution_backward_weights() = default; + + /// Constructs a convolution weights gradient primitive. + /// @param pd Primitive descriptor for a convolution weights gradient + /// primitive. + convolution_backward_weights(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a convolution weights gradient primitive from a cache blob. + /// @param pd Primitive descriptor for a convolution weights gradient + /// primitive. + /// @param cache_blob Cache blob. + convolution_backward_weights( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_convolution +// +/// @addtogroup dnnl_api_deconvolution Deconvolution +/// +/// A primitive to perform 1D, 2D or 3D deconvolution. Supported variants are +/// forward propagation, backward propagation, and weights gradient with or +/// without bias. +/// +/// @{ + +/// Deconvolution forward propagation primitive. +struct deconvolution_forward : public primitive { + /// Primitive descriptor for a deconvolution forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a deconvolution forward + /// propagation primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Deconvolution algorithm: + /// #dnnl::algorithm::deconvolution_direct, and + /// #dnnl::algorithm::deconvolution_winograd. + /// @param src_desc Source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param bias_desc Bias memory descriptor. Passing zero memory + /// descriptor disables the bias term. + /// @param dst_desc Destination memory descriptor. + /// @param strides Vector of strides for spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &bias_desc, + const memory::desc &dst_desc, const memory::dims &strides, + const memory::dims &padding_l, const memory::dims &padding_r, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + weights_desc, &bias_desc, dst_desc, strides, nullptr, + padding_l, padding_r, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution forward + /// propagation primitive without bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Deconvolution algorithm: + /// #dnnl::algorithm::deconvolution_direct, and + /// #dnnl::algorithm::deconvolution_winograd. + /// @param src_desc Source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param strides Vector of strides for spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &dst_desc, + const memory::dims &strides, const memory::dims &padding_l, + const memory::dims &padding_r, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + weights_desc, nullptr, dst_desc, strides, nullptr, + padding_l, padding_r, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution forward + /// propagation primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Deconvolution algorithm: + /// #dnnl::algorithm::deconvolution_direct, and + /// #dnnl::algorithm::deconvolution_winograd. + /// @param src_desc Source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param bias_desc Bias memory descriptor. Passing zero memory + /// descriptor disables the bias term. + /// @param dst_desc Destination memory descriptor. + /// @param strides Vector of strides for spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &bias_desc, + const memory::desc &dst_desc, const memory::dims &strides, + const memory::dims &dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + weights_desc, &bias_desc, dst_desc, strides, &dilates, + padding_l, padding_r, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution forward + /// propagation primitive without bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Deconvolution algorithm: + /// #dnnl::algorithm::deconvolution_direct, and + /// #dnnl::algorithm::deconvolution_winograd. + /// @param src_desc Source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param strides Vector of strides for spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &dst_desc, + const memory::dims &strides, const memory::dims &dilates, + const memory::dims &padding_l, const memory::dims &padding_r, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + weights_desc, nullptr, dst_desc, strides, &dilates, + padding_l, padding_r, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution forward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a deconvolution forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::deconvolution, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::convolution_forward::primitive_desc::bias_desc()const + memory::desc bias_desc() const { return base::weights_desc(1); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_strides()const + memory::dims get_strides() const { return base::get_strides(); } + + /// @copydoc dnnl::primitive_desc_base::get_dilations()const + memory::dims get_dilations() const { return base::get_dilations(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_l()const + memory::dims get_padding_l() const { return base::get_padding_l(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_r()const + memory::dims get_padding_r() const { return base::get_padding_r(); } + + private: + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc *bias_desc, + const memory::desc &dst_desc, const memory::dims &strides, + const memory::dims *dilates, const memory::dims &padding_l, + const memory::dims &padding_r, const primitive_attr &attr, + bool allow_empty) { + + memory::validate_dims(strides, src_desc.get_ndims() - 2); + memory::validate_dims(padding_l, src_desc.get_ndims() - 2); + memory::validate_dims(padding_r, src_desc.get_ndims() - 2); + + if (dilates) + memory::validate_dims(*dilates, src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_deconvolution_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + convert_to_c(aalgorithm), src_desc.get(), + weights_desc.get(), optional_arg(bias_desc), + dst_desc.get(), &strides[0], optional_arg(dilates), + &padding_l[0], &padding_r[0], attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the deconvolution forward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + deconvolution_forward() = default; + + /// Constructs a deconvolution forward propagation primitive. + /// @param pd Primitive descriptor for a deconvolution forward propagation + /// primitive. + deconvolution_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a deconvolution forward propagation primitive from a cache + /// blob. + /// @param pd Primitive descriptor for a deconvolution forward propagation + /// primitive. + /// @param cache_blob Cache blob. + deconvolution_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Deconvolution backward propagation primitive. +struct deconvolution_backward_data : public primitive { + /// Primitive descriptor for a deconvolution backward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a deconvolution backward + /// propagation primitive. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Deconvolution algorithm + /// (#dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd). + /// @param diff_src_desc Diff source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a deconvolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &padding_l, const memory::dims &padding_r, + const deconvolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, diff_src_desc, weights_desc, + diff_dst_desc, strides, nullptr, padding_l, padding_r, + hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution backward + /// propagation primitive. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Deconvolution algorithm + /// (#dnnl::algorithm::convolution_direct, + /// #dnnl::algorithm::convolution_winograd). + /// @param diff_src_desc Diff source memory descriptor. + /// @param weights_desc Weights memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a deconvolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const deconvolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, diff_src_desc, weights_desc, + diff_dst_desc, strides, &dilates, padding_l, padding_r, + hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a deconvolution backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::deconvolution, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_strides()const + memory::dims get_strides() const { return base::get_strides(); } + + /// @copydoc dnnl::primitive_desc_base::get_dilations()const + memory::dims get_dilations() const { return base::get_dilations(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_l()const + memory::dims get_padding_l() const { return base::get_padding_l(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_r()const + memory::dims get_padding_r() const { return base::get_padding_r(); } + + private: + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims *dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const deconvolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr, bool allow_empty) { + + memory::validate_dims(strides, diff_src_desc.get_ndims() - 2); + memory::validate_dims(padding_l, diff_src_desc.get_ndims() - 2); + memory::validate_dims(padding_r, diff_src_desc.get_ndims() - 2); + + if (dilates) + memory::validate_dims(*dilates, diff_src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_deconvolution_backward_data_primitive_desc_create( + &pd, aengine.get(), convert_to_c(aalgorithm), + diff_src_desc.get(), weights_desc.get(), + diff_dst_desc.get(), &strides[0], + optional_arg(dilates), &padding_l[0], &padding_r[0], + hint_fwd_pd.get(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the deconvolution backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + deconvolution_backward_data() = default; + + /// Constructs a deconvolution backward propagation primitive. + /// @param pd Primitive descriptor for a deconvolution backward propagation + /// primitive. + deconvolution_backward_data(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a deconvolution backward propagation primitive from a cache + /// blob. + /// @param pd Primitive descriptor for a deconvolution backward propagation + /// primitive. + /// @param cache_blob Cache blob. + deconvolution_backward_data( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Deconvolution weights gradient primitive. +struct deconvolution_backward_weights : public primitive { + /// Primitive descriptor for a deconvolution weights gradient primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a deconvolution weights + /// gradient primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Deconvolution algorithm. Possible values are + /// #dnnl::algorithm::deconvolution_direct, and + /// #dnnl::algorithm::deconvolution_winograd. + /// @param src_desc Source memory descriptor. + /// @param diff_weights_desc Diff weights memory descriptor. + /// @param diff_bias_desc Diff bias memory descriptor. Passing zero + /// memory descriptor disables the bias term. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a deconvolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &padding_l, const memory::dims &padding_r, + const deconvolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, src_desc, diff_weights_desc, + &diff_bias_desc, diff_dst_desc, strides, nullptr, + padding_l, padding_r, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution weights + /// gradient primitive without bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p padding_l, and @p padding_r contain values + /// for spatial dimensions only and hence must have the same number of + /// elements as there are spatial dimensions. The order of values is + /// the same as in the tensor: depth (for 3D tensors), height (for 3D + /// and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Deconvolution algorithm. Possible values are + /// #dnnl::algorithm::deconvolution_direct, and + /// #dnnl::algorithm::deconvolution_winograd. + /// @param src_desc Source memory descriptor. + /// @param diff_weights_desc Diff weights memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a deconvolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &padding_l, const memory::dims &padding_r, + const deconvolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, src_desc, diff_weights_desc, + nullptr, diff_dst_desc, strides, nullptr, padding_l, + padding_r, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution weights + /// gradient primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Deconvolution algorithm. Possible values are + /// #dnnl::algorithm::deconvolution_direct, and + /// #dnnl::algorithm::deconvolution_winograd. + /// @param src_desc Source memory descriptor. + /// @param diff_weights_desc Diff weights memory descriptor. + /// @param diff_bias_desc Diff bias memory descriptor. Passing zero + /// memory descriptor disables the bias term. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a deconvolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const deconvolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, src_desc, diff_weights_desc, + &diff_bias_desc, diff_dst_desc, strides, &dilates, + padding_l, padding_r, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution weights + /// gradient primitive without bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// Arrays @p strides, @p dilates, @p padding_l, and @p padding_r + /// contain values for spatial dimensions only and hence must have the + /// same number of elements as there are spatial dimensions. The order + /// of values is the same as in the tensor: depth (for 3D tensors), + /// height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Deconvolution algorithm. Possible values are + /// #dnnl::algorithm::deconvolution_direct, and + /// #dnnl::algorithm::deconvolution_winograd. + /// @param src_desc Source memory descriptor. + /// @param diff_weights_desc Diff weights memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Strides for each spatial dimension. + /// @param dilates Dilations for each spatial dimension. A zero value + /// means no dilation in the corresponding dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a deconvolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const deconvolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, src_desc, diff_weights_desc, + nullptr, diff_dst_desc, strides, &dilates, padding_l, + padding_r, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a deconvolution weights + /// gradient primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a deconvolution weights + /// gradient primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::deconvolution, + dnnl::prop_kind::backward_weights) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_weights_desc()const + memory::desc diff_weights_desc() const { + return base::diff_weights_desc(0); + } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::convolution_backward_weights::primitive_desc::diff_bias_desc()const + memory::desc diff_bias_desc() const { + return base::diff_weights_desc(1); + } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_strides()const + memory::dims get_strides() const { return base::get_strides(); } + + /// @copydoc dnnl::primitive_desc_base::get_dilations()const + memory::dims get_dilations() const { return base::get_dilations(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_l()const + memory::dims get_padding_l() const { return base::get_padding_l(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_r()const + memory::dims get_padding_r() const { return base::get_padding_r(); } + + private: + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc *diff_bias_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims *dilates, const memory::dims &padding_l, + const memory::dims &padding_r, + const deconvolution_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr, bool allow_empty) { + + memory::validate_dims(strides, src_desc.get_ndims() - 2); + memory::validate_dims(padding_l, src_desc.get_ndims() - 2); + memory::validate_dims(padding_r, src_desc.get_ndims() - 2); + + if (dilates) + memory::validate_dims(*dilates, src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_deconvolution_backward_weights_primitive_desc_create( + &pd, aengine.get(), convert_to_c(aalgorithm), + src_desc.get(), diff_weights_desc.get(), + optional_arg(diff_bias_desc), diff_dst_desc.get(), + &strides[0], optional_arg(dilates), &padding_l[0], + &padding_r[0], hint_fwd_pd.get(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the deconvolution weights update primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + deconvolution_backward_weights() = default; + + /// Constructs a deconvolution weights gradient primitive. + /// @param pd Primitive descriptor for a deconvolution weights gradient + /// primitive. + deconvolution_backward_weights(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a deconvolution weights gradient primitive from a cache + /// blob. + /// @param pd Primitive descriptor for a deconvolution weights gradient + /// primitive. + /// @param cache_blob Cache blob. + deconvolution_backward_weights( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_deconvolution + +/// @addtogroup dnnl_api_lrn LRN +/// +/// A primitive to perform local response normalization (LRN) across or within +/// channels. +/// +/// @sa @ref dev_guide_lrn in developer guide +/// +/// @{ + +/// Local response normalization (LRN) forward propagation primitive. +struct lrn_forward : public primitive { + /// Primitive descriptor for an LRN forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an LRN forward propagation + /// primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm LRN algorithm kind: either + /// #dnnl::algorithm::lrn_across_channels, or + /// #dnnl::algorithm::lrn_within_channel. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param local_size Regularization local size. + /// @param alpha The alpha regularization parameter. + /// @param beta The beta regularization parameter. + /// @param k The k regularization parameter. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &dst_desc, memory::dim local_size, + float alpha, float beta, float k, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_lrn_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + convert_to_c(aalgorithm), src_desc.get(), dst_desc.get(), + local_size, alpha, beta, k, attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the lrn forward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for an LRN forward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for an LRN forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::lrn, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_alpha()const + float get_alpha() const { return base::get_alpha(); } + + /// @copydoc dnnl::primitive_desc_base::get_beta()const + float get_beta() const { return base::get_beta(); } + + /// @copydoc dnnl::primitive_desc_base::get_local_size()const + memory::dim get_local_size() const { return base::get_local_size(); } + + /// @copydoc dnnl::primitive_desc_base::get_k()const + float get_k() const { return base::get_k(); } + }; + + /// Default constructor. Produces an empty object. + lrn_forward() = default; + + /// Constructs an LRN forward propagation primitive. + /// @param pd Primitive descriptor for an LRN forward propagation + /// primitive. + lrn_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an LRN forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an LRN forward propagation + /// primitive. + /// @param cache_blob Cache blob. + lrn_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Local response normalization (LRN) backward propagation primitive. +struct lrn_backward : public primitive { + /// Primitive descriptor for an LRN backward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an LRN backward propagation + /// primitive. + /// + /// @param aengine Engine to use. + /// @param aalgorithm LRN algorithm kind: either + /// #dnnl::algorithm::lrn_across_channels, or + /// #dnnl::algorithm::lrn_within_channel. + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param src_desc Source memory descriptor. + /// @param local_size Regularization local size. + /// @param alpha The alpha regularization parameter. + /// @param beta The beta regularization parameter. + /// @param k The k regularization parameter. + /// @param hint_fwd_pd Primitive descriptor for an LRN forward + /// propagation primitive. It is used as a hint for deciding which + /// memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::desc &src_desc, + memory::dim local_size, float alpha, float beta, float k, + const lrn_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_lrn_backward_primitive_desc_create(&pd, + aengine.get(), convert_to_c(aalgorithm), + diff_src_desc.get(), diff_dst_desc.get(), src_desc.get(), + local_size, alpha, beta, k, hint_fwd_pd.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the lrn backward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for an LRN backward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for an LRN backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::lrn, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_alpha()const + float get_alpha() const { return base::get_alpha(); } + + /// @copydoc dnnl::primitive_desc_base::get_beta()const + float get_beta() const { return base::get_beta(); } + + /// @copydoc dnnl::primitive_desc_base::get_local_size()const + memory::dim get_local_size() const { return base::get_local_size(); } + + /// @copydoc dnnl::primitive_desc_base::get_k()const + float get_k() const { return base::get_k(); } + }; + + /// Default constructor. Produces an empty object. + lrn_backward() = default; + + /// Constructs an LRN backward propagation primitive. + /// @param pd Primitive descriptor for an LRN backward propagation + /// primitive. + lrn_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an LRN backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an LRN backward propagation + /// primitive. + /// @param cache_blob Cache blob. + lrn_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_lrn + +/// @addtogroup dnnl_api_eltwise Eltwise +/// +/// A primitive to perform elementwise operations such as the +/// rectifier linear unit (ReLU). +/// +/// Both forward and backward propagation primitives support in-place +/// operation; that is, src and dst can refer to the same memory for forward +/// propagation, and diff_dst and diff_src can refer to the same memory for +/// backward propagation. +/// +/// @warning +/// Because the original source data is required for backward propagation, +/// in-place forward propagation is not generally supported in the +/// training mode. However, for algorithms supporting destination as input +/// memory, dst can be used for the backward propagation, which makes it +/// possible to get performance benefit even in the training mode. +/// +/// @sa @ref dev_guide_eltwise in developer guide +/// +/// @{ + +/// Elementwise unary operation forward propagation primitive. +struct eltwise_forward : public primitive { + /// Primitive descriptor for an elementwise forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an elementwise forward + /// propagation primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Elementwise algorithm kind. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &dst_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + dst_desc, nullptr, nullptr, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an elementwise forward + /// propagation primitive with an alpha parameter. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Elementwise algorithm kind. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param alpha The alpha parameter for the elementwise operation. + /// Specific meaning depends on the algorithm. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &dst_desc, float alpha, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + dst_desc, &alpha, nullptr, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an elementwise forward + /// propagation primitive with an alpha and beta parameters. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Elementwise algorithm kind. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param alpha The alpha parameter for the elementwise operation. + /// Specific meaning depends on the algorithm. + /// @param beta The beta parameter for the elementwise operation. + /// Specific meaning depends on the algorithm. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &dst_desc, float alpha, float beta, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, src_desc, + dst_desc, &alpha, &beta, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an eltwise forward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for an eltwise forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::eltwise, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + dnnl::algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_alpha()const + float get_alpha() const { return base::get_alpha(); } + + /// @copydoc dnnl::primitive_desc_base::get_beta()const + float get_beta() const { return base::get_beta(); } + + private: + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &dst_desc, const float *alpha, + const float *beta, const primitive_attr &attr, + bool allow_empty) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_eltwise_forward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(aalgorithm), src_desc.get(), + dst_desc.get(), alpha ? *alpha : 0.0f, beta ? *beta : 0.0f, + attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the eltwise forward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + eltwise_forward() = default; + + /// Constructs an eltwise forward propagation primitive. + /// @param pd Primitive descriptor for an eltwise forward propagation + /// primitive. + eltwise_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an eltwise forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an eltwise forward propagation + /// primitive. + /// @param cache_blob Cache blob. + eltwise_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Elementwise unary operation backward propagation primitive. +struct eltwise_backward : public primitive { + /// Primitive descriptor for eltwise backward propagation. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an elementwise backward + /// propagation primitive with an alpha parameter. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Elementwise algorithm kind. + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param data_desc Destination memory descriptor if one of the + /// "use_dst_for_bwd" algorithms are used (such as + /// #dnnl_eltwise_relu_use_dst_for_bwd), source memory descriptor + /// otherwise. + /// @param hint_fwd_pd Primitive descriptor for an elementwise + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, + const memory::desc &data_desc, + const eltwise_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, diff_src_desc, diff_dst_desc, + data_desc, nullptr, nullptr, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for an elementwise backward + /// propagation primitive with an alpha parameter. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Elementwise algorithm kind. + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param data_desc Destination memory descriptor if one of the + /// "use_dst_for_bwd" algorithms are used (such as + /// #dnnl_eltwise_relu_use_dst_for_bwd), source memory descriptor + /// otherwise. + /// @param alpha The alpha parameter for the elementwise operation. + /// Specific meaning depends on the algorithm. + /// @param hint_fwd_pd Primitive descriptor for an elementwise + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, + const memory::desc &data_desc, float alpha, + const eltwise_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, diff_src_desc, diff_dst_desc, + data_desc, &alpha, nullptr, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for an elementwise backward + /// propagation primitive with an alpha and beta parameters. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Elementwise algorithm kind. + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param data_desc Destination memory descriptor if one of the + /// "use_dst_for_bwd" algorithms are used (such as + /// #dnnl_eltwise_relu_use_dst_for_bwd), source memory descriptor + /// otherwise. + /// @param alpha The alpha parameter for the elementwise operation. + /// Specific meaning depends on the algorithm. + /// @param beta The beta parameter for the elementwise operation. + /// Specific meaning depends on the algorithm. + /// @param hint_fwd_pd Primitive descriptor for an elementwise + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, + const memory::desc &data_desc, float alpha, float beta, + const eltwise_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, diff_src_desc, diff_dst_desc, + data_desc, &alpha, &beta, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for an eltwise backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for an eltwise backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::eltwise, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + dnnl::algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_alpha()const + float get_alpha() const { return base::get_alpha(); } + + /// @copydoc dnnl::primitive_desc_base::get_beta()const + float get_beta() const { return base::get_beta(); } + + private: + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, + const memory::desc &data_desc, const float *alpha, + const float *beta, + const eltwise_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr, bool allow_empty) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_eltwise_backward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aalgorithm), + diff_src_desc.get(), diff_dst_desc.get(), data_desc.get(), + alpha ? *alpha : 0.0f, beta ? *beta : 0.0f, + hint_fwd_pd.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the eltwise backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + eltwise_backward() = default; + + /// Constructs an eltwise backward propagation primitive. + /// @param pd Primitive descriptor for an eltwise backward propagation + /// primitive. + eltwise_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an eltwise backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an eltwise backward propagation + /// primitive. + /// @param cache_blob Cache blob. + eltwise_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_eltwise + +/// @addtogroup dnnl_api_softmax Softmax +/// +/// A primitive to perform softmax. +/// +/// @sa @ref dev_guide_softmax in developer guide +/// +/// @{ + +/// Softmax forward propagation primitive. +struct softmax_forward : public primitive { + /// Primitive descriptor for a softmax forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a softmax forward propagation + /// primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Softmax algorithm kind: either + /// #dnnl::algorithm::softmax_accurate, + /// or #dnnl::algorithm::softmax_log. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param axis Axis over which softmax is computed. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &dst_desc, int axis, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_softmax_forward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(aalgorithm), src_desc.get(), + dst_desc.get(), axis, attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the softmax forward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a softmax forward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a softmax forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::softmax, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + dnnl::algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_axis()const + int get_axis() const { return base::get_axis(); } + }; + + /// Default constructor. Produces an empty object. + softmax_forward() = default; + + /// Constructs a softmax forward propagation primitive. + /// @param pd Primitive descriptor for a softmax forward propagation + /// primitive. + softmax_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a softmax forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for a softmax forward propagation + /// primitive. + /// @param cache_blob Cache blob. + softmax_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Softmax backward propagation primitive. +struct softmax_backward : public primitive { + /// Primitive descriptor for a softmax backward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a softmax backward propagation + /// primitive. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Softmax algorithm kind: either + /// #dnnl::algorithm::softmax_accurate, + /// or #dnnl::algorithm::softmax_log. + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param axis Axis over which softmax is computed. + /// @param hint_fwd_pd Primitive descriptor for a softmax + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::desc &dst_desc, + int axis, const softmax_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_softmax_backward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aalgorithm), + diff_src_desc.get(), diff_dst_desc.get(), dst_desc.get(), + axis, hint_fwd_pd.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the softmax backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a softmax backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a softmax backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::softmax, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + dnnl::algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_axis()const + int get_axis() const { return base::get_axis(); } + }; + + /// Default constructor. Produces an empty object. + softmax_backward() = default; + + /// Constructs a softmax backward propagation primitive. + /// @param pd Primitive descriptor for a softmax backward propagation + /// primitive. + softmax_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a softmax backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for a softmax backward propagation + /// primitive. + /// @param cache_blob Cache blob. + softmax_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_softmax + +/// @addtogroup dnnl_api_batch_normalization Batch Normalization +/// +/// A primitive to perform batch normalization. +/// +/// Both forward and backward propagation primitives support in-place +/// operation; that is, src and dst can refer to the same memory for forward +/// propagation, and diff_dst and diff_src can refer to the same memory for +/// backward propagation. +/// +/// The batch normalization primitives computations can be controlled by +/// specifying different @ref dnnl::normalization_flags values. For example, +/// batch normalization forward propagation can be configured to either +/// compute the mean and variance or take them as arguments. It can either +/// perform scaling and shifting using gamma and beta parameters or not. +/// Optionally, it can also perform a fused ReLU, which in case of training +/// would also require a workspace. +/// +/// @sa @ref dev_guide_batch_normalization in developer guide +/// +/// @{ + +/// Batch normalization forward propagation primitive. +struct batch_normalization_forward : public primitive { + /// Primitive descriptor for a batch normalization forward propagation + /// primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a batch normalization forward + /// propagation primitive. + /// + /// @note + /// In-place operation is supported: the dst can refer to the same + /// memory as the src. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param epsilon Batch normalization epsilon parameter. + /// @param flags Batch normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &dst_desc, + float epsilon, normalization_flags flags, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_batch_normalization_forward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + src_desc.get(), dst_desc.get(), epsilon, + convert_to_c(flags), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the batch normalization forward propagation " + "primitive. Run workload with environment variable " + "ONEDNN_VERBOSE=all to get additional diagnostic " + "information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a batch normalization + /// forward propagation primitive from a C API primitive descriptor + /// that must have a matching kind. + /// + /// @param pd C API primitive descriptor for a batch normalization + /// forward propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, + dnnl::primitive::kind::batch_normalization, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// Returns memory descriptor for mean. + /// @returns Memory descriptor for mean. + memory::desc mean_desc() const { return stat_desc(mean); } + + /// Returns memory descriptor for variance. + /// @returns Memory descriptor for variance. + memory::desc variance_desc() const { return stat_desc(var); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_epsilon()const + float get_epsilon() const { return base::get_epsilon(); } + + /// Returns normalization flags. + /// @return Normalization flags. + normalization_flags get_flags() const { + return base::get_flags(); + } + + private: + enum { + mean = 1, + var = 2, + }; + memory::desc stat_desc(int kind) const { + const bool use_global_stats + = (get_flags() & normalization_flags::use_global_stats) + != normalization_flags::none; + return query_md( + use_global_stats ? query::src_md : query::dst_md, kind); + } + }; + + /// Default constructor. Produces an empty object. + batch_normalization_forward() = default; + + /// Constructs a batch normalization forward propagation primitive. + /// @param pd Primitive descriptor for a batch normalization forward + /// propagation primitive. + batch_normalization_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a batch normalization forward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for a batch normalization forward + /// propagation primitive. + /// @param cache_blob Cache blob. + batch_normalization_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Batch normalization backward propagation primitive. +struct batch_normalization_backward : public primitive { + /// Primitive descriptor for a batch normalization backward propagation + /// primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a batch normalization backward + /// propagation primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::backward_data and #dnnl::prop_kind::backward + /// (diffs for all parameters are computed in this case). + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param src_desc Source memory descriptor. + /// @param epsilon Batch normalization epsilon parameter. + /// @param flags Batch normalization flags (@ref + /// dnnl::normalization_flags). + /// @param hint_fwd_pd Primitive descriptor for a batch normalization + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::desc &src_desc, + float epsilon, normalization_flags flags, + const batch_normalization_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_batch_normalization_backward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + diff_src_desc.get(), diff_dst_desc.get(), + src_desc.get(), epsilon, convert_to_c(flags), + hint_fwd_pd.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the batch normalization backward propagation " + "primitive. Run workload with environment variable " + "ONEDNN_VERBOSE=all to get additional diagnostic " + "information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a batch normalization + /// backward propagation primitive from a C API primitive descriptor + /// that must have a matching kind. + /// + /// @param pd C API primitive descriptor for a batch normalization + /// backward propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, + dnnl::primitive::kind::batch_normalization, + dnnl::prop_kind::backward, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_weights_desc()const + memory::desc diff_weights_desc() const { + return base::diff_weights_desc(0); + } + + /// @copydoc dnnl::batch_normalization_forward::primitive_desc::mean_desc()const + memory::desc mean_desc() const { return query_md(query::src_md, 1); } + + /// @copydoc dnnl::batch_normalization_forward::primitive_desc::variance_desc()const + memory::desc variance_desc() const { + return query_md(query::src_md, 2); + } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_epsilon()const + float get_epsilon() const { return base::get_epsilon(); } + + /// Returns normalization flags. + /// @return Normalization flags. + normalization_flags get_flags() const { + return base::get_flags(); + } + }; + + /// Default constructor. Produces an empty object. + batch_normalization_backward() = default; + + /// Constructs a batch normalization backward propagation primitive. + /// @param pd Primitive descriptor for a batch normalization backward + /// propagation primitive. + batch_normalization_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a batch normalization backward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for a batch normalization backward + /// propagation primitive. + /// @param cache_blob Cache blob. + batch_normalization_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_batch_normalization + +/// @addtogroup dnnl_api_group_normalization Group Normalization +/// +/// A primitive to perform group normalization. +/// +/// Both forward and backward propagation primitives support in-place +/// operation; that is, src and dst can refer to the same memory for forward +/// propagation, and diff_dst and diff_src can refer to the same memory for +/// backward propagation. +/// +/// The group normalization primitives computations can be controlled by +/// specifying different @ref dnnl::normalization_flags values. For example, +/// group normalization forward propagation can be configured to either +/// compute the mean and variance or take them as arguments. It can either +/// perform scaling and shifting using gamma and beta parameters or not. +/// +/// @sa @ref dev_guide_group_normalization in developer guide +/// +/// @{ + +/// Group normalization forward propagation primitive. +struct group_normalization_forward : public primitive { + /// Primitive descriptor for a group normalization forward propagation + /// primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a group normalization forward + /// propagation primitive. + /// + /// @note + /// In-place operation is supported: the dst can refer to the same + /// memory as the src. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param groups Group normalization groups parameter. + /// @param epsilon Group normalization epsilon parameter. + /// @param flags Group normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &dst_desc, + memory::dim groups, float epsilon, normalization_flags flags, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_group_normalization_forward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + src_desc.get(), dst_desc.get(), groups, epsilon, + convert_to_c(flags), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the group normalization forward propagation " + "primitive. Run workload with environment variable " + "ONEDNN_VERBOSE=all to get additional diagnostic " + "information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a group normalization + /// forward propagation primitive from a C API primitive descriptor + /// that must have a matching kind. + /// + /// @param pd C API primitive descriptor for a group normalization + /// forward propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, + dnnl::primitive::kind::group_normalization, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// Returns memory descriptor for mean. + /// @returns Memory descriptor for mean. + memory::desc mean_desc() const { return stat_desc(mean); } + + /// Returns memory descriptor for variance. + /// @returns Memory descriptor for variance. + memory::desc variance_desc() const { return stat_desc(var); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_group_size()const + memory::dim get_group_size() const { return base::get_group_size(); } + + /// @copydoc dnnl::primitive_desc_base::get_epsilon()const + float get_epsilon() const { return base::get_epsilon(); } + + /// Returns normalization flags. + /// @return Normalization flags. + normalization_flags get_flags() const { + return base::get_flags(); + } + + private: + enum { + mean = 1, + var = 2, + }; + memory::desc stat_desc(int kind) const { + const bool use_global_stats + = (get_flags() & normalization_flags::use_global_stats) + != normalization_flags::none; + return query_md( + use_global_stats ? query::src_md : query::dst_md, kind); + } + }; + + /// Default constructor. Produces an empty object. + group_normalization_forward() = default; + + /// Constructs a group normalization forward propagation primitive. + /// @param pd Primitive descriptor for a group normalization forward + /// propagation primitive. + group_normalization_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a group normalization forward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for a group normalization forward + /// propagation primitive. + /// @param cache_blob Cache blob. + group_normalization_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Group normalization backward propagation primitive. +struct group_normalization_backward : public primitive { + /// Primitive descriptor for a group normalization backward propagation + /// primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a group normalization backward + /// propagation primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::backward_data and #dnnl::prop_kind::backward + /// (diffs for all parameters are computed in this case). + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param src_desc Source memory descriptor. + /// @param groups Group normalization groups parameter. + /// @param epsilon Group normalization epsilon parameter. + /// @param flags Group normalization flags (@ref + /// dnnl::normalization_flags). + /// @param hint_fwd_pd Primitive descriptor for a group normalization + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::desc &src_desc, + memory::dim groups, float epsilon, normalization_flags flags, + const group_normalization_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_group_normalization_backward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + diff_src_desc.get(), diff_dst_desc.get(), + src_desc.get(), groups, epsilon, + convert_to_c(flags), hint_fwd_pd.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the group normalization backward propagation " + "primitive. Run workload with environment variable " + "ONEDNN_VERBOSE=all to get additional diagnostic " + "information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a group normalization + /// backward propagation primitive from a C API primitive descriptor + /// that must have a matching kind. + /// + /// @param pd C API primitive descriptor for a group normalization + /// backward propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, + dnnl::primitive::kind::group_normalization, + dnnl::prop_kind::backward, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_weights_desc()const + memory::desc diff_weights_desc() const { + return base::diff_weights_desc(0); + } + + /// @copydoc dnnl::group_normalization_forward::primitive_desc::mean_desc()const + memory::desc mean_desc() const { return query_md(query::src_md, 1); } + + /// @copydoc dnnl::group_normalization_forward::primitive_desc::variance_desc()const + memory::desc variance_desc() const { + return query_md(query::src_md, 2); + } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_group_size()const + memory::dim get_group_size() const { return base::get_group_size(); } + + /// @copydoc dnnl::primitive_desc_base::get_epsilon()const + float get_epsilon() const { return base::get_epsilon(); } + + /// Returns normalization flags. + /// @return Normalization flags. + normalization_flags get_flags() const { + return base::get_flags(); + } + }; + + /// Default constructor. Produces an empty object. + group_normalization_backward() = default; + + /// Constructs a group normalization backward propagation primitive. + /// @param pd Primitive descriptor for a group normalization backward + /// propagation primitive. + group_normalization_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a group normalization backward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for a group normalization backward + /// propagation primitive. + /// @param cache_blob Cache blob. + group_normalization_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_group_normalization + +/// @addtogroup dnnl_api_layer_normalization Layer Normalization +/// +/// A primitive to perform layer normalization. Normalization is performed +/// within the last logical dimension of data tensor. +/// +/// Both forward and backward propagation primitives support in-place +/// operation; that is, src and dst can refer to the same memory for forward +/// propagation, and diff_dst and diff_src can refer to the same memory for +/// backward propagation. +/// +/// The layer normalization primitives computations can be controlled by +/// specifying different @ref dnnl::normalization_flags values. For example, +/// layer normalization forward propagation can be configured to either +/// compute the mean and variance or take them as arguments. It can either +/// perform scaling and shifting using gamma and beta parameters or not. +/// +/// @sa @ref dev_guide_layer_normalization in developer guide +/// +/// @{ + +/// Layer normalization forward propagation primitive. +struct layer_normalization_forward : public primitive { + /// Primitive descriptor for a layer normalization forward propagation + /// primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a layer normalization forward + /// propagation primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param stat_desc Statistics memory descriptors. + /// @param epsilon Layer normalization epsilon parameter. + /// @param flags Layer normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &dst_desc, + const memory::desc &stat_desc, float epsilon, + normalization_flags flags, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, src_desc, dst_desc, + &stat_desc, memory::data_type::f32, epsilon, flags, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for a layer normalization forward + /// propagation primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param epsilon Layer normalization epsilon parameter. + /// @param flags Layer normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &dst_desc, + float epsilon, normalization_flags flags, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, src_desc, dst_desc, nullptr, + memory::data_type::f32, epsilon, flags, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for a layer normalization forward + /// propagation primitive with a user-provided data type for the scale + /// and shift memory objects. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param stat_desc Statistics memory descriptors. + /// @param scale_shift_data_type Data type of scale and shift memory. + /// If neither scale nor shift flag are specified the parameter + /// is ignored. + /// @param epsilon Layer normalization epsilon parameter. + /// @param flags Layer normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &dst_desc, + const memory::desc &stat_desc, + memory::data_type scale_shift_data_type, float epsilon, + normalization_flags flags, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, src_desc, dst_desc, + &stat_desc, scale_shift_data_type, epsilon, flags, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for a layer normalization forward + /// propagation primitive with a user-provided data type for the scale + /// and shift memory objects. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param scale_shift_data_type Data type of scale and shift memory. + /// If neither scale nor shift flag are specified the parameter + /// is ignored. + /// @param epsilon Layer normalization epsilon parameter. + /// @param flags Layer normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &dst_desc, + memory::data_type scale_shift_data_type, float epsilon, + normalization_flags flags, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, src_desc, dst_desc, nullptr, + scale_shift_data_type, epsilon, flags, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for a layer normalization + /// forward propagation primitive from a C API primitive descriptor + /// that must have a matching kind. + /// + /// @param pd C API primitive descriptor for a layer normalization + /// forward propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, + dnnl::primitive::kind::layer_normalization, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// @copydoc dnnl::batch_normalization_forward::primitive_desc::mean_desc()const + memory::desc mean_desc() const { return stat_desc(mean); } + + /// @copydoc dnnl::batch_normalization_forward::primitive_desc::variance_desc()const + memory::desc variance_desc() const { return stat_desc(var); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_epsilon()const + float get_epsilon() const { return base::get_epsilon(); } + + /// Returns normalization flags. + /// @return Normalization flags. + normalization_flags get_flags() const { + return base::get_flags(); + } + + private: + enum { + mean = 1, + var = 2, + }; + memory::desc stat_desc(int kind) const { + const bool use_global_stats + = (get_flags() & normalization_flags::use_global_stats) + != normalization_flags::none; + return query_md( + use_global_stats ? query::src_md : query::dst_md, kind); + } + + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &dst_desc, + const memory::desc *stat_desc, + memory::data_type scale_shift_data_type, float epsilon, + normalization_flags flags, const primitive_attr &attr, + bool allow_empty) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_layer_normalization_forward_primitive_desc_create_v2( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + src_desc.get(), dst_desc.get(), + optional_arg(stat_desc), + memory::convert_to_c(scale_shift_data_type), + epsilon, convert_to_c(flags), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the layer normalization forward propagation " + "primitive. Run workload with environment variable " + "ONEDNN_VERBOSE=all to get additional diagnostic " + "information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + layer_normalization_forward() = default; + + /// Constructs a layer normalization forward propagation primitive. + /// @param pd Primitive descriptor for a layer normalization forward + /// propagation primitive. + layer_normalization_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a layer normalization forward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for a layer normalization forward + /// propagation primitive. + /// @param cache_blob Cache blob. + layer_normalization_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Layer normalization backward propagation primitive. +struct layer_normalization_backward : public primitive { + /// Primitive descriptor for a layer normalization backward propagation + /// primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a layer normalization backward + /// propagation primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::backward_data and #dnnl::prop_kind::backward + /// (diffs for all parameters are computed in this case). + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param src_desc Source memory descriptor. + /// @param stat_desc Statistics memory descriptors. + /// @param epsilon Layer normalization epsilon parameter. + /// @param flags Layer normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param hint_fwd_pd Primitive descriptor for a layer normalization + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::desc &src_desc, + const memory::desc &stat_desc, float epsilon, + normalization_flags flags, + const layer_normalization_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, diff_src_desc, diff_dst_desc, + src_desc, &stat_desc, memory::data_type::f32, + memory::data_type::f32, epsilon, flags, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for a layer normalization backward + /// propagation primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::backward_data and #dnnl::prop_kind::backward + /// (diffs for all parameters are computed in this case). + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param src_desc Source memory descriptor. + /// @param epsilon Layer normalization epsilon parameter. + /// @param flags Layer normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param hint_fwd_pd Primitive descriptor for a layer normalization + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::desc &src_desc, + float epsilon, normalization_flags flags, + const layer_normalization_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, diff_src_desc, diff_dst_desc, + src_desc, nullptr, memory::data_type::f32, + memory::data_type::f32, epsilon, flags, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for a layer normalization backward + /// propagation primitive with a user-provided data type for the scale + /// and shift memory objects. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::backward_data and #dnnl::prop_kind::backward + /// (diffs for all parameters are computed in this case). + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param src_desc Source memory descriptor. + /// @param stat_desc Statistics memory descriptors. + /// @param diff_scale_shift_data_type Data type of diff scale and shift + /// memory. If neither scale nor shift flag are specified the + /// parameter is ignored. + /// @param scale_shift_data_type Data type of scale and shift memory. + /// If neither scale nor shift flag are specified the parameter + /// is ignored. + /// @param epsilon Layer normalization epsilon parameter. + /// @param flags Layer normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param hint_fwd_pd Primitive descriptor for a layer normalization + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::desc &src_desc, + const memory::desc &stat_desc, + memory::data_type diff_scale_shift_data_type, + memory::data_type scale_shift_data_type, float epsilon, + normalization_flags flags, + const layer_normalization_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, diff_src_desc, diff_dst_desc, + src_desc, &stat_desc, diff_scale_shift_data_type, + scale_shift_data_type, epsilon, flags, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for a layer normalization backward + /// propagation primitive with a user-provided data type for the scale + /// and shift memory objects. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::backward_data and #dnnl::prop_kind::backward + /// (diffs for all parameters are computed in this case). + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param src_desc Source memory descriptor. + /// @param diff_scale_shift_data_type Data type of diff scale and shift + /// memory. If neither scale nor shift flag are specified the + /// parameter is ignored. + /// @param scale_shift_data_type Data type of scale and shift memory. + /// If neither scale nor shift flag are specified the parameter + /// is ignored. + /// @param epsilon Layer normalization epsilon parameter. + /// @param flags Layer normalization flags (@ref + /// dnnl::normalization_flags). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param hint_fwd_pd Primitive descriptor for a layer normalization + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::desc &src_desc, + memory::data_type diff_scale_shift_data_type, + memory::data_type scale_shift_data_type, float epsilon, + normalization_flags flags, + const layer_normalization_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, diff_src_desc, diff_dst_desc, + src_desc, nullptr, diff_scale_shift_data_type, + scale_shift_data_type, epsilon, flags, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for a layer normalization + /// backward propagation primitive from a C API primitive descriptor + /// that must have a matching kind. + /// + /// @param pd C API primitive descriptor for a layer normalization + /// backward propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, + dnnl::primitive::kind::layer_normalization, + dnnl::prop_kind::backward, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_weights_desc()const + memory::desc diff_weights_desc() const { + return base::diff_weights_desc(0); + } + + /// @copydoc dnnl::batch_normalization_forward::primitive_desc::mean_desc()const + memory::desc mean_desc() const { return query_md(query::src_md, 1); } + + /// @copydoc dnnl::batch_normalization_forward::primitive_desc::variance_desc()const + memory::desc variance_desc() const { + return query_md(query::src_md, 2); + } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + dnnl::prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_epsilon()const + float get_epsilon() const { return base::get_epsilon(); } + + /// Returns normalization flags. + /// @return Normalization flags. + normalization_flags get_flags() const { + return base::get_flags(); + } + + private: + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::desc &src_desc, + const memory::desc *stat_desc, + memory::data_type diff_scale_shift_data_type, + memory::data_type scale_shift_data_type, float epsilon, + normalization_flags flags, + const layer_normalization_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr, bool allow_empty) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_layer_normalization_backward_primitive_desc_create_v2( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + diff_src_desc.get(), diff_dst_desc.get(), + src_desc.get(), optional_arg(stat_desc), + memory::convert_to_c(diff_scale_shift_data_type), + memory::convert_to_c(scale_shift_data_type), + epsilon, convert_to_c(flags), hint_fwd_pd.get(), + attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the layer normalization backward propagation " + "primitive. Run workload with environment variable " + "ONEDNN_VERBOSE=all to get additional diagnostic " + "information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + layer_normalization_backward() = default; + + /// Constructs a layer normalization backward propagation primitive. + /// @param pd Primitive descriptor for a layer normalization backward + /// propagation primitive. + layer_normalization_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a layer normalization backward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for a layer normalization backward + /// propagation primitive. + /// @param cache_blob Cache blob. + layer_normalization_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_layer_normalization + +/// @addtogroup dnnl_api_inner_product Inner Product +/// +/// A primitive to compute an inner product. +/// +/// @sa @ref dev_guide_inner_product in developer guide +/// +/// @{ + +/// Inner product forward propagation primitive. +struct inner_product_forward : public primitive { + /// Primitive descriptor for an inner product forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an inner product forward + /// propagation primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Memory descriptor for src. + /// @param weights_desc Memory descriptor for weights. + /// @param bias_desc Memory descriptor for bias. + /// @param dst_desc Memory descriptor for dst. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &weights_desc, + const memory::desc &bias_desc, const memory::desc &dst_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, src_desc, weights_desc, + &bias_desc, dst_desc, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an inner product forward + /// propagation primitive. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Memory descriptor for src. + /// @param weights_desc Memory descriptor for weights. + /// @param dst_desc Memory descriptor for dst. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &weights_desc, + const memory::desc &dst_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, src_desc, weights_desc, + nullptr, dst_desc, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an inner product forward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for an inner product forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::inner_product, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::convolution_forward::primitive_desc::bias_desc()const + memory::desc bias_desc() const { return base::weights_desc(1); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + private: + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &weights_desc, + const memory::desc *bias_desc, const memory::desc &dst_desc, + const primitive_attr &attr, bool allow_empty) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_inner_product_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + src_desc.get(), weights_desc.get(), + optional_arg(bias_desc), dst_desc.get(), + attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the inner product forward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + inner_product_forward() = default; + + /// Constructs an inner product forward propagation primitive. + /// @param pd Primitive descriptor for an inner product forward + /// propagation primitive. + inner_product_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an inner product forward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for an inner product forward + /// propagation primitive. + /// @param cache_blob Cache blob. + inner_product_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Inner product backward propagation primitive. +struct inner_product_backward_data : public primitive { + /// Primitive descriptor for an inner product backward propagation + /// primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an inner product backward + /// propagation primitive. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param diff_src_desc Memory descriptor for diff src. + /// @param weights_desc Memory descriptor for weights. + /// @param diff_dst_desc Memory descriptor for diff dst. + /// @param hint_fwd_pd Primitive descriptor for an inner product + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const memory::desc &diff_src_desc, + const memory::desc &weights_desc, + const memory::desc &diff_dst_desc, + const inner_product_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_inner_product_backward_data_primitive_desc_create( + &pd, aengine.get(), diff_src_desc.get(), + weights_desc.get(), diff_dst_desc.get(), + hint_fwd_pd.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the inner product backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for an inner product backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for an inner product backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::inner_product, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { return base::weights_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + }; + + /// Default constructor. Produces an empty object. + inner_product_backward_data() = default; + + /// Constructs an inner product backward propagation primitive. + /// @param pd Primitive descriptor for an inner product backward + /// propagation primitive. + inner_product_backward_data(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an inner product backward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for an inner product backward + /// propagation primitive. + /// @param cache_blob Cache blob. + inner_product_backward_data( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Inner product weights gradient primitive. +struct inner_product_backward_weights : public primitive { + /// Primitive descriptor for an inner product weights gradient primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an inner product weights + /// update primitive with bias. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param src_desc Memory descriptor for src. + /// @param diff_weights_desc Memory descriptor for diff weights. + /// @param diff_bias_desc Memory descriptor for diff bias. + /// @param diff_dst_desc Memory descriptor for diff dst. + /// @param hint_fwd_pd Primitive descriptor for an inner product + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_desc, + const inner_product_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, src_desc, diff_weights_desc, + &diff_bias_desc, diff_dst_desc, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for an inner product weights + /// update primitive. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param src_desc Memory descriptor for src. + /// @param diff_weights_desc Memory descriptor for diff weights. + /// @param diff_dst_desc Memory descriptor for diff dst. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param hint_fwd_pd Primitive descriptor for an inner product + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_dst_desc, + const inner_product_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, src_desc, diff_weights_desc, nullptr, + diff_dst_desc, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an inner product weights + /// update primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for an inner product weights + /// gradient primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::inner_product, + dnnl::prop_kind::backward_weights) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_weights_desc()const + memory::desc diff_weights_desc() const { + return base::diff_weights_desc(0); + } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::convolution_backward_weights::primitive_desc::diff_bias_desc()const + memory::desc diff_bias_desc() const { + return base::diff_weights_desc(1); + } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + private: + primitive_desc(const engine &aengine, const memory::desc &src_desc, + const memory::desc &diff_weights_desc, + const memory::desc *diff_bias_desc, + const memory::desc &diff_dst_desc, + const inner_product_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr, bool allow_empty) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_inner_product_backward_weights_primitive_desc_create( + &pd, aengine.get(), src_desc.get(), + diff_weights_desc.get(), + optional_arg(diff_bias_desc), diff_dst_desc.get(), + hint_fwd_pd.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the inner product weights gradient primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + inner_product_backward_weights() = default; + + /// Constructs an inner product weights gradient primitive. + /// @param pd Primitive descriptor for an inner product weights gradient + /// primitive. + inner_product_backward_weights(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an inner product weights gradient primitive from a cache + /// blob. + /// @param pd Primitive descriptor for an inner product weights gradient + /// primitive. + /// @param cache_blob Cache blob. + inner_product_backward_weights( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_inner_product + +/// @addtogroup dnnl_api_rnn RNN +/// +/// A primitive to compute recurrent neural network layers. +/// +/// @sa @ref dev_guide_rnn in developer guide +/// +/// @{ + +/// Base class for primitive descriptors for RNN primitives. +struct rnn_primitive_desc_base : public primitive_desc { + using primitive_desc::primitive_desc; + + /// Default constructor. Produces an empty object. + rnn_primitive_desc_base() = default; + + /// Constructs an RNN primitive descriptor base from a C API primitive + /// descriptor while checking that it actually describes the expected + /// primitive by comparing propagation and primitive kinds. + /// + /// @param pd C API primitive descriptor. + /// @param aprop_kind Expected propagation kind. + /// @param cell_kind Expected cell kind. + rnn_primitive_desc_base(dnnl_primitive_desc_t pd, + dnnl::prop_kind aprop_kind, dnnl::algorithm cell_kind) + : rnn_primitive_desc_base(pd, aprop_kind, aprop_kind, cell_kind) {} + + /// Returns source layer memory descriptor. + /// @returns Source layer memory descriptor. + memory::desc src_layer_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_SRC_LAYER); + } + + /// Returns AUGRU attention memory descriptor. + /// @returns AUGRU attention memory descriptor. + memory::desc augru_attention_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_AUGRU_ATTENTION); + } + + /// Returns source iteration memory descriptor. + /// @returns Source iteration memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// source iteration parameter. + memory::desc src_iter_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_SRC_ITER); + } + + /// Returns source recurrent cell state memory descriptor. + /// @returns Source recurrent cell state memory descriptor. + memory::desc src_iter_c_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_SRC_ITER_C); + } + + /// Returns weights layer memory descriptor. + /// @returns Weights layer memory descriptor. + memory::desc weights_layer_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_WEIGHTS_LAYER); + } + + /// Returns weights iteration memory descriptor. + /// @returns Weights iteration memory descriptor. + memory::desc weights_iter_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_WEIGHTS_ITER); + } + + /// Returns weights peephole memory descriptor. + /// @returns Weights peephole memory descriptor. + memory::desc weights_peephole_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_WEIGHTS_PEEPHOLE); + } + + /// Returns weights projection memory descriptor. + /// @returns Weights projection memory descriptor. + memory::desc weights_projection_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_WEIGHTS_PROJECTION); + } + + /// Returns bias memory descriptor. + /// @returns Bias memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// bias parameter. + memory::desc bias_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_BIAS); + } + + /// Returns destination layer memory descriptor. + /// @returns Destination layer memory descriptor. + memory::desc dst_layer_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DST_LAYER); + } + + /// Returns destination iteration memory descriptor. + /// @returns Destination iteration memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// destination iteration parameter. + memory::desc dst_iter_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DST_ITER); + } + + /// Returns destination recurrent cell state memory descriptor. + /// @returns Destination recurrent cell state memory descriptor. + memory::desc dst_iter_c_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DST_ITER_C); + } + + /// Returns diff source layer memory descriptor. + /// @returns Diff source layer memory descriptor. + memory::desc diff_src_layer_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DIFF_SRC_LAYER); + } + + /// Returns diff AUGRU attention memory descriptor. + /// @returns Diff AUGRU attention memory descriptor. + memory::desc diff_augru_attention_desc() const { + return base::query_md( + query::exec_arg_md, DNNL_ARG_DIFF_AUGRU_ATTENTION); + } + + /// Returns diff source iteration memory descriptor. + /// @returns Diff source iteration memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// diff source iteration parameter. + memory::desc diff_src_iter_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DIFF_SRC_ITER); + } + + /// Returns diff source recurrent cell state memory descriptor. + /// @returns Diff source recurrent cell state memory descriptor. + memory::desc diff_src_iter_c_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DIFF_SRC_ITER_C); + } + + /// Returns diff weights layer memory descriptor. + /// @returns Diff weights layer memory descriptor. + memory::desc diff_weights_layer_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DIFF_WEIGHTS_LAYER); + } + + /// Returns diff weights iteration memory descriptor. + /// @returns Diff weights iteration memory descriptor. + memory::desc diff_weights_iter_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DIFF_WEIGHTS_ITER); + } + + /// Returns diff weights peephole memory descriptor. + /// @returns Diff weights peephole memory descriptor. + memory::desc diff_weights_peephole_desc() const { + return base::query_md( + query::exec_arg_md, DNNL_ARG_DIFF_WEIGHTS_PEEPHOLE); + } + + /// Returns diff weights projection memory descriptor. + /// @returns Diff weights projection memory descriptor. + memory::desc diff_weights_projection_desc() const { + return base::query_md( + query::exec_arg_md, DNNL_ARG_DIFF_WEIGHTS_PROJECTION); + } + + /// Returns diff bias memory descriptor. + /// @returns Diff bias memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// diff bias parameter. + memory::desc diff_bias_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DIFF_BIAS); + } + + /// Returns diff destination layer memory descriptor. + /// @returns Diff destination layer memory descriptor. + memory::desc diff_dst_layer_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DIFF_DST_LAYER); + } + + /// Returns diff destination iteration memory descriptor. + /// @returns Diff destination iteration memory descriptor. + /// @returns A zero memory descriptor if the primitive does not have a + /// diff destination iteration parameter. + memory::desc diff_dst_iter_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DIFF_DST_ITER); + } + + /// Returns diff destination recurrent cell state memory descriptor. + /// @returns Diff destination recurrent cell state memory descriptor. + memory::desc diff_dst_iter_c_desc() const { + return base::query_md(query::exec_arg_md, DNNL_ARG_DIFF_DST_ITER_C); + } + +protected: + using rnn_base = rnn_primitive_desc_base; + + // (Deliberately not using doxygen comments) + // + // Constructs an RNN primitive descriptor base from a C API primitive + // descriptor while checking that it actually describes the expected + // primitive by comparing propagation and primitive kinds. Caller can + // pass two options propagation kinds. This is typically used to check + // that propagation kind is inference or training forward propagation. + // + // @param pd C API primitive descriptor. + // @param prop_kind1 Expected propagation kind. + // @param prop_kind2 Expected propagation kind. + // @param cell_kind Expected cell kind. + rnn_primitive_desc_base(dnnl_primitive_desc_t pd, + dnnl::prop_kind prop_kind1, dnnl::prop_kind prop_kind2, + dnnl::algorithm cell_kind) { + + dnnl_status_t rc; + + dnnl_primitive_kind_t q_primitive_kind; + rc = dnnl_primitive_desc_query( + pd, dnnl_query_primitive_kind, 0, &q_primitive_kind); + error::wrap_c_api(rc, + "could not retrieve a primitive kind from a primitive " + "descriptor for an RNN primitive"); + + dnnl_prop_kind_t q_prop_kind; + rc = dnnl_primitive_desc_query( + pd, dnnl_query_prop_kind, 0, &q_prop_kind); + error::wrap_c_api(rc, + "could not retrieve a propagation kind from a primitive " + "descriptor for an RNN primitive"); + + dnnl_alg_kind_t q_cell_kind; + rc = dnnl_primitive_desc_query( + pd, dnnl_query_cell_kind, 0, &q_cell_kind); + error::wrap_c_api(rc, + "could not retrieve a cell kind from a primitive descriptor " + "for an RNN primitive"); + + dnnl_prop_kind_t c_prop_kind1 = convert_to_c(prop_kind1); + dnnl_prop_kind_t c_prop_kind2 = convert_to_c(prop_kind2); + dnnl_alg_kind_t c_cell_kind = convert_to_c(cell_kind); + + bool ok = q_primitive_kind == dnnl_rnn + && (q_prop_kind == c_prop_kind1 || q_prop_kind == c_prop_kind2) + && q_cell_kind == c_cell_kind; + + if (!ok) + DNNL_THROW_ERROR(dnnl_invalid_arguments, + "mismatch between expected and provided descriptors for an " + "RNN primitive"); + + reset_with_clone(pd); + } + + // Constructs an RNN forward propagation primitive descriptor base for + // any cell kind. + rnn_primitive_desc_base(const engine &aengine, algorithm cell_kind, + prop_kind aprop_kind, algorithm activation, rnn_direction direction, + const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc *src_iter_c_desc, + const memory::desc *attention_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc *weights_peephole_desc, + const memory::desc *weights_projection_desc, + const memory::desc &bias_desc, const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc *dst_iter_c_desc, rnn_flags flags, float alpha, + float beta, const primitive_attr &attr, bool allow_empty) { + + dnnl_status_t status = dnnl_success; + const char *msg + = "could not create a primitive descriptor for a requested " + "cell kind"; + + dnnl_primitive_desc_t pd = nullptr; + switch (cell_kind) { + case algorithm::vanilla_rnn: + status = dnnl_vanilla_rnn_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(activation), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), weights_layer_desc.get(), + weights_iter_desc.get(), bias_desc.get(), + dst_layer_desc.get(), dst_iter_desc.get(), + convert_to_c(flags), alpha, beta, attr.get()); + msg = "could not create a primitive descriptor for " + "the vanilla RNN forward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."; + break; + case algorithm::vanilla_lstm: + status = dnnl_lstm_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), optional_arg(src_iter_c_desc), + weights_layer_desc.get(), weights_iter_desc.get(), + optional_arg(weights_peephole_desc), + optional_arg(weights_projection_desc), bias_desc.get(), + dst_layer_desc.get(), dst_iter_desc.get(), + optional_arg(dst_iter_c_desc), convert_to_c(flags), + attr.get()); + msg = "could not create a primitive descriptor for " + "the LSTM forward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."; + break; + case algorithm::vanilla_gru: + status = dnnl_gru_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), weights_layer_desc.get(), + weights_iter_desc.get(), bias_desc.get(), + dst_layer_desc.get(), dst_iter_desc.get(), + convert_to_c(flags), attr.get()); + msg = "could not create a primitive descriptor for " + "the GRU forward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."; + break; + case algorithm::lbr_gru: + status = dnnl_lbr_gru_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), weights_layer_desc.get(), + weights_iter_desc.get(), bias_desc.get(), + dst_layer_desc.get(), dst_iter_desc.get(), + convert_to_c(flags), attr.get()); + msg = "could not create a primitive descriptor for " + "the LBR GRU forward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."; + break; + case algorithm::vanilla_augru: + status = dnnl_augru_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), optional_arg(attention_desc), + weights_layer_desc.get(), weights_iter_desc.get(), + bias_desc.get(), dst_layer_desc.get(), + dst_iter_desc.get(), convert_to_c(flags), attr.get()); + msg = "could not create a primitive descriptor for " + "the AUGRU forward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."; + break; + case algorithm::lbr_augru: + status = dnnl_lbr_augru_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), optional_arg(attention_desc), + weights_layer_desc.get(), weights_iter_desc.get(), + bias_desc.get(), dst_layer_desc.get(), + dst_iter_desc.get(), convert_to_c(flags), attr.get()); + msg = "could not create a primitive descriptor for " + "the LBR AUGRU forward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."; + break; + default: status = dnnl_unimplemented; + } + + if (!allow_empty) error::wrap_c_api(status, msg); + reset(pd); + } + + // Constructs an RNN backward propagation primitive descriptor base for + // any cell kind. + rnn_primitive_desc_base(const engine &aengine, algorithm cell_kind, + prop_kind aprop_kind, algorithm activation, rnn_direction direction, + const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc *src_iter_c_desc, + const memory::desc *attention_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc *weights_peephole_desc, + const memory::desc *weights_projection_desc, + const memory::desc &bias_desc, const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc *dst_iter_c_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc *diff_src_iter_c_desc, + const memory::desc *diff_attention_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc *diff_weights_peephole_desc, + const memory::desc *diff_weights_projection_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, + const memory::desc *diff_dst_iter_c_desc, rnn_flags flags, + float alpha, float beta, const rnn_primitive_desc_base &hint_fwd_pd, + const primitive_attr &attr, bool allow_empty) { + + dnnl_status_t status = dnnl_success; + const char *msg = ""; + + dnnl_primitive_desc_t pd = nullptr; + switch (cell_kind) { + case algorithm::vanilla_rnn: + status = dnnl_vanilla_rnn_backward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(activation), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), weights_layer_desc.get(), + weights_iter_desc.get(), bias_desc.get(), + dst_layer_desc.get(), dst_iter_desc.get(), + diff_src_layer_desc.get(), diff_src_iter_desc.get(), + diff_weights_layer_desc.get(), + diff_weights_iter_desc.get(), diff_bias_desc.get(), + diff_dst_layer_desc.get(), diff_dst_iter_desc.get(), + convert_to_c(flags), alpha, beta, hint_fwd_pd.get(), + attr.get()); + msg = "could not create a primitive descriptor for " + "the vanilla RNN backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."; + break; + case algorithm::vanilla_lstm: + status = dnnl_lstm_backward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), optional_arg(src_iter_c_desc), + weights_layer_desc.get(), weights_iter_desc.get(), + optional_arg(weights_peephole_desc), + optional_arg(weights_projection_desc), bias_desc.get(), + dst_layer_desc.get(), dst_iter_desc.get(), + optional_arg(dst_iter_c_desc), + diff_src_layer_desc.get(), diff_src_iter_desc.get(), + optional_arg(diff_src_iter_c_desc), + diff_weights_layer_desc.get(), + diff_weights_iter_desc.get(), + optional_arg(diff_weights_peephole_desc), + optional_arg(diff_weights_projection_desc), + diff_bias_desc.get(), diff_dst_layer_desc.get(), + diff_dst_iter_desc.get(), + optional_arg(diff_dst_iter_c_desc), convert_to_c(flags), + hint_fwd_pd.get(), attr.get()); + msg = "could not create a primitive descriptor for " + "the LSTM backward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."; + break; + case algorithm::vanilla_gru: + status = dnnl_gru_backward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), weights_layer_desc.get(), + weights_iter_desc.get(), bias_desc.get(), + dst_layer_desc.get(), dst_iter_desc.get(), + diff_src_layer_desc.get(), diff_src_iter_desc.get(), + diff_weights_layer_desc.get(), + diff_weights_iter_desc.get(), diff_bias_desc.get(), + diff_dst_layer_desc.get(), diff_dst_iter_desc.get(), + convert_to_c(flags), hint_fwd_pd.get(), attr.get()); + msg = "could not create a primitive descriptor for " + "the GRU backward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."; + break; + case algorithm::lbr_gru: + status = dnnl_lbr_gru_backward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), weights_layer_desc.get(), + weights_iter_desc.get(), bias_desc.get(), + dst_layer_desc.get(), dst_iter_desc.get(), + diff_src_layer_desc.get(), diff_src_iter_desc.get(), + diff_weights_layer_desc.get(), + diff_weights_iter_desc.get(), diff_bias_desc.get(), + diff_dst_layer_desc.get(), diff_dst_iter_desc.get(), + convert_to_c(flags), hint_fwd_pd.get(), attr.get()); + msg = "could not create a primitive descriptor for " + "the LBR GRU backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."; + break; + case algorithm::vanilla_augru: + status = dnnl_augru_backward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), optional_arg(attention_desc), + weights_layer_desc.get(), weights_iter_desc.get(), + bias_desc.get(), dst_layer_desc.get(), + dst_iter_desc.get(), diff_src_layer_desc.get(), + diff_src_iter_desc.get(), + optional_arg(diff_attention_desc), + diff_weights_layer_desc.get(), + diff_weights_iter_desc.get(), diff_bias_desc.get(), + diff_dst_layer_desc.get(), diff_dst_iter_desc.get(), + convert_to_c(flags), hint_fwd_pd.get(), attr.get()); + msg = "could not create a primitive descriptor for " + "the AUGRU backward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."; + break; + case algorithm::lbr_augru: + status = dnnl_lbr_augru_backward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + dnnl::convert_to_c(direction), src_layer_desc.get(), + src_iter_desc.get(), optional_arg(attention_desc), + weights_layer_desc.get(), weights_iter_desc.get(), + bias_desc.get(), dst_layer_desc.get(), + dst_iter_desc.get(), diff_src_layer_desc.get(), + diff_src_iter_desc.get(), + optional_arg(diff_attention_desc), + diff_weights_layer_desc.get(), + diff_weights_iter_desc.get(), diff_bias_desc.get(), + diff_dst_layer_desc.get(), diff_dst_iter_desc.get(), + convert_to_c(flags), hint_fwd_pd.get(), attr.get()); + msg = "could not create a primitive descriptor for " + "the LBR AUGRU backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."; + break; + default: status = dnnl_unimplemented; + } + if (!allow_empty) error::wrap_c_api(status, msg); + reset(pd); + } +}; + +/// Vanilla RNN forward propagation primitive. +struct vanilla_rnn_forward : public primitive { + /// Primitive descriptor for a vanilla RNN forward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a vanilla RNN forward + /// propagation primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc, + /// - @p bias_desc, + /// - @p dst_iter_desc. + /// + /// This would then indicate that the RNN forward propagation primitive + /// should not use them and should default to zero values instead. + /// + /// @note + /// All memory descriptors except @p src_iter_desc can be + /// initialized with an #dnnl::memory::format_tag::any value of @p + /// format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param activation Activation kind. Possible values are + /// #dnnl::algorithm::eltwise_relu, + /// #dnnl::algorithm::eltwise_tanh, or + /// #dnnl::algorithm::eltwise_logistic. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm activation, rnn_direction direction, + const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_rnn, + aprop_kind, activation, direction, src_layer_desc, + src_iter_desc, nullptr, nullptr, weights_layer_desc, + weights_iter_desc, nullptr, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, nullptr, rnn_flags::undef, + 0.0f, 0.0f, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a vanilla RNN forward + /// propagation primitive with alpha parameter. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc, + /// - @p bias_desc, + /// - @p dst_iter_desc. + /// + /// This would then indicate that the RNN forward propagation primitive + /// should not use them and should default to zero values instead. + /// + /// @note + /// All memory descriptors except @p src_iter_desc can be + /// initialized with an #dnnl::memory::format_tag::any value of @p + /// format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param activation Activation kind. Possible values are + /// #dnnl::algorithm::eltwise_relu, + /// #dnnl::algorithm::eltwise_tanh, or + /// #dnnl::algorithm::eltwise_logistic. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param alpha Negative slope if activation is + /// #dnnl::algorithm::eltwise_relu. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm activation, rnn_direction direction, + const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, float alpha, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_rnn, + aprop_kind, activation, direction, src_layer_desc, + src_iter_desc, nullptr, nullptr, weights_layer_desc, + weights_iter_desc, nullptr, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, nullptr, rnn_flags::undef, + alpha, 0.0f, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a vanilla RNN forward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a vanilla RNN forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference, + dnnl::algorithm::vanilla_rnn) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_activation_kind()const + algorithm get_activation_kind() const { + return base::get_activation_kind(); + } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + + /// @copydoc dnnl::primitive_desc_base::get_alpha()const + float get_alpha() const { return base::get_alpha(); } + + /// @copydoc dnnl::primitive_desc_base::get_beta()const + float get_beta() const { return base::get_beta(); } + }; + + /// Default constructor. Produces an empty object. + vanilla_rnn_forward() = default; + + /// Constructs a vanilla RNN forward propagation primitive. + /// @param pd Primitive descriptor for a vanilla RNN forward + /// propagation primitive. + vanilla_rnn_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a vanilla RNN forward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for a vanilla RNN forward + /// propagation primitive. + /// @param cache_blob Cache blob. + vanilla_rnn_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Vanilla RNN backward propagation primitive. +struct vanilla_rnn_backward : public primitive { + /// Primitive descriptor for an RNN backward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a vanilla RNN backward + /// propagation primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p diff_src_iter_desc, + /// - @p bias_desc together with @p diff_bias_desc, + /// - @p dst_iter_desc together with @p diff_dst_iter_desc. + /// + /// This would then indicate that the RNN backward propagation + /// primitive should not use the respective data and should use zero + /// values instead. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Must be + /// #dnnl::prop_kind::backward. + /// @param activation Activation kind. Possible values are + /// #dnnl::algorithm::eltwise_relu, + /// #dnnl::algorithm::eltwise_tanh, or + /// #dnnl::algorithm::eltwise_logistic. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param diff_src_layer_desc Memory descriptor for the diff of input + /// vector. + /// @param diff_src_iter_desc Memory descriptor for the diff of input + /// recurrent hidden state vector. + /// @param diff_weights_layer_desc Memory descriptor for the diff of + /// weights applied to the layer input. + /// @param diff_weights_iter_desc Memory descriptor for the diff of + /// weights applied to the recurrent input. + /// @param diff_bias_desc Diff bias memory descriptor. + /// @param diff_dst_layer_desc Memory descriptor for the diff of + /// output vector. + /// @param diff_dst_iter_desc Memory descriptor for the diff of output + /// recurrent hidden state vector. + /// @param hint_fwd_pd Primitive descriptor for a vanilla RNN + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm activation, rnn_direction direction, + const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, + const vanilla_rnn_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_rnn, + aprop_kind, activation, direction, src_layer_desc, + src_iter_desc, nullptr, nullptr, weights_layer_desc, + weights_iter_desc, nullptr, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, nullptr, + diff_src_layer_desc, diff_src_iter_desc, nullptr, nullptr, + diff_weights_layer_desc, diff_weights_iter_desc, nullptr, + nullptr, diff_bias_desc, diff_dst_layer_desc, + diff_dst_iter_desc, nullptr, rnn_flags::undef, 0.0f, 0.0f, + hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a vanilla RNN backward + /// propagation primitive with an alpha parameter. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p diff_src_iter_desc, + /// - @p bias_desc together with @p diff_bias_desc, + /// - @p dst_iter_desc together with @p diff_dst_iter_desc. + /// + /// This would then indicate that the RNN backward propagation + /// primitive should not use the respective data and should use zero + /// values instead. + /// + /// @note + /// All the memory descriptors may be initialized with the + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Must be + /// #dnnl::prop_kind::backward. + /// @param activation Activation kind. Possible values are + /// #dnnl::algorithm::eltwise_relu, + /// #dnnl::algorithm::eltwise_tanh, or + /// #dnnl::algorithm::eltwise_logistic. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param diff_src_layer_desc Memory descriptor for the diff of input + /// vector. + /// @param diff_src_iter_desc Memory descriptor for the diff of input + /// recurrent hidden state vector. + /// @param diff_weights_layer_desc Memory descriptor for the diff of + /// weights applied to the layer input. + /// @param diff_weights_iter_desc Memory descriptor for the diff of + /// weights applied to the recurrent input. + /// @param diff_bias_desc Diff bias memory descriptor. + /// @param diff_dst_layer_desc Memory descriptor for the diff of + /// output vector. + /// @param diff_dst_iter_desc Memory descriptor for the diff of output + /// recurrent hidden state vector. + /// @param alpha Negative slope if activation is + /// #dnnl::algorithm::eltwise_relu. + /// @param hint_fwd_pd Primitive descriptor for a vanilla RNN + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm activation, rnn_direction direction, + const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, float alpha, + const vanilla_rnn_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_rnn, + aprop_kind, activation, direction, src_layer_desc, + src_iter_desc, nullptr, nullptr, weights_layer_desc, + weights_iter_desc, nullptr, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, nullptr, + diff_src_layer_desc, diff_src_iter_desc, nullptr, nullptr, + diff_weights_layer_desc, diff_weights_iter_desc, nullptr, + nullptr, diff_bias_desc, diff_dst_layer_desc, + diff_dst_iter_desc, nullptr, rnn_flags::undef, alpha, + 0.0f, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a vanilla RNN backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a vanilla RNN backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::backward, + dnnl::algorithm::vanilla_rnn) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_layer_desc()const + memory::desc diff_src_layer_desc() const { + return rnn_base::diff_src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_iter_desc()const + memory::desc diff_src_iter_desc() const { + return rnn_base::diff_src_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_layer_desc()const + memory::desc diff_weights_layer_desc() const { + return rnn_base::diff_weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_iter_desc()const + memory::desc diff_weights_iter_desc() const { + return rnn_base::diff_weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_bias_desc()const + memory::desc diff_bias_desc() const { + return rnn_base::diff_bias_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_layer_desc()const + memory::desc diff_dst_layer_desc() const { + return rnn_base::diff_dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_iter_desc()const + memory::desc diff_dst_iter_desc() const { + return rnn_base::diff_dst_iter_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_activation_kind()const + algorithm get_activation_kind() const { + return base::get_activation_kind(); + } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + + /// @copydoc dnnl::primitive_desc_base::get_alpha()const + float get_alpha() const { return base::get_alpha(); } + + /// @copydoc dnnl::primitive_desc_base::get_beta()const + float get_beta() const { return base::get_beta(); } + }; + + /// Default constructor. Produces an empty object. + vanilla_rnn_backward() = default; + + /// Constructs a vanilla RNN backward propagation primitive. + /// @param pd Primitive descriptor for a vanilla RNN backward + /// propagation primitive. + vanilla_rnn_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a vanilla RNN backward propagation primitive from + /// a cache blob. + /// @param pd Primitive descriptor for a vanilla RNN backward + /// propagation primitive. + /// @param cache_blob Cache blob. + vanilla_rnn_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// LSTM forward propagation primitive. +struct lstm_forward : public primitive { + /// Primitive descriptor for an LSTM forward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an LSTM (with or without + /// peephole and with or without projection) forward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p src_iter_c_desc, + /// - @p weights_peephole_desc, + /// - @p bias_desc, + /// - @p dst_iter_desc together with @p dst_iter_c_desc. + /// + /// This would then indicate that the LSTM forward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// The @p weights_projection_desc may point to a zero memory + /// descriptor. This would then indicate that the LSTM doesn't have + /// recurrent projection layer. + /// + /// @note + /// All memory descriptors can be initialized with an + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param src_iter_c_desc Memory descriptor for the input recurrent + /// cell state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param weights_peephole_desc Memory descriptor for the weights + /// applied to the cell states (according to the Peephole LSTM + /// formula). + /// @param weights_projection_desc Memory descriptor for the weights + /// applied to the hidden states to get the recurrent projection + /// (according to the Projection LSTM formula). + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param dst_iter_c_desc Memory descriptor for the output recurrent + /// cell state vector. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &src_iter_c_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &weights_peephole_desc, + const memory::desc &weights_projection_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &dst_iter_c_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_lstm, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, &src_iter_c_desc, nullptr, + weights_layer_desc, weights_iter_desc, + &weights_peephole_desc, &weights_projection_desc, + bias_desc, dst_layer_desc, dst_iter_desc, + &dst_iter_c_desc, rnn_flags::undef, 0.0f, 0.0f, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for an LSTM (with or without + /// peephole) forward propagation primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p src_iter_c_desc, + /// - @p weights_peephole_desc, + /// - @p bias_desc, + /// - @p dst_iter_desc together with @p dst_iter_c_desc. + /// + /// This would then indicate that the LSTM forward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors can be initialized with an + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param src_iter_c_desc Memory descriptor for the input recurrent + /// cell state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param weights_peephole_desc Memory descriptor for the weights + /// applied to the cell states (according to the Peephole LSTM + /// formula). + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param dst_iter_c_desc Memory descriptor for the output recurrent + /// cell state vector. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &src_iter_c_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &weights_peephole_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &dst_iter_c_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_lstm, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, &src_iter_c_desc, nullptr, + weights_layer_desc, weights_iter_desc, + &weights_peephole_desc, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, &dst_iter_c_desc, + rnn_flags::undef, 0.0f, 0.0f, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an LSTM forward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p src_iter_c_desc, + /// - @p bias_desc, + /// - @p dst_iter_desc together with @p dst_iter_c_desc. + /// + /// This would then indicate that the LSTM forward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors can be initialized with an + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param src_iter_c_desc Memory descriptor for the input recurrent + /// cell state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param dst_iter_c_desc Memory descriptor for the output recurrent + /// cell state vector. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &src_iter_c_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &dst_iter_c_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_lstm, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, &src_iter_c_desc, nullptr, + weights_layer_desc, weights_iter_desc, nullptr, nullptr, + bias_desc, dst_layer_desc, dst_iter_desc, + &dst_iter_c_desc, rnn_flags::undef, 0.0f, 0.0f, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for an LSTM forward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for an LSTM forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference, + dnnl::algorithm::vanilla_lstm) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_c_desc() const { + return rnn_base::src_iter_c_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_peephole_desc()const + memory::desc weights_peephole_desc() const { + return rnn_base::weights_peephole_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_projection_desc()const + memory::desc weights_projection_desc() const { + return rnn_base::weights_projection_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc dst_iter_c_desc() const { + return rnn_base::dst_iter_c_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + lstm_forward() = default; + + /// Constructs an LSTM forward propagation primitive. + /// @param pd Primitive descriptor for an LSTM forward propagation + /// primitive. + lstm_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an LSTM forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an LSTM forward propagation + /// primitive. + /// @param cache_blob Cache blob. + lstm_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// LSTM backward propagation primitive. +struct lstm_backward : public primitive { + /// Primitive descriptor for an LSTM backward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs an LSTM (with or without peephole and with or without + /// projection) primitive descriptor for backward propagation + /// using @p prop_kind, @p direction, and memory descriptors. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p src_iter_c_desc, + /// @p diff_src_iter_desc, and @p diff_src_iter_c_desc, + /// - @p weights_peephole_desc together with + /// @p diff_weights_peephole_desc + /// - @p bias_desc together with @p diff_bias_desc, + /// - @p dst_iter_desc together with @p dst_iter_c_desc, + /// @p diff_dst_iter_desc, and @p diff_dst_iter_c_desc. + /// + /// This would then indicate that the LSTM backward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// The @p weights_projection_desc together with @p + /// diff_weights_projection_desc may point to a zero memory descriptor. + /// This would then indicate that the LSTM doesn't have recurrent + /// projection layer. + /// + /// @note + /// All memory descriptors can be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Must be + /// #dnnl::prop_kind::backward. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param src_iter_c_desc Memory descriptor for the input recurrent + /// cell state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param weights_peephole_desc Memory descriptor for the weights + /// applied to the cell states (according to the Peephole LSTM + /// formula). + /// @param weights_projection_desc Memory descriptor for the weights + /// applied to the hidden states to get the recurrent projection + /// (according to the Projection LSTM formula). + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param dst_iter_c_desc Memory descriptor for the output recurrent + /// cell state vector. + /// @param diff_src_layer_desc Memory descriptor for the diff of input + /// vector. + /// @param diff_src_iter_desc Memory descriptor for the diff of input + /// recurrent hidden state vector. + /// @param diff_src_iter_c_desc Memory descriptor for the diff of + /// input recurrent cell state vector. + /// @param diff_weights_layer_desc Memory descriptor for the diff of + /// weights applied to the layer input. + /// @param diff_weights_iter_desc Memory descriptor for the diff of + /// weights applied to the recurrent input. + /// @param diff_weights_peephole_desc Memory descriptor for the diff of + /// weights applied to the cell states (according to the Peephole + /// LSTM formula). + /// @param diff_weights_projection_desc Memory descriptor for the diff + /// of weights applied to the hidden states to get the recurrent + /// projection (according to the Projection LSTM formula). + /// @param diff_bias_desc Diff bias memory descriptor. + /// @param diff_dst_layer_desc Memory descriptor for the diff of + /// output vector. + /// @param diff_dst_iter_desc Memory descriptor for the diff of output + /// recurrent hidden state vector. + /// @param diff_dst_iter_c_desc Memory descriptor for the diff of + /// output recurrent cell state vector. + /// @param hint_fwd_pd Primitive descriptor for an LSTM + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &src_iter_c_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &weights_peephole_desc, + const memory::desc &weights_projection_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &dst_iter_c_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc &diff_src_iter_c_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc &diff_weights_peephole_desc, + const memory::desc &diff_weights_projection_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, + const memory::desc &diff_dst_iter_c_desc, + const lstm_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_lstm, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, &src_iter_c_desc, nullptr, + weights_layer_desc, weights_iter_desc, + &weights_peephole_desc, &weights_projection_desc, + bias_desc, dst_layer_desc, dst_iter_desc, + &dst_iter_c_desc, diff_src_layer_desc, diff_src_iter_desc, + &diff_src_iter_c_desc, nullptr, diff_weights_layer_desc, + diff_weights_iter_desc, &diff_weights_peephole_desc, + &diff_weights_projection_desc, diff_bias_desc, + diff_dst_layer_desc, diff_dst_iter_desc, + &diff_dst_iter_c_desc, rnn_flags::undef, 0.0f, 0.0f, + hint_fwd_pd, attr, allow_empty) {} + + /// Constructs an LSTM (with or without peephole) primitive descriptor + /// for backward propagation using @p prop_kind, @p direction, + /// and memory descriptors. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p src_iter_c_desc, + /// @p diff_src_iter_desc, and @p diff_src_iter_c_desc, + /// - @p weights_peephole_desc together with + /// @p diff_weights_peephole_desc + /// - @p bias_desc together with @p diff_bias_desc, + /// - @p dst_iter_desc together with @p dst_iter_c_desc, + /// @p diff_dst_iter_desc, and @p diff_dst_iter_c_desc. + /// + /// This would then indicate that the LSTM backward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors may be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Must be + /// #dnnl::prop_kind::backward. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param src_iter_c_desc Memory descriptor for the input recurrent + /// cell state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param weights_peephole_desc Memory descriptor for the weights + /// applied to the cell states (according to the Peephole LSTM + /// formula). + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param dst_iter_c_desc Memory descriptor for the output recurrent + /// cell state vector. + /// @param diff_src_layer_desc Memory descriptor for the diff of input + /// vector. + /// @param diff_src_iter_desc Memory descriptor for the diff of input + /// recurrent hidden state vector. + /// @param diff_src_iter_c_desc Memory descriptor for the diff of + /// input recurrent cell state vector. + /// @param diff_weights_layer_desc Memory descriptor for the diff of + /// weights applied to the layer input. + /// @param diff_weights_iter_desc Memory descriptor for the diff of + /// weights applied to the recurrent input. + /// @param diff_weights_peephole_desc Memory descriptor for the diff of + /// weights applied to the cell states (according to the Peephole + /// LSTM formula). + /// @param diff_bias_desc Diff bias memory descriptor. + /// @param diff_dst_layer_desc Memory descriptor for the diff of + /// output vector. + /// @param diff_dst_iter_desc Memory descriptor for the diff of output + /// recurrent hidden state vector. + /// @param diff_dst_iter_c_desc Memory descriptor for the diff of + /// output recurrent cell state vector. + /// @param hint_fwd_pd Primitive descriptor for an LSTM + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &src_iter_c_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &weights_peephole_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &dst_iter_c_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc &diff_src_iter_c_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc &diff_weights_peephole_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, + const memory::desc &diff_dst_iter_c_desc, + const lstm_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_lstm, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, &src_iter_c_desc, nullptr, + weights_layer_desc, weights_iter_desc, + &weights_peephole_desc, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, &dst_iter_c_desc, + diff_src_layer_desc, diff_src_iter_desc, + &diff_src_iter_c_desc, nullptr, diff_weights_layer_desc, + diff_weights_iter_desc, &diff_weights_peephole_desc, + nullptr, diff_bias_desc, diff_dst_layer_desc, + diff_dst_iter_desc, &diff_dst_iter_c_desc, + rnn_flags::undef, 0.0f, 0.0f, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs an LSTM primitive descriptor for backward propagation + /// using @p prop_kind, @p direction, and memory descriptors. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p src_iter_c_desc, + /// @p diff_src_iter_desc, and @p diff_src_iter_c_desc, + /// - @p bias_desc together with @p diff_bias_desc, + /// - @p dst_iter_desc together with @p dst_iter_c_desc, + /// @p diff_dst_iter_desc, and @p diff_dst_iter_c_desc. + /// + /// This would then indicate that the LSTM backward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors may be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Must be + /// #dnnl::prop_kind::backward. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param src_iter_c_desc Memory descriptor for the input recurrent + /// cell state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param dst_iter_c_desc Memory descriptor for the output recurrent + /// cell state vector. + /// @param diff_src_layer_desc Memory descriptor for the diff of input + /// vector. + /// @param diff_src_iter_desc Memory descriptor for the diff of input + /// recurrent hidden state vector. + /// @param diff_src_iter_c_desc Memory descriptor for the diff of + /// input recurrent cell state vector. + /// @param diff_weights_layer_desc Memory descriptor for the diff of + /// weights applied to the layer input. + /// @param diff_weights_iter_desc Memory descriptor for the diff of + /// weights applied to the recurrent input. + /// @param diff_bias_desc Diff bias memory descriptor. + /// @param diff_dst_layer_desc Memory descriptor for the diff of + /// output vector. + /// @param diff_dst_iter_desc Memory descriptor for the diff of output + /// recurrent hidden state vector. + /// @param diff_dst_iter_c_desc Memory descriptor for the diff of + /// output recurrent cell state vector. + /// @param hint_fwd_pd Primitive descriptor for a convolution + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &src_iter_c_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &dst_iter_c_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc &diff_src_iter_c_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, + const memory::desc &diff_dst_iter_c_desc, + const lstm_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_lstm, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, &src_iter_c_desc, nullptr, + weights_layer_desc, weights_iter_desc, nullptr, nullptr, + bias_desc, dst_layer_desc, dst_iter_desc, + &dst_iter_c_desc, diff_src_layer_desc, diff_src_iter_desc, + &diff_src_iter_c_desc, nullptr, diff_weights_layer_desc, + diff_weights_iter_desc, nullptr, nullptr, diff_bias_desc, + diff_dst_layer_desc, diff_dst_iter_desc, + &diff_dst_iter_c_desc, rnn_flags::undef, 0.0f, 0.0f, + hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an LSTM backward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for an LSTM backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::backward, + dnnl::algorithm::vanilla_lstm) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_c_desc() const { + return rnn_base::src_iter_c_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_peephole_desc()const + memory::desc weights_peephole_desc() const { + return rnn_base::weights_peephole_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_projection_desc()const + memory::desc weights_projection_desc() const { + return rnn_base::weights_projection_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc dst_iter_c_desc() const { + return rnn_base::dst_iter_c_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_layer_desc()const + memory::desc diff_src_layer_desc() const { + return rnn_base::diff_src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_iter_desc()const + memory::desc diff_src_iter_desc() const { + return rnn_base::diff_src_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_iter_c_desc()const + memory::desc diff_src_iter_c_desc() const { + return rnn_base::diff_src_iter_c_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_layer_desc()const + memory::desc diff_weights_layer_desc() const { + return rnn_base::diff_weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_iter_desc()const + memory::desc diff_weights_iter_desc() const { + return rnn_base::diff_weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_peephole_desc()const + memory::desc diff_weights_peephole_desc() const { + return rnn_base::diff_weights_peephole_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_projection_desc()const + memory::desc diff_weights_projection_desc() const { + return rnn_base::diff_weights_projection_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_bias_desc()const + memory::desc diff_bias_desc() const { + return rnn_base::diff_bias_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_layer_desc()const + memory::desc diff_dst_layer_desc() const { + return rnn_base::diff_dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_iter_desc()const + memory::desc diff_dst_iter_desc() const { + return rnn_base::diff_dst_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_iter_c_desc()const + memory::desc diff_dst_iter_c_desc() const { + return rnn_base::diff_dst_iter_c_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + lstm_backward() = default; + + /// Constructs an LSTM backward propagation primitive. + /// @param pd Primitive descriptor for an LSTM backward propagation + /// primitive. + lstm_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an LSTM backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an LSTM backward propagation + /// primitive. + /// @param cache_blob Cache blob. + lstm_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// GRU forward propagation primitive. +struct gru_forward : public primitive { + /// Primitive descriptor for a GRU forward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a GRU forward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc, + /// - @p bias_desc, + /// - @p dst_iter_desc. + /// + /// This would then indicate that the GRU forward propagation primitive + /// should not use them and should default to zero values instead. + /// + /// @note + /// All memory descriptors except @p src_iter_desc may be + /// initialized with an #dnnl::memory::format_tag::any value of @p + /// format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_gru, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, nullptr, nullptr, weights_layer_desc, + weights_iter_desc, nullptr, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, nullptr, rnn_flags::undef, + 0.0f, 0.0f, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a GRU forward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for a GRU forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference, + dnnl::algorithm::vanilla_gru) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + gru_forward() = default; + + /// Constructs a GRU forward propagation primitive. + /// @param pd Primitive descriptor for a GRU forward propagation + /// primitive. + gru_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a GRU forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for a GRU forward propagation + /// primitive. + /// @param cache_blob Cache blob. + gru_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// GRU backward propagation primitive. +struct gru_backward : public primitive { + /// Primitive descriptor for a GRU backward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a GRU backward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p diff_src_iter_desc, + /// - @p bias_desc together with @p diff_bias_desc, + /// - @p dst_iter_desc together with @p diff_dst_iter_desc. + /// + /// This would then indicate that the GRU backward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors may be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Must be + /// #dnnl::prop_kind::backward. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param diff_src_layer_desc Memory descriptor for the diff of input + /// vector. + /// @param diff_src_iter_desc Memory descriptor for the diff of input + /// recurrent hidden state vector. + /// @param diff_weights_layer_desc Memory descriptor for the diff of + /// weights applied to the layer input. + /// @param diff_weights_iter_desc Memory descriptor for the diff of + /// weights applied to the recurrent input. + /// @param diff_bias_desc Diff bias memory descriptor. + /// @param diff_dst_layer_desc Memory descriptor for the diff of + /// output vector. + /// @param diff_dst_iter_desc Memory descriptor for the diff of output + /// recurrent hidden state vector. + /// @param hint_fwd_pd Primitive descriptor for a GRU + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, + const gru_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_gru, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, nullptr, nullptr, weights_layer_desc, + weights_iter_desc, nullptr, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, nullptr, + diff_src_layer_desc, diff_src_iter_desc, nullptr, nullptr, + diff_weights_layer_desc, diff_weights_iter_desc, nullptr, + nullptr, diff_bias_desc, diff_dst_layer_desc, + diff_dst_iter_desc, nullptr, rnn_flags::undef, 0.0f, 0.0f, + hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a GRU backward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for a GRU backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::backward, + dnnl::algorithm::vanilla_gru) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_layer_desc()const + memory::desc diff_src_layer_desc() const { + return rnn_base::diff_src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_iter_desc()const + memory::desc diff_src_iter_desc() const { + return rnn_base::diff_src_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_layer_desc()const + memory::desc diff_weights_layer_desc() const { + return rnn_base::diff_weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_iter_desc()const + memory::desc diff_weights_iter_desc() const { + return rnn_base::diff_weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_bias_desc()const + memory::desc diff_bias_desc() const { + return rnn_base::diff_bias_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_layer_desc()const + memory::desc diff_dst_layer_desc() const { + return rnn_base::diff_dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_iter_desc()const + memory::desc diff_dst_iter_desc() const { + return rnn_base::diff_dst_iter_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + gru_backward() = default; + + /// Constructs a GRU backward propagation primitive. + /// @param pd Primitive descriptor for a GRU backward propagation + /// primitive. + gru_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a GRU backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for a GRU backward propagation + /// primitive. + /// @param cache_blob Cache blob. + gru_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// LBR GRU forward propagation primitive. +struct lbr_gru_forward : public primitive { + /// Primitive descriptor for an LBR GRU forward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for LBR GRU forward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc, + /// - @p bias_desc, + /// - @p dst_iter_desc. + /// + /// This would then indicate that the LBR GRU forward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors except @p src_iter_desc may be + /// initialized with an #dnnl::memory::format_tag::any value of @p + /// format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::lbr_gru, aprop_kind, + algorithm::undef, direction, src_layer_desc, + src_iter_desc, nullptr, nullptr, weights_layer_desc, + weights_iter_desc, nullptr, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, nullptr, rnn_flags::undef, + 0.0f, 0.0f, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a LBR GRU forward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for a LBR GRU forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference, + dnnl::algorithm::lbr_gru) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + lbr_gru_forward() = default; + + /// Constructs an LBR GRU forward propagation primitive. + /// @param pd Primitive descriptor for an LBR GRU forward propagation + /// primitive. + lbr_gru_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an LBR GRU forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an LBR GRU forward propagation + /// primitive. + /// @param cache_blob Cache blob. + lbr_gru_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// LBR GRU backward propagation primitive. +struct lbr_gru_backward : public primitive { + /// Primitive descriptor for an LBR GRU backward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for LBR GRU backward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p diff_src_iter_desc, + /// - @p bias_desc together with @p diff_bias_desc, + /// - @p dst_iter_desc together with @p diff_dst_iter_desc. + /// + /// This would then indicate that the LBR GRU backward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors may be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Must be + /// #dnnl::prop_kind::backward. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param diff_src_layer_desc Memory descriptor for the diff of input + /// vector. + /// @param diff_src_iter_desc Memory descriptor for the diff of input + /// recurrent hidden state vector. + /// @param diff_weights_layer_desc Memory descriptor for the diff of + /// weights applied to the layer input. + /// @param diff_weights_iter_desc Memory descriptor for the diff of + /// weights applied to the recurrent input. + /// @param diff_bias_desc Diff bias memory descriptor. + /// @param diff_dst_layer_desc Memory descriptor for the diff of + /// output vector. + /// @param diff_dst_iter_desc Memory descriptor for the diff of output + /// recurrent hidden state vector. + /// @param hint_fwd_pd Primitive descriptor for an LBR GRU + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, + const lbr_gru_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::lbr_gru, aprop_kind, + algorithm::undef, direction, src_layer_desc, + src_iter_desc, nullptr, nullptr, weights_layer_desc, + weights_iter_desc, nullptr, nullptr, bias_desc, + dst_layer_desc, dst_iter_desc, nullptr, + diff_src_layer_desc, diff_src_iter_desc, nullptr, nullptr, + diff_weights_layer_desc, diff_weights_iter_desc, nullptr, + nullptr, diff_bias_desc, diff_dst_layer_desc, + diff_dst_iter_desc, nullptr, rnn_flags::undef, 0.0f, 0.0f, + hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a LBR GRU backward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for a LBR GRU backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::backward, + dnnl::algorithm::lbr_gru) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_layer_desc()const + memory::desc diff_src_layer_desc() const { + return rnn_base::diff_src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_iter_desc()const + memory::desc diff_src_iter_desc() const { + return rnn_base::diff_src_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_layer_desc()const + memory::desc diff_weights_layer_desc() const { + return rnn_base::diff_weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_iter_desc()const + memory::desc diff_weights_iter_desc() const { + return rnn_base::diff_weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_bias_desc()const + memory::desc diff_bias_desc() const { + return rnn_base::diff_bias_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_layer_desc()const + memory::desc diff_dst_layer_desc() const { + return rnn_base::diff_dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_iter_desc()const + memory::desc diff_dst_iter_desc() const { + return rnn_base::diff_dst_iter_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + lbr_gru_backward() = default; + + /// Constructs an LBR GRU backward propagation primitive. + /// @param pd Primitive descriptor for an LBR GRU backward propagation + /// primitive. + lbr_gru_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an LBR GRU backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an LBR GRU backward propagation + /// primitive. + /// @param cache_blob Cache blob. + lbr_gru_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// AUGRU forward propagation primitive. +struct augru_forward : public primitive { + /// Primitive descriptor for an AUGRU forward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an AUGRU forward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc, + /// - @p bias_desc, + /// - @p dst_iter_desc. + /// + /// This would then indicate that the AUGRU forward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors except @p src_iter_desc may be + /// initialized with an #dnnl::memory::format_tag::any value of @p + /// format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param attention_desc Memory descriptor for the attention vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &attention_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_augru, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, nullptr, &attention_desc, + weights_layer_desc, weights_iter_desc, nullptr, nullptr, + bias_desc, dst_layer_desc, dst_iter_desc, nullptr, + rnn_flags::undef, 0.0f, 0.0f, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an AUGRU forward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for an AUGRU forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference, + dnnl::algorithm::vanilla_augru) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::augru_attention_desc()const + memory::desc attention_desc() const { + return rnn_base::augru_attention_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + augru_forward() = default; + + /// Constructs an AUGRU forward propagation primitive. + /// @param pd Primitive descriptor for an AUGRU forward propagation + /// primitive. + augru_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an AUGRU forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an AUGRU forward propagation + /// primitive. + /// @param cache_blob Cache blob. + augru_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// AUGRU backward propagation primitive. +struct augru_backward : public primitive { + /// Descriptor for an AUGRU backward propagation primitive. + /// Primitive descriptor for an AUGRU backward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an AUGRU backward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p diff_src_iter_desc, + /// - @p bias_desc together with @p diff_bias_desc, + /// - @p dst_iter_desc together with @p diff_dst_iter_desc. + /// + /// This would then indicate that the AUGRU backward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors may be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Must be + /// #dnnl::prop_kind::backward. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param attention_desc Memory descriptor for the attention vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param diff_src_layer_desc Memory descriptor for the diff of input + /// vector. + /// @param diff_src_iter_desc Memory descriptor for the diff of input + /// recurrent hidden state vector. + /// @param diff_attention_desc Memory descriptor for the diff of + /// attention vector. + /// @param diff_weights_layer_desc Memory descriptor for the diff of + /// weights applied to the layer input. + /// @param diff_weights_iter_desc Memory descriptor for the diff of + /// weights applied to the recurrent input. + /// @param diff_bias_desc Diff bias memory descriptor. + /// @param diff_dst_layer_desc Memory descriptor for the diff of + /// output vector. + /// @param diff_dst_iter_desc Memory descriptor for the diff of output + /// recurrent hidden state vector. + /// @param hint_fwd_pd Primitive descriptor for an AUGRU + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &attention_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc &diff_attention_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, + const augru_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::vanilla_augru, + aprop_kind, algorithm::undef, direction, src_layer_desc, + src_iter_desc, nullptr, &attention_desc, + weights_layer_desc, weights_iter_desc, nullptr, nullptr, + bias_desc, dst_layer_desc, dst_iter_desc, nullptr, + diff_src_layer_desc, diff_src_iter_desc, nullptr, + &diff_attention_desc, diff_weights_layer_desc, + diff_weights_iter_desc, nullptr, nullptr, diff_bias_desc, + diff_dst_layer_desc, diff_dst_iter_desc, nullptr, + rnn_flags::undef, 0.0f, 0.0f, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for an AUGRU backward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for an AUGRU backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::backward, + dnnl::algorithm::vanilla_augru) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::augru_attention_desc()const + memory::desc attention_desc() const { + return rnn_base::augru_attention_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_layer_desc()const + memory::desc diff_src_layer_desc() const { + return rnn_base::diff_src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_iter_desc()const + memory::desc diff_src_iter_desc() const { + return rnn_base::diff_src_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_augru_attention_desc()const + memory::desc diff_attention_desc() const { + return rnn_base::diff_augru_attention_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_layer_desc()const + memory::desc diff_weights_layer_desc() const { + return rnn_base::diff_weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_iter_desc()const + memory::desc diff_weights_iter_desc() const { + return rnn_base::diff_weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_bias_desc()const + memory::desc diff_bias_desc() const { + return rnn_base::diff_bias_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_layer_desc()const + memory::desc diff_dst_layer_desc() const { + return rnn_base::diff_dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_iter_desc()const + memory::desc diff_dst_iter_desc() const { + return rnn_base::diff_dst_iter_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + augru_backward() = default; + + /// Constructs an AUGRU backward propagation primitive. + /// @param pd Primitive descriptor for an AUGRU backward propagation + /// primitive. + augru_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an AUGRU backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an AUGRU backward propagation + /// primitive. + /// @param cache_blob Cache blob. + augru_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// LBR AUGRU forward propagation primitive. +struct lbr_augru_forward : public primitive { + /// Descriptor for an LBR AUGRU forward propagation primitive. + + /// Primitive descriptor for an LBR AUGRU forward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for LBR AUGRU forward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc, + /// - @p bias_desc, + /// - @p dst_iter_desc. + /// + /// This would then indicate that the LBR AUGRU forward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors except @p src_iter_desc may be + /// initialized with an #dnnl::memory::format_tag::any value of @p + /// format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param attention_desc Memory descriptor for the attention vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &attention_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::lbr_augru, aprop_kind, + algorithm::undef, direction, src_layer_desc, + src_iter_desc, nullptr, &attention_desc, + weights_layer_desc, weights_iter_desc, nullptr, nullptr, + bias_desc, dst_layer_desc, dst_iter_desc, nullptr, + rnn_flags::undef, 0.0f, 0.0f, attr, allow_empty) {} + + /// Constructs a primitive descriptor for an LBR AUGRU forward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for an LBR AUGRU forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference, + dnnl::algorithm::lbr_augru) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::augru_attention_desc()const + memory::desc attention_desc() const { + return rnn_base::augru_attention_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + lbr_augru_forward() = default; + + /// Constructs an LBR AUGRU forward propagation primitive. + /// @param pd Primitive descriptor for an LBR AUGRU forward propagation + /// primitive. + lbr_augru_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an LBR AUGRU forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an LBR AUGRU forward propagation + /// primitive. + /// @param cache_blob Cache blob. + lbr_augru_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// LBR AUGRU backward propagation primitive. +struct lbr_augru_backward : public primitive { + /// Primitive descriptor for an LBR AUGRU backward propagation primitive. + struct primitive_desc : public rnn_primitive_desc_base { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for LBR AUGRU backward propagation + /// primitive. + /// + /// The following arguments may point to a zero memory descriptor: + /// - @p src_iter_desc together with @p diff_src_iter_desc, + /// - @p bias_desc together with @p diff_bias_desc, + /// - @p dst_iter_desc together with @p diff_dst_iter_desc. + /// + /// This would then indicate that the LBR AUGRU backward propagation + /// primitive should not use them and should default to zero values + /// instead. + /// + /// @note + /// All memory descriptors may be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Must be + /// #dnnl::prop_kind::backward. + /// @param direction RNN direction. See @ref dnnl::rnn_direction for + /// more info. + /// @param src_layer_desc Memory descriptor for the input vector. + /// @param src_iter_desc Memory descriptor for the input recurrent + /// hidden state vector. + /// @param attention_desc Memory descriptor for the attention vector. + /// @param weights_layer_desc Memory descriptor for the weights + /// applied to the layer input. + /// @param weights_iter_desc Memory descriptor for the weights applied + /// to the recurrent input. + /// @param bias_desc Bias memory descriptor. + /// @param dst_layer_desc Memory descriptor for the output vector. + /// @param dst_iter_desc Memory descriptor for the output recurrent + /// hidden state vector. + /// @param diff_src_layer_desc Memory descriptor for the diff of input + /// vector. + /// @param diff_src_iter_desc Memory descriptor for the diff of input + /// recurrent hidden state vector. + /// @param diff_attention_desc Memory descriptor for the diff of + /// attention vector. + /// @param diff_weights_layer_desc Memory descriptor for the diff of + /// weights applied to the layer input. + /// @param diff_weights_iter_desc Memory descriptor for the diff of + /// weights applied to the recurrent input. + /// @param diff_bias_desc Diff bias memory descriptor. + /// @param diff_dst_layer_desc Memory descriptor for the diff of + /// output vector. + /// @param diff_dst_iter_desc Memory descriptor for the diff of output + /// recurrent hidden state vector. + /// @param hint_fwd_pd Primitive descriptor for an LBR AUGRU + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + rnn_direction direction, const memory::desc &src_layer_desc, + const memory::desc &src_iter_desc, + const memory::desc &attention_desc, + const memory::desc &weights_layer_desc, + const memory::desc &weights_iter_desc, + const memory::desc &bias_desc, + const memory::desc &dst_layer_desc, + const memory::desc &dst_iter_desc, + const memory::desc &diff_src_layer_desc, + const memory::desc &diff_src_iter_desc, + const memory::desc &diff_attention_desc, + const memory::desc &diff_weights_layer_desc, + const memory::desc &diff_weights_iter_desc, + const memory::desc &diff_bias_desc, + const memory::desc &diff_dst_layer_desc, + const memory::desc &diff_dst_iter_desc, + const lbr_augru_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : rnn_primitive_desc_base(aengine, algorithm::lbr_augru, aprop_kind, + algorithm::undef, direction, src_layer_desc, + src_iter_desc, nullptr, &attention_desc, + weights_layer_desc, weights_iter_desc, nullptr, nullptr, + bias_desc, dst_layer_desc, dst_iter_desc, nullptr, + diff_src_layer_desc, diff_src_iter_desc, nullptr, + &diff_attention_desc, diff_weights_layer_desc, + diff_weights_iter_desc, nullptr, nullptr, diff_bias_desc, + diff_dst_layer_desc, diff_dst_iter_desc, nullptr, + rnn_flags::undef, 0.0f, 0.0f, hint_fwd_pd, attr, + allow_empty) {} + + /// Constructs a primitive descriptor for an LBR AUGRU backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for an LBR AUGRU backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : rnn_primitive_desc_base(pd, dnnl::prop_kind::backward, + dnnl::algorithm::lbr_augru) {} + + /// @copydoc dnnl::rnn_primitive_desc_base::src_layer_desc()const + memory::desc src_layer_desc() const { + return rnn_base::src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::src_iter_desc()const + memory::desc src_iter_desc() const { return rnn_base::src_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::augru_attention_desc()const + memory::desc attention_desc() const { + return rnn_base::augru_attention_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_layer_desc()const + memory::desc weights_layer_desc() const { + return rnn_base::weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::weights_iter_desc()const + memory::desc weights_iter_desc() const { + return rnn_base::weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::bias_desc()const + memory::desc bias_desc() const { return rnn_base::bias_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_layer_desc()const + memory::desc dst_layer_desc() const { + return rnn_base::dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::dst_iter_desc()const + memory::desc dst_iter_desc() const { return rnn_base::dst_iter_desc(); } + + /// @copydoc dnnl::rnn_primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { + return rnn_base::workspace_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_layer_desc()const + memory::desc diff_src_layer_desc() const { + return rnn_base::diff_src_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_src_iter_desc()const + memory::desc diff_src_iter_desc() const { + return rnn_base::diff_src_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_augru_attention_desc()const + memory::desc diff_attention_desc() const { + return rnn_base::diff_augru_attention_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_layer_desc()const + memory::desc diff_weights_layer_desc() const { + return rnn_base::diff_weights_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_weights_iter_desc()const + memory::desc diff_weights_iter_desc() const { + return rnn_base::diff_weights_iter_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_bias_desc()const + memory::desc diff_bias_desc() const { + return rnn_base::diff_bias_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_layer_desc()const + memory::desc diff_dst_layer_desc() const { + return rnn_base::diff_dst_layer_desc(); + } + + /// @copydoc dnnl::rnn_primitive_desc_base::diff_dst_iter_desc()const + memory::desc diff_dst_iter_desc() const { + return rnn_base::diff_dst_iter_desc(); + } + + /// @copydoc dnnl::primitive_desc_base::get_cell_kind()const + algorithm get_cell_kind() const { return base::get_cell_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_direction()const + rnn_direction get_direction() const { return base::get_direction(); } + }; + + /// Default constructor. Produces an empty object. + lbr_augru_backward() = default; + + /// Constructs an LBR AUGRU backward propagation primitive. + /// @param pd Primitive descriptor for an LBR AUGRU backward propagation + /// primitive. + lbr_augru_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an LBR AUGRU backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for an LBR AUGRU backward propagation + /// primitive. + /// @param cache_blob Cache blob. + lbr_augru_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_rnn + +/// @addtogroup dnnl_api_shuffle Shuffle +/// +/// A primitive to shuffle tensor data along an axis. +/// +/// @sa @ref dev_guide_shuffle in developer guide +/// +/// @{ + +/// Shuffle forward propagation primitive. +struct shuffle_forward : public primitive { + /// Primitive descriptor for a shuffle forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a shuffle forward propagation + /// primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param axis The axis along which the data is shuffled. + /// @param group_size Shuffle group size. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &dst_desc, + int axis, int group_size, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_shuffle_forward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + src_desc.get(), dst_desc.get(), axis, group_size, + attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the shuffle forward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a shuffle forward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for a shuffle forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::shuffle, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_axis()const + int get_axis() const { return base::get_axis(); } + + /// @copydoc dnnl::primitive_desc_base::get_group_size()const + memory::dim get_group_size() const { return base::get_group_size(); } + }; + + /// Default constructor. Produces an empty object. + shuffle_forward() = default; + + /// Constructs a shuffle forward propagation primitive. + /// @param pd Primitive descriptor for a shuffle forward propagation + /// primitive. + shuffle_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a shuffle forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for a shuffle forward propagation + /// primitive. + /// @param cache_blob Cache blob. + shuffle_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Shuffle backward propagation primitive. +struct shuffle_backward : public primitive { + /// Primitive descriptor for a shuffle backward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a shuffle backward propagation + /// primitive. + /// + /// @param aengine Engine to use. + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param axis The axis along which the data is shuffled. + /// @param group_size Shuffle group size. + /// @param hint_fwd_pd Primitive descriptor for a shuffle forward + /// propagation primitive. It is used as a hint for deciding which + /// memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, int axis, int group_size, + const shuffle_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_shuffle_backward_primitive_desc_create( + &pd, aengine.get(), diff_src_desc.get(), + diff_dst_desc.get(), axis, group_size, hint_fwd_pd.get(), + attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the shuffle backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a shuffle backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a shuffle backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::shuffle, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_axis()const + int get_axis() const { return base::get_axis(); } + + /// @copydoc dnnl::primitive_desc_base::get_group_size()const + memory::dim get_group_size() const { return base::get_group_size(); } + }; + + /// Default constructor. Produces an empty object. + shuffle_backward() = default; + + /// Constructs a shuffle backward propagation primitive. + /// @param pd Primitive descriptor for a shuffle backward propagation + /// primitive. + shuffle_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a shuffle backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for a shuffle backward propagation + /// primitive. + /// @param cache_blob Cache blob. + shuffle_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_shuffle + +/// @addtogroup dnnl_api_binary Binary +/// +/// A primitive to perform tensor operations over two tensors. +/// +/// @sa @ref dev_guide_binary in developer guide +/// +/// @{ + +/// Elementwise binary operator primitive. +struct binary : public primitive { + /// Primitive descriptor for an elementwise binary operator primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for an elementwise binary operator + /// primitive. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Elementwise binary algorithm. + /// @param src0 Memory descriptor for source tensor #0. + /// @param src1 Memory descriptor for source tensor #1. + /// @param dst Memory descriptor for destination tensor. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src0, const memory::desc &src1, + const memory::desc &dst, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_binary_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aalgorithm), src0.get(), + src1.get(), dst.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the binary operation primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for an elementwise binary operator + /// primitive with support of ternary operators. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Elementwise binary algorithm. + /// @param src0 Memory descriptor for source tensor #0. + /// @param src1 Memory descriptor for source tensor #1. + /// @param src2 Memory descriptor for source tensor #2 for ternary + /// operations. Might be empty. + /// @param dst Memory descriptor for destination tensor. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src0, const memory::desc &src1, + const memory::desc &src2, const memory::desc &dst, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_binary_primitive_desc_create_v2(&pd, + aengine.get(), dnnl::convert_to_c(aalgorithm), src0.get(), + src1.get(), src2.get(), dst.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the binary v2 operation primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a binary primitive from a C + /// API primitive descriptor that must have a matching kind. + /// + /// @param pd C API primitive descriptor for a binary primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::binary) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc(int)const + memory::desc src_desc(int idx = 0) const { return base::src_desc(idx); } + + /// Returns the memory descriptor for source #0. + memory::desc src0_desc() const { return base::src_desc(0); } + + /// Returns the memory descriptor for source #1. + memory::desc src1_desc() const { return base::src_desc(1); } + + /// Returns the memory descriptor for source #2. + memory::desc src2_desc() const { return base::src_desc(2); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + }; + + /// Default constructor. Produces an empty object. + binary() = default; + + /// Constructs an elementwise binary operation primitive. + /// @param pd Primitive descriptor for an elementwise binary operation + /// primitive. + binary(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs an elementwise binary operation primitive from a cache blob. + /// @param pd Primitive descriptor for an elementwise binary operation + /// primitive. + /// @param cache_blob Cache blob. + binary(const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_binary + +/// @addtogroup dnnl_api_matmul Matrix Multiplication +/// +/// A primitive to perform matrix-matrix multiplication. The batched mode +/// is supported with 3D tensors. +/// +/// @sa @ref dev_guide_matmul in developer guide +/// +/// +/// @{ + +/// Matrix multiplication (matmul) primitive. +struct matmul : public primitive { + /// Primitive descriptor for a matmul primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a matmul primitive + /// without bias. + /// + /// @param aengine Engine to use. + /// @param src_desc Memory descriptor for source (matrix A). + /// @param weights_desc Memory descriptor for weights (matrix B). + /// @param dst_desc Memory descriptor for destination (matrix C). + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &dst_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, src_desc, weights_desc, nullptr, dst_desc, + attr, allow_empty) {} + + /// Constructs a primitive descriptor for a matmul primitive with bias. + /// + /// @param aengine Engine to use. + /// @param src_desc Memory descriptor for source (matrix A). + /// @param weights_desc Memory descriptor for weights (matrix B). + /// @param dst_desc Memory descriptor for destination (matrix C). + /// @param bias_desc Memory descriptor for bias. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc &bias_desc, + const memory::desc &dst_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, src_desc, weights_desc, &bias_desc, + dst_desc, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a matmul primitive from a C + /// API primitive descriptor that must have a matching kind. + /// + /// @param pd C API primitive descriptor for a matmul primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::matmul) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return query_md(query::src_md, 0); } + + /// @copydoc dnnl::primitive_desc_base::weights_desc()const + memory::desc weights_desc() const { + return query_md(query::weights_md, 0); + } + + /// @copydoc dnnl::convolution_forward::primitive_desc::bias_desc()const + memory::desc bias_desc() const { + return query_md(query::weights_md, 1); + } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return query_md(query::dst_md, 0); } + + private: + primitive_desc(const engine &aengine, const memory::desc &src_desc, + const memory::desc &weights_desc, const memory::desc *bias_desc, + const memory::desc &dst_desc, const primitive_attr &attr, + bool allow_empty) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_matmul_primitive_desc_create(&pd, + aengine.get(), src_desc.get(), weights_desc.get(), + optional_arg(bias_desc), dst_desc.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the matmul primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + matmul() = default; + + /// Constructs a matmul primitive. + /// @param pd Primitive descriptor for a matmul primitive. + matmul(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a matmul primitive from a cache blob. + /// @param pd Primitive descriptor for a matmul primitive. + /// @param cache_blob Cache blob. + matmul(const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_matmul + +/// @addtogroup dnnl_api_resampling Resampling +/// +/// A primitive to compute resampling operation on 1D, 2D or 3D data tensor +/// using Nearest Neighbor, or Linear (Bilinear, Trilinear) interpolation +/// method. +/// +/// @sa @ref dev_guide_resampling in developer guide +/// +/// @{ + +/// Resampling forward propagation. +struct resampling_forward : public primitive { + /// Primitive descriptor for a resampling forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a resampling forward + /// propagation primitive using source and destination memory + /// descriptors. + /// + /// @note + /// Destination memory descriptor may be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm resampling algorithm kind: either + /// #dnnl::algorithm::resampling_nearest, or + /// #dnnl::algorithm::resampling_linear + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &dst_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, nullptr, src_desc, + &dst_desc, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a resampling forward + /// propagation primitive using source memory descriptor and + /// factors. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm resampling algorithm kind: either + /// #dnnl::algorithm::resampling_nearest, or + /// #dnnl::algorithm::resampling_linear + /// @param factors Vector of scaling factors for spatial dimension. + /// @param src_desc Source memory descriptor. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const std::vector &factors, + const memory::desc &src_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, &factors, + src_desc, nullptr, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a resampling forward + /// propagation primitive. + /// + /// @note + /// The destination memory descriptor may be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm resampling algorithm kind: either + /// #dnnl::algorithm::resampling_nearest, or + /// #dnnl::algorithm::resampling_linear + /// @param factors Vector of scaling factors for spatial dimension. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const std::vector &factors, + const memory::desc &src_desc, const memory::desc &dst_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aprop_kind, aalgorithm, &factors, + src_desc, &dst_desc, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a resampling forward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a resampling forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::resampling, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + private: + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const std::vector *factors, + const memory::desc &src_desc, const memory::desc *dst_desc, + const primitive_attr &attr, bool allow_empty) { + + if (factors) + memory::validate_dims(*factors, src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_resampling_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + convert_to_c(aalgorithm), optional_arg(factors), + src_desc.get(), optional_arg(dst_desc), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the resampling forward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + resampling_forward() = default; + + /// Constructs a resampling forward propagation primitive. + /// @param pd Primitive descriptor for a resampling forward propagation + /// primitive. + resampling_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a resampling forward propagation primitive from a cache + /// blob. + /// @param pd Primitive descriptor for a resampling forward propagation + /// primitive. + /// @param cache_blob Cache blob. + resampling_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Resampling backward propagation primitive. +struct resampling_backward : public primitive { + /// Primitive descriptor for resampling backward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a resampling backward + /// propagation primitive using source and destination memory + /// descriptors. + /// + /// @param aengine Engine to use. + /// @param aalgorithm resampling algorithm kind: either + /// #dnnl::algorithm::resampling_nearest, or + /// #dnnl::algorithm::resampling_linear + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param hint_fwd_pd Primitive descriptor for a resampling + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, + const resampling_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, nullptr, diff_src_desc, + diff_dst_desc, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for resampling backward + /// propagation primitive. + /// + /// @param aengine Engine to use. + /// @param aalgorithm resampling algorithm kind: either + /// #dnnl::algorithm::resampling_nearest, or + /// #dnnl::algorithm::resampling_linear + /// @param factors Vector of scaling factors for spatial dimension. + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param hint_fwd_pd Primitive descriptor for a resampling + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const std::vector &factors, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, + const resampling_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) + : primitive_desc(aengine, aalgorithm, &factors, diff_src_desc, + diff_dst_desc, hint_fwd_pd, attr, allow_empty) {} + + /// Constructs a primitive descriptor for a resampling backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a resampling backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::resampling, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + private: + primitive_desc(const engine &aengine, algorithm aalgorithm, + const std::vector *factors, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, + const resampling_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr, bool allow_empty) { + + if (factors) + memory::validate_dims(*factors, diff_src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status + = dnnl_resampling_backward_primitive_desc_create(&pd, + aengine.get(), convert_to_c(aalgorithm), + optional_arg(factors), diff_src_desc.get(), + diff_dst_desc.get(), hint_fwd_pd.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the resampling backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + }; + + /// Default constructor. Produces an empty object. + resampling_backward() = default; + + /// Constructs a resampling backward propagation primitive. + /// @param pd Primitive descriptor for a resampling backward propagation + /// primitive. + resampling_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a resampling backward propagation primitive from a cache + /// blob. + /// @param pd Primitive descriptor for a resampling backward propagation + /// primitive. + /// @param cache_blob Cache blob. + resampling_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_resampling + +/// @addtogroup dnnl_api_pooling Pooling +/// +/// A primitive to perform max or average pooling with dilation. +/// +/// @sa @ref dev_guide_pooling in developer guide +/// +/// @{ + +/// Pooling forward propagation primitive. +struct pooling_forward : public primitive { + /// Primitive descriptor for a pooling forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for pooling forward propagation + /// primitive. + /// + /// Arrays @p strides, @p kernel, @p dilation, @p padding_l + /// and @p padding_r contain values for spatial dimensions only and + /// hence must have the same number of elements as there are spatial + /// dimensions. The order of values is the same as in the tensor: + /// depth (for 3D tensors), height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param aalgorithm Pooling algorithm kind: either + /// #dnnl::algorithm::pooling_max, + /// #dnnl::algorithm::pooling_avg_include_padding, + /// or #dnnl::algorithm::pooling_avg_exclude_padding. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param strides Vector of strides for spatial dimension. + /// @param kernel Vector of kernel spatial dimensions. + /// @param dilation Array of dilations for spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + algorithm aalgorithm, const memory::desc &src_desc, + const memory::desc &dst_desc, const memory::dims &strides, + const memory::dims &kernel, const memory::dims &dilation, + const memory::dims &padding_l, const memory::dims &padding_r, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + memory::validate_dims(strides, src_desc.get_ndims() - 2); + memory::validate_dims(kernel, src_desc.get_ndims() - 2); + memory::validate_dims(padding_l, src_desc.get_ndims() - 2); + memory::validate_dims(padding_r, src_desc.get_ndims() - 2); + memory::validate_dims(dilation, src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_pooling_forward_primitive_desc_create( + &pd, aengine.get(), dnnl::convert_to_c(aprop_kind), + convert_to_c(aalgorithm), src_desc.get(), dst_desc.get(), + &strides[0], &kernel[0], &dilation[0], &padding_l[0], + &padding_r[0], attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a descriptor for a pooling forward " + "propagation primitive"); + reset(pd); + } + + /// Constructs a primitive descriptor for a pooling forward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for a pooling forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::pooling, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_strides()const + memory::dims get_strides() const { return base::get_strides(); } + + /// @copydoc dnnl::primitive_desc_base::get_kernel()const + memory::dims get_kernel() const { return base::get_kernel(); } + + /// @copydoc dnnl::primitive_desc_base::get_dilations()const + memory::dims get_dilations() const { return base::get_dilations(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_l()const + memory::dims get_padding_l() const { return base::get_padding_l(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_r()const + memory::dims get_padding_r() const { return base::get_padding_r(); } + }; + + /// Default constructor. Produces an empty object. + pooling_forward() = default; + + /// Constructs a pooling forward propagation primitive. + /// + /// @param pd Primitive descriptor for a pooling forward propagation + /// primitive. + pooling_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a pooling forward propagation primitive from a cache blob. + /// + /// @param pd Primitive descriptor for a pooling forward propagation + /// primitive. + /// @param cache_blob Cache blob. + pooling_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// Pooling backward propagation primitive. +struct pooling_backward : public primitive { + /// Primitive descriptor for a pooling backward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a pooling backward propagation + /// primitive. + /// + /// Arrays @p strides, @p kernel, @p dilation, @p padding_l + /// and @p padding_r contain values for spatial dimensions only and + /// hence must have the same number of elements as there are spatial + /// dimensions. The order of values is the same as in the tensor: + /// depth (for 3D tensors), height (for 3D and 2D tensors), and width. + /// + /// @param aengine Engine to use. + /// @param aalgorithm Pooling algorithm kind: either + /// #dnnl::algorithm::pooling_max, + /// #dnnl::algorithm::pooling_avg_include_padding, + /// or #dnnl::algorithm::pooling_avg_exclude_padding. + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param strides Vector of strides for spatial dimension. + /// @param kernel Vector of kernel spatial dimensions. + /// @param dilation Array of dilations for spatial dimension. + /// @param padding_l Vector of padding values for low indices for each + /// spatial dimension `([[front,] top,] left)`. + /// @param padding_r Vector of padding values for high indices for + /// each spatial dimension `([[back,] bottom,] right)`. + /// @param hint_fwd_pd Primitive descriptor for a pooling + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &diff_src_desc, + const memory::desc &diff_dst_desc, const memory::dims &strides, + const memory::dims &kernel, const memory::dims &dilation, + const memory::dims &padding_l, const memory::dims &padding_r, + const pooling_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + memory::validate_dims(strides, diff_src_desc.get_ndims() - 2); + memory::validate_dims(kernel, diff_src_desc.get_ndims() - 2); + memory::validate_dims(padding_l, diff_src_desc.get_ndims() - 2); + memory::validate_dims(padding_r, diff_src_desc.get_ndims() - 2); + memory::validate_dims(dilation, diff_src_desc.get_ndims() - 2); + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_pooling_backward_primitive_desc_create( + &pd, aengine.get(), convert_to_c(aalgorithm), + diff_src_desc.get(), diff_dst_desc.get(), &strides[0], + &kernel[0], &dilation[0], &padding_l[0], &padding_r[0], + hint_fwd_pd.get(), attr.get()); + if (!allow_empty) + error::wrap_c_api(status, + "could not create a descriptor for a pooling backward " + "propagation primitive"); + reset(pd); + } + + /// Constructs a primitive descriptor for a pooling backward propagation + /// primitive from a C API primitive descriptor that must have a + /// matching kind. + /// + /// @param pd C API primitive descriptor for a pooling backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::pooling, + dnnl::prop_kind::backward_data) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::workspace_desc()const + memory::desc workspace_desc() const { return base::workspace_desc(); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + + /// @copydoc dnnl::primitive_desc_base::get_strides()const + memory::dims get_strides() const { return base::get_strides(); } + + /// @copydoc dnnl::primitive_desc_base::get_kernel()const + memory::dims get_kernel() const { return base::get_kernel(); } + + /// @copydoc dnnl::primitive_desc_base::get_dilations()const + memory::dims get_dilations() const { return base::get_dilations(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_l()const + memory::dims get_padding_l() const { return base::get_padding_l(); } + + /// @copydoc dnnl::primitive_desc_base::get_padding_r()const + memory::dims get_padding_r() const { return base::get_padding_r(); } + }; + + /// Default constructor. Produces an empty object. + pooling_backward() = default; + + /// Constructs a pooling backward propagation primitive. + /// + /// @param pd Primitive descriptor for a pooling backward propagation + /// primitive. + pooling_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a pooling backward propagation primitive from a cache blob. + /// + /// @param pd Primitive descriptor for a pooling backward propagation + /// primitive. + /// @param cache_blob Cache blob. + pooling_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_pooling + +/// @addtogroup dnnl_api_prelu PReLU +/// +/// PReLU primitive +/// A primitive to perform PReLU (leaky ReLU with trainable alpha parameter) +/// +/// @sa @ref dev_guide_prelu in developer guide +/// +/// @{ + +/// PReLU forward propagation primitive. +struct prelu_forward : public primitive { + /// Primitive descriptor for a PReLU forward propagation primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a PReLU forward propagation + /// primitive. + /// + /// @param aengine Engine to use. + /// @param aprop_kind Propagation kind. Possible values are + /// #dnnl::prop_kind::forward_training, and + /// #dnnl::prop_kind::forward_inference. + /// @param src_desc Source memory descriptor. + /// @param weight_desc Alpha parameters memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, prop_kind aprop_kind, + const memory::desc &src_desc, const memory::desc &weight_desc, + const memory::desc &dst_desc, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_prelu_forward_primitive_desc_create(&pd, + aengine.get(), dnnl::convert_to_c(aprop_kind), + src_desc.get(), weight_desc.get(), dst_desc.get(), + attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the prelu forward propagation primitive. Run workload " + "with environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a prelu forward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a prelu forward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::prelu, + dnnl::prop_kind::forward_training, + dnnl::prop_kind::forward_inference) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + }; + + /// Default constructor. Produces an empty object. + prelu_forward() = default; + + /// Constructs a prelu forward propagation primitive. + /// @param pd Primitive descriptor for a prelu forward propagation + /// primitive. + prelu_forward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a prelu forward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for a prelu forward propagation + /// primitive. + /// @param cache_blob Cache blob. + prelu_forward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// PReLU backward propagation primitive. +struct prelu_backward : public primitive { + /// Primitive descriptor for prelu backward propagation. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a descriptor for a PReLU backward propagation + /// primitive. + /// + /// @param aengine Engine to use. + /// @param src_desc Source memory descriptor. + /// @param weight_desc Alpha parameters memory descriptor. + /// @param diff_src_desc Diff source memory descriptor. + /// @param diff_weights_desc Diff alpha parameters memory descriptor. + /// @param diff_dst_desc Diff destination memory descriptor. + /// @param hint_fwd_pd Primitive descriptor for a PReLU + /// forward propagation primitive. It is used as a hint for + /// deciding which memory format to use. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, const memory::desc &src_desc, + const memory::desc &weight_desc, + const memory::desc &diff_src_desc, + const memory::desc &diff_weights_desc, + const memory::desc &diff_dst_desc, + const prelu_forward::primitive_desc &hint_fwd_pd, + const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_prelu_backward_primitive_desc_create( + &pd, aengine.get(), src_desc.get(), weight_desc.get(), + diff_src_desc.get(), diff_weights_desc.get(), + diff_dst_desc.get(), hint_fwd_pd.get(), attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the prelu backward propagation primitive. Run " + "workload with environment variable ONEDNN_VERBOSE=all " + "to get additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a prelu backward + /// propagation primitive from a C API primitive descriptor that must + /// have a matching kind. + /// + /// @param pd C API primitive descriptor for a prelu backward + /// propagation primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::prelu, + dnnl::prop_kind::backward) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_src_desc()const + memory::desc diff_src_desc() const { return base::diff_src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::diff_dst_desc()const + memory::desc diff_dst_desc() const { return base::diff_dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_prop_kind()const + prop_kind get_prop_kind() const { return base::get_prop_kind(); } + }; + + /// Default constructor. Produces an empty object. + prelu_backward() = default; + + /// Constructs a prelu backward propagation primitive. + /// @param pd Primitive descriptor for a prelu backward propagation + /// primitive. + prelu_backward(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a prelu backward propagation primitive from a cache blob. + /// @param pd Primitive descriptor for a prelu backward propagation + /// primitive. + /// @param cache_blob Cache blob. + prelu_backward( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_prelu + +/// @addtogroup dnnl_api_reduction Reduction +/// +/// A primitive to compute reduction operation on data tensor +/// using min, max, mul, sum, mean and norm_lp operations. +/// +/// @sa @ref dev_guide_reduction in developer guide +/// +/// @{ + +/// Reduction. +struct reduction : public primitive { + /// Primitive descriptor for a reduction primitive. + struct primitive_desc : public dnnl::primitive_desc { + /// Default constructor. Produces an empty object. + primitive_desc() = default; + + /// Constructs a primitive descriptor for a reduction primitive using + /// algorithm specific parameters, source and destination memory + /// descriptors. + /// + /// @note + /// Destination memory descriptor may be initialized with + /// #dnnl::memory::format_tag::any value of @p format_tag. + /// + /// @param aengine Engine to use. + /// @param aalgorithm reduction algorithm kind. Possible values: + /// #dnnl_reduction_max, #dnnl_reduction_min, #dnnl_reduction_sum, + /// #dnnl_reduction_mul, #dnnl_reduction_mean, + /// #dnnl_reduction_norm_lp_max, #dnnl_reduction_norm_lp_sum, + /// #dnnl_reduction_norm_lp_power_p_max, + /// #dnnl_reduction_norm_lp_power_p_sum. + /// @param p algorithm specific parameter. For Lp-norm algorithms, + /// must be a finite value >= 1.0. + /// @param eps algorithm specific parameter. + /// @param src_desc Source memory descriptor. + /// @param dst_desc Destination memory descriptor. + /// @param attr Primitive attributes to use. Attributes are optional + /// and default to empty attributes. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + primitive_desc(const engine &aengine, algorithm aalgorithm, + const memory::desc &src_desc, const memory::desc &dst_desc, + float p, float eps, const primitive_attr &attr = default_attr(), + bool allow_empty = false) { + + dnnl_primitive_desc_t pd = nullptr; + dnnl_status_t status = dnnl_reduction_primitive_desc_create(&pd, + aengine.get(), convert_to_c(aalgorithm), src_desc.get(), + dst_desc.get(), p, eps, attr.get()); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a primitive descriptor for " + "the reduction primitive. Run workload with " + "environment variable ONEDNN_VERBOSE=all to get " + "additional diagnostic information."); + reset(pd); + } + + /// Constructs a primitive descriptor for a reduction primitive from a C + /// API primitive descriptor that must have a matching kind. + /// + /// @param pd C API primitive descriptor for a reduction primitive. + primitive_desc(dnnl_primitive_desc_t pd) + : dnnl::primitive_desc(pd, dnnl::primitive::kind::reduction) {} + + /// @copydoc dnnl::primitive_desc_base::src_desc()const + memory::desc src_desc() const { return base::src_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::dst_desc()const + memory::desc dst_desc() const { return base::dst_desc(0); } + + /// @copydoc dnnl::primitive_desc_base::get_p()const + float get_p() const { return base::get_p(); } + + /// @copydoc dnnl::primitive_desc_base::get_epsilon()const + float get_epsilon() const { return base::get_epsilon(); } + + /// @copydoc dnnl::primitive_desc_base::get_algorithm()const + algorithm get_algorithm() const { return base::get_algorithm(); } + }; + + /// Default constructor. Produces an empty object. + reduction() = default; + + /// Constructs a reduction primitive. + /// @param pd Primitive descriptor for a reduction primitive. + reduction(const primitive_desc &pd) : primitive(pd) {} + + /// Constructs a reduction primitive from a cache blob. + /// @param pd Primitive descriptor for a reduction primitive. + /// @param cache_blob Cache blob. + reduction(const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd, cache_blob) {} +}; + +/// @} dnnl_api_reduction + +/// @} dnnl_api_primitives + +/// @addtogroup dnnl_api_service Service +/// +/// A set of functions that aid in oneDNN debugging and profiling. +/// +/// @{ + +/// @copydoc dnnl_version_t +using version_t = dnnl_version_t; + +/// Status values returned by the library functions. +enum class status { + /// @copydoc dnnl_success + success = dnnl_success, + /// @copydoc dnnl_out_of_memory + out_of_memory = dnnl_out_of_memory, + /// @copydoc dnnl_invalid_arguments + invalid_arguments = dnnl_invalid_arguments, + /// @copydoc dnnl_unimplemented + unimplemented = dnnl_unimplemented, + /// @copydoc dnnl_last_impl_reached + last_impl_reached = dnnl_last_impl_reached, + /// @copydoc dnnl_runtime_error + runtime_error = dnnl_runtime_error, + /// @copydoc dnnl_not_required + not_required = dnnl_not_required, +}; + +/// @copydoc dnnl_set_verbose() +inline status set_verbose(int level) { + return static_cast(dnnl_set_verbose(level)); +} + +/// @copydoc dnnl_version() +inline const version_t *version() { + return dnnl_version(); +} + +/// Returns the floating-point math mode that will be used by default +/// for all subsequently created primitives. +/// +/// @returns Output FP math mode. +inline fpmath_mode get_default_fpmath_mode() { + dnnl_fpmath_mode_t mode; + error::wrap_c_api(dnnl_get_default_fpmath_mode(&mode), + "could not get a default fpmath mode"); + return static_cast(mode); +} + +/// @copydoc dnnl_set_default_fpmath_mode() +inline status set_default_fpmath_mode(fpmath_mode mode) { + return static_cast( + dnnl_set_default_fpmath_mode(convert_to_c(mode))); +} + +/// @copydoc dnnl_set_jit_dump() +inline status set_jit_dump(int enable) { + return static_cast(dnnl_set_jit_dump(enable)); +} + +/// @copydoc dnnl_set_jit_profiling_flags() +inline status set_jit_profiling_flags(unsigned flags) { + return static_cast(dnnl_set_jit_profiling_flags(flags)); +} + +/// @copydoc dnnl_set_jit_profiling_jitdumpdir() +inline status set_jit_profiling_jitdumpdir(const std::string &dir) { + return static_cast(dnnl_set_jit_profiling_jitdumpdir(dir.c_str())); +} + +/// @copydoc dnnl_cpu_isa_t +enum class cpu_isa { + /// @copydoc dnnl_cpu_isa_default + isa_default = dnnl_cpu_isa_default, + /// @copydoc dnnl_cpu_isa_sse41 + sse41 = dnnl_cpu_isa_sse41, + /// @copydoc dnnl_cpu_isa_avx + avx = dnnl_cpu_isa_avx, + /// @copydoc dnnl_cpu_isa_avx2 + avx2 = dnnl_cpu_isa_avx2, + /// @copydoc dnnl_cpu_isa_avx2_vnni + avx2_vnni = dnnl_cpu_isa_avx2_vnni, + /// @copydoc dnnl_cpu_isa_avx2_vnni_2 + avx2_vnni_2 = dnnl_cpu_isa_avx2_vnni_2, + /// @copydoc dnnl_cpu_isa_avx512_core + avx512_core = dnnl_cpu_isa_avx512_core, + /// @copydoc dnnl_cpu_isa_avx512_core_vnni + avx512_core_vnni = dnnl_cpu_isa_avx512_core_vnni, + /// @copydoc dnnl_cpu_isa_avx512_core_bf16 + avx512_core_bf16 = dnnl_cpu_isa_avx512_core_bf16, + /// @copydoc dnnl_cpu_isa_avx10_1_512 + avx10_1_512 = dnnl_cpu_isa_avx10_1_512, + /// @copydoc dnnl_cpu_isa_avx512_core_fp16 + avx512_core_fp16 = dnnl_cpu_isa_avx512_core_fp16, + /// @copydoc dnnl_cpu_isa_avx10_1_512_amx + avx10_1_512_amx = dnnl_cpu_isa_avx10_1_512_amx, + /// @copydoc dnnl_cpu_isa_avx512_core_amx + avx512_core_amx = dnnl_cpu_isa_avx512_core_amx, + /// @copydoc dnnl_cpu_isa_avx10_1_512_amx_fp16 + avx10_1_512_amx_fp16 = dnnl_cpu_isa_avx10_1_512_amx_fp16, + /// @copydoc dnnl_cpu_isa_avx512_core_amx_fp16 + avx512_core_amx_fp16 = dnnl_cpu_isa_avx512_core_amx_fp16, + /// @copydoc dnnl_cpu_isa_avx10_2_512 + avx10_2_512 = dnnl_cpu_isa_avx10_2_512, + /// @copydoc dnnl_cpu_isa_avx10_2_512_amx_2 + avx10_2_512_amx_2 = dnnl_cpu_isa_avx10_2_512_amx_2, +}; + +/// @copydoc dnnl_set_max_cpu_isa() +inline status set_max_cpu_isa(cpu_isa isa) { + return static_cast( + dnnl_set_max_cpu_isa(static_cast(isa))); +} + +/// @copydoc dnnl_get_effective_cpu_isa() +inline cpu_isa get_effective_cpu_isa() { + return static_cast(dnnl_get_effective_cpu_isa()); +} + +/// @copydoc dnnl_cpu_isa_hints_t +enum class cpu_isa_hints { + /// @copydoc dnnl_cpu_isa_no_hints + no_hints = dnnl_cpu_isa_no_hints, + /// @copydoc dnnl_cpu_isa_prefer_ymm + prefer_ymm = dnnl_cpu_isa_prefer_ymm, +}; + +/// @copydoc dnnl_set_cpu_isa_hints() +inline status set_cpu_isa_hints(cpu_isa_hints isa_hints) { + return static_cast(dnnl_set_cpu_isa_hints( + static_cast(isa_hints))); +} + +/// @copydoc dnnl_get_cpu_isa_hints() +inline cpu_isa_hints get_cpu_isa_hints() { + return static_cast(dnnl_get_cpu_isa_hints()); +} + +/// @} dnnl_api_service + +#ifdef DNNL_EXPERIMENTAL_PROFILING +/// @addtogroup dnnl_api_profiling Profiling +/// @{ + +/// Profiling data kind. +enum class profiling_data_kind { + /// Undefined profiling data kind. + undef = dnnl_profiling_data_kind_undef, + /// Data kind to query an execution time in nanoseconds. + time = dnnl_profiling_data_kind_time, +}; + +/// Resets a profiler's state. +/// +/// @param stream Stream associated with the profiler. +inline void reset_profiling(stream &stream) { + error::wrap_c_api( + dnnl_reset_profiling(stream.get()), "could not reset profiling"); +} + +/// Returns requested profiling data. The profiling data accumulates for each +/// primitive execution. The size of the vector will be equal to the number +/// of executions since the last `dnnl::reset_profiling` call. +/// +/// The profiling data can be reset by calling #dnnl::reset_profiling. +/// +/// @note +/// It is required to wait for all submitted primitives to complete +/// using #dnnl::stream::wait prior to querying profiling data. +/// +/// @param stream Stream that was used for executing a primitive that +/// is being profiled. +/// @param data_kind Profiling data kind to query. +/// +/// @returns A vector with the requested profiling data. +inline std::vector get_profiling_data( + stream &stream, profiling_data_kind data_kind) { + int num_entries = 0; + error::wrap_c_api( + dnnl_query_profiling_data(stream.get(), + static_cast(data_kind), + &num_entries, nullptr), + "could not get number of entries for profiling data"); + + if (num_entries == 0) return {}; + + std::vector data(num_entries); + error::wrap_c_api( + dnnl_query_profiling_data(stream.get(), + static_cast(data_kind), + &num_entries, data.data()), + "could not get profiling data"); + return data; +} + +/// @} dnnl_api_profiling +#endif + +/// @addtogroup dnnl_api_primitive_cache Primitive Cache +/// +/// A set of functions that provide primitive cache control. +/// +/// @{ + +/// Returns the number of primitives that can be held in the primitive cache +/// at the same time. +inline int get_primitive_cache_capacity() { + int result = 0; + error::wrap_c_api(dnnl_get_primitive_cache_capacity(&result), + "could not get primitive cache capacity"); + return result; +} + +/// @copydoc dnnl_set_primitive_cache_capacity(int capacity) +inline void set_primitive_cache_capacity(int capacity) { + error::wrap_c_api(dnnl_set_primitive_cache_capacity(capacity), + "could not set primitive cache capacity"); +} + +/// @} dnnl_api_primitive_cache + +/// @addtogroup dnnl_api_blas BLAS functions +/// +/// A subset of Basic Linear Algebra (BLAS) functions that perform +/// matrix-matrix multiplication. +/// +/// @{ + +/// @copydoc dnnl_sgemm() +inline status sgemm(char transa, char transb, dnnl_dim_t M, dnnl_dim_t N, + dnnl_dim_t K, float alpha, const float *A, dnnl_dim_t lda, + const float *B, dnnl_dim_t ldb, float beta, float *C, dnnl_dim_t ldc) { + return static_cast(dnnl_sgemm( + transa, transb, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc)); +} + +/// @copydoc dnnl_gemm_u8s8s32() +inline status gemm_u8s8s32(char transa, char transb, char offsetc, dnnl_dim_t M, + dnnl_dim_t N, dnnl_dim_t K, float alpha, const uint8_t *A, + dnnl_dim_t lda, uint8_t ao, const int8_t *B, dnnl_dim_t ldb, int8_t bo, + float beta, int32_t *C, dnnl_dim_t ldc, const int32_t *co) { + return static_cast(dnnl_gemm_u8s8s32(transa, transb, offsetc, M, N, + K, alpha, A, lda, ao, B, ldb, bo, beta, C, ldc, co)); +} + +/// @copydoc dnnl_gemm_s8s8s32() +inline status gemm_s8s8s32(char transa, char transb, char offsetc, dnnl_dim_t M, + dnnl_dim_t N, dnnl_dim_t K, float alpha, const int8_t *A, + dnnl_dim_t lda, int8_t ao, const int8_t *B, dnnl_dim_t ldb, int8_t bo, + float beta, int32_t *C, dnnl_dim_t ldc, const int32_t *co) { + return static_cast(dnnl_gemm_s8s8s32(transa, transb, offsetc, M, N, + K, alpha, A, lda, ao, B, ldb, bo, beta, C, ldc, co)); +} + +/// @} dnnl_api_blas + +// implementation section + +/// @cond DO_NOT_DOCUMENT_THIS +inline primitive::primitive(const_dnnl_primitive_desc_t c_pd) { + dnnl_primitive_t result; + error::wrap_c_api(dnnl_primitive_create(&result, c_pd), + "could not create a primitive"); + reset(result); +} + +inline primitive::primitive(const_dnnl_primitive_desc_t c_pd, + const std::vector &cache_blob) { + dnnl_primitive_t result; + size_t size = cache_blob.size(); + const uint8_t *cache_blob_data = cache_blob.data(); + error::wrap_c_api(dnnl_primitive_create_from_cache_blob( + &result, c_pd, size, cache_blob_data), + "could not create a primitive from a cache blob"); + reset(result); +} + +inline primitive::primitive(const primitive_desc &pd) : primitive(pd.get()) {} +inline primitive::primitive( + const primitive_desc &pd, const std::vector &cache_blob) + : primitive(pd.get(), cache_blob) {} + +inline void primitive::execute(const stream &astream, + const std::unordered_map &args) const { + std::vector c_args; + c_args.reserve(args.size()); + for (const auto &a : args) + c_args.push_back({a.first, a.second.get(true)}); + + error::wrap_c_api(dnnl_primitive_execute(get(), astream.get(), + (int)c_args.size(), c_args.data()), + "could not execute a primitive"); +} + +/// @endcond + +} // namespace dnnl + +/// oneAPI namespace + +/// The oneAPI namespace. +/// Contains the oneapi::dnnl namespace as an alias to the ::dnnl namespace. +namespace oneapi { +// Note: without this guard, doxygen warns of potentially recursive namespace +#ifndef DOXYGEN_SHOULD_SKIP_THIS +/// oneDNN alias namespace +namespace dnnl = ::dnnl; +#endif +} // namespace oneapi + +/// @} dnnl_api + +// NOLINTEND(readability-identifier-naming) +#endif /* ONEAPI_DNNL_DNNL_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common.h new file mode 100644 index 0000000000000000000000000000000000000000..2ba5aebbc307d8402a6cabd02cde130d7464c352 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common.h @@ -0,0 +1,180 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// C common API + +#ifndef ONEAPI_DNNL_DNNL_COMMON_H +#define ONEAPI_DNNL_DNNL_COMMON_H + +#include "oneapi/dnnl/dnnl_common_types.h" +#include "oneapi/dnnl/dnnl_config.h" +#include "oneapi/dnnl/dnnl_version.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api oneDNN API +/// @{ + +/// @addtogroup dnnl_api_common Common API +/// @{ + +/// @addtogroup dnnl_api_engine Engine +/// @{ + +/// Returns the number of engines of a particular kind. +/// +/// @param kind Kind of engines to count. +/// @returns Count of the engines. +size_t DNNL_API dnnl_engine_get_count(dnnl_engine_kind_t kind); + +/// Creates an engine. +/// +/// @param engine Output engine. +/// @param kind Engine kind. +/// @param index Engine index that should be between 0 and the count of +/// engines of the requested kind. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_engine_create( + dnnl_engine_t *engine, dnnl_engine_kind_t kind, size_t index); + +/// Returns the kind of an engine. +/// +/// @param engine Engine to query. +/// @param kind Output engine kind. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_engine_get_kind( + dnnl_engine_t engine, dnnl_engine_kind_t *kind); + +/// Destroys an engine. +/// +/// @param engine Engine to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_engine_destroy(dnnl_engine_t engine); + +/// @} dnnl_api_engine + +/// @addtogroup dnnl_api_stream Stream +/// @{ + +/// Creates an execution stream. +/// +/// @param stream Output execution stream. +/// @param engine Engine to create the execution stream on. +/// @param flags Stream behavior flags (@sa dnnl_stream_flags_t). +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_stream_create( + dnnl_stream_t *stream, dnnl_engine_t engine, unsigned flags); + +/// Returns the engine of a stream object. +/// +/// @param stream Stream object. +/// @param engine Output engine on which the stream is created. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_stream_get_engine( + const_dnnl_stream_t stream, dnnl_engine_t *engine); + +/// Waits for all primitives in the execution stream to finish computations. +/// +/// @param stream Execution stream. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_stream_wait(dnnl_stream_t stream); + +/// Destroys an execution stream. +/// +/// @param stream Execution stream to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_stream_destroy(dnnl_stream_t stream); + +/// @} dnnl_api_stream + +/// @addtogroup dnnl_api_fpmath_mode Floating-point Math Mode +/// @{ + +/// Returns the floating-point math mode that will be used by default +/// for all subsequently created primitives. +/// +/// @param mode Output FP math mode. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_get_default_fpmath_mode(dnnl_fpmath_mode_t *mode); + +/// Sets the floating-point math mode that will be used by default +/// for all subsequently created primitives. +/// +/// @param mode FP math mode. The possible values are: +/// #dnnl_fpmath_mode_strict, +/// #dnnl_fpmath_mode_bf16, +/// #dnnl_fpmath_mode_f16, +/// #dnnl_fpmath_mode_tf32, +/// #dnnl_fpmath_mode_any. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_set_default_fpmath_mode(dnnl_fpmath_mode_t mode); + +/// @} dnnl_api_fpmath_mode + +/// @addtogroup dnnl_api_service +/// @{ + +/// Configures verbose output to stdout. +/// +/// @note +/// Enabling verbose output affects performance. +/// This setting overrides the ONEDNN_VERBOSE environment variable. +/// +/// @param level Verbosity level: +/// - 0: no verbose output (default), +/// - 1: primitive and graph information at execution, +/// - 2: primitive and graph information at creation/compilation and execution. +/// @returns #dnnl_invalid_arguments/#dnnl::status::invalid_arguments if the +/// @p level value is invalid, and #dnnl_success/#dnnl::status::success on +/// success. +dnnl_status_t DNNL_API dnnl_set_verbose(int level); + +/// Returns library version information. +/// @returns Pointer to a constant structure containing +/// - major: major version number, +/// - minor: minor version number, +/// - patch: patch release number, +/// - hash: git commit hash. +const dnnl_version_t DNNL_API *dnnl_version(void); + +/// @} dnnl_api_service + +/// @} dnnl_api_common + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif /* ONEAPI_DNNL_DNNL_COMMON_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common.hpp new file mode 100644 index 0000000000000000000000000000000000000000..96a50f047fa6b719c5a4abd9e920e1b66fe93926 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common.hpp @@ -0,0 +1,486 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// C++ common API + +#ifndef ONEAPI_DNNL_DNNL_COMMON_HPP +#define ONEAPI_DNNL_DNNL_COMMON_HPP +// NOLINTBEGIN(readability-identifier-naming) + +/// @cond DO_NOT_DOCUMENT_THIS +#include +#include +#include +#include +#include +#include +#include + +#include "oneapi/dnnl/dnnl_common.h" +/// @endcond + +// If exceptions are enabled: +// - gcc < 5 only define __EXCEPTIONS +// - MSVC and Clang only define __cpp_exceptions +// - new gcc and icx/icpx define both +#ifndef DNNL_ENABLE_EXCEPTIONS +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) +#define DNNL_ENABLE_EXCEPTIONS 1 +#else +#define DNNL_ENABLE_EXCEPTIONS 0 +#endif +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define DNNL_TRAP() __builtin_trap() +#elif defined(__INTEL_COMPILER) || defined(_MSC_VER) +#define DNNL_TRAP() __debugbreak() +#else +#error "unknown compiler" +#endif + +#if DNNL_ENABLE_EXCEPTIONS +#define DNNL_THROW_ERROR(status, msg) throw error(status, msg) +#else +#include +#define DNNL_THROW_ERROR(status, msg) \ + do { \ + fputs(msg, stderr); \ + DNNL_TRAP(); \ + } while (0) +#endif + +/// @addtogroup dnnl_api oneDNN API +/// @{ + +/// oneDNN namespace +namespace dnnl { + +/// @addtogroup dnnl_api_common Common API +/// @{ + +/// @addtogroup dnnl_api_utils Utilities +/// Utility types and definitions. +/// @{ + +/// oneDNN exception class. +/// +/// This class captures the status returned by a failed C API function and +/// the error message from the call site. +struct error : public std::exception { + dnnl_status_t status; + const char *message; + + /// Constructs an instance of an exception class. + /// + /// @param status The error status returned by a C API function. + /// @param message The error message. + error(dnnl_status_t status, const char *message) + : status(status), message(message) {} + + /// Returns the explanatory string. + const char *what() const noexcept override { return message; } + + /// A convenience function for wrapping calls to C API functions. Checks + /// the return status and throws an dnnl::error in case of failure. + /// + /// @param status The error status returned by a C API function. + /// @param message The error message. + static void wrap_c_api(dnnl_status_t status, const char *message) { + if (status != dnnl_success) DNNL_THROW_ERROR(status, message); + } +}; + +/// A class that provides the destructor for a oneDNN C API handle. +template +struct handle_traits {}; + +/// oneDNN C API handle wrapper class. +/// +/// This class is used as the base class for primitive (dnnl::primitive), +/// engine (dnnl::engine), and stream (dnnl::stream) classes, as well as +/// others. An object of the dnnl::handle class can be passed by value. +/// +/// A handle can be weak, in which case it follows std::weak_ptr semantics. +/// Otherwise, it follows `std::shared_ptr` semantics. +/// +/// @note +/// The implementation stores oneDNN C API handles in a `std::shared_ptr` +/// with deleter set to a dummy function in the weak mode. +/// +template > +struct handle { +private: + static dnnl_status_t dummy_destructor(T) { return dnnl_success; } + std::shared_ptr::type> data_ {nullptr}; + +protected: + bool operator==(const T other) const { return other == data_.get(); } + bool operator!=(const T other) const { return !(*this == other); } + +public: + /// Constructs an empty handle object. + /// + /// @warning + /// Uninitialized object cannot be used in most library calls and is + /// equivalent to a null pointer. Any attempt to use its methods, or + /// passing it to the other library function, will cause an exception + /// to be thrown. + handle() = default; + + /// Copy constructor. + handle(const handle &) = default; + /// Assignment operator. + handle &operator=(const handle &) = default; + /// Move constructor. + handle(handle &&) = default; + /// Move assignment operator. + handle &operator=(handle &&) = default; + + /// Constructs a handle wrapper object from a C API handle. + /// + /// @param t The C API handle to wrap. + /// @param weak A flag specifying whether to construct a weak wrapper; + /// defaults to @c false. + explicit handle(T t, bool weak = false) { reset(t, weak); } + + /// Resets the handle wrapper objects to wrap a new C API handle. + /// + /// @param t The new value of the C API handle. + /// @param weak A flag specifying whether the wrapper should be weak; + /// defaults to @c false. + void reset(T t, bool weak = false) { + data_.reset(t, weak ? &dummy_destructor : traits::destructor); + } + + /// Returns the underlying C API handle. + /// + /// @param allow_empty A flag signifying whether the method is allowed to + /// return an empty (null) object without throwing an exception. + /// @returns The underlying C API handle. + T get(bool allow_empty = false) const { + T result = data_.get(); + if (allow_empty == false && result == nullptr) + DNNL_THROW_ERROR( + dnnl_invalid_arguments, "object is not initialized"); + return result; + } + + /// Converts a handle to the underlying C API handle type. Does not throw + /// and returns `nullptr` if the object is empty. + /// + /// @returns The underlying C API handle. + explicit operator T() const { return get(true); } + + /// Checks whether the object is not empty. + /// + /// @returns Whether the object is not empty. + explicit operator bool() const { return get(true) != nullptr; } + + /// Equality operator. + /// + /// @param other Another handle wrapper. + /// @returns @c true if this and the other handle wrapper manage the same + /// underlying C API handle, and @c false otherwise. Empty handle + /// objects are considered to be equal. + bool operator==(const handle &other) const { + return other.data_.get() == data_.get(); + } + + /// Inequality operator. + /// + /// @param other Another handle wrapper. + /// @returns @c true if this and the other handle wrapper manage different + /// underlying C API handles, and @c false otherwise. Empty handle + /// objects are considered to be equal. + bool operator!=(const handle &other) const { return !(*this == other); } +}; + +/// @} dnnl_api_utils + +/// @addtogroup dnnl_api_engine Engine +/// +/// An abstraction of a computational device: a CPU, a specific GPU +/// card in the system, etc. Most primitives are created to execute +/// computations on one specific engine. The only exceptions are reorder +/// primitives that transfer data between two different engines. +/// +/// @sa @ref dev_guide_basic_concepts +/// +/// @{ + +/// @cond DO_NOT_DOCUMENT_THIS +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_engine_t p) { + return dnnl_engine_destroy(p); + } +}; +/// @endcond + +/// An execution engine. +struct engine : public handle { + friend struct primitive; + friend struct reorder; + + /// Kinds of engines. + enum class kind { + /// An unspecified engine + any = dnnl_any_engine, + /// CPU engine + cpu = dnnl_cpu, + /// GPU engine + gpu = dnnl_gpu, + }; + + using handle::handle; + + /// Constructs an empty engine. An empty engine cannot be used in any + /// operations. + engine() = default; + + /// Returns the number of engines of a certain kind. + /// + /// @param akind The kind of engines to count. + /// @returns The number of engines of the specified kind. + static size_t get_count(kind akind) { + return dnnl_engine_get_count(convert_to_c(akind)); + } + + /// Constructs an engine. + /// + /// @param akind The kind of engine to construct. + /// @param index The index of the engine. Must be less than the value + /// returned by #get_count() for this particular kind of engine. + engine(kind akind, size_t index) { + dnnl_engine_t engine; + error::wrap_c_api( + dnnl_engine_create(&engine, convert_to_c(akind), index), + "could not create an engine"); + reset(engine); + } + + /// Returns the kind of the engine. + /// @returns The kind of the engine. + kind get_kind() const { + dnnl_engine_kind_t kind; + error::wrap_c_api(dnnl_engine_get_kind(get(), &kind), + "could not get kind of an engine"); + return static_cast(kind); + } + +private: + static dnnl_engine_kind_t convert_to_c(kind akind) { + return static_cast(akind); + } +}; + +/// Converts engine kind enum value from C++ API to C API type. +/// +/// @param akind C++ API engine kind enum value. +/// @returns Corresponding C API engine kind enum value. +inline dnnl_engine_kind_t convert_to_c(engine::kind akind) { + return static_cast(akind); +} + +/// @} dnnl_api_engine + +/// @addtogroup dnnl_api_stream Stream +/// +/// An encapsulation of execution context tied to a particular engine. +/// +/// @sa @ref dev_guide_basic_concepts +/// +/// @{ + +/// @cond DO_NOT_DOCUMENT_THIS +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_stream_t p) { + return dnnl_stream_destroy(p); + } +}; +/// @endcond + +/// An execution stream. +struct stream : public handle { + using handle::handle; + + /// Stream flags. Can be combined using the bitwise OR operator. + enum class flags : unsigned { + /// In-order execution. + in_order = dnnl_stream_in_order, + /// Out-of-order execution. + out_of_order = dnnl_stream_out_of_order, + /// Default stream configuration. + default_flags = dnnl_stream_default_flags, +#ifdef DNNL_EXPERIMENTAL_PROFILING + /// Enables profiling capabilities. + profiling = dnnl_stream_profiling, +#endif + }; + + /// Constructs an empty stream. An empty stream cannot be used in any + /// operations. + stream() = default; + + /// Constructs a stream for the specified engine and with behavior + /// controlled by the specified flags. + /// + /// @param aengine Engine to create the stream on. + /// @param aflags Flags controlling stream behavior. + explicit stream( + const engine &aengine, flags aflags = flags::default_flags) { + dnnl_stream_t stream; + error::wrap_c_api(dnnl_stream_create(&stream, aengine.get(), + static_cast(aflags)), + "could not create a stream"); + reset(stream); + } + + /// Returns the associated engine. + engine get_engine() const { + dnnl_engine_t c_engine; + error::wrap_c_api(dnnl_stream_get_engine(get(), &c_engine), + "could not get an engine from a stream object"); + return engine(c_engine, true); + } + + /// Waits for all primitives executing in the stream to finish. + /// @returns The stream itself. + stream &wait() { + error::wrap_c_api( + dnnl_stream_wait(get()), "could not wait on a stream"); + return *this; + } +}; + +//NOLINTBEGIN(bugprone-macro-parentheses) +#define DNNL_DEFINE_BITMASK_OPS(enum_name) \ + inline enum_name operator|(enum_name lhs, enum_name rhs) { \ + return static_cast( \ + static_cast(lhs) | static_cast(rhs)); \ + } \ +\ + inline enum_name operator&(enum_name lhs, enum_name rhs) { \ + return static_cast( \ + static_cast(lhs) & static_cast(rhs)); \ + } \ +\ + inline enum_name operator^(enum_name lhs, enum_name rhs) { \ + return static_cast( \ + static_cast(lhs) ^ static_cast(rhs)); \ + } \ +\ + inline enum_name &operator|=(enum_name &lhs, enum_name rhs) { \ + lhs = static_cast( \ + static_cast(lhs) | static_cast(rhs)); \ + return lhs; \ + } \ +\ + inline enum_name &operator&=(enum_name &lhs, enum_name rhs) { \ + lhs = static_cast( \ + static_cast(lhs) & static_cast(rhs)); \ + return lhs; \ + } \ +\ + inline enum_name &operator^=(enum_name &lhs, enum_name rhs) { \ + lhs = static_cast( \ + static_cast(lhs) ^ static_cast(rhs)); \ + return lhs; \ + } \ +\ + inline enum_name operator~(enum_name rhs) { \ + return static_cast(~static_cast(rhs)); \ + } +//NOLINTEND(bugprone-macro-parentheses) + +DNNL_DEFINE_BITMASK_OPS(stream::flags) + +/// @} dnnl_api_stream + +/// @addtogroup dnnl_api_fpmath_mode Floating-point Math Mode +/// @{ + +/// Floating-point math mode +enum class fpmath_mode { + /// Default behavior, no downconversions allowed + strict = dnnl_fpmath_mode_strict, + /// Implicit f32->bf16 conversions allowed + bf16 = dnnl_fpmath_mode_bf16, + /// Implicit f32->f16 conversions allowed + f16 = dnnl_fpmath_mode_f16, + /// Implicit f32->tf32 conversions allowed + tf32 = dnnl_fpmath_mode_tf32, + /// Implicit f32->f16, f32->tf32 or f32->bf16 conversions allowed + any = dnnl_fpmath_mode_any +}; + +/// Converts an fpmath mode enum value from C++ API to C API type. +/// +/// @param mode C++ API fpmath mode enum value. +/// @returns Corresponding C API fpmath mode enum value. +inline dnnl_fpmath_mode_t convert_to_c(fpmath_mode mode) { + return static_cast(mode); +} + +/// @} dnnl_api_fpmath_mode + +/// @addtogroup dnnl_api_accumulation_mode Accumulation Mode +/// @{ + +/// Accumulation mode +enum class accumulation_mode { + /// Default behavior, f32 for floating point computation, s32 for integer + strict = dnnl_accumulation_mode_strict, + /// same as strict except some partial accumulators can be rounded to + /// src/dst datatype in memory. + relaxed = dnnl_accumulation_mode_relaxed, + /// uses fastest implementation, could use src/dst datatype or + /// wider datatype for accumulators + any = dnnl_accumulation_mode_any, + /// use s32 accumulators during computation + s32 = dnnl_accumulation_mode_s32, + /// use f32 accumulators during computation + f32 = dnnl_accumulation_mode_f32, + /// use f16 accumulators during computation + f16 = dnnl_accumulation_mode_f16 +}; + +/// Converts an accumulation mode enum value from C++ API to C API type. +/// +/// @param mode C++ API accumulation mode enum value. +/// @returns Corresponding C API accumulation mode enum value. +inline dnnl_accumulation_mode_t convert_to_c(accumulation_mode mode) { + return static_cast(mode); +} + +/// @} dnnl_api_accumulation_mode + +/// @} dnnl_api_common + +} // namespace dnnl + +/// @} dnnl_api + +// NOLINTEND(readability-identifier-naming) +#endif /* ONEAPI_DNNL_DNNL_COMMON_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common_types.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common_types.h new file mode 100644 index 0000000000000000000000000000000000000000..29c75f351ecdb447567a76d4116d9b72e12d7354 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common_types.h @@ -0,0 +1,272 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// C API common types definitions + +#ifndef ONEAPI_DNNL_DNNL_COMMON_TYPES_H +#define ONEAPI_DNNL_DNNL_COMMON_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/// @cond DO_NOT_DOCUMENT_THIS +#include +#include + +#include "oneapi/dnnl/dnnl_config.h" + +/// @endcond + +/// @addtogroup dnnl_api oneDNN API +/// @{ + +/// @addtogroup dnnl_api_common Common API +/// @{ + +/// @addtogroup dnnl_api_utils +/// @{ + +/// Status values returned by the library functions. +typedef enum { + /// The operation was successful + dnnl_success = 0, + /// The operation failed due to an out-of-memory condition + dnnl_out_of_memory = 1, + /// The operation failed because of incorrect function arguments + dnnl_invalid_arguments = 2, + /// The operation failed because requested functionality is not implemented + dnnl_unimplemented = 3, + /// The last available implementation is reached + dnnl_last_impl_reached = 4, + /// Primitive or engine failed on execution + dnnl_runtime_error = 5, + /// Queried element is not required for given primitive + dnnl_not_required = 6, + /// The graph is not legitimate + dnnl_invalid_graph = 7, + /// The operation is not legitimate according to op schema + dnnl_invalid_graph_op = 8, + /// The shape cannot be inferred or compiled + dnnl_invalid_shape = 9, + /// The data type cannot be inferred or compiled + dnnl_invalid_data_type = 10, +} dnnl_status_t; + +/// @} dnnl_api_utils + +/// @addtogroup dnnl_api_data_types Data types +/// @{ + +/// Data type specification +typedef enum { + /// Undefined data type, used for empty memory descriptors. + dnnl_data_type_undef = 0, + /// 16-bit/half-precision floating point. + dnnl_f16 = 1, + /// non-standard 16-bit (bfloat16 w/ 7 bit mantissa) floating point. + dnnl_bf16 = 2, + /// 32-bit/single-precision floating point. + dnnl_f32 = 3, + /// 32-bit signed integer. + dnnl_s32 = 4, + /// 8-bit signed integer. + dnnl_s8 = 5, + /// 8-bit unsigned integer. + dnnl_u8 = 6, + /// 64-bit/double-precision floating point. + dnnl_f64 = 7, + /// Boolean data type. Size is C++ implementation defined. + dnnl_boolean = 8, + /// [OFP8 standard 8-bit floating-point](https://www.opencompute.org/documents/ocp-8-bit-floating-point-specification-ofp8-revision-1-0-2023-06-20-pdf) + /// with a 5-bit exponent and a 2-bit mantissa. + dnnl_f8_e5m2 = 9, + /// [OFP8 standard 8-bit floating-point](https://www.opencompute.org/documents/ocp-8-bit-floating-point-specification-ofp8-revision-1-0-2023-06-20-pdf) + /// with a 4-bit exponent and a 3-bit mantissa. + dnnl_f8_e4m3 = 10, + /// 4-bit signed integer. + dnnl_s4 = 11, + /// 4-bit unsigned integer. + dnnl_u4 = 12, + /// [MX-compliant 8-bit compliant scale data type](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf) with 8-bit exponent. + dnnl_e8m0 = 13, + /// [MX-compliant 4-bit float data type](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf) with 2-bit exponent and 1 bit mantissa. + dnnl_f4_e2m1 = 14, + /// 4-bit float data type with 3-bit exponent and 0 bit mantissa. + dnnl_f4_e3m0 = 15, + /// 64-bit signed integer + dnnl_s64 = 16, + + // Max value to prevent UB for internal-use-only values. + dnnl_data_type_max = 0x7fff, +} dnnl_data_type_t; + +/// Maximum number of dimensions a tensor can have. Only restricts the amount +/// of space used for the tensor description. Individual computational +/// primitives may support only tensors of certain dimensions. +#define DNNL_MAX_NDIMS 12 + +/// A type to describe tensor dimension. +typedef int64_t dnnl_dim_t; + +/// A type to describe tensor dimensions. +typedef dnnl_dim_t dnnl_dims_t[DNNL_MAX_NDIMS]; + +/// @} dnnl_api_data_types + +/// @addtogroup dnnl_api_fpmath_mode Floating-point Math Mode +/// @{ + +/// Floating-point math mode +typedef enum { + /// Default behavior, no downconversions allowed + dnnl_fpmath_mode_strict, + /// Implicit f32->bf16 conversions allowed + dnnl_fpmath_mode_bf16, + /// Implicit f32->f16 conversions allowed + dnnl_fpmath_mode_f16, + /// Implicit f32->f16, f32->tf32 or f32->bf16 conversions allowed + dnnl_fpmath_mode_any, + /// Implicit f32->tf32 conversions allowed + dnnl_fpmath_mode_tf32, +} dnnl_fpmath_mode_t; + +/// @} dnnl_api_fpmath_mode + +/// @addtogroup dnnl_api_accumulation_mode Accumulation Mode +/// @{ + +/// Accumulation mode +typedef enum { + /// Default behavior, f32/f64 for floating point computation, s32 + /// for integer + dnnl_accumulation_mode_strict, + /// Same as strict but allows some partial accumulators to be + /// rounded to src/dst datatype in memory. + dnnl_accumulation_mode_relaxed, + /// uses fastest implementation, could use src/dst datatype or + /// wider datatype for accumulators + dnnl_accumulation_mode_any, + /// use s32 accumulators during computation + dnnl_accumulation_mode_s32, + /// use f32 accumulators during computation + dnnl_accumulation_mode_f32, + /// use f16 accumulators during computation + dnnl_accumulation_mode_f16 +} dnnl_accumulation_mode_t; + +/// @} dnnl_api_accumulation_mode + +/// @addtogroup dnnl_api_engine Engine +/// @{ + +/// @brief Kinds of engines. +typedef enum { + /// An unspecified engine. + dnnl_any_engine, + /// CPU engine. + dnnl_cpu, + /// GPU engine. + dnnl_gpu, +} dnnl_engine_kind_t; + +/// @struct dnnl_engine +/// @brief An opaque structure to describe an engine. +struct dnnl_engine; +/// @brief An engine handle. +typedef struct dnnl_engine *dnnl_engine_t; +#if 0 +// FIXME: looks like this never happens +/// @brief A constant engine handle. +typedef const struct dnnl_engine *const_dnnl_engine_t; +#endif + +/// @} dnnl_api_engine + +/// @addtogroup dnnl_api_stream Stream +/// @{ + +/// @brief Stream flags. +typedef enum { + // In-order execution. + dnnl_stream_in_order = 0x1U, + /// Out-of-order execution. + dnnl_stream_out_of_order = 0x2U, + /// Default stream configuration. + dnnl_stream_default_flags = dnnl_stream_in_order, +#ifdef DNNL_EXPERIMENTAL_PROFILING + /// Enables profiling capabilities. + dnnl_stream_profiling = 0x4U, +#endif + + // Max value to prevent UB for internal-use-only values. + dnnl_stream_flags_max = 0x7fff, +} dnnl_stream_flags_t; + +/// @struct dnnl_stream +/// An opaque structure to describe an execution stream. +struct dnnl_stream; +/// An execution stream handle. +typedef struct dnnl_stream *dnnl_stream_t; +/// A constant execution stream handle. +typedef const struct dnnl_stream *const_dnnl_stream_t; + +/// @} dnnl_api_stream + +/// @addtogroup dnnl_api_service +/// @{ + +/// Structure containing version information as per [Semantic +/// Versioning](https://semver.org) +typedef struct { + int major; ///< Major version + int minor; ///< Minor version + int patch; ///< Patch version + const char *hash; ///< Git hash of the sources (may be absent) + unsigned cpu_runtime; ///< CPU runtime + unsigned gpu_runtime; ///< GPU runtime +} dnnl_version_t; + +/// @} dnnl_api_service + +/// @addtogroup dnnl_api_memory +/// @{ + +/// Special pointer value that indicates that a memory object should not have +/// an underlying buffer. +#define DNNL_MEMORY_NONE (NULL) + +/// Special pointer value that indicates that the library needs to allocate an +/// underlying buffer for a memory object. +#define DNNL_MEMORY_ALLOCATE ((void *)(size_t) - 1) + +/// @} dnnl_api_memory + +/// @} dnnl_api_common + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_config.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_config.h new file mode 100644 index 0000000000000000000000000000000000000000..21463436a926e4da7dc247bfd5cfae6d3555e81d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_config.h @@ -0,0 +1,240 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_CONFIG_H +#define ONEAPI_DNNL_DNNL_CONFIG_H + +/// @cond DO_NOT_DOCUMENT_THIS + +// All symbols shall be internal unless marked as DNNL_API +#if defined _WIN32 || defined __CYGWIN__ +#define DNNL_HELPER_DLL_IMPORT __declspec(dllimport) +#define DNNL_HELPER_DLL_EXPORT __declspec(dllexport) +#else +#if __GNUC__ >= 4 +#define DNNL_HELPER_DLL_IMPORT __attribute__((visibility("default"))) +#define DNNL_HELPER_DLL_EXPORT __attribute__((visibility("default"))) +#else +#define DNNL_HELPER_DLL_IMPORT +#define DNNL_HELPER_DLL_EXPORT +#endif +#endif + +#ifdef DNNL_DLL +#ifdef DNNL_DLL_EXPORTS +#define DNNL_API DNNL_HELPER_DLL_EXPORT +#else +#define DNNL_API DNNL_HELPER_DLL_IMPORT +#endif +#else +#define DNNL_API +#endif + +#if defined(__GNUC__) +#define DNNL_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define DNNL_DEPRECATED __declspec(deprecated) +#else +#define DNNL_DEPRECATED +#endif + +/// @endcond + +// clang-format off + +/// @addtogroup dnnl_api_service +/// @{ + +/// No runtime (disabled) +#define DNNL_RUNTIME_NONE 0u + +/// Sequential runtime (CPU only) +#define DNNL_RUNTIME_SEQ 1u + +/// OpenMP runtime (CPU only) +#define DNNL_RUNTIME_OMP 2u + +/// TBB runtime (CPU only) +#define DNNL_RUNTIME_TBB 4u + +/// Threadpool runtime (CPU only) +#define DNNL_RUNTIME_THREADPOOL 8u + +/// OpenCL runtime +#define DNNL_RUNTIME_OCL 256u + +/// SYCL runtime +#define DNNL_RUNTIME_SYCL 512u + +/// DPC++ runtime +#define DNNL_RUNTIME_DPCPP DNNL_RUNTIME_SYCL + +/// No vendor (corresponding runtime is disabled) +#define DNNL_VENDOR_NONE 0u + +/// Intel vendor +#define DNNL_VENDOR_INTEL 1u + +/// NVIDIA vendor +#define DNNL_VENDOR_NVIDIA 2u + +/// AMD vendor +#define DNNL_VENDOR_AMD 4u + +/// Generic vendor +#define DNNL_VENDOR_GENERIC 8u + +/// @} dnnl_api_service + +// oneDNN CPU threading runtime +#define DNNL_CPU_THREADING_RUNTIME DNNL_RUNTIME_OMP + +// oneDNN CPU engine runtime +#define DNNL_CPU_RUNTIME DNNL_RUNTIME_OMP + +// oneDNN GPU engine runtime +#define DNNL_GPU_RUNTIME DNNL_RUNTIME_NONE + +// oneDNN GPU vendor +#define DNNL_GPU_VENDOR DNNL_VENDOR_NONE + +// clang-format on + +#if defined(DNNL_CPU_RUNTIME) && defined(DNNL_GPU_RUNTIME) +#if (DNNL_CPU_RUNTIME == DNNL_RUNTIME_OCL) +#error "Unexpected DNNL_CPU_RUNTIME" +#endif +#if (DNNL_GPU_RUNTIME != DNNL_RUNTIME_NONE) \ + && (DNNL_GPU_RUNTIME != DNNL_RUNTIME_OCL) \ + && (DNNL_GPU_RUNTIME != DNNL_RUNTIME_SYCL) +#error "Unexpected DNNL_GPU_RUNTIME" +#endif +#if (DNNL_CPU_RUNTIME == DNNL_RUNTIME_NONE \ + && DNNL_GPU_RUNTIME == DNNL_RUNTIME_NONE) +#error "At least one runtime must be specified" +#endif +#else +#error "BOTH DNNL_CPU_RUNTIME and DNNL_GPU_RUNTIME must be defined" +#endif + +// For SYCL CPU, a primitive may be created and executed in different threads +// hence the global scratchpad does not work. This enables concurrent execution +// when CPU runtime is SYCL to avoid the issue. +#if DNNL_CPU_RUNTIME == DNNL_RUNTIME_SYCL +#ifndef DNNL_ENABLE_CONCURRENT_EXEC +#define DNNL_ENABLE_CONCURRENT_EXEC +#endif +#endif + +// When defined, primitive cache stores runtime objects. +/* #undef DNNL_USE_RT_OBJECTS_IN_PRIMITIVE_CACHE */ + +// When defined, DPCPP is supported. +/* #undef DNNL_WITH_SYCL */ + +// When defined, Level Zero is supported. +/* #undef DNNL_WITH_LEVEL_ZERO */ + +// When defined, SYCL CUDA backend is used. +/* #undef DNNL_SYCL_CUDA */ + +// When defined, SYCL HIP backend is used. +/* #undef DNNL_SYCL_HIP */ + +// When defined, SYCL Generic backend is used. +/* #undef DNNL_SYCL_GENERIC */ + +// When defined, stack checker is enabled. +/* #undef DNNL_ENABLE_STACK_CHECKER */ + +// When defined, experimental features are enabled. +/* #undef DNNL_EXPERIMENTAL */ + +// When defined, experimental functionality for ukernels is enabled. +#define DNNL_EXPERIMENTAL_UKERNEL + +// When defined, graph component is enabled. +#define ONEDNN_BUILD_GRAPH + +// When defined, experimental profiling capabilities are enabled. +/* #undef DNNL_EXPERIMENTAL_PROFILING */ + +// When defined, experimental logging capabilities are enabled. +/* #undef DNNL_EXPERIMENTAL_LOGGING */ + +// When defined, RBP register is untouchable in JIT kernels +// to allow stack unwind +/* #undef DNNL_SAFE_RBP */ + +// When defined, experimental SYCL capabilities are enabled. +/* #undef DNNL_EXPERIMENTAL_SYCL_KERNEL_COMPILER */ + +// When defined, it disables GPU compute reference kernels. +/* #undef DNNL_DISABLE_GPU_REF_KERNELS */ + +// List of configurating build controls +// Workload controls +#define BUILD_TRAINING 1 +#define BUILD_INFERENCE 0 +// Primitive controls +#define BUILD_PRIMITIVE_ALL 1 +#define BUILD_BATCH_NORMALIZATION 0 +#define BUILD_BINARY 0 +#define BUILD_CONCAT 0 +#define BUILD_CONVOLUTION 0 +#define BUILD_DECONVOLUTION 0 +#define BUILD_ELTWISE 0 +#define BUILD_GROUP_NORMALIZATION 0 +#define BUILD_INNER_PRODUCT 0 +#define BUILD_LAYER_NORMALIZATION 0 +#define BUILD_LRN 0 +#define BUILD_MATMUL 0 +#define BUILD_POOLING 0 +#define BUILD_PRELU 0 +#define BUILD_REDUCTION 0 +#define BUILD_REORDER 0 +#define BUILD_RESAMPLING 0 +#define BUILD_RNN 0 +#define BUILD_SDPA 0 +#define BUILD_SHUFFLE 0 +#define BUILD_SOFTMAX 0 +#define BUILD_SUM 0 +// Primitives CPU ISA controls +#define BUILD_PRIMITIVE_CPU_ISA_ALL 1 +#define BUILD_SSE41 0 +#define BUILD_AVX2 0 +#define BUILD_AVX512 0 +#define BUILD_AMX 0 +// Primitives GPU ISA controls +#define BUILD_PRIMITIVE_GPU_ISA_ALL 1 +#define BUILD_XELP 0 +#define BUILD_XEHP 0 +#define BUILD_XEHPG 0 +#define BUILD_XEHPC 0 +#define BUILD_XE2 0 +#define BUILD_XE3 0 +// GeMM kernels ISA controls +#define BUILD_GEMM_KERNELS_ALL 1 +#define BUILD_GEMM_KERNELS_NONE 0 +#define BUILD_GEMM_SSE41 0 +#define BUILD_GEMM_AVX2 0 +#define BUILD_GEMM_AVX512 0 +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_debug.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..9d6e03f90d28891b881bfa719ac6bd672f49a95a --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_debug.h @@ -0,0 +1,65 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +// DO NOT EDIT, AUTO-GENERATED +// Use this script to update the file: scripts/generate_dnnl_debug.py + +// clang-format off + +#ifndef ONEAPI_DNNL_DNNL_DEBUG_H +#define ONEAPI_DNNL_DNNL_DEBUG_H + +/// @file +/// Debug capabilities + +#include "oneapi/dnnl/dnnl_config.h" +#include "oneapi/dnnl/dnnl_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +const char DNNL_API *dnnl_status2str(dnnl_status_t v); +const char DNNL_API *dnnl_dt2str(dnnl_data_type_t v); +const char DNNL_API *dnnl_fpmath_mode2str(dnnl_fpmath_mode_t v); +const char DNNL_API *dnnl_accumulation_mode2str(dnnl_accumulation_mode_t v); +const char DNNL_API *dnnl_engine_kind2str(dnnl_engine_kind_t v); +const char DNNL_API *dnnl_sparse_encoding2str(dnnl_sparse_encoding_t v); +const char DNNL_API *dnnl_fmt_tag2str(dnnl_format_tag_t v); +const char DNNL_API *dnnl_prop_kind2str(dnnl_prop_kind_t v); +const char DNNL_API *dnnl_prim_kind2str(dnnl_primitive_kind_t v); +const char DNNL_API *dnnl_alg_kind2str(dnnl_alg_kind_t v); +const char DNNL_API *dnnl_rnn_flags2str(dnnl_rnn_flags_t v); +const char DNNL_API *dnnl_rnn_direction2str(dnnl_rnn_direction_t v); +const char DNNL_API *dnnl_scratchpad_mode2str(dnnl_scratchpad_mode_t v); +const char DNNL_API *dnnl_rounding_mode2str(dnnl_rounding_mode_t v); +const char DNNL_API *dnnl_quantization_mode2str(dnnl_quantization_mode_t v); +const char DNNL_API *dnnl_cpu_isa2str(dnnl_cpu_isa_t v); +const char DNNL_API *dnnl_cpu_isa_hints2str(dnnl_cpu_isa_hints_t v); + +const char DNNL_API *dnnl_runtime2str(unsigned v); +const char DNNL_API *dnnl_fmt_kind2str(dnnl_format_kind_t v); + +#ifdef __cplusplus +} +#endif + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph.h new file mode 100644 index 0000000000000000000000000000000000000000..3b0866dc84e037ff951aee8f9db21084c1269c23 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph.h @@ -0,0 +1,814 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// Graph C API + +#ifndef ONEAPI_DNNL_DNNL_GRAPH_H +#define ONEAPI_DNNL_DNNL_GRAPH_H + +#include "oneapi/dnnl/dnnl_common.h" +#include "oneapi/dnnl/dnnl_config.h" +#include "oneapi/dnnl/dnnl_graph_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_graph_api +/// @{ + +/// @addtogroup dnnl_graph_api_allocator +/// @{ + +/// Creates a host allocator with the given allocation and deallocation +/// call-back function pointers. +/// +/// @param allocator Output allocator. +/// @param host_malloc A pointer to malloc function for host. +/// @param host_free A pointer to free function for host. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_allocator_create( + dnnl_graph_allocator_t *allocator, + dnnl_graph_host_allocate_f host_malloc, + dnnl_graph_host_deallocate_f host_free); + +/// Destroys an allocator. +/// +/// @param allocator The allocator to be destroyed. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_allocator_destroy( + dnnl_graph_allocator_t allocator); + +/// @} dnnl_graph_api_allocator + +/// @addtogroup dnnl_graph_api_engine +/// @{ + +/// This API is a supplement for existing onednn engine API. +dnnl_status_t DNNL_API dnnl_graph_make_engine_with_allocator( + dnnl_engine_t *engine, dnnl_engine_kind_t kind, size_t index, + const_dnnl_graph_allocator_t alloc); + +/// @} dnnl_graph_api_engine + +/// @addtogroup dnnl_graph_api_logical_tensor +/// @{ + +/// Initializes a logical tensor with id, data type, number of dimensions, +/// layout type, and property. The logical tensor's dims are unknown with this +/// interface. +/// +/// @param logical_tensor Output logical tensor. +/// @param tid The unique id of the output logical tensor. +/// @param dtype Elements data type. +/// @param ndims Number of dimensions. +/// @param ltype Layout type of the underlying tensor buffer. +/// @param ptype Tensor property type. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_logical_tensor_init( + dnnl_graph_logical_tensor_t *logical_tensor, size_t tid, + dnnl_data_type_t dtype, int32_t ndims, dnnl_graph_layout_type_t ltype, + dnnl_graph_tensor_property_t ptype); + +/// Initializes a logical tensor with basic information and dims. The logical +/// tensor's dimensions and layout will be initialized according to the input +/// arguments. +/// +/// @note +/// If dims contains all valid values and layout type is +/// #dnnl_graph_layout_type_strided. The strides field in +/// #dnnl_graph_logical_tensor_t will be calculated in a row major and +/// contiguous way. Otherwise, Accessing the strides field is an undefined +/// behavior. +/// +/// Eg. dims (2, 3, 4, 5) will get strides (60, 20, 5, 1) +/// +/// @param logical_tensor Output logical tensor. +/// @param tid The unique id of output logical tensor. +/// @param dtype Elements data type. +/// @param ndims Number of dimensions. +/// @param dims Array of dimensions. +/// @param ltype Layout type of the underlying tensor memory. +/// @param ptype Tensor property type. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_logical_tensor_init_with_dims( + dnnl_graph_logical_tensor_t *logical_tensor, size_t tid, + dnnl_data_type_t dtype, int32_t ndims, const dnnl_dims_t dims, + dnnl_graph_layout_type_t ltype, dnnl_graph_tensor_property_t ptype); + +/// Initializes a logical tensor with dimensions and strides provided by user. +/// +/// @note +/// Once strides are explicitly provided through the API, the `layout_type` +/// in #dnnl_graph_logical_tensor_t can only be +/// #dnnl_graph_layout_type_strided or #dnnl_graph_layout_type_any. +/// +/// @param logical_tensor Output logical tensor. +/// @param tid The unique id of output logical tensor. +/// @param dtype Elements data type. +/// @param ndims Number of dimensions. +/// @param dims Array of dimensions. +/// @param strides Array of strides. +/// @param ptype Tensor property type. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_logical_tensor_init_with_strides( + dnnl_graph_logical_tensor_t *logical_tensor, size_t tid, + dnnl_data_type_t dtype, int32_t ndims, const dnnl_dims_t dims, + const dnnl_dims_t strides, dnnl_graph_tensor_property_t ptype); + +/// Returns the memory size described by the logical tensor. If it's a strided +/// layout, the size will be calculated by `dims` and `strides`. If it's an +/// opaque layout, the size will be decided by `layout_id`. +/// +/// @param logical_tensor Logical tensor. +/// @param size Output memory size in bytes. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_logical_tensor_get_mem_size( + const dnnl_graph_logical_tensor_t *logical_tensor, size_t *size); + +/// Compares if two logical tenors are equal. Users can decide accordingly +/// if layout reordering is needed for two logical tensors. The method will +/// return true for below two circumstances: +/// +/// 1. the two logical tensors are equal regarding each field in the struct, +/// eg. id, ndims, dims, layout type, property, etc. +/// 2. If all other fields are equal but the layout types in two logical +/// tensors are different, the method will return true when the underlying +/// memory layout is the same. For example, one logical tensor has strided +/// layout type while the other one has opaque layout type, but underneath, +/// both layouts are NHWC, the method will still return true for this case. +/// +/// @param lt1 The handle of first logical tensor. +/// @param lt2 The handle of second logical tensor. +/// @param is_equal 1 if these two logical tensors are equal, 0 otherwise. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_logical_tensor_is_equal( + const dnnl_graph_logical_tensor_t *lt1, + const dnnl_graph_logical_tensor_t *lt2, uint8_t *is_equal); + +/// @} dnnl_graph_api_logical_tensor + +/// @addtogroup dnnl_graph_api_tensor +/// @{ + +/// Creates a tensor with logical tensor, engine, and data handle. +/// +/// @param tensor Output tensor. +/// @param logical_tensor Description for this tensor. +/// @param engine Engine to use. +/// @param handle Handle of the memory buffer to use as an underlying storage. +/// - A pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer for the tensor. In this case the library +/// owns the buffer. +/// - DNNL_MEMORY_NONE to create tensor without an underlying buffer. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_tensor_create(dnnl_graph_tensor_t *tensor, + const dnnl_graph_logical_tensor_t *logical_tensor, dnnl_engine_t engine, + void *handle); + +/// Creates a scalar tensor with logical tensor and scalar data handle. +/// +/// @param tensor Output scalar tensor. +/// @param logical_tensor Description for this tensor. +/// @param handle Handle of the memory buffer to use as an underlying storage. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_tensor_create_scalar( + dnnl_graph_tensor_t *tensor, + const dnnl_graph_logical_tensor_t *logical_tensor, void *handle); + +/// Destroys a tensor. +/// +/// @param tensor The tensor to be destroyed. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_tensor_destroy(dnnl_graph_tensor_t tensor); + +/// Gets the data handle of a tensor. +/// +/// @param tensor The input tensor. +/// @param handle Pointer to the data of input tensor. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_tensor_get_data_handle( + const_dnnl_graph_tensor_t tensor, void **handle); + +/// Set data handle for a tensor. +/// +/// @param tensor The input tensor. +/// @param handle New data handle for tensor. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_tensor_set_data_handle( + dnnl_graph_tensor_t tensor, void *handle); + +/// Returns the engine of a tensor object. +/// +/// @param tensor The input tensor. +/// @param engine Output engine on which the tensor is located. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_tensor_get_engine( + const_dnnl_graph_tensor_t tensor, dnnl_engine_t *engine); + +/// Returns the logical tensor of a tensor object. +/// +/// @param tensor The input tensor. +/// @param logical_tensor Output logical tensor of the tensor object. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_tensor_get_logical_tensor( + const_dnnl_graph_tensor_t tensor, + dnnl_graph_logical_tensor_t *logical_tensor); + +/// @} dnnl_graph_api_tensor + +/// @addtogroup dnnl_graph_api_op +/// @{ + +/// Initializes an op with unique id, kind, and name. +/// +/// @param op Output op +/// @param id The unique id of the output op. +/// @param kind The op kind. +/// @param verbose_name The string added as the op name. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_create(dnnl_graph_op_t *op, size_t id, + dnnl_graph_op_kind_t kind, const char *verbose_name); + +/// Destroys an op. +/// +/// @param op The op to be destroyed. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_destroy(dnnl_graph_op_t op); + +/// Adds input logical tensor to the op. +/// +/// @param op Input op. +/// @param input The input logical tensor to be added. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_add_input( + dnnl_graph_op_t op, const dnnl_graph_logical_tensor_t *input); + +/// Adds output logical tensor to the op. +/// +/// @param op Input op. +/// @param output The output logical tensor to be added. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_add_output( + dnnl_graph_op_t op, const dnnl_graph_logical_tensor_t *output); + +/// Sets floating point attribute to an op. +/// +/// @param op Input op. +/// @param name The attribute's name. +/// @param value The attribute's value. +/// @param value_len The number of value element. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_set_attr_f32(dnnl_graph_op_t op, + dnnl_graph_op_attr_t name, const float *value, size_t value_len); + +/// Sets boolean attribute to an op. +/// +/// @param op Input op. +/// @param name The attribute's name. +/// @param value The attribute's value. +/// @param value_len The number of value element. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_set_attr_bool(dnnl_graph_op_t op, + dnnl_graph_op_attr_t name, const uint8_t *value, size_t value_len); + +/// Sets integer attribute to an op. +/// +/// @param op Input op. +/// @param name The attribute's name. +/// @param value The attribute's value. +/// @param value_len The number of value element. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_set_attr_s64(dnnl_graph_op_t op, + dnnl_graph_op_attr_t name, const int64_t *value, size_t value_len); + +/// Sets string attribute to an op. +/// +/// @param op Input op. +/// @param name The attribute's name. +/// @param value The attribute's value. +/// @param value_len The length of the string value. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_set_attr_str(dnnl_graph_op_t op, + dnnl_graph_op_attr_t name, const char *value, size_t value_len); + +/// Returns the unique id of an op. +/// +/// @param op Input op. +/// @param id Output the unique id. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_get_id( + const_dnnl_graph_op_t op, size_t *id); + +/// Returns the kind of an op. +/// +/// @param op Input op. +/// @param kind Output op kind. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_op_get_kind( + const_dnnl_graph_op_t op, dnnl_graph_op_kind_t *kind); + +/// @} dnnl_graph_api_op + +/// @addtogroup dnnl_graph_api_partition +/// @{ + +/// Creates a new partition with a given operator and engine kind. The API is +/// used to create a partition from an operation directly without creating the +/// graph and calling `get_partitions()`. The output partition contains only one +/// operation specified by the parameter. The output partition instance should +/// be destroyed via #dnnl_graph_partition_destroy after use. +/// +/// @param partition The handle of output partition. +/// @param op The operation used to create partition. +/// @param ekind The engine kind used to create partition. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_create_with_op( + dnnl_graph_partition_t *partition, const_dnnl_graph_op_t op, + dnnl_engine_kind_t ekind); + +/// Destroys a partition. +/// +/// @param partition The partition to be destroyed. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_destroy( + dnnl_graph_partition_t partition); + +/// Returns the number of operations in a partition. +/// +/// @param partition The target partition. +/// @param num Output the number of operations. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_get_op_num( + const_dnnl_graph_partition_t partition, size_t *num); + +/// Returns the list of op IDs of the partition. +/// +/// @param partition The target partition. +/// @param num The number of ops. +/// @param ids Output the op IDs. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_get_ops( + dnnl_graph_partition_t partition, size_t num, size_t *ids); + +/// Returns the ID of a partition. +/// +/// @param partition The target partition. +/// @param id Output the ID of the partition. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_get_id( + const_dnnl_graph_partition_t partition, size_t *id); + +/// Compiles a partition with given input and output logical tensors. The output +/// logical tensors can contain unknown dimensions. For this case, the +/// compilation will deduce the output shapes according to input shapes. The +/// output logical tensors can also have layout type `any`. The compilation will +/// choose the optimal layout for output tensors. The optimal layout will be +/// represented as an opaque layout ID saved in the output logical tensor. +/// +/// @param partition The target partition. +/// @param compiled_partition Output compiled partition. +/// @param in_num The number of input logical tensors. +/// @param inputs A list of input logical tensors. +/// @param out_num The number of output logical tensors. +/// @param outputs A list of output logical tensors. +/// @param engine The target engine of the compilation. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_compile( + dnnl_graph_partition_t partition, + dnnl_graph_compiled_partition_t compiled_partition, size_t in_num, + const dnnl_graph_logical_tensor_t **inputs, size_t out_num, + const dnnl_graph_logical_tensor_t **outputs, dnnl_engine_t engine); + +/// Returns the number of input logical tensors of a partition. +/// +/// @param partition The target partition. +/// @param num Output the number of input logical tensors. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_get_input_ports_num( + const_dnnl_graph_partition_t partition, size_t *num); + +/// Returns a list of input logical tensors from a partition. +/// +/// @param partition The target partition. +/// @param num The number of input logical tensors. +/// @param inputs The list of input logical tensors. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_get_input_ports( + const_dnnl_graph_partition_t partition, size_t num, + dnnl_graph_logical_tensor_t *inputs); + +/// Returns the number of output logical tensors of a partition. +/// +/// @param partition The target partition. +/// @param num Output the number of output logical tensors. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_get_output_ports_num( + const_dnnl_graph_partition_t partition, size_t *num); + +/// Returns a list of output logical tensors from a partition. +/// +/// @param partition The target partition. +/// @param num The number of output logical tensors. +/// @param outputs The list of output logical tensors. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_get_output_ports( + const_dnnl_graph_partition_t partition, size_t num, + dnnl_graph_logical_tensor_t *outputs); + +/// Returns the supporting status of a partition. Some operations may not be +/// supported by the library under certain circumstances. During partitioning +/// stage, unsupported partitions will be returned to users with each containing +/// an unsupported operation. Users should check the supporting status of a +/// partition before transforming the computation graph or compiling the +/// partition. +/// +/// @param partition The target partition. +/// @param is_supported Output flag to indicate the supporting status. 0 means +/// unsupported while 1 means supported. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_is_supported( + const_dnnl_graph_partition_t partition, uint8_t *is_supported); + +/// Returns the engine kind of a partition. +/// +/// @param partition The target partition. +/// @param kind The output engine kind. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_partition_get_engine_kind( + const_dnnl_graph_partition_t partition, dnnl_engine_kind_t *kind); + +/// @} dnnl_graph_api_partition + +/// @addtogroup dnnl_graph_api_compiled_partition +/// @{ + +/// Creates a new compiled partition handle. +/// +/// @param compiled_partition The handle of output compiled partition. +/// @param partition The handle of input partition. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_compiled_partition_create( + dnnl_graph_compiled_partition_t *compiled_partition, + dnnl_graph_partition_t partition); + +/// Executes a compiled partition. +/// +/// @param compiled_partition The handle of target compiled partition. +/// @param stream The stream used for execution. +/// @param num_inputs The number of input tensors. +/// @param inputs A list of input tensors. +/// @param num_outputs The number of output tensors. +/// @param outputs A non-empty list of output tensors. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_compiled_partition_execute( + const_dnnl_graph_compiled_partition_t compiled_partition, + dnnl_stream_t stream, size_t num_inputs, + const_dnnl_graph_tensor_t *inputs, size_t num_outputs, + const_dnnl_graph_tensor_t *outputs); + +/// Destroys a compiled partition. +/// +/// @param compiled_partition The compiled partition to be destroyed. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_compiled_partition_destroy( + dnnl_graph_compiled_partition_t compiled_partition); + +/// Queries an input or output logical tensor according to tensor ID. If the +/// tensor ID doesn't belong to any input or output of the compiled partition, +/// an error status #dnnl_invalid_arguments will be returned by the API. +/// +/// @param compiled_partition The handle of target compiled_partition. +/// @param tid The unique id of required tensor. +/// @param lt The output logical tensor. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_compiled_partition_query_logical_tensor( + const_dnnl_graph_compiled_partition_t compiled_partition, size_t tid, + dnnl_graph_logical_tensor_t *lt); + +/// Returns the hint of in-place pairs from a compiled partition. It indicates +/// that an input and an output of the partition can share the same memory +/// buffer for computation. In-place computation helps to reduce the memory +/// footprint and improves cache locality. But since the library may not have a +/// global view of user's application, it's possible that the tensor with +/// `input_id` is used at other places in user's computation graph. In this +/// case, the user should take the in-place pair as a hint and pass a different +/// memory buffer for output tensor to avoid overwriting the input memory buffer +/// which will probably cause unexpected incorrect results. +/// +/// @param compiled_partition The handle of target compiled_partition. +/// @param num_inplace_pairs The number of in-place pairs. +/// @param inplace_pairs The handle of in-place pairs. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_compiled_partition_get_inplace_ports( + const_dnnl_graph_compiled_partition_t compiled_partition, + size_t *num_inplace_pairs, + const dnnl_graph_inplace_pair_t **inplace_pairs); + +/// @} dnnl_graph_api_compiled_partition + +/// @addtogroup dnnl_graph_api_graph +/// @{ + +/// Creates a new empty graph. A graph is associated to a specific engine kind. +/// The partitions returned from the graph will inherit the engine kind of the +/// graph. +/// +/// @param graph The handle of output graph. +/// @param engine_kind The target engine kind. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_create( + dnnl_graph_graph_t *graph, dnnl_engine_kind_t engine_kind); + +/// Creates a new empty graph with an engine kind and a floating-point math +/// mode. All partitions returned from the graph will inherit the engine kind +/// and floating-point math mode. +/// +/// @param graph The handle of output graph. +/// @param engine_kind The kind for engine. +/// @param mode The floating-point math mode. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_create_with_fpmath_mode( + dnnl_graph_graph_t *graph, dnnl_engine_kind_t engine_kind, + dnnl_fpmath_mode_t mode); + +/// Destroys a graph. +/// +/// @param graph The graph to be destroyed. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_destroy(dnnl_graph_graph_t graph); + +/// Set the floating point math mode for a graph. +/// +/// @param graph The target graph. +/// @param mode The floating-point math mode. +/// @param apply_to_int The flag that controls whether to use floating-point +/// arithmetic for integral operations. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_set_fpmath_mode( + dnnl_graph_graph_t graph, dnnl_fpmath_mode_t mode, int apply_to_int); + +/// Get the floating point math mode for a graph. +/// +/// @param graph The target graph. +/// @param mode The floating-point math mode. +/// @param apply_to_int The flag that controls whether to use floating-point +/// arithmetic for integral operations. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_get_fpmath_mode( + dnnl_graph_graph_t graph, dnnl_fpmath_mode_t *mode, int *apply_to_int); + +/// Adds an operation into a graph. The API will return failure if the operator +/// has already been added to the graph or the operation cannot pass the schema +/// check in the library (eg. input and output numbers and data types, the +/// attributes of the operation, etc.). +/// +/// @param graph The target graph. +/// @param op The operation to be added. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_add_op( + dnnl_graph_graph_t graph, dnnl_graph_op_t op); + +/// Finalizes a graph. It means users have finished adding operations into the +/// graph and the graph is ready for partitioning. Adding a new operation into a +/// finalized graph will return failures. Similarly, partitioning on a +/// un-finalized graph will also return failures. +/// +/// @param graph The target graph to be finalized. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_finalize(dnnl_graph_graph_t graph); + +/// Checks if a graph is finalized. +/// +/// @param graph The target graph to be finalized. +/// @param finalized Output the finalization status. 0 means then graph is not +/// finalized. Other values means the graph is finalized. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_is_finalized( + dnnl_graph_graph_t graph, uint8_t *finalized); + +/// Filters a graph. Partitions will be claimed internally according to the +/// capability of the library, the engine kind, and the policy. +/// +/// @param graph The target graph. +/// @param policy The partition policy. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_filter( + dnnl_graph_graph_t graph, dnnl_graph_partition_policy_t policy); + +/// Returns the number of partitions of a graph. The API should be called after +/// a partition is already filtered. Otherwise, the output number is zero. +/// +/// @param graph The graph. +/// @param num Output the number of partitions. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_get_partition_num( + const_dnnl_graph_graph_t graph, size_t *num); + +/// Returns the partitions from a filtered graph. Output partition instances +/// will be written into the parameter `partitions`. Users need to make sure +/// `partitions` is valid and has enough space to accept the partition +/// instances. Each output partition instance should be destroyed via +/// #dnnl_graph_partition_destroy explicitly after use. +/// +/// @param graph The target graph. +/// @param num The number of partitions. +/// @param partitions Output the partitions. +/// @returns #dnnl_success on success or a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_graph_get_partitions(dnnl_graph_graph_t graph, + size_t num, dnnl_graph_partition_t *partitions); + +/// @} dnnl_graph_api_graph + +/// @addtogroup dnnl_graph_api_compiled_partition_cache +/// @{ + +/// Returns the number of compiled partitions that can be held in the compiled +/// partition cache at the same time. +/// +/// @param capacity Compiled partition cache capacity to query. Concurrently +/// accessing @p capacity is safe. +/// @returns #dnnl_invalid_arguments if the @p capacity value +/// is invalid, and #dnnl_success on success. +dnnl_status_t DNNL_API dnnl_graph_get_compiled_partition_cache_capacity( + int *capacity); + +/// Sets a number of compiled partitions that can be held in the compiled +/// partition cache at the same time. The default capacity of compiled partition +/// cache is 1024. +/// +/// @param capacity Compiled partition cache capacity to set. The default cache +/// capacity is 1024. If a new @p capacity is less than a number of compiled +/// partition that the compiled partition cache already has, then the excess +/// entries will be evicted. Setting the @p capacity to 0 clears the compiled +/// partition cache and disables it. Concurrently modifying @p capacity is safe. +/// @returns #dnnl_invalid_arguments if the @p capacity value +/// is invalid, and #dnnl_success on success. +dnnl_status_t DNNL_API dnnl_graph_set_compiled_partition_cache_capacity( + int capacity); + +/// @} dnnl_graph_api_compiled_partition_cache + +/// @addtogroup dnnl_graph_api_constant_tensor_cache +/// @{ + +/// Control the enabling or disabling of constant tensor cache. This API must +/// be called once before compilation stage. By default, constant tensor cache is +/// disabled in the library. +/// +/// @param flag Set to positive value to enable the cache and set to 0 to +/// disable the cache. Negative values are invalid. +/// @returns #dnnl_invalid_arguments if the @p flag value is +/// invalid, and #dnnl_success on success. +/// @note This API is deprecated and will be removed in future release, please +/// use the dnnl_graph_set_constant_tensor_cache_capacity API to disable +/// constant tensor cache by setting it's capacity to zero. +dnnl_status_t DNNL_API dnnl_graph_set_constant_tensor_cache(int flag); + +/// Return the enabling or disabling status of constant tensor cache. +/// +/// @param flag The constant tensor cache enabling status to query. +/// @returns #dnnl_invalid_arguments if the @p flag value is +/// nullptr, and #dnnl_success on success. +/// @note This API is deprecated and will be removed in future release, please +/// use the dnnl_graph_get_constant_tensor_cache_capacity API to check the +/// enabling status by checking it's capacity. +dnnl_status_t DNNL_API dnnl_graph_get_constant_tensor_cache(int *flag); + +/// Control the capacity for the constant tensor cache that used for specific +/// engine kind. This API is thread safe and can be called multiple times at +/// runtime. The capacity is set to zero by default which means the cache is +/// disabled. When calling this API, the corresponding cache will be flushed. +/// Setting capacity to 0 means to clear all cached tensors and disable cache. +/// Once the capacity limit is reached, no new tensors will be cached. If there +/// are multiple devices for an engine kind, the capacity set here is for each +/// device. +/// +/// @param eng_kind The engine kind that the constant tensor cache used for. +/// @param size The constant tensor cache capacity size to set. +/// @returns #dnnl_invalid_arguments if the @p eng_kind value is invalid, and +/// #dnnl_success on success. +dnnl_status_t DNNL_API dnnl_graph_set_constant_tensor_cache_capacity( + dnnl_engine_kind_t eng_kind, size_t size); + +/// Return the current capacity of constant tensor cache. +/// +/// @param eng_kind The engine kind that the constant tensor cache used for. +/// @param size The constant tensor cache capacity size to query. +/// @returns #dnnl_invalid_arguments if the @p eng_kind value is +/// nullptr or the @p size is nullptr, and #dnnl_success on success. +dnnl_status_t DNNL_API dnnl_graph_get_constant_tensor_cache_capacity( + dnnl_engine_kind_t eng_kind, size_t *size); + +/// @} dnnl_graph_api_constant_tensor_cache + +/// @addtogroup dnnl_graph_api_dump_mode +/// @{ + +/// Configures graph dump modes at runtime. +/// +/// @note +/// Enabling graph dump affects performance. +/// This setting overrides the ONEDNN_GRAPH_DUMP environment variable. +/// +/// @param modes Bitmask composed of values from #dnnl_graph_dump_mode_t. +/// Accepted values: +/// - #dnnl_graph_dump_mode_graph: dump the full graph prior to +/// partitioning. +/// - #dnnl_graph_dump_mode_subgraph: dump each partitioned subgraph. +/// - #dnnl_graph_dump_mode_none: disable all graph dumping. +/// +/// Bitmask combinations using bitwise operators are supported. For +/// instance, `graph | subgraph` enables both modes, `none | graph` +/// behaves like `graph`, and `none & graph` behaves like `none`. +/// @returns #dnnl_invalid_arguments if the +/// @p modes value contains unsupported bits or graph dump is disabled, +/// and #dnnl_success on success. +dnnl_status_t DNNL_API dnnl_graph_set_dump_mode(dnnl_graph_dump_mode_t modes); + +/// @} dnnl_graph_api_dump_mode + +/// @} dnnl_graph_api + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fc7e90d29cfb86517bb8d0d975016fb7b713d2bd --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph.hpp @@ -0,0 +1,1714 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// Graph C++ API + +#ifndef ONEAPI_DNNL_DNNL_GRAPH_HPP +#define ONEAPI_DNNL_DNNL_GRAPH_HPP +// NOLINTBEGIN(readability-identifier-naming) + +#include "oneapi/dnnl/dnnl_common.hpp" +#include "oneapi/dnnl/dnnl_graph.h" + +#include +#include +#include +#include +#include + +/// @addtogroup dnnl_api +/// @{ + +namespace dnnl { + +/// @addtogroup dnnl_graph_api Graph API +/// oneDNN Graph API +/// @{ + +/// oneDNN Graph namespace +namespace graph { + +/// @cond DO_NOT_DOCUMENT_THIS + +// Alias for common engine and stream API. +using engine = dnnl::engine; +using stream = dnnl::stream; +using fpmath_mode = dnnl::fpmath_mode; + +/// @endcond + +/// @addtogroup dnnl_graph_api_utils Utilities +/// Utility types and definitions +/// \ingroup dnnl_graph_api +/// @{ + +/// @cond DO_NOT_DOCUMENT_THIS + +/// A class that provides the destructor for a oneDNN graph C API handle. +template +struct graph_handle_traits : public dnnl::handle_traits {}; + +template <> +struct graph_handle_traits { + static dnnl_status_t destructor(dnnl_graph_op_t p) { + return dnnl_graph_op_destroy(p); + } +}; + +template <> +struct graph_handle_traits { + static dnnl_status_t destructor(dnnl_graph_graph_t p) { + return dnnl_graph_graph_destroy(p); + } +}; + +template <> +struct graph_handle_traits { + static dnnl_status_t destructor(dnnl_graph_tensor_t p) { + return dnnl_graph_tensor_destroy(p); + } +}; + +template <> +struct graph_handle_traits { + static dnnl_status_t destructor(dnnl_graph_partition_t p) { + return dnnl_graph_partition_destroy(p); + } +}; + +template <> +struct graph_handle_traits { + static dnnl_status_t destructor(dnnl_graph_compiled_partition_t p) { + return dnnl_graph_compiled_partition_destroy(p); + } +}; + +template <> +struct graph_handle_traits { + static dnnl_status_t destructor(dnnl_graph_allocator_t p) { + return dnnl_graph_allocator_destroy(p); + } +}; + +#define DNNL_GRAPH_HANDLE_ALIAS(type) \ + using type##_handle = dnnl::handle> + +DNNL_GRAPH_HANDLE_ALIAS(allocator); +DNNL_GRAPH_HANDLE_ALIAS(graph); +DNNL_GRAPH_HANDLE_ALIAS(op); +DNNL_GRAPH_HANDLE_ALIAS(tensor); +DNNL_GRAPH_HANDLE_ALIAS(compiled_partition); +DNNL_GRAPH_HANDLE_ALIAS(partition); + +#undef DNNL_GRAPH_HANDLE_ALIAS + +template +using req = typename std::enable_if::type; + +/// @endcond + +/// @} dnnl_graph_api_utils + +/// @addtogroup dnnl_graph_api_status Status +/// Definitions of status values returned by the library functions. +/// \ingroup dnnl_graph_api +/// @{ + +/// Status values returned by the library functions. +enum class status { + /// The operation was successful + success = dnnl_success, + /// The operation failed due to an out-of-memory condition + out_of_memory = dnnl_out_of_memory, + /// The operation failed because of incorrect function arguments + invalid_arguments = dnnl_invalid_arguments, + /// The operation failed because requested functionality is not implemented + unimplemented = dnnl_unimplemented, + /// The last available implementation is reached + last_impl_reached = dnnl_last_impl_reached, + /// Primitive or engine failed on execution + runtime_error = dnnl_runtime_error, + /// Queried element is not required for given primitive + not_required = dnnl_not_required, + /// The graph is not legitimate + invalid_graph = dnnl_invalid_graph, + /// The operation is not legitimate according to op schema + invalid_graph_op = dnnl_invalid_graph_op, + /// The shape cannot be inferred or compiled + invalid_shape = dnnl_invalid_shape, + /// The data type cannot be inferred or compiled + invalid_data_type = dnnl_invalid_data_type, +}; + +/// @} dnnl_graph_api_status + +/// @addtogroup dnnl_graph_api_allocator Allocator +/// +/// Definitions of allocator which is used to acquire memory resources in +/// partition compilation and execution. SYCL allocator +/// (#dnnl::graph::sycl_interop::make_allocator) should be used for SYCL runtime +/// and host allocator should be used for non-SYCL. +/// +/// @{ + +/// Allocator +class allocator : public allocator_handle { +public: + using allocator_handle::handle; + + /// Constructs an allocator according to given function pointers + /// + /// @param host_malloc A pointer to malloc function for CPU + /// @param host_free A pointer to free function for CPU + allocator(dnnl_graph_host_allocate_f host_malloc, + dnnl_graph_host_deallocate_f host_free) { + dnnl_graph_allocator_t a = nullptr; + error::wrap_c_api( + dnnl_graph_allocator_create(&a, host_malloc, host_free), + "could not create allocator for cpu"); + reset(a); + } + + /// Default constructor + allocator() { + dnnl_graph_allocator_t a = nullptr; + error::wrap_c_api(dnnl_graph_allocator_create(&a, nullptr, nullptr), + "could not create allocator"); + reset(a); + } +}; + +/// @} dnnl_graph_api_allocator + +/// @addtogroup dnnl_graph_api_engine Engine +/// @{ + +/// This API is a supplement for existing onednn engine API. +inline engine make_engine_with_allocator( + engine::kind kind, size_t index, const allocator &alloc) { + dnnl_engine_t c_engine; + error::wrap_c_api( + dnnl_graph_make_engine_with_allocator(&c_engine, + static_cast(kind), index, alloc.get()), + "could not make an engine with allocator"); + return engine(c_engine); +} + +/// @} dnnl_graph_api_engine + +/// @addtogroup dnnl_graph_api_logical_tensor Logical Tensor +/// +/// Logical tensor describes the meta-data of the input or output tensor, like +/// elements data type, number of dimensions, size for each dimension (shape), +/// layout, and the property of the tensor. +/// +/// Each logical tensor has an unique ID. The library uses logical tensor IDs to +/// build up the connections between operations if the output of one operation +/// has the same ID as the input of another operation. The meta-data in a +/// logical tensor may be enriched in the framework graph as it progresses +/// toward final execution. For example, the library doesn't require detailed +/// shape information at the operation and graph creation stage. But shape +/// information of input logical tensor will be required at partition +/// compilation stage. Logical tensor is not mutable. Users must create a new +/// logical tensor with the same ID to pass any new additional information to +/// oneDNN Graph API. Please note that the library also has unique IDs for +/// operations. The ID should be unique among different logical tensors, but it +/// can have the same value between a logical tensor and an operation. +/// +/// @{ + +/// Logical tensor object +class logical_tensor { + friend class op; + friend class tensor; + friend class partition; + friend class compiled_partition; + + dnnl_graph_logical_tensor_t data; + +public: + /// Integer type for representing dimension sizes and indices. + using dim = dnnl_dim_t; + /// Vector of dimensions. Implementations are free to force a limit on the + /// vector's length. + using dims = std::vector; + + /// Data Type + enum class data_type { + undef = dnnl_data_type_undef, + /// 16-bit/half-precision floating point. + f16 = dnnl_f16, + /// non-standard 16-bit (bfloat16 w/ 7 bit mantissa) floating point. + bf16 = dnnl_bf16, + /// 32-bit/single-precision floating point. + f32 = dnnl_f32, + /// 32-bit signed integer. + s32 = dnnl_s32, + /// 8-bit signed integer. + s8 = dnnl_s8, + /// 8-bit unsigned integer. + u8 = dnnl_u8, + /// Boolean data type. Size is C++ implementation defined. + boolean = dnnl_boolean, + /// [OFP8 standard 8-bit + /// floating-point](https://www.opencompute.org/documents/ocp-8-bit-floating-point-specification-ofp8-revision-1-0-2023-06-20-pdf) + /// with a 5-bit exponent and a 2-bit mantissa. + f8_e5m2 = dnnl_f8_e5m2, + /// [OFP8 standard 8-bit + /// floating-point](https://www.opencompute.org/documents/ocp-8-bit-floating-point-specification-ofp8-revision-1-0-2023-06-20-pdf) + /// with a 4-bit exponent and a 3-bit mantissa. + f8_e4m3 = dnnl_f8_e4m3, + /// 4-bit signed integer. + s4 = dnnl_s4, + /// 4-bit unsigned integer. + u4 = dnnl_u4, + }; + + /// Layout type + enum class layout_type { + /// Undefined layout type. + undef = dnnl_graph_layout_type_undef, + /// Any means to let the library to decide the layout for a tensor + /// during partition compilation. + any = dnnl_graph_layout_type_any, + /// Strided means that the layout of a tensor is determined by the + /// strides field in the logical tensor. + strided = dnnl_graph_layout_type_strided, + /// Opaque means that the layout of a tensor is the library specific. + /// Usually, an opaque layout is generated by a partition which is + /// compiled with layout type any. + opaque = dnnl_graph_layout_type_opaque, + }; + + /// Tensor property + enum class property_type { + /// Undefined tensor property. + undef = dnnl_graph_tensor_property_undef, + /// Variable means the tensor may be changed during computation or + /// between different iterations. + variable = dnnl_graph_tensor_property_variable, + /// Constant means the tensor will keep unchanged during computation and + /// between different iterations. It's useful for the library to apply + /// optimizations for constant tensors or cache constant tensors inside + /// the library. For example, constant weight tensors in inference + /// scenarios. + constant = dnnl_graph_tensor_property_constant, + /// Host scalar means the tensor will be a 0-D scalar tensor on host. + /// It should be used with a CPU engine when creating the tensor. + host_scalar = dnnl_graph_tensor_property_host_scalar, + }; + + /// default constructor + /// construct an empty object + logical_tensor() = default; + + /// Constructs a logical tensor object + explicit logical_tensor(const dnnl_graph_logical_tensor_t &c_data) + : data(c_data) {} + + /// Copy + logical_tensor(const logical_tensor &other) = default; + + /// Assign + logical_tensor &operator=(const logical_tensor &other) = default; + + /// Constructs a logical tensor object with ID, data type, ndims, layout + /// type, and property type. + /// + /// @param tid Logical tensor ID. + /// @param dtype Elements data type. + /// @param ndims Number of dimensions. -1 means unknown (see + /// #DNNL_GRAPH_UNKNOWN_NDIMS) and 0 means a scalar tensor. + /// @param ltype Layout type. + /// @param ptype Property type. + logical_tensor(size_t tid, data_type dtype, int32_t ndims, + layout_type ltype, property_type ptype = property_type::undef) { + dnnl_graph_logical_tensor_t val; + error::wrap_c_api( + dnnl_graph_logical_tensor_init(&val, tid, convert_to_c(dtype), + ndims, convert_to_c(ltype), convert_to_c(ptype)), + "could not create logical_tensor with property"); + data = val; + } + + /// Delegated constructor. + /// + /// @param tid Logical tensor ID. + /// @param dtype Elements data type. + /// @param ltype Layout type. + logical_tensor( + size_t tid, data_type dtype, layout_type ltype = layout_type::undef) + : logical_tensor(tid, dtype, DNNL_GRAPH_UNKNOWN_NDIMS, ltype) {} + + /// Constructs a logical tensor object with basic information and detailed + /// dims. + /// + /// @param tid Logical tensor ID. + /// @param dtype Elements data type. + /// @param adims Logical tensor dimensions. #DNNL_GRAPH_UNKNOWN_DIM means + /// the size of that dimension is unknown. 0 is used to define + /// zero-dimension tensor. + /// @param ltype Layout type. If it's strided, the strides field in the + /// output logical tensor will be deduced accordingly. + /// @param ptype Property type. + logical_tensor(size_t tid, data_type dtype, const dims &adims, + layout_type ltype, property_type ptype = property_type::undef) { + dnnl_graph_logical_tensor_t val; + // if dimension size equals to 0, it's a scalar + if (adims.empty()) + error::wrap_c_api(dnnl_graph_logical_tensor_init(&val, tid, + convert_to_c(dtype), 0, + convert_to_c(ltype), convert_to_c(ptype)), + "could not create logical_tensor with property"); + else + error::wrap_c_api( + dnnl_graph_logical_tensor_init_with_dims(&val, tid, + convert_to_c(dtype), + static_cast(adims.size()), adims.data(), + convert_to_c(ltype), convert_to_c(ptype)), + "could not create logical_tensor with dims and property"); + data = val; + } + + /// Constructs a logical tensor object with detailed dims and strides. The + /// layout_type of the output logical tensor object will always be strided. + /// + /// @param tid Logical tensor ID. + /// @param dtype Elements data type. + /// @param adims Logical tensor dimensions. #DNNL_GRAPH_UNKNOWN_DIM means + /// the size of that dimension is unknown. 0 is used to define + /// zero-dimension tensor. + /// @param strides Logical tensor strides. #DNNL_GRAPH_UNKNOWN_DIM means + /// the stride of the dimension is unknown. The library currently + /// doesn't support other negative stride values. + /// @param ptype Property type. + logical_tensor(size_t tid, data_type dtype, const dims &adims, + const dims &strides, property_type ptype = property_type::undef) { + dnnl_graph_logical_tensor_t val; + // TODO(lvtao): check the size of adims and strides. + // They should be same. + error::wrap_c_api( + dnnl_graph_logical_tensor_init_with_strides(&val, tid, + convert_to_c(dtype), static_cast(adims.size()), + adims.data(), strides.data(), convert_to_c(ptype)), + "could not create logical_tensor with strides and property"); + data = val; + } + + /// Constructs a logical tensor object with detailed dims and an opaque + /// layout ID. layout_type of the output logical tensor object will always + /// be opaque. + /// + /// @param tid Logical tensor ID. + /// @param dtype Elements data type. + /// @param adims Logical tensor dimensions. #DNNL_GRAPH_UNKNOWN_DIM means + /// the size of that dimension is unknown. 0 is used to define + /// zero-dimension tensor. + /// @param lid Opaque layout id. + /// @param ptype Property type + logical_tensor(size_t tid, data_type dtype, const dims &adims, size_t lid, + property_type ptype = property_type::undef) { + dnnl_graph_logical_tensor_t val; + + if (adims.empty()) { + error::wrap_c_api(dnnl_graph_logical_tensor_init(&val, tid, + convert_to_c(dtype), 0, + convert_to_c(layout_type::opaque), + convert_to_c(ptype)), + "could not create logical_tensor"); + } else { + error::wrap_c_api( + dnnl_graph_logical_tensor_init_with_dims(&val, tid, + convert_to_c(dtype), + static_cast(adims.size()), adims.data(), + convert_to_c(layout_type::opaque), + convert_to_c(ptype)), + "could not create logical_tensor with dims"); + } + + val.layout.layout_id = lid; + data = val; + } + + /// Returns dimensions of a logical tensor. + /// + /// @returns A vector describing the size of each dimension. + dims get_dims() const { + if (data.ndims < 0) { + error::wrap_c_api(dnnl_invalid_arguments, + "cannot return dims when ndims < 0"); + } + + return {data.dims, data.dims + data.ndims}; + } + + /// Returns the unique id of a logical tensor. + /// + /// @returns An integer value describing the ID. + size_t get_id() const { return data.id; } + + /// Returns the data type of a logical tensor. + /// + /// @returns The data type. + data_type get_data_type() const { + return static_cast(data.data_type); + } + + /// Returns the property type of a logical tensor. + /// + /// @returns The property type. + property_type get_property_type() const { + return static_cast(data.property); + } + + /// Returns the layout type of a logical tensor. + /// + /// @returns The layout type. + layout_type get_layout_type() const { + return static_cast(data.layout_type); + } + + /// Returns the layout ID of a logical tensor. The API should be called on a + /// logical tensor with opaque layout type. Otherwise, an exception will be + /// raised. + /// + /// @returns Layout ID. + size_t get_layout_id() const { + if (get_layout_type() != layout_type::opaque) { + error::wrap_c_api( + dnnl_invalid_arguments, "layout type should be opaque"); + } + + return data.layout.layout_id; + } + + /// Returns the strides of a logical tensor. The API should be called on a + /// logical tensor with strided layout type. Otherwise, an exception will be + /// raised. + /// + /// @returns A vector describing the stride size of each dimension. + dims get_strides() const { + if (get_layout_type() != layout_type::strided) { + error::wrap_c_api( + dnnl_invalid_arguments, "layout type should be strided"); + } + + if (data.ndims < 0) { + error::wrap_c_api(dnnl_invalid_arguments, + "cannot return strides when ndims < 0"); + } + + return {data.layout.strides, data.layout.strides + data.ndims}; + } + + /// Returns memory size in bytes required by this logical tensor. + /// + /// @returns The memory size in bytes. + size_t get_mem_size() const { + size_t size = 0; + error::wrap_c_api(dnnl_graph_logical_tensor_get_mem_size(&data, &size), + "could not get memory size from the logical_tensor"); + return size; + } + + /// Compares if two logical tenors are equal. Users can decide accordingly + /// if layout reordering is needed for two logical tensors. The method will + /// return true for below two circumstances: + /// + /// 1. the two logical tensors are equal regarding each field in the struct, + /// eg. id, ndims, dims, layout type, property, etc. + /// 2. If all other fields are equal but the layout types in two logical + /// tensors are different, the method will return true when the underlying + /// memory layout is the same. For example, one logical tensor has strided + /// layout type while the other one has opaque layout type, but underneath, + /// both layouts are NHWC, the method will still return true for this case. + /// + /// @param lt The input logical tensor to be compared. + /// @returns @c true if the two logical tensors are equal. @c false otherwise + bool is_equal(const logical_tensor <) const { + uint8_t equal = 0; + error::wrap_c_api( + dnnl_graph_logical_tensor_is_equal(&data, <.data, &equal), + "could not compare between the two logical tensors"); + return equal != 0; + } + +private: + static dnnl_data_type_t convert_to_c(data_type dtype) { + return static_cast(dtype); + } + + static dnnl_graph_layout_type_t convert_to_c(layout_type ltype) { + return static_cast(ltype); + } + + static dnnl_graph_tensor_property_t convert_to_c(property_type ptype) { + return static_cast(ptype); + } +}; + +/// @} dnnl_graph_api_logical_tensor + +/// @addtogroup dnnl_graph_api_tensor Tensor +/// +/// Tensor is an abstraction for multi-dimensional input and output data needed +/// in the execution of a compiled partition. A tensor object encapsulates a +/// handle to a memory buffer allocated on a specific engine and a logical +/// tensor which describes the dimensions, elements data type, and memory +/// layout. +/// +/// @{ + +/// A tensor object +class tensor : public tensor_handle { +public: + using tensor_handle::handle; + + /// Default constructor. Constructs an empty object. + tensor() = default; + + /// Constructs a tensor object according to a given logical tensor, an + /// engine, and a memory handle. + /// + /// @param lt The given logical tensor + /// @param aengine Engine to store the data on. + /// @param handle Handle of memory buffer to use as an underlying storage. + /// - A pointer to the user-allocated buffer. In this case the library + /// doesn't own the buffer. + /// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to + /// allocate the buffer for the tensor. In this case the library + /// owns the buffer. + /// - DNNL_MEMORY_NONE to create tensor without an underlying buffer. + tensor(const logical_tensor <, const engine &aengine, void *handle) { + dnnl_graph_tensor_t t = nullptr; + error::wrap_c_api( + dnnl_graph_tensor_create(&t, &(lt.data), aengine.get(), handle), + "could not create tensor object with the logical_tensor, " + "engine, and handle"); + reset(t); + } + + /// Constructs a tensor object. + /// The underlying buffer for the memory will be allocated by the library. + /// + /// @param lt The given logical tensor + /// @param aengine Engine to store the data on. + tensor(const logical_tensor <, const engine &aengine) + : tensor(lt, aengine, DNNL_MEMORY_ALLOCATE) {} + + /// Creates a tensor object for host-side scalar value. The data type contained + /// in the logical tensor parameter will be used to interpret the scalar + /// pointer. The property type in the logical tensor must be `host_scalar`. + /// + /// @param lt The logical tensor describing the host scalar + /// @param scalar The pointer to scalar value + /// @returns Created tensor object + static tensor make_scalar_tensor(const logical_tensor <, void *scalar) { + dnnl_graph_tensor_t t = nullptr; + error::wrap_c_api( + dnnl_graph_tensor_create_scalar(&t, &(lt.data), scalar), + "could not create a scalar tensor object"); + + return tensor(t); + } + + /// Returns the underlying memory buffer. + /// + /// On the CPU engine, or when using USM, this is a pointer to the + /// allocated memory. + void *get_data_handle() const { + void *handle = nullptr; + error::wrap_c_api(dnnl_graph_tensor_get_data_handle(get(), &handle), + "could not get data handle from the tensor"); + return handle; + } + + /// Sets the underlying memory handle. + /// + /// @param handle Memory handle. + void set_data_handle(void *handle) { + error::wrap_c_api(dnnl_graph_tensor_set_data_handle(get(), handle), + "setting data handle to the tensor failed"); + } + + /// Returns the associated engine. + /// + /// @returns An engine object + engine get_engine() const { + dnnl_engine_t c_engine = nullptr; + error::wrap_c_api(dnnl_graph_tensor_get_engine(get(), &c_engine), + "could not get an engine from a tensor object"); + return engine(c_engine, true); + } + + /// Returns the logical tensor of a tensor object. + /// + /// @returns A logical_tensor object. + logical_tensor get_logical_tensor() const { + dnnl_graph_logical_tensor_t lt; + error::wrap_c_api(dnnl_graph_tensor_get_logical_tensor(get(), <), + "could not get logical tensor from a tensor object"); + return logical_tensor(lt); + } +}; + +/// @} dnnl_graph_api_tensor + +/// @addtogroup dnnl_graph_api_compiled_partition Compiled Partition +/// +/// A compiled partition represents the generated kernels specialized for a +/// partition on a target hardware (engine) with input and output information +/// specified by the logical tensors. +/// +/// @{ + +/// A compiled partition object. +class compiled_partition : public compiled_partition_handle { +public: + /// Default constructor. Constructs an empty object. + compiled_partition() = default; + + /// Constructs a compiled partition object + compiled_partition(dnnl_graph_compiled_partition_t compiled_partition) { + reset(compiled_partition, false); + } + + /// Queries an input or output logical tensor according to tensor ID. If the + /// tensor ID doesn't belong to any input or output of the compiled + /// partition, an exception will be raised by the API. + /// + /// @param tid The unique id of required tensor. + /// @returns The logical tensor. + logical_tensor query_logical_tensor(size_t tid) const { + dnnl_graph_logical_tensor_t lt; + error::wrap_c_api(dnnl_graph_compiled_partition_query_logical_tensor( + get(), tid, <), + "query logical tensor from compiled_partition failed"); + return logical_tensor {lt}; + } + + /// Returns the hint of in-place pairs from a compiled partition. It + /// indicates that an input and an output of the partition can share the + /// same memory buffer for computation. In-place computation helps to reduce + /// the memory footprint and improves cache locality. But since the library + /// may not have a global view of user's application, it's possible that the + /// input tensor is used at other places in user's computation graph. In + /// this case, the user should take the in-place pair as a hint and pass a + /// different memory buffer for output tensor to avoid overwriting the input + /// memory buffer which will probably cause unexpected incorrect results. + /// + /// @returns A list of pairs of input and output IDs. + std::vector> get_inplace_ports() const { + size_t num = 0; + const dnnl_graph_inplace_pair_t *inplace_pairs; + + error::wrap_c_api(dnnl_graph_compiled_partition_get_inplace_ports( + get(), &num, &inplace_pairs), + "could not get the in-place pairs from a compiled partition"); + if (num == 0) return {}; + + std::vector> inplace_options; + inplace_options.reserve(num); + for (size_t i = 0; i < num; ++i) { + const dnnl_graph_inplace_pair_t *inplace_pair = inplace_pairs + i; + inplace_options.emplace_back( + inplace_pair->input_id, inplace_pair->output_id); + } + return inplace_options; + } + + /// Execute a compiled partition. + /// + /// @param astream Stream object to run over. + /// @param inputs A list of input tensors. + /// @param outputs A list of output tensors. + void execute(stream &astream, const std::vector &inputs, + const std::vector &outputs) const { + std::vector c_inputs; + c_inputs.reserve(inputs.size()); + for (auto &in : inputs) { + c_inputs.push_back(in.get()); + } + std::vector c_outputs; + c_outputs.reserve(outputs.size()); + for (auto &out : outputs) { + c_outputs.push_back(out.get()); + } + + error::wrap_c_api( + dnnl_graph_compiled_partition_execute(get(), astream.get(), + c_inputs.size(), c_inputs.data(), c_outputs.size(), + c_outputs.data()), + "could not execute the compiled_partition"); + } +}; + +/// @} dnnl_graph_api_compiled_partition + +/// @addtogroup dnnl_graph_api_op Op +/// +/// OP is an abstraction of computation logic for deep neural network +/// operations. An op object encapsulates an operation kind which describes the +/// computation logic, an unique ID which differentiates operations with the +/// same kind, and logical tensors which describes the input and output of the +/// operation and its connections to other operations in the graph. +/// +/// @{ + +/// An op object. +class op : public op_handle { +public: + /// Kinds of operations + enum class kind { + Abs = dnnl_graph_op_abs, + AbsBackward = dnnl_graph_op_abs_backward, + Add = dnnl_graph_op_add, + AvgPool = dnnl_graph_op_avg_pool, + AvgPoolBackward = dnnl_graph_op_avg_pool_backward, + BatchNormForwardTraining = dnnl_graph_op_batch_norm_forward_training, + BatchNormInference = dnnl_graph_op_batch_norm_inference, + BatchNormTrainingBackward = dnnl_graph_op_batch_norm_backward, + BiasAdd = dnnl_graph_op_bias_add, + BiasAddBackward = dnnl_graph_op_bias_add_backward, + Clamp = dnnl_graph_op_clamp, + ClampBackward = dnnl_graph_op_clamp_backward, + Concat = dnnl_graph_op_concat, + Convolution = dnnl_graph_op_convolution, + ConvolutionBackwardData = dnnl_graph_op_convolution_backward_data, + ConvolutionBackwardWeights = dnnl_graph_op_convolution_backward_weights, + ConvTranspose = dnnl_graph_op_conv_transpose, + ConvTransposeBackwardData = dnnl_graph_op_conv_transpose_backward_data, + ConvTransposeBackwardWeights + = dnnl_graph_op_conv_transpose_backward_weights, + Dequantize = dnnl_graph_op_dequantize, + Divide = dnnl_graph_op_divide, + DynamicDequantize = dnnl_graph_op_dynamic_dequantize, + DynamicQuantize = dnnl_graph_op_dynamic_quantize, + Elu = dnnl_graph_op_elu, + EluBackward = dnnl_graph_op_elu_backward, + End = dnnl_graph_op_end, + Exp = dnnl_graph_op_exp, + GELU = dnnl_graph_op_gelu, + GELUBackward = dnnl_graph_op_gelu_backward, + GroupNorm = dnnl_graph_op_group_norm, + HardSigmoid = dnnl_graph_op_hard_sigmoid, + HardSigmoidBackward = dnnl_graph_op_hard_sigmoid_backward, + HardSwish = dnnl_graph_op_hard_swish, + HardSwishBackward = dnnl_graph_op_hard_swish_backward, + Interpolate = dnnl_graph_op_interpolate, + InterpolateBackward = dnnl_graph_op_interpolate_backward, + LayerNorm = dnnl_graph_op_layer_norm, + LayerNormBackward = dnnl_graph_op_layer_norm_backward, + LeakyReLU = dnnl_graph_op_leaky_relu, + Log = dnnl_graph_op_log, + LogSoftmax = dnnl_graph_op_log_softmax, + LogSoftmaxBackward = dnnl_graph_op_log_softmax_backward, + MatMul = dnnl_graph_op_matmul, + Maximum = dnnl_graph_op_maximum, + MaxPool = dnnl_graph_op_max_pool, + MaxPoolBackward = dnnl_graph_op_max_pool_backward, + Minimum = dnnl_graph_op_minimum, + Mish = dnnl_graph_op_mish, + MishBackward = dnnl_graph_op_mish_backward, + Multiply = dnnl_graph_op_multiply, + Pow = dnnl_graph_op_pow, + PReLU = dnnl_graph_op_prelu, + PReLUBackward = dnnl_graph_op_prelu_backward, + Quantize = dnnl_graph_op_quantize, + Reciprocal = dnnl_graph_op_reciprocal, + ReduceL1 = dnnl_graph_op_reduce_l1, + ReduceL2 = dnnl_graph_op_reduce_l2, + ReduceMax = dnnl_graph_op_reduce_max, + ReduceMean = dnnl_graph_op_reduce_mean, + ReduceMin = dnnl_graph_op_reduce_min, + ReduceProd = dnnl_graph_op_reduce_prod, + ReduceSum = dnnl_graph_op_reduce_sum, + ReLU = dnnl_graph_op_relu, + ReLUBackward = dnnl_graph_op_relu_backward, + Reorder = dnnl_graph_op_reorder, + Round = dnnl_graph_op_round, + RMSNorm = dnnl_graph_op_rms_norm, + Select = dnnl_graph_op_select, + Sigmoid = dnnl_graph_op_sigmoid, + SigmoidBackward = dnnl_graph_op_sigmoid_backward, + SoftMax = dnnl_graph_op_softmax, + SoftMaxBackward = dnnl_graph_op_softmax_backward, + SoftPlus = dnnl_graph_op_softplus, + SoftPlusBackward = dnnl_graph_op_softplus_backward, + Sqrt = dnnl_graph_op_sqrt, + SqrtBackward = dnnl_graph_op_sqrt_backward, + Square = dnnl_graph_op_square, + SquaredDifference = dnnl_graph_op_squared_difference, + StaticReshape = dnnl_graph_op_static_reshape, + StaticTranspose = dnnl_graph_op_static_transpose, + Subtract = dnnl_graph_op_subtract, + Tanh = dnnl_graph_op_tanh, + TanhBackward = dnnl_graph_op_tanh_backward, + TypeCast = dnnl_graph_op_type_cast, + Wildcard = dnnl_graph_op_wildcard, + GenIndex = dnnl_graph_op_gen_index, + GreaterEqual = dnnl_graph_op_greater_equal, + // Sentinel + LastSymbol = dnnl_graph_op_last_symbol, + }; + + /// Attributes of operations. Different operations support different + /// attributes. Check the document of each operation for what attributes are + /// supported and what are the potential values for them. Missing required + /// attribute or illegal attribute value may lead to failure when adding the + /// operation to a graph. + enum class attr { + /// Undefined op attribute. + undef = dnnl_graph_op_attr_undef, + + // float32 attributes. The value of these attributes can be any single + // float32 number. + + /// Specifies an alpha attribute to an op. + alpha = dnnl_graph_op_attr_alpha, + /// Specifies an beta attribute to an op. + beta = dnnl_graph_op_attr_beta, + /// Specifies an epsilon attribute to an op. + epsilon = dnnl_graph_op_attr_epsilon, + /// Specifies a max attribute to an op. + max = dnnl_graph_op_attr_max, + /// Specifies a min attribute to an op. + min = dnnl_graph_op_attr_min, + /// Specifies a momentum attribute to an op. + momentum = dnnl_graph_op_attr_momentum, + + // float32 vector attributes. The value of these attributes can be a + // vector of float32 numbers. + + /// Specifies a scales attribute to an op. + scales = dnnl_graph_op_attr_scales, + + // int64_t attributes. The value of these attributes can be any single + // int64 number. + + /// Specifies an axis attribute to an op. + axis = dnnl_graph_op_attr_axis, + /// Specifies a begin_norm_axis attribute to an op. + begin_norm_axis = dnnl_graph_op_attr_begin_norm_axis, + /// Specifies a groups attribute to an op. + groups = dnnl_graph_op_attr_groups, + + // int64_t vector attributes. The value of these attributes can be a + // vector of int64 numbers. + + /// Specifies an axes attribute to an op. + axes = dnnl_graph_op_attr_axes, + /// Specifies a dilations attribute to an op. + dilations = dnnl_graph_op_attr_dilations, + /// Specifies an dst_shape attribute to an op. + dst_shape = dnnl_graph_op_attr_dst_shape, + /// Specifies a kernel attribute to an op. + kernel = dnnl_graph_op_attr_kernel, + /// Specifies an order attribute to an op. + order = dnnl_graph_op_attr_order, + /// Specifies an output_padding attribute to an op. + output_padding = dnnl_graph_op_attr_output_padding, + /// Specifies a pads_begin attribute to an op. + pads_begin = dnnl_graph_op_attr_pads_begin, + /// Specifies a pads_end attribute to an op. + pads_end = dnnl_graph_op_attr_pads_end, + /// Specifies a shape attribute to an op. + shape = dnnl_graph_op_attr_shape, + /// Specifies a sizes attribute to an op. + sizes = dnnl_graph_op_attr_sizes, + /// Specifies an src_shape attribute to an op. + src_shape = dnnl_graph_op_attr_src_shape, + /// Specifies a strides attribute to an op. + strides = dnnl_graph_op_attr_strides, + /// Specifies a weight_shape attribute to an op. + weights_shape = dnnl_graph_op_attr_weights_shape, + /// Specifies a zps attribute to an op. + zps = dnnl_graph_op_attr_zps, + /// Specifies the group shape of an op. The size of the vector should + /// match that of the input. For the dimensions where the grouped + /// quantization occurs, the values should correspond to the group + /// size, which indicates the number of elements that will share the + /// same scaling factor. + group_shape = dnnl_graph_op_attr_group_shape, + + // bool attributes. The value of these attributes can be any single bool + // value. + + /// Specifies an exclude_pad attribute to an op. + exclude_pad = dnnl_graph_op_attr_exclude_pad, + /// Specifies a keep_dims attribute to an op. + keep_dims = dnnl_graph_op_attr_keep_dims, + /// Specifies a keep_stats attribute to an op. + keep_stats = dnnl_graph_op_attr_keep_stats, + /// Specifies a per_channel_broadcast attribute to an op. + per_channel_broadcast = dnnl_graph_op_attr_per_channel_broadcast, + /// Specifies a special_zero attribute to an op. + special_zero = dnnl_graph_op_attr_special_zero, + /// Specifies a transpose_a attribute to an op. + transpose_a = dnnl_graph_op_attr_transpose_a, + /// Specifies a transpose_b attribute to an op. + transpose_b = dnnl_graph_op_attr_transpose_b, + /// Specifies an use_affine attribute to an op. + use_affine = dnnl_graph_op_attr_use_affine, + /// Specifies an use_dst attribute to an op. + use_dst = dnnl_graph_op_attr_use_dst, + + // string attributes. The value of these attributes can be a string. + + /// Specifies an auto_broadcast attribute to an op. The value can be + /// "none" or "numpy". + auto_broadcast = dnnl_graph_op_attr_auto_broadcast, + /// Specifies an auto_pad attribute to an op. The value can be "none", + /// "same_upper", "same_lower", or "valid". + auto_pad = dnnl_graph_op_attr_auto_pad, + /// Specifies an coordinate_transformation_mode attribute to an op. The + /// value can be "half_pixel" or "align_corners". The attribute is + /// defined for Interpolate operations. + coordinate_transformation_mode + = dnnl_graph_op_attr_coordinate_transformation_mode, + /// Specifies a data_format of an op. The value can be "NCX" or "NXC". + data_format = dnnl_graph_op_attr_data_format, + /// Specifies a mode attribute of an op. + /// Interpolate: "nearest", "linear", "bilinear", or "trilinear". + /// SoftMax: "none", "inf_as_zero". + /// GELU/GELUBackward: "gelu_erf", "gelu_tanh". + mode = dnnl_graph_op_attr_mode, + /// Specifies a qtype attribute to an op. The value can be "per_channel" + /// or "per_tensor". The attribute is defined for quantization + /// operations. + qtype = dnnl_graph_op_attr_qtype, + /// Specifies a rounding_type attribute to an op. The value can be + /// "ceil" or "floor". + rounding_type = dnnl_graph_op_attr_rounding_type, + /// Specifies a weights_format of an op. The value can be "OIX", "XIO", + /// "IOX", or "XOI". Different operations may support different values. + weights_format = dnnl_graph_op_attr_weights_format, + /// Specifies an accumulation_mode attribute to an op. The value can be + /// "strict", "relaxed", "any", "f32", "s32", or "f16". + accumulation_mode = dnnl_graph_op_attr_accumulation_mode, + + /// Specifies the end of all above exteral attributes for check. + end = dnnl_graph_op_attr_end, + }; + + /// Constructs an op object with an unique ID, an operation kind, and a name + /// string. + /// + /// @param id The unique ID of the op. + /// @param akind The op kind specifies which computation is represented by + /// the op, such as Convolution or ReLU. + /// @param verbose_name The string added as the op name. + op(size_t id, kind akind, const std::string &verbose_name = "") { + dnnl_graph_op_t op = nullptr; + error::wrap_c_api(dnnl_graph_op_create(&op, id, convert_to_c(akind), + verbose_name.c_str()), + "could not create op with id and op kind"); + reset(op); + } + + /// Constructs an op object with an unique ID, an operation kind, and + /// input/output logical tensors. + /// + /// @param id The unique ID of this op. + /// @param akind The op kind specifies which computation is represented by + /// this op, such as Convolution or ReLU. + /// @param inputs Input logical tensor to be bound to this op. + /// @param outputs Output logical tensor to be bound to this op. + /// @param verbose_name The string added as the op name. + op(size_t id, kind akind, const std::vector &inputs, + const std::vector &outputs, + const std::string &verbose_name = "") + : op(id, akind, verbose_name) { + for (const auto &input : inputs) { + error::wrap_c_api(dnnl_graph_op_add_input(get(), &(input.data)), + "adding input to the op failed"); + } + for (const auto &output : outputs) { + error::wrap_c_api(dnnl_graph_op_add_output(get(), &(output.data)), + "adding output to the op failed"); + } + } + + /// Adds an input logical tensor to the op. + /// + /// @param t Input logical tensor. + void add_input(const logical_tensor &t) { + error::wrap_c_api(dnnl_graph_op_add_input(get(), &(t.data)), + "adding input to the op failed"); + } + + /// Adds a vector of input logical tensors to the op. + /// + /// @param ts The list of input logical tensors. + void add_inputs(const std::vector &ts) { + for (const auto &t : ts) { + error::wrap_c_api(dnnl_graph_op_add_input(get(), &(t.data)), + "adding input to the op failed"); + } + } + + /// Adds an output logical tensor to the op. + /// + /// @param t Output logical tensor. + void add_output(const logical_tensor &t) { + error::wrap_c_api(dnnl_graph_op_add_output(get(), &(t.data)), + "adding output to the op failed"); + } + + /// Adds a vector of output logical tensors to the op. + /// + /// @param ts The list of output logical tensors. + void add_outputs(const std::vector &ts) { + for (const auto &t : ts) { + error::wrap_c_api(dnnl_graph_op_add_output(get(), &(t.data)), + "adding output to the op failed"); + } + } + + /// Sets the attribute according to the name and type (int64_t). + /// + /// @tparam Type_i Attribute's type. + /// @param name Attribute's name. + /// @param value The attribute's value. + /// @returns The Op self. + template ::value> = true> + op &set_attr(attr name, const Type_i &value) { + dnnl_graph_op_attr_t attr = convert_to_c(name); + error::wrap_c_api(dnnl_graph_op_set_attr_s64(get(), attr, &value, 1), + "could not set attribute to the op"); + return *this; + } + + /// Sets the attribute according to the name and type (float). + /// + /// @tparam Type_f Attribute's type. + /// @param name Attribute's name. + /// @param value The attribute's value. + /// @returns The Op self. + template ::value> = true> + op &set_attr(attr name, const Type_f &value) { + dnnl_graph_op_attr_t attr = convert_to_c(name); + error::wrap_c_api(dnnl_graph_op_set_attr_f32(get(), attr, &value, 1), + "could not set attribute to the op"); + return *this; + } + + /// Sets the attribute according to the name and type (bool). + /// + /// @tparam Type_b Attribute's type. + /// @param name Attribute's name. + /// @param value The attribute's value. + /// @returns The Op self. + template ::value> = true> + op &set_attr(attr name, const Type_b &value) { + dnnl_graph_op_attr_t attr = convert_to_c(name); + const uint8_t val = value; + error::wrap_c_api(dnnl_graph_op_set_attr_bool(get(), attr, &val, 1), + "could not set attribute to the op"); + return *this; + } + + /// Sets the attribute according to the name and type (string). + /// + /// @tparam Type_s Attribute's type. + /// @param name Attribute's name. + /// @param value The attribute's value. + /// @returns The Op self. + template ::value> = true> + op &set_attr(attr name, const Type_s &value) { + dnnl_graph_op_attr_t attr = convert_to_c(name); + error::wrap_c_api(dnnl_graph_op_set_attr_str( + get(), attr, value.c_str(), value.size()), + "could not set attribute to the op"); + return *this; + } + + /// Sets the attribute according to the name and type + /// (std::vector). + /// + /// @tparam Type_is Attribute's type. + /// @param name Attribute's name. + /// @param value The attribute's value. + /// @returns The Op self. + template >::value> = true> + op &set_attr(attr name, const Type_is &value) { + dnnl_graph_op_attr_t attr = convert_to_c(name); + error::wrap_c_api(dnnl_graph_op_set_attr_s64( + get(), attr, value.data(), value.size()), + "could not set attribute to the op"); + return *this; + } + + /// Sets the attribute according to the name and type (std::vector). + /// + /// @tparam Type_fs Attribute's type. + /// @param name Attribute's name. + /// @param value The attribute's value. + /// @returns The Op self. + template >::value> = true> + op &set_attr(attr name, const Type_fs &value) { + dnnl_graph_op_attr_t attr = convert_to_c(name); + error::wrap_c_api(dnnl_graph_op_set_attr_f32( + get(), attr, value.data(), value.size()), + "could not set attribute to the op"); + return *this; + } + +private: + dnnl_graph_op_kind_t convert_to_c(kind akind) { + return static_cast(akind); + } + + dnnl_graph_op_attr_t convert_to_c(attr aattr) { + return static_cast(aattr); + } +}; + +/// @} dnnl_graph_api_op + +/// @addtogroup dnnl_graph_api_partition Partition +/// +/// Partition represents a collection of operations and their input and output +/// logical tensors identified by library as the basic unit for compilation and +/// execution. +/// +/// @{ + +/// A partition object. +class partition : public partition_handle { +public: + /// Policy specifications for partitioning. + enum class policy { + /// Fusion policy returns partitions with typical post-op fusions, eg. + /// Convolution + ReLU or other element-wise operations or a chian of + /// post-ops. + fusion = dnnl_graph_partition_policy_fusion, + /// Debug policy doesn't not apply any fusions. It returns partitions + /// with single operations in each partition. The policy is useful when + /// users notice any bug or correctness issue in fusion policy. + debug = dnnl_graph_partition_policy_debug, + }; + + partition() = default; + + /// Constructs a partition object + /// + /// @param p A raw pointer to the C API handle + partition(dnnl_graph_partition_t p) { reset(p, false); } + + /// Creates a new partition with a given operator and engine kind. The API + /// is used to create a partition from an operation directly without + /// creating the graph and calling `get_partitions()`. The output partition + /// contains only one operation. + /// + /// @param aop An operation used to create the partition. + /// @param ekind Engine kind. + partition(const op &aop, engine::kind ekind) { + dnnl_graph_partition_t p = nullptr; + error::wrap_c_api(dnnl_graph_partition_create_with_op(&p, aop.get(), + static_cast(ekind)), + "could not create a partition with the op and engine kind"); + reset(p); + } + + /// Returns the number of operations contained in the partition. + /// + /// @returns Number of operations. + size_t get_ops_num() const { + size_t num {0}; + error::wrap_c_api(dnnl_graph_partition_get_op_num(get(), &num), + "could not get number of ops from the partition"); + return num; + } + + /// Returns all operation IDs contained in the partition. + /// + /// @returns An unordered set of operation IDs. + std::vector get_ops() const { + auto num = get_ops_num(); + std::vector ops(num); + + error::wrap_c_api(dnnl_graph_partition_get_ops(get(), num, ops.data()), + "could not get op ids from the partition"); + return ops; + } + + /// Returns the unique ID of the partition. Partition ID is generated by the + /// library internally. The ID can be used for debugging purpose or verbose. + /// + /// @returns ID of the partition. + size_t get_id() const { + size_t id {}; + error::wrap_c_api(dnnl_graph_partition_get_id(get(), &id), + "could not get id of the partition"); + return id; + } + + /// Compiles a partition with given input and output logical tensors. The + /// output logical tensors can contain unknown dimensions. For this case, + /// the compilation will deduce the output shapes according to input shapes. + /// The output logical tensors can also have layout type `any`. The + /// compilation will choose the optimal layout for output tensors. The + /// optimal layout will be represented as an opaque layout ID saved in the + /// output logical tensor. + /// + /// @param inputs A list of input logical tensors. + /// @param outputs A list of output logical tensors. + /// @param e The engine used to compile the partition. + /// @returns A compiled partition. + compiled_partition compile(const std::vector &inputs, + const std::vector &outputs, const engine &e) const { + if (!is_supported()) { + error::wrap_c_api(dnnl_invalid_arguments, + "could not compile an unsupported partition"); + } + + return compile_(inputs, outputs, e); + } + + /// Returns the supporting status of a partition. Some operations may not be + /// supported by the library under certain circumstances. During + /// partitioning stage, unsupported partitions will be returned to users + /// with each containing an unsupported operation. Users should check the + /// supporting status of a partition before transforming the computation + /// graph or compiling the partition. + /// + /// @returns @c true if this partition is supported or @c false if this + /// partition isn't supported by the library + bool is_supported() const { + uint8_t supported {0}; + error::wrap_c_api(dnnl_graph_partition_is_supported(get(), &supported), + "could not get supporting status of the partition"); + return supported != 0; + } + + /// Returns a list of input logical tensors from the partition. + /// + /// @returns A list of input logical tensors. + std::vector get_input_ports() const { + size_t num = 0; + error::wrap_c_api(dnnl_graph_partition_get_input_ports_num(get(), &num), + "could not get number of inputs of the partition"); + if (num == 0) return {}; + + std::vector c_inputs(num); + error::wrap_c_api(dnnl_graph_partition_get_input_ports( + get(), num, c_inputs.data()), + "could not get input logical tensors of the partition"); + + std::vector inputs; + inputs.reserve(num); + for (auto &c_lt : c_inputs) + inputs.emplace_back(c_lt); + return inputs; + } + + /// Returns a list of output logical tensors from the partition. + /// + /// @returns A list of output logical tensor. + std::vector get_output_ports() const { + size_t num = 0; + error::wrap_c_api( + dnnl_graph_partition_get_output_ports_num(get(), &num), + "cannot get number of outputs of the partition"); + if (num == 0) return {}; + + std::vector c_outputs(num); + error::wrap_c_api(dnnl_graph_partition_get_output_ports( + get(), num, c_outputs.data()), + "could not get output logical tensors of the partition"); + + std::vector outputs; + outputs.reserve(num); + for (auto &c_lt : c_outputs) + outputs.emplace_back(c_lt); + return outputs; + } + + /// Returns the engine kind of the partition + /// + /// @returns The engine kind + engine::kind get_engine_kind() const { + dnnl_engine_kind_t akind; + error::wrap_c_api(dnnl_graph_partition_get_engine_kind(get(), &akind), + "cannot get the engine kind from the partition"); + + return static_cast(akind); + } + +private: + compiled_partition compile_(const std::vector &inputs, + const std::vector &outputs, const engine &e) const { + std::vector c_inputs; + std::vector c_outputs; + + c_inputs.reserve(inputs.size()); + for (const auto &in : inputs) { + c_inputs.push_back(&(in.data)); + } + + c_outputs.reserve(outputs.size()); + for (const auto &out : outputs) { + c_outputs.push_back(&(out.data)); + } + + dnnl_graph_compiled_partition_t cpartitions = nullptr; + error::wrap_c_api( + dnnl_graph_compiled_partition_create(&cpartitions, get()), + "could not create compiled_partition"); + error::wrap_c_api(dnnl_graph_partition_compile(get(), cpartitions, + c_inputs.size(), c_inputs.data(), + c_outputs.size(), c_outputs.data(), e.get()), + "partition compile failed"); + + return compiled_partition(cpartitions); + } +}; + +/// @} dnnl_graph_api_partition + +/// @addtogroup dnnl_graph_api_graph Graph +/// +/// Graph represents a computational DAG with a set of operations. +/// #dnnl::graph::graph::add_op() adds an operation and its input and output +/// logical tensors into a graph. The library accumulates the operations and +/// logical tensors and constructs and validates the graph as an internal state. +/// A graph object is associated to a specific engine kind. The partitions +/// returned from the graph will inherit the engine kind of the graph. +/// +/// @{ + +/// A graph object. +class graph : public graph_handle { +public: + /// Constructs a graph with an engine kind. + /// + /// @param engine_kind Engine kind. + graph(engine::kind engine_kind) { + dnnl_graph_graph_t g = nullptr; + error::wrap_c_api( + dnnl_graph_graph_create(&g, convert_to_c(engine_kind)), + "could not create graph with engine kind"); + reset(g); + } + + /// Creates a new empty graph with an engine kind and a floating-point math + /// mode. All partitions returned from the graph will inherit the engine + /// kind and floating-point math mode. + /// + /// Setting the floating-point math mode enables automatic down-conversion + /// of inputs for the given graph, promoting speedup by using + /// lower-precision data types when available. + /// + /// @param engine_kind Engine kind. + /// @param mode Floating-point math mode. + graph(engine::kind engine_kind, fpmath_mode mode) { + dnnl_graph_graph_t g = nullptr; + error::wrap_c_api( + dnnl_graph_graph_create_with_fpmath_mode( + &g, convert_to_c(engine_kind), convert_to_c(mode)), + "could not create graph with engine kind and math mode"); + reset(g); + } + + /// Set the floating point math mode for a graph. Users can enforce the + /// graph to comply with the mode by specifying a boolean flag with the + /// setter function. + /// + /// @param mode The floating-point math mode. + /// @param apply_to_int The flag that controls whether to use + /// floating-point arithmetic for integral operations. + void set_fpmath_mode(fpmath_mode mode, bool apply_to_int = false) { + error::wrap_c_api(dnnl_graph_graph_set_fpmath_mode( + get(), convert_to_c(mode), apply_to_int), + "could not set fpmath mode graph attribute"); + } + + /// Get the floating point math mode and the boolean flag that specifies + /// whether the graph will be enforced to comply the mode. + /// + /// @param mode The floating-point math mode. + /// @param apply_to_int The flag that controls whether to use + /// floating-point arithmetic for integral operations. + void get_fpmath_mode(fpmath_mode &mode, bool &apply_to_int) const { + dnnl_fpmath_mode_t c_mode; + int c_apply_to_int; + + error::wrap_c_api(dnnl_graph_graph_get_fpmath_mode( + get(), &c_mode, &c_apply_to_int), + "could not get fpmath mode graph attribute"); + + mode = fpmath_mode(c_mode); + apply_to_int = static_cast(c_apply_to_int); + } + + /// Adds an op into the graph to construct a computational DAG. The API will + /// return failure if the operator has already been added to the graph or + /// the operation cannot pass the schema check in the library (eg. input and + /// output numbers and data types, the attributes of the operation, etc.). + /// + /// @param op An operation to be added. + /// @param allow_exception A flag indicating whether the method is allowed + /// to throw an exception if it fails to add the op to the graph. + /// @returns #status::success or a status describing the error otherwise. + status add_op(const op &op, bool allow_exception = true) { + dnnl_status_t ret = dnnl_graph_add_op(get(), op.get()); + + if (allow_exception) { + error::wrap_c_api(ret, "could not add op to the graph"); + } + + return static_cast(ret); + } + + /// Finalizes a graph. It means users have finished adding operations into + /// the graph and the graph is ready for partitioning. Adding a new + /// operation into a finalized graph will return failures. Similarly, + /// partitioning on a un-finalized graph will also return failures. + void finalize() { + error::wrap_c_api(dnnl_graph_graph_finalize(get()), + "could not finalize the graph"); + } + + /// Checks if a graph is finalized. + /// + /// @return True if the graph is finalized or false if the graph is not + /// finalized. + bool is_finalized() const { + uint8_t ret = 0; + error::wrap_c_api(dnnl_graph_graph_is_finalized(get(), &ret), + "could not get the finalization status of the graph"); + + return ret != 0; + } + + /// Gets filtered partitions from a graph. Partitions will be claimed + /// internally according to the capability of the library, the engine kind + /// of the graph, and the policy. + /// + /// @param policy Partition policy, defaults to policy + /// #dnnl::graph::partition::policy::fusion. + /// @return A vector storing the partitions. + std::vector get_partitions( + partition::policy policy = partition::policy::fusion) { + if (!is_finalized()) { + error::wrap_c_api( + dnnl_invalid_graph, "the graph is not finalized yet"); + } + + error::wrap_c_api( + dnnl_graph_graph_filter(get(), + static_cast(policy)), + "could not filter the graph"); + + size_t num = 0; + error::wrap_c_api(dnnl_graph_graph_get_partition_num(get(), &num), + "could not get number of partitions from the graph"); + + // return early if there is no partitions in the graph. + if (num == 0) return {}; + + std::vector out_list; + out_list.reserve(num); + + std::vector partitions(num); + error::wrap_c_api( + dnnl_graph_graph_get_partitions(get(), num, partitions.data()), + "could not get partitions from the graph"); + + for (auto p : partitions) { + out_list.emplace_back(p); + } + + return out_list; + } + +private: + static dnnl_fpmath_mode_t convert_to_c(fpmath_mode mode) { + return static_cast(mode); + } + + static dnnl_engine_kind_t convert_to_c(engine::kind akind) { + return static_cast(akind); + } +}; + +/// @} dnnl_graph_api_graph + +/// @addtogroup dnnl_graph_api_compiled_partition_cache Compiled Partition Cache +/// +/// A set of functions that provide compiled partition cache control. +/// +/// @{ + +/// Returns the number of compiled partition that can be held in the compiled +/// partition cache at the same time. +inline int get_compiled_partition_cache_capacity() { + int result = 0; + error::wrap_c_api(dnnl_graph_get_compiled_partition_cache_capacity(&result), + "could not get compiled partition cache capacity"); + return result; +} + +/// @copydoc dnnl_graph_set_compiled_partition_cache_capacity(int capacity) +inline void set_compiled_partition_cache_capacity(int capacity) { + error::wrap_c_api( + dnnl_graph_set_compiled_partition_cache_capacity(capacity), + "could not set compiled partition cache capacity"); +} + +/// @} dnnl_graph_api_compiled_partition_cache + +/// @addtogroup dnnl_graph_api_constant_tensor_cache Constant Tensor Cache +/// +/// A set of functions that provide constant tensor cache control +/// +/// @{ + +/// Control the enabling or disabling of constant tensor cache. This API must be +/// called once before compilation stage. By default, constant tensor cache is +/// disabled in the library. +/// @note This API is deprecated and will be removed in future release, please +/// use the set_constant_tensor_cache_capacity API to disable +/// constant tensor cache by setting it's capacity to zero. +/// +/// @param flag Set to positive value to enable the cache and set to 0 to +/// disable the cache. Negative values are invalid. +inline void set_constant_tensor_cache(int flag) { + error::wrap_c_api(dnnl_graph_set_constant_tensor_cache(flag), + "fail to set constant tensor cache"); +} + +/// Return the enabling status of constant tensor cache. +/// @note This API is deprecated and will be removed in future release, please +/// use the get_constant_tensor_cache_capacity API to check the +/// enabling status by checking it's capacity. +inline int get_constant_tensor_cache() { + int result = 0; + error::wrap_c_api(dnnl_graph_get_constant_tensor_cache(&result), + "fail to get constant tensor cache"); + return result; +} + +/// Control the capacity for the constant tensor cache that used for specific +/// engine kind. This API is thread safe and can be called multiple times at +/// runtime. The capacity is set to zero by default which means the cache is +/// disabled. When calling this API, the corresponding cache will be flushed. +/// Setting capacity to 0 means to clear all cached tensors and disable cache. +/// Once the capacity limit is reached, no new tensors will be cached. If there +/// are multiple devices for an engine kind, the capacity set here is for each +/// device. +/// +/// @param kind The engine kind that the constant tensor cache used for. +/// @param size The constant tensor cache capacity size to set. +inline void set_constant_tensor_cache_capacity(engine::kind kind, size_t size) { + error::wrap_c_api(dnnl_graph_set_constant_tensor_cache_capacity( + static_cast(kind), size), + "fail to set constant tensor cache capacity"); +} + +/// Return the current capacity of constant tensor cache. +/// +/// @param kind The engine kind that the constant tensor cache used for. +inline size_t get_constant_tensor_cache_capacity(engine::kind kind) { + size_t size = 0; + error::wrap_c_api(dnnl_graph_get_constant_tensor_cache_capacity( + static_cast(kind), &size), + "fail to get constant tensor cache capacity"); + return size; +} + +/// @} dnnl_graph_api_constant_tensor_cache + +/// @addtogroup dnnl_graph_api_dump_mode Dump Mode +/// +/// Control graph dumping behavior +/// +/// @{ + +/// @enum graph_dump_mode +/// Dump mode bitmask for graph debugging utilities. +enum class graph_dump_mode : unsigned { + /// Disable all graph dumps. + none = dnnl_graph_dump_mode_none, + /// Dump subgraphs extracted during partitioning. + subgraph = dnnl_graph_dump_mode_subgraph, + /// Dump the full graph prior to partitioning. + graph = dnnl_graph_dump_mode_graph, +}; + +DNNL_DEFINE_BITMASK_OPS(graph_dump_mode) + +/// Configures graph dump modes at runtime. +/// +/// @note +/// Enabling graph dump affects performance. +/// This setting overrides the ONEDNN_GRAPH_DUMP environment variable. +/// +/// @param modes Bitmask composed of values from #dnnl::graph::graph_dump_mode. +/// Accepted values: +/// - #dnnl::graph::graph_dump_mode::graph: dump the full graph prior to +/// partitioning. +/// - #dnnl::graph::graph_dump_mode::subgraph: dump each partitioned subgraph. +/// - #dnnl::graph::graph_dump_mode::none: disable all graph dumping. +/// +/// Bitmask combinations using bitwise operators are supported. For +/// instance, `graph | subgraph` enables both modes, `none | graph` +/// behaves like `graph`, and `none & graph` behaves like `none`. +/// @returns #dnnl::status::invalid_arguments if the +/// @p modes value contains unsupported bits or graph dump is disabled, +/// and #dnnl::status::success on success. +inline status set_dump_mode(graph_dump_mode modes) { + return static_cast(dnnl_graph_set_dump_mode( + static_cast(static_cast(modes)))); +} + +/// @} dnnl_graph_api_dump_mode + +} // namespace graph + +/// @} dnnl_graph_api + +} // namespace dnnl + +/// @cond DO_NOT_DOCUMENT_THIS + +/// oneAPI namespace +// Contains the oneapi::dnnl namespace as an alias to the ::dnnl namespace. +namespace oneapi { +// Note: without this guard, doxygen warns of potentially recursive namespace +#ifndef DOXYGEN_SHOULD_SKIP_THIS +/// oneDNN alias namespace +namespace dnnl = ::dnnl; +#endif +} // namespace oneapi + +/// @endcond + +/// @} dnnl_api + +// NOLINTEND(readability-identifier-naming) +#endif /* ONEAPI_DNNL_DNNL_GRAPH_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_ocl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_ocl.h new file mode 100644 index 0000000000000000000000000000000000000000..6a566fb44c7c54e3872dd679a6f9e7fd6718156c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_ocl.h @@ -0,0 +1,149 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2024 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_GRAPH_OCL_H +#define ONEAPI_DNNL_DNNL_GRAPH_OCL_H + +#include "oneapi/dnnl/dnnl_graph.h" + +/// @cond DO_NOT_DOCUMENT_THIS +#include +/// @endcond + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_graph_api +/// @{ + +/// @addtogroup dnnl_graph_api_interop +/// @{ + +/// @addtogroup dnnl_graph_api_ocl_interop +/// @{ + +/// Allocation call-back function interface for OpenCL. OpenCL allocator should +/// be used for OpenCL GPU runtime. The call-back should return a USM device +/// memory pointer. +/// +/// @param size Memory size in bytes for requested allocation +/// @param alignment The minimum alignment in bytes for the requested allocation +/// @param device A valid OpenCL device used to allocate +/// @param context A valid OpenCL context used to allocate +/// @returns The memory address of the requested USM allocation. +typedef void *(*dnnl_graph_ocl_allocate_f)( + size_t size, size_t alignment, cl_device_id device, cl_context context); + +/// Deallocation call-back function interface for OpenCL. OpenCL allocator +/// should be used for OpenCL runtime. The call-back should deallocate a USM +/// device memory returned by #dnnl_graph_ocl_allocate_f. The event should be +/// completed before deallocate the USM. +/// +/// @param buf The USM allocation to be released +/// @param device A valid OpenCL device the USM associated with +/// @param context A valid OpenCL context used to free the USM allocation +/// @param event A event which the USM deallocation depends on +typedef void (*dnnl_graph_ocl_deallocate_f)( + void *buf, cl_device_id device, cl_context context, cl_event event); + +/// Creates an allocator with the given allocation and deallocation call-back +/// function pointers. +/// +/// @param allocator Output allocator +/// @param ocl_malloc A pointer to OpenCL malloc function +/// @param ocl_free A pointer to OpenCL free function +/// @returns #dnnl_success on success and a status describing the +/// error otherwise. +dnnl_status_t DNNL_API dnnl_graph_ocl_interop_allocator_create( + dnnl_graph_allocator_t *allocator, dnnl_graph_ocl_allocate_f ocl_malloc, + dnnl_graph_ocl_deallocate_f ocl_free); + +/// This API is a supplement for existing oneDNN engine API: +/// dnnl_status_t DNNL_API dnnl_ocl_interop_engine_create( +/// dnnl_engine_t *engine, cl_device_id device, cl_context context); +/// +/// @param engine Output engine. +/// @param device Underlying OpenCL device to use for the engine. +/// @param context Underlying OpenCL context to use for the engine. +/// @param alloc Underlying allocator to use for the engine. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_graph_ocl_interop_make_engine_with_allocator( + dnnl_engine_t *engine, cl_device_id device, cl_context context, + const_dnnl_graph_allocator_t alloc); + +/// This API is a supplement for existing oneDNN engine API: +/// dnnl_status_t DNNL_API dnnl_ocl_interop_engine_create_from_cache_blob( +/// dnnl_engine_t *engine, cl_device_id device, cl_context context, +/// size_t size, const uint8_t *cache_blob); +/// +/// @param engine Output engine. +/// @param device The OpenCL device that this engine will encapsulate. +/// @param context The OpenCL context (containing the device) that this +/// engine will use for all operations. +/// @param alloc Underlying allocator to use for the engine. +/// @param size Size of the cache blob in bytes. +/// @param cache_blob Cache blob of size @p size. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API +dnnl_graph_ocl_interop_make_engine_from_cache_blob_with_allocator( + dnnl_engine_t *engine, cl_device_id device, cl_context context, + const_dnnl_graph_allocator_t alloc, size_t size, + const uint8_t *cache_blob); + +/// Execute a compiled partition with OpenCL runtime. +/// +/// @param compiled_partition The handle of target compiled_partition. +/// @param stream The stream used for execution +/// @param num_inputs The number of input tensors +/// @param inputs A list of input tensors +/// @param num_outputs The number of output tensors +/// @param outputs A non-empty list of output tensors +/// @param deps Optional handle of list with `cl_event` dependencies. +/// @param ndeps Number of dependencies. +/// @param return_event The handle of cl_event. +/// @returns #dnnl_success on success and a status describing the +/// error otherwise. +dnnl_status_t DNNL_API dnnl_graph_ocl_interop_compiled_partition_execute( + const_dnnl_graph_compiled_partition_t compiled_partition, + dnnl_stream_t stream, size_t num_inputs, + const_dnnl_graph_tensor_t *inputs, size_t num_outputs, + const_dnnl_graph_tensor_t *outputs, const cl_event *deps, int ndeps, + cl_event *return_event); + +/// @} dnnl_graph_api_ocl_interop + +/// @} dnnl_graph_api_interop + +/// @} dnnl_graph_api + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_ocl.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_ocl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..14d1372e6a940a3bac2dd1a774a95396eb752d8c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_ocl.hpp @@ -0,0 +1,161 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2024 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// Graph OpenCL interop API + +#ifndef ONEAPI_DNNL_DNNL_GRAPH_OCL_HPP +#define ONEAPI_DNNL_DNNL_GRAPH_OCL_HPP + +/// @cond DO_NOT_DOCUMENT_THIS +#include + +#include + +#include "oneapi/dnnl/dnnl_graph.hpp" +#include "oneapi/dnnl/dnnl_graph_ocl.h" +#include "oneapi/dnnl/dnnl_ocl.hpp" +/// @endcond + +/// @addtogroup dnnl_api +/// @{ + +namespace dnnl { + +/// @addtogroup dnnl_graph_api +/// @{ + +namespace graph { + +/// @addtogroup dnnl_graph_api_interop Runtime interoperability API +/// API extensions to interact with the underlying run-time. +/// @{ + +/// @addtogroup dnnl_graph_api_ocl_interop OpenCL interoperability API +/// API extensions to interact with the underlying OpenCL run-time. +/// @{ + +/// OpenCL interoperability namespace +namespace ocl_interop { + +/// Constructs an allocator from OpenCL malloc and free function pointer. OpenCL +/// allocator should be used for OpenCL GPU runtime. Currently, only device USM +/// allocator is supported. +/// +/// @param ocl_malloc The pointer to OpenCL malloc function +/// @param ocl_free The pointer to OpenCL free function +/// @returns Created allocator +inline allocator make_allocator(dnnl_graph_ocl_allocate_f ocl_malloc, + dnnl_graph_ocl_deallocate_f ocl_free) { + dnnl_graph_allocator_t c_allocator = nullptr; + error::wrap_c_api(dnnl_graph_ocl_interop_allocator_create( + &c_allocator, ocl_malloc, ocl_free), + "could not create allocator for opencl device"); + return allocator(c_allocator); +} + +/// Constructs an engine from an OpenCL device, an OpenCL context, and an +/// allocator. +/// +/// @param device A valid OpenCL device to construct the engine +/// @param context A valid OpenCL context to construct the engine +/// @param alloc An allocator to associate with the engine +/// @returns Created engine +inline engine make_engine_with_allocator( + cl_device_id device, cl_context context, const allocator &alloc) { + dnnl_engine_t c_engine; + error::wrap_c_api(dnnl_graph_ocl_interop_make_engine_with_allocator( + &c_engine, device, context, alloc.get()), + "could not make an engine with allocator"); + return engine(c_engine); +} + +/// Constructs an engine from an OpenCL device, an OpenCL context, an +/// allocator, and a serialized engine cache blob. +/// +/// @param device A valid OpenCL device to construct the engine +/// @param context A valid OpenCL context to construct the engine +/// @param alloc An allocator to associate with the engine +/// @param cache_blob Cache blob serialized beforehand +/// @returns Created engine +inline engine make_engine_with_allocator(cl_device_id device, + cl_context context, const allocator &alloc, + const std::vector &cache_blob) { + dnnl_engine_t c_engine; + error::wrap_c_api( + dnnl_graph_ocl_interop_make_engine_from_cache_blob_with_allocator( + &c_engine, device, context, alloc.get(), cache_blob.size(), + cache_blob.data()), + "could not make an engine with allocator from cache blob"); + return engine(c_engine); +} + +/// Executes a compiled partition in a specified stream and returns a OpenCL +/// event. +/// +/// @param c_partition Compiled partition to execute. +/// @param astream Stream object to run over +/// @param inputs Arguments map. +/// @param outputs Arguments map. +/// @param deps Optional vector with `cl_event` dependencies. +/// @returns Output event. +inline cl_event execute(compiled_partition &c_partition, stream &astream, + const std::vector &inputs, std::vector &outputs, + const std::vector &deps = {}) { + std::vector c_inputs; + c_inputs.reserve(inputs.size()); + for (auto &in : inputs) { + c_inputs.push_back(in.get()); + } + std::vector c_outputs; + c_outputs.reserve(outputs.size()); + for (auto &out : outputs) { + c_outputs.push_back(out.get()); + } + + const cl_event *c_deps = deps.empty() ? nullptr : deps.data(); + + cl_event ocl_event; + error::wrap_c_api( + dnnl_graph_ocl_interop_compiled_partition_execute(c_partition.get(), + astream.get(), c_inputs.size(), c_inputs.data(), + c_outputs.size(), c_outputs.data(), c_deps, + (int)deps.size(), &ocl_event), + "could not execute the compiled_partition on a specified opencl " + "stream"); + return ocl_event; +} + +} // namespace ocl_interop + +/// @} dnnl_graph_api_ocl_interop + +/// @} dnnl_graph_api_interop + +} // namespace graph + +/// @} dnnl_graph_api + +} // namespace dnnl + +/// @} dnnl_api + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_sycl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_sycl.h new file mode 100644 index 0000000000000000000000000000000000000000..49633a5b26e352e5cc0cbb9c149c0432f8eb9f88 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_sycl.h @@ -0,0 +1,104 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_GRAPH_SYCL_H +#define ONEAPI_DNNL_DNNL_GRAPH_SYCL_H + +#include "oneapi/dnnl/dnnl_graph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_graph_api +/// @{ + +/// @addtogroup dnnl_graph_api_interop +/// @{ + +/// @addtogroup dnnl_graph_api_sycl_interop +/// @{ + +/// Allocation call-back function interface for SYCL. SYCL allocator should be +/// used for SYCL runtime and host allocator should be used for non-SYCL. The +/// call-back should return a USM device memory pointer. +typedef void *(*dnnl_graph_sycl_allocate_f)( + size_t size, size_t alignment, const void *dev, const void *context); + +/// Deallocation call-back function interface for SYCL. SYCL allocator should be +/// used for SYCL runtime and host allocator should be used for non-SYCL. The +/// call-back should deallocate a USM device memory returned by +/// #dnnl_graph_sycl_allocate_f. +typedef void (*dnnl_graph_sycl_deallocate_f)( + void *buf, const void *dev, const void *context, void *event); + +/// Creates an allocator with the given allocation and deallocation call-back +/// function pointers. +/// +/// @param allocator Output allocator +/// @param sycl_malloc A pointer to SYCL malloc function +/// @param sycl_free A pointer to SYCL free function +/// @returns #dnnl_success on success and a status describing the +/// error otherwise. +dnnl_status_t DNNL_API dnnl_graph_sycl_interop_allocator_create( + dnnl_graph_allocator_t *allocator, + dnnl_graph_sycl_allocate_f sycl_malloc, + dnnl_graph_sycl_deallocate_f sycl_free); + +/// This API is a supplement for existing onednn engine API. +dnnl_status_t DNNL_API dnnl_graph_sycl_interop_make_engine_with_allocator( + dnnl_engine_t *engine, const void *device, const void *context, + const_dnnl_graph_allocator_t alloc); + +/// Execute a compiled partition with sycl runtime. +/// +/// @param compiled_partition The handle of target compiled_partition. +/// @param stream The stream used for execution +/// @param num_inputs The number of input tensors +/// @param inputs A list of input tensors +/// @param num_outputs The number of output tensors +/// @param outputs A non-empty list of output tensors +/// @param deps Optional handle of list with `sycl::event` dependencies. +/// @param sycl_event The handle of sycl event. +/// @returns #dnnl_success on success and a status describing the +/// error otherwise. +dnnl_status_t DNNL_API dnnl_graph_sycl_interop_compiled_partition_execute( + const_dnnl_graph_compiled_partition_t compiled_partition, + dnnl_stream_t stream, size_t num_inputs, + const_dnnl_graph_tensor_t *inputs, size_t num_outputs, + const_dnnl_graph_tensor_t *outputs, const void *deps, void *sycl_event); + +/// @} dnnl_graph_api_sycl_interop + +/// @} dnnl_graph_api_interop + +/// @} dnnl_graph_api + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_sycl.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_sycl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cbee478ebabc206c001368db117f48d871518e79 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_sycl.hpp @@ -0,0 +1,136 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// Graph SYCL interop API + +#ifndef ONEAPI_DNNL_DNNL_GRAPH_SYCL_HPP +#define ONEAPI_DNNL_DNNL_GRAPH_SYCL_HPP + +/// @cond DO_NOT_DOCUMENT_THIS +#include + +#if __has_include() +#include +#else +#error "Unsupported compiler" +#endif + +#include "oneapi/dnnl/dnnl_graph.hpp" +#include "oneapi/dnnl/dnnl_graph_sycl.h" +/// @endcond + +/// @addtogroup dnnl_api +/// @{ + +namespace dnnl { + +/// @addtogroup dnnl_graph_api +/// @{ + +namespace graph { + +/// @addtogroup dnnl_graph_api_interop Runtime interoperability API +/// API extensions to interact with the underlying run-time. +/// @{ + +/// @addtogroup dnnl_graph_api_sycl_interop SYCL interoperability API +/// API extensions to interact with the underlying SYCL run-time. +/// @{ + +/// SYCL interoperability namespace +namespace sycl_interop { + +/// Constructs an allocator from SYCL malloc and free function pointer. SYCL +/// allocator should be used for SYCL runtime and host allocator should be used +/// for non-SYCL. Currently, only device USM allocator is supported. +/// +/// @param sycl_malloc The pointer to SYCL malloc function +/// @param sycl_free The pointer to SYCL free function +/// @returns Created allocator +inline allocator make_allocator(dnnl_graph_sycl_allocate_f sycl_malloc, + dnnl_graph_sycl_deallocate_f sycl_free) { + dnnl_graph_allocator_t c_allocator = nullptr; + error::wrap_c_api(dnnl_graph_sycl_interop_allocator_create( + &c_allocator, sycl_malloc, sycl_free), + "could not create allocator for sycl device"); + return allocator(c_allocator); +} + +inline engine make_engine_with_allocator(const sycl::device &adevice, + const sycl::context &acontext, const allocator &alloc) { + dnnl_engine_t c_engine; + error::wrap_c_api( + dnnl_graph_sycl_interop_make_engine_with_allocator(&c_engine, + static_cast(&adevice), + static_cast(&acontext), alloc.get()), + "could not make an engine with allocator"); + return engine(c_engine); +} + +/// Executes a compiled partition in a specified stream and returns a SYCL +/// event. +/// +/// @param c_partition Compiled partition to execute. +/// @param astream Stream object to run over +/// @param inputs Arguments map. +/// @param outputs Arguments map. +/// @param deps Optional vector with `sycl::event` dependencies. +/// @returns Output event. +inline sycl::event execute(compiled_partition &c_partition, stream &astream, + const std::vector &inputs, std::vector &outputs, + const std::vector &deps = {}) { + std::vector c_inputs; + c_inputs.reserve(inputs.size()); + for (auto &in : inputs) { + c_inputs.push_back(in.get()); + } + std::vector c_outputs; + c_outputs.reserve(outputs.size()); + for (auto &out : outputs) { + c_outputs.push_back(out.get()); + } + + sycl::event sycl_event; + error::wrap_c_api(dnnl_graph_sycl_interop_compiled_partition_execute( + c_partition.get(), astream.get(), c_inputs.size(), + c_inputs.data(), c_outputs.size(), + c_outputs.data(), &deps, &sycl_event), + "could not execute the compiled_partition on a specified sycl " + "stream"); + return sycl_event; +} + +} // namespace sycl_interop + +/// @} dnnl_graph_api_sycl_interop + +/// @} dnnl_graph_api_interop + +} // namespace graph + +/// @} dnnl_graph_api + +} // namespace dnnl + +/// @} dnnl_api + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_types.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_types.h new file mode 100644 index 0000000000000000000000000000000000000000..a5dbd7112e4bdb89cfdbf3d080b11adb4c354d2c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_types.h @@ -0,0 +1,503 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* + * Copyright 2020 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +/// @file +/// C API definitions + +#ifndef ONEAPI_DNNL_DNNL_GRAPH_TYPES_H +#define ONEAPI_DNNL_DNNL_GRAPH_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/// @cond DO_NOT_DOCUMENT_THIS +#include +#include + +#include "oneapi/dnnl/dnnl_common_types.h" +/// @endcond + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_graph_api +/// @{ + +/// @addtogroup dnnl_graph_api_logical_tensor +/// @{ + +/// A wildcard value for number of dimensions which is unknown at a tensor or +/// operation creation time. +#define DNNL_GRAPH_UNKNOWN_NDIMS -1 + +/// A wildcard value for dimensions that are unknown at a tensor or operation +/// creation time. +#define DNNL_GRAPH_UNKNOWN_DIM INT64_MIN + +/// Layout type specification +typedef enum { + /// Undefined layout type + dnnl_graph_layout_type_undef = 0, + /// Any means to let the library to decide the layout for a tensor during + /// partition compilation. + dnnl_graph_layout_type_any = 1, + /// Strided means that the layout of a tensor is determined by the strides + /// field in the logical tensor. + dnnl_graph_layout_type_strided = 2, + /// Opaque means that the layout of a tensor is the library specific. + /// Usually, an opaque layout is generated by a partition which is compiled + /// with layout type any. + dnnl_graph_layout_type_opaque = 3, +} dnnl_graph_layout_type_t; + +/// Logical tensor property +typedef enum { + /// Undefined tensor property + dnnl_graph_tensor_property_undef = 0, + /// Variable means the tensor may be changed during computation or between + /// different iterations. + dnnl_graph_tensor_property_variable = 1, + /// Constant means the tensor will keep unchanged during computation and + /// between different iterations. It's useful for the library to apply + /// optimizations for constant tensors or cache constant tensors inside the + /// library. For example, constant weight tensors in inference scenarios. + dnnl_graph_tensor_property_constant = 2, + /// Host scalar means the tensor will be a 0-D scalar tensor on host. + /// It should be used with a CPU engine when creating the tensor. + dnnl_graph_tensor_property_host_scalar = 3, +} dnnl_graph_tensor_property_t; + +/// Logical tensor. It is based on an ID, a number of dimensions, dimensions +/// themselves, element data type, tensor property and tensor memory layout. +typedef struct { + /// Unique id of each logical tensor. The library uses logical tensor IDs to + /// build up the connections between operations if the output of one + /// operation has the same ID as the input of another operation. + size_t id; + + /// Number of dimensions. -1 means unknown (DNNL_GRAPH_UNKNOWN_NDIMS). 0 is + /// used to define scalar tensor. + int ndims; + + /// Size of each dimension. #DNNL_GRAPH_UNKNOWN_DIM means the size of that + /// dimension is unknown. 0 is used to define zero-dimension tensor. The + /// library supports to deduce output shapes according to input shapes + /// during compilation. Unlike memory descriptor in oneDNN primitive API, + /// the order of dimensions is not defined in logical tensor. It is defined + /// by the operations which respect the order through the attributes + /// #dnnl_graph_op_attr_data_format or #dnnl_graph_op_attr_weights_format. + /// For example, for a Convolution with `data_format=NXC`, it means the + /// first element of dims of activation tensor is mini-batch size, the last + /// effective element of dims is channel size, and other elements between + /// them are spatial dimensions. + dnnl_dims_t dims; + + /// Data type of the tensor elements. + dnnl_data_type_t data_type; + + /// Property type of the tensor. + dnnl_graph_tensor_property_t property; + + /// Layout type of the tensor. + dnnl_graph_layout_type_t layout_type; + union { + /// The field is valid when `layout_type` is + /// #dnnl_graph_layout_type_strided. #DNNL_GRAPH_UNKNOWN_DIM means the + /// stride of the dimension is unknown. The library currently doesn't + /// support other negative stride values. + dnnl_dims_t strides; + + /// The field is valid when `layout_type` is + /// #dnnl_graph_layout_type_opaque. An opaque layout ID is usually + /// generated by a partition which is compiled with layout type any. + size_t layout_id; + } layout; +} dnnl_graph_logical_tensor_t; + +/// @} dnnl_graph_api_logical_tensor + +/// @addtogroup dnnl_graph_api_partition +/// @{ + +/// Policy specifications for partitioning +typedef enum { + /// Fusion policy returns partitions with typical post-op fusions, eg. + /// Convolution + ReLU or other element-wise operations or a chian of + /// post-ops. + dnnl_graph_partition_policy_fusion = 1, + /// Debug policy doesn't not apply any fusions. It returns partitions with + /// single operation in each partition. The policy is useful when users + /// notice any bug or correctness issue in fusion policy. + dnnl_graph_partition_policy_debug = 2, +} dnnl_graph_partition_policy_t; + +/// An opaque structure to describe a partition. +struct dnnl_graph_partition; + +/// A partition handle. +typedef struct dnnl_graph_partition *dnnl_graph_partition_t; + +/// A constant partition handle. +typedef const struct dnnl_graph_partition *const_dnnl_graph_partition_t; + +/// @} dnnl_graph_api_partition + +/// @addtogroup dnnl_graph_api_graph +/// @{ + +/// An opaque structure to describe a graph. +struct dnnl_graph_graph; + +/// A graph handle. +typedef struct dnnl_graph_graph *dnnl_graph_graph_t; + +/// A constant graph handle. +typedef const struct dnnl_graph_graph *const_dnnl_graph_graph_t; + +/// @} dnnl_graph_api_graph + +/// @addtogroup dnnl_graph_api_dump_mode +/// @{ + +/// Dump mode bitmask for graph debugging utilities. +typedef enum { + /// Disable all graph dumps. + dnnl_graph_dump_mode_none = 0x0U, + /// Dump subgraphs extracted during partitioning. + dnnl_graph_dump_mode_subgraph = 0x1U, + /// Dump the full graph prior to partitioning. + dnnl_graph_dump_mode_graph = 0x2U, +} dnnl_graph_dump_mode_t; + +/// @} dnnl_graph_api_dump_mode + +/// @addtogroup dnnl_graph_api_op +/// @{ + +/// Kinds of operations +typedef enum { + dnnl_graph_op_abs, + dnnl_graph_op_abs_backward, + dnnl_graph_op_add, + dnnl_graph_op_avg_pool, + dnnl_graph_op_avg_pool_backward, + dnnl_graph_op_batch_norm_backward, + dnnl_graph_op_batch_norm_forward_training, + dnnl_graph_op_batch_norm_inference, + dnnl_graph_op_bias_add, + dnnl_graph_op_bias_add_backward, + dnnl_graph_op_clamp, + dnnl_graph_op_clamp_backward, + dnnl_graph_op_concat, + dnnl_graph_op_convolution, + dnnl_graph_op_convolution_backward_data, + dnnl_graph_op_convolution_backward_weights, + dnnl_graph_op_conv_transpose, + dnnl_graph_op_conv_transpose_backward_data, + dnnl_graph_op_conv_transpose_backward_weights, + dnnl_graph_op_dequantize, + dnnl_graph_op_divide, + dnnl_graph_op_dynamic_dequantize, + dnnl_graph_op_dynamic_quantize, + dnnl_graph_op_elu, + dnnl_graph_op_elu_backward, + dnnl_graph_op_end, + dnnl_graph_op_exp, + dnnl_graph_op_gelu, + dnnl_graph_op_gelu_backward, + dnnl_graph_op_hard_swish, + dnnl_graph_op_hard_swish_backward, + dnnl_graph_op_interpolate, + dnnl_graph_op_interpolate_backward, + dnnl_graph_op_layer_norm, + dnnl_graph_op_layer_norm_backward, + dnnl_graph_op_leaky_relu, + dnnl_graph_op_log, + dnnl_graph_op_log_softmax, + dnnl_graph_op_log_softmax_backward, + dnnl_graph_op_matmul, + dnnl_graph_op_maximum, + dnnl_graph_op_max_pool, + dnnl_graph_op_max_pool_backward, + dnnl_graph_op_minimum, + dnnl_graph_op_mish, + dnnl_graph_op_mish_backward, + dnnl_graph_op_multiply, + dnnl_graph_op_prelu, + dnnl_graph_op_prelu_backward, + dnnl_graph_op_quantize, + dnnl_graph_op_reciprocal, + dnnl_graph_op_reduce_l1, + dnnl_graph_op_reduce_l2, + dnnl_graph_op_reduce_max, + dnnl_graph_op_reduce_mean, + dnnl_graph_op_reduce_min, + dnnl_graph_op_reduce_prod, + dnnl_graph_op_reduce_sum, + dnnl_graph_op_relu, + dnnl_graph_op_relu_backward, + dnnl_graph_op_reorder, + dnnl_graph_op_round, + dnnl_graph_op_sigmoid, + dnnl_graph_op_sigmoid_backward, + dnnl_graph_op_softmax, + dnnl_graph_op_softmax_backward, + dnnl_graph_op_softplus, + dnnl_graph_op_softplus_backward, + dnnl_graph_op_sqrt, + dnnl_graph_op_sqrt_backward, + dnnl_graph_op_square, + dnnl_graph_op_squared_difference, + dnnl_graph_op_static_reshape, + dnnl_graph_op_static_transpose, + dnnl_graph_op_subtract, + dnnl_graph_op_tanh, + dnnl_graph_op_tanh_backward, + dnnl_graph_op_type_cast, + dnnl_graph_op_wildcard, + dnnl_graph_op_hard_sigmoid, + dnnl_graph_op_hard_sigmoid_backward, + dnnl_graph_op_select, + dnnl_graph_op_pow, + dnnl_graph_op_group_norm, + dnnl_graph_op_gen_index, + dnnl_graph_op_greater_equal, + dnnl_graph_op_rms_norm, + dnnl_graph_op_last_symbol, +} dnnl_graph_op_kind_t; + +/// Attributes of operations +typedef enum { + /// Undefined op attribute. + dnnl_graph_op_attr_undef = 0, + + // float32 attributes. The value of these attributes can be any single + // float32 number. + + /// Specifies an alpha attribute to an op. + dnnl_graph_op_attr_alpha = 0x1, + /// Specifies an beta attribute to an op. + dnnl_graph_op_attr_beta, + /// Specifies an epsilon attribute to an op. + dnnl_graph_op_attr_epsilon, + /// Specifies a max attribute to an op. + dnnl_graph_op_attr_max, + ///Specifies a min attribute to an op. + dnnl_graph_op_attr_min, + /// Specifies a momentum attribute to an op. + dnnl_graph_op_attr_momentum, + + // float32 vector attributes. The value of these attributes can be a vector + // of float32 numbers. + + /// Specifies a scales attribute to an op. + dnnl_graph_op_attr_scales = 0x20, + + // int64_t attributes. The value of these attributes can be any single int64 + // number. + + /// Specifies an axis attribute to an op. + dnnl_graph_op_attr_axis = 0x30, + /// Specifies a begin_norm_axis attribute to an op. + dnnl_graph_op_attr_begin_norm_axis, + /// Specifies a groups attribute to an op. + dnnl_graph_op_attr_groups, + + // int64_t vector attributes. The value of these attributes can be a vector + // of int64 numbers. + + /// Specifies an axes attribute to an op. + dnnl_graph_op_attr_axes = 0x40, + /// Specifies a dilations attribute to an op. + dnnl_graph_op_attr_dilations, + /// Specifies an dst_shape attribute to an op. + dnnl_graph_op_attr_dst_shape, + /// Specifies a kernel attribute to an op. + dnnl_graph_op_attr_kernel, + /// Specifies an order attribute to an op. + dnnl_graph_op_attr_order, + /// Specifies an output_padding attribute to an op. + dnnl_graph_op_attr_output_padding, + /// Specifies a pads_begin attribute to an op. + dnnl_graph_op_attr_pads_begin, + /// Specifies a pads_end attribute to an op. + dnnl_graph_op_attr_pads_end, + /// Specifies a shape attribute to an op. + dnnl_graph_op_attr_shape, + /// Specifies a sizes attribute to an op. + dnnl_graph_op_attr_sizes, + /// Specifies a input_shape attribute to an op. + dnnl_graph_op_attr_src_shape, + /// Specifies a strides attribute to an op. + dnnl_graph_op_attr_strides, + /// Specifies a weight_shape attribute to an op. + dnnl_graph_op_attr_weights_shape, + /// Specifies a zps attribute to an op. + dnnl_graph_op_attr_zps, + /// Specifies a group shape attribute to an op. + dnnl_graph_op_attr_group_shape, + + // bool attributes. The value of these attributes can be any single bool + // value. + + /// Specifies an exclude_pad attribute to an op. + dnnl_graph_op_attr_exclude_pad = 0x60, + /// Specifies a keep_dims attribute to an op. + dnnl_graph_op_attr_keep_dims, + /// Specifies a keep_stats attribute to an op. + dnnl_graph_op_attr_keep_stats, + /// Specifies a per_channel_broadcast attribute to an op. + dnnl_graph_op_attr_per_channel_broadcast, + /// Specifies a special_zero attribute to an op. + dnnl_graph_op_attr_special_zero, + /// Specifies a transpose_a attribute to an op. + dnnl_graph_op_attr_transpose_a, + /// Specifies a transpose_b attribute to an op. + dnnl_graph_op_attr_transpose_b, + /// Specifies an use_affine attribute to an op. + dnnl_graph_op_attr_use_affine, + /// Specifies an use_dst attribute to an op. + dnnl_graph_op_attr_use_dst, + + // string attributes. The value of these attributes can be a string. + + /// Specifies an auto_broadcast attribute to an op. The value can be "none" + /// or "numpy". + dnnl_graph_op_attr_auto_broadcast = 0x80, + /// Specifies an auto_pad attribute to an op. The value can be "none", + /// "same_upper", "same_lower", or "valid". + dnnl_graph_op_attr_auto_pad, + /// Specifies an coordinate_transformation_mode attribute to an op. The + /// value can be "half_pixel" or "align_corners". The attribute is defined + /// for Interpolate operations. + dnnl_graph_op_attr_coordinate_transformation_mode, + /// Specifies a data_format of an op. The value can be "NCX" or "NXC". + dnnl_graph_op_attr_data_format, + /// Specifies a mode attribute of an op. + /// Interpolate: "nearest", "linear", "bilinear", or "trilinear". + /// SoftMax: "none", "inf_as_zero". + /// GELU/GELUBackward: "gelu_erf", "gelu_tanh". + dnnl_graph_op_attr_mode, + /// Specifies a qtype attribute to an op. The value can be "per_channel" or + /// "per_tensor". The attribute is defined for quantization operations. + dnnl_graph_op_attr_qtype, + /// Specifies a rounding_type attribute to an op. The value can be "ceil" or + /// "floor". + dnnl_graph_op_attr_rounding_type, + /// Specifies a weights_format of an op. The value can be "OIX", "XIO", + /// "IOX", or "XOI". Different operations may support different values. + dnnl_graph_op_attr_weights_format, + /// Specifies an accumulation_mode attribute to an op. The value can be + /// "strict", "relaxed", "any", "f32", "s32", or "f16". + dnnl_graph_op_attr_accumulation_mode, + + /// Specifies the end of all above exteral attributes for check. + dnnl_graph_op_attr_end = 0xFF, +} dnnl_graph_op_attr_t; + +/// An opaque structure to describe an operation. +struct dnnl_graph_op; + +/// An operation handle. +typedef struct dnnl_graph_op *dnnl_graph_op_t; + +/// A constant operation handle. +typedef const struct dnnl_graph_op *const_dnnl_graph_op_t; + +/// @} dnnl_graph_api_op + +/// @addtogroup dnnl_graph_api_allocator +/// @{ + +/// Allocation call-back function interface for host. For SYCL allocator, see +/// #dnnl_graph_sycl_allocate_f. +typedef void *(*dnnl_graph_host_allocate_f)(size_t size, size_t alignment); + +/// Deallocation call-back function interface for host. For SYCL allocator, see +/// #dnnl_graph_sycl_deallocate_f. +typedef void (*dnnl_graph_host_deallocate_f)(void *); + +/// An opaque structure to describe an allocator. +struct dnnl_graph_allocator; + +/// An allocator handle. +typedef struct dnnl_graph_allocator *dnnl_graph_allocator_t; + +/// A constant allocator handle. +typedef const struct dnnl_graph_allocator *const_dnnl_graph_allocator_t; + +/// @} dnnl_graph_api_allocator + +/// @addtogroup dnnl_graph_api_compiled_partition +/// @{ + +/// In-place pair definition. It can queried from a compiled partition +/// indicating that an input and an output of the partition can share the same +/// memory buffer for computation. In-place computation helps to reduce the +/// memory footprint and improves cache locality. But since the library may not +/// have a global view of user's application, it's possible that the tensor with +/// `input_id` is used at other places in user's computation graph. In this +/// case, the user should take the in-place pair as a hint and pass a different +/// memory buffer for output tensor to avoid overwriting the input memory buffer +/// which will probably cause unexpected incorrect results. +typedef struct { + /// The id of input tensor + size_t input_id; + + /// The id of output tensor + size_t output_id; +} dnnl_graph_inplace_pair_t; + +/// An opaque structure to describe a compiled partition. +struct dnnl_graph_compiled_partition; + +/// A compiled partition handle. +typedef struct dnnl_graph_compiled_partition *dnnl_graph_compiled_partition_t; + +/// A constant compiled partition handle. +typedef const struct dnnl_graph_compiled_partition + *const_dnnl_graph_compiled_partition_t; + +/// @} dnnl_graph_api_compiled_partition + +/// @addtogroup dnnl_graph_api_tensor +/// @{ + +/// An opaque structure to describe a tensor. +struct dnnl_graph_tensor; + +/// A tensor handle. +typedef struct dnnl_graph_tensor *dnnl_graph_tensor_t; + +/// A constant tensor handle. +typedef const struct dnnl_graph_tensor *const_dnnl_graph_tensor_t; + +/// @} dnnl_graph_api_tensor + +/// @} dnnl_graph_api + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl.h new file mode 100644 index 0000000000000000000000000000000000000000..cfd522c61cd60e6d356f4d2eca02f6d0b38affaf --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl.h @@ -0,0 +1,273 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_OCL_H +#define ONEAPI_DNNL_DNNL_OCL_H + +#include "oneapi/dnnl/dnnl.h" + +#include "oneapi/dnnl/dnnl_ocl_types.h" + +#include +/// @endcond + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_api_interop +/// @{ + +/// @addtogroup dnnl_api_ocl_interop +/// @{ + +/// Creates a memory object. +/// +/// Unless @p handle is equal to DNNL_MEMORY_NONE or DNNL_MEMORY_ALLOCATE, the +/// constructed memory object will have the underlying buffer set. In this +/// case, the buffer will be initialized as if: +/// - dnnl_memory_set_data_handle() has been called, if @p memory_kind is equal +/// to dnnl_ocl_interop_usm, or +/// - dnnl_ocl_interop_memory_set_mem_object() has been called, if @p memory_kind +/// is equal to dnnl_ocl_interop_buffer. +/// +/// @param memory Output memory object. +/// @param memory_desc Memory descriptor. +/// @param engine Engine to use. +/// @param memory_kind Memory allocation kind to specify the type of handle. +/// @param handle Handle of the memory buffer to use as an underlying storage. +/// - A USM pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. Requires @p memory_kind to be equal to +/// dnnl_ocl_interop_usm. +/// - An OpenCL buffer. In this case the library doesn't own the buffer. +/// Requires @p memory_kind be equal to be equal to dnnl_ocl_interop_buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer that corresponds to the memory allocation kind +/// @p memory_kind for the memory object. In this case the library +/// owns the buffer. +/// - The DNNL_MEMORY_NONE specific value. Instructs the library to +/// create memory object without an underlying buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_memory_create(dnnl_memory_t *memory, + const_dnnl_memory_desc_t memory_desc, dnnl_engine_t engine, + dnnl_ocl_interop_memory_kind_t memory_kind, void *handle); + +/// Creates a memory object with multiple handles. +/// +/// @param memory Output memory object. +/// @param memory_desc Memory descriptor. +/// @param engine Engine to use. +/// @param memory_kind Memory allocation kind to specify the type of handles. +/// @param nhandles Number of handles. +/// @param handles Handles of the memory buffers to use as underlying storages. +/// For each element of the @p handles array the following applies: +/// - A USM pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. Requires @p memory_kind to be equal to +/// dnnl_ocl_interop_usm. +/// - An OpenCL buffer. In this case the library doesn't own the buffer. +/// Requires @p memory_kind be equal to be equal to dnnl_ocl_interop_buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer that corresponds to the memory allocation kind +/// @p memory_kind for the memory object. In this case the library +/// owns the buffer. +/// - The DNNL_MEMORY_NONE specific value. Instructs the library to +/// create memory object without an underlying buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_memory_create_v2(dnnl_memory_t *memory, + const_dnnl_memory_desc_t memory_desc, dnnl_engine_t engine, + dnnl_ocl_interop_memory_kind_t memory_kind, int nhandles, + void **handles); + +/// Returns the memory allocation kind associated with a memory object. +/// +/// @param memory Memory to query. +/// @param memory_kind Output underlying memory allocation kind of the memory +/// object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_memory_get_memory_kind( + const_dnnl_memory_t memory, + dnnl_ocl_interop_memory_kind_t *memory_kind); + +/// Returns an OpenCL memory object associated with a memory object. +/// +/// @param memory Memory object. +/// @param mem_object Output OpenCL memory object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_memory_get_mem_object( + const_dnnl_memory_t memory, cl_mem *mem_object); + +/// Sets OpenCL memory object associated with a memory object. +/// +/// For behavioral details, see dnnl_memory_set_data_handle(). +/// +/// @param memory Memory object. +/// @param mem_object OpenCL memory object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_memory_set_mem_object( + dnnl_memory_t memory, cl_mem mem_object); + +/// Retrieves a cache blob ID for the OpenCL device. +/// +/// @warning +/// This API is intended to be used with +/// #dnnl_ocl_interop_engine_get_cache_blob() and +/// #dnnl_ocl_interop_engine_create_from_cache_blob(). The returned cache +/// blob ID can only be used as an ID of the cache blob returned by +/// #dnnl_ocl_interop_engine_get_cache_blob(). +/// +/// @note The cache blob ID can be empty (@p size will be 0 and +/// @p cache_blob_id will be nullptr) if oneDNN doesn't have anything to +/// put in the cache blob. (#dnnl_ocl_interop_engine_get_cache_blob will +/// return an empty cache blob). +/// +/// @param device An OpenCL device. +/// @param size Size of the cache blob ID in bytes. +/// @param cache_blob_id Cache blob id of size @p size. If +/// the @p cache_blob_id is nullptr then the size of the cache blob ID is +/// returned in @p size. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_engine_get_cache_blob_id( + cl_device_id device, size_t *size, uint8_t *cache_blob_id); + +/// Retrieves a cache blob associated with the given engine. +/// +/// @note The cache blob can be empty (@p size will be 0 and @p cache_blob +/// will be nullptr) if oneDNN doesn't have anything to put in the cache +/// blob. It's the user's responsibility to check whether it's empty +/// prior to passing it to +/// #dnnl_ocl_interop_engine_create_from_cache_blob(). +/// +/// @param engine Engine to query for the cache blob. +/// @param size Size of the cache blob in bytes. +/// @param cache_blob Cache blob of size @p size. If the @p cache_blob is +/// nullptr then the size of the cache blob is returned in @p size. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_engine_get_cache_blob( + dnnl_engine_t engine, size_t *size, uint8_t *cache_blob); + +/// Creates an engine from the given cache blob. +/// +/// @param engine Output engine. +/// @param device The OpenCL device that this engine will encapsulate. +/// @param context The OpenCL context (containing the device) that this +/// engine will use for all operations. +/// @param size Size of the cache blob in bytes. +/// @param cache_blob Cache blob of size @p size. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_engine_create_from_cache_blob( + dnnl_engine_t *engine, cl_device_id device, cl_context context, + size_t size, const uint8_t *cache_blob); + +/// Creates an engine associated with an OpenCL device and an OpenCL context. +/// +/// @param engine Output engine. +/// @param device Underlying OpenCL device to use for the engine. +/// @param context Underlying OpenCL context to use for the engine. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_engine_create( + dnnl_engine_t *engine, cl_device_id device, cl_context context); + +/// Returns the OpenCL context associated with an engine. +/// +/// @param engine Engine to query. +/// @param context Output underlying OpenCL context of the engine. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_engine_get_context( + dnnl_engine_t engine, cl_context *context); + +/// Returns the OpenCL device associated with an engine. +/// +/// @param engine Engine to query. +/// @param device Output underlying OpenCL device of the engine. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_get_device( + dnnl_engine_t engine, cl_device_id *device); + +/// Creates an execution stream for a given engine associated with +/// an OpenCL command queue. +/// +/// @param stream Output execution stream. +/// @param engine Engine to create the execution stream on. +/// @param queue OpenCL command queue to use. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_stream_create( + dnnl_stream_t *stream, dnnl_engine_t engine, cl_command_queue queue); + +/// Returns the OpenCL command queue associated with an execution stream. +/// +/// @param stream Execution stream to query. +/// @param queue Output OpenCL command queue. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_stream_get_command_queue( + dnnl_stream_t stream, cl_command_queue *queue); + +/// Executes computations specified by the primitive in a specified stream and +/// returns an OpenCL event. +/// +/// @param primitive Primitive to execute. +/// @param stream Stream to use. +/// @param nargs Number of arguments. +/// @param args Array of arguments. Each argument is an +/// pair. The index is one of the `DNNL_ARG_*` +/// values such as `DNNL_ARG_SRC`. Unless runtime shapes are used (see +/// #DNNL_RUNTIME_DIM_VAL), the memory object must have the same memory +/// descriptor as that returned by +/// #dnnl_primitive_desc_query_md(#dnnl_query_exec_arg_md, index). +/// @param deps A pointer to a vector of size @p ndeps that contains +/// dependencies. +/// @param ndeps Number of dependencies. +/// @param return_event Output event. It's the user's responsibility to +/// manage lifetime of the event. Can be NULL. When @p stream is in-order +/// NULL will be returned. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ocl_interop_primitive_execute( + const_dnnl_primitive_t primitive, dnnl_stream_t stream, int nargs, + const dnnl_exec_arg_t *args, const cl_event *deps, int ndeps, + cl_event *return_event); + +/// @} dnnl_api_ocl_interop + +/// @} dnnl_api_interop + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..95d6b1f91fdf025e795af6e1980d7a30d79f7ade --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl.hpp @@ -0,0 +1,394 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_OCL_HPP +#define ONEAPI_DNNL_DNNL_OCL_HPP + +#include "oneapi/dnnl/dnnl.hpp" + +/// @cond DO_NOT_DOCUMENT_THIS +#include +#include +#include +#include +#include +#include +#include + +#include "oneapi/dnnl/dnnl_ocl.h" + +#include +/// @endcond + +/// @addtogroup dnnl_api +/// @{ + +namespace dnnl { + +/// @addtogroup dnnl_api_interop Runtime interoperability API +/// API extensions to interact with the underlying run-time. +/// @{ + +/// @addtogroup dnnl_api_ocl_interop OpenCL interoperability API +/// API extensions to interact with the underlying OpenCL run-time. +/// +/// @sa @ref dev_guide_opencl_interoperability in developer guide +/// @{ + +/// OpenCL interoperability namespace +namespace ocl_interop { + +/// Memory allocation kind. +enum class memory_kind { + /// USM (device, shared, host, or unknown) memory allocation kind. + usm = dnnl_ocl_interop_usm, + /// Buffer memory allocation kind - default. + buffer = dnnl_ocl_interop_buffer, +}; + +/// Converts a memory allocation kind enum value from C++ API to C API type. +/// +/// @param akind C++ API memory allocation kind enum value. +/// @returns Corresponding C API memory allocation kind enum value. +inline dnnl_ocl_interop_memory_kind_t convert_to_c(memory_kind akind) { + return static_cast(akind); +} + +/// Returns the cache blob ID of the OpenCL device. +/// +/// @warning +/// This API is intended to be used with +/// #dnnl::ocl_interop::get_engine_cache_blob() and +/// #dnnl::ocl_interop::make_engine(cl_device_id, cl_context, const std::vector &). +/// The returned cache blob ID can only be used as an ID of the cache blob +/// returned by #dnnl::ocl_interop::get_engine_cache_blob(). +/// +/// @note The cache blob ID can be empty (@p size will be 0 and +/// @p cache_blob_id will be nullptr) if oneDNN doesn't have anything to +/// put in the cache blob. (#dnnl_ocl_interop_engine_get_cache_blob will +/// return an empty cache blob). +/// +/// @param device An OpenCL device. +/// @returns A vector containing the cache blob ID. +inline std::vector get_engine_cache_blob_id(cl_device_id device) { + size_t size = 0; + error::wrap_c_api( + dnnl_ocl_interop_engine_get_cache_blob_id(device, &size, nullptr), + "could not get an engine cache blob id size"); + + std::vector cache_blob_id(size); + error::wrap_c_api(dnnl_ocl_interop_engine_get_cache_blob_id( + device, &size, cache_blob_id.data()), + "could not get an engine cache blob id"); + return cache_blob_id; +} + +/// Returns a cache blob for the engine. +/// +/// @note The cache blob vector can be empty if oneDNN doesn't have anything +/// to put in the cache blob. It's the user's responsibility to check +/// whether it's empty prior to passing it to +/// #dnnl::ocl_interop::make_engine(cl_device_id, cl_context, const std::vector &) +/// +/// @param aengine Engine to query for the cache blob. +/// @returns Vector containing the cache blob. +inline std::vector get_engine_cache_blob(const engine &aengine) { + size_t size = 0; + error::wrap_c_api(dnnl_ocl_interop_engine_get_cache_blob( + aengine.get(), &size, nullptr), + "could not get an engine cache blob size"); + + std::vector cache_blob(size); + error::wrap_c_api(dnnl_ocl_interop_engine_get_cache_blob( + aengine.get(), &size, cache_blob.data()), + "could not get an engine cache blob"); + return cache_blob; +} + +/// Constructs an engine from the given cache blob. +/// +/// @param device The OpenCL device that this engine will encapsulate. +/// @param context The OpenCL context (containing the device) that this +/// engine will use for all operations. +/// @param cache_blob Cache blob. +/// @returns An engine. +inline engine make_engine(cl_device_id device, cl_context context, + const std::vector &cache_blob) { + dnnl_engine_t c_engine; + error::wrap_c_api( + dnnl_ocl_interop_engine_create_from_cache_blob(&c_engine, device, + context, cache_blob.size(), cache_blob.data()), + "could not create an engine from cache blob"); + return engine(c_engine); +} + +/// Constructs an engine from OpenCL device and context objects. +/// +/// @param device The OpenCL device that this engine will encapsulate. +/// @param context The OpenCL context (containing the device) that this +/// engine will use for all operations. +/// @returns An engine. +inline engine make_engine(cl_device_id device, cl_context context) { + dnnl_engine_t c_engine; + error::wrap_c_api( + dnnl_ocl_interop_engine_create(&c_engine, device, context), + "could not create an engine"); + return engine(c_engine); +} + +/// Returns OpenCL context associated with the engine. +/// +/// @param aengine An engine. +/// @returns Underlying OpenCL context. +inline cl_context get_context(const engine &aengine) { + cl_context context = nullptr; + error::wrap_c_api( + dnnl_ocl_interop_engine_get_context(aengine.get(), &context), + "could not get an OpenCL context from an engine"); + return context; +} + +/// Returns OpenCL device associated with the engine. +/// +/// @param aengine An engine. +/// @returns Underlying OpenCL device. +inline cl_device_id get_device(const engine &aengine) { + cl_device_id device = nullptr; + error::wrap_c_api(dnnl_ocl_interop_get_device(aengine.get(), &device), + "could not get an OpenCL device from an engine"); + return device; +} + +/// Constructs an execution stream for the specified engine and OpenCL queue. +/// +/// @param aengine Engine to create the stream on. +/// @param queue OpenCL queue to use for the stream. +/// @returns An execution stream. +inline stream make_stream(const engine &aengine, cl_command_queue queue) { + dnnl_stream_t c_stream; + error::wrap_c_api( + dnnl_ocl_interop_stream_create(&c_stream, aengine.get(), queue), + "could not create a stream"); + return stream(c_stream); +} + +/// Returns OpenCL queue object associated with the execution stream. +/// +/// @param astream An execution stream. +/// @returns Underlying OpenCL queue. +inline cl_command_queue get_command_queue(const stream &astream) { + cl_command_queue queue = nullptr; + error::wrap_c_api( + dnnl_ocl_interop_stream_get_command_queue(astream.get(), &queue), + "could not get an OpenCL command queue from a stream"); + return queue; +} + +/// Returns the OpenCL memory object associated with the memory object. +/// +/// @param amemory A memory object. +/// @returns Underlying OpenCL memory object. +inline cl_mem get_mem_object(const memory &amemory) { + cl_mem mem_object; + error::wrap_c_api( + dnnl_ocl_interop_memory_get_mem_object(amemory.get(), &mem_object), + "could not get OpenCL buffer object from a memory object"); + return mem_object; +} + +/// Sets the OpenCL memory object associated with the memory object. +/// +/// For behavioral details see memory::set_data_handle(). +/// +/// @param amemory A memory object. +/// @param mem_object OpenCL cl_mem object to use as the underlying +/// storage. It must have at least get_desc().get_size() bytes +/// allocated. +inline void set_mem_object(memory &amemory, cl_mem mem_object) { + error::wrap_c_api( + dnnl_ocl_interop_memory_set_mem_object(amemory.get(), mem_object), + "could not set OpenCL buffer object from a memory object"); +} + +/// Returns the memory allocation kind associated with a memory object. +/// +/// @param amemory A memory object. +/// +/// @returns The underlying memory allocation kind of the memory object. +inline memory_kind get_memory_kind(const memory &amemory) { + dnnl_ocl_interop_memory_kind_t ckind; + error::wrap_c_api( + dnnl_ocl_interop_memory_get_memory_kind(amemory.get(), &ckind), + "could not get memory kind"); + return static_cast(ckind); +} + +/// Creates a memory object with multiple handles. +/// +/// @param memory_desc Memory descriptor. +/// @param aengine Engine to use. +/// @param kind Memory allocation kind to specify the type of handles. +/// @param handles Handles of the memory buffers to use as underlying storages. +/// For each element of the @p handles array the following applies: +/// - A USM pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. Requires @p memory_kind to be equal to +/// dnnl_ocl_interop_usm. +/// - An OpenCL buffer. In this case the library doesn't own the buffer. +/// Requires @p memory_kind be equal to be equal to dnnl_ocl_interop_buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer that corresponds to the memory allocation kind +/// @p memory_kind for the memory object. In this case the library +/// owns the buffer. +/// - The DNNL_MEMORY_NONE specific value. Instructs the library to +/// create memory object without an underlying buffer. +/// +/// If the @p handles vector is not provided the library will allocate all +/// buffers as if all handles have the special value DNNL_MEMORY_ALLOCATE. +/// +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +inline memory make_memory(const memory::desc &memory_desc, + const engine &aengine, memory_kind kind, + std::vector handles = {}) { + if (handles.empty()) { + const int nhandles = memory_desc.get_num_handles(); + handles.resize(nhandles, DNNL_MEMORY_ALLOCATE); + } + + dnnl_memory_t c_memory; + error::wrap_c_api( + dnnl_ocl_interop_memory_create_v2(&c_memory, memory_desc.get(), + aengine.get(), convert_to_c(kind), (int)handles.size(), + handles.data()), + "could not create a memory"); + return memory(c_memory); +} + +/// Constructs a memory object with multiple OpenCL buffers. +/// +/// @param memory_desc Memory descriptor. +/// @param aengine Engine to use. +/// @param mem_objects A vector of OpenCL buffers to use. +/// +/// @returns Created memory object. +inline memory make_memory(const memory::desc &memory_desc, + const engine &aengine, std::vector mem_objects) { + const int nhandles = memory_desc.get_num_handles(); + std::vector handles(nhandles, DNNL_MEMORY_NONE); + memory amemory(memory_desc, aengine, handles); + for (int i = 0; i < nhandles; i++) + amemory.set_data_handle(mem_objects[i], i); + return amemory; +} + +/// Creates a memory object. +/// +/// Unless @p handle is equal to DNNL_MEMORY_NONE or DNNL_MEMORY_ALLOCATE, the +/// constructed memory object will have the underlying buffer set. In this +/// case, the buffer will be initialized as if: +/// - dnnl::memory::set_data_handle() had been called, if @p memory_kind is +/// equal to dnnl::ocl_interop::memory_kind::usm, or +/// - dnnl::ocl_interop::set_mem_object() has been called, if @p memory_kind is +/// equal to dnnl::ocl_interop::memory_kind::buffer. +/// +/// @param memory_desc Memory descriptor. +/// @param aengine Engine to use. +/// @param kind Memory allocation kind to specify the type of handle. +/// @param handle Handle of the memory buffer to use as an underlying storage. +/// - A USM pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. Requires @p memory_kind to be equal to +/// dnnl::ocl_interop::memory_kind::usm. +/// - An OpenCL buffer. In this case the library doesn't own the buffer. +/// Requires @p memory_kind be equal to be equal to +/// dnnl::ocl_interop::memory_kind::buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer that corresponds to the memory allocation kind +/// @p memory_kind for the memory object. In this case the library +/// owns the buffer. +/// - The DNNL_MEMORY_NONE specific value. Instructs the library to +/// create memory object without an underlying buffer. +/// +/// @returns Created memory object. +inline memory make_memory(const memory::desc &memory_desc, + const engine &aengine, memory_kind kind, void *handle) { + return make_memory( + memory_desc, aengine, kind, std::vector {handle}); +} + +/// Constructs a memory object from an OpenCL buffer. +/// +/// @param memory_desc Memory descriptor. +/// @param aengine Engine to use. +/// @param mem_object An OpenCL buffer to use. +/// +/// @returns Created memory object. +inline memory make_memory(const memory::desc &memory_desc, + const engine &aengine, cl_mem mem_object) { + return make_memory(memory_desc, aengine, std::vector {mem_object}); +} + +/// Executes computations specified by the primitive in a specified stream and +/// returns a SYCL event. +/// +/// Arguments are passed via an arguments map containing +/// pairs. The index must be one of the `DNNL_ARG_*` +/// values such as `DNNL_ARG_SRC`, and the memory must have a memory descriptor +/// matching the one returned by +/// #dnnl::primitive_desc::query_md(#query::exec_arg_md, index) unless using +/// dynamic shapes (see #DNNL_RUNTIME_DIM_VAL). +/// +/// @param aprimitive Primitive to execute. +/// @param astream Stream object. The stream must belong to the same engine +/// as the primitive. +/// @param args Arguments map. +/// @param deps Optional vector with `cl_event` dependencies. +/// +/// @returns Output event. It's the user's responsibility to manage lifetime +/// of the event. +inline cl_event execute(const dnnl::primitive &aprimitive, + const stream &astream, const std::unordered_map &args, + const std::vector &deps = {}) { + std::vector c_args; + c_args.reserve(args.size()); + for (const auto &a : args) + c_args.push_back({a.first, a.second.get()}); + + const cl_event *c_deps = deps.empty() ? nullptr : deps.data(); + + cl_event return_event; + error::wrap_c_api(dnnl_ocl_interop_primitive_execute(aprimitive.get(), + astream.get(), (int)c_args.size(), c_args.data(), + c_deps, (int)deps.size(), &return_event), + "could not execute a primitive"); + return return_event; +} + +} // namespace ocl_interop + +/// @} dnnl_api_ocl_interop + +/// @} dnnl_api_interop + +} // namespace dnnl + +/// @} dnnl_api + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl_types.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl_types.h new file mode 100644 index 0000000000000000000000000000000000000000..4b8e3ab7be1897a19a4db44393e0cfdf4f9a36d8 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl_types.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_OCL_TYPES_H +#define ONEAPI_DNNL_DNNL_OCL_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_api_interop +/// @{ + +/// @addtogroup dnnl_api_ocl_interop +/// @{ + +/// Memory allocation kind. +typedef enum { + /// USM (device, shared, host, or unknown) memory allocation kind. + dnnl_ocl_interop_usm, + /// Buffer memory allocation kind - default. + dnnl_ocl_interop_buffer, +} dnnl_ocl_interop_memory_kind_t; + +/// @} dnnl_api_ocl_interop + +/// @} dnnl_api_interop + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl.h new file mode 100644 index 0000000000000000000000000000000000000000..670e52f19afbdf6388970f802ddaa91aeed1c720 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl.h @@ -0,0 +1,202 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_SYCL_H +#define ONEAPI_DNNL_DNNL_SYCL_H + +#include "oneapi/dnnl/dnnl.h" + +#include "oneapi/dnnl/dnnl_sycl_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_api_interop +/// @{ + +/// @addtogroup dnnl_api_sycl_interop +/// @{ + +/// Creates an engine associated with a SYCL device and a SYCL context. +/// +/// @param engine Output engine. +/// @param device Pointer to the SYCL device to use for the engine. +/// @param context Pointer to the SYCL context to use for the engine. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_engine_create( + dnnl_engine_t *engine, const void *device, const void *context); + +/// Returns the SYCL context associated with an engine. +/// +/// @param engine Engine to query. +/// @param context Pointer to the underlying SYCL context of the engine. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_engine_get_context( + dnnl_engine_t engine, void **context); + +/// Returns the SYCL device associated with an engine. +/// +/// @param engine Engine to query. +/// @param device Pointer to the underlying SYCL device of the engine. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_engine_get_device( + dnnl_engine_t engine, void **device); + +/// Creates a memory object. +/// +/// Unless @p handle is equal to DNNL_MEMORY_NONE or DNNL_MEMORY_ALLOCATE, the +/// constructed memory object will have the underlying buffer set. In this +/// case, the buffer will be initialized as if: +/// - dnnl_memory_set_data_handle() had been called, if @p memory_kind is equal +/// to dnnl_sycl_interop_usm, or +/// - dnnl_sycl_interop_memory_set_buffer() has been called, if @p memory_kind +/// is equal to dnnl_sycl_interop_buffer. +/// +/// @param memory Output memory object. +/// @param memory_desc Memory descriptor. +/// @param engine Engine to use. +/// @param memory_kind Memory allocation kind to specify the type of handle. +/// @param handle Handle of the memory buffer to use as an underlying storage. +/// - A USM pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. Requires @p memory_kind to be equal to +/// dnnl_sycl_interop_usm. +/// - A pointer to SYCL buffer. In this case the library doesn't own the +/// buffer. Requires @p memory_kind be equal to be equal to +/// dnnl_sycl_interop_buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer that corresponds to the memory allocation kind +/// @p memory_kind for the memory object. In this case the library +/// owns the buffer. +/// - The DNNL_MEMORY_NONE specific value. Instructs the library to +/// create memory object without an underlying buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_memory_create(dnnl_memory_t *memory, + const_dnnl_memory_desc_t memory_desc, dnnl_engine_t engine, + dnnl_sycl_interop_memory_kind_t memory_kind, void *handle); + +/// Creates a memory object with multiple handles. +/// +/// @param memory Output memory object. +/// @param memory_desc Memory descriptor. +/// @param engine Engine to use. +/// @param memory_kind Memory allocation kind to specify the type of handles. +/// @param nhandles Number of handles. +/// @param handles Handles of the memory buffers to use as underlying storages. +/// For each element of the @p handles array the following applies: +/// - A USM pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. Requires @p memory_kind to be equal to +/// dnnl_sycl_interop_usm. +/// - A pointer to SYCL buffer. In this case the library doesn't own the +/// buffer. Requires @p memory_kind be equal to be equal to +/// dnnl_sycl_interop_buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer that corresponds to the memory allocation kind +/// @p memory_kind for the memory object. In this case the library +/// owns the buffer. +/// - The DNNL_MEMORY_NONE specific value. Instructs the library to +/// create memory object without an underlying buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_memory_create_v2(dnnl_memory_t *memory, + const_dnnl_memory_desc_t memory_desc, dnnl_engine_t engine, + dnnl_sycl_interop_memory_kind_t memory_kind, int nhandles, + void **handles); + +/// Returns the memory allocation kind associated with a memory object. +/// +/// @param memory Memory to query. +/// @param memory_kind Output underlying memory allocation kind of the memory +/// object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_memory_get_memory_kind( + const_dnnl_memory_t memory, + dnnl_sycl_interop_memory_kind_t *memory_kind); + +/// Sets a SYCL buffer for a memory object. +/// +/// @param memory Memory object. +/// @param buffer SYCL buffer to be set in the memory object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_memory_set_buffer( + dnnl_memory_t memory, void *buffer); + +/// Creates an execution stream for a given engine associated with a SYCL +/// queue. +/// +/// @param stream Output execution stream. +/// @param engine Engine to create the execution stream on. +/// @param queue SYCL queue to use. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_stream_create( + dnnl_stream_t *stream, dnnl_engine_t engine, void *queue); + +/// Returns the SYCL queue associated with an execution stream. +/// +/// @param stream Execution stream to query. +/// @param queue Output SYCL command queue. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_stream_get_queue( + dnnl_stream_t stream, void **queue); + +/// Executes computations specified by the primitive in a specified stream and +/// returns a SYCL event. +/// +/// @param primitive Primitive to execute. +/// @param stream Stream to use. +/// @param nargs Number of arguments. +/// @param args Array of arguments. Each argument is an +/// pair. The index is one of the `DNNL_ARG_*` +/// values such as `DNNL_ARG_SRC`. Unless runtime shapes are used (see +/// #DNNL_RUNTIME_DIM_VAL), the memory object must have the same memory +/// descriptor as that returned by +/// #dnnl_primitive_desc_query_md(#dnnl_query_exec_arg_md, index). +/// @param deps A pointer to std::vector that contains +/// dependencies. +/// @param return_event Output event. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_sycl_interop_primitive_execute( + const_dnnl_primitive_t primitive, dnnl_stream_t stream, int nargs, + const dnnl_exec_arg_t *args, const void *deps, void *return_event); + +/// @} dnnl_api_sycl_interop + +/// @} dnnl_api_interop + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..674c7c2c182770f4cc8f0098b31a8515d95951dc --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl.hpp @@ -0,0 +1,347 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_SYCL_HPP +#define ONEAPI_DNNL_DNNL_SYCL_HPP + +/// @cond DO_NOT_DOCUMENT_THIS +#include +#include +#include +#include +#include +#include +#include + +#if __has_include() +#include +#else +#error "Unsupported compiler" +#endif + +#include "oneapi/dnnl/dnnl.hpp" +#include "oneapi/dnnl/dnnl_sycl.h" + +/// @endcond + +/// @addtogroup dnnl_api +/// @{ + +namespace dnnl { + +/// @addtogroup dnnl_api_interop +/// @{ + +/// @addtogroup dnnl_api_sycl_interop SYCL interoperability API +/// API extensions to interact with the underlying SYCL run-time. +/// +/// @sa @ref dev_guide_dpcpp_interoperability in developer guide +/// @{ + +/// SYCL interoperability namespace +namespace sycl_interop { + +/// Memory allocation kind. +enum class memory_kind { + /// USM (device, shared, host, or unknown) memory allocation kind - default. + usm = dnnl_sycl_interop_usm, + /// Buffer memory allocation kind. + buffer = dnnl_sycl_interop_buffer, +}; + +/// Converts a memory allocation kind enum value from C++ API to C API type. +/// +/// @param akind C++ API memory allocation kind enum value. +/// @returns Corresponding C API memory allocation kind enum value. +inline dnnl_sycl_interop_memory_kind_t convert_to_c(memory_kind akind) { + return static_cast(akind); +} + +/// Constructs an engine from SYCL device and context objects. +/// +/// @param adevice SYCL device. +/// @param acontext SYCL context. +/// +/// @returns Created engine. +inline engine make_engine( + const sycl::device &adevice, const sycl::context &acontext) { + dnnl_engine_t aengine; + error::wrap_c_api(dnnl_sycl_interop_engine_create(&aengine, + static_cast(&adevice), + static_cast(&acontext)), + "could not create an engine"); + return engine(aengine); +} + +/// Returns the SYCL context associated with an engine. +/// +/// @param aengine Engine to query. +/// +/// @returns The underlying SYCL device of the engine. +inline sycl::context get_context(const engine &aengine) { + void *ctx_ptr; + error::wrap_c_api( + dnnl_sycl_interop_engine_get_context(aengine.get(), &ctx_ptr), + "could not get a context handle"); + auto ctx = *static_cast(ctx_ptr); + return ctx; +} + +/// Returns the SYCL device associated with an engine. +/// +/// @param aengine Engine to query. +/// +/// @returns The underlying SYCL context of the engine. +inline sycl::device get_device(const engine &aengine) { + void *dev_ptr; + error::wrap_c_api( + dnnl_sycl_interop_engine_get_device(aengine.get(), &dev_ptr), + "could not get a device handle"); + auto dev = *static_cast(dev_ptr); + return dev; +} + +/// Creates an execution stream for a given engine associated with a SYCL +/// queue. +/// +/// @param aengine Engine object to use for the stream. +/// @param aqueue SYCL queue to use for the stream. +/// +/// @returns An execution stream. +inline stream make_stream(const engine &aengine, sycl::queue &aqueue) { + dnnl_stream_t astream; + error::wrap_c_api( + dnnl_sycl_interop_stream_create(&astream, aengine.get(), &aqueue), + "could not create a stream"); + return stream(astream); +} + +/// Returns the SYCL queue associated with an execution stream. +/// +/// @param astream Execution stream to query. +/// +/// @returns SYCL queue object. +inline sycl::queue get_queue(const stream &astream) { + void *queue_ptr; + error::wrap_c_api( + dnnl_sycl_interop_stream_get_queue(astream.get(), &queue_ptr), + "could not get a stream handle"); + auto queue = *static_cast(queue_ptr); + return queue; +} + +/// Returns the SYCL buffer associated with a memory object. +/// +/// Throws an exception if the memory allocation kind associated with the +/// memory object is not equal to dnnl::sycl_interop::memory_kind::buffer. +/// +/// @tparam T Type of the requested buffer. +/// @tparam ndims Number of dimensions of the requested buffer. +/// @param amemory Memory object. +/// +/// @returns SYCL buffer associated with the memory object. +template +sycl::buffer get_buffer(const memory &amemory) { + static_assert(ndims == 1, "only 1D buffers supported"); + + // XXX: workaround: when CPU runtime is not SYCL and amemory was created + // for CPU engine `get_buffer` should return an error. Use interop API to + // implement the check. + dnnl_sycl_interop_memory_kind_t ckind; + error::wrap_c_api( + dnnl_sycl_interop_memory_get_memory_kind(amemory.get(), &ckind), + "could not get SYCL buffer object"); + + void *handle_ptr; + error::wrap_c_api(dnnl_memory_get_data_handle(amemory.get(), &handle_ptr), + "could not get SYCL buffer object"); + + // XXX: workaround: zero-range buffer cannot be constructed. + if (!handle_ptr) return sycl::buffer(sycl::range<1>(1)); + + auto &buf_u8 = *static_cast *>(handle_ptr); + + auto range = sycl::range<1>(buf_u8.byte_size() / sizeof(T)); + return buf_u8.reinterpret(range); +} + +/// Sets SYCL buffer associated with a memory object. +/// +/// @tparam T Type of the buffer. +/// @tparam ndims Number of dimensions of the buffer. +/// @param amemory Memory object to change. +/// @param abuffer SYCL buffer. +template +void set_buffer(memory &amemory, sycl::buffer &abuffer) { + auto range = sycl::range<1>(abuffer.byte_size()); + auto buf_u8 = abuffer.template reinterpret(range); + error::wrap_c_api(dnnl_sycl_interop_memory_set_buffer( + amemory.get(), static_cast(&buf_u8)), + "could not set SYCL buffer object"); +} + +/// Returns the memory allocation kind associated with a memory object. +/// +/// @param amemory A memory object. +/// +/// @returns The underlying memory allocation kind of the memory object. +inline memory_kind get_memory_kind(const memory &amemory) { + dnnl_sycl_interop_memory_kind_t ckind; + error::wrap_c_api( + dnnl_sycl_interop_memory_get_memory_kind(amemory.get(), &ckind), + "could not get memory kind"); + return static_cast(ckind); +} + +/// Creates a memory object with multiple handles. +/// +/// @param memory_desc Memory descriptor. +/// @param aengine Engine to use. +/// @param kind Memory allocation kind to specify the type of handles. +/// @param handles Handles of the memory buffers to use as underlying storages. +/// For each element of the @p handles array the following applies: +/// - A USM pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. Requires @p memory_kind to be equal to +/// dnnl::sycl_interop::memory_kind::usm. +/// - A pointer to SYCL buffer. In this case the library doesn't own the +/// buffer. Requires @p memory_kind be equal to be equal to +/// dnnl::sycl_interop::memory_kind::buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer that corresponds to the memory allocation kind +/// @p memory_kind for the memory object. In this case the library +/// owns the buffer. +/// - The DNNL_MEMORY_NONE specific value. Instructs the library to +/// create memory object without an underlying buffer. +/// +/// If the @p handles vector is not provided the library will allocate all +/// buffers as if all handles have the special value DNNL_MEMORY_ALLOCATE. +/// +/// @returns Created memory object. +inline memory make_memory(const memory::desc &memory_desc, + const engine &aengine, memory_kind kind, + std::vector handles = {}) { + if (handles.empty()) { + const int nhandles = memory_desc.get_num_handles(); + handles.resize(nhandles, DNNL_MEMORY_ALLOCATE); + } + + dnnl_memory_t c_memory; + error::wrap_c_api( + dnnl_sycl_interop_memory_create_v2(&c_memory, memory_desc.get(), + aengine.get(), convert_to_c(kind), (int)handles.size(), + handles.data()), + "could not create a memory"); + return memory(c_memory); +} + +/// Creates a memory object. +/// +/// Unless @p handle is equal to DNNL_MEMORY_NONE or DNNL_MEMORY_ALLOCATE, the +/// constructed memory object will have the underlying buffer set. In this +/// case, the buffer will be initialized as if: +/// - dnnl::memory::set_data_handle() had been called, if @p memory_kind is +/// equal to dnnl::sycl_interop::memory_kind::usm, or +/// - dnnl::sycl_interop::set_buffer() has been called, if @p memory_kind is +/// equal to dnnl::sycl_interop::memory_kind::buffer. +/// +/// @param memory_desc Memory descriptor. +/// @param aengine Engine to use. +/// @param kind Memory allocation kind to specify the type of handle. +/// @param handle Handle of the memory buffer to use as an underlying storage. +/// - A USM pointer to the user-allocated buffer. In this case the library +/// doesn't own the buffer. Requires @p memory_kind to be equal to +/// dnnl::sycl_interop::memory_kind::usm. +/// - A pointer to SYCL buffer. In this case the library doesn't own the +/// buffer. Requires @p memory_kind be equal to be equal to +/// dnnl::sycl_interop::memory_kind::buffer. +/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to +/// allocate the buffer that corresponds to the memory allocation kind +/// @p memory_kind for the memory object. In this case the library +/// owns the buffer. +/// - The DNNL_MEMORY_NONE specific value. Instructs the library to +/// create memory object without an underlying buffer. +/// +/// @returns Created memory object. +inline memory make_memory(const memory::desc &memory_desc, + const engine &aengine, memory_kind kind, void *handle) { + return make_memory( + memory_desc, aengine, kind, std::vector {handle}); +} + +/// Constructs a memory object from a SYCL buffer. +/// +/// @param memory_desc Memory descriptor. +/// @param aengine Engine to use. +/// @param abuffer A SYCL buffer to use. +/// +/// @returns Created memory object. +template +memory make_memory(const memory::desc &memory_desc, const engine &aengine, + sycl::buffer &abuffer) { + memory amemory(memory_desc, aengine, DNNL_MEMORY_NONE); + set_buffer(amemory, abuffer); + return amemory; +} + +/// Executes computations specified by the primitive in a specified stream and +/// returns a SYCL event. +/// +/// Arguments are passed via an arguments map containing +/// pairs. The index must be one of the `DNNL_ARG_*` +/// values such as `DNNL_ARG_SRC`, and the memory must have a memory descriptor +/// matching the one returned by +/// #dnnl::primitive_desc::query_md(#query::exec_arg_md, index) unless using +/// dynamic shapes (see #DNNL_RUNTIME_DIM_VAL). +/// +/// @param aprimitive Primitive to execute. +/// @param astream Stream object. The stream must belong to the same engine +/// as the primitive. +/// @param args Arguments map. +/// @param deps Optional vector with `sycl::event` dependencies. +/// +/// @returns Output event. +inline sycl::event execute(const dnnl::primitive &aprimitive, + const stream &astream, const std::unordered_map &args, + const std::vector &deps = {}) { + std::vector c_args; + c_args.reserve(args.size()); + for (const auto &a : args) + c_args.push_back({a.first, a.second.get()}); + + sycl::event return_event; + error::wrap_c_api( + dnnl_sycl_interop_primitive_execute(aprimitive.get(), astream.get(), + (int)c_args.size(), c_args.data(), &deps, &return_event), + "could not execute a primitive"); + return return_event; +} + +} // namespace sycl_interop + +/// @} dnnl_api_sycl_interop + +/// @} dnnl_api_interop + +} // namespace dnnl + +/// @} dnnl_api + +#endif // ONEAPI_DNNL_DNNL_SYCL_HPP + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl_types.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl_types.h new file mode 100644 index 0000000000000000000000000000000000000000..06ceb5dccac4719136d9211a5eed787f2db83693 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl_types.h @@ -0,0 +1,56 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_SYCL_TYPES_H +#define ONEAPI_DNNL_DNNL_SYCL_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_api_interop +/// @{ + +/// @addtogroup dnnl_api_sycl_interop +/// @{ + +/// Memory allocation kind. +typedef enum { + /// USM (device, shared, host, or unknown) memory allocation kind - default. + dnnl_sycl_interop_usm, + /// Buffer memory allocation kind. + dnnl_sycl_interop_buffer, +} dnnl_sycl_interop_memory_kind_t; + +/// @} dnnl_api_sycl_interop + +/// @} dnnl_api_interop + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool.h new file mode 100644 index 0000000000000000000000000000000000000000..0f0df843bd0f681ef85e0b8bfd52caef11385fcf --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool.h @@ -0,0 +1,123 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_THREADPOOL_H +#define ONEAPI_DNNL_DNNL_THREADPOOL_H + +#include "oneapi/dnnl/dnnl_config.h" +#include "oneapi/dnnl/dnnl_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_api_interop +/// @{ + +/// @addtogroup dnnl_api_threadpool_interop +/// @{ + +/// Creates an execution stream with specified threadpool. +/// +/// @sa @ref dev_guide_threadpool +/// +/// @param stream Output execution stream. +/// @param engine Engine to create the execution stream on. +/// @param threadpool Pointer to an instance of a C++ class that implements +/// dnnl::threapdool_iface interface. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_threadpool_interop_stream_create( + dnnl_stream_t *stream, dnnl_engine_t engine, void *threadpool); + +/// Returns a threadpool to be used by the execution stream. +/// +/// @sa @ref dev_guide_threadpool +/// +/// @param astream Execution stream. +/// @param threadpool Output pointer to an instance of a C++ class that +/// implements dnnl::threapdool_iface interface. Set to NULL if the +/// stream was created without threadpool. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_threadpool_interop_stream_get_threadpool( + dnnl_stream_t astream, void **threadpool); + +/// Sets the maximum concurrency assumed by oneDNN when outside a +/// parallel call. +/// +/// @param max_concurrency The maximum concurrency assumed by oneDNN +/// when outside a parallel call. This is a threadlocal setting. +/// @returns #dnnl_success on success and a status describing the +/// error otherwise. +dnnl_status_t DNNL_API dnnl_threadpool_interop_set_max_concurrency( + int max_concurrency); + +/// Gets the maximum concurrency assumed by oneDNN when outside a +/// parallel call. +/// +/// @param max_concurrency The maximum concurrency assumed by oneDNN +/// when outside a parallel call. This is a threadlocal setting. +/// @returns #dnnl_success on success and a status describing the +/// error otherwise. +dnnl_status_t DNNL_API dnnl_threadpool_interop_get_max_concurrency( + int *max_concurrency); + +/// @copydoc dnnl_sgemm() +/// @param threadpool A pointer to a threadpool interface (only when built with +/// the THREADPOOL CPU runtime). +dnnl_status_t DNNL_API dnnl_threadpool_interop_sgemm(char transa, char transb, + dnnl_dim_t M, dnnl_dim_t N, dnnl_dim_t K, float alpha, const float *A, + dnnl_dim_t lda, const float *B, dnnl_dim_t ldb, float beta, float *C, + dnnl_dim_t ldc, void *threadpool); + +/// @copydoc dnnl_gemm_u8s8s32() +/// @param threadpool A pointer to a threadpool interface (only when built with +/// the THREADPOOL CPU runtime). +dnnl_status_t DNNL_API dnnl_threadpool_interop_gemm_u8s8s32(char transa, + char transb, char offsetc, dnnl_dim_t M, dnnl_dim_t N, dnnl_dim_t K, + float alpha, const uint8_t *A, dnnl_dim_t lda, uint8_t ao, + const int8_t *B, dnnl_dim_t ldb, int8_t bo, float beta, int32_t *C, + dnnl_dim_t ldc, const int32_t *co, void *threadpool); + +/// @copydoc dnnl_gemm_s8s8s32() +/// @param threadpool A pointer to a threadpool interface (only when built with +/// the THREADPOOL CPU runtime). +dnnl_status_t DNNL_API dnnl_threadpool_interop_gemm_s8s8s32(char transa, + char transb, char offsetc, dnnl_dim_t M, dnnl_dim_t N, dnnl_dim_t K, + float alpha, const int8_t *A, dnnl_dim_t lda, int8_t ao, + const int8_t *B, dnnl_dim_t ldb, int8_t bo, float beta, int32_t *C, + dnnl_dim_t ldc, const int32_t *co, void *threadpool); + +/// @} dnnl_api_threadpool_interop + +/// @} dnnl_api_interop + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e060e5f2f50740c754ea8d844ca1d31c0b5960c1 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool.hpp @@ -0,0 +1,118 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_THREADPOOL_HPP +#define ONEAPI_DNNL_DNNL_THREADPOOL_HPP + +#include "oneapi/dnnl/dnnl.hpp" +#include "oneapi/dnnl/dnnl_threadpool.h" + +#include "oneapi/dnnl/dnnl_threadpool_iface.hpp" + +/// @addtogroup dnnl_api +/// @{ + +namespace dnnl { + +/// @addtogroup dnnl_api_interop +/// @{ + +/// @addtogroup dnnl_api_threadpool_interop Threadpool interoperability API +/// API extensions to interact with the underlying Threadpool run-time. +/// @{ + +/// Threadpool interoperability namespace +namespace threadpool_interop { + +/// Constructs an execution stream for the specified engine and threadpool. +/// +/// @sa @ref dev_guide_threadpool +/// +/// @param aengine Engine to create the stream on. +/// @param threadpool Pointer to an instance of a C++ class that implements +/// dnnl::threapdool_iface interface. +/// @returns An execution stream. +inline dnnl::stream make_stream( + const dnnl::engine &aengine, threadpool_iface *threadpool) { + dnnl_stream_t c_stream; + dnnl::error::wrap_c_api(dnnl_threadpool_interop_stream_create( + &c_stream, aengine.get(), threadpool), + "could not create stream"); + return dnnl::stream(c_stream); +} + +/// Returns the pointer to a threadpool that is used by an execution stream. +/// +/// @sa @ref dev_guide_threadpool +/// +/// @param astream An execution stream. +/// @returns Output pointer to an instance of a C++ class that implements +/// dnnl::threapdool_iface interface or NULL if the stream was created +/// without threadpool. +inline threadpool_iface *get_threadpool(const dnnl::stream &astream) { + void *tp; + dnnl::error::wrap_c_api( + dnnl_threadpool_interop_stream_get_threadpool(astream.get(), &tp), + "could not get stream threadpool"); + return static_cast(tp); +} + +/// @copydoc dnnl_threadpool_interop_sgemm() +inline status sgemm(char transa, char transb, dnnl_dim_t M, dnnl_dim_t N, + dnnl_dim_t K, float alpha, const float *A, dnnl_dim_t lda, + const float *B, dnnl_dim_t ldb, float beta, float *C, dnnl_dim_t ldc, + threadpool_iface *threadpool) { + return static_cast(dnnl_threadpool_interop_sgemm(transa, transb, M, + N, K, alpha, A, lda, B, ldb, beta, C, ldc, threadpool)); +} +/// @copydoc dnnl_threadpool_interop_gemm_u8s8s32() +inline status gemm_u8s8s32(char transa, char transb, char offsetc, dnnl_dim_t M, + dnnl_dim_t N, dnnl_dim_t K, float alpha, const uint8_t *A, + dnnl_dim_t lda, uint8_t ao, const int8_t *B, dnnl_dim_t ldb, int8_t bo, + float beta, int32_t *C, dnnl_dim_t ldc, const int32_t *co, + threadpool_iface *threadpool) { + return static_cast(dnnl_threadpool_interop_gemm_u8s8s32(transa, + transb, offsetc, M, N, K, alpha, A, lda, ao, B, ldb, bo, beta, C, + ldc, co, threadpool)); +} + +/// @copydoc dnnl_threadpool_interop_gemm_s8s8s32() +inline status gemm_s8s8s32(char transa, char transb, char offsetc, dnnl_dim_t M, + dnnl_dim_t N, dnnl_dim_t K, float alpha, const int8_t *A, + dnnl_dim_t lda, int8_t ao, const int8_t *B, dnnl_dim_t ldb, int8_t bo, + float beta, int32_t *C, dnnl_dim_t ldc, const int32_t *co, + threadpool_iface *threadpool) { + return static_cast(dnnl_threadpool_interop_gemm_s8s8s32(transa, + transb, offsetc, M, N, K, alpha, A, lda, ao, B, ldb, bo, beta, C, + ldc, co, threadpool)); +} + +} // namespace threadpool_interop + +/// @} dnnl_api_threadpool_interop + +/// @} dnnl_api_interop + +} // namespace dnnl + +/// @} dnnl_api + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool_iface.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool_iface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c0e2274d972861fbf369b6d32402345439050f45 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool_iface.hpp @@ -0,0 +1,86 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// Threadpool Interoperability C++ Types + +#ifndef ONEAPI_DNNL_DNNL_THREADPOOL_IFACE_HPP +#define ONEAPI_DNNL_DNNL_THREADPOOL_IFACE_HPP +// NOLINTBEGIN(readability-identifier-naming) + +#include +#include + +/// @addtogroup dnnl_api +/// @{ + +namespace dnnl { + +/// @addtogroup dnnl_api_interop +/// @{ + +/// @addtogroup dnnl_api_threadpool_interop +/// @{ + +namespace threadpool_interop { + +/// Abstract threadpool interface. The users are expected to subclass this +/// interface and pass an object to the library during CPU stream creation or +/// directly in case of BLAS functions. +struct threadpool_iface { + /// Returns the number of worker threads. + virtual int get_num_threads() const = 0; + + /// Returns true if the calling thread belongs to this threadpool. + virtual bool get_in_parallel() const = 0; + + /// Submits n instances of a closure for execution in parallel: + /// + /// for (int i = 0; i < n; i++) fn(i, n); + /// + virtual void parallel_for(int n, const std::function &fn) + = 0; + + /// Returns threadpool behavior flags bit mask (see below). + virtual uint64_t get_flags() const = 0; + + // Does nothing if SYNCHRONOUS, waits for all jobs for ASYNCHRONOUS + virtual void wait() = 0; + + /// If set, parallel_for() returns immediately and oneDNN needs implement + /// waiting for the submitted closures to finish execution on its own. + static constexpr uint64_t ASYNCHRONOUS = 1; + + virtual ~threadpool_iface() = default; +}; + +} // namespace threadpool_interop + +/// @} dnnl_api_threadpool_interop + +/// @} dnnl_api_interop + +} // namespace dnnl + +/// @} dnnl_api + +// NOLINTEND(readability-identifier-naming) +#endif /* ONEAPI_DNNL_DNNL_THREADPOOL_IFACE_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_types.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_types.h new file mode 100644 index 0000000000000000000000000000000000000000..c324625bed052be24b5bc5c169e815289d5b9838 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_types.h @@ -0,0 +1,3007 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2016 Intel Corporation +* Copyright 2024-2025 FUJITSU LIMITED +* Copyright 2025 Arm Ltd. and affiliates +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// C API types definitions + +#ifndef ONEAPI_DNNL_DNNL_TYPES_H +#define ONEAPI_DNNL_DNNL_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/// @cond DO_NOT_DOCUMENT_THIS +#include +#include +/// @endcond + +#include "oneapi/dnnl/dnnl_config.h" + +#include "oneapi/dnnl/dnnl_common_types.h" + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_api_memory +/// @{ + +/// Memory format kind +typedef enum { + /// Undefined memory format kind, used for empty memory descriptors. + dnnl_format_kind_undef = 0, + /// A special format kind that indicates that the actual format will be + /// selected by a primitive automatically. + dnnl_format_kind_any, + /// A tensor in a generic format described by the stride and blocking + /// values in each dimension. + dnnl_blocked, + /// A special format kind that indicates that tensor format is opaque. + dnnl_format_kind_opaque, + /// Format kind for sparse tensors. + dnnl_format_kind_sparse, + /// Format kind for host scalars. + dnnl_format_kind_host_scalar, + + // Max value to prevent UB for internal-use-only values. + dnnl_format_kind_max = 0x7fff, +} dnnl_format_kind_t; + +/// Sparse encodings. +/// @sa @ref dev_guide_sparsity +typedef enum { + /// Undefined sparse encoding kind, used for empty memory descriptors. + dnnl_sparse_encoding_undef = 0, + /// Compressed Sparse Row (CSR) encoding. + dnnl_csr, + /// An encoding that is used for an opaque storage schema for + /// tensors with unstructured sparsity. A memory descriptor with the + /// packed encoding cannot be used to create a memory object. It can + /// only be used to create a primitive descriptor to query the + /// actual memory descriptor (similar to the format tag `any`). + dnnl_packed, + /// Coordinate Sparse Encoding (COO). + dnnl_coo, +} dnnl_sparse_encoding_t; + +#ifdef DNNL_EXPERIMENTAL_PROFILING +/// Profiling data kind. +typedef enum { + /// Undefined profiling data kind. + dnnl_profiling_data_kind_undef = 0, + /// Data kind to query an execution time in nanoseconds. + dnnl_profiling_data_kind_time, + + // Max value to prevent UB for internal-use-only values. + dnnl_profiling_data_max = 0x7fff, +} dnnl_profiling_data_kind_t; + +#endif + +/// Memory format tag specification. +/// +/// oneDNN formats describe physical data layout. The physical layout +/// is described as a sequence of the dimensions as they are laid out in the +/// memory (from the outer-most to the inner-most). Note that this order +/// doesn't affect the logical order of the dimensions that is kept in the +/// `dims` field of the dnnl_memory_desc_t structure. The logical order of the +/// dimensions is specified by the primitive that uses the tensor. +/// +/// For example, CNN 5D tensor always has its logical dimensions in the order +/// `(batch, channels, depth, height, width)`, while the physical layout might be +/// `NCDHW` (corresponds to #dnnl_ncdhw format tag) or +/// `NDHWC` (corresponds to #dnnl_ndhwc format tag). +/// +/// ~~~cpp +/// int batch = 2, channels = 16, depth = 13, height = 13, width = 13; +/// +/// int ndims = 5; // 5D tensor +/// dnnl_dims_t dims = {batch, channels, depth, height, width}; +/// dnnl_memory_desc_t data_in_ncdhw; +/// dnnl_memory_desc_create_with_tag( +/// &data_in_ncdhw, 5, dims, dnnl_f32, dnnl_ncdhw); +/// +/// // note that in both cases dims passed are the same +/// dnnl_memory_desc_t data_in_ndhwc; +/// dnnl_memory_desc_create_with_tag( +/// &data_in_ndhwc, 5, dims, dnnl_f32, dnnl_ndhwc); +/// +/// dnnl_memory_desc_destroy(data_in_ncdhw); +/// dnnl_memory_desc_destroy(data_in_ndhwc); +/// ~~~ +/// +/// Memory format tags can be further divided into two categories: +/// - Domain-agnostic names, i.e. names the do not depend on the tensor usage +/// in the specific primitive. These names use letters from `a` to `l` to +/// denote logical dimension from 1 to 12, and form the order in which the +/// dimensions are laid in memory. For instance, #dnnl_ab is used to denote +/// 2D tensor where the second logical dimension (aka `b`) is the innermost, +/// i.e. has stride = 1, and the first logical dimension (`a`) laid out in +/// memory with stride equal to the size of second dimension. On the other +/// hand, #dnnl_ba is just transposed version of the same tensor: the +/// first dimension (`a`) becomes the innermost one. +/// - Domain-specific names, i.e. names that make sense only in the context of +/// a certain domain, such as CNN. This names are just aliases to the +/// corresponding domain-agnostic tags and used mostly for the convenience. +/// For example, #dnnl_nc is used to denote 2D CNN activations tensor +/// memory format, where channels are the innermost dimension and batch is an +/// outermost one. Moreover, #dnnl_nc is just an alias to #dnnl_ab, +/// since for oneDNN CNN primitives the logical dimensions of +/// activations tensors come in order: batch, channels, spatial. +/// In other words, batch corresponds to the first logical dimension (`a`), +/// channels correspond to the second one (`b`). +/// +/// The following domain-specific notation applies to memory format tags: +/// - @c 'n' denotes the mini-batch dimension +/// - @c 'c' denotes a channels dimension +/// - When there are multiple channel dimensions (for example, in convolution +/// weights tensor), @c 'i' and @c 'o' denote dimensions of input and output +/// channels +/// - @c 'd', @c 'h', and @c 'w' denote spatial depth, height, and width +/// respectively +/// +/// Upper-case letters indicate that the data is laid out in blocks for a +/// particular dimension. In such cases, the format name contains both upper- +/// and lower-case letters for that dimension with a lower-case letter preceded +/// by the block size. For example: #dnnl_nChw8c describes a format where the +/// outermost dimension is mini-batch, followed by the channel block number, +/// followed by the spatial height and width, and finally followed by 8-element +/// channel blocks. +/// +/// @sa @ref dev_guide_understanding_memory_formats +typedef enum { + /// Undefined memory format tag + dnnl_format_tag_undef = 0, + /// Undefined memory format tag. + /// The primitive selects a format automatically. + dnnl_format_tag_any, + + // Semantic agnostic section + // The physical order of dimensions is defined by the permutation of the + // characters, assuming that ab..z defines the natural order. + + // Plain formats + + dnnl_a, ///< plain 1D tensor + dnnl_ab, ///< plain 2D tensor + dnnl_abc, ///< plain 3D tensor + dnnl_abcd, ///< plain 4D tensor + dnnl_abcde, ///< plain 5D tensor + dnnl_abcdef, ///< plain 6D tensor + dnnl_abcdefg, ///< plain 7D tensor + dnnl_abcdefgh, ///< plain 8D tensor + dnnl_abcdefghi, ///< plain 9D tensor + dnnl_abcdefghij, ///< plain 10D tensor + dnnl_abcdefghijk, ///< plain 11D tensor + dnnl_abcdefghijkl, ///< plain 12D tensor + + // Permuted plain formats + + dnnl_ba, ///< permuted 2D tensor + dnnl_acb, ///< permuted 3D tensor + dnnl_bac, ///< permuted 3D tensor + dnnl_bca, ///< permuted 3D tensor + dnnl_cab, ///< permuted 3D tensor + dnnl_cba, ///< permuted 3D tensor + dnnl_abdc, ///< permuted 4D tensor + dnnl_acbd, ///< permuted 4D tensor + dnnl_acdb, ///< permuted 4D tensor + dnnl_adbc, ///< permuted 4D tensor + dnnl_adcb, ///< permuted 4D tensor + dnnl_bacd, ///< permuted 4D tensor + dnnl_bcda, ///< permuted 4D tensor + dnnl_cdab, ///< permuted 4D tensor + dnnl_cdba, ///< permuted 4D tensor + dnnl_dcab, ///< permuted 4D tensor + dnnl_abced, ///< permuted 5D tensor + dnnl_abdec, ///< permuted 5D tensor + dnnl_acbde, ///< permuted 5D tensor + dnnl_acdeb, ///< permuted 5D tensor + dnnl_adecb, ///< permuted 5D tensor + dnnl_bacde, ///< permuted 5D tensor + dnnl_bcdea, ///< permuted 5D tensor + dnnl_cdeab, ///< permuted 5D tensor + dnnl_cdeba, ///< permuted 5D tensor + dnnl_decab, ///< permuted 5D tensor + dnnl_abcdfe, ///< permuted 6D tensor + dnnl_abdefc, ///< permuted 6D tensor + dnnl_abdfce, ///< permuted 6D tensor + dnnl_acbdef, ///< permuted 6D tensor + dnnl_adefcb, ///< permuted 6D tensor + dnnl_defcab, ///< permuted 6D tensor + dnnl_abcdegf, ///< permuted 7D tensor + dnnl_abcdefhg, ///< permuted 8D tensor + dnnl_abcdefgih, ///< permuted 9D tensor + dnnl_abcdefghji, ///< permuted 10D tensor + dnnl_abcdefghikj, ///< permuted 11D tensor + dnnl_abcdefghijlk, ///< permuted 12D tensor + + // Opaque blocked formats + + dnnl_Abc16a, + dnnl_ABc16a16b, + dnnl_ABc32a32b, + dnnl_ABc4a4b, + /// 3D tensor blocked by 2nd dimension with block size 16 + dnnl_aBc16b, + dnnl_ABc16b16a, + dnnl_Abc4a, + /// 3D tensor blocked by 2nd dimension with block size 32 + dnnl_aBc32b, + /// 3D tensor blocked by 2nd dimension with block size 4 + dnnl_aBc4b, + dnnl_ABc4b16a4b, + dnnl_ABc2b8a4b, + dnnl_ABc16b16a4b, + dnnl_ABc16b16a2b, + dnnl_ABc4b4a, + dnnl_ABc8a16b2a, + dnnl_ABc8a8b, + dnnl_ABc8a4b, + /// 3D tensor blocked by 2nd dimension with block size 8 + dnnl_aBc8b, + dnnl_ABc8b16a2b, + dnnl_BAc8a16b2a, + dnnl_ABc8b8a, + dnnl_Abcd16a, + dnnl_Abcd8a, + dnnl_ABcd16a16b, + dnnl_Abcd32a, + dnnl_ABcd32a32b, + /// 4D tensor blocked by 2nd dimension with block size 16 + dnnl_aBcd16b, + dnnl_ABcd16b16a, + dnnl_aBCd16b16c, + dnnl_aBCd16c16b, + dnnl_Abcd4a, + /// 4D tensor blocked by 2nd dimension with block size 32 + dnnl_aBcd32b, + /// 4D tensor blocked by 2nd dimension with block size 4 + dnnl_aBcd4b, + dnnl_ABcd4b16a4b, + dnnl_ABcd16b16a4b, + dnnl_ABcd16b16a2b, + dnnl_ABcd4b4a, + dnnl_ABcd4a4b, + dnnl_aBCd2c4b2c, + dnnl_aBCd4b8c2b, + dnnl_aBCd4c16b4c, + dnnl_aBCd2c8b4c, + dnnl_aBCd16c16b4c, + dnnl_aBCd16c16b2c, + dnnl_aBCd4c4b, + dnnl_aBCd4b4c, + dnnl_ABcd8a16b2a, + dnnl_ABcd2b8a4b, + dnnl_ABcd8a8b, + dnnl_ABcd8a4b, + /// 4D tensor blocked by 2nd dimension with block size 8 + dnnl_aBcd8b, + dnnl_aBCd4c8b2c, + dnnl_ABcd8b16a2b, + dnnl_aBCd8b16c2b, + dnnl_BAcd8a16b2a, + /// 4D tensor blocked by 1st and 2nd dimension with block size 8 + dnnl_ABcd8b8a, + dnnl_aBCd8b8c, + dnnl_aBCd8b4c, + dnnl_aBCd8c16b2c, + dnnl_ABcde8a16b2a, + dnnl_aCBd8b16c2b, + dnnl_aBCd8c8b, + dnnl_Abcde16a, + dnnl_Abcde32a, + dnnl_ABcde16a16b, + dnnl_BAcde8a16b2a, + /// 4D tensor blocked by 3rd dimension with block size 4 + dnnl_aBCd2b4c2b, + /// 5D tensor blocked by 1st dimension with block size 16 + dnnl_ABcde4b16a4b, + /// 5D tensor blocked by 1st dimension with block size 8 + dnnl_ABcde2b8a4b, + /// 5D tensor blocked by 2nd dimension with block size 16 + dnnl_aBcde16b, + dnnl_ABcde16b16a, + dnnl_aBCde16b16c, + dnnl_aBCde16c16b, + dnnl_aBCde2c8b4c, + dnnl_Abcde4a, + /// 5D tensor blocked by 2nd dimension with block size 32 + dnnl_aBcde32b, + /// 5D tensor blocked by 2nd dimension with block size 4 + dnnl_aBcde4b, + dnnl_ABcde4b4a, + dnnl_ABcde4a4b, + dnnl_aBCde4b4c, + dnnl_aBCde2c4b2c, + dnnl_aBCde4b8c2b, + dnnl_aBCde4c16b4c, + dnnl_aBCde16c16b4c, + dnnl_aBCde16c16b2c, + dnnl_aBCde4c4b, + dnnl_Abcde8a, + dnnl_ABcde8a8b, + dnnl_ABcde8a4b, + dnnl_BAcde16b16a, + /// 5D tensor blocked by 2nd dimension with block size 8 + dnnl_aBcde8b, + dnnl_ABcde8b16a2b, + dnnl_aBCde8b16c2b, + dnnl_aBCde4c8b2c, + dnnl_aCBde8b16c2b, + dnnl_ABcde8b8a, + dnnl_ABcde32a32b, + dnnl_aBCde8b8c, + dnnl_aBCde8b4c, + dnnl_ABc4a8b8a4b, + dnnl_ABcd4a8b8a4b, + dnnl_ABcde4a8b8a4b, + dnnl_BAc4b8a8b4a, + dnnl_BAcd4b8a8b4a, + dnnl_BAcde4b8a8b4a, + dnnl_ABcd2a8b8a2b, + dnnl_aBCd4b8c8b4c, + dnnl_aBCde4b8c8b4c, + dnnl_aBCde2b8c8b2c, + dnnl_aBCde8c16b2c, + dnnl_aBCde8c8b, + /// 5D tensor blocked by 3rd dimension with block size 4 + dnnl_aBCde2b4c2b, + /// 6D tensor blocked by 2nd dimension with block size 16 + dnnl_aBcdef16b, + dnnl_aBCdef16b16c, + dnnl_aBCdef16c16b, + dnnl_aBCdef4c16b4c, + /// 6D tensor blocked by 2nd dimension with block size 8 + dnnl_aBCdef2c8b4c, + dnnl_aBCdef4c8b2c, + /// 6D tensor blocked by 3rd dimension with block size 4 + dnnl_aBCdef2b4c2b, + /// 6D tensor blocked by 2nd dimension with block size 4 + dnnl_aBcdef4b, + dnnl_aBCdef4c4b, + dnnl_aBCdef4b4c, + dnnl_aBCdef2c4b2c, + dnnl_aBCdef4b8c2b, + dnnl_aBCdef8b8c, + dnnl_aBCdef8b4c, + dnnl_aBCdef8c16b2c, + dnnl_aBCdef4b8c8b4c, + dnnl_aBCdef8b16c2b, + dnnl_aCBdef8b16c2b, + dnnl_aBCdef8c8b, + dnnl_aBdc16b, + dnnl_aBdC16b2c, + dnnl_aBdC16b4c, + dnnl_aBdc4b, + dnnl_aBdc8b, + dnnl_aBdec16b, + dnnl_aBdeC16b2c, + dnnl_aBdeC16b4c, + dnnl_aBdec32b, + dnnl_aBdec4b, + dnnl_aBdec8b, + dnnl_aBdefc16b, + dnnl_aBdefC16b2c, + dnnl_aCBdef16c16b, + dnnl_aBdefc4b, + dnnl_aBdefc8b, + dnnl_Abcdef16a, + dnnl_Abcdef32a, + dnnl_aBedc16b, + dnnl_Acb16a, + dnnl_AcB16a2b, + dnnl_AcB16a4b, + dnnl_Acb4a, + dnnl_Acb8a, + dnnl_aCBd16b16c, + dnnl_aCBd16c16b, + dnnl_aCBde16b16c, + dnnl_aCBde16c16b, + dnnl_Acdb16a, + dnnl_AcdB16a2b, + dnnl_AcdB16a4b, + dnnl_Acdb32a, + dnnl_Acdb4a, + dnnl_Acdb8a, + dnnl_Acdeb16a, + dnnl_AcdeB16a2b, + dnnl_Acdeb4a, + dnnl_Acdeb8a, + dnnl_Adcb16a, + dnnl_BAc16a16b, + dnnl_BAc16b16a, + dnnl_BAcd16a16b, + dnnl_BAcd16b16a, + dnnl_aCBd4c8b8c4b, + dnnl_aCBde4c8b8c4b, + dnnl_aCBdef4c8b8c4b, + dnnl_BAcde16a16b, + dnnl_aCBdef16b16c, + dnnl_ABc16b32a, + dnnl_ABc16b64a, + dnnl_ABc4b32a4b, + dnnl_ABc4b64a4b, + dnnl_ABc8b32a2b, + dnnl_ABc8b64a2b, + dnnl_AB16b16a, + dnnl_AB16b32a, + dnnl_AB16b64a, + dnnl_AB8b16a2b, + dnnl_AB8b32a2b, + dnnl_AB8b64a2b, + dnnl_AB4b16a4b, + dnnl_AB4b32a4b, + dnnl_AB4b64a4b, + dnnl_AB16b16a4b, + dnnl_ABcd16b32a, + dnnl_ABcd16b64a, + dnnl_ABcd4b32a4b, + dnnl_ABcd4b64a4b, + dnnl_ABcd8b32a2b, + dnnl_ABcd8b64a2b, + dnnl_ABcde4b32a4b, + dnnl_ABcde4b64a4b, + dnnl_ABcde16b16a4b, + dnnl_ABcde16b16a2b, + dnnl_ABcde16b32a, + dnnl_ABcde16b64a, + dnnl_ABcde8b32a2b, + dnnl_ABcde8b64a2b, + dnnl_aBCdef16c16b4c, + dnnl_aBCdef16c16b2c, + dnnl_AB32a32b8a4b, + dnnl_AB8a4b, + dnnl_AB32a32b8a2b, + dnnl_AB8a2b, + dnnl_abDc32d, + dnnl_abDC32d4c, + dnnl_abdEc32e, + dnnl_abdEC32e2c, + dnnl_abdEC32e4c, + dnnl_aBdefC16b4c, + dnnl_AcdeB16a4b, + dnnl_ABcd16a16b2a, + dnnl_ABc16a16b2a, + dnnl_aBCd16b16c2b, + dnnl_aBCde16b16c2b, + dnnl_Acb32a, + dnnl_AcB32a2b, + dnnl_AcB32a4b, + dnnl_Acb48a, + dnnl_AcB48a2b, + dnnl_AcB48a4b, + dnnl_Acb64a, + dnnl_AcB64a2b, + dnnl_AcB64a4b, + dnnl_cBa2b, + dnnl_cBa4b, + dnnl_aBdc32b, + dnnl_aBdC32b2c, + dnnl_aBdC32b4c, + dnnl_aBdc48b, + dnnl_aBdC48b2c, + dnnl_aBdC48b4c, + dnnl_aBdc64b, + dnnl_aBdC64b2c, + dnnl_aBdC64b4c, + dnnl_adCb2c, + dnnl_adCb4c, + dnnl_AcdB32a2b, + dnnl_AcdB32a4b, + dnnl_Acdb48a, + dnnl_AcdB48a2b, + dnnl_AcdB48a4b, + dnnl_Acdb64a, + dnnl_AcdB64a2b, + dnnl_AcdB64a4b, + dnnl_cdBa2b, + dnnl_cdBa4b, + dnnl_aBdeC32b2c, + dnnl_aBdeC32b4c, + dnnl_aBdec48b, + dnnl_aBdeC48b2c, + dnnl_aBdeC48b4c, + dnnl_aBdec64b, + dnnl_aBdeC64b2c, + dnnl_aBdeC64b4c, + dnnl_adeCb2c, + dnnl_adeCb4c, + dnnl_Acdeb32a, + dnnl_AcdeB32a2b, + dnnl_AcdeB32a4b, + dnnl_Acdeb48a, + dnnl_AcdeB48a2b, + dnnl_AcdeB48a4b, + dnnl_Acdeb64a, + dnnl_AcdeB64a2b, + dnnl_AcdeB64a4b, + dnnl_cdeBa2b, + dnnl_cdeBa4b, + dnnl_aBdefc32b, + dnnl_aBdefC32b2c, + dnnl_aBdefC32b4c, + dnnl_aBdefc48b, + dnnl_aBdefC48b2c, + dnnl_aBdefC48b4c, + dnnl_aBdefc64b, + dnnl_aBdefC64b2c, + dnnl_aBdefC64b4c, + dnnl_adefCb2c, + dnnl_adefCb4c, + dnnl_AB16b32a4b, + dnnl_AB16b48a4b, + dnnl_AB16b64a4b, + dnnl_AB16b16a2b, + dnnl_AB16b32a2b, + dnnl_AB16b48a2b, + dnnl_AB16b64a2b, + dnnl_ABc16b32a4b, + dnnl_ABc16b48a4b, + dnnl_ABc16b64a4b, + dnnl_ABc16b32a2b, + dnnl_ABc16b48a2b, + dnnl_ABc16b64a2b, + dnnl_ABcd16b32a4b, + dnnl_ABcd16b48a4b, + dnnl_ABcd16b64a4b, + dnnl_ABcd16b32a2b, + dnnl_ABcd16b48a2b, + dnnl_ABcd16b64a2b, + dnnl_ABcde16b32a4b, + dnnl_ABcde16b48a4b, + dnnl_ABcde16b64a4b, + dnnl_ABcde16b32a2b, + dnnl_ABcde16b48a2b, + dnnl_ABcde16b64a2b, + dnnl_ABc32a16b, + dnnl_ABcd32a16b, + dnnl_ABcde32a16b, + dnnl_AB48a16b, + dnnl_AB48a32b, + dnnl_ABc40a16b, + dnnl_ABc40a32b, + dnnl_aBC48b16c, + dnnl_aBC48b32c, + dnnl_ABcd40a16b, + dnnl_ABcd40a32b, + dnnl_abCd32c, + dnnl_abdCe32c, + dnnl_abdCE32c2e, + dnnl_BA16a16b2a, + dnnl_BA16a32b2a, + dnnl_BA16a48b2a, + dnnl_BA16a64b2a, + dnnl_BA16a16b4a, + dnnl_BA16a32b4a, + dnnl_BA16a48b4a, + dnnl_BA16a64b4a, + dnnl_ABcd8a2b, + dnnl_aBdeC16c16b2c, + dnnl_aBdeC16c16b4c, + dnnl_aBdefC16c16b2c, + dnnl_AcB16b16a2b, + dnnl_AcB16b16a4b, + dnnl_AcdB16b16a2b, + dnnl_AcdB16b16a4b, + dnnl_AcdeB16b16a2b, + dnnl_aBdefC16c16b4c, + dnnl_AcdeB16b16a4b, + dnnl_AcB16b32a2b, + dnnl_AcB16b32a4b, + dnnl_AcB16b48a2b, + dnnl_AcB16b48a4b, + dnnl_AcB16b64a2b, + dnnl_AcB16b64a4b, + dnnl_aBdC16c16b2c, + dnnl_aBdC16c16b4c, + dnnl_aBdC16c32b2c, + dnnl_aBdC16c32b4c, + dnnl_aBdC16c48b2c, + dnnl_aBdC16c48b4c, + dnnl_aBdC16c64b2c, + dnnl_aBdC16c64b4c, + dnnl_AcdB16b32a2b, + dnnl_AcdB16b32a4b, + dnnl_AcdB16b48a2b, + dnnl_AcdB16b48a4b, + dnnl_AcdB16b64a2b, + dnnl_AcdB16b64a4b, + dnnl_aBdeC16c32b2c, + dnnl_aBdeC16c32b4c, + dnnl_aBdeC16c48b2c, + dnnl_aBdeC16c48b4c, + dnnl_aBdeC16c64b2c, + dnnl_aBdeC16c64b4c, + dnnl_AcdeB16b32a2b, + dnnl_AcdeB16b32a4b, + dnnl_AcdeB16b48a2b, + dnnl_AcdeB16b48a4b, + dnnl_AcdeB16b64a2b, + dnnl_AcdeB16b64a4b, + dnnl_aBdefC16c32b2c, + dnnl_aBdefC16c32b4c, + dnnl_aBdefC16c48b2c, + dnnl_aBdefC16c48b4c, + dnnl_aBdefC16c64b2c, + dnnl_aBdefC16c64b4c, + dnnl_decbA16a, + dnnl_ABc4a2b, + dnnl_ABc8a2b, + dnnl_aBCd8b2c, + dnnl_ABcde4a2b, + dnnl_ABcde8a2b, + dnnl_ABcde40a16b, + dnnl_ABcde40a32b, + dnnl_aBCde8b2c, + dnnl_ABcde4a8b8a2b, + dnnl_ABcd4a8b8a2b, + dnnl_ABc4a8b8a2b, + dnnl_aBCdef4b8c8b2c, + dnnl_aBCde4b8c8b2c, + dnnl_aBCd4b8c8b2c, + dnnl_BAcde4b8a8b2a, + dnnl_BAcd4b8a8b2a, + dnnl_BAc4b8a8b2a, + dnnl_aCBdef4c8b8c2b, + dnnl_aCBde4c8b8c2b, + dnnl_aCBd4c8b8c2b, + dnnl_aBCdef8b2c, + dnnl_AB32a16b, + dnnl_AB32a32b, + dnnl_BA4b8a8b2a, + dnnl_BA4b8a8b4a, + dnnl_aBC32b16c, + dnnl_aBC32b32c, + dnnl_aCB4c8b8c2b, + dnnl_aCB4c8b8c4b, + dnnl_ABcd4a2b, + dnnl_ABc2b8a16b4a, + dnnl_ABcd2b8a16b4a, + dnnl_ABcde2b8a16b4a, + dnnl_ABc2a8b16a4b, + dnnl_ABc2a8b16a2b, + dnnl_ABc2b32a8b, + dnnl_ABcd2a8b16a4b, + dnnl_ABcd2a8b16a2b, + dnnl_aCBd2c8b16c2b, + dnnl_ABcd2b32a8b, + dnnl_aBCd2c8b16c2b, + dnnl_ABcde2a8b16a4b, + dnnl_ABcde2a8b16a2b, + dnnl_aCBde2c8b16c2b, + dnnl_ABcde2b32a8b, + dnnl_aBC2b8c16b2c, + dnnl_aBCd2b8c16b2c, + dnnl_aBCde2b8c16b2c, + dnnl_aBCdef2b8c16b2c, + dnnl_BAcde2b8a16b4a, + dnnl_BAcd2b8a16b4a, + dnnl_BAc2b8a16b4a, + dnnl_BAcde2b8a16b2a, + dnnl_BAcd2b8a16b2a, + dnnl_BAc2b8a16b2a, + dnnl_aBCde2c8b16c2b, + dnnl_aBCdef2c8b16c2b, + dnnl_aCBdef2c8b16c2b, + dnnl_aBCd2b8c16b4c, + dnnl_aBCde2b8c16b4c, + dnnl_BA4b8a16b2a, + dnnl_BA4b8a16b4a, + dnnl_aCB4c8b16c2b, + dnnl_aCB4c8b16c4b, + dnnl_BA16a16b, + dnnl_BA16a32b, + dnnl_BA16a48b, + dnnl_BA16a64b, + dnnl_aCB16c2b, + dnnl_aCB16c4b, + dnnl_BA16b2a, + dnnl_BA16b4a, + dnnl_aBC16b16c, + dnnl_aBC16b32c, + dnnl_AB16a16b, + dnnl_AB16a32b, + dnnl_ABcde16a16b2a, + dnnl_aBCdef16b16c2b, + dnnl_Acedb16a, + dnnl_aBdfec16b, + dnnl_abdEC64e2c, + dnnl_abdEC64e4c, + dnnl_aCB16b16c, + dnnl_aCB16b32c, + dnnl_aCB16b48c, + dnnl_aCB16b64c, + dnnl_aCB16b16c2b, + dnnl_aCB16b32c2b, + dnnl_aCB16b48c2b, + dnnl_aCB16b64c2b, + dnnl_aCB16b16c4b, + dnnl_aCB16b32c4b, + dnnl_aCB16b48c4b, + dnnl_aCB16b64c4b, + dnnl_abCd4c, + dnnl_abCde4c, + dnnl_abCdef4c, + dnnl_abCde32c, + dnnl_abCdef32c, + dnnl_ABcd16a32b, + dnnl_decbA8a, + dnnl_aCdefB16b32c2b, + dnnl_aCdefB16b32c4b, + dnnl_aCdefB16b48c2b, + dnnl_aCdefB16b48c4b, + dnnl_aCdefB16b64c2b, + dnnl_aCdefB16b64c4b, + dnnl_BcdeA16a32b2a, + dnnl_BcdeA16a32b4a, + dnnl_BcdeA16a48b2a, + dnnl_BcdeA16a48b4a, + dnnl_BcdeA16a64b2a, + dnnl_BcdeA16a64b4a, + dnnl_aCdefb32c, + dnnl_aCdefB32c2b, + dnnl_aCdefB32c4b, + dnnl_aCdefb48c, + dnnl_aCdefB48c2b, + dnnl_aCdefB48c4b, + dnnl_aCdefb64c, + dnnl_aCdefB64c2b, + dnnl_aCdefB64c4b, + dnnl_Bcdea32b, + dnnl_BcdeA32b2a, + dnnl_BcdeA32b4a, + dnnl_Bcdea48b, + dnnl_BcdeA48b2a, + dnnl_BcdeA48b4a, + dnnl_Bcdea64b, + dnnl_BcdeA64b2a, + dnnl_BcdeA64b4a, + dnnl_Bca32b, + dnnl_BcA32b2a, + dnnl_BcA32b4a, + dnnl_Bca48b, + dnnl_BcA48b2a, + dnnl_BcA48b4a, + dnnl_Bca64b, + dnnl_BcA64b2a, + dnnl_BcA64b4a, + dnnl_aCdb32c, + dnnl_aCdB32c2b, + dnnl_aCdB32c4b, + dnnl_aCdb48c, + dnnl_aCdB48c2b, + dnnl_aCdB48c4b, + dnnl_aCdb64c, + dnnl_aCdB64c2b, + dnnl_aCdB64c4b, + dnnl_BcA16a16b2a, + dnnl_BcA16a16b4a, + dnnl_BcdA16a16b2a, + dnnl_BcdA16a16b4a, + dnnl_BcdeA16a16b2a, + dnnl_BcdeA16a16b4a, + dnnl_aCdB16b16c2b, + dnnl_aCdB16b16c4b, + dnnl_aCdeB16b16c2b, + dnnl_aCdeB16b16c4b, + dnnl_aCdefB16b16c2b, + dnnl_aCdefB16b16c4b, + dnnl_BcA16a32b2a, + dnnl_BcA16a32b4a, + dnnl_BcA16a48b2a, + dnnl_BcA16a48b4a, + dnnl_BcA16a64b2a, + dnnl_BcA16a64b4a, + dnnl_aCdB16b32c2b, + dnnl_aCdB16b32c4b, + dnnl_aCdB16b48c2b, + dnnl_aCdB16b48c4b, + dnnl_aCdB16b64c2b, + dnnl_aCdB16b64c4b, + dnnl_BcdA16a32b2a, + dnnl_BcdA16a32b4a, + dnnl_BcdA16a48b2a, + dnnl_BcdA16a48b4a, + dnnl_BcdA16a64b2a, + dnnl_BcdA16a64b4a, + dnnl_aCdeB16b32c2b, + dnnl_aCdeB16b32c4b, + dnnl_aCdeB16b48c2b, + dnnl_aCdeB16b48c4b, + dnnl_aCdeB16b64c2b, + dnnl_aCdeB16b64c4b, + dnnl_Bca16b, + dnnl_BcA16b2a, + dnnl_BcA16b4a, + dnnl_Bcda16b, + dnnl_BcdA16b2a, + dnnl_BcdA16b4a, + dnnl_Bcdea16b, + dnnl_BcdeA16b2a, + dnnl_BcdeA16b4a, + dnnl_aCdb16c, + dnnl_aCdB16c2b, + dnnl_aCdB16c4b, + dnnl_aCdeb16c, + dnnl_aCdeB16c2b, + dnnl_aCdeB16c4b, + dnnl_aCdefb16c, + dnnl_aCdefB16c2b, + dnnl_aCdefB16c4b, + dnnl_Bcda32b, + dnnl_BcdA32b2a, + dnnl_BcdA32b4a, + dnnl_Bcda48b, + dnnl_BcdA48b2a, + dnnl_BcdA48b4a, + dnnl_Bcda64b, + dnnl_BcdA64b2a, + dnnl_BcdA64b4a, + dnnl_aCdeb32c, + dnnl_aCdeB32c2b, + dnnl_aCdeB32c4b, + dnnl_aCdeb48c, + dnnl_aCdeB48c2b, + dnnl_aCdeB48c4b, + dnnl_aCdeb64c, + dnnl_aCdeB64c2b, + dnnl_aCdeB64c4b, + dnnl_Acb24a, + dnnl_Acdb24a, + dnnl_Acdeb24a, + dnnl_aBdc24b, + dnnl_aBdec24b, + dnnl_aBdefc24b, + dnnl_abDc16d, + dnnl_abdEc16e, + dnnl_abdCe16c, + dnnl_AcB24a2b, + dnnl_AcdB24a2b, + dnnl_AcdeB24a2b, + dnnl_aBdC24b2c, + dnnl_aBdeC24b2c, + dnnl_aBdefC24b2c, + dnnl_AcB8a2b, + dnnl_AcdB8a2b, + dnnl_AcdeB8a2b, + dnnl_aBdC8b2c, + dnnl_aBdeC8b2c, + dnnl_aBdefC8b2c, + dnnl_AB8b32a, + dnnl_ABc8b32a, + dnnl_ABcd8b32a, + dnnl_ABcde8b32a, + dnnl_AB8b24a, + dnnl_ABc8b24a, + dnnl_ABcd8b24a, + dnnl_ABcde8b24a, + dnnl_AB8b16a, + dnnl_ABc8b16a, + dnnl_ABcd8b16a, + dnnl_ABcde8b16a, + dnnl_AB8b8a, + dnnl_AB4b8a4b, + dnnl_AB4b24a4b, + dnnl_ABc4b8a4b, + dnnl_ABc4b24a4b, + dnnl_ABcd4b8a4b, + dnnl_ABcd4b24a4b, + dnnl_ABcde4b8a4b, + dnnl_ABcde4b24a4b, + dnnl_AB8b24a2b, + dnnl_ABc8b24a2b, + dnnl_ABcd8b24a2b, + dnnl_ABcde8b24a2b, + dnnl_AB8b8a2b, + dnnl_ABc8b8a2b, + dnnl_ABcd8b8a2b, + dnnl_ABcde8b8a2b, + dnnl_AcB24a4b, + dnnl_AcdB24a4b, + dnnl_AcdeB24a4b, + dnnl_aBdC24b4c, + dnnl_aBdeC24b4c, + dnnl_aBdefC24b4c, + dnnl_AcB8a4b, + dnnl_AcdB8a4b, + dnnl_AcdeB8a4b, + dnnl_aBdC8b4c, + dnnl_aBdeC8b4c, + dnnl_aBdefC8b4c, + dnnl_Bca8b, + dnnl_BcA8b2a, + dnnl_Bcda8b, + dnnl_BcdA8b2a, + dnnl_Bcdea8b, + dnnl_BcdeA8b2a, + dnnl_aCdb8c, + dnnl_aCdB8c2b, + dnnl_aCdeb8c, + dnnl_aCdeB8c2b, + dnnl_aCdefb8c, + dnnl_aCdefB8c2b, + dnnl_Bca24b, + dnnl_BcA24b2a, + dnnl_Bcda24b, + dnnl_BcdA24b2a, + dnnl_Bcdea24b, + dnnl_BcdeA24b2a, + dnnl_aCdb24c, + dnnl_aCdB24c2b, + dnnl_aCdeb24c, + dnnl_aCdeB24c2b, + dnnl_aCdefb24c, + dnnl_aCdefB24c2b, + dnnl_BcA8b4a, + dnnl_BcdA8b4a, + dnnl_BcdeA8b4a, + dnnl_aCdB8c4b, + dnnl_aCdeB8c4b, + dnnl_aCdefB8c4b, + dnnl_BcA24b4a, + dnnl_BcdA24b4a, + dnnl_BcdeA24b4a, + dnnl_aCdB24c4b, + dnnl_aCdeB24c4b, + dnnl_aCdefB24c4b, + dnnl_AB16b48a, + dnnl_ABc16b48a, + dnnl_ABcd16b48a, + dnnl_ABcde16b48a, + dnnl_ABc16a4b, + dnnl_ABcd16a4b, + dnnl_ABcde16a4b, + dnnl_defcbA16a, + dnnl_defcbA8a, + dnnl_AcB16b64a, + dnnl_AcdB16b64a, + dnnl_AcdeB16b64a, + dnnl_AcB16b48a, + dnnl_AcdB16b48a, + dnnl_AcdeB16b48a, + dnnl_AcB16b32a, + dnnl_AcdB16b32a, + dnnl_AcdeB16b32a, + dnnl_AcB16b16a, + dnnl_AcdB16b16a, + dnnl_AcdeB16b16a, + dnnl_AcB8b32a, + dnnl_AcdB8b32a, + dnnl_AcdeB8b32a, + dnnl_AcB8b24a, + dnnl_AcdB8b24a, + dnnl_AcdeB8b24a, + dnnl_AcB8b16a, + dnnl_AcdB8b16a, + dnnl_AcdeB8b16a, + dnnl_AcB8b8a, + dnnl_AcdB8b8a, + dnnl_AcdeB8b8a, + dnnl_AcB8b64a2b, + dnnl_AcdB8b64a2b, + dnnl_AcdeB8b64a2b, + dnnl_AcB8b32a2b, + dnnl_AcdB8b32a2b, + dnnl_AcdeB8b32a2b, + dnnl_AcB8b24a2b, + dnnl_AcdB8b24a2b, + dnnl_AcdeB8b24a2b, + dnnl_AcB8b16a2b, + dnnl_AcdB8b16a2b, + dnnl_AcdeB8b16a2b, + dnnl_AcB8b8a2b, + dnnl_AcdB8b8a2b, + dnnl_AcdeB8b8a2b, + dnnl_AcB4b64a4b, + dnnl_AcdB4b64a4b, + dnnl_AcdeB4b64a4b, + dnnl_AcB4b32a4b, + dnnl_AcdB4b32a4b, + dnnl_AcdeB4b32a4b, + dnnl_AcB4b24a4b, + dnnl_AcdB4b24a4b, + dnnl_AcdeB4b24a4b, + dnnl_AcB4b16a4b, + dnnl_AcdB4b16a4b, + dnnl_AcdeB4b16a4b, + dnnl_AcB4b8a4b, + dnnl_AcdB4b8a4b, + dnnl_AcdeB4b8a4b, + dnnl_Ab4a, + dnnl_Ab8a, + dnnl_BA4b4a, + dnnl_BA8b4a, + dnnl_BA2a24b, + dnnl_aCB2b24c, + dnnl_BA2a8b, + dnnl_aCB2b8c, + dnnl_BA8a24b, + dnnl_aCB8b24c, + dnnl_BA8a16b, + dnnl_aCB8b16c, + dnnl_BA8a8b, + dnnl_aCB8b8c, + dnnl_bcad, + dnnl_cabd, + dnnl_dabc, + dnnl_Ab32a, + dnnl_aCBd8b8c, + dnnl_aCBde8b8c, + dnnl_BAc8a8b, + dnnl_BAcd8a8b, + dnnl_BAcde8a8b, + dnnl_aCBdef8b8c, + dnnl_abdEC16e4c, + dnnl_abDC16d4c, + dnnl_BA24b8a, + dnnl_aCB24c8b, + dnnl_abDC24d8c, + dnnl_decbA4a, + dnnl_defcbA4a, + dnnl_abDC8d8c, + dnnl_abDC16d8c, + dnnl_aCB8c8b, + dnnl_aCB16c8b, + dnnl_BA8b8a, + dnnl_BA16b8a, + dnnl_AB2a4b, + dnnl_aCBd4b4c, + dnnl_aCBde4b4c, + dnnl_aCBdef4b4c, + dnnl_BAc4a4b, + dnnl_BAcd4a4b, + dnnl_BAcde4a4b, + + /// Just a sentinel, not real memory format tag. Must be changed after new + /// format tag is added. + dnnl_format_tag_last, + + // Aliases + + /// 1D tensor, an alias to #dnnl_a + dnnl_x = dnnl_a, + /// 2D CNN activations tensor, an alias to #dnnl_ab + dnnl_nc = dnnl_ab, + /// 2D CNN activations tensor, an alias to #dnnl_ba + dnnl_cn = dnnl_ba, + /// 2D RNN statistics tensor, an alias to #dnnl_ab + dnnl_tn = dnnl_ab, + /// 2D RNN statistics tensor, an alias to #dnnl_ba + dnnl_nt = dnnl_ba, + /// 3D CNN activations tensor, an alias to #dnnl_abc + dnnl_ncw = dnnl_abc, + /// 3D CNN activations tensor, an alias to #dnnl_acb + dnnl_nwc = dnnl_acb, + /// 4D CNN activations tensor, an alias to #dnnl_abcd + dnnl_nchw = dnnl_abcd, + /// 4D CNN activations tensor, an alias to #dnnl_acdb + dnnl_nhwc = dnnl_acdb, + /// 4D CNN activations tensor, an alias to #dnnl_bcda + dnnl_chwn = dnnl_bcda, + /// 5D CNN activations tensor, an alias to #dnnl_abcde + dnnl_ncdhw = dnnl_abcde, + /// 5D CNN activations tensor, an alias to #dnnl_acdeb + dnnl_ndhwc = dnnl_acdeb, + + /// 2D CNN weights tensor, an alias to #dnnl_ab + dnnl_oi = dnnl_ab, + /// 2D CNN weights tensor, an alias to #dnnl_ba + dnnl_io = dnnl_ba, + /// 3D CNN weights tensor, an alias to #dnnl_abc + dnnl_oiw = dnnl_abc, + /// 3D CNN weights tensor, an alias to #dnnl_acb + dnnl_owi = dnnl_acb, + /// 3D CNN weights tensor, an alias to #dnnl_cba + dnnl_wio = dnnl_cba, + /// 3D CNN weights tensor, an alias to #dnnl_cab + dnnl_woi = dnnl_cab, + /// 3D CNN weights tensor, an alias to #dnnl_bca + dnnl_iwo = dnnl_bca, + /// 4D CNN weights tensor, an alias to #dnnl_abcd + dnnl_oihw = dnnl_abcd, + /// 4D CNN weights tensor, an alias to #dnnl_cdba + dnnl_hwio = dnnl_cdba, + /// 4D CNN weights tensor, an alias to #dnnl_cdab + dnnl_hwoi = dnnl_cdab, + /// 4D CNN weights tensor, an alias to #dnnl_acdb + dnnl_ohwi = dnnl_acdb, + /// 4D CNN weights tensor, an alias to #dnnl_bcda + dnnl_ihwo = dnnl_bcda, + /// 4D CNN weights tensor, an alias to #dnnl_bacd + dnnl_iohw = dnnl_bacd, + /// 5D CNN weights tensor, an alias to #dnnl_abcde + dnnl_oidhw = dnnl_abcde, + /// 5D CNN weights tensor, an alias to #dnnl_bacde + dnnl_iodhw = dnnl_bacde, + /// 5D CNN weights tensor, an alias to #dnnl_cdeba + dnnl_dhwio = dnnl_cdeba, + /// 5D CNN weights tensor, an alias to #dnnl_cdeab + dnnl_dhwoi = dnnl_cdeab, + /// 5D CNN weights tensor, an alias to #dnnl_acdeb + dnnl_odhwi = dnnl_acdeb, + /// 5D CNN weights tensor, an alias to #dnnl_bcdea + dnnl_idhwo = dnnl_bcdea, + + /// 4D CNN weights tensor (incl. groups), an alias to #dnnl_abcd + dnnl_goiw = dnnl_abcd, + /// 4D CNN weights tensor (incl. groups), an alias to #dnnl_abdc + dnnl_gowi = dnnl_abdc, + /// 4D CNN weights tensor (incl. groups), an alias to #dnnl_dcab + dnnl_wigo = dnnl_dcab, + /// 5D CNN weights tensor (incl. groups), an alias to #dnnl_abcde + dnnl_goihw = dnnl_abcde, + /// 5D CNN weights tensor (incl. groups), an alias to #dnnl_abdec + dnnl_gohwi = dnnl_abdec, + /// 5D CNN weights tensor (incl. groups), an alias to #dnnl_decab + dnnl_hwigo = dnnl_decab, + /// 5D CNN weights tensor (incl. groups), an alias to #dnnl_acbde + dnnl_giohw = dnnl_acbde, + /// 6D CNN weights tensor (incl. groups), an alias to #dnnl_abcdef + dnnl_goidhw = dnnl_abcdef, + /// 6D CNN weights tensor (incl. groups), an alias to #dnnl_abdefc + dnnl_godhwi = dnnl_abdefc, + /// 6D CNN weights tensor (incl. groups), an alias to #dnnl_acbdef + dnnl_giodhw = dnnl_acbdef, + /// 6D CNN weights tensor (incl. groups), an alias to #dnnl_defcab + dnnl_dhwigo = dnnl_defcab, + + /// 3D RNN data tensor in the format (seq_length, batch, input channels), + /// an alias to #dnnl_abc. + dnnl_tnc = dnnl_abc, + /// 3D RNN data tensor in the format (batch, seq_length, input channels), + /// an alias to #dnnl_bac. + dnnl_ntc = dnnl_bac, + /// 4D RNN states tensor in the format (num_layers, num_directions, + /// batch, state channels), an alias to #dnnl_abcd. + dnnl_ldnc = dnnl_abcd, + /// 5D RNN weights tensor in the format (num_layers, num_directions, + /// input_channels, num_gates, output_channels), an alias to #dnnl_abcde. + /// + /// - For LSTM cells, the gates order is input, forget, candidate + /// and output gate. + /// - For GRU cells, the gates order is update, reset and output gate. + dnnl_ldigo = dnnl_abcde, + /// 5D RNN weights tensor in the format (num_layers, num_directions, + /// num_gates, output_channels, input_channels), an alias to #dnnl_abdec. + /// + /// - For LSTM cells, the gates order is input, forget, candidate + /// and output gate. + /// - For GRU cells, the gates order is update, reset and output gate. + dnnl_ldgoi = dnnl_abdec, + /// 4D LSTM projection tensor in the format (num_layers, num_directions, + /// num_channels_in_hidden_state, num_channels_in_recurrent_projection), + /// an alias to #dnnl_abcd. + dnnl_ldio = dnnl_abcd, + /// 4D LSTM projection tensor in the format (num_layers, num_directions, + /// num_channels_in_recurrent_projection, num_channels_in_hidden_state), + /// an alias to #dnnl_abdc. + dnnl_ldoi = dnnl_abdc, + /// 4D RNN bias tensor in the format (num_layers, num_directions, + /// num_gates, output_channels), an alias to #dnnl_abcd. + /// + /// - For LSTM cells, the gates order is input, forget, candidate + /// and output gate. + /// - For GRU cells, the gates order is update, reset and output gate. + dnnl_ldgo = dnnl_abcd, + /// 5D LSTM projection tensor + dnnl_ldOi16o = dnnl_abDc16d, + dnnl_ldOi32o = dnnl_abDc32d, + dnnl_ldOI16o4i = dnnl_abDC16d4c, + dnnl_ldOI32o4i = dnnl_abDC32d4c, + dnnl_ldIo32i = dnnl_abCd32c, + /// 6D RNN weights tensor + dnnl_ldgOi16o = dnnl_abdEc16e, + dnnl_ldgOI16o4i = dnnl_abdEC16e4c, + dnnl_ldgOi32o = dnnl_abdEc32e, + dnnl_ldgOI32o2i = dnnl_abdEC32e2c, + dnnl_ldgOI32o4i = dnnl_abdEC32e4c, + dnnl_ldgOI64o2i = dnnl_abdEC64e2c, + dnnl_ldgOI64o4i = dnnl_abdEC64e4c, + dnnl_ldgIo16i = dnnl_abdCe16c, + dnnl_ldgIo32i = dnnl_abdCe32c, + dnnl_ldgIO32i2o = dnnl_abdCE32c2e, + + // Opaque data types, are not to be used explicitly + + // data + /// 5D CNN activations tensor blocked by channels with block size 32, + /// an alias to #dnnl_aBcde32b + dnnl_nCdhw32c = dnnl_aBcde32b, + /// 5D CNN activations tensor blocked by channels with block size 16, + /// an alias to #dnnl_aBcde16b + dnnl_nCdhw16c = dnnl_aBcde16b, + /// 5D CNN activations tensor blocked by channels with block size 4, + /// an alias to #dnnl_aBcde4b + dnnl_nCdhw4c = dnnl_aBcde4b, + /// 5D CNN activations tensor blocked by channels with block size 8, + /// an alias to #dnnl_aBcde8b + dnnl_nCdhw8c = dnnl_aBcde8b, + /// 4D CNN activations tensor blocked by channels with block size 32, + /// an alias to #dnnl_aBcd32b + dnnl_nChw32c = dnnl_aBcd32b, + /// 4D CNN activations tensor blocked by channels with block size 16, + /// an alias to #dnnl_aBcd16b + dnnl_nChw16c = dnnl_aBcd16b, + /// 4D CNN activations tensor blocked by channels with block size 4, + /// an alias to #dnnl_aBcd4b + dnnl_nChw4c = dnnl_aBcd4b, + /// 4D CNN activations tensor blocked by channels with block size 8, + /// an alias to #dnnl_aBcd8b + dnnl_nChw8c = dnnl_aBcd8b, + /// 3D CNN activations tensor blocked by channels with block size 32, + /// an alias to #dnnl_aBc32b + dnnl_nCw32c = dnnl_aBc32b, + /// 3D CNN activations tensor blocked by channels with block size 16, + /// an alias to #dnnl_aBc16b + dnnl_nCw16c = dnnl_aBc16b, + /// 3D CNN activations tensor blocked by channels with block size 4, + /// an alias to #dnnl_aBc4b + dnnl_nCw4c = dnnl_aBc4b, + /// 3D CNN activations tensor blocked by channels with block size 8, + /// an alias to #dnnl_aBc8b + dnnl_nCw8c = dnnl_aBc8b, + dnnl_NCw16n16c = dnnl_ABc16a16b, + dnnl_NCdhw16n16c = dnnl_ABcde16a16b, + dnnl_NChw16n16c = dnnl_ABcd16a16b, + dnnl_NCw32n16c = dnnl_ABc32a16b, + dnnl_NChw32n16c = dnnl_ABcd32a16b, + dnnl_NChw16n32c = dnnl_ABcd16a32b, + dnnl_NCdhw32n16c = dnnl_ABcde32a16b, + dnnl_NCw32n32c = dnnl_ABc32a32b, + dnnl_NChw32n32c = dnnl_ABcd32a32b, + dnnl_NCdhw32n32c = dnnl_ABcde32a32b, + + // weights, 2D + dnnl_OI16i16o = dnnl_AB16b16a, + dnnl_OI16i32o = dnnl_AB16b32a, + dnnl_OI16i48o = dnnl_AB16b48a, + dnnl_OI16i64o = dnnl_AB16b64a, + dnnl_OI8i8o2i = dnnl_AB8b8a2b, + dnnl_OI8i16o2i = dnnl_AB8b16a2b, + dnnl_OI8i24o2i = dnnl_AB8b24a2b, + dnnl_OI8i32o2i = dnnl_AB8b32a2b, + dnnl_OI8i64o2i = dnnl_AB8b64a2b, + dnnl_OI4i8o4i = dnnl_AB4b8a4b, + dnnl_OI4i16o4i = dnnl_AB4b16a4b, + dnnl_OI4i24o4i = dnnl_AB4b24a4b, + dnnl_OI4i32o4i = dnnl_AB4b32a4b, + dnnl_OI4i64o4i = dnnl_AB4b64a4b, + dnnl_OI16i16o4i = dnnl_AB16b16a4b, + dnnl_OI8i32o = dnnl_AB8b32a, + dnnl_OI8i24o = dnnl_AB8b24a, + dnnl_OI8i16o = dnnl_AB8b16a, + dnnl_OI8i8o = dnnl_AB8b8a, + + // weights, 3D + dnnl_IOw4o4i = dnnl_BAc4a4b, + dnnl_IOw8o8i = dnnl_BAc8a8b, + dnnl_IOw16o16i = dnnl_BAc16a16b, + dnnl_IOw16i16o = dnnl_BAc16b16a, + dnnl_OIw16i16o = dnnl_ABc16b16a, + dnnl_OwI16i16o = dnnl_AcB16b16a, + dnnl_OIw16i32o = dnnl_ABc16b32a, + dnnl_OwI16i32o = dnnl_AcB16b32a, + dnnl_OIw16i48o = dnnl_ABc16b48a, + dnnl_OwI16i48o = dnnl_AcB16b48a, + dnnl_OIw16i64o = dnnl_ABc16b64a, + dnnl_OwI16i64o = dnnl_AcB16b64a, + dnnl_OIw16o16i = dnnl_ABc16a16b, + dnnl_Oiw16o = dnnl_Abc16a, + dnnl_OIw4i8o4i = dnnl_ABc4b8a4b, + dnnl_OwI4i8o4i = dnnl_AcB4b8a4b, + dnnl_OIw4i16o4i = dnnl_ABc4b16a4b, + dnnl_OwI4i16o4i = dnnl_AcB4b16a4b, + dnnl_OIw4i24o4i = dnnl_ABc4b24a4b, + dnnl_OwI4i24o4i = dnnl_AcB4b24a4b, + dnnl_OIw4i32o4i = dnnl_ABc4b32a4b, + dnnl_OwI4i32o4i = dnnl_AcB4b32a4b, + dnnl_OIw4i64o4i = dnnl_ABc4b64a4b, + dnnl_OwI4i64o4i = dnnl_AcB4b64a4b, + dnnl_OIw2i8o4i = dnnl_ABc2b8a4b, + dnnl_OIw16i16o4i = dnnl_ABc16b16a4b, + dnnl_OIw16i16o2i = dnnl_ABc16b16a2b, + dnnl_OIw16o16i2o = dnnl_ABc16a16b2a, + dnnl_OIw4i4o = dnnl_ABc4b4a, + dnnl_OIw4o4i = dnnl_ABc4a4b, + dnnl_Oiw4o = dnnl_Abc4a, + dnnl_OIw8i8o2i = dnnl_ABc8b8a2b, + dnnl_OwI8i8o2i = dnnl_AcB8b8a2b, + dnnl_OIw8i16o2i = dnnl_ABc8b16a2b, + dnnl_OwI8i16o2i = dnnl_AcB8b16a2b, + dnnl_OIw8i24o2i = dnnl_ABc8b24a2b, + dnnl_OwI8i24o2i = dnnl_AcB8b24a2b, + dnnl_OIw8i32o2i = dnnl_ABc8b32a2b, + dnnl_OwI8i32o2i = dnnl_AcB8b32a2b, + dnnl_OIw8i64o2i = dnnl_ABc8b64a2b, + dnnl_OwI8i64o2i = dnnl_AcB8b64a2b, + dnnl_OIw8i8o = dnnl_ABc8b8a, + dnnl_OwI8i8o = dnnl_AcB8b8a, + dnnl_OIw8o16i2o = dnnl_ABc8a16b2a, + dnnl_IOw8o16i2o = dnnl_BAc8a16b2a, + dnnl_OIw8o8i = dnnl_ABc8a8b, + dnnl_OIw8o4i = dnnl_ABc8a4b, + dnnl_Owi16o = dnnl_Acb16a, + dnnl_OwI16o2i = dnnl_AcB16a2b, + dnnl_OwI16o4i = dnnl_AcB16a4b, + dnnl_Iwo8i = dnnl_Bca8b, + dnnl_IwO8i2o = dnnl_BcA8b2a, + dnnl_IwO8i4o = dnnl_BcA8b4a, + dnnl_Iwo16i = dnnl_Bca16b, + dnnl_IwO16i2o = dnnl_BcA16b2a, + dnnl_IwO16i4o = dnnl_BcA16b4a, + dnnl_Iwo24i = dnnl_Bca24b, + dnnl_IwO24i2o = dnnl_BcA24b2a, + dnnl_IwO24i4o = dnnl_BcA24b4a, + dnnl_Owi4o = dnnl_Acb4a, + dnnl_Owi8o = dnnl_Acb8a, + dnnl_OwI8o2i = dnnl_AcB8a2b, + dnnl_OIw8i32o = dnnl_ABc8b32a, + dnnl_OwI8i32o = dnnl_AcB8b32a, + dnnl_OIw8i24o = dnnl_ABc8b24a, + dnnl_OwI8i24o = dnnl_AcB8b24a, + dnnl_OIw8i16o = dnnl_ABc8b16a, + dnnl_OwI8i16o = dnnl_AcB8b16a, + dnnl_OwI8o4i = dnnl_AcB8a4b, + + // weights, 4D + dnnl_IOhw16i16o = dnnl_BAcd16b16a, + dnnl_IOhw4o4i = dnnl_BAcd4a4b, + dnnl_IOhw8o8i = dnnl_BAcd8a8b, + dnnl_IOhw16o16i = dnnl_BAcd16a16b, + dnnl_Ohwi16o = dnnl_Acdb16a, + dnnl_OhwI16o2i = dnnl_AcdB16a2b, + dnnl_OhwI16o4i = dnnl_AcdB16a4b, + dnnl_Ihwo8i = dnnl_Bcda8b, + dnnl_IhwO8i2o = dnnl_BcdA8b2a, + dnnl_IhwO8i4o = dnnl_BcdA8b4a, + dnnl_Ihwo16i = dnnl_Bcda16b, + dnnl_IhwO16i2o = dnnl_BcdA16b2a, + dnnl_IhwO16i4o = dnnl_BcdA16b4a, + dnnl_Ihwo24i = dnnl_Bcda24b, + dnnl_IhwO24i2o = dnnl_BcdA24b2a, + dnnl_IhwO24i4o = dnnl_BcdA24b4a, + dnnl_Ohwi24o = dnnl_Acdb24a, + dnnl_Ohwi32o = dnnl_Acdb32a, + dnnl_Ohwi4o = dnnl_Acdb4a, + dnnl_Ohwi8o = dnnl_Acdb8a, + dnnl_OhwI8o2i = dnnl_AcdB8a2b, + dnnl_OhwI8o4i = dnnl_AcdB8a4b, + dnnl_OIhw16i16o = dnnl_ABcd16b16a, + dnnl_OhwI16i16o = dnnl_AcdB16b16a, + dnnl_OIhw16i32o = dnnl_ABcd16b32a, + dnnl_OhwI16i32o = dnnl_AcdB16b32a, + dnnl_OIhw16i48o = dnnl_ABcd16b48a, + dnnl_OhwI16i48o = dnnl_AcdB16b48a, + dnnl_OIhw16i64o = dnnl_ABcd16b64a, + dnnl_OhwI16i64o = dnnl_AcdB16b64a, + dnnl_OIhw16o16i = dnnl_ABcd16a16b, + dnnl_Oihw16o = dnnl_Abcd16a, + dnnl_OIhw4i8o4i = dnnl_ABcd4b8a4b, + dnnl_OhwI4i8o4i = dnnl_AcdB4b8a4b, + dnnl_OIhw4i16o4i = dnnl_ABcd4b16a4b, + dnnl_OhwI4i16o4i = dnnl_AcdB4b16a4b, + dnnl_OIhw4i24o4i = dnnl_ABcd4b24a4b, + dnnl_OhwI4i24o4i = dnnl_AcdB4b24a4b, + dnnl_OIhw4i32o4i = dnnl_ABcd4b32a4b, + dnnl_OhwI4i32o4i = dnnl_AcdB4b32a4b, + dnnl_OIhw4i64o4i = dnnl_ABcd4b64a4b, + dnnl_OhwI4i64o4i = dnnl_AcdB4b64a4b, + dnnl_OIhw16i16o4i = dnnl_ABcd16b16a4b, + dnnl_OIhw16i16o2i = dnnl_ABcd16b16a2b, + dnnl_OIhw16o16i2o = dnnl_ABcd16a16b2a, + dnnl_OIhw4i4o = dnnl_ABcd4b4a, + dnnl_OIhw4o4i = dnnl_ABcd4a4b, + dnnl_Oihw4o = dnnl_Abcd4a, + dnnl_OIhw8i8o2i = dnnl_ABcd8b8a2b, + dnnl_OhwI8i8o2i = dnnl_AcdB8b8a2b, + dnnl_OIhw8i16o2i = dnnl_ABcd8b16a2b, + dnnl_OhwI8i16o2i = dnnl_AcdB8b16a2b, + dnnl_OIhw8i32o2i = dnnl_ABcd8b32a2b, + dnnl_OhwI8i32o2i = dnnl_AcdB8b32a2b, + dnnl_OIhw8i24o2i = dnnl_ABcd8b24a2b, + dnnl_OhwI8i24o2i = dnnl_AcdB8b24a2b, + dnnl_OIhw8i64o2i = dnnl_ABcd8b64a2b, + dnnl_OhwI8i64o2i = dnnl_AcdB8b64a2b, + dnnl_OIhw8i8o = dnnl_ABcd8b8a, + dnnl_OhwI8i8o = dnnl_AcdB8b8a, + dnnl_OIhw8o16i2o = dnnl_ABcd8a16b2a, + dnnl_OIhw2i8o4i = dnnl_ABcd2b8a4b, + dnnl_IOhw8o16i2o = dnnl_BAcd8a16b2a, + dnnl_OIhw8o8i = dnnl_ABcd8a8b, + dnnl_OIhw8o4i = dnnl_ABcd8a4b, + dnnl_Owhi16o = dnnl_Adcb16a, + dnnl_OIhw8i32o = dnnl_ABcd8b32a, + dnnl_OhwI8i32o = dnnl_AcdB8b32a, + dnnl_OIhw8i24o = dnnl_ABcd8b24a, + dnnl_OhwI8i24o = dnnl_AcdB8b24a, + dnnl_OIhw8i16o = dnnl_ABcd8b16a, + dnnl_OhwI8i16o = dnnl_AcdB8b16a, + + // weights, 5D + dnnl_Odhwi16o = dnnl_Acdeb16a, + dnnl_OdhwI16o2i = dnnl_AcdeB16a2b, + dnnl_OdhwI16o4i = dnnl_AcdeB16a4b, + dnnl_Idhwo8i = dnnl_Bcdea8b, + dnnl_IdhwO8i2o = dnnl_BcdeA8b2a, + dnnl_IdhwO8i4o = dnnl_BcdeA8b4a, + dnnl_Idhwo16i = dnnl_Bcdea16b, + dnnl_IdhwO16i2o = dnnl_BcdeA16b2a, + dnnl_IdhwO16i4o = dnnl_BcdeA16b4a, + dnnl_Idhwo24i = dnnl_Bcdea24b, + dnnl_IdhwO24i2o = dnnl_BcdeA24b2a, + dnnl_IdhwO24i4o = dnnl_BcdeA24b4a, + dnnl_Odhwi4o = dnnl_Acdeb4a, + dnnl_Odhwi8o = dnnl_Acdeb8a, + dnnl_OdhwI8o2i = dnnl_AcdeB8a2b, + dnnl_OdhwI8o4i = dnnl_AcdeB8a4b, + dnnl_Odwhi16o = dnnl_Acedb16a, + dnnl_OIdhw16i16o = dnnl_ABcde16b16a, + dnnl_OdhwI16i16o = dnnl_AcdeB16b16a, + dnnl_OIdhw16i32o = dnnl_ABcde16b32a, + dnnl_OdhwI16i32o = dnnl_AcdeB16b32a, + dnnl_OIdhw16i48o = dnnl_ABcde16b48a, + dnnl_OdhwI16i48o = dnnl_AcdeB16b48a, + dnnl_OIdhw16i64o = dnnl_ABcde16b64a, + dnnl_OdhwI16i64o = dnnl_AcdeB16b64a, + dnnl_OIdhw16o16i = dnnl_ABcde16a16b, + dnnl_Oidhw16o = dnnl_Abcde16a, + dnnl_OIdhw4i4o = dnnl_ABcde4b4a, + dnnl_OIdhw4o4i = dnnl_ABcde4a4b, + dnnl_Oidhw4o = dnnl_Abcde4a, + dnnl_OIdhw8i8o2i = dnnl_ABcde8b8a2b, + dnnl_OdhwI8i8o2i = dnnl_AcdeB8b8a2b, + dnnl_OIdhw8i16o2i = dnnl_ABcde8b16a2b, + dnnl_OdhwI8i16o2i = dnnl_AcdeB8b16a2b, + dnnl_OIdhw8i32o2i = dnnl_ABcde8b32a2b, + dnnl_OdhwI8i32o2i = dnnl_AcdeB8b32a2b, + dnnl_OIdhw8i24o2i = dnnl_ABcde8b24a2b, + dnnl_OdhwI8i24o2i = dnnl_AcdeB8b24a2b, + dnnl_OIdhw8i64o2i = dnnl_ABcde8b64a2b, + dnnl_OdhwI8i64o2i = dnnl_AcdeB8b64a2b, + dnnl_OIdhw8i8o = dnnl_ABcde8b8a, + dnnl_OdhwI8i8o = dnnl_AcdeB8b8a, + dnnl_OIdhw8o16i2o = dnnl_ABcde8a16b2a, + dnnl_IOdhw8o16i2o = dnnl_BAcde8a16b2a, + dnnl_OIdhw4i8o4i = dnnl_ABcde4b8a4b, + dnnl_OdhwI4i8o4i = dnnl_AcdeB4b8a4b, + dnnl_OIdhw4i16o4i = dnnl_ABcde4b16a4b, + dnnl_OdhwI4i16o4i = dnnl_AcdeB4b16a4b, + dnnl_OIdhw4i24o4i = dnnl_ABcde4b24a4b, + dnnl_OdhwI4i24o4i = dnnl_AcdeB4b24a4b, + dnnl_OIdhw4i32o4i = dnnl_ABcde4b32a4b, + dnnl_OdhwI4i32o4i = dnnl_AcdeB4b32a4b, + dnnl_OIdhw4i64o4i = dnnl_ABcde4b64a4b, + dnnl_OdhwI4i64o4i = dnnl_AcdeB4b64a4b, + dnnl_OIdhw16i16o4i = dnnl_ABcde16b16a4b, + dnnl_OIdhw16i16o2i = dnnl_ABcde16b16a2b, + dnnl_OIdhw2i8o4i = dnnl_ABcde2b8a4b, + dnnl_OIdhw8o8i = dnnl_ABcde8a8b, + dnnl_OIdhw8o4i = dnnl_ABcde8a4b, + dnnl_IOdhw16i16o = dnnl_BAcde16b16a, + dnnl_OIdhw4o8i8o4i = dnnl_ABcde4a8b8a4b, + dnnl_IOdhw4o4i = dnnl_BAcde4a4b, + dnnl_IOdhw8o8i = dnnl_BAcde8a8b, + dnnl_IOdhw16o16i = dnnl_BAcde16a16b, + dnnl_OIdhw16o16i2o = dnnl_ABcde16a16b2a, + dnnl_OIdhw8i32o = dnnl_ABcde8b32a, + dnnl_OdhwI8i32o = dnnl_AcdeB8b32a, + dnnl_OIdhw8i24o = dnnl_ABcde8b24a, + dnnl_OdhwI8i24o = dnnl_AcdeB8b24a, + dnnl_OIdhw8i16o = dnnl_ABcde8b16a, + dnnl_OdhwI8i16o = dnnl_AcdeB8b16a, + + // weights w/ groups, 3D + dnnl_Goiw16g = dnnl_Abcd16a, + dnnl_Goiw8g = dnnl_Abcd8a, + dnnl_Goiw4g = dnnl_Abcd4a, + dnnl_gIOw4o4i = dnnl_aCBd4b4c, + dnnl_gIOw8o8i = dnnl_aCBd8b8c, + dnnl_gIOw16o16i = dnnl_aCBd16b16c, + dnnl_gIOw16i16o = dnnl_aCBd16c16b, + dnnl_gOIw16i16o = dnnl_aBCd16c16b, + dnnl_gOIw16o16i = dnnl_aBCd16b16c, + dnnl_gOiw16o = dnnl_aBcd16b, + dnnl_gOIw4i16o4i = dnnl_aBCd4c16b4c, + dnnl_gOIw2i8o4i = dnnl_aBCd2c8b4c, + dnnl_gOIw16i16o4i = dnnl_aBCd16c16b4c, + dnnl_gOIw16i16o2i = dnnl_aBCd16c16b2c, + dnnl_gOIw16o16i2o = dnnl_aBCd16b16c2b, + dnnl_gOIw4i4o = dnnl_aBCd4c4b, + dnnl_gOIw4o4i = dnnl_aBCd4b4c, + dnnl_gOiw4o = dnnl_aBcd4b, + dnnl_gOIw8i16o2i = dnnl_aBCd8c16b2c, + dnnl_gOIw8i8o = dnnl_aBCd8c8b, + dnnl_gOIw8o16i2o = dnnl_aBCd8b16c2b, + dnnl_gIOw8o16i2o = dnnl_aCBd8b16c2b, + dnnl_gOIw8o8i = dnnl_aBCd8b8c, + dnnl_gOIw8o4i = dnnl_aBCd8b4c, + dnnl_gOwi16o = dnnl_aBdc16b, + dnnl_gOwI16o2i = dnnl_aBdC16b2c, + dnnl_gOwI16o4i = dnnl_aBdC16b4c, + dnnl_gIwo8i = dnnl_aCdb8c, + dnnl_gIwO8i2o = dnnl_aCdB8c2b, + dnnl_gIwO8i4o = dnnl_aCdB8c4b, + dnnl_gIwo16i = dnnl_aCdb16c, + dnnl_gIwO16i2o = dnnl_aCdB16c2b, + dnnl_gIwO16i4o = dnnl_aCdB16c4b, + dnnl_gIwo24i = dnnl_aCdb24c, + dnnl_gIwO24i2o = dnnl_aCdB24c2b, + dnnl_gIwO24i4o = dnnl_aCdB24c4b, + dnnl_gOwi4o = dnnl_aBdc4b, + dnnl_gOwi8o = dnnl_aBdc8b, + dnnl_gOwI8o2i = dnnl_aBdC8b2c, + dnnl_gOwI8o4i = dnnl_aBdC8b4c, + dnnl_Goiw32g = dnnl_Abcd32a, + dnnl_gOIw2i4o2i = dnnl_aBCd2c4b2c, + dnnl_gOIw2o4i2o = dnnl_aBCd2b4c2b, + dnnl_gOIw4i8o2i = dnnl_aBCd4c8b2c, + dnnl_gOIw4o8i2o = dnnl_aBCd4b8c2b, + dnnl_goIw4i = dnnl_abCd4c, + dnnl_goIw32i = dnnl_abCd32c, + + // weights w/ groups, 4D + dnnl_gIOhw16i16o = dnnl_aCBde16c16b, + dnnl_gIOhw4o4i = dnnl_aCBde4b4c, + dnnl_gIOhw8o8i = dnnl_aCBde8b8c, + dnnl_gIOhw16o16i = dnnl_aCBde16b16c, + dnnl_gOhwi16o = dnnl_aBdec16b, + dnnl_gOhwI16o2i = dnnl_aBdeC16b2c, + dnnl_gOhwI16o4i = dnnl_aBdeC16b4c, + dnnl_gIhwo8i = dnnl_aCdeb8c, + dnnl_gIhwO8i2o = dnnl_aCdeB8c2b, + dnnl_gIhwO8i4o = dnnl_aCdeB8c4b, + dnnl_gIhwo16i = dnnl_aCdeb16c, + dnnl_gIhwO16i2o = dnnl_aCdeB16c2b, + dnnl_gIhwO16i4o = dnnl_aCdeB16c4b, + dnnl_gIhwo24i = dnnl_aCdeb24c, + dnnl_gIhwO24i2o = dnnl_aCdeB24c2b, + dnnl_gIhwO24i4o = dnnl_aCdeB24c4b, + dnnl_gOhwi32o = dnnl_aBdec32b, + dnnl_gOhwi24o = dnnl_aBdec24b, + dnnl_gOhwI24o2i = dnnl_aBdeC24b2c, + dnnl_gOhwI24o4i = dnnl_aBdeC24b4c, + dnnl_gOhwi4o = dnnl_aBdec4b, + dnnl_gOhwi8o = dnnl_aBdec8b, + dnnl_gOhwI8o2i = dnnl_aBdeC8b2c, + dnnl_gOhwI8o4i = dnnl_aBdeC8b4c, + dnnl_Goihw16g = dnnl_Abcde16a, + dnnl_gOIhw16i16o = dnnl_aBCde16c16b, + dnnl_gOIhw16o16i = dnnl_aBCde16b16c, + dnnl_gOihw16o = dnnl_aBcde16b, + dnnl_gOIhw2i8o4i = dnnl_aBCde2c8b4c, + dnnl_gOIhw4i16o4i = dnnl_aBCde4c16b4c, + dnnl_gOIhw16i16o4i = dnnl_aBCde16c16b4c, + dnnl_gOIhw16i16o2i = dnnl_aBCde16c16b2c, + dnnl_gOIhw16o16i2o = dnnl_aBCde16b16c2b, + dnnl_gOIhw4i4o = dnnl_aBCde4c4b, + dnnl_gOIhw4o4i = dnnl_aBCde4b4c, + dnnl_gOihw4o = dnnl_aBcde4b, + dnnl_Goihw8g = dnnl_Abcde8a, + dnnl_Goihw4g = dnnl_Abcde4a, + dnnl_gOIhw8i16o2i = dnnl_aBCde8c16b2c, + dnnl_gOIhw8i8o = dnnl_aBCde8c8b, + dnnl_gOIhw8o16i2o = dnnl_aBCde8b16c2b, + dnnl_gIOhw8o16i2o = dnnl_aCBde8b16c2b, + dnnl_gOIhw8o8i = dnnl_aBCde8b8c, + dnnl_gOIhw8o4i = dnnl_aBCde8b4c, + dnnl_Goihw32g = dnnl_Abcde32a, + dnnl_gOwhi16o = dnnl_aBedc16b, + dnnl_goIhw4i = dnnl_abCde4c, + dnnl_goIhw32i = dnnl_abCde32c, + + dnnl_OIw4o8i8o4i = dnnl_ABc4a8b8a4b, + dnnl_OIhw4o8i8o4i = dnnl_ABcd4a8b8a4b, + dnnl_IOw4i8o8i4o = dnnl_BAc4b8a8b4a, + dnnl_IOhw4i8o8i4o = dnnl_BAcd4b8a8b4a, + dnnl_IOdhw4i8o8i4o = dnnl_BAcde4b8a8b4a, + + dnnl_OIhw2o8i8o2i = dnnl_ABcd2a8b8a2b, + dnnl_gOIw4o8i8o4i = dnnl_aBCd4b8c8b4c, + dnnl_gOIhw4o8i8o4i = dnnl_aBCde4b8c8b4c, + dnnl_gOIdhw4o8i8o4i = dnnl_aBCdef4b8c8b4c, + dnnl_gIOw4i8o8i4o = dnnl_aCBd4c8b8c4b, + dnnl_gIOhw4i8o8i4o = dnnl_aCBde4c8b8c4b, + dnnl_gIOdhw4i8o8i4o = dnnl_aCBdef4c8b8c4b, + dnnl_gOIhw2o8i8o2i = dnnl_aBCde2b8c8b2c, + dnnl_gOIhw2i4o2i = dnnl_aBCde2c4b2c, + dnnl_gOIhw2o4i2o = dnnl_aBCde2b4c2b, + dnnl_gOIhw4i8o2i = dnnl_aBCde4c8b2c, + dnnl_gOIhw4o8i2o = dnnl_aBCde4b8c2b, + + // weights w/ groups, 6D + dnnl_gIOdhw16i16o = dnnl_aCBdef16c16b, + dnnl_gIOdhw4o4i = dnnl_aCBdef4b4c, + dnnl_gIOdhw8o8i = dnnl_aCBdef8b8c, + dnnl_gIOdhw16o16i = dnnl_aCBdef16b16c, + dnnl_gOdhwi16o = dnnl_aBdefc16b, + dnnl_gOdhwI16o2i = dnnl_aBdefC16b2c, + dnnl_gOdhwI16o4i = dnnl_aBdefC16b4c, + dnnl_gIdhwo8i = dnnl_aCdefb8c, + dnnl_gIdhwO8i2o = dnnl_aCdefB8c2b, + dnnl_gIdhwO8i4o = dnnl_aCdefB8c4b, + dnnl_gIdhwo16i = dnnl_aCdefb16c, + dnnl_gIdhwO16i2o = dnnl_aCdefB16c2b, + dnnl_gIdhwO16i4o = dnnl_aCdefB16c4b, + dnnl_gIdhwo24i = dnnl_aCdefb24c, + dnnl_gIdhwO24i2o = dnnl_aCdefB24c2b, + dnnl_gIdhwO24i4o = dnnl_aCdefB24c4b, + dnnl_gOdhwi4o = dnnl_aBdefc4b, + dnnl_gOdhwi8o = dnnl_aBdefc8b, + dnnl_gOdhwI8o2i = dnnl_aBdefC8b2c, + dnnl_gOdhwI8o4i = dnnl_aBdefC8b4c, + dnnl_gOdwhi16o = dnnl_aBdfec16b, + dnnl_gOIdhw16i16o = dnnl_aBCdef16c16b, + dnnl_gOIdhw4i16o4i = dnnl_aBCdef4c16b4c, + dnnl_gOIdhw16i16o4i = dnnl_aBCdef16c16b4c, + dnnl_gOIdhw2i8o4i = dnnl_aBCdef2c8b4c, + dnnl_gOIdhw16i16o2i = dnnl_aBCdef16c16b2c, + dnnl_gOIdhw16o16i = dnnl_aBCdef16b16c, + dnnl_gOIdhw16o16i2o = dnnl_aBCdef16b16c2b, + dnnl_gOidhw16o = dnnl_aBcdef16b, + dnnl_gOIdhw4i4o = dnnl_aBCdef4c4b, + dnnl_gOIdhw4o4i = dnnl_aBCdef4b4c, + dnnl_gOidhw4o = dnnl_aBcdef4b, + dnnl_gOIdhw8i16o2i = dnnl_aBCdef8c16b2c, + dnnl_gOIdhw8i8o = dnnl_aBCdef8c8b, + dnnl_gOIdhw8o16i2o = dnnl_aBCdef8b16c2b, + dnnl_gIOdhw8o16i2o = dnnl_aCBdef8b16c2b, + dnnl_gOIdhw8o8i = dnnl_aBCdef8b8c, + dnnl_gOIdhw8o4i = dnnl_aBCdef8b4c, + dnnl_Goidhw16g = dnnl_Abcdef16a, + dnnl_Goidhw32g = dnnl_Abcdef32a, + dnnl_gOIdhw2i4o2i = dnnl_aBCdef2c4b2c, + dnnl_gOIdhw4i8o2i = dnnl_aBCdef4c8b2c, + dnnl_gOIdhw2o4i2o = dnnl_aBCdef2b4c2b, + dnnl_gOIdhw4o8i2o = dnnl_aBCdef4b8c2b, + dnnl_goIdhw4i = dnnl_abCdef4c, + dnnl_goIdhw32i = dnnl_abCdef32c, + + // weights, 3D + dnnl_Owi24o = dnnl_Acb24a, + dnnl_OwI24o2i = dnnl_AcB24a2b, + dnnl_OwI24o4i = dnnl_AcB24a4b, + dnnl_Owi32o = dnnl_Acb32a, + dnnl_OwI32o2i = dnnl_AcB32a2b, + dnnl_OwI32o4i = dnnl_AcB32a4b, + dnnl_Owi48o = dnnl_Acb48a, + dnnl_OwI48o2i = dnnl_AcB48a2b, + dnnl_OwI48o4i = dnnl_AcB48a4b, + dnnl_Owi64o = dnnl_Acb64a, + dnnl_OwI64o2i = dnnl_AcB64a2b, + dnnl_OwI64o4i = dnnl_AcB64a4b, + dnnl_Iwo32i = dnnl_Bca32b, + dnnl_IwO32i2o = dnnl_BcA32b2a, + dnnl_IwO32i4o = dnnl_BcA32b4a, + dnnl_Iwo48i = dnnl_Bca48b, + dnnl_IwO48i2o = dnnl_BcA48b2a, + dnnl_IwO48i4o = dnnl_BcA48b4a, + dnnl_Iwo64i = dnnl_Bca64b, + dnnl_IwO64i2o = dnnl_BcA64b2a, + dnnl_IwO64i4o = dnnl_BcA64b4a, + dnnl_wIo2i = dnnl_cBa2b, + dnnl_wIo4i = dnnl_cBa4b, + dnnl_gOwi24o = dnnl_aBdc24b, + dnnl_gOwI24o2i = dnnl_aBdC24b2c, + dnnl_gOwI24o4i = dnnl_aBdC24b4c, + dnnl_gOwi32o = dnnl_aBdc32b, + dnnl_gOwI32o2i = dnnl_aBdC32b2c, + dnnl_gOwI32o4i = dnnl_aBdC32b4c, + dnnl_gOwi48o = dnnl_aBdc48b, + dnnl_gOwI48o2i = dnnl_aBdC48b2c, + dnnl_gOwI48o4i = dnnl_aBdC48b4c, + dnnl_gOwi64o = dnnl_aBdc64b, + dnnl_gOwI64o2i = dnnl_aBdC64b2c, + dnnl_gOwI64o4i = dnnl_aBdC64b4c, + dnnl_gIwo32i = dnnl_aCdb32c, + dnnl_gIwO32i2o = dnnl_aCdB32c2b, + dnnl_gIwO32i4o = dnnl_aCdB32c4b, + dnnl_gIwo48i = dnnl_aCdb48c, + dnnl_gIwO48i2o = dnnl_aCdB48c2b, + dnnl_gIwO48i4o = dnnl_aCdB48c4b, + dnnl_gIwo64i = dnnl_aCdb64c, + dnnl_gIwO64i2o = dnnl_aCdB64c2b, + dnnl_gIwO64i4o = dnnl_aCdB64c4b, + dnnl_gwio = dnnl_adcb, + dnnl_gwIo2i = dnnl_adCb2c, + dnnl_gwIo4i = dnnl_adCb4c, + // weights, 4D + dnnl_OhwI24o = dnnl_Acdb24a, + dnnl_OhwI24o2i = dnnl_AcdB24a2b, + dnnl_OhwI24o4i = dnnl_AcdB24a4b, + dnnl_OhwI32o = dnnl_Acdb32a, + dnnl_OhwI32o2i = dnnl_AcdB32a2b, + dnnl_OhwI32o4i = dnnl_AcdB32a4b, + dnnl_Ohwi48o = dnnl_Acdb48a, + dnnl_OhwI48o2i = dnnl_AcdB48a2b, + dnnl_OhwI48o4i = dnnl_AcdB48a4b, + dnnl_Ohwi64o = dnnl_Acdb64a, + dnnl_OhwI64o2i = dnnl_AcdB64a2b, + dnnl_OhwI64o4i = dnnl_AcdB64a4b, + dnnl_Ihwo32i = dnnl_Bcda32b, + dnnl_IhwO32i2o = dnnl_BcdA32b2a, + dnnl_IhwO32i4o = dnnl_BcdA32b4a, + dnnl_Ihwo48i = dnnl_Bcda48b, + dnnl_IhwO48i2o = dnnl_BcdA48b2a, + dnnl_IhwO48i4o = dnnl_BcdA48b4a, + dnnl_Ihwo64i = dnnl_Bcda64b, + dnnl_IhwO64i2o = dnnl_BcdA64b2a, + dnnl_IhwO64i4o = dnnl_BcdA64b4a, + dnnl_hwIo2i = dnnl_cdBa2b, + dnnl_hwIo4i = dnnl_cdBa4b, + dnnl_gOhwI24o = dnnl_aBdec24b, + dnnl_gOhwI32o = dnnl_aBdec32b, + dnnl_gOhwI32o2i = dnnl_aBdeC32b2c, + dnnl_gOhwI32o4i = dnnl_aBdeC32b4c, + dnnl_gOhwi48o = dnnl_aBdec48b, + dnnl_gOhwI48o2i = dnnl_aBdeC48b2c, + dnnl_gOhwI48o4i = dnnl_aBdeC48b4c, + dnnl_gOhwi64o = dnnl_aBdec64b, + dnnl_gOhwI64o2i = dnnl_aBdeC64b2c, + dnnl_gOhwI64o4i = dnnl_aBdeC64b4c, + dnnl_gIhwo32i = dnnl_aCdeb32c, + dnnl_gIhwO32i2o = dnnl_aCdeB32c2b, + dnnl_gIhwO32i4o = dnnl_aCdeB32c4b, + dnnl_gIhwo48i = dnnl_aCdeb48c, + dnnl_gIhwO48i2o = dnnl_aCdeB48c2b, + dnnl_gIhwO48i4o = dnnl_aCdeB48c4b, + dnnl_gIhwo64i = dnnl_aCdeb64c, + dnnl_gIhwO64i2o = dnnl_aCdeB64c2b, + dnnl_gIhwO64i4o = dnnl_aCdeB64c4b, + dnnl_ghwio = dnnl_adecb, + dnnl_ghwIo2i = dnnl_adeCb2c, + dnnl_ghwIo4i = dnnl_adeCb4c, + // weights, 5D + dnnl_Odhwi24o = dnnl_Acdeb24a, + dnnl_OdhwI24o2i = dnnl_AcdeB24a2b, + dnnl_OdhwI24o4i = dnnl_AcdeB24a4b, + dnnl_Odhwi32o = dnnl_Acdeb32a, + dnnl_OdhwI32o2i = dnnl_AcdeB32a2b, + dnnl_OdhwI32o4i = dnnl_AcdeB32a4b, + dnnl_Odhwi48o = dnnl_Acdeb48a, + dnnl_OdhwI48o2i = dnnl_AcdeB48a2b, + dnnl_OdhwI48o4i = dnnl_AcdeB48a4b, + dnnl_Odhwi64o = dnnl_Acdeb64a, + dnnl_OdhwI64o2i = dnnl_AcdeB64a2b, + dnnl_OdhwI64o4i = dnnl_AcdeB64a4b, + dnnl_Idhwo32i = dnnl_Bcdea32b, + dnnl_IdhwO32i2o = dnnl_BcdeA32b2a, + dnnl_IdhwO32i4o = dnnl_BcdeA32b4a, + dnnl_Idhwo48i = dnnl_Bcdea48b, + dnnl_IdhwO48i2o = dnnl_BcdeA48b2a, + dnnl_IdhwO48i4o = dnnl_BcdeA48b4a, + dnnl_Idhwo64i = dnnl_Bcdea64b, + dnnl_IdhwO64i2o = dnnl_BcdeA64b2a, + dnnl_IdhwO64i4o = dnnl_BcdeA64b4a, + dnnl_dhwIo2i = dnnl_cdeBa2b, + dnnl_dhwIo4i = dnnl_cdeBa4b, + dnnl_gOdhwi24o = dnnl_aBdefc24b, + dnnl_gOdhwI24o2i = dnnl_aBdefC24b2c, + dnnl_gOdhwI24o4i = dnnl_aBdefC24b4c, + dnnl_gOdhwi32o = dnnl_aBdefc32b, + dnnl_gOdhwI32o2i = dnnl_aBdefC32b2c, + dnnl_gOdhwI32o4i = dnnl_aBdefC32b4c, + dnnl_gOdhwi48o = dnnl_aBdefc48b, + dnnl_gOdhwI48o2i = dnnl_aBdefC48b2c, + dnnl_gOdhwI48o4i = dnnl_aBdefC48b4c, + dnnl_gOdhwi64o = dnnl_aBdefc64b, + dnnl_gOdhwI64o2i = dnnl_aBdefC64b2c, + dnnl_gOdhwI64o4i = dnnl_aBdefC64b4c, + dnnl_gIdhwo32i = dnnl_aCdefb32c, + dnnl_gIdhwO32i2o = dnnl_aCdefB32c2b, + dnnl_gIdhwO32i4o = dnnl_aCdefB32c4b, + dnnl_gIdhwo48i = dnnl_aCdefb48c, + dnnl_gIdhwO48i2o = dnnl_aCdefB48c2b, + dnnl_gIdhwO48i4o = dnnl_aCdefB48c4b, + dnnl_gIdhwo64i = dnnl_aCdefb64c, + dnnl_gIdhwO64i2o = dnnl_aCdefB64c2b, + dnnl_gIdhwO64i4o = dnnl_aCdefB64c4b, + dnnl_gdhwio = dnnl_adefcb, + dnnl_gdhwIo2i = dnnl_adefCb2c, + dnnl_gdhwIo4i = dnnl_adefCb4c, + dnnl_OI16i32o4i = dnnl_AB16b32a4b, + dnnl_OI16i48o4i = dnnl_AB16b48a4b, + dnnl_OI16i64o4i = dnnl_AB16b64a4b, + dnnl_OI16i16o2i = dnnl_AB16b16a2b, + dnnl_OI16i32o2i = dnnl_AB16b32a2b, + dnnl_OI16i48o2i = dnnl_AB16b48a2b, + dnnl_OI16i64o2i = dnnl_AB16b64a2b, + dnnl_OIw16i32o4i = dnnl_ABc16b32a4b, + dnnl_OIw16i48o4i = dnnl_ABc16b48a4b, + dnnl_OIw16i64o4i = dnnl_ABc16b64a4b, + dnnl_OIw16i32o2i = dnnl_ABc16b32a2b, + dnnl_OIw16i48o2i = dnnl_ABc16b48a2b, + dnnl_OIw16i64o2i = dnnl_ABc16b64a2b, + dnnl_OIhw16i32o4i = dnnl_ABcd16b32a4b, + dnnl_OIhw16i48o4i = dnnl_ABcd16b48a4b, + dnnl_OIhw16i64o4i = dnnl_ABcd16b64a4b, + dnnl_OIhw16i32o2i = dnnl_ABcd16b32a2b, + dnnl_OIhw16i48o2i = dnnl_ABcd16b48a2b, + dnnl_OIhw16i64o2i = dnnl_ABcd16b64a2b, + dnnl_OIdhw16i32o4i = dnnl_ABcde16b32a4b, + dnnl_OIdhw16i48o4i = dnnl_ABcde16b48a4b, + dnnl_OIdhw16i64o4i = dnnl_ABcde16b64a4b, + dnnl_OIdhw16i32o2i = dnnl_ABcde16b32a2b, + dnnl_OIdhw16i48o2i = dnnl_ABcde16b48a2b, + dnnl_OIdhw16i64o2i = dnnl_ABcde16b64a2b, + dnnl_OwI16i16o2i = dnnl_AcB16b16a2b, + dnnl_OwI16i16o4i = dnnl_AcB16b16a4b, + dnnl_OhwI16i16o2i = dnnl_AcdB16b16a2b, + dnnl_OhwI16i16o4i = dnnl_AcdB16b16a4b, + dnnl_OdhwI16i16o2i = dnnl_AcdeB16b16a2b, + dnnl_OdhwI16i16o4i = dnnl_AcdeB16b16a4b, + dnnl_IwO16o16i2o = dnnl_BcA16a16b2a, + dnnl_IwO16o16i4o = dnnl_BcA16a16b4a, + dnnl_IhwO16o16i2o = dnnl_BcdA16a16b2a, + dnnl_IhwO16o16i4o = dnnl_BcdA16a16b4a, + dnnl_IdhwO16o16i2o = dnnl_BcdeA16a16b2a, + dnnl_IdhwO16o16i4o = dnnl_BcdeA16a16b4a, + dnnl_gOwI16i16o2i = dnnl_aBdC16c16b2c, + dnnl_gOwI16i16o4i = dnnl_aBdC16c16b4c, + dnnl_gOhwI16i16o2i = dnnl_aBdeC16c16b2c, + dnnl_gOhwI16i16o4i = dnnl_aBdeC16c16b4c, + dnnl_gOdhwI16i16o2i = dnnl_aBdefC16c16b2c, + dnnl_gOdhwI16i16o4i = dnnl_aBdefC16c16b4c, + dnnl_gIwO16o16i2o = dnnl_aCdB16b16c2b, + dnnl_gIwO16o16i4o = dnnl_aCdB16b16c4b, + dnnl_gIhwO16o16i2o = dnnl_aCdeB16b16c2b, + dnnl_gIhwO16o16i4o = dnnl_aCdeB16b16c4b, + dnnl_gIdhwO16o16i2o = dnnl_aCdefB16b16c2b, + dnnl_gIdhwO16o16i4o = dnnl_aCdefB16b16c4b, + dnnl_OwI16i32o2i = dnnl_AcB16b32a2b, + dnnl_OwI16i32o4i = dnnl_AcB16b32a4b, + dnnl_OwI16i48o2i = dnnl_AcB16b48a2b, + dnnl_OwI16i48o4i = dnnl_AcB16b48a4b, + dnnl_OwI16i64o2i = dnnl_AcB16b64a2b, + dnnl_OwI16i64o4i = dnnl_AcB16b64a4b, + dnnl_IwO16o32i2o = dnnl_BcA16a32b2a, + dnnl_IwO16o32i4o = dnnl_BcA16a32b4a, + dnnl_IwO16o48i2o = dnnl_BcA16a48b2a, + dnnl_IwO16o48i4o = dnnl_BcA16a48b4a, + dnnl_IwO16o64i2o = dnnl_BcA16a64b2a, + dnnl_IwO16o64i4o = dnnl_BcA16a64b4a, + dnnl_gOwI16i32o2i = dnnl_aBdC16c32b2c, + dnnl_gOwI16i32o4i = dnnl_aBdC16c32b4c, + dnnl_gOwI16i48o2i = dnnl_aBdC16c48b2c, + dnnl_gOwI16i48o4i = dnnl_aBdC16c48b4c, + dnnl_gOwI16i64o2i = dnnl_aBdC16c64b2c, + dnnl_gOwI16i64o4i = dnnl_aBdC16c64b4c, + dnnl_gIwO16o32i2o = dnnl_aCdB16b32c2b, + dnnl_gIwO16o32i4o = dnnl_aCdB16b32c4b, + dnnl_gIwO16o48i2o = dnnl_aCdB16b48c2b, + dnnl_gIwO16o48i4o = dnnl_aCdB16b48c4b, + dnnl_gIwO16o64i2o = dnnl_aCdB16b64c2b, + dnnl_gIwO16o64i4o = dnnl_aCdB16b64c4b, + dnnl_OhwI16i32o2i = dnnl_AcdB16b32a2b, + dnnl_OhwI16i32o4i = dnnl_AcdB16b32a4b, + dnnl_OhwI16i48o2i = dnnl_AcdB16b48a2b, + dnnl_OhwI16i48o4i = dnnl_AcdB16b48a4b, + dnnl_OhwI16i64o2i = dnnl_AcdB16b64a2b, + dnnl_OhwI16i64o4i = dnnl_AcdB16b64a4b, + dnnl_IhwO16o32i2o = dnnl_BcdA16a32b2a, + dnnl_IhwO16o32i4o = dnnl_BcdA16a32b4a, + dnnl_IhwO16o48i2o = dnnl_BcdA16a48b2a, + dnnl_IhwO16o48i4o = dnnl_BcdA16a48b4a, + dnnl_IhwO16o64i2o = dnnl_BcdA16a64b2a, + dnnl_IhwO16o64i4o = dnnl_BcdA16a64b4a, + dnnl_gOhwI16i32o2i = dnnl_aBdeC16c32b2c, + dnnl_gOhwI16i32o4i = dnnl_aBdeC16c32b4c, + dnnl_gOhwI16i48o2i = dnnl_aBdeC16c48b2c, + dnnl_gOhwI16i48o4i = dnnl_aBdeC16c48b4c, + dnnl_gOhwI16i64o2i = dnnl_aBdeC16c64b2c, + dnnl_gOhwI16i64o4i = dnnl_aBdeC16c64b4c, + dnnl_gIhwO16o32i2o = dnnl_aCdeB16b32c2b, + dnnl_gIhwO16o32i4o = dnnl_aCdeB16b32c4b, + dnnl_gIhwO16o48i2o = dnnl_aCdeB16b48c2b, + dnnl_gIhwO16o48i4o = dnnl_aCdeB16b48c4b, + dnnl_gIhwO16o64i2o = dnnl_aCdeB16b64c2b, + dnnl_gIhwO16o64i4o = dnnl_aCdeB16b64c4b, + dnnl_OdhwI16i32o2i = dnnl_AcdeB16b32a2b, + dnnl_OdhwI16i32o4i = dnnl_AcdeB16b32a4b, + dnnl_OdhwI16i48o2i = dnnl_AcdeB16b48a2b, + dnnl_OdhwI16i48o4i = dnnl_AcdeB16b48a4b, + dnnl_OdhwI16i64o2i = dnnl_AcdeB16b64a2b, + dnnl_OdhwI16i64o4i = dnnl_AcdeB16b64a4b, + dnnl_IdhwO16o32i2o = dnnl_BcdeA16a32b2a, + dnnl_IdhwO16o32i4o = dnnl_BcdeA16a32b4a, + dnnl_IdhwO16o48i2o = dnnl_BcdeA16a48b2a, + dnnl_IdhwO16o48i4o = dnnl_BcdeA16a48b4a, + dnnl_IdhwO16o64i2o = dnnl_BcdeA16a64b2a, + dnnl_IdhwO16o64i4o = dnnl_BcdeA16a64b4a, + dnnl_gOdhwI16i32o2i = dnnl_aBdefC16c32b2c, + dnnl_gOdhwI16i32o4i = dnnl_aBdefC16c32b4c, + dnnl_gOdhwI16i48o2i = dnnl_aBdefC16c48b2c, + dnnl_gOdhwI16i48o4i = dnnl_aBdefC16c48b4c, + dnnl_gOdhwI16i64o2i = dnnl_aBdefC16c64b2c, + dnnl_gOdhwI16i64o4i = dnnl_aBdefC16c64b4c, + dnnl_gIdhwO16o32i2o = dnnl_aCdefB16b32c2b, + dnnl_gIdhwO16o32i4o = dnnl_aCdefB16b32c4b, + dnnl_gIdhwO16o48i2o = dnnl_aCdefB16b48c2b, + dnnl_gIdhwO16o48i4o = dnnl_aCdefB16b48c4b, + dnnl_gIdhwO16o64i2o = dnnl_aCdefB16b64c2b, + dnnl_gIdhwO16o64i4o = dnnl_aCdefB16b64c4b, + dnnl_hwioG16g = dnnl_decbA16a, + dnnl_hwioG8g = dnnl_decbA8a, + dnnl_hwioG4g = dnnl_decbA4a, + dnnl_dhwioG16g = dnnl_defcbA16a, + dnnl_dhwioG8g = dnnl_defcbA8a, + dnnl_dhwioG4g = dnnl_defcbA4a, + dnnl_NCdhw40n16c = dnnl_ABcde40a16b, + dnnl_NCw40n16c = dnnl_ABc40a16b, + dnnl_NChw40n16c = dnnl_ABcd40a16b, + dnnl_NCw40n32c = dnnl_ABc40a32b, + dnnl_NChw40n32c = dnnl_ABcd40a32b, + dnnl_NCdhw40n32c = dnnl_ABcde40a32b, + dnnl_OIdhw4o8i8o2i = dnnl_ABcde4a8b8a2b, + dnnl_OIhw4o8i8o2i = dnnl_ABcd4a8b8a2b, + dnnl_OIw4o8i8o2i = dnnl_ABc4a8b8a2b, + dnnl_gOIdhw4o8i8o2i = dnnl_aBCdef4b8c8b2c, + dnnl_gOIhw4o8i8o2i = dnnl_aBCde4b8c8b2c, + dnnl_gOIw4o8i8o2i = dnnl_aBCd4b8c8b2c, + dnnl_IOdhw4i8o8i2o = dnnl_BAcde4b8a8b2a, + dnnl_IOhw4i8o8i2o = dnnl_BAcd4b8a8b2a, + dnnl_IOw4i8o8i2o = dnnl_BAc4b8a8b2a, + dnnl_gIOdhw4i8o8i2o = dnnl_aCBdef4c8b8c2b, + dnnl_gIOhw4i8o8i2o = dnnl_aCBde4c8b8c2b, + dnnl_gIOw4i8o8i2o = dnnl_aCBd4c8b8c2b, + dnnl_NCw2c32n8c = dnnl_ABc2b32a8b, + dnnl_NChw2c32n8c = dnnl_ABcd2b32a8b, + dnnl_NCdhw2c32n8c = dnnl_ABcde2b32a8b, + dnnl_OIw2i8o16i4o = dnnl_ABc2b8a16b4a, + dnnl_OIhw2i8o16i4o = dnnl_ABcd2b8a16b4a, + dnnl_OIdhw2i8o16i4o = dnnl_ABcde2b8a16b4a, + dnnl_OIw2o8i16o4i = dnnl_ABc2a8b16a4b, + dnnl_OIw2o8i16o2i = dnnl_ABc2a8b16a2b, + dnnl_IOw2i8o16i4o = dnnl_BAc2b8a16b4a, + dnnl_IOw2i8o16i2o = dnnl_BAc2b8a16b2a, + dnnl_OIhw2o8i16o4i = dnnl_ABcd2a8b16a4b, + dnnl_OIhw2o8i16o2i = dnnl_ABcd2a8b16a2b, + dnnl_IOhw2i8o16i4o = dnnl_BAcd2b8a16b4a, + dnnl_IOhw2i8o16i2o = dnnl_BAcd2b8a16b2a, + dnnl_OIdhw2o8i16o4i = dnnl_ABcde2a8b16a4b, + dnnl_OIdhw2o8i16o2i = dnnl_ABcde2a8b16a2b, + dnnl_IOdhw2i8o16i4o = dnnl_BAcde2b8a16b4a, + dnnl_IOdhw2i8o16i2o = dnnl_BAcde2b8a16b2a, + dnnl_gOIw2o8i16o2i = dnnl_aBCd2b8c16b2c, + dnnl_gIOw2i8o16i2o = dnnl_aCBd2c8b16c2b, + dnnl_gIOhw2i8o16i2o = dnnl_aBCde2c8b16c2b, + dnnl_gIOdhw2i8o16i2o = dnnl_aBCdef2c8b16c2b, + dnnl_gOIhw2o8i16o2i = dnnl_aBCde2b8c16b2c, + dnnl_gOIdhw2o8i16o2i = dnnl_aBCdef2b8c16b2c, + dnnl_gOIw2o8i16o4i = dnnl_aBCd2b8c16b4c, + dnnl_gOIhw2o8i16o4i = dnnl_aBCde2b8c16b4c, +} dnnl_format_tag_t; + +/// @} dnnl_api_memory + +/// @addtogroup dnnl_api_primitives +/// @{ +/// @addtogroup dnnl_api_primitives_common +/// @{ + +/// Kinds of propagation. +typedef enum { + // TODO: suggest renames + /// Undefined propagation type. + dnnl_prop_kind_undef = 0, + /// Forward data propagation (training mode). In this mode primitives + /// perform computations necessary for subsequent backward propagation. + dnnl_forward_training = 64, + /// Forward data propagation (inference mode). In this mode primitives + /// perform only computations that are necessary for inference and omit + /// computations that are necessary only for backward propagation. + dnnl_forward_inference = 96, + /// Forward data propagation (alias for @c dnnl_forward_training). + dnnl_forward = dnnl_forward_training, + /// Backward propagation (with respect to all parameters). + dnnl_backward = 128, + /// Backward data propagation. + dnnl_backward_data = 160, + /// Backward weights propagation. + dnnl_backward_weights = 192, + /// Backward bias propagation. + dnnl_backward_bias = 193, +} dnnl_prop_kind_t; + +/// Kinds of primitives. Used to implement a way to extend the library with new +/// primitives without changing the ABI. +typedef enum { + /// Undefined primitive + dnnl_undefined_primitive, + /// A reorder primitive. + dnnl_reorder, + /// A shuffle primitive. + dnnl_shuffle, + /// A (out-of-place) concat primitive. + dnnl_concat, + /// A sum primitive. + dnnl_sum, + /// A convolution primitive. + dnnl_convolution, + /// A deconvolution primitive. + dnnl_deconvolution, + /// An element-wise primitive. + dnnl_eltwise, + /// An LRN primitive. + dnnl_lrn, + /// A batch normalization primitive. + dnnl_batch_normalization, + /// An inner product primitive. + dnnl_inner_product, + /// A rnn primitive. + dnnl_rnn, + /// A matrix multiplication primitive (internal). + dnnl_gemm, + /// A binary primitive. + dnnl_binary, + /// A matrix multiplication primitive. + dnnl_matmul, + /// A resampling primitive. + dnnl_resampling, + /// A pooling primitive. + dnnl_pooling, + /// A reduction primitive. + dnnl_reduction, + /// A PReLU primitive. + dnnl_prelu, + /// A softmax primitive. + dnnl_softmax, + /// A layer normalization primitive. + dnnl_layer_normalization, + /// A group normalization primitive. + dnnl_group_normalization, + + // Max value to prevent UB for internal-use-only values. + dnnl_primitive_kind_max = 0x7fff, +} dnnl_primitive_kind_t; + +/// Kinds of algorithms. +typedef enum { + dnnl_alg_kind_undef, + /// Direct convolution + dnnl_convolution_direct = 0x1, + /// Winograd convolution + dnnl_convolution_winograd = 0x2, + /// Convolution algorithm(either direct or Winograd) is chosen just in time + dnnl_convolution_auto = 0x3, + /// Direct deconvolution + dnnl_deconvolution_direct = 0xa, + /// Winograd deconvolution + dnnl_deconvolution_winograd = 0xb, + /// Eltwise: ReLU + dnnl_eltwise_relu = 0x20, + /// Eltwise: hyperbolic tangent non-linearity (tanh) + dnnl_eltwise_tanh, + /// Eltwise: exponential linear unit (elu) + dnnl_eltwise_elu, + /// Eltwise: square + dnnl_eltwise_square, + /// Eltwise: abs + dnnl_eltwise_abs, + /// Eltwise: square root + dnnl_eltwise_sqrt, + /// Eltwise: linear + dnnl_eltwise_linear, + /// Eltwise: soft_relu + dnnl_eltwise_soft_relu, + /// Eltwise: hardsigmoid + dnnl_eltwise_hardsigmoid, + /// Eltwise: logistic + dnnl_eltwise_logistic, + /// Eltwise: exponent + dnnl_eltwise_exp, + /// Eltwise: gelu + /// + /// @note Tanh approximation formula is used to approximate + /// the cumulative distribution function of a Gaussian here + dnnl_eltwise_gelu_tanh, + /// Eltwise: swish + dnnl_eltwise_swish, + /// Eltwise: natural logarithm + dnnl_eltwise_log, + /// Eltwise: clip + dnnl_eltwise_clip, + /// Eltwise: clip version 2 + dnnl_eltwise_clip_v2, + /// Eltwise: pow + dnnl_eltwise_pow, + /// Eltwise: erf-based gelu + dnnl_eltwise_gelu_erf, + /// Eltwise: round + dnnl_eltwise_round, + /// Eltwise: mish + dnnl_eltwise_mish, + /// Eltwise: hardswish + dnnl_eltwise_hardswish, + /// Eltwise: ReLU (dst for backward) + dnnl_eltwise_relu_use_dst_for_bwd = 0x100, + /// Eltwise: hyperbolic tangent non-linearity (tanh) (dst for backward) + dnnl_eltwise_tanh_use_dst_for_bwd, + /// Eltwise: exponential linear unit (elu) (dst for backward) + dnnl_eltwise_elu_use_dst_for_bwd, + /// Eltwise: square root (dst for backward) + dnnl_eltwise_sqrt_use_dst_for_bwd, + /// Eltwise: logistic (dst for backward) + dnnl_eltwise_logistic_use_dst_for_bwd, + /// Eltwise: exp (dst for backward) + dnnl_eltwise_exp_use_dst_for_bwd, + /// Eltwise: clip version 2 (dst for backward) + dnnl_eltwise_clip_v2_use_dst_for_bwd, + /// Max pooling + dnnl_pooling_max = 0x1ff, + /// Average pooling include padding + dnnl_pooling_avg_include_padding = 0x2ff, + /// Average pooling exclude padding + dnnl_pooling_avg_exclude_padding = 0x3ff, + /// Local response normalization (LRN) across multiple channels + dnnl_lrn_across_channels = 0xaff, + /// LRN within a single channel + dnnl_lrn_within_channel = 0xbff, + /// RNN cell + dnnl_vanilla_rnn = 0x1fff, + /// LSTM cell + dnnl_vanilla_lstm = 0x2fff, + /// GRU cell + dnnl_vanilla_gru = 0x3fff, + /// GRU cell with linear before reset + /// + /// Modification of original GRU cell. Differs from #dnnl_vanilla_gru + /// in how the new memory gate is calculated: + /// \f[ c_t = tanh(W_c*x_t + b_{c_x} + r_t*(U_c*h_{t-1}+b_{c_h})) \f] + /// Primitive expects 4 biases on input: + /// \f$[b_{u}, b_{r}, b_{c_x}, b_{c_h}]\f$ + dnnl_lbr_gru = 0x4fff, + /// AUGRU cell + dnnl_vanilla_augru = 0x5fff, + /// AUGRU cell with linear before reset + dnnl_lbr_augru = 0x6fff, + /// Binary add + dnnl_binary_add = 0x1fff0, + /// Binary mul + dnnl_binary_mul = 0x1fff1, + /// Binary max + dnnl_binary_max = 0x1fff2, + /// Binary min + dnnl_binary_min = 0x1fff3, + /// Binary div + dnnl_binary_div = 0x1fff4, + /// Binary sub + dnnl_binary_sub = 0x1fff5, + /// Binary greater or equal + dnnl_binary_ge = 0x1fff6, + /// Binary greater than + dnnl_binary_gt = 0x1fff7, + /// Binary less or equal + dnnl_binary_le = 0x1fff8, + /// Binary less than + dnnl_binary_lt = 0x1fff9, + /// Binary equal + dnnl_binary_eq = 0x1fffa, + /// Binary not equal + dnnl_binary_ne = 0x1fffb, + /// Binary select + dnnl_binary_select = 0x1fffc, + /// Nearest Neighbor Resampling Method + dnnl_resampling_nearest = 0x2fff0, + /// Linear Resampling Method + dnnl_resampling_linear = 0x2fff1, + /// Reduction using max + dnnl_reduction_max, + /// Reduction using min + dnnl_reduction_min, + /// Reduction using sum + dnnl_reduction_sum, + /// Reduction using mul + dnnl_reduction_mul, + /// Reduction using mean + dnnl_reduction_mean, + /// Reduction using lp norm + dnnl_reduction_norm_lp_max, + /// Reduction using lp norm + dnnl_reduction_norm_lp_sum, + /// Reduction using lp norm without final pth-root + dnnl_reduction_norm_lp_power_p_max, + /// Reduction using lp norm without final pth-root + dnnl_reduction_norm_lp_power_p_sum, + /// Softmax + dnnl_softmax_accurate = 0x30000, + /// Logsoftmax + dnnl_softmax_log, +} dnnl_alg_kind_t; + +/// Flags for normalization primitives. +typedef enum { + /// Use no normalization flags. If specified, the library computes mean and + /// variance on forward propagation for training and inference, outputs + /// them on forward propagation for training, and computes the respective + /// derivatives on backward propagation. + /// + /// @note + /// Backward propagation of type prop_kind == #dnnl_backward_data has + /// the same behavior as prop_kind == #dnnl_backward. + dnnl_normalization_flags_none = 0x0U, + + /// Use global statistics. If specified, the library uses mean and + /// variance provided by the user as an input on forward propagation and + /// does not compute their derivatives on backward propagation. Otherwise, + /// the library computes mean and variance on forward propagation for + /// training and inference, outputs them on forward propagation for + /// training, and computes the respective derivatives on backward + /// propagation. + dnnl_use_global_stats = 0x1U, + + /// Use scale parameter. If specified, the user is expected to pass scale as + /// input on forward propagation. On backward propagation of type + /// #dnnl_backward, the library computes its derivative. + dnnl_use_scale = 0x2U, + + /// Use shift parameter. If specified, the user is expected to pass shift as + /// input on forward propagation. On backward propagation of type + /// #dnnl_backward, the library computes its derivative. + dnnl_use_shift = 0x4U, + + /// Fuse normalization with ReLU. On training, normalization will require + /// the workspace to implement backward propagation. On inference, the + /// workspace is not required and behavior is the same as when normalization + /// is fused with ReLU using the post-ops API. + /// + /// @note + /// The flag implies negative slope being 0. On training this is the only + /// configuration supported. For inference, to use non-zero negative slope + /// consider using @ref dev_guide_attributes_post_ops. + dnnl_fuse_norm_relu = 0x8U, + + /// Fuse normalization with an elementwise binary Add operation + /// followed by ReLU. + /// During training, normalization will require a workspace to implement + /// backward propagation. For inference, the workspace is not needed. + /// On forward propagation, an elementwise binary Add operation is applied + /// to the normalization results with an additional input tensor, followed + /// by ReLU with a negative slope of 0. + /// On backward propagation, the result of the backward ReLU operation + /// with the input tensor and workspace from the forward pass is saved + /// to an extra output tensor, and backward normalization is performed. + dnnl_fuse_norm_add_relu = 0x10U, + + /// Use Root Mean Square (RMS) Normalization. In forward propagation, + /// the mean is considered zero, and RMS norm is used instead of variance + /// for scaling. Only the RMS norm is output during forward propagation for + /// training. In backward propagation, the library calculates the derivative + /// with respect to the RMS norm only, assuming the mean is zero. + /// + /// @note + /// When used with #dnnl_use_global_stats, + /// only RMS norm is required to be provided as input. + dnnl_rms_norm = 0x20U, +} dnnl_normalization_flags_t; + +/// @} dnnl_api_primitives_common +/// @} dnnl_api_primitives + +/// @addtogroup dnnl_api_memory +/// @{ + +/// A wildcard value for dimensions that are unknown at a primitive creation +/// time. +#define DNNL_RUNTIME_DIM_VAL INT64_MIN + +/// A `size_t` counterpart of the DNNL_RUNTIME_DIM_VAL. +/// For instance, this value is returned by dnnl_memory_desc_get_size() if +/// either of the dimensions or strides equal to #DNNL_RUNTIME_DIM_VAL. +#define DNNL_RUNTIME_SIZE_VAL ((size_t)DNNL_RUNTIME_DIM_VAL) + +/// @cond DO_NOT_DOCUMENT_THIS +/// Hex representation for a **special** quiet NAN (!= NAN from math.h) +static const union { + unsigned u; + float f; +} DNNL_RUNTIME_F32_VAL_REP = {0x7fc000d0}; +/// @endcond + +/// A wildcard value for floating point values that are unknown at a primitive +/// creation time. +#define DNNL_RUNTIME_F32_VAL (DNNL_RUNTIME_F32_VAL_REP.f) + +/// @cond DO_NOT_DOCUMENT_THIS +static const int DNNL_RUNTIME_S32_VAL_REP = INT32_MIN; +/// @endcond + +/// A wildcard value for int32_t values that are unknown at a primitive creation +/// time. +#define DNNL_RUNTIME_S32_VAL DNNL_RUNTIME_S32_VAL_REP + +/// @struct dnnl_memory_desc +/// An opaque structure to describe a memory descriptor. +struct dnnl_memory_desc; + +/// A memory descriptor handle. +typedef struct dnnl_memory_desc *dnnl_memory_desc_t; + +/// A memory descriptor handle. +typedef const struct dnnl_memory_desc *const_dnnl_memory_desc_t; + +/// @struct dnnl_memory +/// An opaque structure to describe a memory. +struct dnnl_memory; + +/// A memory handle. +typedef struct dnnl_memory *dnnl_memory_t; + +/// A constant memory handle. +typedef const struct dnnl_memory *const_dnnl_memory_t; + +/// @} dnnl_api_memory + +/// @addtogroup dnnl_api_primitives +/// @{ + +/// @addtogroup dnnl_api_rnn +/// @{ + +/// Flags for RNN cell. +typedef enum { + /// Undefined RNN flags + dnnl_rnn_flags_undef = 0x0, + /// Do not add weights gradient to existing diff_weights memory + dnnl_rnn_flags_diff_weights_overwrite = 0x1, +} dnnl_rnn_flags_t; + +/// A direction of RNN primitive execution. +typedef enum { + /// Undefined RNN direction. + dnnl_rnn_direction_undef = 0, + /// Unidirectional execution of RNN primitive from left to right. + dnnl_unidirectional_left2right, + /// Unidirectional execution of RNN primitive from right to left. + dnnl_unidirectional_right2left, + /// Bidirectional execution of RNN primitive with concatenation of the + /// results. + dnnl_bidirectional_concat, + /// Bidirectional execution of RNN primitive with summation of the + /// results. + dnnl_bidirectional_sum, +} dnnl_rnn_direction_t; + +/// @} dnnl_api_rnn + +/// @} dnnl_api_primitives + +/// @addtogroup dnnl_api_primitives +/// @{ +/// @addtogroup dnnl_api_primitives_common +/// @{ + +/// @struct dnnl_primitive_desc +/// @brief An opaque structure to describe a primitive descriptor. +struct dnnl_primitive_desc; + +/// @brief A primitive descriptor handle. +typedef struct dnnl_primitive_desc *dnnl_primitive_desc_t; + +/// @brief A constant primitive descriptor handle. +typedef const struct dnnl_primitive_desc *const_dnnl_primitive_desc_t; + +/// @} dnnl_api_primitives_common + +/// @addtogroup dnnl_api_attributes +/// @{ + +/// Scratchpad mode +typedef enum { + /// The library manages the scratchpad allocation according to the policy + /// specified by the `DNNL_ENABLE_CONCURRENT_EXEC` + /// [build option](@ref dev_guide_build_options) (default). + /// + /// When `DNNL_ENABLE_CONCURRENT_EXEC=OFF` (default), the library + /// scratchpad is common to all primitives to reduce the memory footprint. + /// This configuration comes with limited thread-safety properties, namely + /// primitives can be created and executed in parallel but cannot migrate + /// between threads (in other words, each primitive should be executed in + /// the same thread it was created in). + /// + /// When `DNNL_ENABLE_CONCURRENT_EXEC=ON`, the library scratchpad is + /// private to each primitive. The memory footprint is larger than when + /// using `DNNL_ENABLE_CONCURRENT_EXEC=OFF` but different primitives can be + /// created and run concurrently (the same primitive cannot be run + /// concurrently from two different threads though). + dnnl_scratchpad_mode_library, + /// The user manages the scratchpad allocation by querying and providing + /// the scratchpad memory to primitives. This mode is thread-safe as long + /// as the scratchpad buffers are not used concurrently by two primitive + /// executions. + dnnl_scratchpad_mode_user, +} dnnl_scratchpad_mode_t; + +/// Rounding mode +typedef enum { + /// rounding mode dictated by the floating-point environment + dnnl_rounding_mode_environment, + /// stochastic rounding mode where a random bias is added to the + /// trailing mantissa bits before conversion. + dnnl_rounding_mode_stochastic, +} dnnl_rounding_mode_t; + +/// Quantization kind +typedef enum { + /// used for unspecified quantization kind + dnnl_quantization_mode_undef, + /// static quantization mode: quantization parameter is computed + /// ahead of time with scale applied after zero-point (\f$x_{f32} + /// = scale * (x_{quant} - zp)\f$) and passed to oneDNN as an + /// input. + dnnl_quantization_mode_static_sazp, + /// dynamic quantization mode following OCP MX spec: quantization + /// parameter is computed by oneDNN following the OCP MX spec + /// formula and written as an output. + dnnl_quantization_mode_dynamic_mx, + /// dynamic quantization mode where quantization parameter is computed by + /// oneDNN as \f$scale\_dt(amax(X) / max(dst\_dt))\f$ in `f32` then + /// converted to a scale type and written as an output. + dnnl_quantization_mode_dynamic_fp, +} dnnl_quantization_mode_t; + +/// @struct dnnl_primitive_attr +/// @brief An opaque structure for primitive descriptor attributes. +/// +/// Attributes may contain: +/// - output scales (to scale the result prior to storing it to the memory) +struct dnnl_primitive_attr; + +/// @brief A primitive descriptor attributes handle that controls primitive +/// behavior. +typedef struct dnnl_primitive_attr *dnnl_primitive_attr_t; + +/// @brief A constant primitive descriptor attributes handle. +typedef const struct dnnl_primitive_attr *const_dnnl_primitive_attr_t; + +/// @struct dnnl_post_ops +/// @brief An opaque structure for a chain of post operations. +/// +/// dnnl_post_ops can be used to perform some (trivial) operations like +/// accumulation or eltwise after certain primitives like convolution. +/// +/// Post operations might be combined together, making a chain of post +/// operations. For instance one can configure convolution followed by +/// accumulation followed by eltwise. This might be especially beneficial +/// for residual learning blocks. +/// +/// @warning +/// Of course not all combinations are supported, so the user should handle +/// errors accordingly. +/// +/// Supported post operations: +/// - accumulation (base primitive: convolution) +/// - eltwise (base primitive: convolution) +struct dnnl_post_ops; + +/// @brief A post operation chain handle. +typedef struct dnnl_post_ops *dnnl_post_ops_t; + +/// @brief A constant post operation chain handle. +typedef const struct dnnl_post_ops *const_dnnl_post_ops_t; + +/// @} dnnl_api_attributes + +/// @addtogroup dnnl_api_primitives_common +/// @{ + +/// @struct dnnl_primitive +/// An opaque structure to describe a primitive. +struct dnnl_primitive; +/// A primitive handle. +typedef struct dnnl_primitive *dnnl_primitive_t; +/// A constant primitive handle. +typedef const struct dnnl_primitive *const_dnnl_primitive_t; + +/// Undefined argument. +#define DNNL_ARG_UNDEF 0 +/// Source argument #0. +#define DNNL_ARG_SRC_0 1 +/// A special mnemonic for source argument for primitives that have a +/// single source. An alias for #DNNL_ARG_SRC_0. +#define DNNL_ARG_SRC DNNL_ARG_SRC_0 +/// A special mnemonic for RNN input vector. An alias for +/// #DNNL_ARG_SRC_0. +#define DNNL_ARG_SRC_LAYER DNNL_ARG_SRC_0 +/// A special mnemonic for reorder source argument. An alias for +/// #DNNL_ARG_SRC_0. +#define DNNL_ARG_FROM DNNL_ARG_SRC_0 + +/// Source argument #1. +#define DNNL_ARG_SRC_1 2 +/// A special mnemonic for RNN input recurrent hidden state vector. An alias +/// for #DNNL_ARG_SRC_1. +#define DNNL_ARG_SRC_ITER DNNL_ARG_SRC_1 + +/// Source argument #2. +#define DNNL_ARG_SRC_2 3 +/// A special mnemonic for RNN input recurrent cell state vector. An alias for +/// #DNNL_ARG_SRC_2. +#define DNNL_ARG_SRC_ITER_C DNNL_ARG_SRC_2 + +/// Source argument #3. +#define DNNL_ARG_SRC_3 4 +/// A special mnemonic for RNN input recurrent cell attention vector. An alias for +/// #DNNL_ARG_SRC_3. +#define DNNL_ARG_AUGRU_ATTENTION DNNL_ARG_SRC_3 + +/// Destination argument #0. +#define DNNL_ARG_DST_0 17 +/// A special mnemonic for destination argument for primitives that have a +/// single destination. An alias for #DNNL_ARG_DST_0. +#define DNNL_ARG_DST DNNL_ARG_DST_0 +/// A special mnemonic for reorder destination argument. An alias for +/// #DNNL_ARG_DST_0. +#define DNNL_ARG_TO DNNL_ARG_DST_0 +/// A special mnemonic for RNN output vector. An alias for #DNNL_ARG_DST_0. +#define DNNL_ARG_DST_LAYER DNNL_ARG_DST_0 + +/// Destination argument #1. +#define DNNL_ARG_DST_1 18 +/// A special mnemonic for RNN input recurrent hidden state vector. An +/// alias for #DNNL_ARG_DST_1. +#define DNNL_ARG_DST_ITER DNNL_ARG_DST_1 + +/// Destination argument #2. +#define DNNL_ARG_DST_2 19 +/// A special mnemonic for LSTM output recurrent cell state vector. An +/// alias for #DNNL_ARG_DST_2. +#define DNNL_ARG_DST_ITER_C DNNL_ARG_DST_2 + +/// Weights argument #0. +#define DNNL_ARG_WEIGHTS_0 33 +/// A special mnemonic for primitives that have a single weights +/// argument. Alias for #DNNL_ARG_WEIGHTS_0. +#define DNNL_ARG_WEIGHTS DNNL_ARG_WEIGHTS_0 +/// A special mnemonic for RNN weights applied to the layer input. An +/// alias for #DNNL_ARG_WEIGHTS_0. +#define DNNL_ARG_WEIGHTS_LAYER DNNL_ARG_WEIGHTS_0 + +/// Weights argument #1. +#define DNNL_ARG_WEIGHTS_1 34 +/// A special mnemonic for RNN weights applied to the recurrent input. +/// An alias for #DNNL_ARG_WEIGHTS_1. +#define DNNL_ARG_WEIGHTS_ITER DNNL_ARG_WEIGHTS_1 + +/// Weights argument #2. +#define DNNL_ARG_WEIGHTS_2 35 +/// A special mnemonic for RNN weights applied to the peephole weights. +/// An alias for #DNNL_ARG_WEIGHTS_2. +#define DNNL_ARG_WEIGHTS_PEEPHOLE DNNL_ARG_WEIGHTS_2 + +/// Weights argument #3. +#define DNNL_ARG_WEIGHTS_3 36 +/// A special mnemonic for RNN weights applied to the projection weights. +/// An alias for #DNNL_ARG_WEIGHTS_3. +#define DNNL_ARG_WEIGHTS_PROJECTION DNNL_ARG_WEIGHTS_3 + +/// Bias tensor argument. +#define DNNL_ARG_BIAS 41 + +/// Reduce tensor argument. +#define DNNL_ARG_REDUCE 42 + +/// Note: when adding a new macro after `DNNL_ARG_REDUCE` please reserve a +/// space for potential indices for `DNNL_ARG_REDUCE`. + +/// Mean values tensor argument. +#define DNNL_ARG_MEAN 49 +/// Variance values tensor argument. +#define DNNL_ARG_VARIANCE 50 + +/// A special mnemonic for scale argument of normalization primitives. +#define DNNL_ARG_SCALE 51 +/// A special mnemonic for shift argument of normalization primitives. +#define DNNL_ARG_SHIFT 52 + +/// Workspace tensor argument. Workspace is used to pass information +/// from forward propagation to backward propagation computations. +#define DNNL_ARG_WORKSPACE 64 +/// Scratchpad (temporary storage) tensor argument. +#define DNNL_ARG_SCRATCHPAD 80 + +/// Gradient (diff) of the source argument #0. +#define DNNL_ARG_DIFF_SRC_0 129 +/// A special mnemonic for primitives that have a single diff source argument. +/// An alias for #DNNL_ARG_DIFF_SRC_0. +#define DNNL_ARG_DIFF_SRC DNNL_ARG_DIFF_SRC_0 +/// A special mnemonic for gradient (diff) of RNN input vector. An alias for +/// #DNNL_ARG_DIFF_SRC_0. +#define DNNL_ARG_DIFF_SRC_LAYER DNNL_ARG_DIFF_SRC_0 + +/// Gradient (diff) of the source argument #1. +#define DNNL_ARG_DIFF_SRC_1 130 +/// A special mnemonic for gradient (diff) of RNN input recurrent hidden state +/// vector. An alias for #DNNL_ARG_DIFF_SRC_1. +#define DNNL_ARG_DIFF_SRC_ITER DNNL_ARG_DIFF_SRC_1 + +/// Gradient (diff) of the source argument #2. +#define DNNL_ARG_DIFF_SRC_2 131 +/// A special mnemonic for gradient (diff) of RNN input recurrent cell state +/// vector. An alias for #DNNL_ARG_DIFF_SRC_1. +#define DNNL_ARG_DIFF_SRC_ITER_C DNNL_ARG_DIFF_SRC_2 + +/// Gradient (diff) of the source argument #3. +#define DNNL_ARG_DIFF_SRC_3 132 +/// A special mnemonic for gradient (diff) of RNN input recurrent cell attention +/// vector. An alias for #DNNL_ARG_DIFF_SRC_3. +#define DNNL_ARG_DIFF_AUGRU_ATTENTION DNNL_ARG_DIFF_SRC_3 + +/// Gradient (diff) of the destination argument #0. +#define DNNL_ARG_DIFF_DST_0 145 +/// A special mnemonic for primitives that have a single diff destination +/// argument. An alias for #DNNL_ARG_DIFF_DST_0. +#define DNNL_ARG_DIFF_DST DNNL_ARG_DIFF_DST_0 +/// A special mnemonic for gradient (diff) of RNN output vector. An alias for +/// #DNNL_ARG_DIFF_DST_0. +#define DNNL_ARG_DIFF_DST_LAYER DNNL_ARG_DIFF_DST_0 + +/// Gradient (diff) of the destination argument #1. +#define DNNL_ARG_DIFF_DST_1 146 +/// A special mnemonic for gradient (diff) of RNN input recurrent hidden state +/// vector. An alias for #DNNL_ARG_DIFF_DST_1. +#define DNNL_ARG_DIFF_DST_ITER DNNL_ARG_DIFF_DST_1 + +/// Gradient (diff) of the destination argument #2. +#define DNNL_ARG_DIFF_DST_2 147 +/// A special mnemonic for gradient (diff) of RNN input recurrent cell state +/// vector. An alias for #DNNL_ARG_DIFF_DST_2. +#define DNNL_ARG_DIFF_DST_ITER_C DNNL_ARG_DIFF_DST_2 + +/// Gradient (diff) of the weights argument #0. +#define DNNL_ARG_DIFF_WEIGHTS_0 161 +/// A special mnemonic for primitives that have a single diff weights +/// argument. Alias for #DNNL_ARG_DIFF_WEIGHTS_0. +#define DNNL_ARG_DIFF_WEIGHTS DNNL_ARG_DIFF_WEIGHTS_0 +/// A special mnemonic for diff of RNN weights applied to the layer input. An +/// alias for #DNNL_ARG_DIFF_WEIGHTS_0. +#define DNNL_ARG_DIFF_WEIGHTS_LAYER DNNL_ARG_DIFF_WEIGHTS_0 + +/// Gradient (diff) of the weights argument #1. +#define DNNL_ARG_DIFF_WEIGHTS_1 162 +/// A special mnemonic for diff of RNN weights applied to the recurrent input. +/// An alias for #DNNL_ARG_DIFF_WEIGHTS_1. +#define DNNL_ARG_DIFF_WEIGHTS_ITER DNNL_ARG_DIFF_WEIGHTS_1 + +/// Gradient (diff) of the weights argument #2. +#define DNNL_ARG_DIFF_WEIGHTS_2 163 +/// A special mnemonic for diff of RNN weights applied to the peephole weights. +/// An alias for #DNNL_ARG_DIFF_WEIGHTS_2. +#define DNNL_ARG_DIFF_WEIGHTS_PEEPHOLE DNNL_ARG_DIFF_WEIGHTS_2 + +/// Gradient (diff) of the weights argument #3. +#define DNNL_ARG_DIFF_WEIGHTS_3 164 +/// A special mnemonic for diff of RNN weights applied to the projection +/// weights. An alias for #DNNL_ARG_DIFF_WEIGHTS_3. +#define DNNL_ARG_DIFF_WEIGHTS_PROJECTION DNNL_ARG_DIFF_WEIGHTS_3 + +/// Gradient (diff) of the bias tensor argument. +#define DNNL_ARG_DIFF_BIAS 169 + +/// A special mnemonic for scale argument of normalization primitives. +#define DNNL_ARG_DIFF_SCALE 255 +/// A special mnemonic for shift argument of normalization primitives. +#define DNNL_ARG_DIFF_SHIFT 256 + +/// Dropout offset value passed via a buffer +#define DNNL_ARG_ATTR_DROPOUT_OFFSET 507 + +/// Rounding mode seed for stochastic rounding +/// Single seed needed independently of how many arguments need stochastic rounding +#define DNNL_ARG_ATTR_ROUNDING_SEED 508 + +/// Dropout mask output buffer. +#define DNNL_ARG_ATTR_DROPOUT_MASK 509 + +/// Dropout probability value passed via a buffer. +#define DNNL_ARG_ATTR_DROPOUT_PROBABILITY 510 + +/// Dropout RNG seed value passed via a buffer. +#define DNNL_ARG_ATTR_DROPOUT_SEED 511 + +/// Precomputed reductions argument. +#define DNNL_ARG_ATTR_PRECOMPUTED_REDUCTIONS 512 + +/// Deprecated value. +/// Output scaling factors provided at execution time. +/// Note: there's a collision with +/// `DNNL_ARG_ATTR_PRECOMPUTED_REDUCTIONS | DNNL_ARG_SRC`. +#define DNNL_ARG_ATTR_OUTPUT_SCALES 513 + +/// Starting index for source arguments for primitives that take a variable +/// number of source arguments. +#define DNNL_ARG_MULTIPLE_SRC 1024 +/// Starting index for destination arguments for primitives that produce a +/// variable number of destination arguments. +#define DNNL_ARG_MULTIPLE_DST 2048 + +/// Scaling factors provided at execution time. +#define DNNL_ARG_ATTR_SCALES 4096 + +/// Zero points provided at execution time. +#define DNNL_ARG_ATTR_ZERO_POINTS 8192 + +/// Arguments for fused depthwise convolution. +/// See @ref dev_guide_attributes_post_ops_depthwise_fusion +#define DNNL_ARG_ATTR_POST_OP_DW 16384 + +/// Starting point for a binary post operation. +#define DNNL_ARG_ATTR_MULTIPLE_POST_OP_BASE 32768 + +/// Arguments for a binary post operation. Up to 32 arguments are supported. +/// See @ref dev_guide_attributes_post_ops_binary_fusion +#define DNNL_ARG_ATTR_MULTIPLE_POST_OP(idx) \ + (DNNL_ARG_ATTR_MULTIPLE_POST_OP_BASE * ((idx) + 1)) + +// Dev note: `idx=31` for `DNNL_ARG_ATTR_MULTIPLE_POST_OP` stands right on +// `1 << 20` (or `1048576`), thus, this value can't be used until future rework. + +/// A structure that contains an index and a memory object, and is used to pass +/// arguments to dnnl_primitive_execute(). +typedef struct { + int arg; ///< An argument index, e.g. DNNL_ARG_SRC + dnnl_memory_t memory; ///< Input/output memory +} dnnl_exec_arg_t; + +/// @} dnnl_api_primitives_common + +/// @addtogroup dnnl_api_primitives_common +/// @{ + +/// Primitive descriptor query specification +/// +/// For generic function dnnl_primitive_desc_query(), the type of result must +/// agree with the queried argument. The correspondence table: +/// +/// Query kind | Type of query result +/// --------------------------------|----------------------------- +/// dnnl_query_*_engine | `#dnnl_engine_t *` +/// #dnnl_query_primitive_kind | `#dnnl_primitive_kind_t *` +/// dnnl_query_*_s32 | `int *` +/// dnnl_query_*_s64 | `#dnnl_dim_t *` (same as `int64_t *`) +/// dnnl_query_*_f32 | `float *` +/// dnnl_query_*_f64 | `double *` +/// dnnl_query_*_str | `const char **` +/// dnnl_query_*_md | `#const_dnnl_memory_desc_t *` +/// dnnl_query_*_pd | `#const_dnnl_primitive_desc_t *` +/// dnnl_query_cache_blob_id | `const uint8_t **` +/// dnnl_query_strides | `const #dnnl_dims_t **` +/// dnnl_query_dilations | `const #dnnl_dims_t **` +/// dnnl_query_padding_l | `const #dnnl_dims_t **` +/// dnnl_query_padding_r | `const #dnnl_dims_t **` +/// dnnl_query_flags | `unsigned *` +/// dnnl_query_alg_kind | `#dnnl_alg_kind_t *` +/// dnnl_query_factors | `const float **` +/// dnnl_query_cell_kind | `#dnnl_alg_kind_t *` +/// dnnl_query_direction | `#dnnl_rnn_direction_t *` +/// dnnl_query_activation_kind | `#dnnl_alg_kind_t *` +/// dnnl_query_kernel | `const #dnnl_dims_t **` +/// dnnl_query_dims | `const #dnnl_dims_t **` +/// dnnl_query_data_type | `#dnnl_data_type_t *` +/// dnnl_query_padded_dims | `const #dnnl_dims_t **` +/// dnnl_query_padded_offsets | `const #dnnl_dims_t **` +/// dnnl_query_format_kind | `#dnnl_format_kind_t *` +/// dnnl_query_inner_blks | `const #dnnl_dims_t **` +/// dnnl_query_inner_idxs | `const #dnnl_dims_t **` +/// dnnl_query_sparse_encoding | `#dnnl_sparse_encoding_t *` +/// +/// @note +/// Rule of thumb: all opaque types and structures are returned by +/// reference. All numbers are returned by value. +/// +/// @warning +/// All returned references point to constant objects and are valid only +/// during the lifetime of the queried primitive descriptor. Returned objects +/// must not be destroyed by the user. If you need to keep the object longer +/// than the lifetime of the queried primitive descriptor, use +/// dnnl_primitive_desc_clone() to make a copy. +typedef enum { + dnnl_query_undef = 0, ///< no query + + dnnl_query_engine, ///< execution engine + dnnl_query_primitive_kind, ///< primitive kind + + dnnl_query_num_of_inputs_s32, ///< number of inputs expected + dnnl_query_num_of_outputs_s32, ///< number of outputs expected + + dnnl_query_time_estimate_f64, ///< runtime estimation (seconds) + dnnl_query_memory_consumption_s64, ///< memory consumption -- extra + /// (scratch) memory, additional to + /// all inputs and outputs memory + /// (bytes) + + dnnl_query_scratchpad_engine, ///< scratchpad engine -- engine to be used + /// for creating scratchpad memory + + dnnl_query_impl_info_str, ///< implementation name + + dnnl_query_reorder_src_engine, ///< source engine + dnnl_query_reorder_dst_engine, ///< destination engine + + dnnl_query_prop_kind, ///< propagation kind + + dnnl_query_cache_blob_id_size_s64, ///< size of cache blob ID in bytes + dnnl_query_cache_blob_id, ///< cache blob ID (pointer to array) + + dnnl_query_strides, ///< strides + dnnl_query_dilations, ///< dilations + dnnl_query_padding_l, ///< left padding + dnnl_query_padding_r, ///< right padding + dnnl_query_epsilon_f32, ///< epsilon + dnnl_query_flags, ///< flags + dnnl_query_alg_kind, ///< algorithm kind + dnnl_query_alpha_f32, ///< alpha + dnnl_query_beta_f32, ///< beta + dnnl_query_axis_s32, ///< axis + dnnl_query_local_size_s64, ///< LRN parameter local size + dnnl_query_k_f32, ///< LRN parameter K + dnnl_query_p_f32, ///< Reduction parameter P + dnnl_query_factors, ///< Resampling parameter factors + dnnl_query_cell_kind, ///< RNN parameter cell kind + dnnl_query_direction, ///< RNN parameter direction + dnnl_query_activation_kind, ///< RNN parameter activation kind + dnnl_query_kernel, ///< Pooling parameter kernel + dnnl_query_group_size_s64, ///< Shuffle parameter group size + + // memory descriptor section + dnnl_query_some_md = 128, ///< stub + dnnl_query_src_md, ///< source memory desc + dnnl_query_diff_src_md, ///< source gradient memory desc + dnnl_query_weights_md, ///< weights memory descriptor desc + dnnl_query_diff_weights_md, ///< weights grad. memory desc + dnnl_query_dst_md, ///< destination memory desc + dnnl_query_diff_dst_md, ///< destination grad. memory desc + dnnl_query_workspace_md, ///< workspace memory desc + dnnl_query_scratchpad_md, ///< scratchpad memory desc + dnnl_query_exec_arg_md = 255, ///< memory desc of an execute argument + + dnnl_query_ndims_s32, ///< number of dimensions + dnnl_query_dims, ///< vector of dimensions + dnnl_query_data_type, ///< data type + dnnl_query_submemory_offset_s64, ///< submemory offset + dnnl_query_padded_dims, ///< vector of padded dimensions + dnnl_query_padded_offsets, ///< vector of padded offsets + dnnl_query_format_kind, ///< format kind + dnnl_query_inner_nblks_s32, ///< number of innermost blocks + dnnl_query_inner_blks, ///< vector of sizes of the innermost blocks + dnnl_query_inner_idxs, ///< vector of logical indices of the blocks + dnnl_query_sparse_encoding, ///< Sparse encoding + dnnl_query_nnz_s64, ///< Number of non-zero entries + dnnl_query_num_handles_s32, ///< Number of buffers required for a memory descriptor + + // Max value to prevent UB for internal-use-only values. + dnnl_query_max = 0x7fff, +} dnnl_query_t; + +/// @} dnnl_api_primitives_common + +/// @} dnnl_api_primitives + +/// @addtogroup dnnl_api_service +/// @{ + +/// Disable profiling completely +#define DNNL_JIT_PROFILE_NONE 0u + +/// Enable VTune Profiler integration +#define DNNL_JIT_PROFILE_VTUNE 1u + +/// Enable Linux perf integration via perfmap files +#define DNNL_JIT_PROFILE_LINUX_PERFMAP 2u + +/// Enable Linux perf integration via jitdump files +#define DNNL_JIT_PROFILE_LINUX_JITDUMP 4u + +/// Instruct Linux perf integration via jitdump files to use TSC. @ref +/// DNNL_JIT_PROFILE_LINUX_JITDUMP must be set too for this to take effect. +#define DNNL_JIT_PROFILE_LINUX_JITDUMP_USE_TSC 8u + +/// Enable Linux perf integration (both jitdump and perfmap) +#define DNNL_JIT_PROFILE_LINUX_PERF \ + (DNNL_JIT_PROFILE_LINUX_JITDUMP | DNNL_JIT_PROFILE_LINUX_PERFMAP) + +/// CPU instruction set flags +typedef enum { + /// Library choice of ISA (excepting those listed as initial support) + dnnl_cpu_isa_default = 0x0, + + /// Intel Streaming SIMD Extensions 4.1 (Intel SSE4.1) + dnnl_cpu_isa_sse41 = 0x1, + + /// Intel Advanced Vector Extensions (Intel AVX) + dnnl_cpu_isa_avx = 0x3, + + /// Intel Advanced Vector Extensions 2 (Intel AVX2) + dnnl_cpu_isa_avx2 = 0x7, + + /// Intel AVX2 and Intel Deep Learning Boost (Intel DL Boost) support + dnnl_cpu_isa_avx2_vnni = 0xf, + + /// Intel AVX2 and Intel Deep Learning Boost (Intel DL Boost) + /// with 8-bit integer, float16 and bfloat16 support + dnnl_cpu_isa_avx2_vnni_2 = 0x1f, + + /// Intel AVX-512 subset for Intel Xeon Scalable processor family + /// and Intel Core processor family. + dnnl_cpu_isa_avx512_core = 0x27, + + /// Intel AVX-512 and Intel Deep Learning Boost (Intel DL Boost) support + /// for Intel Xeon Scalable processor family + /// and Intel Core processor family. + dnnl_cpu_isa_avx512_core_vnni = 0x67, + + /// Intel AVX-512, Intel DL Boost and bfloat16 support + /// for Intel Xeon Scalable processor family + /// and Intel Core processor family. + dnnl_cpu_isa_avx512_core_bf16 = 0xe7, + + /// Intel AVX-512 with float16, Intel DL Boost and bfloat16 support + /// for Intel Xeon Scalable processor family + /// and Intel Core processor family. + // TODO: Align avx10_1 values to internal representation. + dnnl_cpu_isa_avx10_1_512 = 0x1ef, + /// @copydoc dnnl_cpu_isa_avx10_1_512 + dnnl_cpu_isa_avx512_core_fp16 = dnnl_cpu_isa_avx10_1_512, + + /// Intel AVX-512 with float16, Intel DL Boost and bfloat16 support and + /// Intel AMX with 8-bit integer and bfloat16 support + // TODO: Align avx10_1 values to internal representation. + dnnl_cpu_isa_avx10_1_512_amx = 0xfef, + /// @copydoc dnnl_cpu_isa_avx10_1_512_amx + dnnl_cpu_isa_avx512_core_amx = dnnl_cpu_isa_avx10_1_512_amx, + + /// Intel AVX-512 with float16, Intel DL Boost and bfloat16 support and + /// Intel AMX with 8-bit integer, bfloat16 and float16 support + // TODO: Align avx10_1 values to internal representation. + dnnl_cpu_isa_avx10_1_512_amx_fp16 = 0x1fef, + /// @copydoc dnnl_cpu_isa_avx10_1_512_amx_fp16 + dnnl_cpu_isa_avx512_core_amx_fp16 = dnnl_cpu_isa_avx10_1_512_amx_fp16, + + /// Intel AVX10.2/512 with float16, Intel DL Boost and bfloat16 support + /// for Intel Xeon Scalable processor family + /// and Intel Core processor family + dnnl_cpu_isa_avx10_2_512 = 0x201ff, + + /// Intel AVX10.2/512 with float16, Intel DL Boost and bfloat16 support and + /// Intel AMX with 8-bit integer, bfloat16, float16, float8 support + dnnl_cpu_isa_avx10_2_512_amx_2 = 0x22fff, +} dnnl_cpu_isa_t; + +/// CPU ISA hints flags +typedef enum { + /// No hints (use default features) + dnnl_cpu_isa_no_hints = 0x0, + + /// Prefer to exclusively use Ymm registers for computations + dnnl_cpu_isa_prefer_ymm = 0x1, +} dnnl_cpu_isa_hints_t; + +/// @} dnnl_api_service + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif // ONEAPI_DNNL_DNNL_TYPES_H + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel.h new file mode 100644 index 0000000000000000000000000000000000000000..13cd16a662e438843ec248556027afd6f92f3eb6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel.h @@ -0,0 +1,350 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2024 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// ukernel C API + +#ifndef ONEAPI_DNNL_DNNL_UKERNEL_H +#define ONEAPI_DNNL_DNNL_UKERNEL_H + +#include "oneapi/dnnl/dnnl.h" +#include "oneapi/dnnl/dnnl_ukernel_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_api_ukernel +/// @{ + +#ifdef DNNL_EXPERIMENTAL_UKERNEL + +/// Creates a ukernel attributes memory storage. +/// +/// @param attr_params Output ukernel attributes memory storage. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ukernel_attr_params_create( + dnnl_ukernel_attr_params_t *attr_params); + +/// Sets post-operations arguments to a storage. +/// +/// @param attr_params Memory pointers storage object. +/// @param post_ops_args A pointer to pointers of post_ops storages. Expected to +/// be packed together. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ukernel_attr_params_set_post_ops_args( + dnnl_ukernel_attr_params_t attr_params, const void **post_ops_args); + +/// Sets tensor A scales argument to a storage. +/// +/// @param attr_params Memory pointers storage object. +/// @param a_scales Pointer to the scales storage. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ukernel_attr_params_set_A_scales( + dnnl_ukernel_attr_params_t attr_params, const void *a_scales); + +/// Sets tensor B scales argument to a storage. +/// +/// If `dnnl_brgemm_set_B_scales` used mask of 2, then at least N values of +/// selected data type are expected. +/// +/// @param attr_params Memory pointers storage object. +/// @param b_scales Pointer to the scales storage. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ukernel_attr_params_set_B_scales( + dnnl_ukernel_attr_params_t attr_params, const void *b_scales); + +/// Sets tensor D scales argument to a storage. +/// +/// @param attr_params Memory pointers storage object. +/// @param d_scales Pointer to the scales storage. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ukernel_attr_params_set_D_scales( + dnnl_ukernel_attr_params_t attr_params, const void *d_scales); + +/// Destroys a ukernel attributes memory storage. +/// +/// @param attr_params Memory pointers storage object to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_ukernel_attr_params_destroy( + dnnl_ukernel_attr_params_t attr_params); + +/// @addtogroup dnnl_api_ukernel_brgemm +/// @{ + +/// Creates a BRGeMM ukernel object. Operates by the following formula: +/// `C = [A x B]`. +/// +/// @param brgemm Output BRGeMM ukernel object. +/// @param M Dimension M of tensor A. +/// @param N Dimension N of tensor B. +/// @param K Dimension K of tensors A and B. +/// @param batch_size Number of batches to process. +/// @param lda Leading dimension of tensor A. +/// @param ldb Leading dimension of tensor B. +/// @param ldc Leading dimension of tensor C. +/// @param a_dt Data type of tensor A. +/// @param b_dt Data type of tensor B. +/// @param c_dt Data type of tensor C. Must be dnnl_f32. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_create(dnnl_brgemm_t *brgemm, dnnl_dim_t M, + dnnl_dim_t N, dnnl_dim_t K, dnnl_dim_t batch_size, dnnl_dim_t lda, + dnnl_dim_t ldb, dnnl_dim_t ldc, dnnl_data_type_t a_dt, + dnnl_data_type_t b_dt, dnnl_data_type_t c_dt); + +/// Sets adding an intermediate result to the output tensor C instead of +/// writing: `C += [A x B]`. +/// +/// @param brgemm BRGeMM ukernel object. +/// @param add_C Value to indicate addition. Can be `0` to skip addition, and +/// `1` to apply addition. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_set_add_C(dnnl_brgemm_t brgemm, int add_C); + +/// Sets post-operations to a BRGeMM ukernel object: `D = post-operations(C)`. +/// +/// Post-operations applies if one of the following holds: +/// * Non-empty attributes are specified. +/// * Output data type `d_dt` is different from accumulation data type `c_dt`. +/// +/// If any of conditions happens, the final call of the accumulation chain +/// must be `dnnl_brgemm_execute_postops`, and `dnnl_brgemm_execute`, otherwise. +/// +/// @param brgemm BRGeMM ukernel object. +/// @param ldd Leading dimension of tensor D. +/// @param d_dt Data type of tensor D. +/// @param post_ops Primitive post operations attribute to extend the kernel +/// operations. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_set_post_ops(dnnl_brgemm_t brgemm, + dnnl_dim_t ldd, dnnl_data_type_t d_dt, const_dnnl_post_ops_t post_ops); + +/// Sets tensor A scales mask to a BRGeMM ukernel object. +/// +/// For quantization flavor tensor A scales apply to accumulation buffer once C +/// is ready. +/// +/// @param brgemm BRGeMM ukernel object. +/// @param a_scale_mask Tensor A scale mask. Can be `0` only. +dnnl_status_t DNNL_API dnnl_brgemm_set_A_scales( + dnnl_brgemm_t brgemm, int a_scale_mask); + +/// Sets tensor B scales mask to a BRGeMM ukernel object. +/// +/// For quantization flavor tensor B scales apply to accumulation buffer once C +/// is ready. +/// +/// @param brgemm BRGeMM ukernel object. +/// @param b_scale_mask Tensor B scale mask. Can be `0` and `2` only. +dnnl_status_t DNNL_API dnnl_brgemm_set_B_scales( + dnnl_brgemm_t brgemm, int b_scale_mask); + +/// Sets tensor D scales mask to a BRGeMM ukernel object. +/// +/// For quantization flavor tensor D scales apply after all post-ops are +/// applied. +/// +/// @param brgemm BRGeMM ukernel object. +/// @param d_scale_mask Tensor D scale mask. Can be `0` only. +dnnl_status_t DNNL_API dnnl_brgemm_set_D_scales( + dnnl_brgemm_t brgemm, int d_scale_mask); + +/// Finalizes initialization of a BRGeMM ukernel object. +/// +/// This step is mandatory to query information from the object. +/// +/// @param brgemm Output BRGeMM ukernel object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_finalize(dnnl_brgemm_t brgemm); + +/// Returns the packing type expected by a tensor B of a BRGeMM ukernel object. +/// +/// @param pack_type Output packing type. Can be `dnnl_brgemm_pack_undef` when +/// ukernel and transform are not supported on the target system, +/// `dnnl_brgemm_no_trans` if packing is not required, and +/// `dnnl_pack_type_pack32` for x64 backend, otherwise. +/// @param a_dt Data type of tensor A. +/// @param b_dt Data type of tensor B. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_get_B_pack_type(dnnl_pack_type_t *pack_type, + dnnl_data_type_t a_dt, dnnl_data_type_t b_dt); + +/// Returns the size of a scratchpad memory needed for the BRGeMM ukernel +/// object. +/// +/// @param brgemm BRGeMM ukernel object. +/// @param size Output size of a buffer required for the BRGeMM ukernel object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_get_scratchpad_size( + const_dnnl_brgemm_t brgemm, size_t *size); + +/// Returns the flag indicating when the call to `dnnl_brgemm_execute_postops` +/// is valid. +/// +/// @param brgemm BRGeMM ukernel object. +/// @param valid The flag indicating if `dnnl_brgemm_execute_postops` is valid +/// for a given ukernel object. `1` is for valid and `0`, otherwise. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_is_execute_postops_valid( + const_dnnl_brgemm_t brgemm, int *valid); + +/// Initializes the hardware-specific context. If no initialization required, +/// returns the success status. +/// +/// @param brgemm BRGeMM ukernel object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_set_hw_context(const_dnnl_brgemm_t brgemm); + +/// Releases the hardware-specific context. Must be used after all the execution +/// calls to BRGeMM ukernel objects. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_release_hw_context(); + +/// Generates an executable part of BRGeMM ukernel object. +/// @param brgemm BRGeMM ukernel object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_generate(dnnl_brgemm_t brgemm); + +/// Executes a BRGeMM ukernel object. +/// +/// @param brgemm BRGeMM ukernel object. +/// @param A_ptr Base pointer to a tensor A. +/// @param B_ptr Base pointer to a tensor B. +/// @param A_B_offsets Pointer to the set of tensor A and tensor B offsets for +/// each batch; the set must be contiguous in memory. Single batch should +/// supply offsets for both tensors A and B simultaneously. The number of +/// batches must coincide with the `batch_size` value passed at the creation +/// stage. +/// @param C_ptr Pointer to a tensor C (accumulation buffer). +/// @param scratchpad_ptr Pointer to a scratchpad buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_execute(const_dnnl_brgemm_t brgemm, + const void *A_ptr, const void *B_ptr, const dnnl_dim_t *A_B_offsets, + void *C_ptr, void *scratchpad_ptr); + +/// Executes a BRGeMM ukernel object with post operations. +/// +/// @param brgemm BRGeMM ukernel object. +/// @param A Base pointer to a tensor A. +/// @param B Base pointer to a tensor B. +/// @param A_B_offsets Pointer to a set of tensor A and tensor B offsets for +/// each batch. A set must be contiguous in memory. A single batch should +/// supply offsets for both tensors A and B simultaneously. The number of +/// batches must coincide with the `batch_size` value passed at the creation +/// stage. +/// @param C_ptr Pointer to a tensor C (accumulation buffer). +/// @param D_ptr Pointer to a tensor D (output buffer). +/// @param scratchpad_ptr Pointer to a scratchpad buffer. +/// @param attr_params Ukernel attributes memory storage. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_execute_postops(const_dnnl_brgemm_t brgemm, + const void *A, const void *B, const dnnl_dim_t *A_B_offsets, + const void *C_ptr, void *D_ptr, void *scratchpad_ptr, + const_dnnl_ukernel_attr_params_t attr_params); + +/// Destroys a BRGeMM ukernel object. +/// +/// @param brgemm BRGeMM ukernel object to destroy. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_brgemm_destroy(dnnl_brgemm_t brgemm); + +/// @} dnnl_api_ukernel_brgemm + +/// @addtogroup dnnl_api_ukernel_transform +/// @{ + +/// Creates a transform object. +/// +/// @param transform Output transform object. +/// @param K Dimension K. +/// @param N Dimension N. +/// @param in_pack_type Input packing type. Must be one of +/// `dnnl_pack_type_no_trans`, or `dnnl_pack_type_trans`. +/// @param in_ld Input leading dimension. +/// @param out_ld Output leading dimension. When packing data, it specifies a +/// block by N dimension. +/// @param in_dt Input data type. +/// @param out_dt Output data type. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_transform_create(dnnl_transform_t *transform, + dnnl_dim_t K, dnnl_dim_t N, dnnl_pack_type_t in_pack_type, + dnnl_dim_t in_ld, dnnl_dim_t out_ld, dnnl_data_type_t in_dt, + dnnl_data_type_t out_dt); + +/// Generates an executable part of transform object. +/// @param transform Transform object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_transform_generate(dnnl_transform_t transform); + +/// Executes a transform object. +/// +/// @param transform Transform object. +/// @param in_ptr Pointer to an input buffer. +/// @param out_ptr Pointer to an output buffer. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_transform_execute( + const_dnnl_transform_t transform, const void *in_ptr, void *out_ptr); + +/// Destroys a transform object. +/// +/// @param transform Transform object. +/// @returns #dnnl_success on success and a status describing the error +/// otherwise. +dnnl_status_t DNNL_API dnnl_transform_destroy(dnnl_transform_t transform); + +/// @} dnnl_api_ukernel_transform + +#endif + +/// @} dnnl_api_ukernel + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif /* ONEAPI_DNNL_DNNL_UKERNEL_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel.hpp b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel.hpp new file mode 100644 index 0000000000000000000000000000000000000000..367a377929d07745b111de49496c859443c2ea6c --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel.hpp @@ -0,0 +1,478 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2024 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// ukernel C++ API + +#ifndef ONEAPI_DNNL_DNNL_UKERNEL_HPP +#define ONEAPI_DNNL_DNNL_UKERNEL_HPP +// NOLINTBEGIN(readability-identifier-naming) + +#include "oneapi/dnnl/dnnl.hpp" +#include "oneapi/dnnl/dnnl_ukernel.h" + +/// @addtogroup dnnl_api oneDNN API +/// @{ + +/// oneDNN namespace +namespace dnnl { + +#ifdef DNNL_EXPERIMENTAL_UKERNEL + +/// @addtogroup dnnl_api_utils +/// @{ + +/// @cond DO_NOT_DOCUMENT_THIS + +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_brgemm_t p) { + return dnnl_brgemm_destroy(p); + } +}; + +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_transform_t p) { + return dnnl_transform_destroy(p); + } +}; + +template <> +struct handle_traits { + static dnnl_status_t destructor(dnnl_ukernel_attr_params_t p) { + return dnnl_ukernel_attr_params_destroy(p); + } +}; + +/// @endcond + +/// @} dnnl_api_utils + +#endif + +/// @addtogroup dnnl_api_ukernel Ukernels +/// Collection of ukernels +/// @{ + +/// ukernel namespace +namespace ukernel { + +#ifdef DNNL_EXPERIMENTAL_UKERNEL + +/// @addtogroup dnnl_api_ukernel_utils ukernel utils +/// ukernel utility functions +/// \ingroup dnnl_api_ukernel +/// @{ + +/// Packing specification +enum class pack_type { + /// Undefined pack type. A guard value. + undef = dnnl_pack_type_undef, + /// Plain, not transposed layout. Similar to format_tag::ab. + no_trans = dnnl_pack_type_no_trans, + /// Plain, transposed layout. Similar to format_tag::ba. + trans = dnnl_pack_type_trans, + /// Packed by 32 bits along K dimension layout. + pack32 = dnnl_pack_type_pack32, +}; + +/// Ukernel attributes memory storage +struct attr_params : public handle { + /// Constructs a ukernel attributes memory storage. + attr_params() { + dnnl_ukernel_attr_params_t c_params = nullptr; + dnnl_status_t status = dnnl_ukernel_attr_params_create(&c_params); + error::wrap_c_api( + status, "could not create an attributes memory storage"); + reset(c_params); + } + + /// Sets post-operations arguments to a storage. + /// + /// @param post_ops_args Pointer to pointers of post_ops storages. + /// Expected to be packed together. + void set_post_ops_args(const void **post_ops_args) { + dnnl_status_t status = dnnl_ukernel_attr_params_set_post_ops_args( + get(), post_ops_args); + if (status != dnnl_success) + error::wrap_c_api( + status, "could not set post operations arguments"); + } + + /// Sets tensor A scales arguments to a storage. + /// + /// @param a_scales Pointer to scales storage. + void set_A_scales(const void *a_scales) { + dnnl_status_t status + = dnnl_ukernel_attr_params_set_A_scales(get(), a_scales); + if (status != dnnl_success) + error::wrap_c_api(status, "could not set A scales argument"); + } + + /// Sets tensor B scales arguments to a storage. + /// + /// If @ref attr_params::set_B_scales used mask of 2, then at + /// least N values of selected data type are expected. + /// + /// @param b_scales Pointer to scales storage. + void set_B_scales(const void *b_scales) { + dnnl_status_t status + = dnnl_ukernel_attr_params_set_B_scales(get(), b_scales); + if (status != dnnl_success) + error::wrap_c_api(status, "could not set B scales argument"); + } + + /// Sets tensor D scales arguments to a storage. + /// + /// @param d_scales Pointer to scales storage. + void set_D_scales(const void *d_scales) { + dnnl_status_t status + = dnnl_ukernel_attr_params_set_D_scales(get(), d_scales); + if (status != dnnl_success) + error::wrap_c_api(status, "could not set D scales argument"); + } +}; +/// @} dnnl_api_ukernel_utils + +/// @addtogroup dnnl_api_ukernel_brgemm BRGeMM ukernel +/// BRGeMM ukernel routines +/// @{ + +/// BRGeMM ukernel +struct brgemm : public handle { + /// Default constructor. Produces an empty object. + brgemm() = default; + + /// Constructs a BRGeMM ukernel object. Operates by the following formula: + /// `C = [A x B]`. + /// + /// @param M Dimension M of tensor A. + /// @param N Dimension N of tensor B. + /// @param K Dimension K of tensors A and B. + /// @param batch_size Number of batches to process. + /// @param lda Leading dimension of tensor A. + /// @param ldb Leading dimension of tensor B. + /// @param ldc Leading dimension of tensor C. + /// @param a_dt Data type of tensor A. + /// @param b_dt Data type of tensor B. + /// @param c_dt Data type of tensor C. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + brgemm(memory::dim M, memory::dim N, memory::dim K, memory::dim batch_size, + memory::dim lda, memory::dim ldb, memory::dim ldc, + memory::data_type a_dt, memory::data_type b_dt, + memory::data_type c_dt, bool allow_empty = false) { + + dnnl_brgemm_t brgemm = nullptr; + dnnl_status_t status = dnnl_brgemm_create(&brgemm, M, N, K, batch_size, + lda, ldb, ldc, memory::convert_to_c(a_dt), + memory::convert_to_c(b_dt), memory::convert_to_c(c_dt)); + + if (!allow_empty) + error::wrap_c_api( + status, "could not create a BRGeMM ukernel object"); + reset(brgemm); + } + + /// Sets adding an intermediate result to the output tensor C instead of + /// writing: `C += [A x B]`. + /// + /// @param add_C Value to indicate addition. `false` to skip addition, and + /// `true` to apply addition. + void set_add_C(bool add_C) { + dnnl_status_t status + = dnnl_brgemm_set_add_C(get(), static_cast(add_C)); + if (status != dnnl_success) + error::wrap_c_api(status, "could not set add_C attribute"); + } + + /// Sets post-operations to a BRGeMM ukernel object: + /// `D = post-operations(C)`. + /// + /// Post-operations applies if one of the following holds: + /// * Non-empty post-operations are specified. + /// * Output data type `d_dt` is different from accumulation data type + /// `c_dt`. + /// + /// @param ldd Leading dimension of tensor D. + /// @param d_dt Data type of tensor D. + /// @param po Primitive post-operation attributes to extend the kernel + /// operations. + void set_post_ops(memory::dim ldd, memory::data_type d_dt, + const post_ops &po = default_post_ops()) { + dnnl_status_t status = dnnl_brgemm_set_post_ops( + get(), ldd, memory::convert_to_c(d_dt), po.get()); + if (status != dnnl_success) + error::wrap_c_api(status, "could not set post operations"); + } + + /// Sets tensor A scales mask to a BRGeMM ukernel object. + /// + /// For quantization flavor tensor A scales apply to accumulation buffer + /// once C is ready. + /// + /// @param a_scale_mask Tensor A scale mask. Can be `0` only. + void set_A_scales(int a_scale_mask) { + dnnl_status_t status = dnnl_brgemm_set_A_scales(get(), a_scale_mask); + if (status != dnnl_success) + error::wrap_c_api(status, "could not set A scales"); + } + + /// Sets tensor B scales mask to a BRGeMM ukernel object. + /// + /// For quantization flavor tensor B scales apply to accumulation buffer + /// once C is ready. + /// + /// @param b_scale_mask Tensor B scale mask. Can be `0` and `2` only. + void set_B_scales(int b_scale_mask) { + dnnl_status_t status = dnnl_brgemm_set_B_scales(get(), b_scale_mask); + if (status != dnnl_success) + error::wrap_c_api(status, "could not set B scales"); + } + + /// Sets tensor D scales mask to a BRGeMM ukernel object. + /// + /// For quantization flavor tensor D scales apply after all post-ops are + /// applied. + /// + /// @param d_scale_mask Tensor D scale mask. Can be `0` only. + void set_D_scales(int d_scale_mask) { + dnnl_status_t status = dnnl_brgemm_set_D_scales(get(), d_scale_mask); + if (status != dnnl_success) + error::wrap_c_api(status, "could not set D scales"); + } + + /// Finalizes initialization of a BRGeMM ukernel object. + /// + /// This step must be performed prior to querying information from the + /// object. + /// + /// Returns `true` if the call successfully completed, and `false`, + /// otherwise. + bool finalize() { + dnnl_status_t status = dnnl_brgemm_finalize(get()); + return status == dnnl_success; + } + + /// Returns the packing type expected by a tensor B of a BRGeMM ukernel + /// object. + /// + /// @param a_dt Data type of tensor A. + /// @param b_dt Data type of tensor B. + static pack_type get_B_pack_type( + memory::data_type a_dt, memory::data_type b_dt) { + dnnl_pack_type_t c_pack_type; + dnnl_status_t status = dnnl_brgemm_get_B_pack_type(&c_pack_type, + memory::convert_to_c(a_dt), memory::convert_to_c(b_dt)); + return status == dnnl_success ? static_cast(c_pack_type) + : dnnl::ukernel::pack_type::undef; + } + + /// Returns the size of a scratchpad memory needed for the BRGeMM ukernel + /// object. + size_t get_scratchpad_size() const { + size_t size; + dnnl_status_t status = dnnl_brgemm_get_scratchpad_size(get(), &size); + if (status != dnnl_success) + error::wrap_c_api(status, + "could not query a scratchpad size from a BRGeMM ukernel " + "object"); + return size; + } + + /// Returns the flag indicating when the call to execute with post + /// operations is valid. + /// + /// `True` is for a valid call, `false`, otherwise. + bool is_execute_postops_valid() const { + int valid; + dnnl_status_t status + = dnnl_brgemm_is_execute_postops_valid(get(), &valid); + if (status != dnnl_success) + error::wrap_c_api(status, + "could not query a flag for execute postops from a BRGeMM " + "ukernel object"); + return static_cast(valid); + } + + /// Initializes the hardware-specific context. Affects the global state for + /// all BRGeMM ukernel objects. If no initialization required, returns. + void set_hw_context() const { + dnnl_status_t status = dnnl_brgemm_set_hw_context(get()); + if (status != dnnl_success) + error::wrap_c_api(status, "could not set hardware context"); + } + + /// Releases the hardware-specific context. Affects the global state for + /// all BRGeMM ukernel objects. Must be used after all the execution calls + /// to BRGeMM ukernel objects. + static void release_hw_context() { + dnnl_status_t status = dnnl_brgemm_release_hw_context(); + if (status != dnnl_success) + error::wrap_c_api(status, "could not release hardware context"); + } + + /// Generates an executable part of BRGeMM ukernel object. + void generate() { + dnnl_status_t status = dnnl_brgemm_generate(get()); + if (status != dnnl_success) + error::wrap_c_api(status, "could not generate a kernel"); + } + + /// Executes a BRGeMM ukernel object. + /// + /// @param A Base pointer to a tensor A. + /// @param B Base pointer to a tensor B. + /// @param A_B_offsets Vector of pairs of tensors A and B offsets for + /// each batch. The number of batches must coincide with the + /// `batch_size` value passed at object construction stage. + /// @param C Pointer to a tensor C (accumulation buffer). + /// @param scratchpad Pointer to a scratchpad buffer. + void execute(const void *A, const void *B, + const std::vector> &A_B_offsets, + void *C, void *scratchpad) const { + // TODO: export batch_element to C API later for user to fill it and + // pass directly to the call. + dnnl_status_t status = dnnl_brgemm_execute(get(), A, B, + (const dnnl_dim_t *)A_B_offsets.data(), C, scratchpad); + if (status != dnnl_success) + error::wrap_c_api( + status, "could not execute a BRGeMM ukernel object"); + } + + /// Executes a BRGeMM ukernel object with post operations. + /// + /// @param A Base pointer to a tensor A. + /// @param B Base pointer to a tensor B. + /// @param A_B_offsets Vector of pairs of tensors A and B offsets for + /// each batch. The number of batches must coincide with the + /// `batch_size` value passed at object construction stage. + /// @param C Pointer to a tensor C (accumulation buffer). + /// @param D Pointer to a tensor D (output buffer). + /// @param scratchpad Pointer to a scratchpad buffer. + /// @param params Post-op memory arguments. Must be passed If binary + /// post-op or scales were set. + void execute(const void *A, const void *B, + const std::vector> &A_B_offsets, + const void *C, void *D, void *scratchpad, + const attr_params ¶ms = default_attr_params()) const { + // TODO: export batch_element to C API later for user to fill it and + // pass directly to the call. + dnnl_status_t status = dnnl_brgemm_execute_postops(get(), A, B, + (const dnnl_dim_t *)A_B_offsets.data(), C, D, scratchpad, + params.get()); + if (status != dnnl_success) + error::wrap_c_api( + status, "could not execute a BRGeMM ukernel object"); + } + + /// Returns a constant reference to a static instance of default constructed + /// primitive post-operations attribute. + static const post_ops &default_post_ops() { + static const post_ops po; + return po; + } + + /// Returns a constant reference to a static instance of default constructed + /// ukernel attributes parameters. + static const attr_params &default_attr_params() { + static const attr_params ap; + return ap; + } +}; +/// @} dnnl_api_ukernel_brgemm + +/// @addtogroup dnnl_api_ukernel_transform Transform ukernel +/// Transform routines +/// @{ + +/// Transform ukernel +struct transform : public handle { + /// Default constructor. Produces an empty object. + transform() = default; + + /// Constructs a transform object. + /// + /// @param K Dimension K. + /// @param N Dimension N. + /// @param in_pack_type Input packing type. Must be one of + /// `pack_type::no_trans`, or `pack_type::trans`. + /// @param in_ld Input leading dimension. + /// @param out_ld Output leading dimension. Specifies a block by N dimension + /// during data packing. + /// @param in_dt Input data type. + /// @param out_dt Output data type. + /// @param allow_empty A flag signifying whether construction is + /// allowed to fail without throwing an exception. In this case an + /// empty object will be produced. This flag is optional and + /// defaults to false. + transform(memory::dim K, memory::dim N, pack_type in_pack_type, + memory::dim in_ld, memory::dim out_ld, memory::data_type in_dt, + memory::data_type out_dt, bool allow_empty = false) { + + dnnl_transform_t transform = nullptr; + dnnl_status_t status = dnnl_transform_create(&transform, K, N, + static_cast(in_pack_type), in_ld, out_ld, + memory::convert_to_c(in_dt), memory::convert_to_c(out_dt)); + + if (!allow_empty) + error::wrap_c_api(status, + "could not create a BRGeMM ukernel packing B object"); + reset(transform); + } + + /// Generates an executable part of transform object. + void generate() { + dnnl_status_t status = dnnl_transform_generate(get()); + if (status != dnnl_success) + error::wrap_c_api(status, + "could not generate a BRGeMM ukernel packing B object"); + } + + /// Executes a transform object. + /// + /// @param in Pointer to an input buffer. + /// @param out Pointer to an output buffer. + void execute(const void *in, void *out) const { + dnnl_status_t status = dnnl_transform_execute(get(), in, out); + if (status != dnnl_success) + error::wrap_c_api(status, + "could not execute a BRGeMM ukernel packing B object"); + } +}; + +/// @} dnnl_api_ukernel_transform + +#endif + +} // namespace ukernel + +/// @} dnnl_api_ukernel + +} // namespace dnnl + +/// @} dnnl_api + +// NOLINTEND(readability-identifier-naming) +#endif /* ONEAPI_DNNL_DNNL_UKERNEL_HPP */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel_types.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel_types.h new file mode 100644 index 0000000000000000000000000000000000000000..44fca4d1491412512ef79c0063279d3dc0ff645d --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel_types.h @@ -0,0 +1,103 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2024 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/// @file +/// ukernel C API types definitions + +#ifndef ONEAPI_DNNL_DNNL_UKERNEL_TYPES_H +#define ONEAPI_DNNL_DNNL_UKERNEL_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "oneapi/dnnl/dnnl_types.h" + +/// @addtogroup dnnl_api +/// @{ + +/// @addtogroup dnnl_api_ukernel +/// @{ + +#ifdef DNNL_EXPERIMENTAL_UKERNEL + +/// Packing specification +typedef enum { + /// Undefined pack type. A guard value. + dnnl_pack_type_undef = 0, + /// Plain, not transposed layout. Similar to format_tag::ab. + dnnl_pack_type_no_trans, + /// Plain, transposed layout. Similar to format_tag::ba. + dnnl_pack_type_trans, + /// Packed by 32 bits along K dimension layout. + dnnl_pack_type_pack32, +} dnnl_pack_type_t; + +/// @struct dnnl_ukernel_attr_params +/// An opaque structure to describe ukernel attributes memory storage. +struct dnnl_ukernel_attr_params; + +/// A ukernel attributes memory storage handle. +typedef struct dnnl_ukernel_attr_params *dnnl_ukernel_attr_params_t; + +/// A constant ukernel attributes memory storage handle. +typedef const struct dnnl_ukernel_attr_params *const_dnnl_ukernel_attr_params_t; + +/// @addtogroup dnnl_api_ukernel_brgemm +/// @{ + +/// @struct dnnl_brgemm +/// An opaque structure to describe a brgemm ukernel. +struct dnnl_brgemm; + +/// A brgemm ukernel handle. +typedef struct dnnl_brgemm *dnnl_brgemm_t; + +/// A constant brgemm ukernel handle. +typedef const struct dnnl_brgemm *const_dnnl_brgemm_t; + +/// @} dnnl_api_ukernel_brgemm + +/// @addtogroup dnnl_api_ukernel_transform +/// @{ + +/// @struct dnnl_transform +/// An opaque structure to describe a transform routine. +struct dnnl_transform; + +/// A transform routine handle. +typedef struct dnnl_transform *dnnl_transform_t; + +/// A constant transform routine handle. +typedef const struct dnnl_transform *const_dnnl_transform_t; + +/// @} dnnl_api_ukernel_transform +#endif + +/// @} dnnl_api_ukernel + +/// @} dnnl_api + +#ifdef __cplusplus +} +#endif + +#endif /* ONEAPI_DNNL_DNNL_UKERNEL_TYPES_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_version.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_version.h new file mode 100644 index 0000000000000000000000000000000000000000..2b1a4837a025afca4ada7b2833dc818487db2496 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_version.h @@ -0,0 +1,38 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_VERSION_H +#define ONEAPI_DNNL_DNNL_VERSION_H + +// clang-format off + +/// Major version +#define DNNL_VERSION_MAJOR 3 + +/// Minor version +#define DNNL_VERSION_MINOR 11 + +/// Patch version +#define DNNL_VERSION_PATCH 2 + +// clang-format on + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_version_hash.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_version_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..c76a851061148b6528e7b881e5b178aa270b47ae --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_version_hash.h @@ -0,0 +1,36 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/******************************************************************************* +* Copyright 2024 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#ifndef ONEAPI_DNNL_DNNL_VERSION_HASH_H +#define ONEAPI_DNNL_DNNL_VERSION_HASH_H + +// clang-format off + +/// Note: this macro and header file were moved to a separate instance to avoid +/// incremental build issues as moving from commit to commit would trigger a +/// complete library rebuild. Including a generated header file in a single +/// translation unit makes this problem go away. +/// Git commit hash +#define DNNL_VERSION_HASH "03c022d3ffdcee958cfacbe720048e725fdf644c" + +// clang-format on + +#endif + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/psimd.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/psimd.h new file mode 100644 index 0000000000000000000000000000000000000000..8c8a96bf67bb294d6e0f4763bf42a54fbccc7541 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/psimd.h @@ -0,0 +1,1389 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#pragma once +#ifndef PSIMD_H +#define PSIMD_H + +#if defined(__CUDA_ARCH__) + /* CUDA compiler */ + #define PSIMD_INTRINSIC __forceinline__ __device__ +#elif defined(__OPENCL_VERSION__) + /* OpenCL compiler */ + #define PSIMD_INTRINSIC inline static +#elif defined(__INTEL_COMPILER) + /* Intel compiler, even on Windows */ + #define PSIMD_INTRINSIC inline static __attribute__((__always_inline__)) +#elif defined(__GNUC__) + /* GCC-compatible compiler (gcc/clang/icc) */ + #define PSIMD_INTRINSIC inline static __attribute__((__always_inline__)) +#elif defined(_MSC_VER) + /* MSVC-compatible compiler (cl/icl/clang-cl) */ + #define PSIMD_INTRINSIC __forceinline static +#elif defined(__cplusplus) + /* Generic C++ compiler */ + #define PSIMD_INTRINSIC inline static +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + /* Generic C99 compiler */ + #define PSIMD_INTRINSIC inline static +#else + /* Generic C compiler */ + #define PSIMD_INTRINSIC static +#endif + +#if defined(__GNUC__) || defined(__clang__) + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + #include + #endif + + #if defined(__SSE2__) + #include + #endif + + #if defined(__SSE3__) + #include + #endif + + #if defined(__SSSE3__) + #include + #endif + + #if defined(__SSE4_1__) + #include + #endif + + #if defined(__SSE4_2__) + #include + #endif + + #if defined(__AVX__) + #include + #endif +#elif defined(_MSC_VER) + #include +#endif + +#if defined(__cplusplus) + #define PSIMD_CXX_SYNTAX +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) + #define PSIMD_C11_SYNTAX +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + #define PSIMD_C99_SYNTAX +#else + #define PSIMD_C89_SYNTAX +#endif + +#if defined(__cplusplus) && (__cplusplus >= 201103L) + #include + #include +#elif !defined(__OPENCL_VERSION__) + #include + #include +#endif + +#if defined(__GNUC__) || defined(__clang__) + #define PSIMD_HAVE_F64 0 + #define PSIMD_HAVE_F32 1 + #define PSIMD_HAVE_U8 1 + #define PSIMD_HAVE_S8 1 + #define PSIMD_HAVE_U16 1 + #define PSIMD_HAVE_S16 1 + #define PSIMD_HAVE_U32 1 + #define PSIMD_HAVE_S32 1 + #define PSIMD_HAVE_U64 0 + #define PSIMD_HAVE_S64 0 + + typedef int8_t psimd_s8 __attribute__((vector_size(16), aligned(1))); + typedef uint8_t psimd_u8 __attribute__((vector_size(16), aligned(1))); + typedef int16_t psimd_s16 __attribute__((vector_size(16), aligned(2))); + typedef uint16_t psimd_u16 __attribute__((vector_size(16), aligned(2))); + typedef int32_t psimd_s32 __attribute__((vector_size(16), aligned(4))); + typedef uint32_t psimd_u32 __attribute__((vector_size(16), aligned(4))); + typedef float psimd_f32 __attribute__((vector_size(16), aligned(4))); + + typedef struct { + psimd_s8 lo; + psimd_s8 hi; + } psimd_s8x2; + + typedef struct { + psimd_u8 lo; + psimd_u8 hi; + } psimd_u8x2; + + typedef struct { + psimd_s16 lo; + psimd_s16 hi; + } psimd_s16x2; + + typedef struct { + psimd_u16 lo; + psimd_u16 hi; + } psimd_u16x2; + + typedef struct { + psimd_s32 lo; + psimd_s32 hi; + } psimd_s32x2; + + typedef struct { + psimd_u32 lo; + psimd_u32 hi; + } psimd_u32x2; + + typedef struct { + psimd_f32 lo; + psimd_f32 hi; + } psimd_f32x2; + + /* Bit casts */ + PSIMD_INTRINSIC psimd_u32x2 psimd_cast_s32x2_u32x2(psimd_s32x2 v) { + return (psimd_u32x2) { .lo = (psimd_u32) v.lo, .hi = (psimd_u32) v.hi }; + } + + PSIMD_INTRINSIC psimd_f32x2 psimd_cast_s32x2_f32x2(psimd_s32x2 v) { + return (psimd_f32x2) { .lo = (psimd_f32) v.lo, .hi = (psimd_f32) v.hi }; + } + + PSIMD_INTRINSIC psimd_s32x2 psimd_cast_u32x2_s32x2(psimd_u32x2 v) { + return (psimd_s32x2) { .lo = (psimd_s32) v.lo, .hi = (psimd_s32) v.hi }; + } + + PSIMD_INTRINSIC psimd_f32x2 psimd_cast_u32x2_f32x2(psimd_u32x2 v) { + return (psimd_f32x2) { .lo = (psimd_f32) v.lo, .hi = (psimd_f32) v.hi }; + } + + PSIMD_INTRINSIC psimd_s32x2 psimd_cast_f32x2_s32x2(psimd_f32x2 v) { + return (psimd_s32x2) { .lo = (psimd_s32) v.lo, .hi = (psimd_s32) v.hi }; + } + + PSIMD_INTRINSIC psimd_u32x2 psimd_cast_f32x2_u32x2(psimd_f32x2 v) { + return (psimd_u32x2) { .lo = (psimd_u32) v.lo, .hi = (psimd_u32) v.hi }; + } + + /* Swap */ + PSIMD_INTRINSIC void psimd_swap_s8(psimd_s8 a[1], psimd_s8 b[1]) { + const psimd_s8 new_a = *b; + const psimd_s8 new_b = *a; + *a = new_a; + *b = new_b; + } + + PSIMD_INTRINSIC void psimd_swap_u8(psimd_u8 a[1], psimd_u8 b[1]) { + const psimd_u8 new_a = *b; + const psimd_u8 new_b = *a; + *a = new_a; + *b = new_b; + } + + PSIMD_INTRINSIC void psimd_swap_s16(psimd_s16 a[1], psimd_s16 b[1]) { + const psimd_s16 new_a = *b; + const psimd_s16 new_b = *a; + *a = new_a; + *b = new_b; + } + + PSIMD_INTRINSIC void psimd_swap_u16(psimd_u16 a[1], psimd_u16 b[1]) { + const psimd_u16 new_a = *b; + const psimd_u16 new_b = *a; + *a = new_a; + *b = new_b; + } + + PSIMD_INTRINSIC void psimd_swap_s32(psimd_s32 a[1], psimd_s32 b[1]) { + const psimd_s32 new_a = *b; + const psimd_s32 new_b = *a; + *a = new_a; + *b = new_b; + } + + PSIMD_INTRINSIC void psimd_swap_u32(psimd_u32 a[1], psimd_u32 b[1]) { + const psimd_u32 new_a = *b; + const psimd_u32 new_b = *a; + *a = new_a; + *b = new_b; + } + + PSIMD_INTRINSIC void psimd_swap_f32(psimd_f32 a[1], psimd_f32 b[1]) { + const psimd_f32 new_a = *b; + const psimd_f32 new_b = *a; + *a = new_a; + *b = new_b; + } + + /* Zero-initialization */ + PSIMD_INTRINSIC psimd_s8 psimd_zero_s8(void) { + return (psimd_s8) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + } + + PSIMD_INTRINSIC psimd_u8 psimd_zero_u8(void) { + return (psimd_u8) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + } + + PSIMD_INTRINSIC psimd_s16 psimd_zero_s16(void) { + return (psimd_s16) { 0, 0, 0, 0, 0, 0, 0, 0 }; + } + + PSIMD_INTRINSIC psimd_u16 psimd_zero_u16(void) { + return (psimd_u16) { 0, 0, 0, 0, 0, 0, 0, 0 }; + } + + PSIMD_INTRINSIC psimd_s32 psimd_zero_s32(void) { + return (psimd_s32) { 0, 0, 0, 0 }; + } + + PSIMD_INTRINSIC psimd_u32 psimd_zero_u32(void) { + return (psimd_u32) { 0, 0, 0, 0 }; + } + + PSIMD_INTRINSIC psimd_f32 psimd_zero_f32(void) { + return (psimd_f32) { 0.0f, 0.0f, 0.0f, 0.0f }; + } + + /* Initialization to the same constant */ + PSIMD_INTRINSIC psimd_s8 psimd_splat_s8(int8_t c) { + return (psimd_s8) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }; + } + + PSIMD_INTRINSIC psimd_u8 psimd_splat_u8(uint8_t c) { + return (psimd_u8) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }; + } + + PSIMD_INTRINSIC psimd_s16 psimd_splat_s16(int16_t c) { + return (psimd_s16) { c, c, c, c, c, c, c, c }; + } + + PSIMD_INTRINSIC psimd_u16 psimd_splat_u16(uint16_t c) { + return (psimd_u16) { c, c, c, c, c, c, c, c }; + } + + PSIMD_INTRINSIC psimd_s32 psimd_splat_s32(int32_t c) { + return (psimd_s32) { c, c, c, c }; + } + + PSIMD_INTRINSIC psimd_u32 psimd_splat_u32(uint32_t c) { + return (psimd_u32) { c, c, c, c }; + } + + PSIMD_INTRINSIC psimd_f32 psimd_splat_f32(float c) { + return (psimd_f32) { c, c, c, c }; + } + + /* Load vector */ + PSIMD_INTRINSIC psimd_s8 psimd_load_s8(const void* address) { + return *((const psimd_s8*) address); + } + + PSIMD_INTRINSIC psimd_u8 psimd_load_u8(const void* address) { + return *((const psimd_u8*) address); + } + + PSIMD_INTRINSIC psimd_s16 psimd_load_s16(const void* address) { + return *((const psimd_s16*) address); + } + + PSIMD_INTRINSIC psimd_u16 psimd_load_u16(const void* address) { + return *((const psimd_u16*) address); + } + + PSIMD_INTRINSIC psimd_s32 psimd_load_s32(const void* address) { + return *((const psimd_s32*) address); + } + + PSIMD_INTRINSIC psimd_u32 psimd_load_u32(const void* address) { + return *((const psimd_u32*) address); + } + + PSIMD_INTRINSIC psimd_f32 psimd_load_f32(const void* address) { + return *((const psimd_f32*) address); + } + + PSIMD_INTRINSIC psimd_s8 psimd_load_splat_s8(const void* address) { + return psimd_splat_s8(*((const int8_t*) address)); + } + + PSIMD_INTRINSIC psimd_u8 psimd_load_splat_u8(const void* address) { + return psimd_splat_u8(*((const uint8_t*) address)); + } + + PSIMD_INTRINSIC psimd_s16 psimd_load_splat_s16(const void* address) { + return psimd_splat_s16(*((const int16_t*) address)); + } + + PSIMD_INTRINSIC psimd_u16 psimd_load_splat_u16(const void* address) { + return psimd_splat_u16(*((const uint16_t*) address)); + } + + PSIMD_INTRINSIC psimd_s32 psimd_load_splat_s32(const void* address) { + return psimd_splat_s32(*((const int32_t*) address)); + } + + PSIMD_INTRINSIC psimd_u32 psimd_load_splat_u32(const void* address) { + return psimd_splat_u32(*((const uint32_t*) address)); + } + + PSIMD_INTRINSIC psimd_f32 psimd_load_splat_f32(const void* address) { + return psimd_splat_f32(*((const float*) address)); + } + + PSIMD_INTRINSIC psimd_s32 psimd_load1_s32(const void* address) { + return (psimd_s32) { *((const int32_t*) address), 0, 0, 0 }; + } + + PSIMD_INTRINSIC psimd_u32 psimd_load1_u32(const void* address) { + return (psimd_u32) { *((const uint32_t*) address), 0, 0, 0 }; + } + + PSIMD_INTRINSIC psimd_f32 psimd_load1_f32(const void* address) { + return (psimd_f32) { *((const float*) address), 0.0f, 0.0f, 0.0f }; + } + + PSIMD_INTRINSIC psimd_s32 psimd_load2_s32(const void* address) { + const int32_t* address_s32 = (const int32_t*) address; + return (psimd_s32) { address_s32[0], address_s32[1], 0, 0 }; + } + + PSIMD_INTRINSIC psimd_u32 psimd_load2_u32(const void* address) { + const uint32_t* address_u32 = (const uint32_t*) address; + return (psimd_u32) { address_u32[0], address_u32[1], 0, 0 }; + } + + PSIMD_INTRINSIC psimd_f32 psimd_load2_f32(const void* address) { + const float* address_f32 = (const float*) address; + return (psimd_f32) { address_f32[0], address_f32[1], 0.0f, 0.0f }; + } + + PSIMD_INTRINSIC psimd_s32 psimd_load3_s32(const void* address) { + const int32_t* address_s32 = (const int32_t*) address; + return (psimd_s32) { address_s32[0], address_s32[1], address_s32[2], 0 }; + } + + PSIMD_INTRINSIC psimd_u32 psimd_load3_u32(const void* address) { + const uint32_t* address_u32 = (const uint32_t*) address; + return (psimd_u32) { address_u32[0], address_u32[1], address_u32[2], 0 }; + } + + PSIMD_INTRINSIC psimd_f32 psimd_load3_f32(const void* address) { + const float* address_f32 = (const float*) address; + return (psimd_f32) { address_f32[0], address_f32[1], address_f32[2], 0.0f }; + } + + PSIMD_INTRINSIC psimd_s32 psimd_load4_s32(const void* address) { + return psimd_load_s32(address); + } + + PSIMD_INTRINSIC psimd_u32 psimd_load4_u32(const void* address) { + return psimd_load_u32(address); + } + + PSIMD_INTRINSIC psimd_f32 psimd_load4_f32(const void* address) { + return psimd_load_f32(address); + } + + PSIMD_INTRINSIC psimd_f32 psimd_load_stride2_f32(const void* address) { + const psimd_f32 v0x1x = psimd_load_f32(address); + const psimd_f32 vx2x3 = psimd_load_f32((const float*) address + 3); + #if defined(__clang__) + return __builtin_shufflevector(v0x1x, vx2x3, 0, 2, 5, 7); + #else + return __builtin_shuffle(v0x1x, vx2x3, (psimd_s32) { 0, 2, 5, 7 }); + #endif + } + + PSIMD_INTRINSIC psimd_f32 psimd_load1_stride2_f32(const void* address) { + return psimd_load_f32(address); + } + + PSIMD_INTRINSIC psimd_f32 psimd_load2_stride2_f32(const void* address) { + const float* address_f32 = (const float*) address; + return (psimd_f32) { address_f32[0], address_f32[2], 0.0f, 0.0f }; + } + + PSIMD_INTRINSIC psimd_f32 psimd_load3_stride2_f32(const void* address) { + const psimd_f32 v0x1x = psimd_load_f32(address); + const psimd_f32 v2zzz = psimd_load1_f32((const float*) address + 2); + #if defined(__clang__) + return __builtin_shufflevector(v0x1x, v2zzz, 0, 2, 4, 6); + #else + return __builtin_shuffle(v0x1x, v2zzz, (psimd_s32) { 0, 2, 4, 6 }); + #endif + } + + PSIMD_INTRINSIC psimd_f32 psimd_load4_stride2_f32(const void* address) { + return psimd_load_stride2_f32(address); + } + + PSIMD_INTRINSIC psimd_f32 psimd_load_stride_f32(const void* address, size_t stride) { + const float* address0_f32 = (const float*) address; + const float* address1_f32 = address0_f32 + stride; + const float* address2_f32 = address1_f32 + stride; + const float* address3_f32 = address2_f32 + stride; + return (psimd_f32) { *address0_f32, *address1_f32, *address2_f32, *address3_f32 }; + } + + PSIMD_INTRINSIC psimd_f32 psimd_load1_stride_f32(const void* address, size_t stride) { + return psimd_load1_f32(address); + } + + PSIMD_INTRINSIC psimd_f32 psimd_load2_stride_f32(const void* address, size_t stride) { + const float* address_f32 = (const float*) address; + return (psimd_f32) { address_f32[0], address_f32[stride], 0.0f, 0.0f }; + } + + PSIMD_INTRINSIC psimd_f32 psimd_load3_stride_f32(const void* address, size_t stride) { + const float* address0_f32 = (const float*) address; + const float* address1_f32 = address0_f32 + stride; + const float* address2_f32 = address1_f32 + stride; + return (psimd_f32) { *address0_f32, *address1_f32, *address2_f32, 0.0f }; + } + + PSIMD_INTRINSIC psimd_f32 psimd_load4_stride_f32(const void* address, size_t stride) { + return psimd_load_stride_f32(address, stride); + } + + /* Store vector */ + PSIMD_INTRINSIC void psimd_store_s8(void* address, psimd_s8 value) { + *((psimd_s8*) address) = value; + } + + PSIMD_INTRINSIC void psimd_store_u8(void* address, psimd_u8 value) { + *((psimd_u8*) address) = value; + } + + PSIMD_INTRINSIC void psimd_store_s16(void* address, psimd_s16 value) { + *((psimd_s16*) address) = value; + } + + PSIMD_INTRINSIC void psimd_store_u16(void* address, psimd_u16 value) { + *((psimd_u16*) address) = value; + } + + PSIMD_INTRINSIC void psimd_store_s32(void* address, psimd_s32 value) { + *((psimd_s32*) address) = value; + } + + PSIMD_INTRINSIC void psimd_store_u32(void* address, psimd_u32 value) { + *((psimd_u32*) address) = value; + } + + PSIMD_INTRINSIC void psimd_store_f32(void* address, psimd_f32 value) { + *((psimd_f32*) address) = value; + } + + PSIMD_INTRINSIC void psimd_store1_s32(void* address, psimd_s32 value) { + *((int32_t*) address) = value[0]; + } + + PSIMD_INTRINSIC void psimd_store1_u32(void* address, psimd_u32 value) { + *((uint32_t*) address) = value[0]; + } + + PSIMD_INTRINSIC void psimd_store1_f32(void* address, psimd_f32 value) { + *((float*) address) = value[0]; + } + + PSIMD_INTRINSIC void psimd_store2_s32(void* address, psimd_s32 value) { + int32_t* address_s32 = (int32_t*) address; + address_s32[0] = value[0]; + address_s32[1] = value[1]; + } + + PSIMD_INTRINSIC void psimd_store2_u32(void* address, psimd_u32 value) { + uint32_t* address_u32 = (uint32_t*) address; + address_u32[0] = value[0]; + address_u32[1] = value[1]; + } + + PSIMD_INTRINSIC void psimd_store2_f32(void* address, psimd_f32 value) { + float* address_f32 = (float*) address; + address_f32[0] = value[0]; + address_f32[1] = value[1]; + } + + PSIMD_INTRINSIC void psimd_store3_s32(void* address, psimd_s32 value) { + int32_t* address_s32 = (int32_t*) address; + address_s32[0] = value[0]; + address_s32[1] = value[1]; + address_s32[2] = value[2]; + } + + PSIMD_INTRINSIC void psimd_store3_u32(void* address, psimd_u32 value) { + uint32_t* address_u32 = (uint32_t*) address; + address_u32[0] = value[0]; + address_u32[1] = value[1]; + address_u32[2] = value[2]; + } + + PSIMD_INTRINSIC void psimd_store3_f32(void* address, psimd_f32 value) { + float* address_f32 = (float*) address; + address_f32[0] = value[0]; + address_f32[1] = value[1]; + address_f32[2] = value[2]; + } + + PSIMD_INTRINSIC void psimd_store4_s32(void* address, psimd_s32 value) { + psimd_store_s32(address, value); + } + + PSIMD_INTRINSIC void psimd_store4_u32(void* address, psimd_u32 value) { + psimd_store_u32(address, value); + } + + PSIMD_INTRINSIC void psimd_store4_f32(void* address, psimd_f32 value) { + psimd_store_f32(address, value); + } + + PSIMD_INTRINSIC void psimd_store_stride_f32(void* address, size_t stride, psimd_f32 value) { + float* address0_f32 = (float*) address; + float* address1_f32 = address0_f32 + stride; + float* address2_f32 = address1_f32 + stride; + float* address3_f32 = address2_f32 + stride; + *address0_f32 = value[0]; + *address1_f32 = value[1]; + *address2_f32 = value[2]; + *address3_f32 = value[3]; + } + + PSIMD_INTRINSIC void psimd_store1_stride_f32(void* address, size_t stride, psimd_f32 value) { + psimd_store1_f32(address, value); + } + + PSIMD_INTRINSIC void psimd_store2_stride_f32(void* address, size_t stride, psimd_f32 value) { + float* address_f32 = (float*) address; + address_f32[0] = value[0]; + address_f32[stride] = value[1]; + } + + PSIMD_INTRINSIC void psimd_store3_stride_f32(void* address, size_t stride, psimd_f32 value) { + float* address0_f32 = (float*) address; + float* address1_f32 = address0_f32 + stride; + float* address2_f32 = address1_f32 + stride; + *address0_f32 = value[0]; + *address1_f32 = value[1]; + *address2_f32 = value[2]; + } + + /* Vector addition */ + PSIMD_INTRINSIC psimd_s8 psimd_add_s8(psimd_s8 a, psimd_s8 b) { + return a + b; + } + + PSIMD_INTRINSIC psimd_u8 psimd_add_u8(psimd_u8 a, psimd_u8 b) { + return a + b; + } + + PSIMD_INTRINSIC psimd_s16 psimd_add_s16(psimd_s16 a, psimd_s16 b) { + return a + b; + } + + PSIMD_INTRINSIC psimd_u16 psimd_add_u16(psimd_u16 a, psimd_u16 b) { + return a + b; + } + + PSIMD_INTRINSIC psimd_s32 psimd_add_s32(psimd_s32 a, psimd_s32 b) { + return a + b; + } + + PSIMD_INTRINSIC psimd_u32 psimd_add_u32(psimd_u32 a, psimd_u32 b) { + return a + b; + } + + PSIMD_INTRINSIC psimd_f32 psimd_add_f32(psimd_f32 a, psimd_f32 b) { + #if defined(__ARM_ARCH_7A__) && defined(__ARM_NEON__) && !defined(__FAST_MATH__) + return (psimd_f32) vaddq_f32((float32x4_t) a, (float32x4_t) b); + #else + return a + b; + #endif + } + + /* Vector subtraction */ + PSIMD_INTRINSIC psimd_s8 psimd_sub_s8(psimd_s8 a, psimd_s8 b) { + return a - b; + } + + PSIMD_INTRINSIC psimd_u8 psimd_sub_u8(psimd_u8 a, psimd_u8 b) { + return a - b; + } + + PSIMD_INTRINSIC psimd_s16 psimd_sub_s16(psimd_s16 a, psimd_s16 b) { + return a - b; + } + + PSIMD_INTRINSIC psimd_u16 psimd_sub_u16(psimd_u16 a, psimd_u16 b) { + return a - b; + } + + PSIMD_INTRINSIC psimd_s32 psimd_sub_s32(psimd_s32 a, psimd_s32 b) { + return a - b; + } + + PSIMD_INTRINSIC psimd_u32 psimd_sub_u32(psimd_u32 a, psimd_u32 b) { + return a - b; + } + + PSIMD_INTRINSIC psimd_f32 psimd_sub_f32(psimd_f32 a, psimd_f32 b) { + #if defined(__ARM_ARCH_7A__) && defined(__ARM_NEON__) && !defined(__FAST_MATH__) + return (psimd_f32) vsubq_f32((float32x4_t) a, (float32x4_t) b); + #else + return a - b; + #endif + } + + /* Vector multiplication */ + PSIMD_INTRINSIC psimd_s8 psimd_mul_s8(psimd_s8 a, psimd_s8 b) { + return a * b; + } + + PSIMD_INTRINSIC psimd_u8 psimd_mul_u8(psimd_u8 a, psimd_u8 b) { + return a * b; + } + + PSIMD_INTRINSIC psimd_s16 psimd_mul_s16(psimd_s16 a, psimd_s16 b) { + return a * b; + } + + PSIMD_INTRINSIC psimd_u16 psimd_mul_u16(psimd_u16 a, psimd_u16 b) { + return a * b; + } + + PSIMD_INTRINSIC psimd_s32 psimd_mul_s32(psimd_s32 a, psimd_s32 b) { + return a * b; + } + + PSIMD_INTRINSIC psimd_u32 psimd_mul_u32(psimd_u32 a, psimd_u32 b) { + return a * b; + } + + PSIMD_INTRINSIC psimd_f32 psimd_mul_f32(psimd_f32 a, psimd_f32 b) { + #if defined(__ARM_ARCH_7A__) && defined(__ARM_NEON__) && !defined(__FAST_MATH__) + return (psimd_f32) vmulq_f32((float32x4_t) a, (float32x4_t) b); + #else + return a * b; + #endif + } + + /* Quasi-Fused Multiply-Add */ + PSIMD_INTRINSIC psimd_f32 psimd_qfma_f32(psimd_f32 a, psimd_f32 b, psimd_f32 c) { + #if defined(__aarch64__) || defined(__ARM_NEON__) && defined(__ARM_FEATURE_FMA) + return (psimd_f32) vfmaq_f32((float32x4_t) a, (float32x4_t) b, (float32x4_t) c); + #elif (defined(__x86_64__) || defined(__i386__) || defined(__i686__)) && defined(__FMA__) + return (psimd_f32) _mm_fmadd_ps((__m128) b, (__m128) c, (__m128) a); + #elif (defined(__x86_64__) || defined(__i386__) || defined(__i686__)) && defined(__FMA4__) + return (psimd_f32) _mm_macc_ps((__m128) b, (__m128) c, (__m128) a); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) && PSIMD_ENABLE_WASM_QFMA + return (psimd_f32) __builtin_wasm_qfma_f32x4(a, b, c); + #else + return a + b * c; + #endif + } + + PSIMD_INTRINSIC psimd_f32 psimd_div_f32(psimd_f32 a, psimd_f32 b) { + return a / b; + } + + /* Vector and */ + PSIMD_INTRINSIC psimd_f32 psimd_andmask_f32(psimd_s32 mask, psimd_f32 v) { + return (psimd_f32) (mask & (psimd_s32) v); + } + + /* Vector and-not */ + PSIMD_INTRINSIC psimd_f32 psimd_andnotmask_f32(psimd_s32 mask, psimd_f32 v) { + return (psimd_f32) (~mask & (psimd_s32) v); + } + + /* Vector blend */ + PSIMD_INTRINSIC psimd_s8 psimd_blend_s8(psimd_s8 mask, psimd_s8 a, psimd_s8 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_s8) vbslq_s8((uint8x16_t) mask, (int8x16_t) a, (int8x16_t) b); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) + return (psimd_s8) __builtin_wasm_bitselect(a, b, mask); + #else + return (mask & a) | (~mask & b); + #endif + } + + PSIMD_INTRINSIC psimd_u8 psimd_blend_u8(psimd_s8 mask, psimd_u8 a, psimd_u8 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_u8) vbslq_u8((uint8x16_t) mask, (uint8x16_t) a, (uint8x16_t) b); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) + return (psimd_u8) __builtin_wasm_bitselect(a, b, mask); + #else + return (psimd_u8) ((mask & (psimd_s8) a) | (~mask & (psimd_s8) b)); + #endif + } + + PSIMD_INTRINSIC psimd_s16 psimd_blend_s16(psimd_s16 mask, psimd_s16 a, psimd_s16 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_s16) vbslq_s16((uint16x8_t) mask, (int16x8_t) a, (int16x8_t) b); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) + return (psimd_s16) __builtin_wasm_bitselect(a, b, mask); + #else + return (mask & a) | (~mask & b); + #endif + } + + PSIMD_INTRINSIC psimd_u16 psimd_blend_u16(psimd_s16 mask, psimd_u16 a, psimd_u16 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_u16) vbslq_u16((uint16x8_t) mask, (uint16x8_t) a, (uint16x8_t) b); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) + return (psimd_u16) __builtin_wasm_bitselect(a, b, mask); + #else + return (psimd_u16) ((mask & (psimd_s16) a) | (~mask & (psimd_s16) b)); + #endif + } + + PSIMD_INTRINSIC psimd_s32 psimd_blend_s32(psimd_s32 mask, psimd_s32 a, psimd_s32 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_s32) vbslq_s32((uint32x4_t) mask, (int32x4_t) a, (int32x4_t) b); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) + return (psimd_s32) __builtin_wasm_bitselect(a, b, mask); + #else + return (mask & a) | (~mask & b); + #endif + } + + PSIMD_INTRINSIC psimd_u32 psimd_blend_u32(psimd_s32 mask, psimd_u32 a, psimd_u32 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_u32) vbslq_u32((uint32x4_t) mask, (uint32x4_t) a, (uint32x4_t) b); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) + return (psimd_u32) __builtin_wasm_bitselect(a, b, mask); + #else + return (psimd_u32) ((mask & (psimd_s32) a) | (~mask & (psimd_s32) b)); + #endif + } + + PSIMD_INTRINSIC psimd_f32 psimd_blend_f32(psimd_s32 mask, psimd_f32 a, psimd_f32 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_f32) vbslq_f32((uint32x4_t) mask, (float32x4_t) a, (float32x4_t) b); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) + return (psimd_f32) __builtin_wasm_bitselect(a, b, mask); + #else + return (psimd_f32) ((mask & (psimd_s32) a) | (~mask & (psimd_s32) b)); + #endif + } + + /* Vector blend on sign */ + PSIMD_INTRINSIC psimd_s8 psimd_signblend_s8(psimd_s8 x, psimd_s8 a, psimd_s8 b) { + return psimd_blend_s8(x >> psimd_splat_s8(7), a, b); + } + + PSIMD_INTRINSIC psimd_u8 psimd_signblend_u8(psimd_s8 x, psimd_u8 a, psimd_u8 b) { + return psimd_blend_u8((x >> psimd_splat_s8(7)), a, b); + } + + PSIMD_INTRINSIC psimd_s16 psimd_signblend_s16(psimd_s16 x, psimd_s16 a, psimd_s16 b) { + return psimd_blend_s16(x >> psimd_splat_s16(15), a, b); + } + + PSIMD_INTRINSIC psimd_u16 psimd_signblend_u16(psimd_s16 x, psimd_u16 a, psimd_u16 b) { + return psimd_blend_u16((x >> psimd_splat_s16(15)), a, b); + } + + PSIMD_INTRINSIC psimd_s32 psimd_signblend_s32(psimd_s32 x, psimd_s32 a, psimd_s32 b) { + return psimd_blend_s32(x >> psimd_splat_s32(31), a, b); + } + + PSIMD_INTRINSIC psimd_u32 psimd_signblend_u32(psimd_s32 x, psimd_u32 a, psimd_u32 b) { + return psimd_blend_u32((x >> psimd_splat_s32(31)), a, b); + } + + PSIMD_INTRINSIC psimd_f32 psimd_signblend_f32(psimd_f32 x, psimd_f32 a, psimd_f32 b) { + const psimd_s32 mask = (psimd_s32) x >> psimd_splat_s32(31); + return psimd_blend_f32(mask, a, b); + } + + /* Vector absolute value */ + PSIMD_INTRINSIC psimd_f32 psimd_abs_f32(psimd_f32 v) { + const psimd_s32 mask = (psimd_s32) psimd_splat_f32(-0.0f); + return (psimd_f32) ((psimd_s32) v & ~mask); + } + + /* Vector negation */ + PSIMD_INTRINSIC psimd_f32 psimd_neg_f32(psimd_f32 v) { + const psimd_s32 mask = (psimd_s32) psimd_splat_f32(-0.0f); + return (psimd_f32) ((psimd_s32) v ^ mask); + } + + /* Vector maximum */ + PSIMD_INTRINSIC psimd_s8 psimd_max_s8(psimd_s8 a, psimd_s8 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_s8) vmaxq_s8((int8x16_t) a, (int8x16_t) b); + #else + return psimd_blend_s8(a > b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_u8 psimd_max_u8(psimd_u8 a, psimd_u8 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_u8) vmaxq_u8((uint8x16_t) a, (uint8x16_t) b); + #else + return psimd_blend_u8(a > b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_s16 psimd_max_s16(psimd_s16 a, psimd_s16 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_s16) vmaxq_s16((int16x8_t) a, (int16x8_t) b); + #else + return psimd_blend_s16(a > b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_u16 psimd_max_u16(psimd_u16 a, psimd_u16 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_u16) vmaxq_u16((uint16x8_t) a, (uint16x8_t) b); + #else + return psimd_blend_u16(a > b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_s32 psimd_max_s32(psimd_s32 a, psimd_s32 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_s32) vmaxq_s32((int32x4_t) a, (int32x4_t) b); + #else + return psimd_blend_s32(a > b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_u32 psimd_max_u32(psimd_u32 a, psimd_u32 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_u32) vmaxq_u32((uint32x4_t) a, (uint32x4_t) b); + #else + return psimd_blend_u32(a > b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_f32 psimd_max_f32(psimd_f32 a, psimd_f32 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_f32) vmaxq_f32((float32x4_t) a, (float32x4_t) b); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) + return __builtin_wasm_max_f32x4(a, b); + #else + return psimd_blend_f32(a > b, a, b); + #endif + } + + /* Vector minimum */ + PSIMD_INTRINSIC psimd_s8 psimd_min_s8(psimd_s8 a, psimd_s8 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_s8) vminq_s8((int8x16_t) a, (int8x16_t) b); + #else + return psimd_blend_s8(a < b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_u8 psimd_min_u8(psimd_u8 a, psimd_u8 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_u8) vminq_u8((uint8x16_t) a, (uint8x16_t) b); + #else + return psimd_blend_u8(a < b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_s16 psimd_min_s16(psimd_s16 a, psimd_s16 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_s16) vminq_s16((int16x8_t) a, (int16x8_t) b); + #else + return psimd_blend_s16(a < b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_u16 psimd_min_u16(psimd_u16 a, psimd_u16 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_u16) vminq_u16((uint16x8_t) a, (uint16x8_t) b); + #else + return psimd_blend_u16(a < b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_s32 psimd_min_s32(psimd_s32 a, psimd_s32 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_s32) vminq_s32((int32x4_t) a, (int32x4_t) b); + #else + return psimd_blend_s32(a < b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_u32 psimd_min_u32(psimd_u32 a, psimd_u32 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_u32) vminq_u32((uint32x4_t) a, (uint32x4_t) b); + #else + return psimd_blend_u32(a < b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_f32 psimd_min_f32(psimd_f32 a, psimd_f32 b) { + #if defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_f32) vminq_f32((float32x4_t) a, (float32x4_t) b); + #elif defined(__wasm__) && defined(__wasm_simd128__) && defined(__clang__) + return __builtin_wasm_min_f32x4(a, b); + #else + return psimd_blend_f32(a < b, a, b); + #endif + } + + PSIMD_INTRINSIC psimd_f32 psimd_cvt_s32_f32(psimd_s32 v) { + #if defined(__clang__) + return __builtin_convertvector(v, psimd_f32); + #elif defined(__ARM_NEON__) || defined(__ARM_NEON) + return (psimd_f32) vcvtq_f32_s32((int32x4_t) v); + #elif defined(__SSE2__) + return (psimd_f32) _mm_cvtepi32_ps((__m128i) v); + #else + return (psimd_f32) { (float) v[0], (float) v[1], (float) v[2], (float) v[3] }; + #endif + } + + /* Broadcast vector element */ + #if defined(__clang__) + PSIMD_INTRINSIC psimd_f32 psimd_splat0_f32(psimd_f32 v) { + return __builtin_shufflevector(v, v, 0, 0, 0, 0); + } + + PSIMD_INTRINSIC psimd_f32 psimd_splat1_f32(psimd_f32 v) { + return __builtin_shufflevector(v, v, 1, 1, 1, 1); + } + + PSIMD_INTRINSIC psimd_f32 psimd_splat2_f32(psimd_f32 v) { + return __builtin_shufflevector(v, v, 2, 2, 2, 2); + } + + PSIMD_INTRINSIC psimd_f32 psimd_splat3_f32(psimd_f32 v) { + return __builtin_shufflevector(v, v, 3, 3, 3, 3); + } + #else + PSIMD_INTRINSIC psimd_f32 psimd_splat0_f32(psimd_f32 v) { + return __builtin_shuffle(v, (psimd_s32) { 0, 0, 0, 0 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_splat1_f32(psimd_f32 v) { + return __builtin_shuffle(v, (psimd_s32) { 1, 1, 1, 1 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_splat2_f32(psimd_f32 v) { + return __builtin_shuffle(v, (psimd_s32) { 2, 2, 2, 2 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_splat3_f32(psimd_f32 v) { + return __builtin_shuffle(v, (psimd_s32) { 3, 3, 3, 3 }); + } + #endif + + /* Reversal of vector elements */ + #if defined(__clang__) + PSIMD_INTRINSIC psimd_s8 psimd_reverse_s8(psimd_s8 v) { + return __builtin_shufflevector(v, v, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); + } + + PSIMD_INTRINSIC psimd_u8 psimd_reverse_u8(psimd_u8 v) { + return __builtin_shufflevector(v, v, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); + } + + PSIMD_INTRINSIC psimd_s16 psimd_reverse_s16(psimd_s16 v) { + return __builtin_shufflevector(v, v, 7, 6, 5, 4, 3, 2, 1, 0); + } + + PSIMD_INTRINSIC psimd_u16 psimd_reverse_u16(psimd_u16 v) { + return __builtin_shufflevector(v, v, 7, 6, 5, 4, 3, 2, 1, 0); + } + + PSIMD_INTRINSIC psimd_s32 psimd_reverse_s32(psimd_s32 v) { + return __builtin_shufflevector(v, v, 3, 2, 1, 0); + } + + PSIMD_INTRINSIC psimd_u32 psimd_reverse_u32(psimd_u32 v) { + return __builtin_shufflevector(v, v, 3, 2, 1, 0); + } + + PSIMD_INTRINSIC psimd_f32 psimd_reverse_f32(psimd_f32 v) { + return __builtin_shufflevector(v, v, 3, 2, 1, 0); + } + #else + PSIMD_INTRINSIC psimd_s8 psimd_reverse_s8(psimd_s8 v) { + return __builtin_shuffle(v, (psimd_s8) { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }); + } + + PSIMD_INTRINSIC psimd_u8 psimd_reverse_u8(psimd_u8 v) { + return __builtin_shuffle(v, (psimd_s8) { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }); + } + + PSIMD_INTRINSIC psimd_s16 psimd_reverse_s16(psimd_s16 v) { + return __builtin_shuffle(v, (psimd_s16) { 7, 6, 5, 4, 3, 2, 1, 0 }); + } + + PSIMD_INTRINSIC psimd_u16 psimd_reverse_u16(psimd_u16 v) { + return __builtin_shuffle(v, (psimd_s16) { 7, 6, 5, 4, 3, 2, 1, 0 }); + } + + PSIMD_INTRINSIC psimd_s32 psimd_reverse_s32(psimd_s32 v) { + return __builtin_shuffle(v, (psimd_s32) { 3, 2, 1, 0 }); + } + + PSIMD_INTRINSIC psimd_u32 psimd_reverse_u32(psimd_u32 v) { + return __builtin_shuffle(v, (psimd_s32) { 3, 2, 1, 0 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_reverse_f32(psimd_f32 v) { + return __builtin_shuffle(v, (psimd_s32) { 3, 2, 1, 0 }); + } + #endif + + /* Interleaving of vector elements */ + #if defined(__clang__) + PSIMD_INTRINSIC psimd_s16 psimd_interleave_lo_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shufflevector(a, b, 0, 8+0, 1, 8+1, 2, 8+2, 3, 8+3); + } + + PSIMD_INTRINSIC psimd_s16 psimd_interleave_hi_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shufflevector(a, b, 4, 8+4, 5, 8+5, 6, 8+6, 7, 8+7); + } + + PSIMD_INTRINSIC psimd_u16 psimd_interleave_lo_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shufflevector(a, b, 0, 8+0, 1, 8+1, 2, 8+2, 3, 8+3); + } + + PSIMD_INTRINSIC psimd_u16 psimd_interleave_hi_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shufflevector(a, b, 4, 8+4, 5, 8+5, 6, 8+6, 7, 8+7); + } + + PSIMD_INTRINSIC psimd_s32 psimd_interleave_lo_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shufflevector(a, b, 0, 4+0, 1, 4+1); + } + + PSIMD_INTRINSIC psimd_s32 psimd_interleave_hi_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shufflevector(a, b, 2, 4+2, 3, 4+3); + } + + PSIMD_INTRINSIC psimd_u32 psimd_interleave_lo_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shufflevector(a, b, 0, 4+0, 1, 4+1); + } + + PSIMD_INTRINSIC psimd_u32 psimd_interleave_hi_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shufflevector(a, b, 2, 4+2, 3, 4+3); + } + + PSIMD_INTRINSIC psimd_f32 psimd_interleave_lo_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shufflevector(a, b, 0, 4+0, 1, 4+1); + } + + PSIMD_INTRINSIC psimd_f32 psimd_interleave_hi_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shufflevector(a, b, 2, 4+2, 3, 4+3); + } + #else + PSIMD_INTRINSIC psimd_s16 psimd_interleave_lo_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 0, 8+0, 1, 8+1, 2, 8+2, 3, 8+3 }); + } + + PSIMD_INTRINSIC psimd_s16 psimd_interleave_hi_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 4, 8+4, 5, 8+5, 6, 8+6, 7, 8+7 }); + } + + PSIMD_INTRINSIC psimd_u16 psimd_interleave_lo_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 0, 8+0, 1, 8+1, 2, 8+2, 3, 8+3 }); + } + + PSIMD_INTRINSIC psimd_u16 psimd_interleave_hi_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 4, 8+4, 5, 8+5, 6, 8+6, 7, 8+7 }); + } + + PSIMD_INTRINSIC psimd_s32 psimd_interleave_lo_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 0, 4+0, 1, 4+1 }); + } + + PSIMD_INTRINSIC psimd_s32 psimd_interleave_hi_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 2, 4+2, 3, 4+3 }); + } + + PSIMD_INTRINSIC psimd_u32 psimd_interleave_lo_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 0, 4+0, 1, 4+1 }); + } + + PSIMD_INTRINSIC psimd_u32 psimd_interleave_hi_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 2, 4+2, 3, 4+3 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_interleave_lo_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 0, 4+0, 1, 4+1 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_interleave_hi_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 2, 4+2, 3, 4+3 }); + } + #endif + + /* Concatenation of low/high vector elements */ + #if defined(__clang__) + PSIMD_INTRINSIC psimd_s16 psimd_concat_lo_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shufflevector(a, b, 0, 1, 2, 3, 8+0, 8+1, 8+2, 8+3); + } + + PSIMD_INTRINSIC psimd_s16 psimd_concat_hi_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shufflevector(a, b, 4, 5, 6, 7, 8+4, 8+5, 8+6, 8+7); + } + + PSIMD_INTRINSIC psimd_u16 psimd_concat_lo_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shufflevector(a, b, 0, 1, 2, 3, 8+0, 8+1, 8+2, 8+3); + } + + PSIMD_INTRINSIC psimd_u16 psimd_concat_hi_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shufflevector(a, b, 4, 5, 6, 7, 8+4, 8+5, 8+6, 8+7); + } + + PSIMD_INTRINSIC psimd_s32 psimd_concat_lo_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shufflevector(a, b, 0, 1, 4+0, 4+1); + } + + PSIMD_INTRINSIC psimd_s32 psimd_concat_hi_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shufflevector(a, b, 2, 3, 4+2, 4+3); + } + + PSIMD_INTRINSIC psimd_u32 psimd_concat_lo_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shufflevector(a, b, 0, 1, 4+0, 4+1); + } + + PSIMD_INTRINSIC psimd_u32 psimd_concat_hi_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shufflevector(a, b, 2, 3, 4+2, 4+3); + } + + PSIMD_INTRINSIC psimd_f32 psimd_concat_lo_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shufflevector(a, b, 0, 1, 4+0, 4+1); + } + + PSIMD_INTRINSIC psimd_f32 psimd_concat_hi_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shufflevector(a, b, 2, 3, 4+2, 4+3); + } + #else + PSIMD_INTRINSIC psimd_s16 psimd_concat_lo_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 0, 1, 2, 3, 8+0, 8+1, 8+2, 8+3 }); + } + + PSIMD_INTRINSIC psimd_s16 psimd_concat_hi_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 4, 5, 6, 7, 8+4, 8+5, 8+6, 8+7 }); + } + + PSIMD_INTRINSIC psimd_u16 psimd_concat_lo_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 0, 1, 2, 3, 8+0, 8+1, 8+2, 8+3 }); + } + + PSIMD_INTRINSIC psimd_u16 psimd_concat_hi_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 4, 5, 6, 7, 8+4, 8+5, 8+6, 8+7 }); + } + + PSIMD_INTRINSIC psimd_s32 psimd_concat_lo_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 0, 1, 4+0, 4+1 }); + } + + PSIMD_INTRINSIC psimd_s32 psimd_concat_hi_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 2, 3, 4+2, 4+3 }); + } + + PSIMD_INTRINSIC psimd_u32 psimd_concat_lo_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 0, 1, 4+0, 4+1 }); + } + + PSIMD_INTRINSIC psimd_u32 psimd_concat_hi_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 2, 3, 4+2, 4+3 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_concat_lo_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 0, 1, 4+0, 4+1 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_concat_hi_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 2, 3, 4+2, 4+3 }); + } + #endif + + /* Concatenation of even/odd vector elements */ + #if defined(__clang__) + PSIMD_INTRINSIC psimd_s8 psimd_concat_even_s8(psimd_s8 a, psimd_s8 b) { + return __builtin_shufflevector(a, b, + 0, 2, 4, 6, 8, 10, 12, 14, 16+0, 16+2, 16+4, 16+6, 16+8, 16+10, 16+12, 16+14); + } + + PSIMD_INTRINSIC psimd_s8 psimd_concat_odd_s8(psimd_s8 a, psimd_s8 b) { + return __builtin_shufflevector(a, b, + 1, 3, 5, 7, 9, 11, 13, 15, 16+1, 16+3, 16+5, 16+7, 16+9, 16+11, 16+13, 16+15); + } + + PSIMD_INTRINSIC psimd_u8 psimd_concat_even_u8(psimd_u8 a, psimd_u8 b) { + return __builtin_shufflevector(a, b, + 0, 2, 4, 6, 8, 10, 12, 14, 16+0, 16+2, 16+4, 16+6, 16+8, 16+10, 16+12, 16+14); + } + + PSIMD_INTRINSIC psimd_u8 psimd_concat_odd_u8(psimd_u8 a, psimd_u8 b) { + return __builtin_shufflevector(a, b, + 1, 3, 5, 7, 9, 11, 13, 15, 16+1, 16+3, 16+5, 16+7, 16+9, 16+11, 16+13, 16+15); + } + + PSIMD_INTRINSIC psimd_s16 psimd_concat_even_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shufflevector(a, b, 0, 2, 4, 6, 8+0, 8+2, 8+4, 8+6); + } + + PSIMD_INTRINSIC psimd_s16 psimd_concat_odd_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shufflevector(a, b, 1, 3, 5, 7, 8+1, 8+3, 8+5, 8+7); + } + + PSIMD_INTRINSIC psimd_u16 psimd_concat_even_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shufflevector(a, b, 0, 2, 4, 6, 8+0, 8+2, 8+4, 8+6); + } + + PSIMD_INTRINSIC psimd_u16 psimd_concat_odd_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shufflevector(a, b, 1, 3, 5, 7, 8+1, 8+3, 8+5, 8+7); + } + + PSIMD_INTRINSIC psimd_s32 psimd_concat_even_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shufflevector(a, b, 0, 2, 4+0, 4+2); + } + + PSIMD_INTRINSIC psimd_s32 psimd_concat_odd_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shufflevector(a, b, 1, 3, 4+1, 4+3); + } + + PSIMD_INTRINSIC psimd_u32 psimd_concat_even_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shufflevector(a, b, 0, 2, 4+0, 4+2); + } + + PSIMD_INTRINSIC psimd_u32 psimd_concat_odd_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shufflevector(a, b, 1, 3, 4+1, 4+3); + } + + PSIMD_INTRINSIC psimd_f32 psimd_concat_even_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shufflevector(a, b, 0, 2, 4+0, 4+2); + } + + PSIMD_INTRINSIC psimd_f32 psimd_concat_odd_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shufflevector(a, b, 1, 3, 4+1, 4+3); + } + #else + PSIMD_INTRINSIC psimd_s8 psimd_concat_even_s8(psimd_s8 a, psimd_s8 b) { + return __builtin_shuffle(a, b, + (psimd_s8) { 0, 2, 4, 6, 8, 10, 12, 14, 16+0, 16+2, 16+4, 16+6, 16+8, 16+10, 16+12, 16+14 }); + } + + PSIMD_INTRINSIC psimd_s8 psimd_concat_odd_s8(psimd_s8 a, psimd_s8 b) { + return __builtin_shuffle(a, b, + (psimd_s8) { 1, 3, 5, 7, 9, 11, 13, 15, 16+1, 16+3, 16+5, 16+7, 16+9, 16+11, 16+13, 16+15 }); + } + + PSIMD_INTRINSIC psimd_u8 psimd_concat_even_u8(psimd_u8 a, psimd_u8 b) { + return __builtin_shuffle(a, b, + (psimd_s8) { 0, 2, 4, 6, 8, 10, 12, 14, 16+0, 16+2, 16+4, 16+6, 16+8, 16+10, 16+12, 16+14 }); + } + + PSIMD_INTRINSIC psimd_u8 psimd_concat_odd_u8(psimd_u8 a, psimd_u8 b) { + return __builtin_shuffle(a, b, + (psimd_s8) { 1, 3, 5, 7, 9, 11, 13, 15, 16+1, 16+3, 16+5, 16+7, 16+9, 16+11, 16+13, 16+15 }); + } + + PSIMD_INTRINSIC psimd_s16 psimd_concat_even_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 0, 2, 4, 6, 8+0, 8+2, 8+4, 8+6 }); + } + + PSIMD_INTRINSIC psimd_s16 psimd_concat_odd_s16(psimd_s16 a, psimd_s16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 1, 3, 5, 7, 8+1, 8+3, 8+5, 8+7 }); + } + + PSIMD_INTRINSIC psimd_u16 psimd_concat_even_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 0, 2, 4, 6, 8+0, 8+2, 8+4, 8+6 }); + } + + PSIMD_INTRINSIC psimd_u16 psimd_concat_odd_u16(psimd_u16 a, psimd_u16 b) { + return __builtin_shuffle(a, b, (psimd_s16) { 1, 3, 5, 7, 8+1, 8+3, 8+5, 8+7 }); + } + + PSIMD_INTRINSIC psimd_s32 psimd_concat_even_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 0, 2, 4+0, 4+2 }); + } + + PSIMD_INTRINSIC psimd_s32 psimd_concat_odd_s32(psimd_s32 a, psimd_s32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 1, 3, 4+1, 4+3 }); + } + + PSIMD_INTRINSIC psimd_u32 psimd_concat_even_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 0, 2, 4+0, 4+2 }); + } + + PSIMD_INTRINSIC psimd_u32 psimd_concat_odd_u32(psimd_u32 a, psimd_u32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 1, 3, 4+1, 4+3 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_concat_even_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 0, 2, 4+0, 4+2 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_concat_odd_f32(psimd_f32 a, psimd_f32 b) { + return __builtin_shuffle(a, b, (psimd_s32) { 1, 3, 4+1, 4+3 }); + } + #endif + + /* Vector reduce */ + #if defined(__clang__) + PSIMD_INTRINSIC psimd_f32 psimd_allreduce_sum_f32(psimd_f32 v) { + const psimd_f32 temp = v + __builtin_shufflevector(v, v, 2, 3, 0, 1); + return temp + __builtin_shufflevector(temp, temp, 1, 0, 3, 2); + } + + PSIMD_INTRINSIC psimd_f32 psimd_allreduce_max_f32(psimd_f32 v) { + const psimd_f32 temp = psimd_max_f32(v, __builtin_shufflevector(v, v, 2, 3, 0, 1)); + return psimd_max_f32(temp, __builtin_shufflevector(temp, temp, 1, 0, 3, 2)); + } + + PSIMD_INTRINSIC psimd_f32 psimd_allreduce_min_f32(psimd_f32 v) { + const psimd_f32 temp = psimd_min_f32(v, __builtin_shufflevector(v, v, 2, 3, 0, 1)); + return psimd_min_f32(temp, __builtin_shufflevector(temp, temp, 1, 0, 3, 2)); + } + + PSIMD_INTRINSIC float psimd_reduce_sum_f32(psimd_f32 v) { + const psimd_f32 temp = v + __builtin_shufflevector(v, v, 2, 3, -1, -1); + const psimd_f32 result = temp + __builtin_shufflevector(temp, temp, 1, -1, -1, -1); + return result[0]; + } + + PSIMD_INTRINSIC float psimd_reduce_max_f32(psimd_f32 v) { + const psimd_f32 temp = psimd_max_f32(v, __builtin_shufflevector(v, v, 2, 3, -1, -1)); + const psimd_f32 result = psimd_max_f32(temp, __builtin_shufflevector(temp, temp, 1, -1, -1, -1)); + return result[0]; + } + + PSIMD_INTRINSIC float psimd_reduce_min_f32(psimd_f32 v) { + const psimd_f32 temp = psimd_min_f32(v, __builtin_shufflevector(v, v, 2, 3, -1, -1)); + const psimd_f32 result = psimd_min_f32(temp, __builtin_shufflevector(temp, temp, 1, -1, -1, -1)); + return result[0]; + } + #else + PSIMD_INTRINSIC psimd_f32 psimd_allreduce_sum_f32(psimd_f32 v) { + const psimd_f32 temp = v + __builtin_shuffle(v, (psimd_s32) { 2, 3, 0, 1 }); + return temp + __builtin_shuffle(temp, (psimd_s32) { 1, 0, 3, 2 }); + } + + PSIMD_INTRINSIC psimd_f32 psimd_allreduce_max_f32(psimd_f32 v) { + const psimd_f32 temp = psimd_max_f32(v, __builtin_shuffle(v, (psimd_s32) { 2, 3, 0, 1 })); + return psimd_max_f32(temp, __builtin_shuffle(temp, (psimd_s32) { 1, 0, 3, 2 })); + } + + PSIMD_INTRINSIC psimd_f32 psimd_allreduce_min_f32(psimd_f32 v) { + const psimd_f32 temp = psimd_min_f32(v, __builtin_shuffle(v, (psimd_s32) { 2, 3, 0, 1 })); + return psimd_min_f32(temp, __builtin_shuffle(temp, (psimd_s32) { 1, 0, 3, 2 })); + } + + PSIMD_INTRINSIC float psimd_reduce_sum_f32(psimd_f32 v) { + const psimd_f32 result = psimd_allreduce_sum_f32(v); + return result[0]; + } + + PSIMD_INTRINSIC float psimd_reduce_max_f32(psimd_f32 v) { + const psimd_f32 result = psimd_allreduce_max_f32(v); + return result[0]; + } + + PSIMD_INTRINSIC float psimd_reduce_min_f32(psimd_f32 v) { + const psimd_f32 result = psimd_allreduce_min_f32(v); + return result[0]; + } + #endif +#endif + +#endif /* PSIMD_H */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pthreadpool.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pthreadpool.h new file mode 100644 index 0000000000000000000000000000000000000000..5cab9f53220467ab7f0c68a49b9c24badb0217c6 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pthreadpool.h @@ -0,0 +1,2560 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +#ifndef PTHREADPOOL_H_ +#define PTHREADPOOL_H_ + +#include +#include + +typedef struct pthreadpool* pthreadpool_t; + +typedef void (*pthreadpool_task_1d_t)(void*, size_t); +typedef void (*pthreadpool_task_1d_with_thread_t)(void*, size_t, size_t); +typedef void (*pthreadpool_task_1d_tile_1d_t)(void*, size_t, size_t); +typedef void (*pthreadpool_task_2d_t)(void*, size_t, size_t); +typedef void (*pthreadpool_task_2d_with_thread_t)(void*, size_t, size_t, size_t); +typedef void (*pthreadpool_task_2d_tile_1d_t)(void*, size_t, size_t, size_t); +typedef void (*pthreadpool_task_2d_tile_2d_t)(void*, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_3d_t)(void*, size_t, size_t, size_t); +typedef void (*pthreadpool_task_3d_tile_1d_t)(void*, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_3d_tile_1d_with_thread_t)(void*, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_3d_tile_2d_t)(void*, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_4d_t)(void*, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_4d_tile_1d_t)(void*, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_4d_tile_2d_t)(void*, size_t, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_5d_t)(void*, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_5d_tile_1d_t)(void*, size_t, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_5d_tile_2d_t)(void*, size_t, size_t, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_6d_t)(void*, size_t, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_6d_tile_1d_t)(void*, size_t, size_t, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_6d_tile_2d_t)(void*, size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t); + +typedef void (*pthreadpool_task_1d_with_id_t)(void*, uint32_t, size_t); +typedef void (*pthreadpool_task_2d_tile_1d_with_id_t)(void*, uint32_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_2d_tile_2d_with_id_t)(void*, uint32_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_3d_tile_1d_with_id_t)(void*, uint32_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_3d_tile_2d_with_id_t)(void*, uint32_t, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_4d_tile_2d_with_id_t)(void*, uint32_t, size_t, size_t, size_t, size_t, size_t, size_t); + +typedef void (*pthreadpool_task_2d_tile_1d_with_id_with_thread_t)(void*, uint32_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_task_3d_tile_1d_with_id_with_thread_t)(void*, uint32_t, size_t, size_t, size_t, size_t, size_t); + + +/** + * Disable support for denormalized numbers to the maximum extent possible for + * the duration of the computation. + * + * Handling denormalized floating-point numbers is often implemented in + * microcode, and incurs significant performance degradation. This hint + * instructs the thread pool to disable support for denormalized numbers before + * running the computation by manipulating architecture-specific control + * registers, and restore the initial value of control registers after the + * computation is complete. The thread pool temporary disables denormalized + * numbers on all threads involved in the computation (i.e. the caller threads, + * and potentially worker threads). + * + * Disabling denormalized numbers may have a small negative effect on results' + * accuracy. As various architectures differ in capabilities to control + * processing of denormalized numbers, using this flag may also hurt results' + * reproducibility across different instruction set architectures. + */ +#define PTHREADPOOL_FLAG_DISABLE_DENORMALS 0x00000001 + +/** + * Yield worker threads to the system scheduler after the operation is finished. + * + * Force workers to use kernel wait (instead of active spin-wait by default) for + * new commands after this command is processed. This flag affects only the + * immediate next operation on this thread pool. To make the thread pool always + * use kernel wait, pass this flag to all parallelization functions. + */ +#define PTHREADPOOL_FLAG_YIELD_WORKERS 0x00000002 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Create a thread pool with the specified number of threads. + * + * @param threads_count the number of threads in the thread pool. + * A value of 0 has special interpretation: it creates a thread pool with as + * many threads as there are logical processors in the system. + * + * @returns A pointer to an opaque thread pool object if the call is + * successful, or NULL pointer if the call failed. + */ +pthreadpool_t pthreadpool_create(size_t threads_count); + +/** + * Query the number of threads in a thread pool. + * + * @param threadpool the thread pool to query. + * + * @returns The number of threads in the thread pool. + */ +size_t pthreadpool_get_threads_count(pthreadpool_t threadpool); + +/** + * Process items on a 1D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range; i++) + * function(context, i); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each item. + * @param context the first argument passed to the specified function. + * @param range the number of items on the 1D grid to process. The + * specified function will be called once for each item. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_1d( + pthreadpool_t threadpool, + pthreadpool_task_1d_t function, + void* context, + size_t range, + uint32_t flags); + +/** + * Process items on a 1D grid passing along the current thread id. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range; i++) + * function(context, thread_index, i); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each item. + * @param context the first argument passed to the specified function. + * @param range the number of items on the 1D grid to process. The + * specified function will be called once for each item. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_1d_with_thread( + pthreadpool_t threadpool, + pthreadpool_task_1d_with_thread_t function, + void* context, + size_t range, + uint32_t flags); + +/** + * Process items on a 1D grid using a microarchitecture-aware task function. + * + * The function implements a parallel version of the following snippet: + * + * uint32_t uarch_index = cpuinfo_initialize() ? + * cpuinfo_get_current_uarch_index() : default_uarch_index; + * if (uarch_index > max_uarch_index) uarch_index = default_uarch_index; + * for (size_t i = 0; i < range; i++) + * function(context, uarch_index, i); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If + * threadpool is NULL, all items are processed serially on the calling + * thread. + * @param function the function to call for each item. + * @param context the first argument passed to the specified + * function. + * @param default_uarch_index the microarchitecture index to use when + * pthreadpool is configured without cpuinfo, cpuinfo initialization failed, + * or index returned by cpuinfo_get_current_uarch_index() exceeds the + * max_uarch_index value. + * @param max_uarch_index the maximum microarchitecture index expected by + * the specified function. If the index returned by + * cpuinfo_get_current_uarch_index() exceeds this value, default_uarch_index + * will be used instead. default_uarch_index can exceed max_uarch_index. + * @param range the number of items on the 1D grid to process. + * The specified function will be called once for each item. + * @param flags a bitwise combination of zero or more optional + * flags (PTHREADPOOL_FLAG_DISABLE_DENORMALS or + * PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_1d_with_uarch( + pthreadpool_t threadpool, + pthreadpool_task_1d_with_id_t function, + void* context, + uint32_t default_uarch_index, + uint32_t max_uarch_index, + size_t range, + uint32_t flags); + +/** + * Process items on a 1D grid with specified maximum tile size. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range; i += tile) + * function(context, i, min(range - i, tile)); + * + * When the call returns, all items have been processed and the thread pool is + * ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, + * the calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range the number of items on the 1D grid to process. + * @param tile the maximum number of items on the 1D grid to process in + * one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_1d_tile_1d( + pthreadpool_t threadpool, + pthreadpool_task_1d_tile_1d_t function, + void* context, + size_t range, + size_t tile, + uint32_t flags); + +/** + * Process items on a 2D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * function(context, i, j); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each item. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 2D grid. + * @param range_j the number of items to process along the second dimension + * of the 2D grid. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_2d( + pthreadpool_t threadpool, + pthreadpool_task_2d_t function, + void* context, + size_t range_i, + size_t range_j, + uint32_t flags); + +/** + * Process items on a 2D grid passing along the current thread id. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * function(context, thread_index, i, j); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each item. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 2D grid. + * @param range_j the number of items to process along the second dimension + * of the 2D grid. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_2d_with_thread( + pthreadpool_t threadpool, + pthreadpool_task_2d_with_thread_t function, + void* context, + size_t range_i, + size_t range_j, + uint32_t flags); + +/** + * Process items on a 2D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j += tile_j) + * function(context, i, j, min(range_j - j, tile_j)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 2D grid. + * @param range_j the number of items to process along the second dimension + * of the 2D grid. + * @param tile_j the maximum number of items along the second dimension of + * the 2D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_2d_tile_1d( + pthreadpool_t threadpool, + pthreadpool_task_2d_tile_1d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t tile_j, + uint32_t flags); + +/** + * Process items on a 2D grid with the specified maximum tile size along the + * last grid dimension using a microarchitecture-aware task function. + * + * The function implements a parallel version of the following snippet: + * + * uint32_t uarch_index = cpuinfo_initialize() ? + * cpuinfo_get_current_uarch_index() : default_uarch_index; + * if (uarch_index > max_uarch_index) uarch_index = default_uarch_index; + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j += tile_j) + * function(context, uarch_index, i, j, min(range_j - j, tile_j)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param default_uarch_index the microarchitecture index to use when + * pthreadpool is configured without cpuinfo, cpuinfo initialization failed, + * or index returned by cpuinfo_get_current_uarch_index() exceeds the + * max_uarch_index value. + * @param max_uarch_index the maximum microarchitecture index expected by + * the specified function. If the index returned by + * cpuinfo_get_current_uarch_index() exceeds this value, default_uarch_index + * will be used instead. default_uarch_index can exceed max_uarch_index. + * @param range_i the number of items to process along the first dimension + * of the 2D grid. + * @param range_j the number of items to process along the second dimension + * of the 2D grid. + * @param tile_j the maximum number of items along the second dimension of + * the 2D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_2d_tile_1d_with_uarch( + pthreadpool_t threadpool, + pthreadpool_task_2d_tile_1d_with_id_t function, + void* context, + uint32_t default_uarch_index, + uint32_t max_uarch_index, + size_t range_i, + size_t range_j, + size_t tile_j, + uint32_t flags); + +/** + * Process items on a 2D grid with the specified maximum tile size along the + * last grid dimension using a microarchitecture-aware task function and passing + * along the current thread id. + * + * The function implements a parallel version of the following snippet: + * + * uint32_t uarch_index = cpuinfo_initialize() ? + * cpuinfo_get_current_uarch_index() : default_uarch_index; + * if (uarch_index > max_uarch_index) uarch_index = default_uarch_index; + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j += tile_j) + * function(context, uarch_index, thread_index, i, j, min(range_j - j, tile_j)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param default_uarch_index the microarchitecture index to use when + * pthreadpool is configured without cpuinfo, cpuinfo initialization failed, + * or index returned by cpuinfo_get_current_uarch_index() exceeds the + * max_uarch_index value. + * @param max_uarch_index the maximum microarchitecture index expected by + * the specified function. If the index returned by + * cpuinfo_get_current_uarch_index() exceeds this value, default_uarch_index + * will be used instead. default_uarch_index can exceed max_uarch_index. + * @param range_i the number of items to process along the first dimension + * of the 2D grid. + * @param range_j the number of items to process along the second dimension + * of the 2D grid. + * @param tile_j the maximum number of items along the second dimension of + * the 2D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_2d_tile_1d_with_uarch_with_thread( + pthreadpool_t threadpool, + pthreadpool_task_2d_tile_1d_with_id_with_thread_t function, + void* context, + uint32_t default_uarch_index, + uint32_t max_uarch_index, + size_t range_i, + size_t range_j, + size_t tile_j, + uint32_t flags); + +/** + * Process items on a 2D grid with the specified maximum tile size along each + * grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i += tile_i) + * for (size_t j = 0; j < range_j; j += tile_j) + * function(context, i, j, + * min(range_i - i, tile_i), min(range_j - j, tile_j)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 2D grid. + * @param range_j the number of items to process along the second dimension + * of the 2D grid. + * @param tile_j the maximum number of items along the first dimension of + * the 2D grid to process in one function call. + * @param tile_j the maximum number of items along the second dimension of + * the 2D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_2d_tile_2d( + pthreadpool_t threadpool, + pthreadpool_task_2d_tile_2d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t tile_i, + size_t tile_j, + uint32_t flags); + +/** + * Process items on a 2D grid with the specified maximum tile size along each + * grid dimension using a microarchitecture-aware task function. + * + * The function implements a parallel version of the following snippet: + * + * uint32_t uarch_index = cpuinfo_initialize() ? + * cpuinfo_get_current_uarch_index() : default_uarch_index; + * if (uarch_index > max_uarch_index) uarch_index = default_uarch_index; + * for (size_t i = 0; i < range_i; i += tile_i) + * for (size_t j = 0; j < range_j; j += tile_j) + * function(context, uarch_index, i, j, + * min(range_i - i, tile_i), min(range_j - j, tile_j)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If + * threadpool is NULL, all items are processed serially on the calling + * thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified + * function. + * @param default_uarch_index the microarchitecture index to use when + * pthreadpool is configured without cpuinfo, + * cpuinfo initialization failed, or index returned + * by cpuinfo_get_current_uarch_index() exceeds + * the max_uarch_index value. + * @param max_uarch_index the maximum microarchitecture index expected + * by the specified function. If the index returned + * by cpuinfo_get_current_uarch_index() exceeds this + * value, default_uarch_index will be used instead. + * default_uarch_index can exceed max_uarch_index. + * @param range_i the number of items to process along the first + * dimension of the 2D grid. + * @param range_j the number of items to process along the second + * dimension of the 2D grid. + * @param tile_j the maximum number of items along the first + * dimension of the 2D grid to process in one function call. + * @param tile_j the maximum number of items along the second + * dimension of the 2D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional + * flags (PTHREADPOOL_FLAG_DISABLE_DENORMALS or + * PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_2d_tile_2d_with_uarch( + pthreadpool_t threadpool, + pthreadpool_task_2d_tile_2d_with_id_t function, + void* context, + uint32_t default_uarch_index, + uint32_t max_uarch_index, + size_t range_i, + size_t range_j, + size_t tile_i, + size_t tile_j, + uint32_t flags); + +/** + * Process items on a 3D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * function(context, i, j, k); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 3D grid. + * @param range_j the number of items to process along the second dimension + * of the 3D grid. + * @param range_k the number of items to process along the third dimension + * of the 3D grid. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_3d( + pthreadpool_t threadpool, + pthreadpool_task_3d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + uint32_t flags); + +/** + * Process items on a 3D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k += tile_k) + * function(context, i, j, k, min(range_k - k, tile_k)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 3D grid. + * @param range_j the number of items to process along the second dimension + * of the 3D grid. + * @param range_k the number of items to process along the third dimension + * of the 3D grid. + * @param tile_k the maximum number of items along the third dimension of + * the 3D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_3d_tile_1d( + pthreadpool_t threadpool, + pthreadpool_task_3d_tile_1d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_k, + uint32_t flags); + +/** + * Process items on a 3D grid with the specified maximum tile size along the + * last grid dimension and passing along the current thread id. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k += tile_k) + * function(context, thread_index, i, j, k, min(range_k - k, tile_k)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 3D grid. + * @param range_j the number of items to process along the second dimension + * of the 3D grid. + * @param range_k the number of items to process along the third dimension + * of the 3D grid. + * @param tile_k the maximum number of items along the third dimension of + * the 3D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_3d_tile_1d_with_thread( + pthreadpool_t threadpool, + pthreadpool_task_3d_tile_1d_with_thread_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_k, + uint32_t flags); + +/** + * Process items on a 3D grid with the specified maximum tile size along the + * last grid dimension using a microarchitecture-aware task function. + * + * The function implements a parallel version of the following snippet: + * + * uint32_t uarch_index = cpuinfo_initialize() ? + * cpuinfo_get_current_uarch_index() : default_uarch_index; + * if (uarch_index > max_uarch_index) uarch_index = default_uarch_index; + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k += tile_k) + * function(context, uarch_index, i, j, k, min(range_k - k, tile_k)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If + * threadpool is NULL, all items are processed serially on the calling + * thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified + * function. + * @param default_uarch_index the microarchitecture index to use when + * pthreadpool is configured without cpuinfo, cpuinfo initialization failed, + * or index returned by cpuinfo_get_current_uarch_index() exceeds the + * max_uarch_index value. + * @param max_uarch_index the maximum microarchitecture index expected by + * the specified function. If the index returned by + * cpuinfo_get_current_uarch_index() exceeds this value, default_uarch_index + * will be used instead. default_uarch_index can exceed max_uarch_index. + * @param range_i the number of items to process along the first + * dimension of the 3D grid. + * @param range_j the number of items to process along the second + * dimension of the 3D grid. + * @param range_k the number of items to process along the third + * dimension of the 3D grid. + * @param tile_k the maximum number of items along the third + * dimension of the 3D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional + * flags (PTHREADPOOL_FLAG_DISABLE_DENORMALS or + * PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_3d_tile_1d_with_uarch( + pthreadpool_t threadpool, + pthreadpool_task_3d_tile_1d_with_id_t function, + void* context, + uint32_t default_uarch_index, + uint32_t max_uarch_index, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_k, + uint32_t flags); + +/** + * Process items on a 3D grid with the specified maximum tile size along the + * last grid dimension using a microarchitecture-aware task function and passing + * along the current thread id. + * + * The function implements a parallel version of the following snippet: + * + * uint32_t uarch_index = cpuinfo_initialize() ? + * cpuinfo_get_current_uarch_index() : default_uarch_index; + * if (uarch_index > max_uarch_index) uarch_index = default_uarch_index; + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k += tile_k) + * function(context, uarch_index, thread_index, i, j, k, min(range_k - k, tile_k)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If + * threadpool is NULL, all items are processed serially on the calling + * thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified + * function. + * @param default_uarch_index the microarchitecture index to use when + * pthreadpool is configured without cpuinfo, cpuinfo initialization failed, + * or index returned by cpuinfo_get_current_uarch_index() exceeds the + * max_uarch_index value. + * @param max_uarch_index the maximum microarchitecture index expected by + * the specified function. If the index returned by + * cpuinfo_get_current_uarch_index() exceeds this value, default_uarch_index + * will be used instead. default_uarch_index can exceed max_uarch_index. + * @param range_i the number of items to process along the first + * dimension of the 3D grid. + * @param range_j the number of items to process along the second + * dimension of the 3D grid. + * @param range_k the number of items to process along the third + * dimension of the 3D grid. + * @param tile_k the maximum number of items along the third + * dimension of the 3D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional + * flags (PTHREADPOOL_FLAG_DISABLE_DENORMALS or + * PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_3d_tile_1d_with_uarch_with_thread( + pthreadpool_t threadpool, + pthreadpool_task_3d_tile_1d_with_id_with_thread_t function, + void* context, + uint32_t default_uarch_index, + uint32_t max_uarch_index, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_k, + uint32_t flags); + +/** + * Process items on a 3D grid with the specified maximum tile size along the + * last two grid dimensions. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j += tile_j) + * for (size_t k = 0; k < range_k; k += tile_k) + * function(context, i, j, k, + * min(range_j - j, tile_j), min(range_k - k, tile_k)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 3D grid. + * @param range_j the number of items to process along the second dimension + * of the 3D grid. + * @param range_k the number of items to process along the third dimension + * of the 3D grid. + * @param tile_j the maximum number of items along the second dimension of + * the 3D grid to process in one function call. + * @param tile_k the maximum number of items along the third dimension of + * the 3D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_3d_tile_2d( + pthreadpool_t threadpool, + pthreadpool_task_3d_tile_2d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_j, + size_t tile_k, + uint32_t flags); + +/** + * Process items on a 3D grid with the specified maximum tile size along the + * last two grid dimensions using a microarchitecture-aware task function. + * + * The function implements a parallel version of the following snippet: + * + * uint32_t uarch_index = cpuinfo_initialize() ? + * cpuinfo_get_current_uarch_index() : default_uarch_index; + * if (uarch_index > max_uarch_index) uarch_index = default_uarch_index; + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j += tile_j) + * for (size_t k = 0; k < range_k; k += tile_k) + * function(context, uarch_index, i, j, k, + * min(range_j - j, tile_j), min(range_k - k, tile_k)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If + * threadpool is NULL, all items are processed serially on the calling + * thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified + * function. + * @param default_uarch_index the microarchitecture index to use when + * pthreadpool is configured without cpuinfo, cpuinfo initialization failed, + * or index returned by cpuinfo_get_current_uarch_index() exceeds the + * max_uarch_index value. + * @param max_uarch_index the maximum microarchitecture index expected by + * the specified function. If the index returned by + * cpuinfo_get_current_uarch_index() exceeds this value, default_uarch_index + * will be used instead. default_uarch_index can exceed max_uarch_index. + * @param range_i the number of items to process along the first + * dimension of the 3D grid. + * @param range_j the number of items to process along the second + * dimension of the 3D grid. + * @param range_k the number of items to process along the third + * dimension of the 3D grid. + * @param tile_j the maximum number of items along the second + * dimension of the 3D grid to process in one function call. + * @param tile_k the maximum number of items along the third + * dimension of the 3D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional + * flags (PTHREADPOOL_FLAG_DISABLE_DENORMALS or + * PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_3d_tile_2d_with_uarch( + pthreadpool_t threadpool, + pthreadpool_task_3d_tile_2d_with_id_t function, + void* context, + uint32_t default_uarch_index, + uint32_t max_uarch_index, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_j, + size_t tile_k, + uint32_t flags); + +/** + * Process items on a 4D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * function(context, i, j, k, l); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 4D grid. + * @param range_j the number of items to process along the second dimension + * of the 4D grid. + * @param range_k the number of items to process along the third dimension + * of the 4D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 4D grid. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_4d( + pthreadpool_t threadpool, + pthreadpool_task_4d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + uint32_t flags); + +/** + * Process items on a 4D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l += tile_l) + * function(context, i, j, k, l, min(range_l - l, tile_l)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 4D grid. + * @param range_j the number of items to process along the second dimension + * of the 4D grid. + * @param range_k the number of items to process along the third dimension + * of the 4D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 4D grid. + * @param tile_l the maximum number of items along the fourth dimension of + * the 4D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_4d_tile_1d( + pthreadpool_t threadpool, + pthreadpool_task_4d_tile_1d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t tile_l, + uint32_t flags); + +/** + * Process items on a 4D grid with the specified maximum tile size along the + * last two grid dimensions. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k += tile_k) + * for (size_t l = 0; l < range_l; l += tile_l) + * function(context, i, j, k, l, + * min(range_k - k, tile_k), min(range_l - l, tile_l)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 4D grid. + * @param range_j the number of items to process along the second dimension + * of the 4D grid. + * @param range_k the number of items to process along the third dimension + * of the 4D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 4D grid. + * @param tile_k the maximum number of items along the third dimension of + * the 4D grid to process in one function call. + * @param tile_l the maximum number of items along the fourth dimension of + * the 4D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_4d_tile_2d( + pthreadpool_t threadpool, + pthreadpool_task_4d_tile_2d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t tile_k, + size_t tile_l, + uint32_t flags); + +/** + * Process items on a 4D grid with the specified maximum tile size along the + * last two grid dimensions using a microarchitecture-aware task function. + * + * The function implements a parallel version of the following snippet: + * + * uint32_t uarch_index = cpuinfo_initialize() ? + * cpuinfo_get_current_uarch_index() : default_uarch_index; + * if (uarch_index > max_uarch_index) uarch_index = default_uarch_index; + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k += tile_k) + * for (size_t l = 0; l < range_l; l += tile_l) + * function(context, uarch_index, i, j, k, l, + * min(range_k - k, tile_k), min(range_l - l, tile_l)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If + * threadpool is NULL, all items are processed serially on the calling + * thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified + * function. + * @param default_uarch_index the microarchitecture index to use when + * pthreadpool is configured without cpuinfo, cpuinfo initialization failed, + * or index returned by cpuinfo_get_current_uarch_index() exceeds the + * max_uarch_index value. + * @param max_uarch_index the maximum microarchitecture index expected by + * the specified function. If the index returned by + * cpuinfo_get_current_uarch_index() exceeds this value, default_uarch_index + * will be used instead. default_uarch_index can exceed max_uarch_index. + * @param range_i the number of items to process along the first + * dimension of the 4D grid. + * @param range_j the number of items to process along the second + * dimension of the 4D grid. + * @param range_k the number of items to process along the third + * dimension of the 4D grid. + * @param range_l the number of items to process along the fourth + * dimension of the 4D grid. + * @param tile_k the maximum number of items along the third + * dimension of the 4D grid to process in one function call. + * @param tile_l the maximum number of items along the fourth + * dimension of the 4D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional + * flags (PTHREADPOOL_FLAG_DISABLE_DENORMALS or + * PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_4d_tile_2d_with_uarch( + pthreadpool_t threadpool, + pthreadpool_task_4d_tile_2d_with_id_t function, + void* context, + uint32_t default_uarch_index, + uint32_t max_uarch_index, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t tile_k, + size_t tile_l, + uint32_t flags); + +/** + * Process items on a 5D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m++) + * function(context, i, j, k, l, m); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 5D grid. + * @param range_j the number of items to process along the second dimension + * of the 5D grid. + * @param range_k the number of items to process along the third dimension + * of the 5D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 5D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 5D grid. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_5d( + pthreadpool_t threadpool, + pthreadpool_task_5d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + uint32_t flags); + +/** + * Process items on a 5D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m += tile_m) + * function(context, i, j, k, l, m, min(range_m - m, tile_m)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 5D grid. + * @param range_j the number of items to process along the second dimension + * of the 5D grid. + * @param range_k the number of items to process along the third dimension + * of the 5D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 5D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 5D grid. + * @param tile_m the maximum number of items along the fifth dimension of + * the 5D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_5d_tile_1d( + pthreadpool_t threadpool, + pthreadpool_task_5d_tile_1d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t tile_m, + uint32_t flags); + +/** + * Process items on a 5D grid with the specified maximum tile size along the + * last two grid dimensions. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l += tile_l) + * for (size_t m = 0; m < range_m; m += tile_m) + * function(context, i, j, k, l, m, + * min(range_l - l, tile_l), min(range_m - m, tile_m)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 5D grid. + * @param range_j the number of items to process along the second dimension + * of the 5D grid. + * @param range_k the number of items to process along the third dimension + * of the 5D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 5D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 5D grid. + * @param tile_l the maximum number of items along the fourth dimension of + * the 5D grid to process in one function call. + * @param tile_m the maximum number of items along the fifth dimension of + * the 5D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_5d_tile_2d( + pthreadpool_t threadpool, + pthreadpool_task_5d_tile_2d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t tile_l, + size_t tile_m, + uint32_t flags); + +/** + * Process items on a 6D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m++) + * for (size_t n = 0; n < range_n; n++) + * function(context, i, j, k, l, m, n); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 6D grid. + * @param range_j the number of items to process along the second dimension + * of the 6D grid. + * @param range_k the number of items to process along the third dimension + * of the 6D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 6D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 6D grid. + * @param range_n the number of items to process along the sixth dimension + * of the 6D grid. + * @param tile_n the maximum number of items along the sixth dimension of + * the 6D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_6d( + pthreadpool_t threadpool, + pthreadpool_task_6d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t range_n, + uint32_t flags); + +/** + * Process items on a 6D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m++) + * for (size_t n = 0; n < range_n; n += tile_n) + * function(context, i, j, k, l, m, n, min(range_n - n, tile_n)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 6D grid. + * @param range_j the number of items to process along the second dimension + * of the 6D grid. + * @param range_k the number of items to process along the third dimension + * of the 6D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 6D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 6D grid. + * @param range_n the number of items to process along the sixth dimension + * of the 6D grid. + * @param tile_n the maximum number of items along the sixth dimension of + * the 6D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_6d_tile_1d( + pthreadpool_t threadpool, + pthreadpool_task_6d_tile_1d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t range_n, + size_t tile_n, + uint32_t flags); + +/** + * Process items on a 6D grid with the specified maximum tile size along the + * last two grid dimensions. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m += tile_m) + * for (size_t n = 0; n < range_n; n += tile_n) + * function(context, i, j, k, l, m, n, + * min(range_m - m, tile_m), min(range_n - n, tile_n)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param function the function to call for each tile. + * @param context the first argument passed to the specified function. + * @param range_i the number of items to process along the first dimension + * of the 6D grid. + * @param range_j the number of items to process along the second dimension + * of the 6D grid. + * @param range_k the number of items to process along the third dimension + * of the 6D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 6D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 6D grid. + * @param range_n the number of items to process along the sixth dimension + * of the 6D grid. + * @param tile_m the maximum number of items along the fifth dimension of + * the 6D grid to process in one function call. + * @param tile_n the maximum number of items along the sixth dimension of + * the 6D grid to process in one function call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +void pthreadpool_parallelize_6d_tile_2d( + pthreadpool_t threadpool, + pthreadpool_task_6d_tile_2d_t function, + void* context, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t range_n, + size_t tile_m, + size_t tile_n, + uint32_t flags); + +/** + * Terminates threads in the thread pool and releases associated resources. + * + * @warning Accessing the thread pool after a call to this function constitutes + * undefined behaviour and may cause data corruption. + * + * @param[in,out] threadpool The thread pool to destroy. + */ +void pthreadpool_destroy(pthreadpool_t threadpool); + +#ifndef PTHREADPOOL_NO_DEPRECATED_API + +/* Legacy API for compatibility with pre-existing users (e.g. NNPACK) */ +#if defined(__GNUC__) + #define PTHREADPOOL_DEPRECATED __attribute__((__deprecated__)) +#else + #define PTHREADPOOL_DEPRECATED +#endif + +typedef void (*pthreadpool_function_1d_t)(void*, size_t); +typedef void (*pthreadpool_function_1d_tiled_t)(void*, size_t, size_t); +typedef void (*pthreadpool_function_2d_t)(void*, size_t, size_t); +typedef void (*pthreadpool_function_2d_tiled_t)(void*, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_function_3d_tiled_t)(void*, size_t, size_t, size_t, size_t, size_t, size_t); +typedef void (*pthreadpool_function_4d_tiled_t)(void*, size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t); + +void pthreadpool_compute_1d( + pthreadpool_t threadpool, + pthreadpool_function_1d_t function, + void* argument, + size_t range) PTHREADPOOL_DEPRECATED; + +void pthreadpool_compute_1d_tiled( + pthreadpool_t threadpool, + pthreadpool_function_1d_tiled_t function, + void* argument, + size_t range, + size_t tile) PTHREADPOOL_DEPRECATED; + +void pthreadpool_compute_2d( + pthreadpool_t threadpool, + pthreadpool_function_2d_t function, + void* argument, + size_t range_i, + size_t range_j) PTHREADPOOL_DEPRECATED; + +void pthreadpool_compute_2d_tiled( + pthreadpool_t threadpool, + pthreadpool_function_2d_tiled_t function, + void* argument, + size_t range_i, + size_t range_j, + size_t tile_i, + size_t tile_j) PTHREADPOOL_DEPRECATED; + +void pthreadpool_compute_3d_tiled( + pthreadpool_t threadpool, + pthreadpool_function_3d_tiled_t function, + void* argument, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_i, + size_t tile_j, + size_t tile_k) PTHREADPOOL_DEPRECATED; + +void pthreadpool_compute_4d_tiled( + pthreadpool_t threadpool, + pthreadpool_function_4d_tiled_t function, + void* argument, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t tile_i, + size_t tile_j, + size_t tile_k, + size_t tile_l) PTHREADPOOL_DEPRECATED; + +#endif /* PTHREADPOOL_NO_DEPRECATED_API */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus + +namespace libpthreadpool { +namespace detail { +namespace { + +template +void call_wrapper_1d(void* arg, size_t i) { + (*static_cast(arg))(i); +} + +template +void call_wrapper_1d_tile_1d(void* arg, size_t range_i, size_t tile_i) { + (*static_cast(arg))(range_i, tile_i); +} + +template +void call_wrapper_2d(void* functor, size_t i, size_t j) { + (*static_cast(functor))(i, j); +} + +template +void call_wrapper_2d_tile_1d(void* functor, + size_t i, size_t range_j, size_t tile_j) +{ + (*static_cast(functor))(i, range_j, tile_j); +} + +template +void call_wrapper_2d_tile_2d(void* functor, + size_t range_i, size_t range_j, + size_t tile_i, size_t tile_j) +{ + (*static_cast(functor))(range_i, range_j, tile_i, tile_j); +} + +template +void call_wrapper_3d(void* functor, size_t i, size_t j, size_t k) { + (*static_cast(functor))(i, j, k); +} + +template +void call_wrapper_3d_tile_1d(void* functor, + size_t i, size_t j, size_t range_k, + size_t tile_k) +{ + (*static_cast(functor))(i, j, range_k, tile_k); +} + +template +void call_wrapper_3d_tile_2d(void* functor, + size_t i, size_t range_j, size_t range_k, + size_t tile_j, size_t tile_k) +{ + (*static_cast(functor))(i, range_j, range_k, tile_j, tile_k); +} + +template +void call_wrapper_4d(void* functor, size_t i, size_t j, size_t k, size_t l) { + (*static_cast(functor))(i, j, k, l); +} + +template +void call_wrapper_4d_tile_1d(void* functor, + size_t i, size_t j, size_t k, size_t range_l, + size_t tile_l) +{ + (*static_cast(functor))(i, j, k, range_l, tile_l); +} + +template +void call_wrapper_4d_tile_2d(void* functor, + size_t i, size_t j, size_t range_k, size_t range_l, + size_t tile_k, size_t tile_l) +{ + (*static_cast(functor))(i, j, range_k, range_l, tile_k, tile_l); +} + +template +void call_wrapper_5d(void* functor, size_t i, size_t j, size_t k, size_t l, size_t m) { + (*static_cast(functor))(i, j, k, l, m); +} + +template +void call_wrapper_5d_tile_1d(void* functor, + size_t i, size_t j, size_t k, size_t l, size_t range_m, + size_t tile_m) +{ + (*static_cast(functor))(i, j, k, l, range_m, tile_m); +} + +template +void call_wrapper_5d_tile_2d(void* functor, + size_t i, size_t j, size_t k, size_t range_l, size_t range_m, + size_t tile_l, size_t tile_m) +{ + (*static_cast(functor))(i, j, k, range_l, range_m, tile_l, tile_m); +} + +template +void call_wrapper_6d(void* functor, size_t i, size_t j, size_t k, size_t l, size_t m, size_t n) { + (*static_cast(functor))(i, j, k, l, m, n); +} + +template +void call_wrapper_6d_tile_1d(void* functor, + size_t i, size_t j, size_t k, size_t l, size_t m, size_t range_n, + size_t tile_n) +{ + (*static_cast(functor))(i, j, k, l, m, range_n, tile_n); +} + +template +void call_wrapper_6d_tile_2d(void* functor, + size_t i, size_t j, size_t k, size_t l, size_t range_m, size_t range_n, + size_t tile_m, size_t tile_n) +{ + (*static_cast(functor))(i, j, k, l, range_m, range_n, tile_m, tile_n); +} + +} /* namespace */ +} /* namespace detail */ +} /* namespace libpthreadpool */ + +/** + * Process items on a 1D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range; i++) + * functor(i); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each item. + * @param range the number of items on the 1D grid to process. The + * specified functor will be called once for each item. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_1d( + pthreadpool_t threadpool, + const T& functor, + size_t range, + uint32_t flags = 0) +{ + pthreadpool_parallelize_1d( + threadpool, + &libpthreadpool::detail::call_wrapper_1d, + const_cast(static_cast(&functor)), + range, + flags); +} + +/** + * Process items on a 1D grid with specified maximum tile size. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range; i += tile) + * functor(i, min(range - i, tile)); + * + * When the call returns, all items have been processed and the thread pool is + * ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, + * the calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range the number of items on the 1D grid to process. + * @param tile the maximum number of items on the 1D grid to process in + * one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_1d_tile_1d( + pthreadpool_t threadpool, + const T& functor, + size_t range, + size_t tile, + uint32_t flags = 0) +{ + pthreadpool_parallelize_1d_tile_1d( + threadpool, + &libpthreadpool::detail::call_wrapper_1d_tile_1d, + const_cast(static_cast(&functor)), + range, + tile, + flags); +} + +/** + * Process items on a 2D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * functor(i, j); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each item. + * @param range_i the number of items to process along the first dimension + * of the 2D grid. + * @param range_j the number of items to process along the second dimension + * of the 2D grid. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_2d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + uint32_t flags = 0) +{ + pthreadpool_parallelize_2d( + threadpool, + &libpthreadpool::detail::call_wrapper_2d, + const_cast(static_cast(&functor)), + range_i, + range_j, + flags); +} + +/** + * Process items on a 2D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j += tile_j) + * functor(i, j, min(range_j - j, tile_j)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 2D grid. + * @param range_j the number of items to process along the second dimension + * of the 2D grid. + * @param tile_j the maximum number of items along the second dimension of + * the 2D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_2d_tile_1d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t tile_j, + uint32_t flags = 0) +{ + pthreadpool_parallelize_2d_tile_1d( + threadpool, + &libpthreadpool::detail::call_wrapper_2d_tile_1d, + const_cast(static_cast(&functor)), + range_i, + range_j, + tile_j, + flags); +} + +/** + * Process items on a 2D grid with the specified maximum tile size along each + * grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i += tile_i) + * for (size_t j = 0; j < range_j; j += tile_j) + * functor(i, j, + * min(range_i - i, tile_i), min(range_j - j, tile_j)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 2D grid. + * @param range_j the number of items to process along the second dimension + * of the 2D grid. + * @param tile_j the maximum number of items along the first dimension of + * the 2D grid to process in one functor call. + * @param tile_j the maximum number of items along the second dimension of + * the 2D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_2d_tile_2d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t tile_i, + size_t tile_j, + uint32_t flags = 0) +{ + pthreadpool_parallelize_2d_tile_2d( + threadpool, + &libpthreadpool::detail::call_wrapper_2d_tile_2d, + const_cast(static_cast(&functor)), + range_i, + range_j, + tile_i, + tile_j, + flags); +} + +/** + * Process items on a 3D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * functor(i, j, k); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 3D grid. + * @param range_j the number of items to process along the second dimension + * of the 3D grid. + * @param range_k the number of items to process along the third dimension + * of the 3D grid. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_3d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + uint32_t flags = 0) +{ + pthreadpool_parallelize_3d( + threadpool, + &libpthreadpool::detail::call_wrapper_3d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + flags); +} + +/** + * Process items on a 3D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k += tile_k) + * functor(i, j, k, min(range_k - k, tile_k)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 3D grid. + * @param range_j the number of items to process along the second dimension + * of the 3D grid. + * @param range_k the number of items to process along the third dimension + * of the 3D grid. + * @param tile_k the maximum number of items along the third dimension of + * the 3D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_3d_tile_1d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_k, + uint32_t flags = 0) +{ + pthreadpool_parallelize_3d_tile_1d( + threadpool, + &libpthreadpool::detail::call_wrapper_3d_tile_1d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + tile_k, + flags); +} + +/** + * Process items on a 3D grid with the specified maximum tile size along the + * last two grid dimensions. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j += tile_j) + * for (size_t k = 0; k < range_k; k += tile_k) + * functor(i, j, k, + * min(range_j - j, tile_j), min(range_k - k, tile_k)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 3D grid. + * @param range_j the number of items to process along the second dimension + * of the 3D grid. + * @param range_k the number of items to process along the third dimension + * of the 3D grid. + * @param tile_j the maximum number of items along the second dimension of + * the 3D grid to process in one functor call. + * @param tile_k the maximum number of items along the third dimension of + * the 3D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_3d_tile_2d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t tile_j, + size_t tile_k, + uint32_t flags = 0) +{ + pthreadpool_parallelize_3d_tile_2d( + threadpool, + &libpthreadpool::detail::call_wrapper_3d_tile_2d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + tile_j, + tile_k, + flags); +} + +/** + * Process items on a 4D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * functor(i, j, k, l); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 4D grid. + * @param range_j the number of items to process along the second dimension + * of the 4D grid. + * @param range_k the number of items to process along the third dimension + * of the 4D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 4D grid. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_4d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + uint32_t flags = 0) +{ + pthreadpool_parallelize_4d( + threadpool, + &libpthreadpool::detail::call_wrapper_4d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + range_l, + flags); +} + +/** + * Process items on a 4D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l += tile_l) + * functor(i, j, k, l, min(range_l - l, tile_l)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 4D grid. + * @param range_j the number of items to process along the second dimension + * of the 4D grid. + * @param range_k the number of items to process along the third dimension + * of the 4D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 4D grid. + * @param tile_l the maximum number of items along the fourth dimension of + * the 4D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_4d_tile_1d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t tile_l, + uint32_t flags = 0) +{ + pthreadpool_parallelize_4d_tile_1d( + threadpool, + &libpthreadpool::detail::call_wrapper_4d_tile_1d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + range_l, + tile_l, + flags); +} + +/** + * Process items on a 4D grid with the specified maximum tile size along the + * last two grid dimensions. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k += tile_k) + * for (size_t l = 0; l < range_l; l += tile_l) + * functor(i, j, k, l, + * min(range_k - k, tile_k), min(range_l - l, tile_l)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 4D grid. + * @param range_j the number of items to process along the second dimension + * of the 4D grid. + * @param range_k the number of items to process along the third dimension + * of the 4D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 4D grid. + * @param tile_k the maximum number of items along the third dimension of + * the 4D grid to process in one functor call. + * @param tile_l the maximum number of items along the fourth dimension of + * the 4D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_4d_tile_2d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t tile_k, + size_t tile_l, + uint32_t flags = 0) +{ + pthreadpool_parallelize_4d_tile_2d( + threadpool, + &libpthreadpool::detail::call_wrapper_4d_tile_2d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + range_l, + tile_k, + tile_l, + flags); +} + +/** + * Process items on a 5D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m++) + * functor(i, j, k, l, m); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 5D grid. + * @param range_j the number of items to process along the second dimension + * of the 5D grid. + * @param range_k the number of items to process along the third dimension + * of the 5D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 5D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 5D grid. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_5d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + uint32_t flags = 0) +{ + pthreadpool_parallelize_5d( + threadpool, + &libpthreadpool::detail::call_wrapper_5d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + range_l, + range_m, + flags); +} + +/** + * Process items on a 5D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m += tile_m) + * functor(i, j, k, l, m, min(range_m - m, tile_m)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 5D grid. + * @param range_j the number of items to process along the second dimension + * of the 5D grid. + * @param range_k the number of items to process along the third dimension + * of the 5D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 5D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 5D grid. + * @param tile_m the maximum number of items along the fifth dimension of + * the 5D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_5d_tile_1d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t tile_m, + uint32_t flags = 0) +{ + pthreadpool_parallelize_5d_tile_1d( + threadpool, + &libpthreadpool::detail::call_wrapper_5d_tile_1d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + range_l, + range_m, + tile_m, + flags); +} + +/** + * Process items on a 5D grid with the specified maximum tile size along the + * last two grid dimensions. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l += tile_l) + * for (size_t m = 0; m < range_m; m += tile_m) + * functor(i, j, k, l, m, + * min(range_l - l, tile_l), min(range_m - m, tile_m)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 5D grid. + * @param range_j the number of items to process along the second dimension + * of the 5D grid. + * @param range_k the number of items to process along the third dimension + * of the 5D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 5D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 5D grid. + * @param tile_l the maximum number of items along the fourth dimension of + * the 5D grid to process in one functor call. + * @param tile_m the maximum number of items along the fifth dimension of + * the 5D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_5d_tile_2d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t tile_l, + size_t tile_m, + uint32_t flags = 0) +{ + pthreadpool_parallelize_5d_tile_2d( + threadpool, + &libpthreadpool::detail::call_wrapper_5d_tile_2d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + range_l, + range_m, + tile_l, + tile_m, + flags); +} + +/** + * Process items on a 6D grid. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m++) + * for (size_t n = 0; n < range_n; n++) + * functor(i, j, k, l, m, n); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 6D grid. + * @param range_j the number of items to process along the second dimension + * of the 6D grid. + * @param range_k the number of items to process along the third dimension + * of the 6D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 6D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 6D grid. + * @param range_n the number of items to process along the sixth dimension + * of the 6D grid. + * @param tile_n the maximum number of items along the sixth dimension of + * the 6D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_6d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t range_n, + uint32_t flags = 0) +{ + pthreadpool_parallelize_6d( + threadpool, + &libpthreadpool::detail::call_wrapper_6d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + range_l, + range_m, + range_n, + flags); +} + +/** + * Process items on a 6D grid with the specified maximum tile size along the + * last grid dimension. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m++) + * for (size_t n = 0; n < range_n; n += tile_n) + * functor(i, j, k, l, m, n, min(range_n - n, tile_n)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 6D grid. + * @param range_j the number of items to process along the second dimension + * of the 6D grid. + * @param range_k the number of items to process along the third dimension + * of the 6D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 6D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 6D grid. + * @param range_n the number of items to process along the sixth dimension + * of the 6D grid. + * @param tile_n the maximum number of items along the sixth dimension of + * the 6D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_6d_tile_1d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t range_n, + size_t tile_n, + uint32_t flags = 0) +{ + pthreadpool_parallelize_6d_tile_1d( + threadpool, + &libpthreadpool::detail::call_wrapper_6d_tile_1d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + range_l, + range_m, + range_n, + tile_n, + flags); +} + +/** + * Process items on a 6D grid with the specified maximum tile size along the + * last two grid dimensions. + * + * The function implements a parallel version of the following snippet: + * + * for (size_t i = 0; i < range_i; i++) + * for (size_t j = 0; j < range_j; j++) + * for (size_t k = 0; k < range_k; k++) + * for (size_t l = 0; l < range_l; l++) + * for (size_t m = 0; m < range_m; m += tile_m) + * for (size_t n = 0; n < range_n; n += tile_n) + * functor(i, j, k, l, m, n, + * min(range_m - m, tile_m), min(range_n - n, tile_n)); + * + * When the function returns, all items have been processed and the thread pool + * is ready for a new task. + * + * @note If multiple threads call this function with the same thread pool, the + * calls are serialized. + * + * @param threadpool the thread pool to use for parallelisation. If threadpool + * is NULL, all items are processed serially on the calling thread. + * @param functor the functor to call for each tile. + * @param range_i the number of items to process along the first dimension + * of the 6D grid. + * @param range_j the number of items to process along the second dimension + * of the 6D grid. + * @param range_k the number of items to process along the third dimension + * of the 6D grid. + * @param range_l the number of items to process along the fourth dimension + * of the 6D grid. + * @param range_m the number of items to process along the fifth dimension + * of the 6D grid. + * @param range_n the number of items to process along the sixth dimension + * of the 6D grid. + * @param tile_m the maximum number of items along the fifth dimension of + * the 6D grid to process in one functor call. + * @param tile_n the maximum number of items along the sixth dimension of + * the 6D grid to process in one functor call. + * @param flags a bitwise combination of zero or more optional flags + * (PTHREADPOOL_FLAG_DISABLE_DENORMALS or PTHREADPOOL_FLAG_YIELD_WORKERS) + */ +template +inline void pthreadpool_parallelize_6d_tile_2d( + pthreadpool_t threadpool, + const T& functor, + size_t range_i, + size_t range_j, + size_t range_k, + size_t range_l, + size_t range_m, + size_t range_n, + size_t tile_m, + size_t tile_n, + uint32_t flags = 0) +{ + pthreadpool_parallelize_6d_tile_2d( + threadpool, + &libpthreadpool::detail::call_wrapper_6d_tile_2d, + const_cast(static_cast(&functor)), + range_i, + range_j, + range_k, + range_l, + range_m, + range_n, + tile_m, + tile_n, + flags); +} + +#endif /* __cplusplus */ + +#endif /* PTHREADPOOL_H_ */ + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/attr.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/attr.h new file mode 100644 index 0000000000000000000000000000000000000000..cdf277758c1b84ed67ebd8199abfcf9198ef4a65 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/attr.h @@ -0,0 +1,727 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + pybind11/attr.h: Infrastructure for processing custom + type and function attributes + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "detail/common.h" +#include "cast.h" +#include "trampoline_self_life_support.h" + +#include + +PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +/// \addtogroup annotations +/// @{ + +/// Annotation for methods +struct is_method { + handle class_; + explicit is_method(const handle &c) : class_(c) {} +}; + +/// Annotation for setters +struct is_setter {}; + +/// Annotation for operators +struct is_operator {}; + +/// Annotation for classes that cannot be subclassed +struct is_final {}; + +/// Annotation for parent scope +struct scope { + handle value; + explicit scope(const handle &s) : value(s) {} +}; + +/// Annotation for documentation +struct doc { + const char *value; + explicit doc(const char *value) : value(value) {} +}; + +/// Annotation for function names +struct name { + const char *value; + explicit name(const char *value) : value(value) {} +}; + +/// Annotation indicating that a function is an overload associated with a given "sibling" +struct sibling { + handle value; + explicit sibling(const handle &value) : value(value.ptr()) {} +}; + +/// Annotation indicating that a class derives from another given type +template +struct base { + + PYBIND11_DEPRECATED( + "base() was deprecated in favor of specifying 'T' as a template argument to class_") + base() = default; +}; + +/// Keep patient alive while nurse lives +template +struct keep_alive {}; + +/// Annotation indicating that a class is involved in a multiple inheritance relationship +struct multiple_inheritance {}; + +/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class +struct dynamic_attr {}; + +/// Annotation which enables the buffer protocol for a type +struct buffer_protocol {}; + +/// Annotation which enables releasing the GIL before calling the C++ destructor of wrapped +/// instances (pybind/pybind11#1446). +struct release_gil_before_calling_cpp_dtor {}; + +/// Annotation which requests that a special metaclass is created for a type +struct metaclass { + handle value; + + PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.") + metaclass() = default; + + /// Override pybind11's default metaclass + explicit metaclass(handle value) : value(value) {} +}; + +/// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that +/// may be used to customize the Python type. +/// +/// The callback is invoked immediately before `PyType_Ready`. +/// +/// Note: This is an advanced interface, and uses of it may require changes to +/// work with later versions of pybind11. You may wish to consult the +/// implementation of `make_new_python_type` in `detail/classes.h` to understand +/// the context in which the callback will be run. +struct custom_type_setup { + using callback = std::function; + + explicit custom_type_setup(callback value) : value(std::move(value)) {} + + callback value; +}; + +/// Annotation that marks a class as local to the module: +struct module_local { + const bool value; + constexpr explicit module_local(bool v = true) : value(v) {} +}; + +/// Annotation to mark enums as an arithmetic type +struct arithmetic {}; + +/// Mark a function for addition at the beginning of the existing overload chain instead of the end +struct prepend {}; + +/** \rst + A call policy which places one or more guard variables (``Ts...``) around the function call. + + For example, this definition: + + .. code-block:: cpp + + m.def("foo", foo, py::call_guard()); + + is equivalent to the following pseudocode: + + .. code-block:: cpp + + m.def("foo", [](args...) { + T scope_guard; + return foo(args...); // forwarded arguments + }); + \endrst */ +template +struct call_guard; + +template <> +struct call_guard<> { + using type = detail::void_type; +}; + +template +struct call_guard { + static_assert(std::is_default_constructible::value, + "The guard type must be default constructible"); + + using type = T; +}; + +template +struct call_guard { + struct type { + T guard{}; // Compose multiple guard types with left-to-right default-constructor order + typename call_guard::type next{}; + }; +}; + +/// @} annotations + +PYBIND11_NAMESPACE_BEGIN(detail) +/* Forward declarations */ +enum op_id : int; +enum op_type : int; +struct undefined_t; +template +struct op_; +void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); + +/// Internal data structure which holds metadata about a keyword argument +struct argument_record { + const char *name; ///< Argument name + const char *descr; ///< Human-readable version of the argument value + handle value; ///< Associated Python object + bool convert : 1; ///< True if the argument is allowed to convert when loading + bool none : 1; ///< True if None is allowed when loading + + argument_record(const char *name, const char *descr, handle value, bool convert, bool none) + : name(name), descr(descr), value(value), convert(convert), none(none) {} +}; + +/// Internal data structure which holds metadata about a bound function (signature, overloads, +/// etc.) +#define PYBIND11_DETAIL_FUNCTION_RECORD_ABI_ID "v1" // PLEASE UPDATE if the struct is changed. +struct function_record { + function_record() + : is_constructor(false), is_new_style_constructor(false), is_stateless(false), + is_operator(false), is_method(false), is_setter(false), has_args(false), + has_kwargs(false), prepend(false) {} + + /// Function name + char *name = nullptr; /* why no C++ strings? They generate heavier code.. */ + + // User-specified documentation string + char *doc = nullptr; + + /// Human-readable version of the function signature + char *signature = nullptr; + + /// List of registered keyword arguments + std::vector args; + + /// Pointer to lambda function which converts arguments and performs the actual call + handle (*impl)(function_call &) = nullptr; + + /// Storage for the wrapped function pointer and captured data, if any + void *data[3] = {}; + + /// Pointer to custom destructor for 'data' (if needed) + void (*free_data)(function_record *ptr) = nullptr; + + /// Return value policy associated with this function + return_value_policy policy = return_value_policy::automatic; + + /// True if name == '__init__' + bool is_constructor : 1; + + /// True if this is a new-style `__init__` defined in `detail/init.h` + bool is_new_style_constructor : 1; + + /// True if this is a stateless function pointer + bool is_stateless : 1; + + /// True if this is an operator (__add__), etc. + bool is_operator : 1; + + /// True if this is a method + bool is_method : 1; + + /// True if this is a setter + bool is_setter : 1; + + /// True if the function has a '*args' argument + bool has_args : 1; + + /// True if the function has a '**kwargs' argument + bool has_kwargs : 1; + + /// True if this function is to be inserted at the beginning of the overload resolution chain + bool prepend : 1; + + /// Number of arguments (including py::args and/or py::kwargs, if present) + std::uint16_t nargs; + + /// Number of leading positional arguments, which are terminated by a py::args or py::kwargs + /// argument or by a py::kw_only annotation. + std::uint16_t nargs_pos = 0; + + /// Number of leading arguments (counted in `nargs`) that are positional-only + std::uint16_t nargs_pos_only = 0; + + /// Python method object + PyMethodDef *def = nullptr; + + /// Python handle to the parent scope (a class or a module) + handle scope; + + /// Python handle to the sibling function representing an overload chain + handle sibling; + + /// Pointer to next overload + function_record *next = nullptr; +}; +// The main purpose of this macro is to make it easy to pin-point the critically related code +// sections. +#define PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(...) \ + static_assert( \ + __VA_ARGS__, \ + "Violation of precondition for pybind11/functional.h performance optimizations!") + +/// Special data structure which (temporarily) holds metadata about a bound class +struct type_record { + PYBIND11_NOINLINE type_record() + : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), + module_local(false), is_final(false), release_gil_before_calling_cpp_dtor(false) {} + + /// Handle to the parent scope + handle scope; + + /// Name of the class + const char *name = nullptr; + + // Pointer to RTTI type_info data structure + const std::type_info *type = nullptr; + + /// How large is the underlying C++ type? + size_t type_size = 0; + + /// What is the alignment of the underlying C++ type? + size_t type_align = 0; + + /// How large is the type's holder? + size_t holder_size = 0; + + /// The global operator new can be overridden with a class-specific variant + void *(*operator_new)(size_t) = nullptr; + + /// Function pointer to class_<..>::init_instance + void (*init_instance)(instance *, const void *) = nullptr; + + /// Function pointer to class_<..>::dealloc + void (*dealloc)(detail::value_and_holder &) = nullptr; + + /// Function pointer for casting alias class (aka trampoline) pointer to + /// trampoline_self_life_support pointer. Sidesteps cross-DSO RTTI issues + /// on platforms like macOS (see PR #5728 for details). + get_trampoline_self_life_support_fn get_trampoline_self_life_support + = [](void *) -> trampoline_self_life_support * { return nullptr; }; + + /// List of base classes of the newly created type + list bases; + + /// Optional docstring + const char *doc = nullptr; + + /// Custom metaclass (optional) + handle metaclass; + + /// Custom type setup. + custom_type_setup::callback custom_type_setup_callback; + + /// Multiple inheritance marker + bool multiple_inheritance : 1; + + /// Does the class manage a __dict__? + bool dynamic_attr : 1; + + /// Does the class implement the buffer protocol? + bool buffer_protocol : 1; + + /// Is the class definition local to the module shared object? + bool module_local : 1; + + /// Is the class inheritable from python classes? + bool is_final : 1; + + /// Solves pybind/pybind11#1446 + bool release_gil_before_calling_cpp_dtor : 1; + + holder_enum_t holder_enum_v = holder_enum_t::undefined; + + PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) { + auto *base_info = detail::get_type_info(base, false); + if (!base_info) { + std::string tname(base.name()); + detail::clean_type_id(tname); + pybind11_fail("generic_type: type \"" + std::string(name) + + "\" referenced unknown base type \"" + tname + "\""); + } + + // SMART_HOLDER_BAKEIN_FOLLOW_ON: Refine holder compatibility checks. + bool this_has_unique_ptr_holder = (holder_enum_v == holder_enum_t::std_unique_ptr); + bool base_has_unique_ptr_holder + = (base_info->holder_enum_v == holder_enum_t::std_unique_ptr); + if (this_has_unique_ptr_holder != base_has_unique_ptr_holder) { + std::string tname(base.name()); + detail::clean_type_id(tname); + pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + + (this_has_unique_ptr_holder ? "does not have" : "has") + + " a non-default holder type while its base \"" + tname + "\" " + + (base_has_unique_ptr_holder ? "does not" : "does")); + } + + bases.append((PyObject *) base_info->type); + +#ifdef PYBIND11_BACKWARD_COMPATIBILITY_TP_DICTOFFSET + dynamic_attr |= base_info->type->tp_dictoffset != 0; +#else + dynamic_attr |= (base_info->type->tp_flags & Py_TPFLAGS_MANAGED_DICT) != 0; +#endif + + if (caster) { + base_info->implicit_casts.emplace_back(type, caster); + } + } +}; + +inline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) { + args.reserve(f.nargs); + args_convert.reserve(f.nargs); +} + +/// Tag for a new-style `__init__` defined in `detail/init.h` +struct is_new_style_constructor {}; + +/** + * Partial template specializations to process custom attributes provided to + * cpp_function_ and class_. These are either used to initialize the respective + * fields in the type_record and function_record data structures or executed at + * runtime to deal with custom call policies (e.g. keep_alive). + */ +template +struct process_attribute; + +template +struct process_attribute_default { + /// Default implementation: do nothing + static void init(const T &, function_record *) {} + static void init(const T &, type_record *) {} + static void precall(function_call &) {} + static void postcall(function_call &, handle) {} +}; + +/// Process an attribute specifying the function's name +template <> +struct process_attribute : process_attribute_default { + static void init(const name &n, function_record *r) { r->name = const_cast(n.value); } +}; + +/// Process an attribute specifying the function's docstring +template <> +struct process_attribute : process_attribute_default { + static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); } +}; + +/// Process an attribute specifying the function's docstring (provided as a C-style string) +template <> +struct process_attribute : process_attribute_default { + static void init(const char *d, function_record *r) { r->doc = const_cast(d); } + static void init(const char *d, type_record *r) { r->doc = d; } +}; +template <> +struct process_attribute : process_attribute {}; + +/// Process an attribute indicating the function's return value policy +template <> +struct process_attribute : process_attribute_default { + static void init(const return_value_policy &p, function_record *r) { r->policy = p; } +}; + +/// Process an attribute which indicates that this is an overloaded function associated with a +/// given sibling +template <> +struct process_attribute : process_attribute_default { + static void init(const sibling &s, function_record *r) { r->sibling = s.value; } +}; + +/// Process an attribute which indicates that this function is a method +template <> +struct process_attribute : process_attribute_default { + static void init(const is_method &s, function_record *r) { + r->is_method = true; + r->scope = s.class_; + } +}; + +/// Process an attribute which indicates that this function is a setter +template <> +struct process_attribute : process_attribute_default { + static void init(const is_setter &, function_record *r) { r->is_setter = true; } +}; + +/// Process an attribute which indicates the parent scope of a method +template <> +struct process_attribute : process_attribute_default { + static void init(const scope &s, function_record *r) { r->scope = s.value; } +}; + +/// Process an attribute which indicates that this function is an operator +template <> +struct process_attribute : process_attribute_default { + static void init(const is_operator &, function_record *r) { r->is_operator = true; } +}; + +template <> +struct process_attribute + : process_attribute_default { + static void init(const is_new_style_constructor &, function_record *r) { + r->is_new_style_constructor = true; + } +}; + +inline void check_kw_only_arg(const arg &a, function_record *r) { + if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\0')) { + pybind11_fail("arg(): cannot specify an unnamed argument after a kw_only() annotation or " + "args() argument"); + } +} + +inline void append_self_arg_if_needed(function_record *r) { + if (r->is_method && r->args.empty()) { + r->args.emplace_back("self", nullptr, handle(), /*convert=*/true, /*none=*/false); + } +} + +/// Process a keyword argument attribute (*without* a default value) +template <> +struct process_attribute : process_attribute_default { + static void init(const arg &a, function_record *r) { + append_self_arg_if_needed(r); + r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none); + + check_kw_only_arg(a, r); + } +}; + +/// Process a keyword argument attribute (*with* a default value) +template <> +struct process_attribute : process_attribute_default { + static void init(const arg_v &a, function_record *r) { + if (r->is_method && r->args.empty()) { + r->args.emplace_back( + "self", /*descr=*/nullptr, /*parent=*/handle(), /*convert=*/true, /*none=*/false); + } + + if (!a.value) { +#if defined(PYBIND11_DETAILED_ERROR_MESSAGES) + std::string descr("'"); + if (a.name) { + descr += std::string(a.name) + ": "; + } + descr += a.type + "'"; + if (r->is_method) { + if (r->name) { + descr += " in method '" + (std::string) str(r->scope) + "." + + (std::string) r->name + "'"; + } else { + descr += " in method of '" + (std::string) str(r->scope) + "'"; + } + } else if (r->name) { + descr += " in function '" + (std::string) r->name + "'"; + } + pybind11_fail("arg(): could not convert default argument " + descr + + " into a Python object (type not registered yet?)"); +#else + pybind11_fail("arg(): could not convert default argument " + "into a Python object (type not registered yet?). " + "#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for " + "more information."); +#endif + } + r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none); + + check_kw_only_arg(a, r); + } +}; + +/// Process a keyword-only-arguments-follow pseudo argument +template <> +struct process_attribute : process_attribute_default { + static void init(const kw_only &, function_record *r) { + append_self_arg_if_needed(r); + if (r->has_args && r->nargs_pos != static_cast(r->args.size())) { + pybind11_fail("Mismatched args() and kw_only(): they must occur at the same relative " + "argument location (or omit kw_only() entirely)"); + } + r->nargs_pos = static_cast(r->args.size()); + } +}; + +/// Process a positional-only-argument maker +template <> +struct process_attribute : process_attribute_default { + static void init(const pos_only &, function_record *r) { + append_self_arg_if_needed(r); + r->nargs_pos_only = static_cast(r->args.size()); + if (r->nargs_pos_only > r->nargs_pos) { + pybind11_fail("pos_only(): cannot follow a py::args() argument"); + } + // It also can't follow a kw_only, but a static_assert in pybind11.h checks that + } +}; + +/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees +/// that) +template +struct process_attribute::value>> + : process_attribute_default { + static void init(const handle &h, type_record *r) { r->bases.append(h); } +}; + +/// Process a parent class attribute (deprecated, does not support multiple inheritance) +template +struct process_attribute> : process_attribute_default> { + static void init(const base &, type_record *r) { r->add_base(typeid(T), nullptr); } +}; + +/// Process a multiple inheritance attribute +template <> +struct process_attribute : process_attribute_default { + static void init(const multiple_inheritance &, type_record *r) { + r->multiple_inheritance = true; + } +}; + +template <> +struct process_attribute : process_attribute_default { + static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; } +}; + +template <> +struct process_attribute { + static void init(const custom_type_setup &value, type_record *r) { + r->custom_type_setup_callback = value.value; + } +}; + +template <> +struct process_attribute : process_attribute_default { + static void init(const is_final &, type_record *r) { r->is_final = true; } +}; + +template <> +struct process_attribute : process_attribute_default { + static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; } +}; + +template <> +struct process_attribute : process_attribute_default { + static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; } +}; + +template <> +struct process_attribute : process_attribute_default { + static void init(const module_local &l, type_record *r) { r->module_local = l.value; } +}; + +template <> +struct process_attribute + : process_attribute_default { + static void init(const release_gil_before_calling_cpp_dtor &, type_record *r) { + r->release_gil_before_calling_cpp_dtor = true; + } +}; + +/// Process a 'prepend' attribute, putting this at the beginning of the overload chain +template <> +struct process_attribute : process_attribute_default { + static void init(const prepend &, function_record *r) { r->prepend = true; } +}; + +/// Process an 'arithmetic' attribute for enums (does nothing here) +template <> +struct process_attribute : process_attribute_default {}; + +template +struct process_attribute> : process_attribute_default> {}; + +/** + * Process a keep_alive call policy -- invokes keep_alive_impl during the + * pre-call handler if both Nurse, Patient != 0 and use the post-call handler + * otherwise + */ +template +struct process_attribute> + : public process_attribute_default> { + template = 0> + static void precall(function_call &call) { + keep_alive_impl(Nurse, Patient, call, handle()); + } + template = 0> + static void postcall(function_call &, handle) {} + template = 0> + static void precall(function_call &) {} + template = 0> + static void postcall(function_call &call, handle ret) { + keep_alive_impl(Nurse, Patient, call, ret); + } +}; + +/// Recursively iterate over variadic template arguments +template +struct process_attributes { + static void init(const Args &...args, function_record *r) { + PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r); + PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r); + using expander = int[]; + (void) expander{ + 0, ((void) process_attribute::type>::init(args, r), 0)...}; + } + static void init(const Args &...args, type_record *r) { + PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r); + PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r); + using expander = int[]; + (void) expander{0, + (process_attribute::type>::init(args, r), 0)...}; + } + static void precall(function_call &call) { + PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call); + using expander = int[]; + (void) expander{0, + (process_attribute::type>::precall(call), 0)...}; + } + static void postcall(function_call &call, handle fn_ret) { + PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call, fn_ret); + PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(fn_ret); + using expander = int[]; + (void) expander{ + 0, (process_attribute::type>::postcall(call, fn_ret), 0)...}; + } +}; + +template +using is_call_guard = is_instantiation; + +/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found) +template +using extract_guard_t = typename exactly_one_t, Extra...>::type; + +/// Check the number of named arguments at compile time +template ::value...), + size_t self = constexpr_sum(std::is_same::value...)> +constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { + PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs); + return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs; +} + +PYBIND11_NAMESPACE_END(detail) +PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/buffer_info.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/buffer_info.h new file mode 100644 index 0000000000000000000000000000000000000000..78a026db838f59376549ee53908fc892cecc8817 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/buffer_info.h @@ -0,0 +1,213 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + pybind11/buffer_info.h: Python buffer object interface + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "detail/common.h" + +PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +PYBIND11_NAMESPACE_BEGIN(detail) + +// Default, C-style strides +inline std::vector c_strides(const std::vector &shape, ssize_t itemsize) { + auto ndim = shape.size(); + std::vector strides(ndim, itemsize); + if (ndim > 0) { + for (size_t i = ndim - 1; i > 0; --i) { + strides[i - 1] = strides[i] * shape[i]; + } + } + return strides; +} + +// F-style strides; default when constructing an array_t with `ExtraFlags & f_style` +inline std::vector f_strides(const std::vector &shape, ssize_t itemsize) { + auto ndim = shape.size(); + std::vector strides(ndim, itemsize); + for (size_t i = 1; i < ndim; ++i) { + strides[i] = strides[i - 1] * shape[i - 1]; + } + return strides; +} + +template +struct compare_buffer_info; + +PYBIND11_NAMESPACE_END(detail) + +/// Information record describing a Python buffer object +struct buffer_info { + void *ptr = nullptr; // Pointer to the underlying storage + ssize_t itemsize = 0; // Size of individual items in bytes + ssize_t size = 0; // Total number of entries + std::string format; // For homogeneous buffers, this should be set to + // format_descriptor::format() + ssize_t ndim = 0; // Number of dimensions + std::vector shape; // Shape of the tensor (1 entry per dimension) + std::vector strides; // Number of bytes between adjacent entries + // (for each per dimension) + bool readonly = false; // flag to indicate if the underlying storage may be written to + + buffer_info() = default; + + buffer_info(void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t ndim, + detail::any_container shape_in, + detail::any_container strides_in, + bool readonly = false) + : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), + shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) { + if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) { + pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); + } + for (size_t i = 0; i < (size_t) ndim; ++i) { + size *= shape[i]; + } + } + + template + buffer_info(T *ptr, + detail::any_container shape_in, + detail::any_container strides_in, + bool readonly = false) + : buffer_info(private_ctr_tag(), + ptr, + sizeof(T), + format_descriptor::format(), + static_cast(shape_in->size()), + std::move(shape_in), + std::move(strides_in), + readonly) {} + + buffer_info(void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t size, + bool readonly = false) + : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {} + + template + buffer_info(T *ptr, ssize_t size, bool readonly = false) + : buffer_info(ptr, sizeof(T), format_descriptor::format(), size, readonly) {} + + template + buffer_info(const T *ptr, ssize_t size, bool readonly = true) + : buffer_info( + const_cast(ptr), sizeof(T), format_descriptor::format(), size, readonly) {} + + explicit buffer_info(Py_buffer *view, bool ownview = true) + : buffer_info( + view->buf, + view->itemsize, + view->format, + view->ndim, + {view->shape, view->shape + view->ndim}, + /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects + * ignore this flag and return a view with NULL strides. + * When strides are NULL, build them manually. */ + view->strides + ? std::vector(view->strides, view->strides + view->ndim) + : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize), + (view->readonly != 0)) { + // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer) + this->m_view = view; + // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer) + this->ownview = ownview; + } + + buffer_info(const buffer_info &) = delete; + buffer_info &operator=(const buffer_info &) = delete; + + buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); } + + buffer_info &operator=(buffer_info &&rhs) noexcept { + ptr = rhs.ptr; + itemsize = rhs.itemsize; + size = rhs.size; + format = std::move(rhs.format); + ndim = rhs.ndim; + shape = std::move(rhs.shape); + strides = std::move(rhs.strides); + std::swap(m_view, rhs.m_view); + std::swap(ownview, rhs.ownview); + readonly = rhs.readonly; + return *this; + } + + ~buffer_info() { + if (m_view && ownview) { + PyBuffer_Release(m_view); + delete m_view; + } + } + + Py_buffer *view() const { return m_view; } + Py_buffer *&view() { return m_view; } + + /* True if the buffer item type is equivalent to `T`. */ + // To define "equivalent" by example: + // `buffer_info::item_type_is_equivalent_to(b)` and + // `buffer_info::item_type_is_equivalent_to(b)` may both be true + // on some platforms, but `int` and `unsigned` will never be equivalent. + // For the ground truth, please inspect `detail::compare_buffer_info<>`. + template + bool item_type_is_equivalent_to() const { + return detail::compare_buffer_info::compare(*this); + } + +private: + struct private_ctr_tag {}; + + buffer_info(private_ctr_tag, + void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t ndim, + detail::any_container &&shape_in, + detail::any_container &&strides_in, + bool readonly) + : buffer_info( + ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {} + + Py_buffer *m_view = nullptr; + bool ownview = false; +}; + +PYBIND11_NAMESPACE_BEGIN(detail) + +template +struct compare_buffer_info { + static bool compare(const buffer_info &b) { + // NOLINTNEXTLINE(bugprone-sizeof-expression) Needed for `PyObject *` + return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T); + } +}; + +template +struct compare_buffer_info::value>> { + static bool compare(const buffer_info &b) { + return (size_t) b.itemsize == sizeof(T) + && (b.format == format_descriptor::value + || ((sizeof(T) == sizeof(long)) + && b.format == (std::is_unsigned::value ? "L" : "l")) + || ((sizeof(T) == sizeof(size_t)) + && b.format == (std::is_unsigned::value ? "N" : "n"))); + } +}; + +PYBIND11_NAMESPACE_END(detail) +PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#else +#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined." +#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) diff --git a/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/cast.h b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/cast.h new file mode 100644 index 0000000000000000000000000000000000000000..6949956d6ac4fa47efa9168daa1a6b82735d9f42 --- /dev/null +++ b/workspace/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/cast.h @@ -0,0 +1,2366 @@ +#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION) +/* + pybind11/cast.h: Partial template specializations to cast between + C++ and Python types + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "detail/common.h" +#include "detail/descr.h" +#include "detail/native_enum_data.h" +#include "detail/type_caster_base.h" +#include "detail/typeid.h" +#include "pytypes.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +PYBIND11_WARNING_DISABLE_MSVC(4127) + +PYBIND11_NAMESPACE_BEGIN(detail) + +template +class type_caster : public type_caster_base {}; +template +using make_caster = type_caster>; + +// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T +template +typename make_caster::template cast_op_type cast_op(make_caster &caster) { + using result_t = typename make_caster::template cast_op_type; // See PR #4893 + return caster.operator result_t(); +} +template +typename make_caster::template cast_op_type::type> +cast_op(make_caster &&caster) { + using result_t = typename make_caster::template cast_op_type< + typename std::add_rvalue_reference::type>; // See PR #4893 + return std::move(caster).operator result_t(); +} + +template +class type_caster_enum_type { +private: + using Underlying = typename std::underlying_type::type; + +public: + static constexpr auto name = const_name(); + + template + static handle cast(SrcType &&src, return_value_policy, handle parent) { + handle native_enum + = global_internals_native_enum_type_map_get_item(std::type_index(typeid(EnumType))); + if (native_enum) { + return native_enum(static_cast(src)).release(); + } + return type_caster_base::cast( + std::forward(src), + // Fixes https://github.com/pybind/pybind11/pull/3643#issuecomment-1022987818: + return_value_policy::copy, + parent); + } + + template + static handle cast(SrcType *src, return_value_policy policy, handle parent) { + return cast(*src, policy, parent); + } + + bool load(handle src, bool convert) { + handle native_enum + = global_internals_native_enum_type_map_get_item(std::type_index(typeid(EnumType))); + if (native_enum) { + if (!isinstance(src, native_enum)) { + return false; + } + type_caster underlying_caster; + if (!underlying_caster.load(src.attr("value"), convert)) { + pybind11_fail("native_enum internal consistency failure."); + } + value = static_cast(static_cast(underlying_caster)); + return true; + } + if (!pybind11_enum_) { + pybind11_enum_.reset(new type_caster_base()); + } + return pybind11_enum_->load(src, convert); + } + + template + using cast_op_type = detail::cast_op_type; + + // NOLINTNEXTLINE(google-explicit-constructor) + operator EnumType *() { + if (!pybind11_enum_) { + return &value; + } + return pybind11_enum_->operator EnumType *(); + } + + // NOLINTNEXTLINE(google-explicit-constructor) + operator EnumType &() { + if (!pybind11_enum_) { + return value; + } + return pybind11_enum_->operator EnumType &(); + } + +private: + std::unique_ptr> pybind11_enum_; + EnumType value; +}; + +template +struct type_caster_enum_type_enabled : std::true_type {}; + +template +struct type_uses_type_caster_enum_type { + static constexpr bool value + = std::is_enum::value && type_caster_enum_type_enabled::value; +}; + +template +class type_caster::value>> + : public type_caster_enum_type {}; + +template ::value, int> = 0> +bool isinstance_native_enum_impl(handle obj, const std::type_info &tp) { + handle native_enum = global_internals_native_enum_type_map_get_item(tp); + if (!native_enum) { + return false; + } + return isinstance(obj, native_enum); +} + +template ::value, int> = 0> +bool isinstance_native_enum_impl(handle, const std::type_info &) { + return false; +} + +template +bool isinstance_native_enum(handle obj, const std::type_info &tp) { + return isinstance_native_enum_impl>(obj, tp); +} + +template +class type_caster> { +private: + using caster_t = make_caster; + caster_t subcaster; + using reference_t = type &; + using subcaster_cast_op_type = typename caster_t::template cast_op_type; + + static_assert( + std::is_same::type &, subcaster_cast_op_type>::value + || std::is_same::value, + "std::reference_wrapper caster requires T to have a caster with an " + "`operator T &()` or `operator const T &()`"); + +public: + bool load(handle src, bool convert) { return subcaster.load(src, convert); } + static constexpr auto name = caster_t::name; + static handle + cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { + // It is definitely wrong to take ownership of this pointer, so mask that rvp + if (policy == return_value_policy::take_ownership + || policy == return_value_policy::automatic) { + policy = return_value_policy::automatic_reference; + } + return caster_t::cast(&src.get(), policy, parent); + } + template + using cast_op_type = std::reference_wrapper; + explicit operator std::reference_wrapper() { return cast_op(subcaster); } +}; + +#define PYBIND11_TYPE_CASTER(type, py_name) \ +protected: \ + type value; \ + \ +public: \ + static constexpr auto name = py_name; \ + template >::value, \ + int> \ + = 0> \ + static ::pybind11::handle cast( \ + T_ *src, ::pybind11::return_value_policy policy, ::pybind11::handle parent) { \ + if (!src) \ + return ::pybind11::none().release(); \ + if (policy == ::pybind11::return_value_policy::take_ownership) { \ + auto h = cast(std::move(*src), policy, parent); \ + delete src; \ + return h; \ + } \ + return cast(*src, policy, parent); \ + } \ + operator type *() { return &value; } /* NOLINT(bugprone-macro-parentheses) */ \ + operator type &() { return value; } /* NOLINT(bugprone-macro-parentheses) */ \ + operator type &&() && { return std::move(value); } /* NOLINT(bugprone-macro-parentheses) */ \ + template \ + using cast_op_type = ::pybind11::detail::movable_cast_op_type + +template +using is_std_char_type = any_of, /* std::string */ +#if defined(PYBIND11_HAS_U8STRING) + std::is_same, /* std::u8string */ +#endif + std::is_same, /* std::u16string */ + std::is_same, /* std::u32string */ + std::is_same /* std::wstring */ + >; + +template +struct type_caster::value && !is_std_char_type::value>> { + using _py_type_0 = conditional_t; + using _py_type_1 = conditional_t::value, + _py_type_0, + typename std::make_unsigned<_py_type_0>::type>; + using py_type = conditional_t::value, double, _py_type_1>; + +public: + bool load(handle src, bool convert) { + py_type py_value; + + if (!src) { + return false; + } + +#if !defined(PYPY_VERSION) + auto index_check = [](PyObject *o) { return PyIndex_Check(o); }; +#else + // In PyPy 7.3.3, `PyIndex_Check` is implemented by calling `__index__`, + // while CPython only considers the existence of `nb_index`/`__index__`. + auto index_check = [](PyObject *o) { return hasattr(o, "__index__"); }; +#endif + + if (std::is_floating_point::value) { + if (convert || PyFloat_Check(src.ptr())) { + py_value = (py_type) PyFloat_AsDouble(src.ptr()); + } else { + return false; + } + } else if (PyFloat_Check(src.ptr()) + || (!convert && !PYBIND11_LONG_CHECK(src.ptr()) && !index_check(src.ptr()))) { + return false; + } else { + handle src_or_index = src; + // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls. +#if defined(PYPY_VERSION) + object index; + if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr()) + index = reinterpret_steal(PyNumber_Index(src.ptr())); + if (!index) { + PyErr_Clear(); + if (!convert) + return false; + } else { + src_or_index = index; + } + } +#endif + if (std::is_unsigned::value) { + py_value = as_unsigned(src_or_index.ptr()); + } else { // signed integer: + py_value = sizeof(T) <= sizeof(long) + ? (py_type) PyLong_AsLong(src_or_index.ptr()) + : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr()); + } + } + + // Python API reported an error + bool py_err = py_value == (py_type) -1 && PyErr_Occurred(); + + // Check to see if the conversion is valid (integers should match exactly) + // Signed/unsigned checks happen elsewhere + if (py_err + || (std::is_integral::value && sizeof(py_type) != sizeof(T) + && py_value != (py_type) (T) py_value)) { + PyErr_Clear(); + if (py_err && convert && (PyNumber_Check(src.ptr()) != 0)) { + auto tmp = reinterpret_steal(std::is_floating_point::value + ? PyNumber_Float(src.ptr()) + : PyNumber_Long(src.ptr())); + PyErr_Clear(); + return load(tmp, false); + } + return false; + } + + value = (T) py_value; + return true; + } + + template + static typename std::enable_if::value, handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PyFloat_FromDouble((double) src); + } + + template + static typename std::enable_if::value && std::is_signed::value + && (sizeof(U) <= sizeof(long)), + handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PYBIND11_LONG_FROM_SIGNED((long) src); + } + + template + static typename std::enable_if::value && std::is_unsigned::value + && (sizeof(U) <= sizeof(unsigned long)), + handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src); + } + + template + static typename std::enable_if::value && std::is_signed::value + && (sizeof(U) > sizeof(long)), + handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PyLong_FromLongLong((long long) src); + } + + template + static typename std::enable_if::value && std::is_unsigned::value + && (sizeof(U) > sizeof(unsigned long)), + handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PyLong_FromUnsignedLongLong((unsigned long long) src); + } + + PYBIND11_TYPE_CASTER(T, + io_name::value>( + "typing.SupportsInt", "int", "typing.SupportsFloat", "float")); +}; + +template +struct void_caster { +public: + bool load(handle src, bool) { + if (src && src.is_none()) { + return true; + } + return false; + } + static handle cast(T, return_value_policy /* policy */, handle /* parent */) { + return none().release(); + } + PYBIND11_TYPE_CASTER(T, const_name("None")); +}; + +template <> +class type_caster : public void_caster {}; + +template <> +class type_caster : public type_caster { +public: + using type_caster::cast; + + bool load(handle h, bool) { + if (!h) { + return false; + } + if (h.is_none()) { + value = nullptr; + return true; + } + + /* Check if this is a capsule */ + if (isinstance(h)) { + value = reinterpret_borrow(h); + return true; + } + + /* Check if this is a C++ type */ + const auto &bases = all_type_info((PyTypeObject *) type::handle_of(h).ptr()); + if (bases.size() == 1) { // Only allowing loading from a single-value type + value = values_and_holders(reinterpret_cast(h.ptr())).begin()->value_ptr(); + return true; + } + + /* Fail */ + return false; + } + + static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) { + if (ptr) { + return capsule(ptr).release(); + } + return none().release(); + } + + template + using cast_op_type = void *&; + explicit operator void *&() { return value; } + static constexpr auto name = const_name(PYBIND11_CAPSULE_TYPE_TYPE_HINT); + +private: + void *value = nullptr; +}; + +template <> +class type_caster : public void_caster {}; + +template <> +class type_caster { +public: + bool load(handle src, bool convert) { + if (!src) { + return false; + } + if (src.ptr() == Py_True) { + value = true; + return true; + } + if (src.ptr() == Py_False) { + value = false; + return true; + } + if (convert || is_numpy_bool(src)) { + // (allow non-implicit conversion for numpy booleans), use strncmp + // since NumPy 1.x had an additional trailing underscore. + + Py_ssize_t res = -1; + if (src.is_none()) { + res = 0; // None is implicitly converted to False + } +#if defined(PYPY_VERSION) + // On PyPy, check that "__bool__" attr exists + else if (hasattr(src, PYBIND11_BOOL_ATTR)) { + res = PyObject_IsTrue(src.ptr()); + } +#else + // Alternate approach for CPython: this does the same as the above, but optimized + // using the CPython API so as to avoid an unneeded attribute lookup. + else if (auto *tp_as_number = Py_TYPE(src.ptr())->tp_as_number) { + if (PYBIND11_NB_BOOL(tp_as_number)) { + res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr()); + } + } +#endif + if (res == 0 || res == 1) { + value = (res != 0); + return true; + } + PyErr_Clear(); + } + return false; + } + static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) { + return handle(src ? Py_True : Py_False).inc_ref(); + } + PYBIND11_TYPE_CASTER(bool, const_name("bool")); + +private: + // Test if an object is a NumPy boolean (without fetching the type). + static inline bool is_numpy_bool(handle object) { + const char *type_name = Py_TYPE(object.ptr())->tp_name; + // Name changed to `numpy.bool` in NumPy 2, `numpy.bool_` is needed for 1.x support + return std::strcmp("numpy.bool", type_name) == 0 + || std::strcmp("numpy.bool_", type_name) == 0; + } +}; + +// Helper class for UTF-{8,16,32} C++ stl strings: +template +struct string_caster { + using CharT = typename StringType::value_type; + + // Simplify life by being able to assume standard char sizes (the standard only guarantees + // minimums, but Python requires exact sizes) + static_assert(!std::is_same::value || sizeof(CharT) == 1, + "Unsupported char size != 1"); +#if defined(PYBIND11_HAS_U8STRING) + static_assert(!std::is_same::value || sizeof(CharT) == 1, + "Unsupported char8_t size != 1"); +#endif + static_assert(!std::is_same::value || sizeof(CharT) == 2, + "Unsupported char16_t size != 2"); + static_assert(!std::is_same::value || sizeof(CharT) == 4, + "Unsupported char32_t size != 4"); + // wchar_t can be either 16 bits (Windows) or 32 (everywhere else) + static_assert(!std::is_same::value || sizeof(CharT) == 2 || sizeof(CharT) == 4, + "Unsupported wchar_t size != 2/4"); + static constexpr size_t UTF_N = 8 * sizeof(CharT); + + bool load(handle src, bool) { + handle load_src = src; + if (!src) { + return false; + } + if (!PyUnicode_Check(load_src.ptr())) { + return load_raw(load_src); + } + + // For UTF-8 we avoid the need for a temporary `bytes` object by using + // `PyUnicode_AsUTF8AndSize`. + if (UTF_N == 8) { + Py_ssize_t size = -1; + const auto *buffer + = reinterpret_cast(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size)); + if (!buffer) { + PyErr_Clear(); + return false; + } + value = StringType(buffer, static_cast(size)); + return true; + } + + auto utfNbytes + = reinterpret_steal(PyUnicode_AsEncodedString(load_src.ptr(), + UTF_N == 8 ? "utf-8" + : UTF_N == 16 ? "utf-16" + : "utf-32", + nullptr)); + if (!utfNbytes) { + PyErr_Clear(); + return false; + } + + const auto *buffer + = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); + size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); + // Skip BOM for UTF-16/32 + if (UTF_N > 8) { + buffer++; + length--; + } + value = StringType(buffer, length); + + // If we're loading a string_view we need to keep the encoded Python object alive: + if (IsView) { + loader_life_support::add_patient(utfNbytes); + } + + return true; + } + + static handle + cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { + const char *buffer = reinterpret_cast(src.data()); + auto nbytes = ssize_t(src.size() * sizeof(CharT)); + handle s = decode_utfN(buffer, nbytes); + if (!s) { + throw error_already_set(); + } + return s; + } + + PYBIND11_TYPE_CASTER(StringType, const_name(PYBIND11_STRING_NAME)); + +private: + static handle decode_utfN(const char *buffer, ssize_t nbytes) { +#if !defined(PYPY_VERSION) + return UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) + : UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) + : PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); +#else + // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as + // well), so bypass the whole thing by just passing the encoding as a string value, which + // works properly: + return PyUnicode_Decode(buffer, + nbytes, + UTF_N == 8 ? "utf-8" + : UTF_N == 16 ? "utf-16" + : "utf-32", + nullptr); +#endif + } + + // When loading into a std::string or char*, accept a bytes/bytearray object as-is (i.e. + // without any encoding/decoding attempt). For other C++ char sizes this is a no-op. + // which supports loading a unicode from a str, doesn't take this path. + template + bool load_raw(enable_if_t::value, handle> src) { + if (PYBIND11_BYTES_CHECK(src.ptr())) { + // We were passed raw bytes; accept it into a std::string or char* + // without any encoding attempt. + const char *bytes = PYBIND11_BYTES_AS_STRING(src.ptr()); + if (!bytes) { + pybind11_fail("Unexpected PYBIND11_BYTES_AS_STRING() failure."); + } + value = StringType(bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr())); + return true; + } + if (PyByteArray_Check(src.ptr())) { + // We were passed a bytearray; accept it into a std::string or char* + // without any encoding attempt. + const char *bytearray = PyByteArray_AsString(src.ptr()); + if (!bytearray) { + pybind11_fail("Unexpected PyByteArray_AsString() failure."); + } + value = StringType(bytearray, (size_t) PyByteArray_Size(src.ptr())); + return true; + } + + return false; + } + + template + bool load_raw(enable_if_t::value, handle>) { + return false; + } +}; + +template +struct type_caster, + enable_if_t::value>> + : string_caster> {}; + +#ifdef PYBIND11_HAS_STRING_VIEW +template +struct type_caster, + enable_if_t::value>> + : string_caster, true> {}; +#endif + +// Type caster for C-style strings. We basically use a std::string type caster, but also add the +// ability to use None as a nullptr char* (which the string caster doesn't allow). +template +struct type_caster::value>> { + using StringType = std::basic_string; + using StringCaster = make_caster; + StringCaster str_caster; + bool none = false; + CharT one_char = 0; + +public: + bool load(handle src, bool convert) { + if (!src) { + return false; + } + if (src.is_none()) { + // Defer accepting None to other overloads (if we aren't in convert mode): + if (!convert) { + return false; + } + none = true; + return true; + } + return str_caster.load(src, convert); + } + + static handle cast(const CharT *src, return_value_policy policy, handle parent) { + if (src == nullptr) { + return pybind11::none().release(); + } + return StringCaster::cast(StringType(src), policy, parent); + } + + static handle cast(CharT src, return_value_policy policy, handle parent) { + if (std::is_same::value) { + handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr); + if (!s) { + throw error_already_set(); + } + return s; + } + return StringCaster::cast(StringType(1, src), policy, parent); + } + + explicit operator CharT *() { + return none ? nullptr : const_cast(static_cast(str_caster).c_str()); + } + explicit operator CharT &() { + if (none) { + throw value_error("Cannot convert None to a character"); + } + + auto &value = static_cast(str_caster); + size_t str_len = value.size(); + if (str_len == 0) { + throw value_error("Cannot convert empty string to a character"); + } + + // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that + // is too high, and one for multiple unicode characters (caught later), so we need to + // figure out how long the first encoded character is in bytes to distinguish between these + // two errors. We also allow want to allow unicode characters U+0080 through U+00FF, as + // those can fit into a single char value. + if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) { + auto v0 = static_cast(value[0]); + // low bits only: 0-127 + // 0b110xxxxx - start of 2-byte sequence + // 0b1110xxxx - start of 3-byte sequence + // 0b11110xxx - start of 4-byte sequence + size_t char0_bytes = (v0 & 0x80) == 0 ? 1 + : (v0 & 0xE0) == 0xC0 ? 2 + : (v0 & 0xF0) == 0xE0 ? 3 + : 4; + + if (char0_bytes == str_len) { + // If we have a 128-255 value, we can decode it into a single char: + if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx + one_char = static_cast(((v0 & 3) << 6) + + (static_cast(value[1]) & 0x3F)); + return one_char; + } + // Otherwise we have a single character, but it's > U+00FF + throw value_error("Character code point not in range(0x100)"); + } + } + + // UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a + // surrogate pair with total length 2 instantly indicates a range error (but not a "your + // string was too long" error). + else if (StringCaster::UTF_N == 16 && str_len == 2) { + one_char = static_cast(value[0]); + if (one_char >= 0xD800 && one_char < 0xE000) { + throw value_error("Character code point not in range(0x10000)"); + } + } + + if (str_len != 1) { + throw value_error("Expected a character, but multi-character string found"); + } + + one_char = value[0]; + return one_char; + } + + static constexpr auto name = const_name(PYBIND11_STRING_NAME); + template + using cast_op_type = pybind11::detail::cast_op_type<_T>; +}; + +// Base implementation for std::tuple and std::pair +template