diff --git a/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/thread_name.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/typeid.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/typeid.h new file mode 100644 index 0000000000000000000000000000000000000000..3f7da4264ad5339af2535aeb10863ef07c75515a --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/util/win32-headers.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/PeerToPeerAccess.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/PeerToPeerAccess.h new file mode 100644 index 0000000000000000000000000000000000000000..9f227662a446845b4c1aa3e00bb299b494566e5c --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUCachingAllocator.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUCachingAllocator.h new file mode 100644 index 0000000000000000000000000000000000000000..2ae0904928db7f8721b679035eb69f66db731d85 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUDeviceProp.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUDeviceProp.h new file mode 100644 index 0000000000000000000000000000000000000000..dcaed872ab21df9c5fe0e24e73439e50d94b3507 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUEvent.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..596fdfcc0ff06ccdb4395c3989e987836804eddc --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUException.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUException.h new file mode 100644 index 0000000000000000000000000000000000000000..514299d6bb1eaa56874908ec5ac44badd30cac03 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUFunctions.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUFunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..e5017a054d32448a372290fcab2adfdea3e7fb36 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUGraphsC10Utils.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUGraphsC10Utils.h new file mode 100644 index 0000000000000000000000000000000000000000..437dda44bfc4826d05389b530a7cd54083ec8f08 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUMacros.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUMacros.h new file mode 100644 index 0000000000000000000000000000000000000000..43a42c2a6f8a47a2276268e58edc176ec5f6a781 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUStream.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/XPUStream.h new file mode 100644 index 0000000000000000000000000000000000000000..8715c12f024332c73bf0d8c30faf8c276cebaab9 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/impl/XPUGuardImpl.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/c10/xpu/test/impl/XPUTest.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/common.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/common.h new file mode 100644 index 0000000000000000000000000000000000000000..f8de86b9ed8e3fc25a3e6efe20bc36f5b29336c0 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/macros.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/macros.h new file mode 100644 index 0000000000000000000000000000000000000000..2e86ebe216d7d7bc2022375a7443040a56997c16 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/timer.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/core/timer.h new file mode 100644 index 0000000000000000000000000000000000000000..54ff81fc25e27eb38cc23e497b692f321b71c6b4 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/perfkernels/common.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/perfkernels/common.h new file mode 100644 index 0000000000000000000000000000000000000000..f927b1ac74631203bfb9ac4bf869d0e2fa7b0a7c --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/perfkernels/embedding_lookup_idx.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/crc_alt.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/file_adapter.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/in_memory_adapter.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/inline_container.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/istream_adapter.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/read_adapter_interface.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/versions.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/serialize/versions.h new file mode 100644 index 0000000000000000000000000000000000000000..ce96250ba9f184955b77e829ded09ba2e5517843 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/fixed_divisor.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/proto_wrap.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/string_utils.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/ThreadPool.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/ThreadPoolCommon.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/WorkersPool.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/pthreadpool-cpp.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/pthreadpool.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/caffe2/utils/threadpool/thread_pool_guard.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/clog.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/clog.h new file mode 100644 index 0000000000000000000000000000000000000000..e12d3ecc0efbfbcfd577d5a6cef63b65587e5014 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/cpuinfo.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/cpuinfo.h new file mode 100644 index 0000000000000000000000000000000000000000..3b2429f42848c6d971003d3f24a0a00eda806ade --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.h new file mode 100644 index 0000000000000000000000000000000000000000..2f23ccc356d39007d0e1526a1915c9f263b353ca --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.hpp b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cfeaa7ae8104ef4ee187593e8293d4fb332a1d7f --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_config.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_config.h new file mode 100644 index 0000000000000000000000000000000000000000..9ed9094b2e8de55cbe29f97203b0a038017bd4e9 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_debug.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..7542b65d3a82845d45550ac22c352532b0e65161 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.h new file mode 100644 index 0000000000000000000000000000000000000000..f7c5cdc04199555228ba220445acc0a6f427c77c --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.hpp b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_ocl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..55e02e842d8b1dde9b932d7bc0b22b39a21df014 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.h new file mode 100644 index 0000000000000000000000000000000000000000..3017d8ce576b0fe44ba275810cf7021f4df649a7 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.hpp b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6001dea399240f83e06f38956fb5aee7355264d6 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl_types.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_sycl_types.h new file mode 100644 index 0000000000000000000000000000000000000000..ede1cdcb3bec776331b64fb27724c72ead100d19 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.h new file mode 100644 index 0000000000000000000000000000000000000000..56427210e54c1516fa2453519965945042a5798c --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.hpp b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool.hpp new file mode 100644 index 0000000000000000000000000000000000000000..436afe2c58752f61287a888ef0b2af1eff290bdd --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool_iface.hpp b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_threadpool_iface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..beead174e90480e97efc996ba20e0c4330e061fa --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_types.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_types.h new file mode 100644 index 0000000000000000000000000000000000000000..35e54d4a3ae678a1674bbadb42c72c5352238743 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_version.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/dnnl_version.h new file mode 100644 index 0000000000000000000000000000000000000000..6a58705775014639fed51001a5069bbf7b2b7efe --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/ConvUtils.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/ConvUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..e02f7219333029289853acf1883b29b840da4198 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Fbgemm.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Fbgemm.h new file mode 100644 index 0000000000000000000000000000000000000000..518d014dd8bdf904cb561071de323cce8d2517eb --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmBuild.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmBuild.h new file mode 100644 index 0000000000000000000000000000000000000000..f413d17980a5b8fcc3ea3e4f98b6ec81a98512c5 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmConvert.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmConvert.h new file mode 100644 index 0000000000000000000000000000000000000000..6574dfc305700356f3ea6d16be69512c45208212 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmEmbedding.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmEmbedding.h new file mode 100644 index 0000000000000000000000000000000000000000..0da43d39fbdfd5d0df2958cc1f6d0b5fe5ff4cdb --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP16.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP16.h new file mode 100644 index 0000000000000000000000000000000000000000..254142290ef03e8aeb5ee40c28443af6f737a6bb --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP32.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFP32.h new file mode 100644 index 0000000000000000000000000000000000000000..91c0c4c7ce6bb8e062391b1b612dfc86720d2ef0 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFPCommon.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmFPCommon.h new file mode 100644 index 0000000000000000000000000000000000000000..e4fd09a18f70ab177229aad256043b955dea884d --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI64.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI64.h new file mode 100644 index 0000000000000000000000000000000000000000..8d95013257c8419d468815ce055bfb56898a432c --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DepthwiseAvx2.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DepthwiseAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..70571cded3d6f574afd2f471cb418baf2ab9022a --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DirectconvAvx2.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8DirectconvAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..e0cd02f1eea7b442fa31bbe03ca5074ca30b2f1c --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8Spmdm.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmI8Spmdm.h new file mode 100644 index 0000000000000000000000000000000000000000..650f5d6bf6ab5c67548f79997f170ef26cdaf614 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmPackMatrixB.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmPackMatrixB.h new file mode 100644 index 0000000000000000000000000000000000000000..407c372c434d7091455f7664baccdc902805c4e2 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmSparse.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FbgemmSparse.h new file mode 100644 index 0000000000000000000000000000000000000000..21a3a111271bc10b949cc9912d75fc775ffe3488 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FloatConversion.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/FloatConversion.h new file mode 100644 index 0000000000000000000000000000000000000000..949e9ebefde3ad93ecdd934f7703a6be2b84ea79 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/OutputProcessing-inl.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/OutputProcessing-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..4457d5ee0ba204e875009e9632bdda2480fc0f4d --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/PackingTraits-inl.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/PackingTraits-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..3d9f26ab2b30b805f9399a61bc5063ee58764d37 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtils.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..90e95beb1ed4d8b32ff0ebe84ac37d6686ca1b60 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx2.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..ec985aeba579fdb4bec0cffedc9115fc194ee861 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx512.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsAvx512.h new file mode 100644 index 0000000000000000000000000000000000000000..d8330f4808c1b258e94d58c68cd14b8060b31b1c --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsNeon.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/QuantUtilsNeon.h new file mode 100644 index 0000000000000000000000000000000000000000..32e571213b6c83d9dd7dd65b4b5930b9a3974224 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/SimdUtils.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/SimdUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..6a1f4aca84462476cec8e1aee731c6f691765881 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Types.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Types.h new file mode 100644 index 0000000000000000000000000000000000000000..615ea0d87471ee752b9bc76873736ad1a36b0ef4 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Utils.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/Utils.h new file mode 100644 index 0000000000000000000000000000000000000000..dc0ef013d11fb4a65fbff6337a5eeac36fbadbc3 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/UtilsAvx2.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/UtilsAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..6a774a3fb71b17dda3bbf67bf8e5819d6fb95654 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtils.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..ba473fb3d8e16a65f743b5a048eacca64c360558 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtilsAvx2.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fbgemm/spmmUtilsAvx2.h new file mode 100644 index 0000000000000000000000000000000000000000..7543b56dfa0410fd678e2ec24fa39a9054dee7d4 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/args.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/args.h new file mode 100644 index 0000000000000000000000000000000000000000..33309f51f704da42ec73074839969d2ef578da17 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/base.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/base.h new file mode 100644 index 0000000000000000000000000000000000000000..c72f2fbe80572fc8bb73b04f262ebdbd866c278b --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/chrono.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/chrono.h new file mode 100644 index 0000000000000000000000000000000000000000..d4519b16353e00d73bdcc493926625937f8c1808 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/color.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/color.h new file mode 100644 index 0000000000000000000000000000000000000000..3246ddceea28f0df7c347a5661d597e21a149edc --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/compile.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/compile.h new file mode 100644 index 0000000000000000000000000000000000000000..955135a39f4eab50b903bd3bfee0cb9217f0238d --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/core.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/core.h new file mode 100644 index 0000000000000000000000000000000000000000..6d2b271f05c9ff22b8c67f8cfa7bc2c8dbdef5b1 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format-inl.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format-inl.h new file mode 100644 index 0000000000000000000000000000000000000000..ccf962a394ea93bc040d5e9b94bfb7e0bcf30bb7 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/format.h new file mode 100644 index 0000000000000000000000000000000000000000..a16acbf64ad9b35b0b008127d7a80a794da7ac0f --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/os.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/os.h new file mode 100644 index 0000000000000000000000000000000000000000..a412fd64a3045f2128b2746dc5bbd0cb90b81654 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ostream.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ostream.h new file mode 100644 index 0000000000000000000000000000000000000000..a3c4887750d4bc5227e3e79f34f8869f706d82f5 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/printf.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/printf.h new file mode 100644 index 0000000000000000000000000000000000000000..087cbae23c6d72af09fb88bdc6c5db721f4f6832 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ranges.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/ranges.h new file mode 100644 index 0000000000000000000000000000000000000000..f8df05f9a4517bb9add87f261a6c29b9c7ec19f6 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/std.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/std.h new file mode 100644 index 0000000000000000000000000000000000000000..1c166432291fad18366482ec158f73c137e84806 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/xchar.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fmt/xchar.h new file mode 100644 index 0000000000000000000000000000000000000000..1cf7170e8bc421671f0e575a60e8b5c1f53d0ce6 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16.h new file mode 100644 index 0000000000000000000000000000000000000000..f5dc61d18ded7ef41d8e9698de12c2fe21094b81 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/bitcasts.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/bitcasts.h new file mode 100644 index 0000000000000000000000000000000000000000..55461b797fb041b8f5d5b6a313cf2ec6fedcce6d --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/fp16.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/fp16.h new file mode 100644 index 0000000000000000000000000000000000000000..4e29f28ccea774a363d6c624d53a4acc9783b4a3 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/psimd.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fp16/psimd.h new file mode 100644 index 0000000000000000000000000000000000000000..346df7b3de42625fb0c1b6774b614ffce0e94993 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fxdiv.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/fxdiv.h new file mode 100644 index 0000000000000000000000000000000000000000..abdd7c70f51f5cbdb1880901060e3df90f91e682 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify-zca.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify-zca.h new file mode 100644 index 0000000000000000000000000000000000000000..b67e229749262849bf6a7947afc4a1470c730c65 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/ittnotify.h new file mode 100644 index 0000000000000000000000000000000000000000..37328bf8211232f97b866f1113bbcda4b49dda7c --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/jitprofiling.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/jitprofiling.h new file mode 100644 index 0000000000000000000000000000000000000000..a2c68e032008c6a43dff11ae2ce2027b9bdbb4fb --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/AbstractConfig.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/AbstractConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..a7381cd242558ffaf5a0fa58f5a94bf43a421191 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityProfilerInterface.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityProfilerInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..27a78877205a07d147b2c5f86be9d9afba871dd7 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityTraceInterface.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityTraceInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..e4c2ca3791a32c737af5762fce0aa652ea848bb0 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityType.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ActivityType.h new file mode 100644 index 0000000000000000000000000000000000000000..5f38e3a0a05780a2f8a28a58e0175ec3c245f27f --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ClientInterface.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ClientInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..eb570e1258c0fedf3e748c1028bc0fb30f3f7aaa --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/Config.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/Config.h new file mode 100644 index 0000000000000000000000000000000000000000..fb5e2c445521030bb6ab884548419321cbabce61 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/GenericTraceActivity.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/GenericTraceActivity.h new file mode 100644 index 0000000000000000000000000000000000000000..6d05084044ea7e663b8b1679f9a8156ddbcd1ce9 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/IActivityProfiler.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/IActivityProfiler.h new file mode 100644 index 0000000000000000000000000000000000000000..7c18d5064504cb9bf28574fb04cbca08f4dad426 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ILoggerObserver.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ILoggerObserver.h new file mode 100644 index 0000000000000000000000000000000000000000..c80aabebd583f75e47d00120a60add0b08a480c1 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ITraceActivity.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ITraceActivity.h new file mode 100644 index 0000000000000000000000000000000000000000..1598dfb4d38c5b8ee5f6d387f74e7c742e14cf71 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/LoggingAPI.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/LoggingAPI.h new file mode 100644 index 0000000000000000000000000000000000000000..d27484403234139ff0153276b08d1953c6821d37 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ThreadUtil.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/ThreadUtil.h new file mode 100644 index 0000000000000000000000000000000000000000..efc92dc98be2eba2d151fd9b9cfdbbc2603d3e46 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/TraceSpan.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/TraceSpan.h new file mode 100644 index 0000000000000000000000000000000000000000..a01ffe27c7833887ae59cdc71fda5f652810c02a --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/libkineto.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/libkineto.h new file mode 100644 index 0000000000000000000000000000000000000000..b3cde9dc4d0225369f18ea5dad454cca45c7fbd0 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/output_base.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/output_base.h new file mode 100644 index 0000000000000000000000000000000000000000..e738f1fdb1ab257e8be31e2f7b273f4191219f74 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/kineto/time_since_epoch.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/legacy/ittnotify.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/legacy/ittnotify.h new file mode 100644 index 0000000000000000000000000000000000000000..307580cd0d0faa459abf5452c8a3f273cba55942 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libittnotify.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libittnotify.h new file mode 100644 index 0000000000000000000000000000000000000000..cb5190ff7d3c2bfe1685dafaddc7cd744e971fa8 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libshm.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/libshm.h new file mode 100644 index 0000000000000000000000000000000000000000..58d368dcf7aea4472e91efb60983e58e70c61654 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/nnpack.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/nnpack.h new file mode 100644 index 0000000000000000000000000000000000000000..62e785e8c9e9f4a28c50f4f5260bc89dbb2d5c83 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.h new file mode 100644 index 0000000000000000000000000000000000000000..1d944da46c10e4c017273511e2d6e608e8fd9284 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.hpp b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..86aebc57cbfa58d76ed436954f319f7d6e6024ac --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common.hpp b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_common_types.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_config.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_debug.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph.hpp b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_ocl.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_ocl.hpp b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_sycl.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_sycl.hpp b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_graph_types.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl.hpp b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ocl_types.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl.hpp b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_sycl_types.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool.hpp b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_threadpool_iface.hpp b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_types.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel.hpp b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_ukernel_types.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_version.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/oneapi/dnnl/dnnl_version_hash.h b/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/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/psimd.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/psimd.h new file mode 100644 index 0000000000000000000000000000000000000000..8c8a96bf67bb294d6e0f4763bf42a54fbccc7541 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pthreadpool.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pthreadpool.h new file mode 100644 index 0000000000000000000000000000000000000000..5cab9f53220467ab7f0c68a49b9c24badb0217c6 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/attr.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/attr.h new file mode 100644 index 0000000000000000000000000000000000000000..cdf277758c1b84ed67ebd8199abfcf9198ef4a65 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/buffer_info.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/buffer_info.h new file mode 100644 index 0000000000000000000000000000000000000000..78a026db838f59376549ee53908fc892cecc8817 --- /dev/null +++ b/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/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/cast.h b/outputs/audit_venv/lib/python3.11/site-packages/torch/include/pybind11/cast.h new file mode 100644 index 0000000000000000000000000000000000000000..6949956d6ac4fa47efa9168daa1a6b82735d9f42 --- /dev/null +++ b/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