Skip to main content
IBM Quantum Platform

OpenQASM 2 et l' Qiskit SDK

  • Le code de cette page a été développé en tenant compte des exigences suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.

    qiskit[all]~=2.5.1
    

Le SDK Qiskit fournit des outils de conversion entre les représentations OpenQASM des programmes quantiques et la classe QuantumCircuit classe.


Importer un programme OpenQASM 2 dans Qiskit

Deux fonctions permettent d'importer les programmes OpenQASM 2 dans Qiskit. Il s'agit de qasm2.load()qui prend un nom de fichier, et qasm2.loads()qui prend le programme OpenQASM 2 sous forme de chaîne de caractères.

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)

Voir OpenQASM 2 Qiskit API pour plus d'informations.

Importer des programmes simples

Pour la plupart des programmes OpenQASM 2, vous pouvez simplement utiliser qasm2.load et qasm2.loads avec un seul argument.

Exemple : importer un programme OpenQASM 2 sous forme de chaîne

Utilisez qasm2.loads() pour importer un programme OpenQASM 2 sous la forme d'une chaîne de caractères dans un fichier de données 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 

Exemple : importer un programme OpenQASM 2 à partir d'un fichier

Utilisez load() pour importer un programme OpenQASM 2 à partir d'un fichier dans un fichier QuantumCircuit:

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

Lien OpenQASM 2 portes avec les portes Qiskit

Par défaut, l'importateur OpenQASM 2 de Qiskit traite le fichier include "qelib1.inc" comme une bibliothèque standard de facto. L'importateur traite ce fichier comme contenant précisément les portes qu'il est censé contenir dans le document original définissant OpenQASM 2. Qiskit utilisera les portes intégrées dans la bibliothèque de circuits pour représenter les portes dans "qelib1.inc". Les portes définies dans le programme par des déclarations manuelles OpenQASM 2 gate seront, par défaut, construites comme des portes personnalisées Qiskit Gate sous-classes.

Vous pouvez indiquer à l'importateur d'utiliser des classes Gate pour les instructions gate qu'il rencontre. Vous pouvez également utiliser ce mécanisme pour traiter des noms de portes supplémentaires comme "intégrés", c'est-à-dire ne nécessitant pas de définition explicite. Si vous spécifiez les classes de portes à utiliser pour les instructions gate en dehors de "qelib1.inc", le circuit résultant sera généralement plus efficace.

Warning

À partir de Qiskit SDKv1.0, l'exportateur OpenQASM 2 de Qiskit (voir Exporter un circuit Qiskit vers OpenQASM 2 ) se comporte toujours comme s'il "qelib1.inc" avait plus de portes qu'il n'en a réellement. Cela signifie que les paramètres par défaut de l'importateur pourraient ne pas permettre d'importer un programme exporté par notre importateur. Consultez l'exemple spécifique sur l'utilisation de l'exportateur hérité pour résoudre ce problème.

Cette divergence est un comportement hérité de Qiskit, et sera résolue dans une version ultérieure de Qiskit.

Pour transmettre des informations sur une instruction personnalisée à l'importateur OpenQASM 2, utilisez la classe qasm2.CustomInstruction . Celui-ci comporte quatre éléments d'information obligatoires, dans l'ordre :

  • Le nom de la porte, utilisé dans le programme OpenQASM 2
  • Nombre de paramètres d'angle pris en compte par la porte
  • Nombre de qubits sur lesquels la porte agit
  • La classe ou fonction de construction Python pour la porte, qui prend les paramètres de la porte (mais pas les qubits) comme arguments individuels

Si l'importateur rencontre une définition gate qui correspond à une instruction personnalisée donnée, il utilisera ces informations personnalisées pour reconstruire l'objet gate. Si une instruction gate correspondant à name d'une instruction personnalisée est rencontrée, mais qu'elle ne correspond pas au nombre de paramètres et au nombre de qubits, l'importateur lèvera un QASM2ParseErrorpour indiquer la non-concordance entre les informations fournies et le programme.

En outre, un cinquième argument builtin peut être optionnellement défini comme True pour que la porte soit automatiquement disponible dans le programme OpenQASM 2, même si elle n'est pas explicitement définie. Si l'importateur rencontre une définition explicite de gate pour une instruction personnalisée intégrée, il l'acceptera silencieusement. Comme précédemment, si une définition explicite du même nom n'est pas compatible avec l'instruction personnalisée fournie, une erreur de type QASM2ParseError sera soulevée. Ceci est utile pour la compatibilité avec les anciens exportateurs OpenQASM 2 et avec certaines autres plateformes quantiques qui traitent les "portes de base" de leur matériel comme des instructions intégrées.

Qiskit fournit un attribut de données pour travailler avec des programmes OpenQASM 2 produits par des versions antérieures des capacités d'exportation de Qiskit OpenQASM 2. Il s'agit de qasm2.LEGACY_CUSTOM_INSTRUCTIONS, qui peut être donné comme argument custom_instructions à qasm2.load() et qasm2.loads().

Exemple : importer un programme créé par l'exportateur hérité de Qiskit

Ce programme OpenQASM 2 utilise des portes qui ne sont pas dans la version originale de "qelib1.inc" sans les déclarer, mais qui sont des portes standard dans la bibliothèque de Qiskit. Vous pouvez utiliser qasm2.LEGACY_CUSTOM_INSTRUCTIONS pour indiquer facilement à l'importateur d'utiliser le même ensemble de portes que l'exportateur OpenQASM 2 de Qiskit utilisait auparavant.

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

Exemple : utiliser une classe de porte particulière lors de l'importation d'un programme OpenQASM 2

En général, Qiskit ne peut pas vérifier si la définition d'une déclaration OpenQASM 2 gate correspond exactement à une porte de la bibliothèque standard de Qiskit. Au lieu de cela, Qiskit choisit une porte personnalisée en utilisant la définition précise fournie. Cela peut s'avérer moins efficace que l'utilisation d'une des portes standard intégrées ou d'une porte personnalisée définie par l'utilisateur. Vous pouvez définir manuellement des instructions gate avec des classes particulières.

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

Exemple : définir une nouvelle porte intégrée dans un programme OpenQASM 2

Si l'argument builtin=True est défini, une porte personnalisée n'a pas besoin d'être associée à une définition.

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

Définir des fonctions classiques personnalisées

OpenQASM 2 comprend des fonctions classiques intégrées à utiliser dans les arguments des portes. Vous pouvez étendre le langage avec d'autres fonctions en utilisant l'argument custom_classical à qasm2.load() et qasm2.loads()avec la classe qasm2.CustomClassical classe.

Pour définir une fonction classique personnalisée, vous devez fournir :

  • Le nom de la fonction tel qu'il apparaît dans le programme OpenQASM 2
  • Le nombre d'arguments en virgule flottante qu'il accepte
  • Un objet appelable Python qui évalue la fonction

Toutes les fonctions classiques personnalisées définies sont traitées par l'importateur comme étant intégrées au langage OpenQASM 2. Le langage OpenQASM 2 ne permet pas officiellement de définir de nouvelles fonctions; il s'agit d'une extension Qiskit.

Exemple : utiliser des instructions classiques personnalisées

Nous proposons ici deux fonctions classiques personnalisées. La première est simple et se contente d'ajouter un à son entrée. La seconde est la fonction math.atan2, qui représente l'opération mathématique arctan(y/x)\arctan(y/x) en tenant compte des quadrants.

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)

Mode strict

Par défaut, cet analyseur est plus souple que la spécification officielle. Il autorise les virgules de fin dans les listes de paramètres, les points-virgules inutiles (déclaration vide), l'omission de la déclaration de version OPENQASM 2.0; et plusieurs autres améliorations de la qualité de vie sans émettre d'erreurs. Toutefois, vous pouvez utiliser le mode "lettre de recommandation" avec strict=True.


Exporter un circuit Qiskit vers OpenQASM 2

Qiskit peut également exporter un QuantumCircuit vers OpenQASM 2. Vous utilisez la fonction qasm2.dump() pour écrire dans un fichier, et qasm2.dumps() pour écrire dans une chaîne de caractères. Ces fonctions ont actuellement une interface très simple : elles acceptent un circuit et, uniquement dans le cas de qasm2.dump()un emplacement où écrire la sortie.

Warning

L'exportateur OpenQASM 2 de Qiskit utilise toujours une version ancienne et non standard du fichier include "qelib1.inc" . Ce problème sera résolu dans une version ultérieure de Qiskit, mais en attendant, si vous devez réimporter un programme OpenQASM 2 créé avec Qiskit, utilisez l 'exemple ci-dessus pour indiquer à l'importateur les anciennes portes.

Exemple : exporter un circuit vers 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")

Etapes suivantes

Recommandations
Cette page a-t-elle été utile ?
Signaler un bogue, une coquille ou proposer du contenu sur GitHub.