OpenQASM 2 y el Qiskit SDK
El código de esta página se ha desarrollado teniendo en cuenta los siguientes requisitos. Recomendamos utilizar estas versiones o versiones más recientes.
qiskit[all]~=2.5.0
El SDK de Qiskit proporciona algunas herramientas para convertir entre OpenQASM representaciones de programas cuánticos, y la clase QuantumCircuit clase.
Importar un programa de OpenQASM 2 a Qiskit
Dos funciones importan programas de OpenQASM 2 a Qiskit.
Estos son qasm2.load()que toma un nombre de archivo, y qasm2.loads()que toma el programa OpenQASM 2 como cadena.
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)Consulte la API Qiskit de OpenQASM 2 para obtener más información.
Importar programas sencillos
Para la mayoría de los programas OpenQASM 2, puede utilizar simplemente qasm2.load y qasm2.loads con un único argumento.
Ejemplo: importar un programa OpenQASM 2 como una cadena
Utilice qasm2.loads() para importar un programa OpenQASM 2 como una cadena en 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()Output:
┌───┐ ┌─┐
q_0: ┤ H ├──■──┤M├───
└───┘┌─┴─┐└╥┘┌─┐
q_1: ─────┤ X ├─╫─┤M├
└───┘ ║ └╥┘
c: 2/═══════════╩══╩═
0 1
Ejemplo: importar un programa OpenQASM 2 desde un archivo
Utilice load() para importar un programa OpenQASM 2 de un archivo a un QuantumCircuit:
import qiskit.qasm2
circuit = qiskit.qasm2.load("myfile.qasm")Enlace OpenQASM 2 puertas con puertas Qiskit
Por defecto, el importador de Qiskit OpenQASM 2 trata el archivo de inclusión "qelib1.inc" como una biblioteca estándar de facto.
El importador trata este archivo como si contuviera precisamente las puertas que se describe que contiene en el documento original que define OpenQASM 2.
Qiskit utilizará las puertas incorporadas en la biblioteca de circuitos para representar las puertas en "qelib1.inc".
Las puertas definidas en el programa mediante sentencias manuales OpenQASM 2 gate se construirán, por defecto, como personalizadas Qiskit Gate subclases.
Puede indicar al importador que utilice clases Gate específicas para las sentencias gate que encuentre.
También puede utilizar este mecanismo para tratar nombres de puerta adicionales como "incorporados", es decir, que no requieren una definición explícita.
Si especifica qué clases de compuerta utilizar para las declaraciones gate fuera de "qelib1.inc", el circuito resultante será normalmente más eficiente para trabajar.
Según Qiskit SDKv1.0, el exportador de Qiskit OpenQASM 2 (véase Exportar un circuito Qiskit a OpenQASM 2 ) sigue comportándose como si "qelib1.inc" tuviera más puertas de las que realmente tiene.
Esto significa que es posible que la configuración predeterminada del importador no permita importar un programa exportado por nuestro importador.
Consulte el ejemplo específico sobre cómo trabajar con el exportador heredado para resolver este problema.
Esta discrepancia es un comportamiento heredado de Qiskit, y se resolverá en una versión posterior de Qiskit.
Para pasar información sobre una instrucción personalizada al importador de OpenQASM 2, utilice la clase qasm2.CustomInstruction .
Tiene cuatro datos obligatorios, por orden:
- El nombre de la puerta, utilizado en el programa OpenQASM 2
- El número de parámetros angulares que toma la puerta
- Número de qubits sobre los que actúa la puerta
- La clase o función constructora Python para la puerta, que toma los parámetros de la puerta (pero no los qubits) como argumentos individuales
Si el importador encuentra una definición de gate que coincide con una instrucción personalizada determinada, utilizará esa información personalizada para reconstruir el objeto de puerta.
Si se encuentra una sentencia gate que coincide con name de una instrucción personalizada, pero no coincide ni con el número de parámetros ni con el número de qubits, el importador emitirá un mensaje QASM2ParseErrorpara indicar el desajuste entre la información suministrada y el programa.
Además, se puede establecer opcionalmente un quinto argumento builtin a True para que la puerta esté disponible automáticamente dentro del programa OpenQASM 2, aunque no esté definida explícitamente.
Si el importador encuentra una definición explícita de gate para una instrucción personalizada incorporada, la aceptará en silencio.
Como antes, si una definición explícita del mismo nombre no es compatible con la instrucción personalizada proporcionada, se producirá un error QASM2ParseError .
Esto es útil para la compatibilidad con antiguos exportadores de OpenQASM 2, y con algunas otras plataformas cuánticas que tratan las "puertas base" de su hardware como instrucciones incorporadas.
Qiskit proporciona un atributo de datos para trabajar con programas OpenQASM 2 producidos por versiones heredadas de las capacidades de exportación de OpenQASM 2 de Qiskit.
Es decir qasm2.LEGACY_CUSTOM_INSTRUCTIONSque se puede dar como argumento de custom_instructions a qasm2.load() y qasm2.loads().
Ejemplo: importar un programa creado por el exportador heredado de Qiskit
Este programa OpenQASM 2 utiliza compuertas que no están en la versión original de "qelib1.inc" sin declararlas, pero son compuertas estándar en la biblioteca de Qiskit.
Puedes usar qasm2.LEGACY_CUSTOM_INSTRUCTIONS para indicar al importador que utilice el mismo conjunto de puertas que el exportador de Qiskit OpenQASM 2.
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,
)Ejemplo: utilizar una clase de puerta concreta al importar un programa de OpenQASM 2
Qiskit no puede, en general, verificar si la definición en una declaración OpenQASM 2 gate corresponde exactamente a una puerta de la biblioteca estándar Qiskit.
En su lugar, Qiskit elige una puerta personalizada a partir de la definición precisa suministrada.
Esto puede ser menos eficaz que utilizar una de las puertas estándar incorporadas, o una puerta personalizada definida por el usuario.
Puede definir manualmente las sentencias gate con clases concretas.
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,
)Ejemplo: definir una nueva puerta integrada en un programa OpenQASM 2
Si se establece el argumento builtin=True , una puerta personalizada no necesita tener una definición asociada.
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,
)Definir funciones clásicas personalizadas
OpenQASM 2 incluye algunas funciones clásicas incorporadas para utilizar en argumentos de puerta.
Puede ampliar el lenguaje con más funciones utilizando el argumento custom_classical de qasm2.load() y qasm2.loads()con la clase qasm2.CustomClassical clase.
Para definir una función clásica personalizada, debe suministrar:
- El nombre de la función tal y como aparece en el programa OpenQASM 2
- El número de argumentos de coma flotante que acepta
- Un objeto invocable Python que evalúa la función
Todas las funciones clásicas personalizadas definidas son tratadas por el importador como incorporadas al lenguaje OpenQASM 2. No existe una forma oficial dentro del lenguaje OpenQASM 2 para definir nuevas funciones; se trata de una extensión de Qiskit.
Ejemplo: utilizar instrucciones clásicas personalizadas
Aquí proporcionamos dos funciones clásicas personalizadas.
La primera es sencilla, y sólo añade uno a su entrada.
La segunda es la función math.atan2, que representa la operación matemática de forma sensible a los cuadrantes.
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)Modalidad estricta
Por defecto, este analizador sintáctico es más relajado que la especificación oficial.
Permite comas finales en las listas de parámetros; puntos y comas innecesarios (declaración vacía); omisión de la declaración de versión OPENQASM 2.0; ; y varias otras mejoras de calidad de vida sin emitir ningún error.
Sin embargo, puede utilizar el modo "letra-de-la-específica" con strict=True.
Exportar un circuito Qiskit a OpenQASM 2
Qiskit también puede exportar un QuantumCircuit a OpenQASM 2.
Se utiliza la función qasm2.dump() para escribir en un fichero, y qasm2.dumps() para escribir en una cadena.
Actualmente, estas funciones tienen una interfaz muy sencilla: aceptan un circuito y, sólo en el caso de qasm2.dump()una ubicación en la que escribir la salida.
El exportador OpenQASM 2 de Qiskit sigue asumiendo una versión heredada y no estándar del archivo de inclusión "qelib1.inc" .
Esto se resolverá en una versión posterior de Qiskit, pero mientras tanto, si necesita volver a importar un programa OpenQASM 2 creado con Qiskit, utilice el ejemplo anterior para saber cómo decirle al importador acerca de las puertas de legado.
Ejemplo: exportar un circuito a 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")Próximos pasos
- Aprenda a generar código OpenQASM en la guía IBM Quantum Composer.
- Consulte la referencia de la API de Qiskit en OpenQASM 2.
- Consulte el apartado «Verificar su programa ».
- Visite la especificación OpenQASM Live.