Implementation:Onnx Onnx Interned Strings
| Knowledge Sources | |
|---|---|
| Domains | String Interning, Graph IR |
| Last Updated | 2026-02-10 00:00 GMT |
Overview
Concrete tool for efficient string interning and symbol management in the ONNX intermediate representation provided by the ONNX library.
Description
The onnx/common/interned_strings.h header defines the Symbol type and builtin symbol constants used throughout ONNX's internal representation for efficient string handling. It replaces costly string comparisons with fast integer comparisons.
The core mechanism relies on the FORALL_BUILTIN_SYMBOLS macro, which enumerates approximately 190 predefined symbols representing common ONNX identifiers. These include:
- Operator names: Add, Sub, Mul, Div, Conv, MatMul, Gemm, Sigmoid, Softmax, BatchNormalization, Reshape, Transpose, Concat, Slice, Squeeze, Unsqueeze, and many more
- Attribute names: axis, perm, shape, kernel_shape, strides, pads, dilations, alpha, beta, epsilon, momentum, and others
- Control flow: Loop, If, body, then_branch, else_branch
- Internal symbols: PythonOp, CppOp, Param, Return, Eval, FusionGroup, Subgraph
The BuiltinSymbol enum assigns each predefined symbol a unique uint8_t value, with kLastSymbol marking where dynamic symbol numbering begins.
The Symbol struct wraps a uint32_t and provides:
- Implicit construction from BuiltinSymbol
- Explicit construction from strings or uint32_t values
- Implicit conversion to uint32_t for comparison
- toString() for converting back to string
Equality operators are provided for Symbol-Symbol, BuiltinSymbol-Symbol, and Symbol-BuiltinSymbol comparisons. A user-defined literal operator""_sym enables convenient compile-time symbol creation from string literals. A std::hash specialization enables Symbol use in unordered containers.
Usage
Use Symbol instead of std::string when working with operator names, attribute names, or other frequently-compared identifiers in the ONNX IR. Prefer the builtin constants (e.g., kAdd, kConv) for predefined symbols, and use the string constructor or _sym literal for custom symbols. The fast integer-based comparison makes Symbol ideal for hash table lookups and switch-like dispatching.
Code Reference
Source Location
- Repository: Onnx_Onnx
- File: onnx/common/interned_strings.h
Signature
namespace ONNX_NAMESPACE {
#define FORALL_BUILTIN_SYMBOLS(_) \
_(spatial) \
_(PythonOp) \
_(CppOp) \
_(Add) \
_(Conv) \
_(MatMul) \
// ... (~190 symbols total) \
_(output_dtype)
enum BuiltinSymbol : std::uint8_t {
#define DEFINE_SYMBOL(s) k##s,
FORALL_BUILTIN_SYMBOLS(DEFINE_SYMBOL)
#undef DEFINE_SYMBOL
kLastSymbol,
};
struct Symbol {
Symbol() = default;
/*implicit*/ Symbol(BuiltinSymbol value);
explicit Symbol(const std::string& s);
explicit Symbol(uint32_t value);
operator uint32_t() const;
const char* toString() const;
private:
uint32_t value{0};
};
static inline bool operator==(Symbol lhs, Symbol rhs);
static inline bool operator==(BuiltinSymbol lhs, Symbol rhs);
static inline bool operator==(Symbol lhs, BuiltinSymbol rhs);
inline Symbol operator""_sym(const char* s, size_t);
} // namespace ONNX_NAMESPACE
namespace std {
template <>
struct hash<ONNX_NAMESPACE::Symbol> {
std::size_t operator()(ONNX_NAMESPACE::Symbol s) const;
};
} // namespace std
Import
#include "onnx/common/interned_strings.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| value | BuiltinSymbol, std::string, or uint32_t | Yes | The symbol value to construct from (builtin enum, string, or raw integer) |
| s | const char* | Yes (for _sym literal) | String literal to intern as a symbol |
Outputs
| Name | Type | Description |
|---|---|---|
| Symbol | Symbol | An interned string identifier with fast integer-based comparison |
| toString() | const char* | The string representation of the symbol |
Usage Examples
#include "onnx/common/interned_strings.h"
using namespace ONNX_NAMESPACE;
// Use builtin symbol constants
Symbol op = kAdd;
if (op == kAdd) {
// handle Add operator
}
// Create a symbol from a string
Symbol custom_op = Symbol("MyCustomOp");
// Use the _sym literal for compile-time symbol creation
Symbol attr = "axis"_sym;
// Convert back to string for display
std::cout << op.toString() << std::endl; // "Add"
// Use symbols in hash maps
std::unordered_map<Symbol, int> symbol_map;
symbol_map[kConv] = 1;
symbol_map[kMatMul] = 2;
// Compare symbols (fast integer comparison)
if (node->kind() == kBatchNormalization) {
// process batch normalization node
}