kernel_dispatch_table.h#

Per-(domain, op_type) dispatch table used by :cpp:func:RunNode / :cpp:class:RuntimeSession to resolve each NodeProto to a matching kernel factory.

The generic dispatch mechanism (this file, :cpp:class:RuntimeContext, :cpp:func:RunNode, …) lives in onnx_core so it has no dependency on any particular set of operator kernels. The concrete kernel implementations for every standard ONNX operator remain in onnx_kernels and register themselves here via :cpp:func:RegisterKernelFn instead of being hard-coded in this table, which keeps the onnx_core -> onnx_kernels dependency direction from ever being introduced.

namespace onnx_light

Alias that makes onnx-light headers compatible with code that references ONNX_LIGHT_NAMESPACE (the macro used in the standard onnx package).

Set to ONNX_LIGHT_NAMESPACE so both names resolve to the same namespace.

Symbol-visibility attribute for the public onnx-light C++ API.

Maps the upstream compatibility macro to onnx-light’s explicit proto ABI annotation. This keeps declarations from vendored ONNX headers visible when lib_onnx_proto uses hidden visibility by default.

Namespace alias so that ONNX C++ code (and consumers such as onnxruntime) that refers to the literal onnx namespace — rather than the ONNX_NAMESPACE macro — resolves to the onnx-light namespace. The standard onnx package lives in namespace onnx; onnx-light uses onnx_light (via ONNX_LIGHT_NAMESPACE), so this alias keeps onnx-light a true drop-in. It is only introduced when the onnx-light namespace differs from onnx.

namespace core
namespace runtime

Typedefs

using NodeKernelFn = std::function<std::unique_ptr<KernelBase>(const NodeProto &node, RuntimeContext &rt)>#

Factory signature registered in :cpp:func:KernelDispatchTable for every (domain, op_type). Called once per node (during kernel resolution / initialization, e.g. by :cpp:func:RuntimeSession::Run or by :cpp:func:RunNode): validates the node’s input/output counts, constructs the concrete kernel object and attaches the node via :cpp:func:KernelBase::set_node, returning a :cpp:class:KernelBase. Must NOT perform any computation itself — all per-run computation belongs in the returned kernel’s :cpp:func:KernelBase::Run.

using SequenceMapPackFn = std::function<Sequences(RuntimeContext &rt, const Sequence &input_sequence, const std::vector<Tensors> &body_outputs_per_iter)>#

Signature of the SequenceMap output-packing callback: given the input sequence (whose length sets the iteration count) and the per-iteration body outputs (body_outputs_per_iter[k][i] is body output k at iteration i), returns the M assembled output sequences. Registered by onnx_kernels (kernel::SequenceMap) so that :cpp:func:RunNode’s SequenceMap orchestration (which must live in onnx_core since it recursively drives a :cpp:class:RuntimeSession) never has to include an onnx_kernels header directly.

Functions

template<typename Kernel, typename ExecutionScope>
std::unique_ptr<KernelBase> MakeSessionKernel(const NodeProto &node, RuntimeContext &rt)#

Builds a backend kernel adapted to the active runtime session.

Kernel supplies the operator implementation and ExecutionScope installs the backend-specific executor bridge while the kernel runs.

Returns: The ready-to-run kernel owned through :cpp:class:KernelBase.

const std::unordered_map<std::string, NodeKernelFn> &KernelDispatchTable()#

Returns the (normalised_domain, op_type) -> NodeKernelFn factory dispatch table. Empty until kernel libraries (e.g. onnx_kernels) populate it via :cpp:func:RegisterKernelFn.

bool RegisterKernelFn(const std::string &domain, const std::string &op_type, symbolic::Device device, NodeKernelFn fn, bool overwrite = true)#

Registers (or replaces) the kernel factory for the identifier (domain, op_type, device) in the shared :cpp:func:KernelDispatchTable.

Use an empty string for domain to denote the default ONNX domain (normalised to :cpp:var:kDefaultOnnxDomain). device is part of the identifier so that a distinct kernel can be registered per device; :cpp:enumerator:symbolic::Device::kCPU (and :cpp:enumerator:symbolic::Device::kUndefined) denote the default host entry. Intended to be called once per operator during static initialization by kernel libraries that must not be linked into onnx_core (e.g. onnx_kernels); see onnx_kernels::RegisterKernelFunctions.

When overwrite is true (the default) an existing entry for the same identifier is replaced. Pass false to register the factory only if no kernel is registered for that identifier yet; this lets bulk built-in registration (onnx_kernels::RegisterKernelFunctions) run without clobbering an override that a downstream library (e.g. onnx-light-cpu) installed earlier, so a custom kernel wins regardless of the order in which the two registrations happen. Explicit per-operator overrides keep the default overwrite = true so they always take precedence over the built-ins.

Parameters:
  • domain – The operator domain ("" or "ai.onnx" for standard ONNX).

  • op_type – The ONNX operator type name (e.g. "Abs").

  • device – The device the kernel runs on (e.g. :cpp:enumerator:symbolic::Device::kCPU).

  • fn – The factory implementing kernel construction for this operator.

  • overwrite – Whether to replace an existing entry (true, default) or keep it and ignore fn when one already exists (false).

Returns:

true when fn was stored, false when an existing entry was kept because overwrite was false.

const CustomKernelMap &GlobalCustomKernels()#

Returns the process-wide (global) custom-kernel registry consulted by :cpp:func:RunNode / :cpp:class:RuntimeSession during kernel resolution.

Global custom kernels complement the per-:cpp:class:RuntimeContext registry (:cpp:func:RuntimeContext::RegisterCustomKernel): they let a caller install a kernel once and have every :cpp:class:RuntimeContext pick it up, rather than registering it on each context separately. Resolution precedence is: model-local functions, built-in control-flow operators, per-context custom kernels, global custom kernels, then the built-in :cpp:func:KernelDispatchTable. A per-context registration for the same (domain, op_type) therefore overrides the global one.

Keys are the canonical "<domain>:<op_type>" pair (the default ONNX domain — the empty NodeProto::domain() — is normalised to :cpp:var:kDefaultOnnxDomain).

Like the built-in :cpp:func:KernelDispatchTable, this registry is a plain process-wide singleton and is not synchronised: register / unregister global kernels before starting concurrent :cpp:func:RunNode / :cpp:class:RuntimeSession::Run calls (e.g. during start-up), not while other threads are resolving nodes.

void RegisterGlobalCustomKernel(const std::string &domain, const std::string &op_type, CustomKernelFn fn)#

Registers (or replaces) a process-wide (global) custom kernel for (domain, op_type) in :cpp:func:GlobalCustomKernels. The empty domain is normalised to :cpp:var:kDefaultOnnxDomain. Unlike :cpp:func:RegisterKernelFn (which registers a per-device kernel factory), fn keeps the simple “run the whole node now” contract of :cpp:type:CustomKernelFn.

bool UnregisterGlobalCustomKernel(const std::string &domain, const std::string &op_type)#

Removes the process-wide custom kernel registered for (domain, op_type). The empty domain is normalised to :cpp:var:kDefaultOnnxDomain. Returns true when an entry was removed, false otherwise.

void ClearGlobalCustomKernels()#

Removes every process-wide custom kernel registration from :cpp:func:GlobalCustomKernels.

const SequenceMapPackFn &GetSequenceMapPackFn()#

Returns the currently registered SequenceMap output-packing callback, or an empty std::function if none has been registered yet (see :cpp:func:RegisterSequenceMapPackFn).

void RegisterSequenceMapPackFn(SequenceMapPackFn fn)#

Registers the SequenceMap output-packing callback (see :cpp:type:SequenceMapPackFn). Called once by onnx_kernels::RegisterKernelFunctions.

template<typename Kernel, typename ExecutionScope>
class SessionKernel : public Kernel#
#include <kernel_dispatch_table.h>

Adapts a backend kernel to the lifetime of a :cpp:class:RuntimeSession.

ExecutionScope remains backend-defined: constructing it from the active :cpp:class:RuntimeContext installs any backend-specific executor bridge for the duration of one kernel invocation. Keeping that policy outside onnx_core lets downstream libraries reuse the session factory without introducing a dependency from onnx_core to a concrete backend.

Public Functions

inline SessionKernel(const NodeProto &node, RuntimeContext &rt)#
inline void Run(RuntimeContext &rt) override#