OpenQASM 2 e o Qiskit SDK
O código desta página foi desenvolvido usando os seguintes requisitos. Recomendamos o uso dessas versões ou de versões mais recentes.
qiskit[all]~=2.5.0
O Qiskit SDK fornece algumas ferramentas para conversão entre OpenQASM representações de programas quânticos e a classe QuantumCircuit classe.
Importar um programa OpenQASM 2 para o Qiskit
Duas funções importam programas do OpenQASM 2 para o Qiskit.
Esses são qasm2.load(), que recebe um nome de arquivo, e qasm2.loads(), que recebe o programa OpenQASM 2 como uma cadeia de caracteres.
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 a API do Qiskit OpenQASM 2 para obter mais informações.
Importar programas simples
Para a maioria dos programas do OpenQASM 2, basta usar qasm2.load e qasm2.loads com um único argumento.
Exemplo: importar um programa OpenQASM 2 como uma string
Use o site qasm2.loads() para importar um programa OpenQASM 2 como uma string para um arquivo 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
Exemplo: importar um programa OpenQASM 2 de um arquivo
Use o site load() para importar um programa OpenQASM 2 de um arquivo para um arquivo QuantumCircuit:
import qiskit.qasm2
circuit = qiskit.qasm2.load("myfile.qasm")Link OpenQASM 2 portas com portas Qiskit
Por padrão, o importador OpenQASM 2 do Qiskit trata o arquivo de inclusão "qelib1.inc" como uma biblioteca padrão de fato.
O importador trata esse arquivo como contendo exatamente as portas descritas no documento original que define OpenQASM 2.
O Qiskit usará as portas integradas na biblioteca de circuitos para representar as portas em "qelib1.inc".
As portas definidas no programa pelo manual OpenQASM 2 gate declarações serão, por padrão, construídas como Qiskit Gate subclasses personalizadas.
Você pode instruir o importador a usar classes Gate específicas para as declarações gate que ele encontrar.
Você também pode usar esse mecanismo para tratar nomes de portas adicionais como "incorporados", ou seja, que não exigem uma definição explícita.
Se você especificar quais classes de porta usar para as instruções gate fora de "qelib1.inc", o circuito resultante normalmente será mais eficiente para trabalhar.
A partir de Qiskit SDKv1.0, o exportador OpenQASM 2 do Qiskit (consulte Exportar um circuito Qiskit para OpenQASM 2 ) ainda se comporta como se "qelib1.inc" tivesse mais portas do que realmente tem.
Isso significa que as configurações padrão do importador podem não ser capazes de importar um programa exportado pelo nosso importador.
Veja o exemplo específico sobre como trabalhar com o exportador legado para resolver esse problema.
Essa discrepância é um comportamento herdado do Qiskit e será resolvida em uma versão posterior do Qiskit.
Para passar informações sobre uma instrução personalizada para o importador do OpenQASM 2, use a classe qasm2.CustomInstruction .
Ele contém quatro informações obrigatórias, em ordem:
- O nome do portão, usado no programa OpenQASM 2
- O número de parâmetros de ângulo que a porta usa
- O número de qubits em que a porta atua
- A classe ou função do construtor Python para a porta, que recebe os parâmetros da porta (mas não os qubits) como argumentos individuais
Se o importador encontrar uma definição de gate que corresponda a uma determinada instrução personalizada, ele usará essas informações personalizadas para reconstruir o objeto de porta.
Se for encontrada uma instrução gate que corresponda ao name de uma instrução personalizada, mas que não corresponda ao número de parâmetros e ao número de qubits, o importador exibirá um QASM2ParseErrorpara indicar a incompatibilidade entre as informações fornecidas e o programa.
Além disso, um quinto argumento builtin pode ser opcionalmente definido como True para tornar a porta automaticamente disponível no programa OpenQASM 2, mesmo que não esteja explicitamente definida.
Se o importador encontrar uma definição explícita do gate para uma instrução personalizada incorporada, ele a aceitará silenciosamente.
Como antes, se uma definição explícita com o mesmo nome não for compatível com a instrução personalizada fornecida, será gerado um QASM2ParseError será gerado.
Isso é útil para a compatibilidade com exportadores antigos do OpenQASM 2 e com algumas outras plataformas quânticas que tratam as "portas básicas" do hardware como instruções integradas.
O Qiskit fornece um atributo de dados para trabalhar com programas OpenQASM 2 produzidos por versões antigas dos recursos de exportação OpenQASM 2 do Qiskit.
Isso é qasm2.LEGACY_CUSTOM_INSTRUCTIONSque pode ser fornecido como o argumento custom_instructions para qasm2.load() e qasm2.loads().
Exemplo: importar um programa criado pelo exportador legado do Qiskit
Esse programa OpenQASM 2 usa portas que não estão na versão original do "qelib1.inc" sem declará-las, mas são portas padrão na biblioteca do Qiskit.
Você pode usar qasm2.LEGACY_CUSTOM_INSTRUCTIONS para dizer facilmente ao importador para usar o mesmo conjunto de portas que o exportador OpenQASM 2 do Qiskit usou anteriormente.
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,
)Exemplo: use uma classe de porta específica ao importar um programa OpenQASM 2
O Qiskit não pode, em geral, verificar se a definição em uma declaração OpenQASM 2 gate corresponde exatamente a uma porta da biblioteca padrão do Qiskit.
Em vez disso, a Qiskit escolhe um portão personalizado usando a definição precisa fornecida.
Isso pode ser menos eficiente do que usar uma das portas padrão integradas ou uma porta personalizada definida pelo usuário.
Você pode definir manualmente as declarações gate com classes específicas.
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,
)Exemplo: definir um novo gate integrado em um programa OpenQASM 2
Se o argumento builtin=True for definido, um portão personalizado não precisará ter uma definição associada.
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,
)Defina funções clássicas personalizadas
OpenQASM 2 inclui algumas funções clássicas incorporadas para uso em argumentos de porta.
Você pode estender a linguagem com mais funções usando o argumento custom_classical para qasm2.load() e qasm2.loads()com a classe qasm2.CustomClassical classe.
Para definir uma função clássica personalizada, você deve fornecer:
- O nome da função como aparece no programa OpenQASM 2
- O número de argumentos de ponto flutuante que ele aceita
- Um objeto Python chamável que avalia a função
Todas as funções clássicas personalizadas definidas são tratadas como incorporadas à linguagem OpenQASM 2 pelo importador. Não há uma maneira oficial na linguagem OpenQASM 2 de definir novas funções; essa é uma extensão do Qiskit.
Exemplo: use instruções clássicas personalizadas
Aqui fornecemos duas funções clássicas personalizadas.
O primeiro é simples e apenas adiciona um à sua entrada.
A segunda é a função math.atan2, que representa a operação matemática de forma sensível ao 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)Modo estrito
Por padrão, esse analisador é mais relaxado do que a especificação oficial.
Ele permite vírgulas finais em listas de parâmetros, pontos e vírgulas desnecessários (declaração vazia), omissão da declaração da versão OPENQASM 2.0; e várias outras melhorias de qualidade de vida sem emitir nenhum erro.
No entanto, você pode usar o modo "letter-of-the-spec" com strict=True.
Exportar um circuito Qiskit para OpenQASM 2
O Qiskit também pode exportar um QuantumCircuit para OpenQASM 2.
Você usa a função qasm2.dump() para gravar em um arquivo e qasm2.dumps() para gravar em uma string.
Atualmente, essas funções têm uma interface muito simples: elas aceitam um circuito e, somente no caso de qasm2.dump()um local para gravar a saída.
O exportador OpenQASM 2 do Qiskit ainda assume uma versão antiga e não padrão do arquivo de inclusão "qelib1.inc" .
Isso será resolvido em uma versão posterior do Qiskit, mas, enquanto isso, se você precisar reimportar um programa OpenQASM 2 criado com o Qiskit, use o exemplo acima para saber como informar o importador sobre as portas legadas.
Exemplo: exportar um circuito para 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óximas etapas
- Saiba como gerar o código OpenQASM no guia IBM Quantum Composer.
- Consulte a referência da API do Qiskit em OpenQASM 2.
- Consulte o tópico “Verifique seu programa ”.
- Visite o site OpenQASM Live Specification.