예제 #1
0
 def test_all2all_connectivity_creation(self):
     hw = hardware_by_name({
         "hardware": {
             "gate_set": ["Cnot"],
             "num_qubits": 2,
             "qubit_connectivity": "All2All"
         }
     })
     self.assertTrue(isinstance(hw.qubit_connectivity, All2All))
예제 #2
0
    def test_add_2qubit_gate(self):
        # qubits 0 and 1 is connected
        hw = hardware_by_name({
            "hardware": {
                "gate_set": ["Cnot"],
                "num_qubits": 2,
                "adj_matrix": [[0, 1], [1, 0]]
            }
        })
        gate_chain = GateChain(hw)
        angle = 2 * np.pi / 30
        cnot = gate_by_name("Cnot")()
        rx30 = gate_by_name(f"Rx({angle})")()
        rz30 = gate_by_name(f"Rz({angle})")()

        gate_chain.add_gate(cnot, [0, 1])
        gate_chain.matrix
        gate_chain.add_gate(rx30, [0])
        gate_chain.matrix
        gate_chain.add_gate(rz30, [0])
        gate_chain.matrix
        gate_chain.add_gate(rx30, [0])
        gate_chain.matrix
        gate_chain.add_gate(rz30, [1])
        gate_chain.matrix
        gate_chain.add_gate(rx30, [1])
        gate_chain.matrix
        gate_chain.add_gate(rz30, [1])

        qiskit_circ = QuantumCircuit(2)
        qiskit_circ.cx(0, 1)

        qiskit_circ.rx(2 * np.pi / 30, 0)
        qiskit_circ.rz(2 * np.pi / 30, 0)
        qiskit_circ.rx(2 * np.pi / 30, 0)
        qiskit_circ.rz(2 * np.pi / 30, 1)
        qiskit_circ.rx(2 * np.pi / 30, 1)
        qiskit_circ.rz(2 * np.pi / 30, 1)

        qiskit_matrix = Operator(qiskit_circ).data
        np.testing.assert_almost_equal(gate_chain.matrix, qiskit_matrix)

        gate_chain.add_gate(cnot, [1, 0])
        gate_chain.add_gate(rx30, [0])
        gate_chain.add_gate(rz30, [1])

        qiskit_circ.cx(1, 0)
        qiskit_circ.rx(angle, 0)
        qiskit_circ.rz(angle, 1)

        qiskit_matrix = Operator(qiskit_circ).data
        np.testing.assert_almost_equal(gate_chain.matrix, qiskit_matrix)
예제 #3
0
 def test_1000_qubit_gate_chain_creation(self):
     # qubits 0 and 1 is not connected
     hw = hardware_by_name({
         "hardware": {
             "gate_set": ["Cnot"],
             "num_qubits": 1000,
             "adj_matrix": np.ones((1000, 1000)).tolist(),
         }
     })
     gate_chain = GateChain(hw)
     cnot = gate_by_name("Cnot")()
     gate_chain.add_gate(cnot, [0, 1])  # Apply CNOT gate to qubits 0 and 1
     gate_chain.add_gate(cnot, [1, 0])  # Apply CNOT gate to qubits 1 and 0
예제 #4
0
 def test_add_2qubit_gate_unconnected_force(self):
     # qubits 0 and 1 is not connected
     hw = hardware_by_name({
         "hardware": {
             "gate_set": ["Cnot"],
             "num_qubits": 2,
             "adj_matrix": [[0, 0], [0, 0]]
         }
     })
     gate_chain = GateChain(hw)
     cnot = gate_by_name("Cnot")()
     gate_chain.add_gate(
         cnot, [0, 1],
         force_connection=True)  # Apply CNOT gate to qubits 0 and 1
     gate_chain.add_gate(
         cnot, [1, 0],
         force_connection=True)  # Apply CNOT gate to qubits 1 and 0
예제 #5
0
 def test_add_2qubit_gate_unconnected(self):
     # qubits 0 and 1 is not connected
     hw = hardware_by_name({
         "hardware": {
             "gate_set": ["Cnot"],
             "num_qubits": 2,
             "adj_matrix": [[0, 0], [0, 0]]
         }
     })
     gate_chain = GateChain(hw)
     cnot = gate_by_name("Cnot")()
     with self.assertRaises(NoQubitConnectionError):
         gate_chain.add_gate(
             cnot, [0, 1]
         )  # Apply CNOT gate to unconnected qubits 0 and 1, must be an error
     with self.assertRaises(NoQubitConnectionError):
         gate_chain.add_gate(
             cnot, [1, 0]
         )  # Apply CNOT gate to unconnected qubits 1 and 0, must be an error
예제 #6
0
    def test_reverse_matrix_building_order(self):
        hw = hardware_by_name({
            "hardware": {
                "gate_set": ["Cnot"],
                "num_qubits": 2,
                "adj_matrix": [[0, 1], [1, 0]]
            }
        })
        gate_chain = GateChain(hw)
        cnot = gate_by_name("Cnot")()
        rx30 = gate_by_name("Rx(30)")()
        rz30 = gate_by_name("Rz(30)")()

        gate_chain.add_gate_left(cnot, [0, 1])
        gate_chain.matrix
        gate_chain.add_gate_left(rx30, [0])
        gate_chain.matrix
        gate_chain.add_gate_left(rz30, [0])
        gate_chain.matrix
        gate_chain.add_gate_left(rx30, [0])
        gate_chain.matrix
        gate_chain.add_gate_left(rz30, [1])
        gate_chain.matrix
        gate_chain.add_gate_left(rx30, [1])
        gate_chain.matrix
        gate_chain.add_gate_left(rz30, [1])

        np.testing.assert_almost_equal(gate_chain.matrix,
                                       gate_chain._calculate_matrix())

        gate_chain.add_gate_left(cnot, [0, 1])
        gate_chain.add_gate_left(rx30, [0])
        gate_chain.add_gate_left(rz30, [0])
        gate_chain.add_gate_left(rx30, [0])
        gate_chain.add_gate_left(rz30, [1])
        gate_chain.add_gate_left(rx30, [1])
        gate_chain.add_gate_left(rz30, [1])

        np.testing.assert_almost_equal(gate_chain.matrix,
                                       gate_chain._calculate_matrix())
예제 #7
0
    def __init__(self, config):
        super().__init__(config=config)
        self._quantum_hardware = hardware_by_name(self._cfg)
        self._actions = []
        self.two_qubit_actions = []
        self.id = 0

        try:
            self.depth_limit = self._cfg["depth_limit"]
        except KeyError:
            self.depth_limit = None

        try:
            self.two_qubit_gate_num_upper_bound = self._cfg[
                "two_qubit_gate_num_upper_bound"]
        except KeyError:
            self.two_qubit_gate_num_upper_bound = None

        try:
            self.two_qubit_gate_num_lower_bound = self._cfg[
                "two_qubit_gate_num_lower_bound"]
            assert self.two_qubit_gate_num_upper_bound is not None
            assert self.two_qubit_gate_num_upper_bound - self.two_qubit_gate_num_lower_bound >= 0
        except KeyError:
            self.two_qubit_gate_num_lower_bound = 0

        if self.two_qubit_gate_num_upper_bound is not None and self.depth_limit is not None:
            raise Exception(
                "'two_qubit_gate_num_upper_bound' and 'depth_limit' can not be specified simultaneously."
            )

        for gate_name, gate in self._quantum_hardware.gate_set.gates_by_name.items(
        ):
            for appy_to_qubits in itertools.permutations(
                    range(self._quantum_hardware.num_qubits), gate.num_qubits):
                if len(appy_to_qubits) > 1:
                    if not self._quantum_hardware.qubit_connectivity.check_connection(
                            appy_to_qubits):
                        continue

                action_name = gate_name + ("_{}" * len(appy_to_qubits)).format(
                    *appy_to_qubits)

                if gate.num_qubits == 2 and self.two_qubit_gate_num_upper_bound is not None:
                    self.two_qubit_actions.append(
                        (action_name, gate, appy_to_qubits))
                    continue

                self._actions.append((action_name, gate, appy_to_qubits))

        self._actions_probabilities = None
        try:
            if self._cfg["gate_distribution"] == "uniform":
                pass
            else:
                self._actions_probabilities = [None for a in self._actions]

                actions_per_gate = {}
                for action_name, gate, appy_to_qubits in self._actions:
                    try:
                        actions_per_gate[gate.__name__] += 1
                    except KeyError:
                        actions_per_gate[gate.__name__] = 1

                total_p = 0
                for i, a in enumerate(self._actions):
                    action_name, gate, appy_to_qubits = a

                    try:
                        p = self._cfg["gate_distribution"][
                            gate.__name__] / actions_per_gate[gate.__name__]
                        self._actions_probabilities[i] = p
                        total_p += p
                    except KeyError:
                        pass

                empty_p_cnt = sum([
                    1 if p is None else 0 for p in self._actions_probabilities
                ])

                if total_p > 1:
                    raise Exception(
                        "The sum of gates probabilies must be <= 1")
                if total_p != 1:
                    if empty_p_cnt == 0:
                        raise Exception(
                            "The sum of gates probabilies must be == 1")
                    else:
                        self._actions_probabilities = [
                            p if p is not None else (1 - total_p) / empty_p_cnt
                            for p in self._actions_probabilities
                        ]

                print(
                    "Actions probabilities:\n", {
                        a[0]: p
                        for a, p in zip(self._actions,
                                        self._actions_probabilities)
                    })

            if self.two_qubit_gate_num_upper_bound is not None and self._actions_probabilities is not None:
                raise Exception(
                    "'two_qubit_gate_num_upper_bound' and 'gate_distribution' can not be specified simultaneously."
                )

        except KeyError:
            pass
예제 #8
0
 def __init__(self, cfg):
     super().__init__(cfg)
     self.quantum_hardware = hardware_by_name(self._cfg)
 def __init__(self, cfg):
     super().__init__(cfg)
     self.quantum_hardware = hardware_by_name(self._cfg)
     self.qiskit_hardware = self.quantum_hardware.convert_to_qiskit_hardware(
     )