Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Onnx Onnx OpSchema Class

From Leeroopedia


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

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)

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment