Custom operator with multiple input/output types #13861
-
I have an onnxruntime custom operator that can support multiple input and output types. For example, inputs can be FP32, FP16 and BF16. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
Hi @netaz, If your custom op has 1 input and 1 output that can be of various tensor types, then you can use Example: struct MyCustomOp: Ort::CustomOpBase<MyCustomOp, MyCustomKernel> {
// ...
size_t GetInputTypeCount() const { return 1; }; // One input only
ONNXTensorElementDataType GetInputType(size_t /*index*/) const {
return ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED; // Can be f32, f16, uint8, etc.
};
size_t GetOutputTypeCount() const { return 1; }; // One output only
ONNXTensorElementDataType GetOutputType(size_t /*index*/) const {
return ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED; // Can be f32, f16, uint8, etc.
};
} Alternatively, if your custom op has multiple inputs/outputs with fixed types, then you can return the type based on the input/output index. Example: struct MyCustomOp: Ort::CustomOpBase<MyCustomOp, MyCustomKernel> {
// ...
size_t GetInputTypeCount() const { return 2; }; // Two inputs
ONNXTensorElementDataType GetInputType(size_t index) const {
if (index == 0) {
return ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT; // The first input is always an f32
}
return ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16; // The second input is always an f16.
};
size_t GetOutputTypeCount() const { return 3; }; // Three outputs
ONNXTensorElementDataType GetOutputType(size_t index) const {
// Similar code for outputs.
};
} Otherwise, if your custom op can have a dynamic number of inputs and outputs of different types (i.e., variadic like printf), then you can define a custom op with variadic inputs and outputs. Example: struct MyCustomOp: Ort::CustomOpBase<MyCustomOp, MyCustomKernel> {
// ...
size_t GetInputTypeCount() const { return 1; }; // One input
OrtCustomOpInputOutputCharacteristic GetInputCharacteristic(size_t index) const noexcept {
return OrtCustomOpInputOutputCharacteristic::INPUT_OUTPUT_VARIADIC; // The input is variadic (like printf)
}
ONNXTensorElementDataType GetInputType(size_t /*index*/) const {
return ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED; // Input can be any type
};
bool GetVariadicInputHomogeneity() const {
return false; // Each input argument can be of different types (heterogeneous).
}
size_t GetOutputTypeCount() const { return 1; }; // One output only
OrtCustomOpInputOutputCharacteristic GetOutputCharacteristic(size_t index) const noexcept {
return OrtCustomOpInputOutputCharacteristic::INPUT_OUTPUT_VARIADIC; // The output is variadic
}
ONNXTensorElementDataType GetOutputType(size_t /*index*/) const {
return ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED; // Output can be any type
};
bool GetVariadicOuputHomogeneity() const {
return false; // Each output operand can be of different type (heterogeneous).
}
} Please refer to the C API header for more information on variadic inputs/outputs. |
Beta Was this translation helpful? Give feedback.
-
if we set output type to ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED, when and how we actualy specify the output type according to input type? In the compute function, we can use GetOutput to get output, but this function do not specify output type, so what is the output value type? |
Beta Was this translation helpful? Give feedback.
Hi @netaz,
If your custom op has 1 input and 1 output that can be of various tensor types, then you can use
ONNXTensorElementDataType::ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED
to indicate that the input (or output) can potentially be of any type defined in the ONNTensorElementDataType enumExample: