예제 #1
0
def test_get_engine_sampler(monkeypatch):
    monkeypatch.setenv('GOOGLE_CLOUD_PROJECT', 'myproj')

    with mock.patch.object(
        cirq_google.engine.client.quantum, 'QuantumEngineServiceClient', autospec=True
    ):
        sampler = cg.get_engine_sampler(processor_id='hi mom', gate_set_name='sqrt_iswap')
    assert hasattr(sampler, 'run_sweep')

    with pytest.raises(ValueError):
        sampler = cg.get_engine_sampler(processor_id='hi mom', gate_set_name='ccz')
예제 #2
0
def test_get_engine_sampler():
    with mock.patch.object(cirq_google.engine.client.quantum,
                           'QuantumEngineServiceClient',
                           autospec=True):
        with mock.patch('google.auth.default', lambda: (None, 'myproj')):
            sampler = cg.get_engine_sampler(processor_id='hi mom',
                                            gate_set_name='sqrt_iswap')
    assert hasattr(sampler, 'run_sweep')

    with pytest.raises(ValueError):
        sampler = cg.get_engine_sampler(processor_id='hi mom',
                                        gate_set_name='ccz')
예제 #3
0
def test_get_engine_sampler():
    with mock.patch.object(cirq_google.cloud.quantum,
                           'QuantumEngineServiceClient',
                           autospec=True):
        with mock.patch('google.auth.default', lambda: (None, 'myproj')):
            sampler = cg.get_engine_sampler(processor_id='hi mom')
    assert hasattr(sampler, 'run_sweep')
예제 #4
0
def test_get_engine_sampler_explicit_project_id():
    with mock.patch.object(cirq_google.cloud.quantum,
                           'QuantumEngineServiceClient',
                           autospec=True):
        sampler = cg.get_engine_sampler(processor_id='hi mom',
                                        project_id='myproj')
    assert hasattr(sampler, 'run_sweep')
예제 #5
0
def get_qcs_objects_for_notebook(
        project_id: Optional[str] = None,
        processor_id: Optional[str] = None) -> QCSObjectsForNotebook:
    """Authenticates on Google Cloud, can return a Device and Simulator.

    Args:
        project_id: Optional explicit Google Cloud project id. Otherwise,
            this defaults to the environment variable GOOGLE_CLOUD_PROJECT.
            By using an environment variable, you can avoid hard-coding
            personal project IDs in shared code.
        processor_id: Engine processor ID (from Cloud console or
            ``Engine.list_processors``).

    Returns:
        An instance of DeviceSamplerInfo.
    """

    # Converting empty strings to None for form field inputs
    if project_id == "":
        project_id = None
    if processor_id == "":
        processor_id = None

    google_cloud_signin_failed: bool = False
    if project_id is None:
        if 'GOOGLE_CLOUD_PROJECT' not in os.environ:
            print(
                "No project_id provided and environment variable GOOGLE_CLOUD_PROJECT not set."
            )
            google_cloud_signin_failed = True
    else:  # pragma: no cover
        os.environ['GOOGLE_CLOUD_PROJECT'] = project_id

        # Following code runs the user through the Colab OAuth process.

        # Checks for Google Application Default Credentials and runs
        # interactive login if the notebook is executed in Colab. In
        # case the notebook is executed in Jupyter notebook or other
        # IPython runtimes, no interactive login is provided, it is
        # assumed that the `GOOGLE_APPLICATION_CREDENTIALS` env var is
        # set or `gcloud auth application-default login` was executed
        # already. For more information on using Application Default Credentials
        # see https://cloud.google.com/docs/authentication/production

        in_colab = False
        try:
            from IPython import get_ipython

            in_colab = 'google.colab' in str(get_ipython())

            if in_colab:
                from google.colab import auth

                print("Getting OAuth2 credentials.")
                print("Press enter after entering the verification code.")
                auth.authenticate_user(clear_output=False)
                print("Authentication complete.")
            else:
                print("Notebook isn't executed with Colab, assuming "
                      "Application Default Credentials are setup.")
        except:
            pass

        # End of Google Colab Authentication segment

    device: cirq.Device
    sampler: Union[PhasedFSimEngineSimulator, QuantumEngineSampler]
    if google_cloud_signin_failed or processor_id is None:
        print("Using a noisy simulator.")
        sampler = PhasedFSimEngineSimulator.create_with_random_gaussian_sqrt_iswap(
            mean=SQRT_ISWAP_INV_PARAMETERS,
            sigma=PhasedFSimCharacterization(theta=0.01,
                                             zeta=0.10,
                                             chi=0.01,
                                             gamma=0.10,
                                             phi=0.02),
        )
        device = Sycamore
    else:  # pragma: no cover
        device = get_engine_device(processor_id)
        sampler = get_engine_sampler(processor_id, gate_set_name="sqrt_iswap")
    return QCSObjectsForNotebook(
        device=device,
        sampler=sampler,
        signed_in=not google_cloud_signin_failed,
    )
예제 #6
0
def main():
    # Set the random seed for the OTOC circuits.
    np.random.seed(0)

    # Specify project ID and processor name.
    processor_name = "rainbow"
    sampler = cg.get_engine_sampler(processor_id=processor_name,
                                    gate_set_name="fsim")

    # Specify qubits to measure. The qubits must form a line. The ancilla qubit
    # must be connected to the first qubit.
    qubit_locs = [(3, 3), (2, 3), (2, 4), (2, 5), (1, 5), (0, 5), (0, 6),
                  (1, 6)]
    qubits = [cirq.GridQubit(*idx) for idx in qubit_locs]
    ancilla_loc = (3, 2)
    ancilla = cirq.GridQubit(*ancilla_loc)
    num_qubits = len(qubits)

    # Specify how the qubits interact. For the 1D chain in this example, only two
    # layers of two-qubit gates (CZ is used here) is needed to enact all
    # interactions.
    int_sets = [
        {(qubits[i], qubits[i + 1])
         for i in range(0, num_qubits - 1, 2)},
        {(qubits[i], qubits[i + 1])
         for i in range(1, num_qubits - 1, 2)},
    ]

    forward_ops = {(qubit_locs[i], qubit_locs[i + 1]):
                   cirq.Circuit([cirq.CZ(qubits[i], qubits[i + 1])])
                   for i in range(num_qubits - 1)}

    reverse_ops = forward_ops

    # Build two random circuit instances (each having 12 cycles).
    circuit_list = []
    cycles = range(12)
    num_trials = 2
    for i in range(num_trials):
        rand_nums = np.random.choice(8, (num_qubits, max(cycles)))
        circuits_i = []
        for cycle in cycles:
            circuits_ic = []
            for k, q_b in enumerate(qubits[1:]):
                circs = build_otoc_circuits(
                    qubits,
                    ancilla,
                    cycle,
                    int_sets,
                    forward_ops=forward_ops,
                    reverse_ops=reverse_ops,
                    butterfly_qubits=q_b,
                    cycles_per_echo=2,
                    sq_gates=rand_nums,
                    use_physical_cz=True,
                )
                # If q_b is the measurement qubit, add both the normalization circuits and the
                # circuits with X as the butterfly operator. Otherwise only add circuits with Y
                # being the butterfly operator.
                if k == 0:
                    circuits_ic.extend(circs.butterfly_I)
                    circuits_ic.extend(circs.butterfly_X)
                else:
                    circuits_ic.extend(circs.butterfly_X)
            circuits_i.append(circuits_ic)
        circuit_list.append(circuits_i)

    # Measure the OTOCs of the two random circuits.
    results = []
    for i, circuits_i in enumerate(circuit_list):
        results_i = np.zeros((num_qubits, len(cycles)))
        for c, circuits_ic in enumerate(circuits_i):
            print("Measuring circuit instance {}, cycle {}...".format(i, c))
            stats = int(2000 + 10000 * (c / max(cycles))**3)
            params = [{} for _ in range(len(circuits_ic))]
            job = sampler.run_batch(programs=circuits_ic,
                                    params_list=params,
                                    repetitions=stats)
            for d in range(num_qubits):
                p = np.mean(job[4 * d][0].measurements["z"])
                p -= np.mean(job[4 * d + 1][0].measurements["z"])
                p -= np.mean(job[4 * d + 2][0].measurements["z"])
                p += np.mean(job[4 * d + 3][0].measurements["z"])
                results_i[d, c] = 0.5 * p
        results.append(results_i)

    # Average the data for the two random circuits and plot out results.
    results_ave = np.mean(results, axis=0)
    fig = plt.figure()
    plt.plot(results_ave[0, :], "ko-", label="Normalization")
    for i in range(1, num_qubits):
        plt.plot(results_ave[i, :], "o-", label="Qubit {}".format(i + 1))
    plt.xlabel("Cycles")
    plt.ylabel(r"$\langle \sigma_y \rangle$")
    plt.legend()
예제 #7
0
def main():
    # Specify a working directory, project ID and processor name.
    dir_str = os.getcwd()
    processor_name = "rainbow"
    sampler = cg.get_engine_sampler(processor_id=processor_name,
                                    gate_set_name="fsim")

    # Specify qubits to measure. Here we choose the qubits to be on a line.
    qubit_locs = [(3, 3), (2, 3), (2, 4), (2, 5), (1, 5), (0, 5), (0, 6),
                  (1, 6)]
    qubits = [cirq.GridQubit(*idx) for idx in qubit_locs]
    num_qubits = len(qubits)

    # Specify the gate layers to calibrate. For qubits on a line, all two-qubit
    # gates can be calibrated in two layers.
    int_layers = [
        {(qubit_locs[i], qubit_locs[i + 1])
         for i in range(0, num_qubits - 1, 2)},
        {(qubit_locs[i], qubit_locs[i + 1])
         for i in range(1, num_qubits - 1, 2)},
    ]

    xeb_configs = [
        [
            cirq.Moment([
                cirq.ISWAP(qubits[i], qubits[i + 1])**0.5
                for i in range(0, num_qubits - 1, 2)
            ])
        ],
        [
            cirq.Moment([
                cirq.ISWAP(qubits[i], qubits[i + 1])**0.5
                for i in range(1, num_qubits - 1, 2)
            ])
        ],
    ]

    # Specify the number of random circuits in parallel XEB the cycles at which
    # fidelities are to be measured.
    num_circuits = 10
    num_num_cycles = range(3, 75, 10)
    num_cycles = len(num_num_cycles)

    # Generate random XEB circuits, measure the resulting bit-strings, and save
    # the data as well as random circuit information.
    all_bits = []
    all_sq_gates = []
    for xeb_config in xeb_configs:
        bits = []
        sq_gates = []
        for i in range(num_circuits):
            print(i)
            circuits, sq_gate_indices_i = build_xeb_circuits(qubits,
                                                             num_num_cycles,
                                                             xeb_config,
                                                             random_seed=i)
            sq_gates.append(sq_gate_indices_i)
            for c in circuits:
                c.append(cirq.measure(*qubits, key="z"))
            sweep_params = [{} for _ in range(len(circuits))]
            job = sampler.run_batch(programs=circuits,
                                    params_list=sweep_params,
                                    repetitions=5000)
            bits.append(
                [job[j][0].measurements["z"] for j in range(num_cycles)])
        all_bits.append(bits)
        all_sq_gates.append(sq_gates)

    # Perform fits on each qubit pair to miminize the cycle errors. The fitting
    # results are saved to the working directory.
    fsim_angles_init = {
        "theta": -0.25 * np.pi,
        "delta_plus": 0,
        "delta_minus_off_diag": 0,
        "delta_minus_diag": 0,
        "phi": 0.0,
    }
    xeb_results = parallel_xeb_fidelities(
        qubit_locs,
        num_num_cycles,
        all_bits,
        all_sq_gates,
        fsim_angles_init,
        interaction_sequence=int_layers,
        gate_to_fit="sqrt-iswap",
        num_restarts=5,
    )

    plot_xeb_results(xeb_results)

    save_data(xeb_results.correction_gates, dir_str + "/gate_corrections")