Ejemplo n.º 1
0
def test_helpers():
    g = Graph()
    cg = Constant(g)
    assert is_constant_graph(cg)

    one = Constant(1)
    assert not is_constant_graph(one)
    assert is_constant(one)

    a = Apply([cg, one], g)
    assert is_apply(a)

    p = Parameter(g)
    assert is_parameter(p)
Ejemplo n.º 2
0
def test_dfs_variants():
    def f(x):
        z = x * x

        def g(y):
            return y + z

        w = z + 3
        q = g(w)
        return q

    graph = parse(f)
    inner_graph_ct, = [x for x in dfs(graph.return_) if is_constant_graph(x)]
    inner_graph = inner_graph_ct.value

    inner_ret = inner_graph.return_

    deep = _name_nodes(_dfs(inner_ret, succ_deep))
    assert deep == set('. return add y z mul x'.split())

    deeper = _name_nodes(_dfs(inner_ret, succ_deeper))
    assert deeper == set('. return add y z mul x w 3 q g'.split())

    _bound_fv = freevars_boundary(inner_graph, True)
    bound_fv = _name_nodes(_dfs(inner_ret, succ_deeper, _bound_fv))
    assert bound_fv == set('. return add y z'.split())

    _no_fv = freevars_boundary(inner_graph, False)
    no_fv = _name_nodes(_dfs(inner_ret, succ_deeper, _no_fv))
    assert no_fv == set('. return add y'.split())

    _excl_root = exclude_from_set([inner_ret])
    excl_root = _name_nodes(_dfs(inner_ret, succ_deeper, _excl_root))
    assert excl_root == set()
Ejemplo n.º 3
0
 def name(node):
     if is_constant_graph(node):
         return node.value.debug.name or '.'
     elif isinstance(node, Constant):
         return str(node.value)
     else:
         return node.debug.name or '.'
Ejemplo n.º 4
0
    def label(self, node, force=None, fn_label=None):
        """Label a node."""
        if isinstance(node, DebugInfo):
            return self.name(node, True if force is None else force)
        elif isinstance(node, Graph):
            return self.name(node.debug, True if force is None else force)
        elif is_constant_graph(node):
            return self.name(node.value.debug,
                             True if force is None else force)
        elif is_constant(node):
            v = node.value
            if isinstance(v, (int, float, str)):
                return repr(v)
            elif isinstance(v, Primitive):
                return v.name
            else:
                class_name = v.__class__.__name__
                return f'{self.label(node.debug, True)}:{class_name}'
        elif is_parameter(node):
            return self.label(node.debug, True)
        else:
            lbl = ''
            if self.function_in_node:
                if fn_label is None:
                    fn_label = self.const_fn(node)
                if fn_label:
                    lbl = fn_label

            name = self.name(node, force)
            if name:
                if lbl:
                    lbl += f'→{name}'
                else:
                    lbl = name
            return lbl or '·'
Ejemplo n.º 5
0
    def graphs_used(self) -> Dict[Graph, Set[Graph]]:
        """Map each graph to the set of graphs it uses.

        For each graph, this is the set of graphs that it refers to
        directly.
        """
        coverage = self.coverage()
        return {
            g: {
                node.value
                for node in dfs(g.return_, succ_incoming, freevars_boundary(g))
                if is_constant_graph(node)
            }
            for g in coverage
        }
Ejemplo n.º 6
0
    def process_node_generic(self, node, g, cl):
        """Create node and edges for a node."""
        lbl = self.label(node)

        self.cynode(id=node, label=lbl, parent=g, classes=cl)

        fn = node.inputs[0] if node.inputs else None
        if fn and is_constant_graph(fn):
            self.graphs.add(fn.value)

        edges = []
        if fn and not (is_constant(fn) and self.function_in_node):
            edges.append((node, 'F', fn))

        edges += [(node, i + 1, inp)
                  for i, inp in enumerate(node.inputs[1:]) or []]

        self.process_edges(edges)
Ejemplo n.º 7
0
    def free_variables_total(self) -> Dict[Graph, Set[ANFNode]]:
        """Map each graph to its free variables.

        This differs from `free_variables_direct` in that it also
        includes free variables needed by children graphs.
        Furthermore, graph Constants may figure as free variables.
        """
        parents = self.parents()
        fvs: Dict[Graph, Set[ANFNode]] = defaultdict(set)

        for node in dfs(self.root.return_, succ_deeper):
            for inp in node.inputs:
                if is_constant_graph(inp):
                    owner = parents[inp.value]
                else:
                    owner = inp.graph
                if owner is None:
                    continue
                g = node.graph
                while g is not owner:
                    fvs[g].add(inp)
                    g = parents[g]

        return fvs
Ejemplo n.º 8
0
 def coverage(self) -> Iterable[Graph]:
     """Return a collection of graphs accessible from the root."""
     root: ANFNode = Constant(self.root)
     nodes = dfs(root, succ_deeper)
     return set(node.value if is_constant_graph(node) else node.graph
                for node in nodes) - {None}
Ejemplo n.º 9
0
 def follow(self, node):
     """Add this node's graph if follow_references is True."""
     if is_constant_graph(node) and self.follow_references:
         self.graphs.add(node.value)