Skip to main content
IBM Quantum Platform

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 Target conté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 Backend possui um Target por padrão, contém informações adicionais — como o InstructionScheduleMap— 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.

Note

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.

Note

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.target

O 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:

Output of the previous code cell

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:

Output of the previous code cell

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.

Note

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:

Output of the previous code cell

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:

Output of the previous code cell

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:

Output of the previous code cell

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:

Output of the previous code cell

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.

Note

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:

Output of the previous code cell

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:

Output of the previous code cell

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

Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.