Representar computadores quânticos para o transpiler
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 qiskit-ibm-runtime~=0.47.0
Para converter um circuito abstrato em um circuito ISA que possa ser executado em uma QPU (unidade de processamento quântico) específica, o transpilador precisa de determinadas informações sobre a QPU. Essas informações são encontradas em dois locais: o objeto BackendV2 (ou BackendV1 herdado) para o qual você planeja enviar trabalhos e o atributo Target do backend.
- O
Targetcontém todas as restrições relevantes de um dispositivo, tais como o conjunto de instruções suportadas, conectividade qubit e informações de pulso ou temporização. - O
Backendpossui umTargetpor padrão, contém informações adicionais — como oInstructionScheduleMap— e fornece a interface para enviar tarefas de circuito quântico.
Você também pode fornecer explicitamente informações para o transpilador usar, por exemplo, se você tiver um caso de uso específico ou se acreditar que essas informações ajudarão o transpilador a gerar um circuito mais otimizado.
A precisão com que o transpilador produz o circuito mais adequado para um hardware específico depende da quantidade de informações que o Target ou Backend tem sobre suas restrições.
Como muitos dos algoritmos de transpilação subjacentes são estocásticos, não há garantia de que um circuito melhor será encontrado.
Esta página apresenta vários exemplos de como passar informações da QPU para o transpilador.
Configuração padrão
O uso mais simples do transpilador é fornecer todas as informações do QPU por meio do Backend ou Target. Para entender melhor como o transpilador funciona, construa um circuito e transpile-o com informações diferentes, como segue.
Importe as bibliotecas necessárias e instancie a QPU: Para converter um circuito abstrato em um circuito ISA que possa ser executado em um processador específico, o transpilador precisa de determinadas informações sobre o processador. Normalmente, essas informações são armazenadas no arquivo Backend ou Target fornecido ao transpilador, e nenhuma outra informação é necessária. No entanto, você também pode fornecer explicitamente informações para o transpilador usar, por exemplo, se tiver um caso de uso específico ou se acreditar que essas informações ajudarão o transpilador a gerar um circuito mais otimizado.
Este tópico apresenta vários exemplos de como passar informações para o transpiler.
Esses exemplos utilizam o alvo do backend qiskit_ibm_runtimeFakeSherbrooke simulado. No entanto, você pode testá-lo em qualquer backend real ou simulado compatível com o Qiskit. Seus resultados podem ser diferentes.
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
target = backend.targetO circuito de exemplo usa uma instância de efficient_su2 da biblioteca de circuitos do Qiskit.
from qiskit.circuit.library import efficient_su2
qc = efficient_su2(12, entanglement="circular", reps=1)
qc.draw("mpl")Output:
Este exemplo usa configurações padrão para transpilar para o site backend target, que fornece todas as informações necessárias para converter o circuito em um que será executado no backend.
from qiskit.transpiler import generate_preset_pass_manager
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=target, seed_transpiler=12345
)
qc_t_target = pass_manager.run(qc)
qc_t_target.draw("mpl", idle_wires=False, fold=-1)Output:
Este exemplo é usado nas seções posteriores deste tópico para ilustrar que o mapa de acoplamento e o conjunto de instruções suportadas são as informações essenciais a serem passadas ao transpilador para a construção ideal do circuito. A QPU geralmente pode selecionar configurações padrão para outras informações que não são transmitidas, como temporização e programação.
Mapa de acoplamento
O mapa de acoplamento é um gráfico que mostra quais qubits estão conectados e, portanto, têm portas de dois qubits entre eles. Às vezes, esse gráfico é direcional, o que significa que as portas de dois qubits só podem ir em uma direção. No entanto, o transpilador sempre pode inverter a direção de uma porta adicionando portas adicionais de um único qubit. Um circuito quântico abstrato sempre pode ser representado nesse gráfico, mesmo que sua conectividade seja limitada, com a introdução de portas SWAP para mover as informações quânticas.
Os qubits de nossos circuitos abstratos são chamados de qubits virtuais e os do mapa de acoplamento são qubits físicos. O transpilador fornece um mapeamento entre qubits virtuais e físicos. Uma das primeiras etapas da transpilação, o estágio de layout, realiza esse mapeamento.
Embora o estágio de roteamento esteja entrelaçado com o estágio de layout - que seleciona os qubits reais - por padrão, este tópico os trata como estágios separados para simplificar. A combinação de roteamento e layout é chamada de mapeamento de qubit. Saiba mais sobre esses estágios no tópico Estágios do Transpiler.
Passe o argumento da palavra-chave coupling_map para ver seu efeito no transpilador:
coupling_map = target.build_coupling_map()
pass_manager = generate_preset_pass_manager(
optimization_level=0, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv0 = pass_manager.run(qc)
qc_t_cm_lv0.draw("mpl", idle_wires=False, fold=-1)Output:
Como mostrado acima, várias portas SWAP foram inseridas (cada uma consistindo em três portas CX), o que causará muitos erros nos dispositivos atuais. Para ver quais qubits estão selecionados na topologia real do qubit, use o site plot_circuit_layout do Qiskit Visualizations:
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv0, backend, view="physical")Output:
Isso mostra que nossos qubits virtuais 0-11 foram trivialmente mapeados para a linha de qubits físicos 0-11. Vamos voltar ao padrão (optimization_level=1), que usa VF2Layout se for necessário algum roteamento.
pass_manager = generate_preset_pass_manager(
optimization_level=1, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv1 = pass_manager.run(qc)
qc_t_cm_lv1.draw("mpl", idle_wires=False, fold=-1)Output:
Agora não há portas SWAP inseridas e os qubits físicos selecionados são os mesmos quando se usa a classe target .
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv1, backend, view="physical")Output:
Agora o layout está em um anel. Como esse layout respeita a conectividade do circuito, não há portas SWAP, o que proporciona um circuito muito melhor para a execução.
Instruções suportadas
Todo computador quântico suporta um conjunto limitado de instruções. Cada porta do circuito deve ser traduzida para os elementos deste conjunto. Este conjunto deve consistir em portas de um e dois qubits que fornecem um conjunto de portas universal, o que significa que qualquer operação quântica pode ser decomposta nessas portas. Isso é feito pelo BasisTranslator e basis_gates pode ser especificado como um argumento de palavra-chave para o transpiler para fornecer essas informações.
basis_gates = list(target.operation_names)
print(basis_gates)Output:
['x', 'switch_case', 'for_loop', 'rz', 'sx', 'measure', 'id', 'ecr', 'delay', 'reset', 'if_else']
As portas padrão de um qubit no FakeSherbrooke são rz, x, e sx, e a porta padrão de dois qubits é ecr (ressonância cruzada com eco). As portas CX são construídas a partir de ecr portas, de modo que, em algumas QPUs, ecr é especificada como a porta de base de dois qubits, enquanto em outras cx é a predefinição. O ecr portão é a parte que se entrelaça do cx portão. Além das portas de controle, há também as delay``measurement instruções e.
As QPUs têm portas básicas padrão, mas você pode escolher as portas que desejar, desde que forneça a instrução ou adicione portas de pulso (consulte Criar passagens do transpiler ) Os portões básicos padrão são aqueles para os quais foram feitas calibrações na QPU, portanto, não é necessário fornecer mais portões de instrução/pulso. Por exemplo, em algumas QPUs, cx é o portão padrão de dois qubits e, ecr em outras,. Consulte a lista de portas e operações nativas possíveis para obter mais detalhes.
pass_manager = generate_preset_pass_manager(
optimization_level=1,
coupling_map=coupling_map,
basis_gates=basis_gates,
seed_transpiler=12345,
)
qc_t_cm_bg = pass_manager.run(qc)
qc_t_cm_bg.draw("mpl", idle_wires=False, fold=-1)Output:
Observe que os CXGate objetos foram decompostos em ecr portas e portas de base de qubit único.
Taxas de erro do dispositivo
A classe Target pode conter informações sobre as taxas de erro das operações no dispositivo.
Por exemplo, o código a seguir recupera as propriedades da porta de ressonância cruzada ecoada (ECR) entre o qubit 1 e 0 (observe que a porta ECR é direcional):
target["ecr"][(1, 0)]Output:
InstructionProperties(duration=5.333333333333332e-07, error=0.007494257741828603)
A saída exibe a duração da porta (em segundos) e sua taxa de erro. Para revelar informações de erro ao transpilador, crie um modelo de destino com basis_gates e coupling_map acima e preencha-o com valores de erro do backend FakeSherbrooke.
from qiskit.transpiler import Target
from qiskit.circuit.controlflow import IfElseOp, SwitchCaseOp, ForLoopOp
err_targ = Target.from_configuration(
basis_gates=basis_gates,
coupling_map=coupling_map,
num_qubits=target.num_qubits,
custom_name_mapping={
"if_else": IfElseOp,
"switch_case": SwitchCaseOp,
"for_loop": ForLoopOp,
},
)
for i, (op, qargs) in enumerate(target.instructions):
if op.name in basis_gates:
err_targ[op.name][qargs] = target.instruction_properties(i)Transpile com nosso novo alvo err_targ como alvo:
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=err_targ, seed_transpiler=12345
)
qc_t_cm_bg_et = pass_manager.run(qc)
qc_t_cm_bg_et.draw("mpl", idle_wires=False, fold=-1)Output:
Como o alvo inclui informações de erro, a passagem VF2PostLayout tenta encontrar os qubits ideais a serem usados, resultando no mesmo circuito que foi originalmente encontrado com os mesmos qubits físicos.
Próximas etapas
- Entenda as configurações padrão e as opções de configuração do Transpilation.
- Revise o tópico Parâmetros comumente usados para transpilação.
- Experimente o guia Comparar configurações do transpiler.
- Consulte a documentação da API Transpile.