def test_cnot_4(self): """ Test with a different input type """ q_map = { 'QPU_1': ['q_1'], 'QPU_2': ['q_2'], 'QPU_3': ['q_3']} q_1 = Qubit(computing_host_id="QPU_1", q_id="q_1") q_2 = Qubit(computing_host_id="QPU_2", q_id="q_2") q_3 = Qubit(computing_host_id="QPU_3", q_id="q_3") q_1.single(gate=Operation.X) q_1.two_qubit(gate=Operation.CNOT, target_qubit=q_2) q_2.two_qubit(gate=Operation.CNOT, target_qubit=q_3) q_1.measure(bit_id=q_1.q_id) q_2.measure(bit_id=q_2.q_id) q_3.measure(bit_id=q_3.q_id) circuit = Circuit(q_map, qubits=[q_1, q_2, q_3]) def controller_host_protocol(host): host.generate_and_send_schedules(circuit) host.receive_results() def computing_host_protocol(host): host.receive_schedule() host.send_results() for i in range(1): self.controller_host.run_protocol(controller_host_protocol) self.computing_host_1.run_protocol(computing_host_protocol) self.computing_host_2.run_protocol(computing_host_protocol) self.computing_host_3.run_protocol(computing_host_protocol) time.sleep(20) self.assertEqual(self.clock._maximum_ticks, 23) self.assertEqual(self.computing_host_1._bits['q_1'], 1) self.assertEqual(self.computing_host_2._bits['q_2'], 1) self.assertEqual(self.computing_host_3._bits['q_3'], 1) results = self.controller_host._results self.assertEqual(results['QPU_1']['type'], 'measurement_result') self.assertEqual(results['QPU_1']['val']['q_1'], 1) self.assertEqual(results['QPU_2']['val']['q_2'], 1)
def test_distributed_scheduler(self): self.controller_host.connect_host("QPU_2") q_map = { 'QPU_1': ['qubit_1', 'qubit_2'], 'QPU_2': ['qubit_2', 'qubit_4'] } # Form layer 1 op_1 = Operation(name="SINGLE", qids=["qubit_1"], gate=Operation.H, computing_host_ids=["QPU_1"]) op_2 = Operation(name="SEND_ENT", qids=["qubit_2"], computing_host_ids=["QPU_1", "QPU_2"]) op_3 = Operation(name="REC_ENT", qids=["qubit_2"], computing_host_ids=["QPU_2", "QPU_1"]) layer_1 = Layer([op_1, op_2, op_3]) # Form layer 2 op_1 = Operation(name="TWO_QUBIT", qids=["qubit_2", "qubit_4"], gate=Operation.CNOT, computing_host_ids=["QPU_2"]) layer_2 = Layer([op_1]) # Form layer 3 op_1 = Operation(name="MEASURE", qids=["qubit_2"], cids=["bit_1"], computing_host_ids=["QPU_2"]) layer_3 = Layer([op_1]) # Form layer 4 op_1 = Operation(name="SEND_CLASSICAL", cids=["bit_1"], computing_host_ids=["QPU_2", "QPU_1"]) op_2 = Operation(name="REC_CLASSICAL", cids=["bit_1"], computing_host_ids=["QPU_1", "QPU_2"]) layer_4 = Layer([op_1, op_2]) # Form layer 5 op_1 = Operation(name="CLASSICAL_CTRL_GATE", qids=["qubit_1"], cids=["bit_1"], gate=Operation.X, computing_host_ids=["QPU_1"]) layer_5 = Layer([op_1]) layers = [layer_1, layer_2, layer_3, layer_4, layer_5] circuit = Circuit(q_map, layers) computing_host_schedules, max_execution_time = self.controller_host._create_distributed_schedules( circuit) self.assertEqual(len(computing_host_schedules), 2) self.assertEqual(len(computing_host_schedules['QPU_1']), 4) self.assertEqual(len(computing_host_schedules['QPU_2']), 4) self.assertEqual(max_execution_time, 5) self.assertEqual(computing_host_schedules['QPU_1'][0]['name'], "SINGLE") self.assertEqual(computing_host_schedules['QPU_1'][0]['layer_end'], 0) self.assertEqual(computing_host_schedules['QPU_1'][1]['name'], "SEND_ENT") self.assertEqual(computing_host_schedules['QPU_1'][1]['layer_end'], 0) self.assertEqual(computing_host_schedules['QPU_1'][2]['name'], "REC_CLASSICAL") self.assertEqual(computing_host_schedules['QPU_1'][2]['layer_end'], 3) self.assertEqual(computing_host_schedules['QPU_1'][3]['name'], "CLASSICAL_CTRL_GATE") self.assertEqual(computing_host_schedules['QPU_1'][3]['layer_end'], 4) self.assertEqual(computing_host_schedules['QPU_2'][0]['name'], "REC_ENT") self.assertEqual(computing_host_schedules['QPU_2'][0]['layer_end'], 0) self.assertEqual(computing_host_schedules['QPU_2'][1]['name'], "TWO_QUBIT") self.assertEqual(computing_host_schedules['QPU_2'][1]['layer_end'], 1) self.assertEqual(computing_host_schedules['QPU_2'][2]['name'], "MEASURE") self.assertEqual(computing_host_schedules['QPU_2'][2]['layer_end'], 2) self.assertEqual(computing_host_schedules['QPU_2'][3]['name'], "SEND_CLASSICAL") self.assertEqual(computing_host_schedules['QPU_2'][3]['layer_end'], 3)
def test_monolithic_to_distributed_circuit_algorithm_2(self): self.controller_host.connect_hosts( ["QPU_2", "QPU_3", "QPU_4", "QPU_5"]) q_map = { 'QPU_1': ['qubit_1', 'qubit_3', 'qubit_4'], 'QPU_2': ['qubit_2'], 'QPU_3': ['qubit_5'], 'QPU_4': ['qubit_6'], 'QPU_5': ['qubit_7'] } # Form layer 1 op_1 = Operation(name="SINGLE", qids=["qubit_1"], gate=Operation.H, computing_host_ids=["QPU_1"]) layer_1 = Layer([op_1]) # Form layer 2 op_1 = Operation(name="TWO_QUBIT", qids=["qubit_2", "qubit_1"], gate=Operation.CNOT, computing_host_ids=["QPU_2", "QPU_1"]) op_2 = Operation(name="TWO_QUBIT", qids=["qubit_5", "qubit_6"], gate=Operation.CNOT, computing_host_ids=["QPU_3", "QPU_4"]) op_3 = Operation(name="SINGLE", qids=["qubit_7"], gate=Operation.H, computing_host_ids=["QPU_5"]) layer_2 = Layer([op_1, op_2, op_3]) # Form layer 3 op_1 = Operation(name="TWO_QUBIT", qids=["qubit_2", "qubit_3"], gate=Operation.CNOT, computing_host_ids=["QPU_2", "QPU_1"]) layer_3 = Layer([op_1]) # Form layer 4 op_1 = Operation(name="TWO_QUBIT", qids=["qubit_2", "qubit_4"], gate=Operation.CNOT, computing_host_ids=["QPU_2", "QPU_1"]) layer_4 = Layer([op_1]) # Form layer 5 op_1 = Operation(name="TWO_QUBIT", qids=["qubit_1", "qubit_6"], gate=Operation.CNOT, computing_host_ids=["QPU_1", "QPU_4"]) layer_5 = Layer([op_1]) layers = [layer_1, layer_2, layer_3, layer_4, layer_5] circuit = Circuit(q_map, layers) distributed_circuit = self.controller_host._generate_distributed_circuit( circuit) layers = distributed_circuit.layers self.assertEqual(len(layers), 23) self.assertEqual(layers[0].operations[0].name, "SINGLE") layer_op_names = [i.name for i in layers[1].operations] self.assertEqual( layer_op_names, ['SINGLE', 'SEND_ENT', 'REC_ENT', 'SEND_ENT', 'REC_ENT']) layer_op_names = [i.name for i in layers[2].operations] self.assertEqual(layer_op_names, ["TWO_QUBIT", "TWO_QUBIT"]) self.assertEqual(layers[6].operations[0].name, "TWO_QUBIT") self.assertEqual(layers[6].operations[1].name, "TWO_QUBIT") self.assertEqual(layers[7].operations[0].name, "TWO_QUBIT") self.assertEqual(layers[7].operations[1].name, "SINGLE") self.assertEqual(layers[8].operations[0].name, "TWO_QUBIT") layer_op_names = [i.name for i in layers[11].operations] self.assertEqual(layer_op_names, ['SEND_CLASSICAL', 'REC_CLASSICAL']) layer_op_names = [i.name for i in layers[13].operations] self.assertEqual(layer_op_names, ['SEND_ENT', 'REC_ENT']) self.assertEqual(layers[22].operations[0].name, "CLASSICAL_CTRL_GATE")
def test_monolithic_to_distributed_circuit_algorithm_1(self): self.controller_host.connect_host("QPU_2") q_map = { 'QPU_1': ['qubit_1', 'qubit_2'], 'QPU_2': ['qubit_3', 'qubit_4'], 'QPU_3': ['qubit_5'] } # Form layer 1 op_1 = Operation(name="SINGLE", qids=["qubit_1"], gate=Operation.H, computing_host_ids=["QPU_1"]) op_2 = Operation(name="SINGLE", qids=["qubit_3"], gate=Operation.H, computing_host_ids=["QPU_2"]) op_3 = Operation(name="SINGLE", qids=["qubit_3"], gate=Operation.H, computing_host_ids=["QPU_3"]) layer_1 = Layer([op_1, op_2, op_3]) # Form layer 2 op_1 = Operation(name="TWO_QUBIT", qids=["qubit_3", "qubit_1"], gate=Operation.CNOT, computing_host_ids=["QPU_2", "QPU_1"]) op_2 = Operation(name="SINGLE", qids=["qubit_3"], gate=Operation.X, computing_host_ids=["QPU_3"]) layer_2 = Layer([op_1, op_2]) # Form layer 3 op_1 = Operation(name="MEASURE", qids=["qubit_3"], cids=["bit_1"], computing_host_ids=["QPU_2"]) layer_3 = Layer([op_1]) layers = [layer_1, layer_2, layer_3] circuit = Circuit(q_map, layers) distributed_circuit = self.controller_host._generate_distributed_circuit( circuit) self.assertEqual(len(distributed_circuit.layers), 12) self.assertEqual(len(distributed_circuit.layers[0].operations), 3) self.assertEqual(len(distributed_circuit.layers[1].operations), 3) self.assertEqual(distributed_circuit.layers[1].operations[0].name, "SINGLE") self.assertEqual(distributed_circuit.layers[1].operations[1].name, "SEND_ENT") self.assertEqual(distributed_circuit.layers[1].operations[2].name, "REC_ENT") self.assertEqual(distributed_circuit.layers[2].operations[0].name, "TWO_QUBIT") self.assertEqual(distributed_circuit.layers[10].operations[0].name, "CLASSICAL_CTRL_GATE") self.assertEqual(distributed_circuit.layers[11].operations[0].name, "MEASURE")
class TestCircuit(unittest.TestCase): # Runs before all tests @classmethod def setUpClass(self) -> None: pass # Runs after all tests @classmethod def tearDownClass(self) -> None: pass def setUp(self): q_map = {'QPU_1': ['qubit_1', 'qubit_3'], 'QPU_2': ['qubit_2']} self._circuit = Circuit(q_map, layers=[]) self._q_map = q_map def tearDown(self): del self._circuit def test_instantiation(self): self.assertEqual(self._circuit.total_qubits(), 3) self.assertEqual(self._circuit.q_map, self._q_map) self.assertEqual(self._circuit.layers, []) self._circuit.add_new_qubit({'QPU_2': ['qubit_4']}) self.assertEqual(self._circuit.total_qubits(), 4) operations = [ Operation(name="SINGLE", qids=["qubit_1"], gate=Operation.X, computing_host_ids=["QPU_1"]) ] layer = Layer(operations) self._circuit.add_layer_to_circuit(layer) self.assertNotEqual(self._circuit.layers, []) self.assertEqual(self._circuit.layers[0].operations[0].name, "SINGLE") def test_control_gate_info(self): self._circuit.add_new_qubit({'QPU_1': ['qubit_4']}) self._circuit.add_new_qubit({'QPU_3': ['qubit_5']}) self._circuit.add_new_qubit({'QPU_4': ['qubit_6']}) self.assertEqual(self._circuit.total_qubits(), 6) op_1 = Operation(name="TWO_QUBIT", qids=["qubit_2", "qubit_1"], gate=Operation.CNOT, computing_host_ids=["QPU_2", "QPU_1"]) op_2 = Operation(name="TWO_QUBIT", qids=["qubit_5", "qubit_6"], gate=Operation.CNOT, computing_host_ids=["QPU_3", "QPU_4"]) layer_1 = Layer([op_1, op_2]) op_1 = Operation(name="TWO_QUBIT", qids=["qubit_2", "qubit_3"], gate=Operation.CNOT, computing_host_ids=["QPU_2", "QPU_1"]) layer_2 = Layer([op_1]) op_1 = Operation(name="TWO_QUBIT", qids=["qubit_2", "qubit_4"], gate=Operation.CNOT, computing_host_ids=["QPU_2", "QPU_1"]) layer_3 = Layer([op_1]) op_1 = Operation(name="TWO_QUBIT", qids=["qubit_6", "qubit_1"], gate=Operation.CNOT, computing_host_ids=["QPU_4", "QPU_1"]) layer_4 = Layer([op_1]) self._circuit.add_layer_to_circuit(layer_1) self._circuit.add_layer_to_circuit(layer_2) self._circuit.add_layer_to_circuit(layer_3) self._circuit.add_layer_to_circuit(layer_4) control_gate_info = self._circuit.control_gate_info() self.assertEqual(len(control_gate_info[0]), 2) self.assertEqual(control_gate_info[0][0]['computing_hosts'], ['QPU_2', 'QPU_1']) self.assertEqual(control_gate_info[1], []) self.assertEqual(control_gate_info[2], []) self.assertEqual(len(control_gate_info[0][1]['operations']), 1) test_operations = control_gate_info[0][0]['operations'] self.assertEqual(len(test_operations), 3) self.assertEqual(test_operations[0].get_target_qubit(), 'qubit_4') self.assertEqual(test_operations[1].get_target_qubit(), 'qubit_3') self.assertEqual(test_operations[2].get_target_qubit(), 'qubit_1') self.assertEqual(control_gate_info[0][0]['control_qubit'], 'qubit_2') self.assertEqual(control_gate_info[3][0]['control_qubit'], 'qubit_6') def test_creating_layers(self): q_1 = Qubit(computing_host_id='QPU_1', q_id='qubit_1') q_2 = Qubit(computing_host_id='QPU_2', q_id='qubit_2') q_3 = Qubit(computing_host_id='QPU_1', q_id='qubit_3') q_1.single(gate=Operation.X) q_2.single(gate=Operation.X) q_1.single(gate=Operation.H) q_3.single(gate=Operation.H) q_1.two_qubit(gate=Operation.CNOT, target_qubit=q_3) self._circuit.create_layers(qubits=[q_1, q_2, q_3]) layers = self._circuit.layers op_names = [op.name for op in layers[0].operations] self.assertEqual( op_names, ['PREPARE_QUBITS', 'PREPARE_QUBITS', 'PREPARE_QUBITS']) op_names = [op.name for op in layers[1].operations] self.assertEqual(op_names, ['SINGLE', 'SINGLE', 'SINGLE']) op_names = [op.name for op in layers[2].operations] self.assertEqual(op_names, ['SINGLE']) op_names = [op.name for op in layers[3].operations] self.assertEqual(op_names, ['TWO_QUBIT'])
def setUp(self): q_map = {'QPU_1': ['qubit_1', 'qubit_3'], 'QPU_2': ['qubit_2']} self._circuit = Circuit(q_map, layers=[]) self._q_map = q_map
def test_cnot_1(self): q_map = { 'QPU_1': ['qubit_1'], 'QPU_2': ['qubit_2']} # TODO: Maybe layer one is always like this # Form layer 1 op_1 = Operation( name="PREPARE_QUBITS", qids=["qubit_1"], computing_host_ids=["QPU_1"]) op_2 = Operation( name="PREPARE_QUBITS", qids=["qubit_2"], computing_host_ids=["QPU_2"]) layer_1 = Layer([op_1, op_2]) # TODO: For operations, can the name and computing host ids be found from # the gate name and qubit id? That would simplify the inputs # We could have an OperationFactory object that takes the topology as input # and then it can generate the operations using those two points # Form layer 2 op_1 = Operation( name="SINGLE", qids=["qubit_1"], gate=Operation.X, computing_host_ids=["QPU_1"]) op_2 = Operation( name="SINGLE", qids=["qubit_2"], gate=Operation.X, computing_host_ids=["QPU_2"]) layer_2 = Layer([op_1, op_2]) # Form layer 3 op_1 = Operation( name="TWO_QUBIT", qids=["qubit_1", "qubit_2"], gate=Operation.CNOT, computing_host_ids=["QPU_1", "QPU_2"]) layer_3 = Layer([op_1]) # Form layer 4 op_1 = Operation( name="MEASURE", qids=["qubit_1"], cids=["qubit_1"], computing_host_ids=["QPU_1"]) op_2 = Operation( name="MEASURE", qids=["qubit_2"], cids=["qubit_2"], computing_host_ids=["QPU_2"]) layer_4 = Layer([op_1, op_2]) layers = [layer_1, layer_2, layer_3, layer_4] circuit = Circuit(q_map, layers) def controller_host_protocol(host): host.generate_and_send_schedules(circuit) host.receive_results() def computing_host_protocol(host): host.receive_schedule() host.send_results() for i in range(1): self.controller_host.run_protocol(controller_host_protocol) self.computing_host_1.run_protocol(computing_host_protocol) self.computing_host_2.run_protocol(computing_host_protocol) time.sleep(12) self.assertEqual(self.clock._maximum_ticks, 13) self.assertEqual(self.computing_host_1._bits['qubit_1'], 1) self.assertEqual(self.computing_host_2._bits['qubit_2'], 0) self.assertEqual(self.controller_host._results['QPU_1']['qubit_1'], 1) self.assertEqual(self.controller_host._results['QPU_2']['qubit_2'], 0)
def test_cnot_3(self): q_map = { 'QPU_1': ['qubit_1'], 'QPU_2': ['qubit_2'], 'QPU_3': ['qubit_3']} # Form layer 1 op_1 = Operation( name="PREPARE_QUBITS", qids=["qubit_1"], computing_host_ids=["QPU_1"]) op_2 = Operation( name="PREPARE_QUBITS", qids=["qubit_2"], computing_host_ids=["QPU_2"]) op_3 = Operation( name="PREPARE_QUBITS", qids=["qubit_3"], computing_host_ids=["QPU_3"]) layer_1 = Layer([op_1, op_2, op_3]) # Form layer 2 op_1 = Operation( name="SINGLE", qids=["qubit_1"], gate=Operation.X, computing_host_ids=["QPU_1"]) layer_2 = Layer([op_1]) # Form layer 3 op_1 = Operation( name="TWO_QUBIT", qids=["qubit_1", "qubit_2"], gate=Operation.CNOT, computing_host_ids=["QPU_1", "QPU_2"]) layer_3 = Layer([op_1]) # Form layer 4 op_1 = Operation( name="TWO_QUBIT", qids=["qubit_2", "qubit_3"], gate=Operation.CNOT, computing_host_ids=["QPU_2", "QPU_3"]) layer_4 = Layer([op_1]) # Form layer 4 op_1 = Operation( name="MEASURE", qids=["qubit_1"], cids=["qubit_1"], computing_host_ids=["QPU_1"]) op_2 = Operation( name="MEASURE", qids=["qubit_2"], cids=["qubit_2"], computing_host_ids=["QPU_2"]) op_3 = Operation( name="MEASURE", qids=["qubit_3"], cids=["qubit_3"], computing_host_ids=["QPU_3"]) layer_5 = Layer([op_1, op_2, op_3]) layers = [layer_1, layer_2, layer_3, layer_4, layer_5] circuit = Circuit(q_map, layers) def controller_host_protocol(host): host.generate_and_send_schedules(circuit) host.receive_results() def computing_host_protocol(host): host.receive_schedule() host.send_results() for i in range(1): self.controller_host.run_protocol(controller_host_protocol) self.computing_host_1.run_protocol(computing_host_protocol) self.computing_host_2.run_protocol(computing_host_protocol) self.computing_host_3.run_protocol(computing_host_protocol) time.sleep(18) self.assertEqual(self.clock._maximum_ticks, 23) self.assertEqual(self.computing_host_1._bits['qubit_1'], 1) self.assertEqual(self.computing_host_2._bits['qubit_2'], 1) self.assertEqual(self.computing_host_3._bits['qubit_3'], 1) results = self.controller_host._results self.assertEqual(results['QPU_1']['type'], 'measurement_result') self.assertEqual(results['QPU_1']['val']['qubit_1'], 1) self.assertEqual(results['QPU_2']['val']['qubit_2'], 1) self.assertEqual(results['QPU_3']['val']['qubit_3'], 1)