OpenQASM 2 e l' Qiskit SDK
Il codice di questa pagina è stato sviluppato in base ai seguenti requisiti. Si consiglia di utilizzare queste versioni o versioni più recenti.
qiskit[all]~=2.5.1
L'SDK di Qiskit fornisce alcuni strumenti per la conversione tra le rappresentazioni OpenQASM dei programmi quantistici e la classe QuantumCircuit classe.
Importare un programma OpenQASM 2 in Qiskit
Due funzioni importano i programmi di OpenQASM 2 in Qiskit.
Questi sono qasm2.load()che accetta un nome di file e qasm2.loads(), che accetta il programma OpenQASM 2 come stringa.
import qiskit.qasm2
qiskit.qasm2.load(filename, include_path=('.',), include_input_directory='append', custom_instructions=(), custom_classical=(), strict=False)
qiskit.qasm2.loads(program, include_path=('.',), custom_instructions=(), custom_classical=(), strict=False)Per ulteriori informazioni, consultare l' API di OpenQASM 2 Qiskit.
Importa programmi semplici
Per la maggior parte dei programmi OpenQASM 2, è possibile utilizzare semplicemente qasm2.load e qasm2.loads con un unico argomento.
Esempio: importare un programma OpenQASM 2 come stringa
Usare qasm2.loads() per importare un programma OpenQASM 2 come stringa in un file QuantumCircuit:
import qiskit.qasm2
program = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0], q[1];
measure q -> c;
"""
circuit = qiskit.qasm2.loads(program)
circuit.draw()Output:
┌───┐ ┌─┐
q_0: ┤ H ├──■──┤M├───
└───┘┌─┴─┐└╥┘┌─┐
q_1: ─────┤ X ├─╫─┤M├
└───┘ ║ └╥┘
c: 2/═══════════╩══╩═
0 1
Esempio: importare un programma OpenQASM 2 da un file
Usare load() per importare un programma OpenQASM 2 da un file in un file QuantumCircuit:
import qiskit.qasm2
circuit = qiskit.qasm2.load("myfile.qasm")Link OpenQASM 2 porte con porte Qiskit
Per impostazione predefinita, l'importatore di Qiskit OpenQASM 2 tratta il file include "qelib1.inc" come una libreria standard di fatto.
L'importatore tratta questo file come se contenesse esattamente le porte che sono state descritte nel documento originale che definisce OpenQASM 2.
Qiskit utilizzerà le porte incorporate nella libreria dei circuiti per rappresentare le porte in "qelib1.inc".
Le porte definite nel programma dalle istruzioni manuali OpenQASM 2 gate saranno costruite, per impostazione predefinita, come Qiskit Gate sottoclassi personalizzate.
Si può dire all'importatore di usare classi specifiche Gate per le dichiarazioni di gate che incontra.
È possibile utilizzare questo meccanismo anche per trattare i nomi di gate aggiuntivi come "incorporati", cioè che non richiedono una definizione esplicita.
Se si specificano le classi di gate da utilizzare per le istruzioni di gate al di fuori di "qelib1.inc", il circuito risultante sarà in genere più efficiente da lavorare.
A partire dalla versione Qiskit SDK v1.0, l'esportatore OpenQASM 2 di Qiskit (vedere Esportare un circuito Qiskit in OpenQASM 2 ) continua a comportarsi come se "qelib1.inc" avesse più porte di quante ne abbia in realtà.
Ciò significa che le impostazioni predefinite dell'importatore potrebbero non essere in grado di importare un programma esportato dal nostro importatore.
Vedi l'esempio specifico sull'utilizzo dell'esportatore legacy per risolvere questo problema.
Questa discrepanza è un comportamento ereditato da Qiskit e sarà risolta in una versione successiva di Qiskit.
Per passare informazioni su un'istruzione personalizzata all'importatore di OpenQASM 2, utilizzare la classe qasm2.CustomInstruction .
Questo contiene quattro informazioni necessarie, in ordine sparso:
- Il nome del cancello, utilizzato nel programma OpenQASM 2
- Il numero di parametri angolari che il gate accetta
- Il numero di qubit su cui agisce il gate
- La classe o la funzione del costruttore Python per il gate, che prende i parametri del gate (ma non i qubit) come argomenti individuali
Se l'importatore incontra una definizione di gate che corrisponde a una determinata istruzione personalizzata, utilizzerà le informazioni personalizzate per ricostruire l'oggetto gate.
Se viene incontrata un'istruzione gate che corrisponde a name di un'istruzione personalizzata, ma non corrisponde sia al numero di parametri che al numero di qubit, l'importatore solleverà un problema QASM2ParseErrorper indicare la mancata corrispondenza tra le informazioni fornite e il programma.
Inoltre, un quinto argomento builtin può essere facoltativamente impostato su True per rendere il gate automaticamente disponibile all'interno del programma OpenQASM 2, anche se non è esplicitamente definito.
Se l'importatore incontra una definizione esplicita di gate per un'istruzione personalizzata integrata, la accetterà silenziosamente.
Come in precedenza, se una definizione esplicita con lo stesso nome non è compatibile con l'istruzione personalizzata fornita, verrà sollevato un problema di tipo QASM2ParseError verrà sollevato.
Questo è utile per la compatibilità con i vecchi esportatori di OpenQASM 2 e con alcune altre piattaforme quantistiche che trattano le "porte di base" del loro hardware come istruzioni incorporate.
Qiskit fornisce un attributo di dati per lavorare con i programmi di OpenQASM 2 prodotti da versioni precedenti delle funzionalità di esportazione di OpenQASM 2 di Qiskit.
Questo è qasm2.LEGACY_CUSTOM_INSTRUCTIONS, che può essere dato come argomento custom_instructions a qasm2.load() e qasm2.loads().
Esempio: importare un programma creato dall'esportatore legacy di Qiskit
Questo programma OpenQASM 2 utilizza porte che non sono presenti nella versione originale di "qelib1.inc" senza dichiararle, ma che sono porte standard nella libreria di Qiskit.
È possibile utilizzare qasm2.LEGACY_CUSTOM_INSTRUCTIONS per indicare facilmente all'importatore di utilizzare lo stesso set di porte che l'esportatore di Qiskit OpenQASM 2 utilizzava in precedenza.
from qiskit import qasm2
program = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[4];
creg c[4];
h q[0];
cx q[0], q[1];
// 'rxx' is not actually in `qelib1.inc`,
// but Qiskit used to behave as if it were.
rxx(0.75) q[2], q[3];
measure q -> c;
"""
circuit = qasm2.loads(
program,
custom_instructions=qasm2.LEGACY_CUSTOM_INSTRUCTIONS,
)Esempio: utilizzare una classe di gate particolare durante l'importazione di un programma OpenQASM 2
In generale, Qiskit non è in grado di verificare se la definizione di una dichiarazione OpenQASM 2 gate corrisponde esattamente a una porta della libreria standard di Qiskit.
Invece, Qiskit sceglie un cancello personalizzato in base alla definizione precisa fornita.
Questo può essere meno efficiente rispetto all'uso di uno dei gate standard integrati o di un gate personalizzato definito dall'utente.
È possibile definire manualmente le dichiarazioni di gate con classi particolari.
from qiskit import qasm2
from qiskit.circuit import Gate
from qiskit.circuit.library import RZXGate
# Define a custom gate that takes one qubit and two angles.
class MyGate(Gate):
def __init__(self, theta, phi):
super().__init__("my", 1, [theta, phi])
custom_instructions = [
# Link the OpenQASM 2 name 'my' with our custom gate.
qasm2.CustomInstruction("my", 2, 1, MyGate),
# Link the OpenQASM 2 name 'rzx' with Qiskit's
# built-in RZXGate.
qasm2.CustomInstruction("rzx", 1, 2, RZXGate),
]
program = """
OPENQASM 2.0;
gate my(theta, phi) q {
U(theta / 2, phi, -theta / 2) q;
}
gate rzx(theta) a, b {
// It doesn't matter what definition is
// supplied, if the parameters match;
// Qiskit will still use `RZXGate`.
}
qreg q[2];
my(0.25, 0.125) q[0];
rzx(pi) q[0], q[1];
"""
circuit = qasm2.loads(
program,
custom_instructions=custom_instructions,
)Esempio: definire un nuovo gate integrato in un programma OpenQASM 2
Se l'argomento builtin=True è impostato, non è necessario che un cancello personalizzato abbia una definizione associata.
from qiskit import qasm2
from qiskit.circuit import Gate
# Define a custom gate that takes one qubit and two angles.
class MyGate(Gate):
def __init__(self, theta, phi):
super().__init__("my", 1, [theta, phi])
custom_instructions = [
qasm2.CustomInstruction("my", 2, 1, MyGate, builtin=True),
]
program = """
OPENQASM 2.0;
qreg q[1];
my(0.25, 0.125) q[0];
"""
circuit = qasm2.loads(
program,
custom_instructions=custom_instructions,
)Definire funzioni classiche personalizzate
OpenQASM 2 include alcune funzioni classiche integrate da utilizzare negli argomenti dei gate.
È possibile estendere il linguaggio con altre funzioni utilizzando l'argomento custom_classical a qasm2.load() e qasm2.loads()con la classe qasm2.CustomClassical classe.
Per definire una funzione classica personalizzata, è necessario fornire:
- Il nome della funzione così come appare nel programma OpenQASM 2
- Il numero di argomenti in virgola mobile che accetta
- Un oggetto callable Python che valuta la funzione
Tutte le funzioni classiche personalizzate definite sono trattate dall'importatore come built-in del linguaggio OpenQASM 2. Non esiste un modo ufficiale all'interno del linguaggio OpenQASM 2 per definire nuove funzioni; si tratta di un'estensione di Qiskit.
Esempio: utilizzare istruzioni classiche personalizzate
Qui forniamo due funzioni classiche personalizzate.
Il primo è semplice e si limita ad aggiungere uno al suo input.
La seconda è la funzione math.atan2, che rappresenta l'operazione matematica in modo consapevole dei quadranti.
import math
from qiskit import qasm2
program = """
include "qelib1.inc";
qreg q[2];
rx(arctan(pi, 3 + add_one(0.2))) q[0];
cx q[0], q[1];
"""
def add_one(x):
return x + 1
customs = [
# Our `add_one` takes only one parameter.
qasm2.CustomClassical("add_one", 1, add_one),
# `arctan` takes two parameters, and `math.atan2` implements it.
qasm2.CustomClassical("arctan", 2, math.atan2),
]
circuit = qasm2.loads(program, custom_classical=customs)Modalità ristretta
Per impostazione predefinita, questo parser è più rilassato rispetto alle specifiche ufficiali.
Consente l'inserimento di virgole a capo negli elenchi di parametri, di punti e virgole non necessari (dichiarazioni vuote), l'omissione della dichiarazione di versione OPENQASM 2.0; e diversi altri miglioramenti della qualità della vita senza emettere alcun errore.
Tuttavia, è possibile utilizzare la modalità "lettera dello specifico" con strict=True.
Esportare un circuito Qiskit in OpenQASM 2
Qiskit può anche esportare un file QuantumCircuit in OpenQASM 2.
Si utilizza la funzione qasm2.dump() per scrivere su un file e qasm2.dumps() per scrivere su una stringa.
Queste funzioni hanno attualmente un'interfaccia molto semplice: accettano un circuito e, solo nel caso di qasm2.dump()una posizione in cui scrivere l'uscita.
L'esportatore OpenQASM 2 di Qiskit assume ancora una versione legacy e non standard del file di inclusione "qelib1.inc" .
Questo problema sarà risolto in una versione successiva di Qiskit, ma nel frattempo, se dovete reimportare un programma OpenQASM 2 creato con Qiskit, utilizzate l'esempio precedente per indicare all'importatore i gate legacy.
Esempio: esportare un circuito in OpenQASM 2
from qiskit import QuantumCircuit, qasm2
# Define any circuit.
circuit = QuantumCircuit(2, 2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure([0, 1], [0, 1])
# Export to a string.
program = qasm2.dumps(circuit)
# Export to a file.
qasm2.dump(circuit, "my_file.qasm")Passi successivi
- Per sapere come generare il codice OpenQASM, consultate la guida IBM Quantum Composer.
- Vedere il riferimento all' API di OpenQASM 2 Qiskit.
- Consulta la sezione "Verifica il tuo programma ".
- Visitate il sito OpenQASM Live Specification.