Add int32_t as required type to some operators (#7192)

* Updates to some operators to always support int32 and int64 based on testing of Android package build config with a minimal build.

If an operator can be used for shape manipulation (int64) it is frequently used for indices manipulation (int32), so we enable both types for that set of ops.
  - e.g. BERT models take indices as input
  - Scatter/Gather ops utilize indices

Misc. fix to python bindings to exclude call that fails in a minimal build.
This commit is contained in:
Scott McKay 2021-04-01 19:32:34 +10:00 committed by GitHub
parent 04679e31ab
commit 329fd03bb4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 47 additions and 25 deletions

View file

@ -15,8 +15,8 @@ ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES_ALL_OPSETS(
float, double, int16_t, int32_t, int64_t);
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Range, Input, 0,
int64_t);
}
int32_t, int64_t);
} // namespace op_kernel_type_control
using RangeDataTypes = ORT_OP_KERNEL_ARG_DEFAULT_TYPE_LIST_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Range, Input, 0);

View file

@ -20,14 +20,14 @@ ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES(kCpuExecutionProvider, kOnnxDomain, Max,
ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES(kCpuExecutionProvider, kOnnxDomain, Max, 12, Input, 0,
float, double, MLFloat16, int32_t, uint32_t, int64_t, uint64_t);
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES(kCpuExecutionProvider, kOnnxDomain, Max, 12, Input, 0,
int64_t);
int32_t, int64_t);
// Min
ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES(kCpuExecutionProvider, kOnnxDomain, Min, 8, Input, 0, float, double);
ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES(kCpuExecutionProvider, kOnnxDomain, Min, 12, Input, 0,
float, double, MLFloat16, int32_t, uint32_t, int64_t, uint64_t);
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES(kCpuExecutionProvider, kOnnxDomain, Min, 12, Input, 0,
int64_t);
int32_t, int64_t);
// Mod
ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain, Mod, Input, 0,

View file

@ -33,13 +33,19 @@ namespace op_kernel_type_control {
ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPE_LIST_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Cast, Input, 0,
element_type_lists::All);
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Cast, Input, 0,
int64_t);
bool, int32_t, int64_t);
ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPE_LIST_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Cast, Output, 0,
element_type_lists::All);
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Cast, Output, 0,
bool, int32_t, int64_t);
} // namespace op_kernel_type_control
namespace {

View file

@ -14,8 +14,8 @@ namespace op_kernel_type_control {
ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Gather, Input, 1, int32_t, int64_t);
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Gather, Input, 1, int64_t);
}
kCpuExecutionProvider, kOnnxDomain, Gather, Input, 1, int32_t, int64_t);
} // namespace op_kernel_type_control
namespace {
using IndexTypes = ORT_OP_KERNEL_ARG_DEFAULT_TYPE_LIST_ALL_OPSETS(kCpuExecutionProvider, kOnnxDomain,

View file

@ -53,6 +53,9 @@ ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES(
uint64_t,
int8_t,
uint8_t);
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES(
kCpuExecutionProvider, kOnnxDomain, Pad, 11, Input, 0, int32_t, int64_t);
} // namespace op_kernel_type_control
using Pad2Types = ORT_OP_KERNEL_ARG_DEFAULT_TYPE_LIST(

View file

@ -22,12 +22,12 @@ ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPE_LIST_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Slice, Input, 0,
element_type_lists::All);
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Slice, Input, 0, int64_t);
kCpuExecutionProvider, kOnnxDomain, Slice, Input, 0, int32_t, int64_t);
ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Slice, Input, 1, int32_t, int64_t);
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Slice, Input, 1, int64_t);
kCpuExecutionProvider, kOnnxDomain, Slice, Input, 1, int32_t, int64_t);
} // namespace op_kernel_type_control
namespace {

View file

@ -17,7 +17,10 @@ namespace op_kernel_type_control {
ORT_SPECIFY_OP_KERNEL_ARG_DEFAULT_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Split, Input, 0,
float, int32_t, int64_t, uint8_t, std::string);
}
ORT_SPECIFY_OP_KERNEL_ARG_REQUIRED_TYPES_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Split, Input, 0,
int32_t, int64_t);
} // namespace op_kernel_type_control
using SplitDataTypes = ORT_OP_KERNEL_ARG_DEFAULT_TYPE_LIST_ALL_OPSETS(
kCpuExecutionProvider, kOnnxDomain, Split, Input, 0);
@ -77,9 +80,9 @@ Status SplitBase::PrepareForCompute(const TensorShape& input_shape, int num_outp
split_sizes = std::vector<int64_t>(static_cast<size_t>(num_outputs), split_dim_size / num_outputs);
} else {
int64_t split_size_sum = split_size_sum_;
if (split_size_sum == -1){
if (split_size_sum == -1) {
split_size_sum = std::accumulate(split_sizes.cbegin(), split_sizes.cend(), 0LL);
}
}
if (split_sizes.size() != static_cast<size_t>(num_outputs) || split_size_sum != split_dim_size)
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL,
"Cannot split using values in 'split' attribute. Axis=", axis_,
@ -146,8 +149,7 @@ Status Split::ComputeImpl(OpKernelContext& context, const Tensor& input) const {
auto nDims = static_cast<size_t>(split_tensor->Shape()[0]);
const auto* data = split_tensor->template Data<int64_t>();
split_sizes.assign(data, data + nDims);
}
else{
} else {
split_sizes.assign(split_sizes_.begin(), split_sizes_.end());
}
ORT_RETURN_IF_ERROR(PrepareForCompute(input_shape,

View file

@ -744,9 +744,13 @@ void InitializeSession(InferenceSession* sess, const std::vector<std::string>& p
RegisterExecutionProviders(sess, provider_types, provider_options_map);
}
#if !defined(ORT_MINIMAL_BUILD)
if (!disabled_optimizer_names.empty()) {
OrtPybindThrowIfError(sess->FilterEnabledOptimizers(disabled_optimizer_names));
}
#else
ORT_UNUSED_PARAMETER(disabled_optimizer_names);
#endif
OrtPybindThrowIfError(sess->Initialize());
}

View file

@ -325,14 +325,13 @@ def _create_operator_type_usage_processors():
default_processor_onnx_ops = ['Abs', 'ArgMax', 'ArgMin', 'AveragePool',
'BatchNormalization', 'BitShift',
'Ceil', 'Clip', 'Conv', 'CumSum',
'DequantizeLinear',
'Exp', 'Expand',
'Floor',
'Gemm',
'IsNaN',
'Log', 'LogSoftmax', 'LpNormalization',
'MatMul', 'Max', 'MaxPool', 'Mean', 'Min',
'Neg', 'NonZero',
'NonZero',
'Pad',
'Range', 'Reciprocal', 'ReduceL1', 'ReduceL2', 'ReduceLogSum', 'ReduceLogSumExp',
'ReduceMax', 'ReduceMean', 'ReduceMin', 'ReduceProd', 'ReduceSum', 'ReduceSumSquare',
@ -343,13 +342,15 @@ def _create_operator_type_usage_processors():
'Unique',
'Where']
default_processor_onnx_ops_requiring_int64_for_input_0 = ['Add',
'Div',
'Equal',
'Greater',
'Less',
'Mul',
'Sub']
# ops that are used to manipulate shapes or indices so require int32_t and int64_t to be available
default_processor_onnx_ops_requiring_ints_for_input_0 = ['Add',
'Div',
'Equal',
'Greater',
'Less',
'Mul',
'Neg', # used in tflite TransposeConv conversion
'Sub']
internal_ops = ['QLinearAdd', 'QLinearMul']
@ -365,8 +366,8 @@ def _create_operator_type_usage_processors():
default_processor_onnxml_ops = []
[add(DefaultTypeUsageProcessor('ai.onnx', op)) for op in default_processor_onnx_ops]
[add(DefaultTypeUsageProcessor('ai.onnx', op, required_input_types={0: {"int64_t"}}))
for op in default_processor_onnx_ops_requiring_int64_for_input_0]
[add(DefaultTypeUsageProcessor('ai.onnx', op, required_input_types={0: {"int32_t", "int64_t"}}))
for op in default_processor_onnx_ops_requiring_ints_for_input_0]
[add(DefaultTypeUsageProcessor('ai.onnx.ml', op)) for op in default_processor_onnxml_ops]
[add(DefaultTypeUsageProcessor('com.microsoft', op)) for op in internal_ops]
@ -395,6 +396,12 @@ def _create_operator_type_usage_processors():
add(Output0TypedRegistrationProcessor('ai.onnx', 'QuantizeLinear'))
add(Output0TypedRegistrationProcessor('ai.onnx', 'DynamicQuantizeLinear'))
# make sure all the dequantize types are enabled. we use int32_t for parts of GEMM and Conv so just
# enabling int8 and uint8 is not enough.
# TODO: Only apply required types to the global type list and ignore if it's model based per-op type reduction
add(DefaultTypeUsageProcessor('ai.onnx', 'DequantizeLinear', inputs=[0],
required_input_types={0: {'int8_t', 'uint8_t', 'int32_t'}}))
# OneHot concatenates type strings into a triple in the typed registration
# e.g. float_int64_t_int64_t
add(OneHotProcessor())