Implementation:Onnx Onnx OpSchema Class
| Knowledge Sources | |
|---|---|
| Domains | Schema Definition, Type System, Operator Interface |
| Last Updated | 2026-02-10 00:00 GMT |
Overview
schema.h defines the OpSchema class, OpSchemaRegistry, and related interfaces that form the specification system for all ONNX operators, including type constraints, formal parameters, attributes, versioning, shape inference, and function body support.
Description
This header establishes the core schema infrastructure for the ONNX operator ecosystem through several major components:
FunctionBodyBuildContext is an abstract interface with methods getAttribute(), hasInput(), hasOutput(), and getInputType() for querying node context when building context-dependent function bodies. FunctionBodyBuildContextImpl provides a concrete implementation backed by a NodeProto and type vector.
SchemaError is a custom exception class extending std::runtime_error with AppendContext() for enriching error messages. The fail_schema macro throws SchemaError with formatted messages.
OpSchema is the central class with extensive nested types and builder methods:
- FormalParameterOption enum: Single (exactly 1), Optional (0 or 1), Variadic (N or more)
- DifferentiationCategory enum: Unknown, Differentiable, NonDifferentiable
- NodeDeterminism enum: Unknown, NonDeterministic, Deterministic
- SupportType enum: COMMON, EXPERIMENTAL
- FormalParameter nested class holds name, type_set, type_str, description, param_option, is_homogeneous, min_arity, and differentiation_category for each input/output
- Attribute struct holds name, description, type, required flag, and default_value
- TypeConstraintParam struct holds type_param_str, allowed_type_strs, and description
Builder-pattern methods enable fluent schema construction:
- SetName(), SetDomain(), SetDoc(), SetLocation(), SinceVersion(), Deprecate()
- Input(), Output() with full parameter specifications
- Attr() with many overloads for different default value types (int64_t, float, string, TensorProto, GraphProto, TypeProto, and vector variants)
- TypeConstraint() for type parameter definitions
- NumInputs(), NumOutputs() with allowed value sets
- TypeAndShapeInferenceFunction(), PartialDataPropagationFunction()
- FunctionBody() (text, node vector, or node vector with opsets)
- SetContextDependentFunctionBodyBuilder()
- AllowUncheckedAttributes(), FillUsing(), SetSupportLevel(), SetNodeDeterminism()
Query methods: Name(), domain(), doc(), since_version(), deprecated(), min_input(), max_input(), inputs(), outputs(), attributes(), typeConstraintParams(), HasFunction(), GetFunction(), HasContextDependentFunction(), GetTypeAndShapeInferenceFunction(), etc.
Static type convenience methods provide pre-defined type vectors for various IR versions (all_tensor_types(), all_numeric_types_ir9(), all_float_types_ir4(), all_optional_types_ir12(), etc.).
OpSchemaRegistry is a singleton managing the global schema map (OpName_Domain_Version_Schema_Map):
- Schema() for lookup by name, version, and domain
- DomainToVersionRange inner class tracking min/max versions per domain (ai.onnx: 1-26, ai.onnx.ml: 1-5, etc.)
- OpSchemaRegisterOnce for registration with duplicate detection and version range validation
- OpSchemaDeregister and OpSchemaDeregisterAll for cleanup
- get_all_schemas() and get_all_schemas_with_history() for enumeration
Registration macros (ONNX_OPERATOR_SCHEMA, ONNX_OPERATOR_SET_SCHEMA, ONNX_ML_OPERATOR_SET_SCHEMA, etc.) provide convenient schema declaration and automatic registration.
Usage
This header is included throughout the ONNX codebase wherever operator schemas need to be defined, queried, or validated. It is the primary header for operator definition files, schema registration infrastructure, model validation, type inference, and documentation generation tools.
Code Reference
Source Location
- Repository: Onnx_Onnx
- File: onnx/defs/schema.h
- Lines: 1-1420
Signature
// OpSchema class (key methods)
class OpSchema final {
public:
static constexpr int kUninitializedSinceVersion = -1;
OpSchema& SetName(std::string name);
OpSchema& SetDomain(std::string domain);
OpSchema& SinceVersion(OperatorSetVersion n);
OpSchema& Deprecate();
OpSchema& SetDoc(const std::string& doc);
OpSchema& Input(int n, std::string name, const std::string& description,
std::string type_str, FormalParameterOption param_option = Single, ...);
OpSchema& Output(int n, std::string name, const std::string& description,
std::string type_str, FormalParameterOption param_option = Single, ...);
OpSchema& Attr(std::string name, std::string description,
AttributeProto::AttributeType type, bool required = true);
OpSchema& TypeConstraint(std::string type_str,
std::vector<std::string> constraints, std::string description);
OpSchema& TypeAndShapeInferenceFunction(InferenceFunction inferenceFunction);
OpSchema& FunctionBody(const char* func_body, int opset_version = kUninitializedSinceVersion);
void Finalize();
void Verify(const NodeProto& node) const;
const FunctionProto* GetFunction(int requested_opset_version = kUninitializedSinceVersion, bool validate = false) const;
};
// OpSchemaRegistry class
class OpSchemaRegistry final : public ISchemaRegistry {
public:
static const OpSchema* Schema(const std::string& key, const int maxInclusiveVersion,
const std::string& domain = ONNX_DOMAIN);
static OpSchemaRegistry* Instance();
static std::vector<OpSchema> get_all_schemas_with_history();
static std::vector<OpSchema> get_all_schemas();
};
// Registration functions
void RegisterSchema(OpSchema&& schema, int opset_version_to_load = 0, ...);
void DeregisterSchema(const std::string& op_type, int version, const std::string& domain);
Import
#include "onnx/defs/schema.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| name | std::string | Yes | Operator name (e.g., "Add", "Conv", "Relu") |
| domain | std::string | No | Operator domain. Empty string or ONNX_DOMAIN for standard ONNX operators, AI_ONNX_ML_DOMAIN for ML operators. Defaults to ONNX_DOMAIN. |
| since_version | OperatorSetVersion (int) | Yes | The opset version in which this operator schema was introduced or last had breaking changes |
| inputs/outputs | FormalParameter specs | Yes | Formal parameter definitions with name, description, type constraint string, option (Single/Optional/Variadic), and differentiability |
| attributes | Attribute specs | No | Attribute definitions with name, description, type, and optional default values |
| type_constraints | TypeConstraintParam specs | No | Type parameter definitions with allowed type sets and descriptions |
Outputs
| Name | Type | Description |
|---|---|---|
| OpSchema | OpSchema (built) | A finalized operator schema object ready for registration and use in validation, type inference, and documentation |
| (side effect) | OpSchemaRegistry | When using registration macros, the schema is automatically inserted into the global registry |
Usage Examples
#include "onnx/defs/schema.h"
using namespace ONNX_NAMESPACE;
// Define an operator schema using the macro
ONNX_OPERATOR_SET_SCHEMA(MyOp, 1, OpSchema()
.SetDoc("A custom operator that adds bias to input.")
.Input(0, "X", "Input tensor", "T")
.Input(1, "bias", "Bias tensor", "T", OpSchema::Optional)
.Output(0, "Y", "Output tensor", "T")
.TypeConstraint("T",
{"tensor(float)", "tensor(double)"},
"Constrained to float types")
.Attr("alpha", "Scaling factor", AttributeProto::FLOAT, 1.0f)
.TypeAndShapeInferenceFunction([](InferenceContext& ctx) {
propagateElemTypeFromInputToOutput(ctx, 0, 0);
propagateShapeFromInputToOutput(ctx, 0, 0);
}));
// Query the registry for a schema
const OpSchema* schema = OpSchemaRegistry::Schema("Add", 13, "");
if (schema) {
std::cout << "Op: " << schema->Name() << std::endl;
std::cout << "Since version: " << schema->since_version() << std::endl;
std::cout << "Min inputs: " << schema->min_input() << std::endl;
std::cout << "Max inputs: " << schema->max_input() << std::endl;
}
// Get all schemas
auto all_schemas = OpSchemaRegistry::get_all_schemas();
for (const auto& s : all_schemas) {
std::cout << s.domain() << "::" << s.Name()
<< " v" << s.since_version() << std::endl;
}
// Check domain version ranges
auto& range = OpSchemaRegistry::DomainToVersionRange::Instance();
auto map = range.Map();
// map[""] => {1, 26} (ai.onnx domain, versions 1-26)