Vai al contenuto principale

OpenQASM 2 e il Qiskit SDK

Versioni dei pacchetti

Il codice in questa pagina è stato sviluppato utilizzando i seguenti requisiti. Si consiglia di usare queste versioni o versioni più recenti.

qiskit[all]~=2.3.0
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit

Il Qiskit SDK fornisce alcuni strumenti per convertire tra le rappresentazioni OpenQASM dei programmi quantistici e la classe QuantumCircuit.

Importare un programma OpenQASM 2 in Qiskit

Due funzioni consentono di importare programmi OpenQASM 2 in Qiskit. Queste 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, consulta l'API Qiskit per OpenQASM 2.

Importare programmi semplici

Per la maggior parte dei programmi OpenQASM 2, puoi usare semplicemente qasm2.load e qasm2.loads con un singolo argomento.

Esempio: importare un programma OpenQASM 2 come stringa

Usa qasm2.loads() per importare un programma OpenQASM 2 come stringa in un 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()
┌───┐     ┌─┐
q_0: ┤ H ├──■──┤M├───
└───┘┌─┴─┐└╥┘┌─┐
q_1: ─────┤ X ├─╫─┤M├
└───┘ ║ └╥┘
c: 2/═══════════╩══╩═
0 1

Esempio: importare un programma OpenQASM 2 da file

Usa load() per importare un programma OpenQASM 2 da file in un QuantumCircuit:

import qiskit.qasm2
circuit = qiskit.qasm2.load("myfile.qasm")

Per impostazione predefinita, l'importatore OpenQASM 2 di Qiskit tratta il file di inclusione "qelib1.inc" come una libreria standard de facto. L'importatore considera questo file come contenente esattamente i gate descritti nel documento originale che definisce OpenQASM 2. Qiskit utilizzerà i gate integrati nella circuit library per rappresentare i gate presenti in "qelib1.inc". I gate definiti nel programma tramite istruzioni OpenQASM 2 gate manuali saranno, per impostazione predefinita, costruiti come sottoclassi personalizzate di Qiskit Gate.

Puoi indicare all'importatore di usare classi Gate specifiche per le istruzioni gate che incontra. Puoi usare questo meccanismo anche per trattare ulteriori nomi di gate come "integrati", ovvero che non richiedono una definizione esplicita. Se specifichi quali classi di gate usare per le istruzioni gate al di fuori di "qelib1.inc", il circuito risultante sarà in genere più efficiente da utilizzare.

avviso

A partire da Qiskit SDK v1.0, l'esportatore OpenQASM 2 di Qiskit (vedi Esportare un circuito Qiskit in OpenQASM 2) si comporta ancora come se "qelib1.inc" contenesse più gate di quanti ne contenga effettivamente. Ciò significa che le impostazioni predefinite dell'importatore potrebbero non essere in grado di importare un programma esportato dal nostro esportatore. Consulta l'esempio specifico su come lavorare con l'esportatore legacy per risolvere questo problema.

Questa discrepanza è un comportamento legacy di Qiskit, e sarà risolta in una versione successiva di Qiskit.

Per passare informazioni su un'istruzione personalizzata all'importatore OpenQASM 2, usa la classe qasm2.CustomInstruction. Questa richiede quattro informazioni obbligatorie, nell'ordine:

  • Il nome del gate, utilizzato nel programma OpenQASM 2
  • Il numero di parametri angolari che il gate accetta
  • Il numero di qubit su cui il gate agisce
  • La classe o funzione Python costruttore per il gate, che accetta i parametri del gate (ma non i qubit) come argomenti individuali

Se l'importatore incontra una definizione gate che corrisponde a un'istruzione personalizzata specificata, utilizzerà quelle informazioni personalizzate per ricostruire l'oggetto gate. Se viene incontrata un'istruzione gate che corrisponde al name di un'istruzione personalizzata, ma non corrisponde né al numero di parametri né al numero di qubit, l'importatore genererà un QASM2ParseError, per indicare la discordanza tra le informazioni fornite e il programma.

Inoltre, un quinto argomento builtin può essere impostato facoltativamente su True per rendere il gate automaticamente disponibile nel programma OpenQASM 2, anche se non è definito esplicitamente. Se l'importatore incontra una definizione gate esplicita per un'istruzione personalizzata integrata, la accetterà silenziosamente. Come prima, se una definizione esplicita con lo stesso nome non è compatibile con l'istruzione personalizzata fornita, verrà generato un QASM2ParseError. Questo è utile per la compatibilità con esportatori OpenQASM 2 più vecchi e con alcune altre piattaforme quantistiche che trattano i "gate base" del proprio hardware come istruzioni integrate.

Qiskit fornisce un attributo dati per lavorare con programmi OpenQASM 2 prodotti da versioni legacy delle capacità di esportazione OpenQASM 2 di Qiskit. Questo è qasm2.LEGACY_CUSTOM_INSTRUCTIONS, che può essere passato come argomento custom_instructions a qasm2.load() e qasm2.loads().

Esempio: importare un programma creato dall'esportatore legacy di Qiskit

Questo programma OpenQASM 2 usa gate non presenti nella versione originale di "qelib1.inc" senza dichiararli, ma che sono gate standard nella libreria di Qiskit. Puoi usare qasm2.LEGACY_CUSTOM_INSTRUCTIONS per indicare facilmente all'importatore di usare lo stesso insieme di gate che l'esportatore OpenQASM 2 di Qiskit 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: usare una classe gate specifica nell'importazione di un programma OpenQASM 2

Qiskit non può, in generale, verificare se la definizione in un'istruzione gate di OpenQASM 2 corrisponde esattamente a un gate della libreria standard di Qiskit. Invece, Qiskit sceglie un gate personalizzato usando la 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. Puoi definire manualmente le istruzioni 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, un gate personalizzato non necessita di 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 usare negli argomenti dei gate. Puoi estendere il linguaggio con ulteriori funzioni usando l'argomento custom_classical di qasm2.load() e qasm2.loads(), con la classe qasm2.CustomClassical.

Per definire una funzione classica personalizzata, devi fornire:

  • Il nome della funzione così come appare nel programma OpenQASM 2
  • Il numero di argomenti in virgola mobile che accetta
  • Un oggetto Python richiamabile che valuta la funzione

Tutte le funzioni classiche personalizzate definite vengono trattate dall'importatore come integrate nel linguaggio OpenQASM 2. Non esiste un modo ufficiale nel linguaggio OpenQASM 2 per definire nuove funzioni; questa è un'estensione di Qiskit.

Esempio: usare istruzioni classiche personalizzate

Qui forniamo due funzioni classiche personalizzate. La prima è semplice e aggiunge semplicemente uno al suo input. La seconda è la funzione math.atan2, che rappresenta l'operazione matematica arctan(y/x)\arctan(y/x) tenendo conto del quadrante.

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à strict

Per impostazione predefinita, questo parser è più permissivo rispetto alla specifica ufficiale. Consente virgole finali nelle liste di parametri; punto e virgola non necessari (istruzioni vuote); omissione dell'istruzione di versione OPENQASM 2.0;; e vari altri miglioramenti alla qualità d'uso senza emettere errori. Tuttavia, puoi usare la modalità "lettera della specifica" con strict=True.

Esportare un circuito Qiskit in OpenQASM 2

Qiskit può anche esportare un QuantumCircuit in OpenQASM 2. Usa la funzione qasm2.dump() per scrivere su file e qasm2.dumps() per scrivere su stringa. Queste funzioni hanno attualmente un'interfaccia molto semplice: accettano un circuito e, solo nel caso di qasm2.dump(), una destinazione in cui scrivere l'output.

avviso

L'esportatore OpenQASM 2 di Qiskit presuppone 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 devi reimportare un programma OpenQASM 2 creato con Qiskit, usa l'esempio sopra su come 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

Raccomandazioni