Exemple #1
0
def test_concat():
    """
    Functional test for concat
    """
    g1 = empty_graph("G1")
    n1 = node('Add',
              inputs=['x1_1', 'x1_2'],
              outputs=['sum_1'],
              name="node_name")
    g1 = add_input(g1, 'x1_1', "FLOAT", [1])
    g1 = add_input(g1, 'x1_2', "FLOAT", [1])
    g1 = add_output(g1, 'sum_1', "FLOAT", [1])
    g1 = add_node(g1, n1)

    g2 = empty_graph("G2")
    n2 = node('Add',
              inputs=['x2_1', 'x2_2'],
              outputs=['sum_2'],
              name="node_name")
    g2 = add_input(g2, 'x2_2', "FLOAT", [1])
    g2 = add_output(g2, 'sum_2', "FLOAT", [1])
    g2 = add_node(g2, n2)

    g = concat(g1, g2, False, True, edge_match=[("x1_2", "x2_1")])

    data = {
        "x1_1": np.array([2]).astype(np.float32),
        "x1_2": np.array([5]).astype(np.float32),
        "x2_2": np.array([5]).astype(np.float32)
    }
    result = run(g, inputs=data, outputs=["sum_1", "sum_2"])
    assert result[
        0], "Sum of 2 and 5 should be equal to constant 7. Concat failed."
Exemple #2
0
def test_check():

    # Invalid, no input/output:
    g = empty_graph()
    n1 = node('Add', inputs=['x1', 'x2'], outputs=['sum'])
    g = add_node(g, n1)
    assert not check(g), "Graph is not complete."

    # Valid graph
    g = add_input(g, 'x1', "FLOAT", [1])
    g = add_input(g, 'x2', "FLOAT", [1])
    g = add_output(g, 'sum', "FLOAT", [1])
    assert check(g), "Graph should pass checks."

    # Invalid: None operator:
    g = empty_graph()
    n1 = node('None', inputs=['x1', 'x2'], outputs=['sum'])
    g = add_node(g, n1)
    g = add_input(g, 'x1', "FLOAT", [1])
    g = add_input(g, 'x2', "FLOAT", [1])
    g = add_output(g, 'sum', "FLOAT", [1])
    assert not check(g), "Graph should not pass checks."

    # Invalid: Dynamic size input
    g = empty_graph()
    n1 = node('Add', inputs=['x1', 'x2'], outputs=['sum'])
    g = add_node(g, n1)
    g = add_input(g, 'x1', "FLOAT", [])
    g = add_input(g, 'x2', "FLOAT", [1])
    g = add_output(g, 'sum', "FLOAT", [1])
    assert not check(g), "Graph should not pass checks."

    check(g, _sclbl_check=False, _onnx_check=False)
    check(g, _onnx_check=False)  # Operator check.
Exemple #3
0
def test_merge():
    """
    Functional test of merge().
    """
    # Subgraph 1
    sg1 = empty_graph("Graph 1")
    n1 = node('Add', inputs=['x1', 'x2'], outputs=['sum'])
    sg1 = add_node(sg1, n1)
    sg1 = add_input(sg1, 'x1', "FLOAT", [1])
    sg1 = add_input(sg1, 'x2', "FLOAT", [1])
    sg1 = add_output(sg1, 'sum', "FLOAT", [1])

    # Subgraph 2
    sg2 = empty_graph("Graph 2")
    sg2 = add_constant(sg2, "const", np.array([7]), "FLOAT")
    n2 = node("Equal", inputs=['sum', 'const'], outputs=['equal'])
    sg2 = add_node(sg2, n2)

    sg2 = add_input(sg2, 'sum', "FLOAT", [1])
    sg2 = add_output(sg2, 'equal', "BOOL", [1])

    g = merge(sg1, sg2, outputs=["sum"], inputs=["sum"])

    data = {
        "x1": np.array([2]).astype(np.float32),
        "x2": np.array([5]).astype(np.float32)
    }
    result = run(g, inputs=data, outputs=["equal"])
    assert result[
        0], "Sum of 2 and 5 should be equal to constant 7. Merged failed."
Exemple #4
0
def test_add_nodes():
    g = empty_graph()
    for i in range(10):
        n = node('Add', inputs=['x1', 'x2'], outputs=['sum'])
        g = add_node(g, n)
    assert len(g.node) == 10, "Nodes not properly added."
    check = add_node(False, True)
    assert not check, "Incorrectly able to add to non-graph."
    check = add_node(g, False)
    assert not check, "Incorrectly able to add a non-node."
Exemple #5
0
def test_delete_node():
    g = empty_graph()
    n = node('Add', inputs=['x1', 'x2'], outputs=['sum'], name="node_name")
    g = add_node(g, n)
    assert len(g.node) == 1, "Node not properly added."
    g = delete_node(g, "node_name")
    assert len(g.node) == 0, "Node not properly deleted."
Exemple #6
0
def test_clean():
    g = empty_graph()
    n1 = node('Add', inputs=['x1', 'x2'], outputs=['sum'])
    g = add_node(g, n1)
    g = add_input(g, 'x1', "FLOAT", [1])
    g = add_input(g, 'x2', "FLOAT", [1])
    g = add_output(g, 'sum', "FLOAT", [1])
    g = clean(g)
    assert type(g) == xpb2.GraphProto, "Clean failed."
Exemple #7
0
def test_split():
    """
    Functional test for split
    """
    g1 = empty_graph("G1")
    n1 = node('Add', inputs=['x1_1', 'x1_2'], outputs=['sum_1'], name="n1")
    g1 = add_input(g1, 'x1_1', "FLOAT", [1])
    g1 = add_input(g1, 'x1_2', "FLOAT", [1])
    g1 = add_output(g1, 'sum_1', "FLOAT", [1])
    g1 = add_node(g1, n1)

    g2 = empty_graph("G2")
    n2 = node('Add', inputs=['x2_1', 'x2_2'], outputs=['sum_2'], name="n2")
    g2 = add_input(g2, 'x2_1', "FLOAT", [1])
    g2 = add_input(g2, 'x2_2', "FLOAT", [1])
    g2 = add_output(g2, 'sum_2', "FLOAT", [1])
    g2 = add_node(g2, n2)

    g3 = empty_graph("G3")
    n3 = node('Add', inputs=['x3_1', 'x3_2'], outputs=['sum_3'], name="n3")
    g3 = add_input(g3, 'x3_1', "FLOAT", [1])
    g3 = add_input(g3, 'x3_2', "FLOAT", [1])
    g3 = add_output(g3, 'sum_3', "FLOAT", [1])
    g3 = add_node(g3, n3)

    g = split(g1,
              g2,
              g3,
              cg1_match=[("sum_1", "x2_2")],
              cg2_match=[("sum_1", "x3_1")])

    data = {
        "x1_1": np.array([1]).astype(np.float32),
        "x1_2": np.array([2]).astype(np.float32),
        "x2_1": np.array([3]).astype(np.float32),
        "x3_2": np.array([4]).astype(np.float32),
    }
    result = run(g, inputs=data, outputs=["sum_2", "sum_3"])
    assert result[
        0], "Sum of 1,2, and 3 should be equal to constant 6. Split failed."
Exemple #8
0
def test_add_constant():

    # Simple add graph
    g = empty_graph()
    n1 = node('Add', inputs=['x1', 'x2'], outputs=['sum'])
    g = add_node(g, n1)

    # Add input and constant
    g = add_constant(g, 'x1', np.array([1]), "INT64")
    g = add_constant(g, 'x2', np.array([5]), "INT64")

    # Output:
    g = add_output(g, 'sum', "INT64", [1])

    # This works, but seems to fail for other data types...
    result = run(g, inputs={}, outputs=["sum"])
    assert result[0] == 6, "Add constant failed."
    # todo(McK): Does not work for INT16 / INT8, check?
Exemple #9
0
# Add the Subtract, Absolute, ReduceSum, and Less nodes
# Node how the names again enforce the topology of the graph
n1 = so.node("Sub", inputs=['in', 'c1'], outputs=['sub'])
n2 = so.node("Abs", inputs=['sub'], outputs=['abs'])
n3 = so.node("ReduceSum", inputs=['abs'], outputs=['sum'],
             keepdims=0)  # Note the keepdims additional parameter.
g = so.add_nodes(g, [n1, n2, n3])

# And, we need to add the threshold (constant c2):
threshold = np.array([3000000]).astype(np.int32)
g = so.add_constant(g, "c2", threshold, "INT32")

# Add the less node. Please note that the nodes have to be added in topological order:
n4 = so.node("Less", inputs=['sum', 'c2'], outputs=['result'])
g = so.add_node(g, n4)

# Check provides an error stating that no outputs have been specified (which is true at this point)
so.check(g)

# Add output:
g = so.add_output(g, "result", "BOOL", [1])

# After which is passes all the checks
so.check(g)

# Let's inspect:
so.display(g)

# Let's clean:
g = so.clean(g)
Exemple #10
0
def test_add_node():
    g = empty_graph()
    n = node('Add', inputs=['x1', 'x2'], outputs=['sum'])
    g = add_node(g, n)
    assert len(g.node) == 1, "Node not properly added."
Exemple #11
0
import sclblonnx as so
"""
EXAMPLE 1: Adding two scalars.

This example shows the basic usage of the sclblonnx package by creating an onnx graph from scratch that adds two
scalars together.
"""

# Use the empty_graph() method to create a named xpb2.GraphProto object:
g = so.empty_graph()

# Add a node to the graph.
# Please note the list of available operators at: https://github.com/onnx/onnx/blob/master/docs/Operators.md
# Run so.list_data_types() and / or so.list_operators() so. to see all Scailable supported data types.
n1 = so.node('Add', inputs=['x1', 'x2'], outputs=['sum'])
g = so.add_node(g, n1)

# We should explicitly specify the named inputs to the graph -- note that the names determine the graph topology.
# Also, we should specify the data type and dimensions of any input.
# Use so.list_data_types() to see available data types.
g = so.add_input(g, 'x1', "FLOAT", [1])
g = so.add_input(g, 'x2', "FLOAT", [1])

# Similarly, we add the named output with its corresponding type and dimension.
# Note that types will need to "match", as do dimensions. Please see the operator docs for more info.
g = so.add_output(g, 'sum', "FLOAT", [1])

# so.check() checks the current graph to see if it matches Scailable's upload criteria for .wasm conversion.
so.check(g)

# Now, a few tricks to sanitize the graph which are always useful.
Exemple #12
0
flexible and can be used for intermediate merging/concatenation of partial graphs (i.e., graphs that are not yet
finished).

Below we provide a number of examples of each of the functions. We recommend using so.display() throughout to visualize
the resulting graphs and truly understand how the graphs are joined together. Examples are all very simple (small graphs,
scalar operations, etc.), but don't underestimate the complexities involved; with larger graphs the behavior of
the concat function can be challenging.
"""

# # Lets start by creating a few simple (and complete) graphs which we will use throughout:
# # Simple absolute value graph:
g1 = so.empty_graph("g_1")
n1 = so.node('Abs', inputs=['in_1_1'], outputs=['out_1_1'], name="node_1_1")
g1 = so.add_input(g1, 'in_1_1', "FLOAT", [1])
g1 = so.add_output(g1, 'out_1_1', "FLOAT", [1])
g1 = so.add_node(g1, n1)
# so.display(g1)
# data = {"in_1_1": np.array([2]).astype(np.float32)}
# print(so.run(g1, inputs=data, outputs=["out_1_1"]))

# # Simple max value graph:
g2 = so.empty_graph("g_2")
n2 = so.node('Max',
             inputs=['in_2_1', 'in_2_2'],
             outputs=['out_2_1'],
             name="node_2_1")
g2 = so.add_input(g2, 'in_2_1', "FLOAT", [1])
g2 = so.add_constant(g2, "in_2_2", np.array([10]), "FLOAT")
g2 = so.add_output(g2, 'out_2_1', "FLOAT", [1])
g2 = so.add_node(g2, n2)
# so.display(g2)
Exemple #13
0
# Check its output, we see the name, type, and dimensions
so.list_outputs(g)

# Run the model to see the outputs:
result = so.run(g, inputs={"input": img_input}, outputs=["output"])
print(result)

# Add and arg_max node to find the highest output in the output vector
# Note the keepdims and axis; the output of the Argmax node should align with the defined output.
n1 = so.node('ArgMax',
             inputs=['output'],
             outputs=['argmax'],
             keepdims=0,
             axis=1)
g = so.add_node(
    g, n1)  # Note, this adds the node, but the output is still "output"
g = so.delete_output(g, "output")  # Remove the old output
g = so.add_output(g, 'argmax', "INT64",
                  [1])  # Add the new output (for testing only)

# Test:
result = so.run(g, inputs={"input": img_input}, outputs=["argmax"])
print(result)

# So, this works. Let's remove the output argmax again before we continue:
g = so.delete_output(g, 'argmax')

# Because the if statement to switch between values of 100 and 0 requires a boolean input condition, we add
# a constant node with the value of 7, and add an equals node:
g = so.add_constant(g, "cut", np.array([7]), "INT64")
n2 = so.node("Equal", inputs=['argmax', 'cut'], outputs=['seven'])