예제 #1
0
    def test_2(self):
        # Test a graph where the inputs have owners
        r1, r5 = MyVariable(1), MyVariable(5)
        o = MyOp.make_node(r1, r1)
        r2b = o.outputs[0]
        o2 = MyOp.make_node(r2b, r2b)
        all = io_toposort([r2b], o2.outputs)
        assert all == [o2]

        o2 = MyOp.make_node(r2b, r5)
        all = io_toposort([r2b], o2.outputs)
        assert all == [o2]
예제 #2
0
 def test_5(self):
     # Test when outputs have clients
     r1, r2, r4 = MyVariable(1), MyVariable(2), MyVariable(4)
     o0 = MyOp.make_node(r1, r2)
     MyOp.make_node(o0.outputs[0], r4)
     all = io_toposort([], o0.outputs)
     assert all == [o0]
예제 #3
0
 def test_4(self):
     # Test inputs and outputs mixed together in a chain graph
     r1, r2 = MyVariable(1), MyVariable(2)
     o0 = MyOp.make_node(r1, r2)
     o1 = MyOp.make_node(o0.outputs[0], r1)
     all = io_toposort([r1, o0.outputs[0]], [o0.outputs[0], o1.outputs[0]])
     assert all == [o1]
예제 #4
0
 def on_detach(self, fgraph):
     """
     Should remove any dynamically added functionality
     that it installed into the function_graph
     """
     for node in io_toposort(fgraph.inputs, fgraph.outputs):
         self.on_prune(fgraph, node, "Bookkeeper.detach")
예제 #5
0
    def toposort(self):
        """Toposort

        Return an ordering of the graph's Apply nodes such that

        * All the nodes of the inputs of a node are before that node.
        * Satisfies the orderings provided by each feature that has
          an 'orderings' method.

        If a feature has an 'orderings' method, it will be called with
        this FunctionGraph as sole argument. It should return a dictionary of
        `{node: predecessors}` where predecessors is a list of nodes that
        should be computed before the key node.
        """
        if len(self.apply_nodes) < 2:
            # optimization
            # when there are 0 or 1 nodes, no sorting is necessary
            # This special case happens a lot because the OpWiseCLinker
            # produces 1-element graphs.
            return list(self.apply_nodes)
        fg = self

        ords = self.orderings()

        order = graph.io_toposort(fg.inputs, fg.outputs, ords)

        return order
예제 #6
0
 def test_3(self):
     # Test a graph which is not connected
     r1, r2, r3, r4 = MyVariable(1), MyVariable(2), MyVariable(
         3), MyVariable(4)
     o0 = MyOp.make_node(r1, r2)
     o1 = MyOp.make_node(r3, r4)
     all = io_toposort([r1, r2, r3, r4], o0.outputs + o1.outputs)
     assert all == [o1, o0] or all == [o0, o1]
예제 #7
0
 def on_attach(self, fgraph):
     """
     Called by FunctionGraph.attach_feature, the method that attaches
     the feature to the FunctionGraph. Since this is called after the
     FunctionGraph is initially populated, this is where you should
     run checks on the initial contents of the FunctionGraph.
     """
     for node in io_toposort(fgraph.inputs, fgraph.outputs):
         self.on_import(fgraph, node, "on_attach")
예제 #8
0
def test_dependence():
    dependence = make_dependence_cmp()

    x = tensor.matrix("x")
    y = tensor.dot(x * 2, x + 1)
    nodes = io_toposort([x], [y])

    for a, b in zip(nodes[:-1], nodes[1:]):
        assert dependence(a, b) <= 0
예제 #9
0
    def test_0(self):
        # Test a simple graph
        r1, r2, r5 = MyVariable(1), MyVariable(2), MyVariable(5)
        o = MyOp.make_node(r1, r2)
        o2 = MyOp.make_node(o.outputs[0], r5)

        all = general_toposort(o2.outputs, prenode)
        assert all == [r5, r2, r1, o, o.outputs[0], o2, o2.outputs[0]]

        all = io_toposort([r5], o2.outputs)
        assert all == [o, o2]
예제 #10
0
    def __import__(self, apply_node, check=True, reason=None):
        """
        Given an apply_node, recursively search from this node to know graph,
        and then add all unknown variables and apply_nodes to this graph.
        """
        node = apply_node

        # We import the nodes in topological order. We only are interested
        # in new nodes, so we use all variables we know of as if they were the input set.
        # (the functions in the graph module only use the input set to
        # know where to stop going down)
        new_nodes = graph.io_toposort(self.variables, apply_node.outputs)

        if check:
            for node in new_nodes:
                if hasattr(node, "fgraph") and node.fgraph is not self:
                    raise Exception("%s is already owned by another fgraph" %
                                    node)
                for r in node.inputs:
                    if hasattr(r, "fgraph") and r.fgraph is not self:
                        raise Exception(
                            "%s is already owned by another fgraph" % r)
                    if (r.owner is None and not isinstance(r, graph.Constant)
                            and r not in self.inputs):
                        # Standard error message
                        error_msg = ("Input %d of the graph (indices start "
                                     "from 0), used to compute %s, was not "
                                     "provided and not given a value. Use the "
                                     "Aesara flag exception_verbosity='high', "
                                     "for more information on this error." %
                                     (node.inputs.index(r), str(node)))
                        raise MissingInputError(error_msg, variable=r)

        for node in new_nodes:
            assert node not in self.apply_nodes
            self.__setup_node__(node)
            self.apply_nodes.add(node)
            if not hasattr(node.tag, "imported_by"):
                node.tag.imported_by = []
            node.tag.imported_by.append(str(reason))
            for output in node.outputs:
                self.__setup_r__(output)
                self.variables.add(output)
            for i, input in enumerate(node.inputs):
                if input not in self.variables:
                    self.__setup_r__(input)
                    self.variables.add(input)
                self.__add_client__(input, (node, i))
            assert node.fgraph is self
            self.execute_callbacks("on_import", node, reason)