yobx.xtracing#
Lightweight mechanism for tracing numpy functions and exporting them to ONNX. See Numpy-Tracing and FunctionTransformer for a full walkthrough.
trace_numpy_function#
- yobx.xtracing.trace_numpy_function(g: GraphBuilderExtendedProtocol, sts: Dict, outputs: List[str], func: Callable, inputs: List[str], name: str = 'trace', kw_args: Dict[str, Any] | None = None) str[source]#
Trace a numpy function by wrapping named tensors in g as
NumpyArrayproxies, then recording all numpy operations as ONNX nodes in g.This function follows the same API convention as other converters in this package: it takes an existing
GraphBuilder, the scikit-learn shape/type dictionary sts, the desired output tensor names, and then the callable and input tensor names.- Parameters:
g – the graph builder to add nodes to
sts – shapes defined by scikit-learn (may be empty; forwarded to
g.set_type_shape_unary_opwhen non-empty)outputs – desired output tensor names (one per output returned by func)
func – the numpy function to trace; must accept
len(inputs)positional arguments and return aNumpyArrayor a tuple/list ofNumpyArrayobjectsinputs – existing input tensor names already present in g
name – node name prefix used when emitting
Identityrename nodeskw_args – optional keyword arguments forwarded to func
- Returns:
the first output tensor name (
outputs[0])
Example:
<<<
from yobx.helpers.onnx_helper import pretty_onnx from yobx.xbuilder import GraphBuilder from yobx.xtracing import trace_numpy_function import numpy as np from onnx import TensorProto g = GraphBuilder({"": 21, "ai.onnx.ml": 1}) g.make_tensor_input("X", TensorProto.FLOAT, ("batch", 3)) def my_func(X): return np.sqrt(np.abs(X) + np.float32(1)) trace_numpy_function(g, {}, ["output_0"], my_func, ["X"]) g.make_tensor_output("output_0", indexed=False, allow_untyped_output=True) art = g.to_onnx() print(pretty_onnx(art))
>>>
opset: domain='' version=21 opset: domain='ai.onnx.ml' version=1 input: name='X' type=dtype('float32') shape=['batch', 3] init: name='init1_s_' type=float32 shape=() -- array([1.], dtype=float32)-- Opset.make_node.1/Small Abs(X) -> _onx_abs_X Add(_onx_abs_X, init1_s_) -> _onx_add_abs_X Sqrt(_onx_add_abs_X) -> output_0 output: name='output_0' type='NOTENSOR' shape=None
trace_numpy_to_onnx#
- yobx.xtracing.trace_numpy_to_onnx(func: Callable, *inputs: ndarray, input_names: Sequence[str] | None = None, output_names: Sequence[str] | None = None, target_opset: int | Dict[str, int] = 21, batch_dim: str = 'batch') ExportArtifact[source]#
Trace a numpy function and return the equivalent ONNX model.
This is the high-level entry point. Internally it creates a fresh
GraphBuilder, registers the graph inputs derived from the inputs sample arrays, delegates the actual tracing totrace_numpy_function(), registers the graph outputs, and exports toonnx.ModelProto.- Parameters:
func – a Python callable that accepts one or more numpy arrays and returns a numpy array (or a tuple/list of arrays). The function may use numpy ufuncs, arithmetic operators, reductions, and shape manipulations; see
yobx.xtracing.numpy_arrayfor the full list of supported operations.inputs – sample numpy arrays used to determine the element type and shape of each input. Only
dtypeandshapeare used; the actual values are ignored.input_names – optional list of tensor names for the ONNX graph inputs. Defaults to
["X"]for a single input or["X0", "X1", …]for multiple inputs.output_names – optional list of tensor names for the ONNX graph outputs. Defaults to
["output_0"]. For functions that return multiple arrays supply the correct number of names, e.g.["out_a", "out_b"].target_opset – ONNX opset version. Can be an integer (default domain only) or a dictionary mapping domain names to opset versions.
batch_dim – name of the dynamic first dimension (default:
"batch"). Change this when the default name conflicts with another symbolic dimension in the same graph.
- Returns:
an
ExportArtifactrepresenting the traced function.
Example:
import numpy as np from yobx.xtracing import trace_numpy_to_onnx def my_func(X): return np.sqrt(np.abs(X) + 1) X = np.random.randn(4, 3).astype(np.float32) onx = trace_numpy_to_onnx(my_func, X)