def test_apply_operation_back_conditional_measure(self):
        """Test consistency of apply_operation_back for conditional measure."""

        # Measure targeting a clbit which is not a member of the conditional
        # register. qc.measure(qr[0], cr[0]).c_if(cr2, 0)

        new_creg = ClassicalRegister(1, 'cr2')
        self.dag.add_creg(new_creg)

        meas_gate = Measure()
        meas_gate.condition = (new_creg, 0)
        meas_node = self.dag.apply_operation_back(meas_gate, [self.qubit0],
                                                  [self.clbit0])

        self.assertEqual(meas_node.qargs, [self.qubit0])
        self.assertEqual(meas_node.cargs, [self.clbit0])
        self.assertEqual(meas_node.condition, meas_gate.condition)

        self.assertEqual(
            sorted(self.dag._multi_graph.in_edges(meas_node._node_id)),
            sorted([
                (self.dag.input_map[self.qubit0]._node_id, meas_node._node_id,
                 {
                     'wire': self.qubit0,
                     'name': 'qr[0]'
                 }),
                (self.dag.input_map[self.clbit0]._node_id, meas_node._node_id,
                 {
                     'wire': self.clbit0,
                     'name': 'cr[0]'
                 }),
                (self.dag.input_map[new_creg[0]]._node_id, meas_node._node_id,
                 {
                     'wire': Clbit(new_creg, 0),
                     'name': 'cr2[0]'
                 }),
            ]))

        self.assertEqual(
            sorted(self.dag._multi_graph.out_edges(meas_node._node_id)),
            sorted([
                (meas_node._node_id, self.dag.output_map[self.qubit0]._node_id,
                 {
                     'wire': self.qubit0,
                     'name': 'qr[0]'
                 }),
                (meas_node._node_id, self.dag.output_map[self.clbit0]._node_id,
                 {
                     'wire': self.clbit0,
                     'name': 'cr[0]'
                 }),
                (meas_node._node_id, self.dag.output_map[new_creg[0]]._node_id,
                 {
                     'wire': Clbit(new_creg, 0),
                     'name': 'cr2[0]'
                 }),
            ]))

        self.assertTrue(rx.is_directed_acyclic_graph(self.dag._multi_graph))
    def test_apply_operation_back_conditional_measure_to_self(self):
        """Test consistency of apply_operation_back for measure onto conditioning bit."""

        # Measure targeting a clbit which _is_ a member of the conditional
        # register. qc.measure(qr[0], cr[0]).c_if(cr, 3)

        meas_gate = Measure()
        meas_gate.condition = self.condition
        meas_node = self.dag.apply_operation_back(meas_gate, [self.qubit1],
                                                  [self.clbit1])

        self.assertEqual(meas_node.qargs, [self.qubit1])
        self.assertEqual(meas_node.cargs, [self.clbit1])
        self.assertEqual(meas_node.condition, meas_gate.condition)

        self.assertEqual(
            sorted(self.dag._multi_graph.in_edges(meas_node._node_id)),
            sorted([
                (self.dag.input_map[self.qubit1]._node_id, meas_node._node_id,
                 {
                     'wire': self.qubit1,
                     'name': 'qr[1]'
                 }),
                (self.dag.input_map[self.clbit0]._node_id, meas_node._node_id,
                 {
                     'wire': self.clbit0,
                     'name': 'cr[0]'
                 }),
                (self.dag.input_map[self.clbit1]._node_id, meas_node._node_id,
                 {
                     'wire': self.clbit1,
                     'name': 'cr[1]'
                 }),
            ]))

        self.assertEqual(
            sorted(self.dag._multi_graph.out_edges(meas_node._node_id)),
            sorted([
                (meas_node._node_id, self.dag.output_map[self.qubit1]._node_id,
                 {
                     'wire': self.qubit1,
                     'name': 'qr[1]'
                 }),
                (meas_node._node_id, self.dag.output_map[self.clbit0]._node_id,
                 {
                     'wire': self.clbit0,
                     'name': 'cr[0]'
                 }),
                (meas_node._node_id, self.dag.output_map[self.clbit1]._node_id,
                 {
                     'wire': self.clbit1,
                     'name': 'cr[1]'
                 }),
            ]))

        self.assertTrue(rx.is_directed_acyclic_graph(self.dag._multi_graph))
Example #3
0
    def test_apply_operation_back_conditional(self):
        """Test consistency of apply_operation_back with condition set."""

        # Single qubit gate conditional: qc.h(qr[2]).c_if(cr, 3)

        h_gate = HGate()
        h_gate.condition = self.condition
        h_node = self.dag.apply_operation_back(h_gate, [self.qubit2], [],
                                               h_gate.condition)

        self.assertEqual(h_node.qargs, [self.qubit2])
        self.assertEqual(h_node.cargs, [])
        self.assertEqual(h_node.condition, h_gate.condition)

        self.assertEqual(
            sorted(self.dag._get_multi_graph_in_edges(h_node._node_id)),
            sorted([
                (self.dag.input_map[self.qubit2]._node_id, h_node._node_id, {
                    'wire': self.qubit2,
                    'name': 'qr[2]'
                }),
                (self.dag.input_map[self.clbit0]._node_id, h_node._node_id, {
                    'wire': self.clbit0,
                    'name': 'cr[0]'
                }),
                (self.dag.input_map[self.clbit1]._node_id, h_node._node_id, {
                    'wire': self.clbit1,
                    'name': 'cr[1]'
                }),
            ]))

        self.assertEqual(
            sorted(self.dag._get_multi_graph_out_edges(h_node._node_id)),
            sorted([
                (h_node._node_id, self.dag.output_map[self.qubit2]._node_id, {
                    'wire': self.qubit2,
                    'name': 'qr[2]'
                }),
                (h_node._node_id, self.dag.output_map[self.clbit0]._node_id, {
                    'wire': self.clbit0,
                    'name': 'cr[0]'
                }),
                (h_node._node_id, self.dag.output_map[self.clbit1]._node_id, {
                    'wire': self.clbit1,
                    'name': 'cr[1]'
                }),
            ]))

        if self.dag._USE_RX:
            self.assertTrue(rx.is_directed_acyclic_graph(
                self.dag._multi_graph))
        else:
            self.assertTrue(nx.is_directed_acyclic_graph(
                self.dag._multi_graph))
Example #4
0
def raise_if_dagdependency_invalid(dag):
    """Validates the internal consistency of a DAGDependency._multi_graph.
    Intended for use in testing.

    Raises:
       DAGDependencyError: if DAGDependency._multi_graph is inconsistent.
    """

    multi_graph = dag._multi_graph

    if not rx.is_directed_acyclic_graph(multi_graph):
        raise DAGDependencyError("multi_graph is not a DAG.")

    # Every node should be of type op.
    for node in dag.get_nodes():
        if node.type != "op":
            raise DAGDependencyError("Found node of unexpected type: {}".format(node.type))
Example #5
0
 def test_is_directed_acyclic_graph_false(self):
     digraph = retworkx.generators.directed_cycle_graph(1000)
     self.assertFalse(retworkx.is_directed_acyclic_graph(digraph))
Example #6
0
 def test_is_directed_acyclic_graph(self):
     dag = retworkx.generators.directed_path_graph(1000)
     res = retworkx.is_directed_acyclic_graph(dag)
     self.assertTrue(res)
Example #7
0
def raise_if_dagcircuit_invalid(dag):
    """Validates the internal consistency of a DAGCircuit._multi_graph.
    Intended for use in testing.

    Raises:
       DAGCircuitError: if DAGCircuit._multi_graph is inconsistent.
    """

    multi_graph = dag._multi_graph

    if dag._USE_RX:
        if not rx.is_directed_acyclic_graph(multi_graph):
            raise DAGCircuitError('multi_graph is not a DAG.')
    else:
        if not nx.is_directed_acyclic_graph(multi_graph):
            raise DAGCircuitError('multi_graph is not a DAG.')

    # Every node should be of type in, out, or op.
    # All input/output nodes should be present in input_map/output_map.
    for node in dag._get_multi_graph_nodes():
        if node.type == 'in':
            assert node is dag.input_map[node.wire]
        elif node.type == 'out':
            assert node is dag.output_map[node.wire]
        elif node.type == 'op':
            continue
        else:
            raise DAGCircuitError('Found node of unexpected type: {}'.format(
                node.type))

    # Shape of node.op should match shape of node.
    for node in dag.op_nodes():
        assert len(node.qargs) == node.op.num_qubits
        assert len(node.cargs) == node.op.num_clbits

    # Every edge should be labled with a known wire.
    edges_outside_wires = [
        edge_data['wire']
        for source, dest, edge_data in dag._get_multi_graph_edges()
        if edge_data['wire'] not in dag.wires
    ]
    if edges_outside_wires:
        raise DAGCircuitError('multi_graph contains one or more edges ({}) '
                              'not found in DAGCircuit.wires ({}).'.format(
                                  edges_outside_wires, dag.wires))

    # Every wire should have exactly one input node and one output node.
    for wire in dag.wires:
        in_node = dag.input_map[wire]
        out_node = dag.output_map[wire]

        assert in_node.wire == wire
        assert out_node.wire == wire
        assert in_node.type == 'in'
        assert out_node.type == 'out'

    # Every wire should be propagated by exactly one edge between nodes.
    for wire in dag.wires:
        cur_node_id = dag.input_map[wire]._node_id
        out_node_id = dag.output_map[wire]._node_id

        while cur_node_id != out_node_id:
            out_edges = dag._get_multi_graph_out_edges(cur_node_id)
            edges_to_follow = [(src, dest, data)
                               for (src, dest, data) in out_edges
                               if data['wire'] == wire]

            assert len(edges_to_follow) == 1
            cur_node_id = edges_to_follow[0][1]

    # Wires can only terminate at input/output nodes.
    for op_node in dag.op_nodes():
        assert multi_graph.in_degree(
            op_node._node_id) == multi_graph.out_degree(op_node._node_id)

    # Node input/output edges should match node qarg/carg/condition.
    for node in dag.op_nodes():
        in_edges = dag._get_multi_graph_in_edges(node._node_id)
        out_edges = dag._get_multi_graph_out_edges(node._node_id)

        in_wires = {data['wire'] for src, dest, data in in_edges}
        out_wires = {data['wire'] for src, dest, data in out_edges}

        node_cond_bits = set(
            node.condition[0][:] if node.condition is not None else [])
        node_qubits = set(node.qargs)
        node_clbits = set(node.cargs)

        all_bits = node_qubits | node_clbits | node_cond_bits

        assert in_wires == all_bits, 'In-edge wires {} != node bits {}'.format(
            in_wires, all_bits)
        assert out_wires == all_bits, 'Out-edge wires {} != node bits {}'.format(
            out_wires, all_bits)