Skip to main content
IBM Quantum Platform

Rappresentare i computer quantistici per il transpiler

  • Il codice di questa pagina è stato sviluppato in base ai seguenti requisiti. Si consiglia di utilizzare queste versioni o versioni più recenti.

    qiskit[all]~=2.5.1
    qiskit-ibm-runtime~=0.47.0
    

Per convertire un circuito astratto in un circuito ISA in grado di funzionare su una specifica QPU (unità di elaborazione quantistica), il transpiler ha bisogno di alcune informazioni sulla QPU. Queste informazioni si trovano in due luoghi: l'oggetto BackendV2 (o legacy BackendV1) a cui si intende inviare i lavori e l'attributo Target del backend.

  • Il Target contiene tutti i vincoli rilevanti di un dispositivo, come il set di istruzioni supportato, la connettività dei qubit e le informazioni relative agli impulsi o alla temporizzazione.
  • Il Backend possiede un Target di default, contiene informazioni aggiuntive -- come il InstructionScheduleMap, e fornisce l'interfaccia per l'invio di lavori di circuiti quantistici.

Si possono anche fornire esplicitamente informazioni da utilizzare per il transpiler, ad esempio se si ha un caso d'uso specifico o se si ritiene che queste informazioni aiutino il transpiler a generare un circuito più ottimizzato.

La precisione con cui il transpiler produce il circuito più appropriato per un hardware specifico dipende dalla quantità di informazioni che Target o Backend ha sui suoi vincoli.

Note

Poiché molti degli algoritmi di transpilazione sottostanti sono stocastici, non c'è alcuna garanzia che venga trovato un circuito migliore.

Questa pagina mostra diversi esempi di come trasmettere le informazioni relative alla QPU al transpiler.


Configurazione predefinita

L'uso più semplice del transpiler è quello di fornire tutte le informazioni sulla QPU fornendo il sito Backend o Target. Per capire meglio come funziona il transpiler, costruite un circuito e transpilatelo con informazioni diverse, come segue.

Importare le librerie necessarie e istanziare la QPU: Per convertire un circuito astratto in un circuito ISA in grado di funzionare su un processore specifico, il transpiler ha bisogno di alcune informazioni sul processore. In genere, queste informazioni sono memorizzate nel file Backend o Target fornito al transpiler e non sono necessarie altre informazioni. Tuttavia, si possono anche fornire esplicitamente informazioni da utilizzare per il transpiler, ad esempio se si ha un caso d'uso specifico o se si ritiene che queste informazioni aiutino il transpiler a generare un circuito più ottimizzato.

In questa sezione vengono illustrati diversi esempi di come trasmettere informazioni al transpiler.

Note

Questi esempi utilizzano il target del backend qiskit_ibm_runtimeFakeSherbrooke simulato. Tuttavia, puoi provarlo su qualsiasi backend reale o simulato compatibile con Qiskit. I tuoi risultati potrebbero essere diversi.

from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

backend = FakeSherbrooke()
target = backend.target

Il circuito di esempio utilizza un'istanza di efficient_su2 della libreria di circuiti di 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

Questo esempio utilizza le impostazioni predefinite per effettuare il transpile su backend's target, che fornisce tutte le informazioni necessarie per convertire il circuito in uno che funzionerà sul 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

Questo esempio viene utilizzato nelle sezioni successive di questo argomento per illustrare che la mappa di accoppiamento e il set di istruzioni supportato sono le informazioni essenziali da trasmettere al transpiler per una costruzione ottimale del circuito. La QPU può solitamente selezionare impostazioni predefinite per altre informazioni che non vengono trasmesse, come la temporizzazione e la programmazione.


Mappa di accoppiamento

La mappa di accoppiamento è un grafico che mostra quali qubit sono connessi e quindi hanno porte a due qubit tra loro. A volte questo grafico è direzionale, il che significa che le porte a due qubit possono andare solo in una direzione. Tuttavia, il transpiler può sempre invertire la direzione di un gate aggiungendo ulteriori gate a singolo qubit. Un circuito quantistico astratto può sempre essere rappresentato su questo grafo, anche se la sua connettività è limitata, introducendo porte SWAP per spostare le informazioni quantistiche.

I qubit dei nostri circuiti astratti sono chiamati qubit virtuali e quelli della mappa di accoppiamento sono qubit fisici. Il transpiler fornisce una mappatura tra qubit virtuali e fisici. Una delle prime fasi della transpilazione, la fase di layout, esegue questa mappatura.

Note

Sebbene lo stadio di instradamento sia interconnesso con lo stadio di layout, che seleziona i qubit effettivi, per impostazione predefinita, questo argomento li tratta come stadi separati per semplicità. La combinazione di routing e layout è chiamata mappatura dei qubit. Per ulteriori informazioni su questi stadi, consultare l'argomento Stadi del transpiler.

Passare l'argomento della parola chiave coupling_map per vedere il suo effetto sul transpiler:

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

Come mostrato sopra, sono state inserite diverse porte SWAP (ciascuna composta da tre porte CX), che causano molti errori sui dispositivi attuali. Per vedere quali qubit sono selezionati sulla topologia di qubit effettiva, utilizzare plot_circuit_layout di 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

Questo dimostra che i nostri qubit virtuali 0-11 sono stati mappati banalmente sulla linea dei qubit fisici 0-11. Torniamo al valore predefinito (optimization_level=1), che utilizza VF2Layout se è necessario un instradamento.

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

Ora non sono state inserite porte SWAP e i qubit fisici selezionati sono gli stessi quando si utilizza la 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

Ora il layout si trova in un anello. Poiché questo layout rispetta la connettività del circuito, non ci sono porte SWAP e il circuito risulta migliore per l'esecuzione.


Istruzioni supportate

Ogni computer quantistico supporta un set di istruzioni limitato. Ogni porta del circuito deve essere tradotta negli elementi di questo insieme. Questo insieme dovrebbe essere composto da porte a uno e due qubit che forniscono un insieme di porte universali, il che significa che qualsiasi operazione quantistica può essere scomposta in tali porte. Questo viene fatto da BasisTranslator e basis_gates può essere specificato come argomento chiave al transpiler per fornire queste informazioni.

basis_gates = list(target.operation_names)
print(basis_gates)

Output:

['sx', 'switch_case', 'if_else', 'rz', 'for_loop', 'ecr', 'id', 'reset', 'measure', 'x', 'delay']

I gate predefiniti a un qubit su FakeSherbrooke sono rz, x, e sx, mentre il gate predefinito a due qubit è ecr (risonanza incrociata con eco). I gate CX sono costituiti da ecr gate, quindi su alcune QPU ecr è specificato come gate di base a due qubit, mentre su altre cx è l'impostazione predefinita. Il ecr gate è la parte che crea l'entanglement del cx gate. Oltre alle porte di controllo, esistono anche le istruzioni delay``measurement e.

Note

Le QPU hanno porte di base predefinite, ma è possibile scegliere qualsiasi porta desiderata, purché si fornisca l'istruzione o si aggiungano porte a impulsi (vedere Creare passaggi del transpiler ) I gate di base predefiniti sono quelli per cui sono state eseguite le calibrazioni sulla QPU, quindi non è necessario fornire ulteriori gate di istruzioni/impulsi. Ad esempio, su alcune QPU cx è il gate a due qubit predefinito e ecr su altre. Per ulteriori dettagli, consultare l'elenco dei possibili gate e operazioni nativi.

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

Si noti che gli CXGate oggetti sono stati scomposti in ecr porte e porte di base a singolo qubit.


Tassi di errore dei dispositivi

La classe Target può contenere informazioni sui tassi di errore delle operazioni sul dispositivo. Ad esempio, il codice seguente recupera le proprietà del gate ECR (echoed cross-resonance) tra i qubit 1 e 0 (si noti che il gate ECR è direzionale):

target["ecr"][(1, 0)]

Output:

InstructionProperties(duration=5.333333333333332e-07, error=0.007494257741828603)

L'uscita visualizza la durata del gate (in secondi) e il suo tasso di errore. Per rivelare le informazioni sugli errori al transpiler, costruire un modello di destinazione con i modelli basis_gates e coupling_map di cui sopra e popolarlo con i valori degli errori dal 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 con il nostro nuovo obiettivo err_targ come bersaglio:

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

Poiché il target include informazioni sull'errore, il passaggio VF2PostLayout cerca di trovare i qubit ottimali da utilizzare, ottenendo lo stesso circuito trovato originariamente con gli stessi qubit fisici.


Passi successivi

Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.