Skip to main content
IBM Quantum Platform

OpenQASM 2 und die Qiskit SDK

  • Der Code auf dieser Seite wurde unter Berücksichtigung der folgenden Anforderungen entwickelt. Wir empfehlen die Verwendung dieser oder neuerer Versionen.

    qiskit[all]~=2.5.2
    

Das Qiskit SDK bietet einige Werkzeuge zur Konvertierung zwischen OpenQASM Repräsentationen von Quantenprogrammen und der QuantumCircuit klasse.


OpenQASM 2-Programm in Qiskit importieren

Zwei Funktionen importieren OpenQASM 2 Programme in Qiskit. Diese sind qasm2.load()der einen Dateinamen annimmt, und qasm2.loads(), die das Programm OpenQASM 2 als Zeichenkette annimmt.

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)

Weitere Informationen finden Sie in der OpenQASM 2 Qiskit API.

Einfache Programme importieren

Für die meisten OpenQASM 2 Programme können Sie einfach qasm2.load und qasm2.loads mit einem einzigen Argument verwenden.

Beispiel: Importieren Sie ein Programm „ OpenQASM 2” als Zeichenfolge

Verwenden Sie qasm2.loads() , um ein OpenQASM 2 Programm als String in eine 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 

Beispiel: Importieren eines Programms „ OpenQASM 2” aus einer Datei

Verwenden Sie load() , um ein OpenQASM 2 Programm aus einer Datei in eine QuantumCircuit:

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

Standardmäßig behandelt der OpenQASM 2 Importer von Qiskit die Include-Datei "qelib1.inc" als eine de facto Standardbibliothek. Der Importer behandelt diese Datei so, als enthalte sie genau die Gatter, die in der ursprünglichen Definition von OpenQASM 2 beschrieben sind. Qiskit verwendet die eingebauten Gatter in der Schaltkreisbibliothek, um die Gatter in "qelib1.inc" darzustellen. Gatter, die im Programm durch manuelle OpenQASM 2 gate Anweisungen definiert werden, werden standardmäßig als benutzerdefinierte Qiskit Gate Unterklassen konstruiert.

Sie können den Importer anweisen, bestimmte Gate klassen für die gegebenen gate Anweisungen zu verwenden, auf die er trifft. Sie können diesen Mechanismus auch verwenden, um zusätzliche Gatternamen als "eingebaut" zu behandeln, d.h. sie müssen nicht explizit definiert werden. Wenn Sie außerhalb von "qelib1.inc" angeben, welche Gatterklassen für gate Anweisungen verwendet werden sollen, ist die resultierende Schaltung in der Regel effizienter.

Warning

Laut Qiskit SDKv1.0 verhält sich der Qiskit-Exporter OpenQASM 2 (siehe Exportieren eines Qiskit-Schaltkreises nach OpenQASM 2 ) immer noch so, als "qelib1.inc" hätte er mehr Gatter als tatsächlich vorhanden sind. Das bedeutet, dass die Standardeinstellungen des Importprogramms möglicherweise nicht in der Lage sind, ein von unserem Importprogramm exportiertes Programm zu importieren. Siehe das konkrete Beispiel zur Verwendung des Legacy-Exporters, um dieses Problem zu beheben.

Diese Diskrepanz ist ein veraltetes Verhalten von Qiskit und wird in einer späteren Version von Qiskit behoben werden.

Um Informationen über eine benutzerdefinierte Anweisung an den OpenQASM 2 Importer zu übergeben, verwenden Sie die Klasse qasm2.CustomInstruction . Dazu sind vier Informationen erforderlich, und zwar in dieser Reihenfolge:

  • Der Name des Tores, der im Programm OpenQASM 2 verwendet wird
  • Die Anzahl der Winkelparameter, die das Tor annimmt
  • Die Anzahl der Qubits, auf die das Gate wirkt
  • Die Python Konstruktorklasse oder -funktion für das Tor, die die Torparameter (aber nicht die Qubits) als einzelne Argumente entgegennimmt

Wenn der Importer auf eine gate Definition stößt, die mit einer bestimmten benutzerdefinierten Anweisung übereinstimmt, verwendet er diese benutzerdefinierte Information, um das Gate-Objekt zu rekonstruieren. Wenn eine gate Anweisung gefunden wird, die mit der name einer benutzerdefinierten Anweisung übereinstimmt, aber nicht mit der Anzahl der Parameter und der Anzahl der Qubits übereinstimmt, löst der Importeur eine QASM2ParseError, um die Nichtübereinstimmung zwischen den gelieferten Informationen und dem Programm anzuzeigen.

Zusätzlich kann ein fünftes Argument builtin optional auf True gesetzt werden, um das Tor automatisch innerhalb des OpenQASM 2 Programms verfügbar zu machen, auch wenn es nicht explizit definiert ist. Wenn der Importer auf eine explizite gate Definition für einen eingebauten benutzerdefinierten Befehl stößt, wird er diesen stillschweigend akzeptieren. Wenn eine explizite Definition desselben Namens nicht mit der bereitgestellten benutzerdefinierten Anweisung kompatibel ist, wird wie zuvor eine QASM2ParseError ausgelöst. Dies ist nützlich für die Kompatibilität mit älteren OpenQASM 2-Exportern und mit bestimmten anderen Quantenplattformen, die die "Basisgatter" ihrer Hardware als eingebaute Anweisungen behandeln.

Qiskit bietet ein Datenattribut für die Arbeit mit OpenQASM 2 Programmen, die mit älteren Versionen von Qiskits OpenQASM 2 Exportfunktionen erstellt wurden. Dies ist qasm2.LEGACY_CUSTOM_INSTRUCTIONS, das als custom_instructions Argument für qasm2.load() und qasm2.loads().

Beispiel: Importieren eines mit dem alten Exporter von Qiskit erstellten Programms

Dieses OpenQASM 2 Programm verwendet Gatter, die nicht in der Originalversion von "qelib1.inc" enthalten sind, ohne sie zu deklarieren, aber Standardgatter in der Qiskit-Bibliothek sind. Sie können mit qasm2.LEGACY_CUSTOM_INSTRUCTIONS können Sie dem Importeur auf einfache Weise mitteilen, dass er denselben Satz von Gates verwenden soll, den der OpenQASM 2 Exporter von Qiskit zuvor verwendet hat.

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,
)

Beispiel: Verwenden Sie beim Importieren eines Programms aus „ OpenQASM 2“ eine bestimmte Gate-Klasse

Qiskit kann im Allgemeinen nicht überprüfen, ob die Definition in einer OpenQASM 2 gate Anweisung genau einem Qiskit Standard-Bibliotheksgatter entspricht. Stattdessen wählt Qiskit ein benutzerdefiniertes Tor anhand der angegebenen Definition aus. Dies kann weniger effizient sein als die Verwendung eines der eingebauten Standardgatter oder eines benutzerdefinierten Gatters. Sie können gate Anweisungen mit bestimmten Klassen manuell definieren.

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,
)

Beispiel: Definieren Sie ein neues integriertes Gate in einem Programm „ OpenQASM 2”

Wenn das Argument builtin=True gesetzt ist, braucht ein benutzerdefiniertes Tor keine zugehörige Definition zu haben.

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,
)

Benutzerdefinierte klassische Funktionen definieren

OpenQASM 2 enthält einige eingebaute klassische Funktionen zur Verwendung in Gate-Argumenten. Sie können die Sprache um weitere Funktionen erweitern, indem Sie das Argument custom_classical für qasm2.load() und qasm2.loads()mit der qasm2.CustomClassical klasse.

Um eine benutzerdefinierte klassische Funktion zu definieren, müssen Sie diese angeben:

  • Der Name der Funktion, wie er im Programm OpenQASM 2 erscheint
  • Die Anzahl der akzeptierten Gleitkomma-Argumente
  • Ein aufrufbares Python Objekt, das die Funktion

Alle benutzerdefinierten klassischen Funktionen werden vom Importer als in die Sprache OpenQASM 2 integriert behandelt. Innerhalb der Sprache OpenQASM 2 gibt es keine offizielle Möglichkeit, neue Funktionen zu definieren; dies ist eine Qiskit-Erweiterung.

Beispiel: Verwenden Sie benutzerdefinierte klassische Anweisungen

Hier bieten wir zwei benutzerdefinierte klassische Funktionen an. Die erste ist einfach und fügt der Eingabe lediglich eine Eins hinzu. Die zweite ist die Funktion math.atan2, die die mathematische Operation arctan⁡(y/x)\arctan(y/x) in einer quadrantengerechten Weise darstellt.

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)

Strikter Modus

Standardmäßig ist dieser Parser entspannter als die offizielle Spezifikation. Es erlaubt abschließende Kommas in Parameterlisten, unnötige (leere Anweisung) Semikolons, das Weglassen der OPENQASM 2.0; Versionsanweisung und verschiedene andere Qualitätsverbesserungen, ohne Fehler zu erzeugen. Sie können jedoch den "Letter-of-the-Spec"-Modus mit strict=True verwenden.


Exportieren Sie einen Qiskit-Schaltkreis nach „ OpenQASM “ 2

Qiskit kann auch eine QuantumCircuit nach OpenQASM 2 exportieren. Sie verwenden die Funktion qasm2.dump() um in eine Datei zu schreiben, und qasm2.dumps() um in eine Zeichenkette zu schreiben. Diese Funktionen haben derzeit eine sehr einfache Schnittstelle: Sie akzeptieren eine Schaltung und, nur im Fall von qasm2.dump()einen Ort, an den die Ausgabe geschrieben werden soll.

Warning

Der OpenQASM 2 Exporter von Qiskit geht immer noch von einer veralteten, nicht standardisierten Version der "qelib1.inc" Include-Datei aus. Dies wird in einer späteren Version von Qiskit behoben werden, aber in der Zwischenzeit, wenn Sie ein OpenQASM 2 Programm, das mit Qiskit erstellt wurde, wieder importieren müssen, verwenden Sie das obige Beispiel, um dem Importer die Legacy Gates mitzuteilen.

Beispiel: Exportieren Sie eine Schaltung nach „ 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")

Nächste Schritte

Empfehlungen
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.