module onnx_tools.onnx_grammar.onnx_translation#

Short summary#

module mlprodict.onnx_tools.onnx_grammar.onnx_translation

One class which visits a syntax tree.

source on GitHub

Functions#

function

truncated documentation

get_default_context

Returns a default context useful for most of the conversion from a function using numpy into ONNX.

get_default_context_cpl

Returns a default useful context to compile the converter returned by translate_fct2onnx().

py_make_float_array

Creates an array with a single element from a constant.

py_mul

Function for python operator *.

py_opp

Function for python unary operator -.

py_pow

Function for python operator **.

squareform_pdist

Replacements for squareform

translate_fct2onnx

Translates a function into ONNX. The code it produces is using classes OnnxAbs, OnnxAdd, …

Documentation#

One class which visits a syntax tree.

source on GitHub

mlprodict.onnx_tools.onnx_grammar.onnx_translation.get_default_context()#

Returns a default context useful for most of the conversion from a function using numpy into ONNX.

source on GitHub

mlprodict.onnx_tools.onnx_grammar.onnx_translation.get_default_context_cpl()#

Returns a default useful context to compile the converter returned by translate_fct2onnx.

source on GitHub

mlprodict.onnx_tools.onnx_grammar.onnx_translation.py_make_float_array(cst, op_version=None)#

Creates an array with a single element from a constant.

Parameters:
  • cst – constant

  • op_version – unused

Returns:

array

<<<

from mlprodict.onnx_tools.onnx_grammar.onnx_translation import py_make_float_array
print(py_make_float_array(5.5))

>>>

    [5.5]

source on GitHub

mlprodict.onnx_tools.onnx_grammar.onnx_translation.py_mul(*x, op_version=None)#

Function for python operator *.

Parameters:
  • x – floats

  • op_version – unused

Returns:

x*y

source on GitHub

mlprodict.onnx_tools.onnx_grammar.onnx_translation.py_opp(x, op_version=None)#

Function for python unary operator -.

Parameters:
  • x – floats

  • op_version – unused

Returns:

-x

source on GitHub

mlprodict.onnx_tools.onnx_grammar.onnx_translation.py_pow(x, p, op_version=None)#

Function for python operator **.

Parameters:
  • x – float

  • p – power

  • op_version – unused

Returns:

x^p

source on GitHub

mlprodict.onnx_tools.onnx_grammar.onnx_translation.squareform_pdist(X, metric='sqeuclidean', op_version=None)#

Replacements for squareform and pdist.

source on GitHub

mlprodict.onnx_tools.onnx_grammar.onnx_translation.translate_fct2onnx(fct, context=None, cpl=False, context_cpl=None, output_names=None, dtype=<class 'numpy.float32'>, verbose=0, fLOG=None)#

Translates a function into ONNX. The code it produces is using classes OnnxAbs, OnnxAdd, …

Parameters:
  • fct – function to convert

  • context – context of the function to convert something like {'numpy.transpose': numpy.transpose}, if context is None, it receives a default value returnd by get_default_context

  • cpl – compile the function after it was created

  • context_cpl – context used at compiling time if context_cpl is None, it receives a default value returnd by get_default_context_cpl

  • output_names – names of the output in the ONNX graph

  • dtypenumpy float type used to produce the model

  • verbose – integer, display more information

  • fLOG – logging function

Returns:

code or compiled code

Convert a function into ONNX code

The following code parses a python function and returns another python function which produces an ONNX graph if executed.

<<<

import numpy
from mlprodict.onnx_tools.onnx_grammar import translate_fct2onnx


def trs(x, y):
    z = x + numpy.transpose(y, axes=[1, 0])
    return x * z


onnx_code = translate_fct2onnx(
    trs, context={'numpy.transpose': numpy.transpose})
print(onnx_code)

>>>

    def trs(x, y, dtype=numpy.float32, op_version=None):
        z = (
            OnnxAdd(
                x,
                OnnxTranspose(
                    y,
                    perm=[1, 0],
                    op_version=op_version
                ),
                op_version=op_version
            )
        )
        return (
            OnnxMul(
                x,
                z,
                op_version=op_version
            )
        )

Next example goes further and compile the outcome.

Convert a function into ONNX code and run

The following code parses a python function and returns another python function which produces an ONNX graph if executed. The example executes the function, creates an ONNX then uses OnnxInference to compute predictions. Finally it compares them to the original.

<<<

import numpy
from mlprodict.onnx_tools.onnx_grammar import translate_fct2onnx
from mlprodict.plotting.text_plot import onnx_simple_text_plot
from mlprodict.onnxrt import OnnxInference
from mlprodict.npy.xop import loadop


OnnxAdd, OnnxTranspose, OnnxMul, OnnxIdentity = loadop(
    'Add', 'Transpose', 'Mul', 'Identity')


ctx = {'OnnxAdd': OnnxAdd,
       'OnnxTranspose': OnnxTranspose,
       'OnnxMul': OnnxMul,
       'OnnxIdentity': OnnxIdentity}


def trs(x, y):
    z = x + numpy.transpose(y, axes=[1, 0])
    return x * z


inputs = {'x': numpy.array([[1, 2]], dtype=numpy.float32),
          'y': numpy.array([[-0.3, 0.4]], dtype=numpy.float32).T}

original = trs(inputs['x'], inputs['y'])

print('original output:', original)

onnx_fct = translate_fct2onnx(
    trs, context={'numpy.transpose': numpy.transpose},
    cpl=True, context_cpl=ctx, output_names=['Z'])

onnx_code = onnx_fct('x', 'y', op_version=12)

onnx_g = onnx_code.to_onnx(inputs, target_opset=12)
print("ONNX model")
print(onnx_simple_text_plot(onnx_g))

oinf = OnnxInference(onnx_g)
res = oinf.run(inputs)

print('-----------')
print("ONNX inference:", res['Z'])

>>>

    original output: [[0.7 4.8]]
    ONNX model
    opset: domain='' version=12
    input: name='x' type=dtype('float32') shape=[1, 2]
    input: name='y' type=dtype('float32') shape=[2, 1]
    Transpose(y, perm=[1,0]) -> out_tra_0
      Add(x, out_tra_0) -> out_add_0
        Mul(x, out_add_0) -> Z
    output: name='Z' type=dtype('float32') shape=[1, 2]
    -----------
    ONNX inference: [[0.7 4.8]]

The function to be converted may include python functions which must not be converted. In that case, their name must be prefixed by py_. The execution of the function this one builds produces the following error:

TypeError: Parameter to MergeFrom() must be instance of same class:
expected onnx.TensorProto got onnx.AttributeProto.

It indicates that constants in the code marges multiple types, usually floats and tensor of floats. Floats should be converted using the following function:

def py_make_float_array(cst):
    return numpy.array([cst], dtype=numpy.float32)

The function replaces empty contexts by default values which covers many numpy functions. The tutorial Execute ONNX graphs gives an example of how it can be used on a more complex function.

source on GitHub