Esempio n. 1
0
def inverse_quantum_fourier_transform(q_ids, computing_host_ids, layers):
    """
    Performs inverse quantum fourier transform
    """

    q_ids.reverse()

    for i in range(len(q_ids)):
        target_qubit_id = q_ids[i]

        for j in range(i):
            control_qubit_id = q_ids[j]

            op = Operation(name=Constants.TWO_QUBIT,
                           qids=[control_qubit_id, target_qubit_id],
                           gate=Operation.CUSTOM_CONTROLLED,
                           gate_param=phase_gate(-np.pi * (2**j) / (2**i)),
                           computing_host_ids=[computing_host_ids[0]])
            layers.append(Layer([op]))

        op = Operation(name=Constants.SINGLE,
                       qids=[target_qubit_id],
                       gate=Operation.H,
                       computing_host_ids=[computing_host_ids[0]])
        layers.append(Layer([op]))
    return layers
Esempio n. 2
0
def create_circuit(q_map):
    """
    Create the necessary circuit here
    """
    layers = []
    computing_host_ids = list(q_map.keys())

    # Circuit input should be added

    # Prepare the qubits on both computing hosts
    ops = []
    for host_id in computing_host_ids:
        op = Operation(name=Constants.PREPARE_QUBITS,
                       qids=q_map[host_id],
                       computing_host_ids=[host_id])
        ops.append(op)

    layers.append(Layer(ops))

    # Put qubit "q_0_0" in |1> state
    op = Operation(name=Constants.SINGLE,
                   qids=[q_map[computing_host_ids[0]][0]],
                   gate=Operation.X,
                   computing_host_ids=[computing_host_ids[0]])
    ops.append(op)

    layers.append(Layer(ops))

    # Apply cnot gate from "q_0_0" to "q_1_0"
    control_qubit_id = q_map[computing_host_ids[0]][0]
    target_qubit_id = q_map[computing_host_ids[1]][0]

    op = Operation(name=Constants.TWO_QUBIT,
                   qids=[control_qubit_id, target_qubit_id],
                   gate=Operation.CNOT,
                   computing_host_ids=computing_host_ids)
    layers.append(Layer([op]))

    # Measure the qubits
    ops = []
    for host_id in computing_host_ids:
        op = Operation(name=Constants.MEASURE,
                       qids=[q_map[host_id][0]],
                       cids=[q_map[host_id][0]],
                       computing_host_ids=[host_id])
        ops.append(op)
    layers.append(Layer(ops))

    circuit = Circuit(q_map, layers)
    return circuit
Esempio n. 3
0
def quantum_phase_estimation_circuit(q_map, client_input_gate):
    """
    Returns the monolithic circuit for quantum phase estimation
    algorithm
    """
    layers = []
    computing_host_ids = list(q_map.keys())

    # Prepare the qubits on both computing hosts
    ops = []
    for host_id in computing_host_ids:
        op = Operation(name=Constants.PREPARE_QUBITS,
                       qids=q_map[host_id],
                       computing_host_ids=[host_id])
        ops.append(op)

    layers.append(Layer(ops))

    # Setup the qubits by apply Hadamard gates on qubits of QPU_1
    # and applying X gate to initialise qubit on QPU_2
    ops = []
    for q_id in q_map[computing_host_ids[0]]:
        op = Operation(name=Constants.SINGLE,
                       qids=[q_id],
                       gate=Operation.H,
                       computing_host_ids=[computing_host_ids[0]])
        ops.append(op)

    op = Operation(name=Constants.SINGLE,
                   qids=[q_map[computing_host_ids[1]][0]],
                   gate=Operation.X,
                   computing_host_ids=[computing_host_ids[1]])
    ops.append(op)

    layers.append(Layer(ops))

    # Apply controlled unitaries
    for i in range(len(q_map[computing_host_ids[0]])):
        max_iter = 2**i
        control_qubit_id = q_map[computing_host_ids[0]][i]
        target_qubit_id = q_map[computing_host_ids[1]][0]

        for _ in range(max_iter):
            op = Operation(name=Constants.TWO_QUBIT,
                           qids=[control_qubit_id, target_qubit_id],
                           gate=Operation.CUSTOM_CONTROLLED,
                           gate_param=client_input_gate,
                           computing_host_ids=computing_host_ids)
            layers.append(Layer([op]))

    # Inverse Fourier Transform circuit
    q_ids = q_map[computing_host_ids[0]].copy()
    layers = inverse_quantum_fourier_transform(q_ids, computing_host_ids,
                                               layers)

    # Measure the qubits
    ops = []
    for q_id in q_ids:
        op = Operation(name=Constants.MEASURE,
                       qids=[q_id],
                       cids=[q_id],
                       computing_host_ids=[computing_host_ids[0]])
        ops.append(op)
    layers.append(Layer(ops))

    circuit = Circuit(q_map, layers)
    return circuit
Esempio n. 4
0
def main():
    network = Network.get_instance()
    network.delay = 0.1
    network.start()

    clock = Clock()

    controller_host = ControllerHost(
        host_id="host_1",
        clock=clock,
    )
    computing_hosts, q_map = controller_host.create_distributed_network(
        num_computing_hosts=2, num_qubits_per_host=10)

    controller_host.start()
    network.add_hosts(
        [computing_hosts[0], computing_hosts[1], controller_host])
    layers = []
    op_1 = Operation(name="PREPARE_QUBITS",
                     qids=["q_0_0"],
                     computing_host_ids=["QPU_0"])
    op_2 = Operation(name="PREPARE_QUBITS",
                     qids=["q_1_0"],
                     computing_host_ids=["QPU_1"])

    layers.append(Layer([op_1, op_2]))
    op_1 = Operation(name="SINGLE",
                     qids=["q_0_0"],
                     gate=Operation.I,
                     computing_host_ids=["QPU_0"])

    layers.append(Layer([op_1]))

    op_1 = Operation(name="TWO_QUBIT",
                     qids=["q_0_0", "q_1_0"],
                     gate=Operation.CNOT,
                     computing_host_ids=["QPU_0", "QPU_1"])
    layers.append(Layer([op_1]))

    op_1 = Operation(name="MEASURE",
                     qids=["q_0_0"],
                     cids=["q_0_0"],
                     computing_host_ids=["QPU_0"])

    op_2 = Operation(name="MEASURE",
                     qids=["q_1_0"],
                     cids=["q_1_0"],
                     computing_host_ids=["QPU_1"])
    layers.append(Layer([op_1, op_2]))

    circuit = Circuit(q_map, layers)

    def controller_host_protocol(host):
        host.generate_and_send_schedules(circuit)
        host.receive_results()
        print(host.results)

    def computing_host_protocol(host):
        host.receive_schedule()
        host.send_results()
        print(host.host_id, host.bits)

    print('starting...')
    t = controller_host.run_protocol(controller_host_protocol)
    computing_hosts[0].run_protocol(computing_host_protocol)
    g = computing_hosts[1].run_protocol(computing_host_protocol)
    t.join()
    g.join()
    network.stop(True)