def test_isomorphic_closures(): @parse def f1(x): def inner1(y): return x * y return inner1(10) @parse def f2(a): def inner2(b): return a * b return inner2(10) @parse def f3(a): def inner3(b): return a + b return inner3(10) _check_isomorphic(f1, f2, True) _check_isomorphic(f1, f3, False) idx1 = GraphIndex(f1) idx2 = GraphIndex(f2) # inner1 and inner2 are not considered isomorphic because their free # variables are not matched together. They are matched together when we # check from f1 and f2, but not when we start from the closures directly. _check_isomorphic(idx1['inner1'], idx2['inner2'], False)
def test_clone_scoping(): def f(x, y): def g(): # Depends on f, therefore cloned return x + y def h(z): # No dependency on f, so not nested and not cloned return z * z def i(q): # Depends on f, therefore cloned return g() * q return g() + h(x) + i(y) g = parse(f) cl = GraphCloner(g, clone_constants=True) g2 = cl[g] idx1 = GraphIndex(g) idx2 = GraphIndex(g2) for name in 'fgi': assert idx1[name] is not idx2[name] for name in 'h': assert idx1[name] is idx2[name]
def test_clone_total(): def f1(x): return x * x def f2(y): return f1(y) + 3 g = parse(f2) idx0 = GraphIndex(g) cl1 = GraphCloner(g, clone_constants=True, total=True) idx1 = GraphIndex(cl1[g]) assert idx1['f2'] is not idx0['f2'] assert idx1['f1'] is not idx0['f1'] cl2 = GraphCloner(g, clone_constants=True, total=False) idx2 = GraphIndex(cl2[g]) assert idx2['f2'] is not idx0['f2'] assert idx2['f1'] is idx0['f1']
def test_clone_closure(): def f(x, y): def j(z): a = x + y b = a + z return b c = j(3) return c parsed_f = parse(f) idx = GraphIndex(parsed_f) g = idx['j'] cl = GraphCloner(g, clone_constants=True) idx2 = GraphIndex(cl[g], succ=succ_incoming) for name in 'xy': assert idx[name] is idx2[name] for name in 'zabj': assert idx[name] is not idx2[name]
def test_GraphIndex_multigraph(): def helper(x): return x * x @parse def f(x, y): def inner(a): b = a - 1000 return b a = inner(x) * helper(y) return a idx = GraphIndex(f) assert idx.get_all("x") == { idx["f"].parameters[0], idx["helper"].parameters[0], } assert idx.get_all("y") == {idx["f"].parameters[1]} assert idx.get_all("a") == {idx["f"].output, idx["inner"].parameters[0]} assert idx.get_all("b") == {idx["inner"].output}
def test_GraphIndex_multigraph(): def helper(x): return x * x @parse def f(x, y): def inner(a): b = a - 1000 return b a = inner(x) * helper(y) return a idx = GraphIndex(f) assert idx.get_all('x') == {idx['f'].parameters[0], idx['helper'].parameters[0]} assert idx.get_all('y') == {idx['f'].parameters[1]} assert idx.get_all('a') == {idx['f'].output, idx['inner'].parameters[0]} assert idx.get_all('b') == {idx['inner'].output}
def test_GraphIndex(): @parse def f(x, y): a = x * y b = x + y c = a - b return c idx = GraphIndex(f) assert idx["x"] is f.parameters[0] assert idx["y"] is f.parameters[1] assert idx["c"] is f.output assert idx["a"] is f.output.inputs[1] assert idx["b"] is f.output.inputs[2] with pytest.raises(Exception): idx["d"]
def test_GraphIndex(): @parse def f(x, y): a = x * y b = x + y c = a - b return c idx = GraphIndex(f) assert idx['x'] is f.parameters[0] assert idx['y'] is f.parameters[1] assert idx['c'] is f.output assert idx['a'] is f.output.inputs[1] assert idx['b'] is f.output.inputs[2] with pytest.raises(Exception): idx['d']