shape_controlflow.h#
Shape-inference functions for ONNX operators in the control flow family (If, Loop, Scan, …).
-
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_NAMESPACEso both names resolve to the same namespace.Symbol-visibility attribute for the public onnx-light C++ API.
Defined as empty because onnx-light does not require explicit
__declspec(dllexport)or__attribute__((visibility("default")))annotations — visibility is controlled at the shared-library level. The macro is provided so that vendored ONNX headers that decorate their declarations withONNX_APIcompile without modification.Namespace alias so that ONNX C++ code (and consumers such as onnxruntime) that refers to the literal
onnxnamespace — rather than theONNX_NAMESPACEmacro — resolves to the onnx-light namespace. The standard onnx package lives innamespace onnx; onnx-light usesonnx_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 fromonnx.-
namespace onnx_optim
-
namespace shapes#
-
namespace controlflow#
Functions
-
void ComputeShapeIf(ShapesContext &ctx, const NodeProto &node)#
Computes the output :cpp:class:
OptimTensordescriptors of anIfnode and stores them inctx.If(since opset 1 in theai.onnxdomain) selects one of two subgraphs depending on the booleancondinput and yields the outputs of the selected subgraph as its own outputs. Both subgraphs must declare the same number of outputs as theIfnode and the corresponding outputs must be type-compatible.Shape inference walks both
then_branchandelse_branchsub-graphs by calling :cpp:func:ComputeShapeson a copy ofctx(so that outer-scope values referenced by the sub-graph remain visible) and then merges the resulting per-output descriptors:the element dtype is kept when both branches agree and is set to :cpp:enumerator:
TensorType::kUndefinedotherwise;the shape is kept verbatim when both branches agree (same rank and identical dimensions); when the ranks match but some dimensions differ, those dimensions are replaced by a symbolic placeholder string of the form
"If_<output_name>_d<i>"; rank mismatches between the two branches are rejected withstd::invalid_argument.
- Parameters:
ctx – In/out context. Must already contain entries for every non-empty input of
nodeand for every outer-scope value referenced from the sub-graphs; on return it also contains entries for every non-empty output declared bynode.node – The
IfNodeProtowhose outputs should be described.node.op_type()must be"If"andnodemust declare exactly one input and at least one output.
- Throws:
std::invalid_argument – if
node.op_type()is not"If", ifnodehas no output, if thethen_branchorelse_branchattribute is missing or not aGraphProto, if a sub-graph does not declare the same number of outputs asnode, or if the two branches produce outputs with mismatching rank.
-
void ComputeShapeLoop(ShapesContext &ctx, const NodeProto &node)#
Computes the output :cpp:class:
OptimTensordescriptors of aLoopnode and stores them inctx.Loop(since opset 1 in theai.onnxdomain) takes2 + Ninputs(M, cond, v_initial[0..N-1])and yieldsN + Koutputs:Nfinal loop-carried dependency values followed byKscan outputs. The loopbodysubgraph declares2 + Ninputs(iter_num, cond_in, v_in[0..N-1])and1 + N + Koutputs(cond_out, v_out[0..N-1], scan_out[0..K-1]).Shape inference walks the
bodysubgraph by calling :cpp:func:ComputeShapeson a copy ofctxaugmented with descriptors foriter_num(INT64 scalar),cond_in(BOOL scalar) andv_in[i](taken from the matchingv_initial[i]outer descriptor). The output descriptors are then derived as:the
i-th loop-carried output adopts the element dtype ofv_out[i]from the body; the shape is kept when it matchesv_initial[i]and is left fully symbolic (Loop_<output_name>_d<j>) otherwise to model the fact that the body may produce a shape that differs from the initial one;the
k-th scan output adopts the element dtype ofscan_out[k]from the body and its shape is the body’s scan-output shape prefixed by a symbolic leading axis namedLoop_<output_name>_d0(the trip count, generally unknown statically).
- Parameters:
ctx – In/out context. Must already contain entries for every non-empty input of
nodeand for every outer-scope value referenced from the body; on return it also contains entries for every non-empty output declared bynode.node – The
LoopNodeProtowhose outputs should be described.node.op_type()must be"Loop"andnodemust declare at least two inputs (Mandcond, either of which may be omitted via an empty input name).
- Throws:
std::invalid_argument – if
node.op_type()is not"Loop", ifnodehas fewer than two inputs, if thebodyattribute is missing or not aGraphProto, if the body does not declare2 + Ninputs and1 + N + Koutputs consistent with the node’s input/ output arity, or if the body’s loop-carried output dtypes do not match the correspondingv_initialdtypes.
-
void ComputeShapeScan(ShapesContext &ctx, const NodeProto &node)#
Computes the output :cpp:class:
OptimTensordescriptors of aScannode and stores them inctx.Scaniterates overMscan_inputtensors and producesKscan_outputtensors, optionally maintainingNloop-carried state variables. The node hasN + Minputs andN + Koutputs. Itsbodysubgraph declaresN + Minputs andN + Koutputs:body input
ifori < Nis the current value of thei-th state variable; fori >= Nit is the per-iteration slice of the(i - N)-thscan_input(rank equals the scan input’s rank minus one for opset >= 9 when the scan axis is removed, and minus one for opset 8 which always has axis 0).body output
ifori < Nis the updated state variable; fori >= Nit is the per-iteration scan output element.
The output descriptors are derived as:
the
i-th state output (fori < N) adopts the body’sv_out[i]element dtype and the shape ofv_initial[i]when they agree, otherwise the dtype/shape produced by the body;the
k-th scan output adopts the body’s scan-output element dtype and shape, prefixed by a leading axis of length equal to the scan dimension of the firstscan_input(or a symbolic placeholder when that dimension is unknown).
- Parameters:
ctx – In/out context. Must already contain entries for every non-empty input of
nodeand for every outer-scope value referenced from the body; on return it also contains entries for every non-empty output declared bynode.node – The
ScanNodeProtowhose outputs should be described.node.op_type()must be"Scan".
- Throws:
std::invalid_argument – if
node.op_type()is not"Scan", if thebodyattribute is missing or not aGraphProto, if thenum_scan_inputsattribute is missing or non-positive, or if the body’s arity is inconsistent withnode.
-
void ComputeShapeIf(ShapesContext &ctx, const NodeProto &node)#
-
namespace controlflow#
-
namespace shapes#
-
namespace onnx_optim