Пример #1
0
class TestOperation(unittest.TestCase):

    # Runs before all tests
    @classmethod
    def setUpClass(self) -> None:

        op_info = {
            'name': "SINGLE",
            'qids': ["qubit_1"],
            'cids': None,
            'gate': Operation.X,
            'gate_param': None,
            'pre_allocated_qubits': False,
            'computing_host_ids': ["QPU_1"]
        }

        self.operation = Operation(
            name=op_info['name'],
            qids=op_info['qids'],
            gate=op_info['gate'],
            computing_host_ids=op_info['computing_host_ids'])

        self._op_info = op_info

    # Runs after all tests
    @classmethod
    def tearDownClass(self) -> None:
        pass

    def test_instantiation(self):
        self.assertEqual(self.operation.name, "SINGLE")
        self.assertEqual(self.operation.gate, Operation.X)
        self.assertEqual(self.operation.computing_host_ids, ["QPU_1"])
        self.assertEqual(self.operation.get_dict(), self._op_info)
Пример #2
0
    def setUpClass(self) -> None:

        op_info = {
            'name': "SINGLE",
            'qids': ["qubit_1"],
            'cids': None,
            'gate': Operation.X,
            'gate_param': None,
            'pre_allocated_qubits': False,
            'computing_host_ids': ["QPU_1"]
        }

        self.operation = Operation(
            name=op_info['name'],
            qids=op_info['qids'],
            gate=op_info['gate'],
            computing_host_ids=op_info['computing_host_ids'])

        self._op_info = op_info
Пример #3
0
    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_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")
Пример #7
0
    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_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)
Пример #10
0
    def _replace_control_gates(control_gate_info: list, current_layer: Layer):
        """
        Replace control gates with a distributed version of the control gate
        over the different computing hosts

        Args:
            control_gate_info (list): List of information regarding control
                gates present in one layer
            current_layer (Layer): Layer object in which the control gates
                are present
        """

        max_gates = 0
        for gate_info in control_gate_info:
            max_gates = max(len(gate_info['operations']), max_gates)

        circuit_len = Constants.DISTRIBUTED_CONTROL_CIRCUIT_LEN + max_gates
        operations = [[] for _ in range(circuit_len)]

        for gate_info in control_gate_info:
            control_qubit = gate_info['control_qubit']
            control_host = gate_info['computing_hosts'][0]
            target_host = gate_info['computing_hosts'][1]

            epr_qubit_id = str(uuid.uuid4())
            bit_id_1, bit_id_2 = str(uuid.uuid4()), str(uuid.uuid4())

            # Generate new EPR pair (counted in the pre-allocated qubits) for the
            # two computing hosts
            op_1 = Operation(name=Constants.SEND_ENT,
                             qids=[epr_qubit_id],
                             computing_host_ids=[control_host, target_host],
                             pre_allocated_qubits=True)

            op_2 = Operation(name=Constants.REC_ENT,
                             qids=[epr_qubit_id],
                             computing_host_ids=[target_host, control_host],
                             pre_allocated_qubits=True)

            current_layer.add_operations([op_1, op_2])

            # Circuit to implement distributed control gate
            itr = 0
            op_1 = Operation(name=Constants.TWO_QUBIT,
                             qids=[control_qubit, epr_qubit_id],
                             gate=Operation.CNOT,
                             computing_host_ids=[control_host])
            operations[itr].extend([op_1])

            itr += 1
            op_1 = Operation(name=Constants.MEASURE,
                             qids=[epr_qubit_id],
                             cids=[bit_id_1],
                             computing_host_ids=[control_host])
            operations[itr].extend([op_1])

            itr += 1
            op_1 = Operation(name=Constants.SEND_CLASSICAL,
                             cids=[bit_id_1],
                             computing_host_ids=[control_host, target_host])

            op_2 = Operation(name=Constants.REC_CLASSICAL,
                             cids=[bit_id_1],
                             computing_host_ids=[target_host, control_host])
            operations[itr].extend([op_1, op_2])

            itr += 1
            op_1 = Operation(name=Constants.CLASSICAL_CTRL_GATE,
                             qids=[epr_qubit_id],
                             cids=[bit_id_1],
                             gate=Operation.X,
                             computing_host_ids=[target_host])
            operations[itr].extend([op_1])

            # The control gate we are trying to implement
            for op in gate_info['operations'][::-1]:
                itr += 1
                op_1 = Operation(name=Constants.TWO_QUBIT,
                                 qids=[epr_qubit_id,
                                       op.get_target_qubit()],
                                 gate=op.gate,
                                 gate_param=op.gate_param,
                                 computing_host_ids=[target_host])
                operations[itr].extend([op_1])

            itr += 1
            op_1 = Operation(name=Constants.SINGLE,
                             qids=[epr_qubit_id],
                             gate=Operation.H,
                             computing_host_ids=[target_host])
            operations[itr].extend([op_1])

            itr += 1
            op_1 = Operation(name=Constants.MEASURE,
                             qids=[epr_qubit_id],
                             cids=[bit_id_2],
                             computing_host_ids=[target_host])
            operations[itr].extend([op_1])

            itr += 1
            op_1 = Operation(name=Constants.SEND_CLASSICAL,
                             cids=[bit_id_2],
                             computing_host_ids=[target_host, control_host])

            op_2 = Operation(name=Constants.REC_CLASSICAL,
                             cids=[bit_id_2],
                             computing_host_ids=[control_host, target_host])
            operations[itr].extend([op_1, op_2])

            itr += 1
            op_1 = Operation(name=Constants.CLASSICAL_CTRL_GATE,
                             qids=[control_qubit],
                             cids=[bit_id_2],
                             gate=Operation.Z,
                             computing_host_ids=[control_host])
            operations[itr].extend([op_1])

        # Make the new layers from the operations
        distributed_layers = []
        if control_gate_info:
            for ops in operations:
                layer = Layer(ops)
                distributed_layers.append(layer)

        return current_layer, distributed_layers