diff --git a/include/onnxruntime/core/framework/kernel_def_builder.h b/include/onnxruntime/core/framework/kernel_def_builder.h index 63c9269409..965d553eb9 100644 --- a/include/onnxruntime/core/framework/kernel_def_builder.h +++ b/include/onnxruntime/core/framework/kernel_def_builder.h @@ -54,7 +54,7 @@ class KernelDef { } const std::map>& TypeConstraints() const { - return type_constraints_; + return enabled_type_constraints_; } const std::vector>& MayInplace() const { @@ -128,7 +128,12 @@ class KernelDef { // The supported data types for inputs/outputs. // Key is input/output name defined in op schema, Value are supported types. // note: std::map as we need the order to be deterministic for the hash - std::map> type_constraints_; + // Note: supported_type_constraints_ are used to calculate the kernel hash so that the hash is + // stable across builds with and without kernel type reduction enabled. + std::map> supported_type_constraints_; + + // the type constraints that are enabled in this build for the kernel + std::map> enabled_type_constraints_; // An element means that output j reuses the memory of input i. std::vector> inplace_map_; @@ -201,12 +206,20 @@ class KernelDefBuilder { of the set of types specified in the op schema. The arg name could be either op formal parameter name, say "X", or type argument name specified in op schema, say "T". + If this build uses type reduction the enabled types can optionally be provided. */ KernelDefBuilder& TypeConstraint(const std::string& arg_name, const std::vector& supported_types); KernelDefBuilder& TypeConstraint(const char* arg_name, const std::vector& supported_types); + KernelDefBuilder& TypeConstraint(const std::string& arg_name, + const std::vector& supported_types, + const std::vector& enabled_types); + KernelDefBuilder& TypeConstraint(const char* arg_name, + const std::vector& supported_types, + const std::vector& enabled_types); + /** Like TypeConstraint but supports just a single type. */ @@ -332,6 +345,10 @@ class KernelDefBuilder { } private: + KernelDefBuilder& TypeConstraintImpl(const std::string& arg_name, + const std::vector& supported_types, + const std::vector* enabled_types = nullptr); + // we own the KernelDef until Build() is called. std::unique_ptr kernel_def_; }; diff --git a/include/onnxruntime/core/framework/op_kernel.h b/include/onnxruntime/core/framework/op_kernel.h index cccbff9319..b39a1bb66e 100644 --- a/include/onnxruntime/core/framework/op_kernel.h +++ b/include/onnxruntime/core/framework/op_kernel.h @@ -62,11 +62,12 @@ class OpKernel { // return Status::OK(); // } // Please refer to MatMulIntegerToFloatBase for a complete example - // @param tesnor: The initialized constant tensor + // @param tensor: The initialized constant tensor // @param input_idx: The input index of the tensor in this kernel // @param is_packed: Set it to true if the kernel packed the tensor or to false - // The kernel is responsible keep the packed data and related metadata if is_packed is set to true - // And the original intialized constant tensor will be released and not accessible anymore in Compute function. + // The kernel is responsible for keeping the packed data and related metadata if is_packed is true, + // and the original initialized constant tensor will be released and not accessible anymore in + // the Compute function. virtual Status PrePack(const Tensor& /*tensor*/, int /*input_idx*/, bool& is_packed) { is_packed = false; return Status::OK(); @@ -435,44 +436,50 @@ using BuildKernelCreateInfoFn = KernelCreateInfo (*)(); #define ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(provider, domain, startver, endver, type, name) \ provider##_##name##_##domain##_ver##startver##_##endver##_##type -#define ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(name, startver, endver, type, builder, ...) \ - ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_EX(name, kOnnxDomain, startver, endver, type, kCpuExecutionProvider, builder, __VA_ARGS__) +#define ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(name, startver, endver, type, builder, ...) \ + ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_EX(name, kOnnxDomain, startver, endver, type, kCpuExecutionProvider, builder, \ + __VA_ARGS__) -#define ONNX_CPU_OPERATOR_VERSIONED_TYPED_ML_KERNEL(name, startver, endver, type, builder, ...) \ - ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_EX(name, kMLDomain, startver, endver, type, kCpuExecutionProvider, builder, __VA_ARGS__) +#define ONNX_CPU_OPERATOR_VERSIONED_TYPED_ML_KERNEL(name, startver, endver, type, builder, ...) \ + ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_EX(name, kMLDomain, startver, endver, type, kCpuExecutionProvider, builder, \ + __VA_ARGS__) -#define ONNX_CPU_OPERATOR_VERSIONED_TYPED_MS_KERNEL(name, startver, endver, type, builder, ...) \ - ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_EX(name, kMSDomain, startver, endver, type, kCpuExecutionProvider, builder, __VA_ARGS__) +#define ONNX_CPU_OPERATOR_VERSIONED_TYPED_MS_KERNEL(name, startver, endver, type, builder, ...) \ + ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_EX(name, kMSDomain, startver, endver, type, kCpuExecutionProvider, builder, \ + __VA_ARGS__) -#define ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_EX(name, domain, startver, endver, type, provider, builder, ...) \ - class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(provider, domain, startver, endver, type, name); \ - template <> \ - KernelCreateInfo \ - BuildKernelCreateInfo() { \ - return KernelCreateInfo( \ - builder.SetName(#name) \ - .SetDomain(domain) \ - .SinceVersion(startver, endver) \ - .Provider(provider) \ - .Build(), \ - static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ +#define ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_EX(name, domain, startver, endver, type, provider, builder, ...) \ + class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(provider, domain, startver, endver, type, name); \ + template <> \ + KernelCreateInfo \ + BuildKernelCreateInfo() { \ + return KernelCreateInfo( \ + builder.SetName(#name) \ + .SetDomain(domain) \ + .SinceVersion(startver, endver) \ + .Provider(provider) \ + .Build(), \ + static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ } #define ONNX_OPERATOR_VERSIONED_TWO_TYPED_KERNEL_CLASS_NAME(provider, domain, startver, endver, type1, type2, name) \ provider##_##name##_##domain##_ver##startver##_##endver##_##type1##_##type2 -#define ONNX_OPERATOR_VERSIONED_TWO_TYPED_KERNEL_EX(name, domain, startver, endver, type1, type2, provider, builder, ...) \ - class ONNX_OPERATOR_VERSIONED_TWO_TYPED_KERNEL_CLASS_NAME(provider, domain, startver, endver, type1, type2, name); \ - template <> \ - KernelCreateInfo \ - BuildKernelCreateInfo() { \ - return KernelCreateInfo( \ - builder.SetName(#name) \ - .SetDomain(domain) \ - .SinceVersion(startver, endver) \ - .Provider(provider) \ - .Build(), \ - static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ +#define ONNX_OPERATOR_VERSIONED_TWO_TYPED_KERNEL_EX(name, domain, startver, endver, type1, type2, \ + provider, builder, ...) \ + class ONNX_OPERATOR_VERSIONED_TWO_TYPED_KERNEL_CLASS_NAME(provider, domain, startver, endver, type1, type2, name); \ + template <> \ + KernelCreateInfo \ + BuildKernelCreateInfo() { \ + return KernelCreateInfo( \ + builder.SetName(#name) \ + .SetDomain(domain) \ + .SinceVersion(startver, endver) \ + .Provider(provider) \ + .Build(), \ + static_cast([](const OpKernelInfo& info) -> OpKernel* { return new __VA_ARGS__(info); })); \ } // Use within macro definitions to create a custom vector of constraints. @@ -493,7 +500,6 @@ struct BuildKernelDefConstraintsFunctor { // the type BuildKernelDefConstraintsFunctor given a type list L template -using BuildKernelDefConstraintsFunctorFromTypeList = - boost::mp11::mp_apply; +using BuildKernelDefConstraintsFunctorFromTypeList = boost::mp11::mp_apply; } // namespace onnxruntime diff --git a/onnxruntime/core/framework/kernel_def_builder.cc b/onnxruntime/core/framework/kernel_def_builder.cc index 05001306ee..255c81f636 100644 --- a/onnxruntime/core/framework/kernel_def_builder.cc +++ b/onnxruntime/core/framework/kernel_def_builder.cc @@ -52,7 +52,9 @@ void KernelDef::CalculateHash() { hash_str(op_domain_); hash_str(provider_type_); - for (const auto& key_value : type_constraints_) { + + // use the supported_type_constraints_ list for the hash so the value in an ORT format model is stable. + for (const auto& key_value : supported_type_constraints_) { hash_str(key_value.first); for (const auto& data_type : key_value.second) { hash_str(std::string(DataTypeImpl::ToString(data_type))); @@ -88,7 +90,7 @@ bool KernelDef::IsConflict(const KernelDef& other) const { //check types const auto& other_types = other.TypeConstraints(); bool type_has_conflict = true; - for (const auto& it : type_constraints_) { + for (const auto& it : supported_type_constraints_) { auto iter = other_types.find(it.first); if (iter != other_types.end()) { if (!AreVectorsOverlap(it.second, iter->second)) { @@ -164,20 +166,41 @@ KernelDefBuilder& KernelDefBuilder::Provider(const char* provider_type) { return *this; } +KernelDefBuilder& KernelDefBuilder::TypeConstraintImpl(const std::string& arg_name, + const std::vector& supported_types, + const std::vector* enabled_types) { + // use the enabled types list if provided + kernel_def_->enabled_type_constraints_[arg_name] = enabled_types ? *enabled_types : supported_types; + kernel_def_->supported_type_constraints_[arg_name] = supported_types; + return *this; +} + KernelDefBuilder& KernelDefBuilder::TypeConstraint(const std::string& arg_name, const std::vector& supported_types) { - kernel_def_->type_constraints_[arg_name] = supported_types; - return *this; + return TypeConstraintImpl(arg_name, supported_types, nullptr); } KernelDefBuilder& KernelDefBuilder::TypeConstraint(const char* arg_name, const std::vector& supported_types) { - return TypeConstraint(std::string(arg_name), supported_types); + return TypeConstraintImpl(arg_name, supported_types, nullptr); +} + +KernelDefBuilder& KernelDefBuilder::TypeConstraint(const std::string& arg_name, + const std::vector& supported_types, + const std::vector& enabled_types) { + return TypeConstraintImpl(arg_name, supported_types, &enabled_types); +} + +KernelDefBuilder& KernelDefBuilder::TypeConstraint(const char* arg_name, + const std::vector& supported_types, + const std::vector& enabled_types) { + return TypeConstraintImpl(arg_name, supported_types, &enabled_types); } KernelDefBuilder& KernelDefBuilder::TypeConstraint(const std::string& arg_name, MLDataType supported_type) { - kernel_def_->type_constraints_[arg_name] = std::vector{supported_type}; + kernel_def_->enabled_type_constraints_[arg_name] = std::vector{supported_type}; + kernel_def_->supported_type_constraints_[arg_name] = std::vector{supported_type}; return *this; } diff --git a/onnxruntime/core/providers/cpu/math/element_wise_ops.cc b/onnxruntime/core/providers/cpu/math/element_wise_ops.cc index a579bbfa17..781603d505 100644 --- a/onnxruntime/core/providers/cpu/math/element_wise_ops.cc +++ b/onnxruntime/core/providers/cpu/math/element_wise_ops.cc @@ -28,7 +28,9 @@ ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES(kCpuExecutionProvider, kOnnxDomain, Mi // Pow ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES(kCpuExecutionProvider, kOnnxDomain, Pow, 7, Input, 0, float, double); -// Pow 12 and later has separate Base and Exponent types +// Pow 12 and later has separate Base and Exponent types. +// To reduce templatization we choose to support a subset of types for the base and exponent. +// This gives us 16 permutations. ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES(kCpuExecutionProvider, kOnnxDomain, Pow, 12, Input, 0, int32_t, int64_t, float, double); ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES(kCpuExecutionProvider, kOnnxDomain, Pow, 12, @@ -38,12 +40,19 @@ ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES(kCpuExecutionProvider, kOnnxDomain, Po // // reduce the supported type lists to what's allowed in this build // +using Max8Types = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Max, 8, Input, 0); +using Max12Types = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Max, 12, Input, 0); using EnabledMax8Types = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Max, 8, Input, 0); using EnabledMax12Types = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Max, 12, Input, 0); +using Min8Types = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Min, 8, Input, 0); +using Min12Types = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Min, 12, Input, 0); using EnabledMin8Types = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Min, 8, Input, 0); using EnabledMin12Types = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Min, 12, Input, 0); +using Pow7Types = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Pow, 7, Input, 0); +using Pow12BaseTypes = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Pow, 12, Input, 0); +using Pow12ExpTypes = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Pow, 12, Input, 1); using EnabledPow7Types = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Pow, 7, Input, 0); using EnabledPow12BaseTypes = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST(kCpuExecutionProvider, kOnnxDomain, Pow, 12, Input, 0); @@ -95,41 +104,45 @@ void Exp::operator()(std::ptrdiff_t first, std::ptrdiff_t last) const { .TypeConstraint("T1", DataTypeImpl::GetTensorType()), \ KERNEL_CLASS); -#define REG_ELEMENTWISE_KERNEL_NONT(OP_TYPE, VERSION, KERNEL_CLASS, CONSTRAINTS) \ - ONNX_CPU_OPERATOR_KERNEL( \ - OP_TYPE, \ - VERSION, \ - KernelDefBuilder() \ - .TypeConstraint("T", CONSTRAINTS), \ - KERNEL_CLASS); - -// var args are type constraints for T and T1 -#define REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(OP_TYPE, VERSION_FROM, VERSION_TO, KERNEL_CLASS, CONSTRAINTS) \ - ONNX_CPU_OPERATOR_VERSIONED_KERNEL( \ +#define REG_ELEMENTWISE_KERNEL_NONT(OP_TYPE, VERSION, KERNEL_CLASS, CONSTRAINTS, ENABLED_TYPES_CONSTRAINTS) \ + ONNX_CPU_OPERATOR_KERNEL( \ OP_TYPE, \ - VERSION_FROM, \ - VERSION_TO, \ + VERSION, \ KernelDefBuilder() \ - .TypeConstraint("T", CONSTRAINTS), \ + .TypeConstraint("T", CONSTRAINTS, ENABLED_TYPES_CONSTRAINTS), \ KERNEL_CLASS); -#define REG_ELEMENTWISE_KERNEL_NONT_2(OP_TYPE, VERSION, KERNEL_CLASS, T1_CONSTRAINTS, T2_CONSTRAINTS) \ - ONNX_CPU_OPERATOR_KERNEL( \ - OP_TYPE, \ - VERSION, \ - KernelDefBuilder() \ - .TypeConstraint("T", T1_CONSTRAINTS) \ - .TypeConstraint("T1", T2_CONSTRAINTS), \ +#define REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(OP_TYPE, VERSION_FROM, VERSION_TO, KERNEL_CLASS, \ + CONSTRAINTS, ENABLED_TYPES_CONSTRAINTS) \ + ONNX_CPU_OPERATOR_VERSIONED_KERNEL( \ + OP_TYPE, \ + VERSION_FROM, \ + VERSION_TO, \ + KernelDefBuilder() \ + .TypeConstraint("T", CONSTRAINTS, ENABLED_TYPES_CONSTRAINTS), \ KERNEL_CLASS); -#define REG_ELEMENTWISE_VERSIONED_KERNEL_NONT_2(OP_TYPE, VERSION_FROM, VERSION_TO, KERNEL_CLASS, T1_CONSTRAINTS, T2_CONSTRAINTS) \ - ONNX_CPU_OPERATOR_VERSIONED_KERNEL( \ - OP_TYPE, \ - VERSION_FROM, \ - VERSION_TO, \ - KernelDefBuilder() \ - .TypeConstraint("T", T1_CONSTRAINTS) \ - .TypeConstraint("T1", T2_CONSTRAINTS), \ +#define REG_ELEMENTWISE_KERNEL_NONT_2(OP_TYPE, VERSION, KERNEL_CLASS, \ + T1_CONSTRAINTS, T1_ENABLED_TYPES_CONSTRAINTS, \ + T2_CONSTRAINTS, T2_ENABLED_TYPES_CONSTRAINTS) \ + ONNX_CPU_OPERATOR_KERNEL( \ + OP_TYPE, \ + VERSION, \ + KernelDefBuilder() \ + .TypeConstraint("T", T1_CONSTRAINTS, T1_ENABLED_TYPES_CONSTRAINTS) \ + .TypeConstraint("T1", T2_CONSTRAINTS, T2_ENABLED_TYPES_CONSTRAINTS), \ + KERNEL_CLASS); + +#define REG_ELEMENTWISE_VERSIONED_KERNEL_NONT_2(OP_TYPE, VERSION_FROM, VERSION_TO, KERNEL_CLASS, \ + T1_CONSTRAINTS, T1_ENABLED_TYPES_CONSTRAINTS, \ + T2_CONSTRAINTS, T2_ENABLED_TYPES_CONSTRAINTS) \ + ONNX_CPU_OPERATOR_VERSIONED_KERNEL( \ + OP_TYPE, \ + VERSION_FROM, \ + VERSION_TO, \ + KernelDefBuilder() \ + .TypeConstraint("T", T1_CONSTRAINTS, T1_ENABLED_TYPES_CONSTRAINTS) \ + .TypeConstraint("T1", T2_CONSTRAINTS, T2_ENABLED_TYPES_CONSTRAINTS), \ KERNEL_CLASS); REG_ELEMENTWISE_VERSIONED_TYPED_KERNEL(Add, 7, 12, float, Add); @@ -217,14 +230,19 @@ REG_ELEMENTWISE_VERSIONED_TYPED_KERNEL(Sqrt, 6, 12, double, Sqrt); REG_ELEMENTWISE_TYPED_KERNEL(Sqrt, 13, float, Sqrt); REG_ELEMENTWISE_TYPED_KERNEL(Sqrt, 13, double, Sqrt); -const auto pow7_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); -// To reduce templatization we choose to support the below types for both -// base and the exponent. This gives us 16 permutations. -const auto pow12_base_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); -const auto pow12_exp_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); -REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Pow, 7, 11, Pow, pow7_types); -REG_ELEMENTWISE_VERSIONED_KERNEL_NONT_2(Pow, 12, 12, Pow, pow12_base_types, pow12_exp_types); -REG_ELEMENTWISE_KERNEL_NONT_2(Pow, 13, Pow, pow12_base_types, pow12_exp_types); +const auto supported_pow7_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_pow7_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_pow12_base_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_pow12_exp_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_pow12_base_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_pow12_exp_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Pow, 7, 11, Pow, supported_pow7_types, enabled_pow7_types); +REG_ELEMENTWISE_VERSIONED_KERNEL_NONT_2(Pow, 12, 12, Pow, + supported_pow12_base_types, enabled_pow12_base_types, + supported_pow12_exp_types, enabled_pow12_exp_types); +REG_ELEMENTWISE_KERNEL_NONT_2(Pow, 13, Pow, + supported_pow12_base_types, enabled_pow12_base_types, + supported_pow12_exp_types, enabled_pow12_exp_types); REG_ELEMENTWISE_VERSIONED_TYPED_KERNEL(Exp, 6, 12, float, Exp); REG_ELEMENTWISE_VERSIONED_TYPED_KERNEL(Exp, 6, 12, double, Exp); @@ -246,20 +264,24 @@ REG_ELEMENTWISE_TYPED_KERNEL(Sum, 13, double, Sum_8); REG_ELEMENTWISE_VERSIONED_TYPED_KERNEL(Max, 6, 7, float, Max_6); -const std::vector max8_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); -const std::vector max12_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); -REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Max, 8, 11, Max_8, max8_types); -REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Max, 12, 12, Max_8, max12_types); +const auto supported_max8_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_max12_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_max8_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_max12_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Max, 8, 11, Max_8, supported_max8_types, enabled_max8_types); +REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Max, 12, 12, Max_8, supported_max12_types, enabled_max12_types); // Supposed to add BFloat16 but we are not supporting now, however, separate registration -REG_ELEMENTWISE_KERNEL_NONT(Max, 13, Max_8, max12_types); +REG_ELEMENTWISE_KERNEL_NONT(Max, 13, Max_8, supported_max12_types, enabled_max12_types); -const std::vector min8_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); -const std::vector min12_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_min8_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_min12_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_min8_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_min12_types = BuildKernelDefConstraintsFunctorFromTypeList{}(); REG_ELEMENTWISE_VERSIONED_TYPED_KERNEL(Min, 6, 7, float, Min_6); -REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Min, 8, 11, Min_8, min8_types); -REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Min, 12, 12, Min_8, min12_types); +REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Min, 8, 11, Min_8, supported_min8_types, enabled_min8_types); +REG_ELEMENTWISE_VERSIONED_KERNEL_NONT(Min, 12, 12, Min_8, supported_min12_types, enabled_min12_types); // Supposed to add BFloat16 but we are not supporting now, however, separate registration -REG_ELEMENTWISE_KERNEL_NONT(Min, 13, Min_8, min12_types); +REG_ELEMENTWISE_KERNEL_NONT(Min, 13, Min_8, supported_min12_types, enabled_min12_types); REG_ELEMENTWISE_LOGICALOP_VERSIONED_TYPED_KERNEL(Less, 7, 8, float, Less); REG_ELEMENTWISE_LOGICALOP_VERSIONED_TYPED_KERNEL(Less, 7, 8, double, Less); diff --git a/onnxruntime/core/providers/cpu/tensor/cast_op.cc b/onnxruntime/core/providers/cpu/tensor/cast_op.cc index 99c438ef8d..aae2f1a5b3 100644 --- a/onnxruntime/core/providers/cpu/tensor/cast_op.cc +++ b/onnxruntime/core/providers/cpu/tensor/cast_op.cc @@ -40,6 +40,10 @@ ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES_ALL_OPSETS( } // namespace op_kernel_type_control namespace { +using SupportedSrcTypes = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, + Cast, Input, 0); +using SupportedDstTypes = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, + Cast, Output, 0); using EnabledSrcTypes = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, Cast, Input, 0); using EnabledDstTypes = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, @@ -304,8 +308,10 @@ Status Cast::Compute(OpKernelContext* context) const { return Status::OK(); } -const std::vector src_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); -const std::vector dst_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_src_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_dst_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_src_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_dst_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); } // namespace @@ -314,8 +320,8 @@ ONNX_CPU_OPERATOR_VERSIONED_KERNEL( 6, 12, KernelDefBuilder() - .TypeConstraint("T1", src_type_constraints) - .TypeConstraint("T2", dst_type_constraints) + .TypeConstraint("T1", supported_src_type_constraints, enabled_src_type_constraints) + .TypeConstraint("T2", supported_dst_type_constraints, enabled_dst_type_constraints) .MayInplace(0, 0), // allocation planner will check input and output sizes match before inplacing Cast); @@ -323,8 +329,8 @@ ONNX_CPU_OPERATOR_KERNEL( Cast, 13, KernelDefBuilder() - .TypeConstraint("T1", src_type_constraints) - .TypeConstraint("T2", dst_type_constraints) + .TypeConstraint("T1", supported_src_type_constraints, enabled_src_type_constraints) + .TypeConstraint("T2", supported_dst_type_constraints, enabled_dst_type_constraints) .MayInplace(0, 0), // allocation planner will check input and output sizes match before inplacing Cast); diff --git a/onnxruntime/core/providers/cpu/tensor/gather.cc b/onnxruntime/core/providers/cpu/tensor/gather.cc index b0fd5dcdf9..c7385be504 100644 --- a/onnxruntime/core/providers/cpu/tensor/gather.cc +++ b/onnxruntime/core/providers/cpu/tensor/gather.cc @@ -16,11 +16,13 @@ ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES_ALL_OPSETS( } namespace { -using EnabledIndexTypes = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST_ALL_OPSETS( - kCpuExecutionProvider, kOnnxDomain, Gather, Input, 1); +using SupportedIndexTypes = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, + Gather, Input, 1); +using EnabledIndexTypes = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, + Gather, Input, 1); -const auto index_type_constraints = - BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_index_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_index_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); } // namespace ONNX_CPU_OPERATOR_VERSIONED_KERNEL( @@ -29,7 +31,7 @@ ONNX_CPU_OPERATOR_VERSIONED_KERNEL( 10, KernelDefBuilder() .TypeConstraint("T", DataTypeImpl::AllTensorTypes()) - .TypeConstraint("Tind", index_type_constraints), + .TypeConstraint("Tind", supported_index_type_constraints, enabled_index_type_constraints), Gather); ONNX_CPU_OPERATOR_VERSIONED_KERNEL( @@ -38,7 +40,7 @@ ONNX_CPU_OPERATOR_VERSIONED_KERNEL( 12, KernelDefBuilder() .TypeConstraint("T", DataTypeImpl::AllTensorTypes()) - .TypeConstraint("Tind", index_type_constraints), + .TypeConstraint("Tind", supported_index_type_constraints, enabled_index_type_constraints), Gather); ONNX_CPU_OPERATOR_KERNEL( @@ -46,7 +48,7 @@ ONNX_CPU_OPERATOR_KERNEL( 13, KernelDefBuilder() .TypeConstraint("T", DataTypeImpl::AllTensorTypes()) - .TypeConstraint("Tind", index_type_constraints), + .TypeConstraint("Tind", supported_index_type_constraints, enabled_index_type_constraints), Gather); Status GatherBase::PrepareForCompute(OpKernelContext* context, Prepare& p) const { diff --git a/onnxruntime/core/providers/cpu/tensor/isinf.cc b/onnxruntime/core/providers/cpu/tensor/isinf.cc index b03298e356..a7c37ae612 100644 --- a/onnxruntime/core/providers/cpu/tensor/isinf.cc +++ b/onnxruntime/core/providers/cpu/tensor/isinf.cc @@ -21,6 +21,9 @@ ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES_ALL_OPSETS( class IsInf final : public OpKernel { public: + using SupportedTypes = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, + IsInf, Input, 0); + using EnabledTypes = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, IsInf, Input, 0); @@ -36,8 +39,9 @@ ONNX_CPU_OPERATOR_KERNEL( IsInf, 10, KernelDefBuilder() - .TypeConstraint( - "T1", BuildKernelDefConstraintsFunctorFromTypeList{}()) + .TypeConstraint("T1", + BuildKernelDefConstraintsFunctorFromTypeList{}(), + BuildKernelDefConstraintsFunctorFromTypeList{}()) .TypeConstraint("T2", DataTypeImpl::GetTensorType()), IsInf); diff --git a/onnxruntime/core/providers/cpu/tensor/slice.cc b/onnxruntime/core/providers/cpu/tensor/slice.cc index 52784823f5..75c81a9bf7 100644 --- a/onnxruntime/core/providers/cpu/tensor/slice.cc +++ b/onnxruntime/core/providers/cpu/tensor/slice.cc @@ -24,16 +24,19 @@ ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES_ALL_OPSETS( } // namespace op_kernel_type_control namespace { +using SupportedDataTypes = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, + Slice, Input, 0); +using SupportedIndicesTypes = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, + Slice, Input, 1); using EnabledDataTypes = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, Slice, Input, 0); using EnabledIndicesTypes = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, Slice, Input, 1); -const std::vector dataTypeConstraints = - BuildKernelDefConstraintsFunctorFromTypeList{}(); - -const std::vector indicesTypeConstraints = - BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_data_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_indices_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_data_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_indices_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); // std::clamp doesn't exist until C++17 so create a local version template @@ -47,15 +50,15 @@ const T& clamp(const T& v, const T& lo, const T& hi) { ONNX_CPU_OPERATOR_VERSIONED_KERNEL( Slice, 1, 9, - KernelDefBuilder().TypeConstraint("T", dataTypeConstraints), + KernelDefBuilder().TypeConstraint("T", supported_data_type_constraints, enabled_data_type_constraints), Slice1); ONNX_CPU_OPERATOR_VERSIONED_KERNEL( Slice, 10, 10, KernelDefBuilder() - .TypeConstraint("T", dataTypeConstraints) - .TypeConstraint("Tind", indicesTypeConstraints), + .TypeConstraint("T", supported_data_type_constraints, enabled_data_type_constraints) + .TypeConstraint("Tind", supported_indices_type_constraints, enabled_indices_type_constraints), Slice10); ONNX_CPU_OPERATOR_VERSIONED_KERNEL( @@ -63,16 +66,16 @@ ONNX_CPU_OPERATOR_VERSIONED_KERNEL( 11, 12, KernelDefBuilder() - .TypeConstraint("T", dataTypeConstraints) - .TypeConstraint("Tind", indicesTypeConstraints), + .TypeConstraint("T", supported_data_type_constraints, enabled_data_type_constraints) + .TypeConstraint("Tind", supported_indices_type_constraints, enabled_indices_type_constraints), Slice10); ONNX_CPU_OPERATOR_KERNEL( Slice, 13, KernelDefBuilder() - .TypeConstraint("T", dataTypeConstraints) - .TypeConstraint("Tind", indicesTypeConstraints), + .TypeConstraint("T", supported_data_type_constraints, enabled_data_type_constraints) + .TypeConstraint("Tind", supported_indices_type_constraints, enabled_indices_type_constraints), Slice10); // Check if it's possible to combine innermost dimensions so we copy larger blocks. diff --git a/onnxruntime/core/providers/cpu/tensor/transpose.cc b/onnxruntime/core/providers/cpu/tensor/transpose.cc index 2c3f2d6478..e8b09b0a4d 100644 --- a/onnxruntime/core/providers/cpu/tensor/transpose.cc +++ b/onnxruntime/core/providers/cpu/tensor/transpose.cc @@ -20,10 +20,13 @@ ORT_SPECIFY_OP_KERNEL_ARG_SUPPORTED_TYPES_ALL_OPSETS( namespace { // reduce the supported types with any global or op specific lists +using SupportedDataTypes = ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, + Transpose, Input, 0); using EnabledDataTypes = ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, Transpose, Input, 0); -const std::vector type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto supported_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); +const auto enabled_type_constraints = BuildKernelDefConstraintsFunctorFromTypeList{}(); } // namespace /* A permutation [a,b,c,...] indicates that @@ -725,13 +728,13 @@ ONNX_CPU_OPERATOR_VERSIONED_KERNEL( Transpose, 1, 12, - KernelDefBuilder().TypeConstraint("T", type_constraints), + KernelDefBuilder().TypeConstraint("T", supported_type_constraints, enabled_type_constraints), Transpose); ONNX_CPU_OPERATOR_KERNEL( Transpose, 13, - KernelDefBuilder().TypeConstraint("T", type_constraints), + KernelDefBuilder().TypeConstraint("T", supported_type_constraints, enabled_type_constraints), Transpose); } // namespace onnxruntime diff --git a/onnxruntime/core/providers/op_kernel_type_control.h b/onnxruntime/core/providers/op_kernel_type_control.h index a9030838ac..6c9ea94262 100644 --- a/onnxruntime/core/providers/op_kernel_type_control.h +++ b/onnxruntime/core/providers/op_kernel_type_control.h @@ -138,7 +138,20 @@ struct EnabledTypes { ::onnxruntime::op_kernel_type_control::OpArgDirection::ArgDirection, \ ArgIndex> +// INTERNAL +// the TypesHolder that contains the supported types list +#define ORT_OP_KERNEL_TYPE_CTRL_INTERNAL_SUPPORTED_TYPES_HOLDER( \ + OpProvider, OpDomain, OpName, OpSet, ArgDirection, ArgIndex) \ + ::onnxruntime::op_kernel_type_control::TypesHolder< \ + ::onnxruntime::op_kernel_type_control::tags::Supported< \ + ORT_OP_KERNEL_TYPE_CTRL_INTERNAL_OP_KERNEL_ARG_TAG(OpDomain, OpName, ArgDirection, ArgIndex), \ + ::onnxruntime::op_kernel_type_control:: \ + ORT_OP_KERNEL_TYPE_CTRL_INTERNAL_PROVIDER_TAG_CLASS_NAME(OpProvider), \ + OpSet>> + +// // public macros +// /** * Specifies a supported set of types for a given Op kernel argument. @@ -186,6 +199,36 @@ struct EnabledTypes { ::onnxruntime::op_kernel_type_control::kAllOpSets, \ ArgDirection, ArgIndex, __VA_ARGS__) +/** + * TypeList type with the supported types for a given Op kernel argument. + * + * @param OpProvider The Op provider. + * @param OpDomain The Op domain. + * @param OpName The Op name. + * @param OpSet The opset to use for the supported types list. + * @param ArgDirection Direction of the given Op kernel argument - Input or Output. + * @param ArgIndex Index of the given Op kernel argument. + */ +#define ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST( \ + OpProvider, OpDomain, OpName, OpSet, ArgDirection, ArgIndex) \ + ORT_OP_KERNEL_TYPE_CTRL_INTERNAL_SUPPORTED_TYPES_HOLDER( \ + OpProvider, OpDomain, OpName, OpSet, ArgDirection, ArgIndex)::types + +/** + * TypeList type with the supported types for a given Op kernel argument that are valid for all opsets. + * + * @param OpProvider The Op provider. + * @param OpDomain The Op domain. + * @param OpName The Op name. + * @param ArgDirection Direction of the given Op kernel argument - Input or Output. + * @param ArgIndex Index of the given Op kernel argument. + */ +#define ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST_ALL_OPSETS( \ + OpProvider, OpDomain, OpName, ArgDirection, ArgIndex) \ + ORT_OP_KERNEL_ARG_SUPPORTED_TYPE_LIST(OpProvider, OpDomain, OpName, \ + ::onnxruntime::op_kernel_type_control::kAllOpSets, \ + ArgDirection, ArgIndex) + /** * TypeList type with the enabled types for a given Op kernel argument. * This is created by intersecting the supported types with any type restrictions coming from the allowed or global @@ -201,12 +244,8 @@ struct EnabledTypes { #define ORT_OP_KERNEL_ARG_ENABLED_TYPE_LIST( \ OpProvider, OpDomain, OpName, OpSet, ArgDirection, ArgIndex) \ ::onnxruntime::op_kernel_type_control::EnabledTypes< \ - ::onnxruntime::op_kernel_type_control::TypesHolder< \ - ::onnxruntime::op_kernel_type_control::tags::Supported< \ - ORT_OP_KERNEL_TYPE_CTRL_INTERNAL_OP_KERNEL_ARG_TAG(OpDomain, OpName, ArgDirection, ArgIndex), \ - ::onnxruntime::op_kernel_type_control:: \ - ORT_OP_KERNEL_TYPE_CTRL_INTERNAL_PROVIDER_TAG_CLASS_NAME(OpProvider), \ - OpSet>>, \ + ORT_OP_KERNEL_TYPE_CTRL_INTERNAL_SUPPORTED_TYPES_HOLDER( \ + OpProvider, OpDomain, OpName, OpSet, ArgDirection, ArgIndex), \ ::onnxruntime::TypeList< \ ::onnxruntime::op_kernel_type_control::TypesHolder< \ ::onnxruntime::op_kernel_type_control::tags::Allowed< \