Ciao Pulse - Amazon Braket

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Ciao Pulse

Qui imparerai come costruire una semplice coppia Bell direttamente con gli impulsi ed eseguire questo programma di impulsi sul Rigetti dispositivo. Una coppia Bell è un circuito a due qubit costituito da una porta Hadamard sul primo qubit seguita da una cnot porta tra il primo e il secondo qubit. La creazione di stati intrecciati con impulsi richiede meccanismi specifici che dipendono dal tipo di hardware e dall'architettura del dispositivo. Non useremo un meccanismo nativo per creare il gate. cnot Utilizzeremo invece forme d'onda e frame specifici che abilitano il cz gate in modo nativo. In questo esempio, creeremo un gate Hadamard utilizzando le porte native a qubit singolo rx ed rz esprimeremo il gate usando gli impulsi. cz

Per prima cosa, importiamo le librerie necessarie. Oltre alla Circuit classe, ora dovrai importare anche la PulseSequence classe.

from braket.aws import AwsDevice from braket.pulse import PulseSequence, ArbitraryWaveform, GaussianWaveform from braket.circuits import Circuit import braket.circuits.circuit as circuit

Successivamente, crea un'istanza di un nuovo dispositivo Braket utilizzando l'Amazon Resource Name (ARN) del dispositivo. Rigetti Aspen-M-3 Consulta la pagina Dispositivi sulla console Amazon Braket per visualizzare il layout del Rigetti Aspen-M-3 dispositivo.

a=10 #specifies the control qubit b=113 #specifies the target qubit device = AwsDevice("arn:aws:braket:us-west-1::device/qpu/rigetti/Aspen-M-3")

Poiché la porta Hadamard non è una porta nativa del Rigetti dispositivo, non può essere utilizzata in combinazione con gli impulsi. È quindi necessario scomporlo in una sequenza di porte e native. rx rz

import numpy as np import matplotlib.pyplot as plt @circuit.subroutine(register=True) def rigetti_native_h(q0): return ( Circuit() .rz(q0, np.pi) .rx(q0, np.pi/2) .rz(q0, np.pi/2) .rx(q0, -np.pi/2) )

Per il cz gate, utilizzeremo una forma d'onda arbitraria con parametri (ampiezza, tempo di salita/discesa e durata) predeterminati dal fornitore dell'hardware durante una fase di calibrazione. Questa forma q10_q113_cz_frame d'onda verrà applicata su. Per una versione più recente della forma d'onda arbitraria utilizzata qui, vedi QCS, sul sito web. Rigetti Potrebbe esserti richiesto di creare un account QCS.

a_b_cz_wfm = ArbitraryWaveform([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.00017888439538396808, 0.00046751103636033026, 0.0011372942989106456, 0.002577059611929697, 0.005443941944632366, 0.010731922770068104, 0.01976701723583167, 0.03406712171899736, 0.05503285980691202, 0.08350670755829034, 0.11932853352131022, 0.16107456696238298, 0.20614055551722368, 0.2512065440720643, 0.292952577513137, 0.328774403476157, 0.3572482512275353, 0.3782139893154499, 0.3925140937986156, 0.40154918826437913, 0.4068371690898149, 0.4097040514225177, 0.41114381673553674, 0.411813599998087, 0.4121022266390633, 0.4122174383870584, 0.41226003881132406, 0.4122746298554775, 0.4122792591252675, 0.4122806196003006, 0.41228098995582513, 0.41228108334474756, 0.4122811051578895, 0.4122811098772742, 0.4122811108230642, 0.4122811109986316, 0.41228111102881937, 0.41228111103362725, 0.4122811110343365, 0.41228111103443343, 0.4122811110344457, 0.4122811110344471, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.41228111103444737, 0.4122811110344471, 0.4122811110344457, 0.41228111103443343, 0.4122811110343365, 0.41228111103362725, 0.41228111102881937, 0.4122811109986316, 0.4122811108230642, 0.4122811098772742, 0.4122811051578895, 0.41228108334474756, 0.41228098995582513, 0.4122806196003006, 0.4122792591252675, 0.4122746298554775, 0.41226003881132406, 0.4122174383870584, 0.4121022266390633, 0.411813599998087, 0.41114381673553674, 0.4097040514225176, 0.4068371690898149, 0.40154918826437913, 0.3925140937986155, 0.37821398931544986, 0.3572482512275351, 0.32877440347615655, 0.2929525775131368, 0.2512065440720641, 0.20614055551722307, 0.16107456696238268, 0.11932853352131002, 0.08350670755829034, 0.05503285980691184, 0.03406712171899729, 0.01976701723583167, 0.010731922770068058, 0.005443941944632366, 0.002577059611929697, 0.0011372942989106229, 0.00046751103636033026, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) a_b_cz_frame = device.frames[f'q{a}_q{b}_cz_frame'] dt = a_b_cz_frame.port.dt a_b_cz_wfm_duration = len(a_b_cz_wfm.amplitudes)*dt print('CZ pulse duration:', a_b_cz_wfm_duration*1e9, 'ns')

Questo dovrebbe restituire:

CZ pulse duration: 124 ns

Ora possiamo costruire il cz gate usando la forma d'onda che abbiamo appena definito. Ricordiamo che il cz gate consiste in un'inversione di fase del qubit target se il qubit di controllo è nello stato. |1>

phase_shift_a=1.1733407221086924 phase_shift_b=6.269846678712192 a_rf_frame = device.frames[f'q{a}_rf_frame'] b_rf_frame = device.frames[f'q{b}_rf_frame'] frames = [a_rf_frame, b_rf_frame, a_b_cz_frame] cz_pulse_sequence = ( PulseSequence() .barrier(frames) .play(a_b_cz_frame, a_b_cz_wfm) .delay(a_rf_frame, a_b_cz_wfm_duration) .shift_phase(a_rf_frame, phase_shift_a) .delay(b_rf_frame, a_b_cz_wfm_duration) .shift_phase(b_rf_frame, phase_shift_b) .barrier(frames) )

La a_b_cz_wfm forma d'onda viene riprodotta su un frame associato a una porta fast-flux. Il suo ruolo è quello di modificare la frequenza del qubit per attivare un'interazione qubit-qubit. Per ulteriori informazioni, vedere Ruoli dei frame e delle porte. Al variare della frequenza, i frame a qubit ruotano a velocità diverse rispetto ai rf frame a qubit singolo che vengono mantenuti intatti: questi ultimi vengono defasati. Questi cambiamenti di fase sono stati precedentemente calibrati tramite Ramsey sequenze e vengono qui forniti come informazioni codificate tramite e (periodo completo). phase_shift_a phase_shift_b Correggiamo questa defasatura utilizzando le istruzioni sui frame. shift_phase rf Nota che questa sequenza funziona solo nei programmi in cui non sono presenti XY frame correlati al qubit a e b viene utilizzata poiché non compensiamo lo spostamento di fase che si verifica su questi frame. Questo è il caso di questo programma Bell a coppia singola, che utilizza solo frame rf ecz. Per ulteriori informazioni, vedere Caldwell et al. .

Ora siamo pronti per creare una coppia Bell con impulsi.

bell_circuit_pulse = ( Circuit() .rigetti_native_h(a) .rigetti_native_h(b) .pulse_gate([a, b], cz_pulse_sequence) .rigetti_native_h(b) ) print(bell_circuit_pulse)
T : | 0 | 1 | 2 | 3 |4 | 5 | 6 | 7 | 8 | q5 : -Rz(3.14)-Rx(1.57)-Rz(1.57)-Rx(-1.57)-PG-------------------------------------- | q6 : -Rz(3.14)-Rx(1.57)-Rz(1.57)-Rx(-1.57)-PG-Rz(3.14)-Rx(1.57)-Rz(1.57)-Rx(-1.57)- T : | 0 | 1 | 2 | 3 |4 | 5 | 6 | 7 | 8 |

Eseguiamo questa coppia Bell sul Rigetti dispositivo. Tieni presente che l'esecuzione di questo blocco di codice comporterà un addebito. Per ulteriori informazioni su questi costi, consulta la pagina dei prezzi di Amazon Braket. Ti consigliamo di testare i circuiti utilizzando una piccola quantità di scatti per assicurarti che possa funzionare sul dispositivo prima di aumentare il numero di colpi.

task = device.run(bell_pair_pulses, shots=100) counts = task.result().measurement_counts plt.bar(sorted(counts), [counts[k] for k in sorted(counts)])
Grafico a barre che mostra i tassi di popolazione per 4 diversi stati binari: 00, 01, 10 e 11, con gli stati 00 e 11 con la proporzione più alta intorno a 0,4 e gli stati 01 e 10 con le proporzioni più basse.