Zum Hauptinhalt springen

Executor-Schnellstart

Paketversionen

Der Code auf dieser Seite wurde mit den folgenden Anforderungen entwickelt. Wir empfehlen, diese Versionen oder neuere zu verwenden.

qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
samplomatic~=0.18.0
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime samplomatic

Ähnlich wie das Sampler-Primitive sampelt Executor Ausgaberegister aus Quantenschaltungs-Ausführungen, hat jedoch keine eingebaute Fehlerunterdrückung oder -minderung. Stattdessen ist er Teil des directed-execution-Modells, das die Bausteine bereitstellt, um Design-Absichten auf der Client-Seite zu erfassen, und die aufwendige Generierung von Schaltungsvarianten auf die Server-Seite verlagert. Executor folgt den Direktiven aus Circuit-Annotationen und Optionen, generiert und bindet Parameterwerte, führt die gebundenen Schaltungen auf der Hardware aus und gibt die Ausführungsergebnisse und Metadaten zurück. Er trifft keine impliziten Entscheidungen für dich und gibt dir volle Kontrolle und Transparenz.

hinweis

Das Qiskit-Paket hat noch keine Basisklasse für das Executor-Primitive.

Bevor du beginnst

Einige der Codebeispiele auf dieser Seite verwenden samplex, das Teil des Samplomatic-Pakets ist. Deshalb musst du Samplomatic installieren, bevor du diese Codeblöcke ausführst, wie im folgenden Codeblock gezeigt. Weitere Informationen findest du in der Samplomatic-Dokumentation.

pip install samplomatic

# For visualization support, include the visualization dependencies.
# pip install samplomatic[vis]

Schritte zur Verwendung des Executor-Primitive

1. Das Konto initialisieren

Da Qiskit Runtime ein verwalteter Dienst ist, musst du zunächst dein Konto initialisieren. Du kannst dann den QPU auswählen, den du zur Berechnung des Erwartungswerts verwenden möchtest.

Folge den Schritten unter Richte dein IBM Cloud®-Konto ein, falls du noch kein Konto hast.

from qiskit_ibm_runtime import QiskitRuntimeService, Executor
from qiskit_ibm_runtime.quantum_program import QuantumProgram
from qiskit.circuit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from samplomatic.transpiler import generate_boxing_pass_manager
from samplomatic import build

# Initialize the service and choose a backend
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
print(backend)
<IBMBackend('ibm_fez')>

2. Einen Circuit erstellen und transpilieren

Du benötigst mindestens einen Circuit, um das Executor-Primitive zu verwenden. Er kann optional Parameter haben.

# Generate the circuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.h(1)
circuit.cz(0, 1)
circuit.h(1)

# Using `measure_all` automatically creates the necessary
# classical registers.
circuit.measure_all()

Der Circuit muss so transformiert werden, dass er nur Anweisungen verwendet, die vom QPU unterstützt werden (sogenannte Instruction Set Architecture (ISA)-Circuits). Verwende dafür den Transpiler.

# Transpile the circuit
preset_pass_manager = generate_preset_pass_manager(
backend=backend, optimization_level=0
)
isa_circuit = preset_pass_manager.run(circuit)

3. Ein QuantumProgram initialisieren

Initialisiere ein QuantumProgram mit deiner Arbeitslast. Ein QuantumProgram besteht aus QuantumProgramItems. In der Regel enthält jedes Element einen Circuit, einen Satz von Parameterwerten und möglicherweise ein samplex, um den Circuit-Inhalt zu randomisieren. Alle Details findest du unter Executor-Eingaben und -Ausgaben.

Die folgende Zelle initialisiert ein QuantumProgram und gibt an, 25 Shots durchzuführen. Anschließend wird der transpilierte Ziel-Circuit angehängt.

# Initialize an empty program
program = QuantumProgram(shots=25)

# Append the circuit to the program
program.append_circuit_item(isa_circuit)

4. Optional: Gates und Messungen in annotierte Boxen gruppieren

Das Gruppieren von Anweisungen in Boxen und deren Annotierung ist der primäre Weg, um deine Absicht anzugeben. Im folgenden Beispiel verwenden wir generate_boxing_pass_manager und seine Twirling-Parameter, um Zwei-Qubit-Gates und Messungen in Boxen zu gruppieren und Twirling-Annotierung anzuwenden.

# Generate a boxing pass manager to group gates
# and measurements into boxes and add
# a`Twirl` annotation.
boxes_pm = generate_boxing_pass_manager(
# Add gate twirling
enable_gates=True,
# Add measurement twirling
enable_measures=True,
)

boxed_circuit = boxes_pm.run(isa_circuit)
boxed_circuit.draw("mpl", idle_wires=False)

Output of the previous code cell

5. Optional: Einen Template-Circuit und Samplex erstellen und zum Programm hinzufügen

Verwende als Nächstes die Samplomatic-Methode build, um das Template-Circuit- und Samplex-Paar zu generieren. Der Template-Circuit ist strukturell äquivalent zum ursprünglichen Circuit. Allerdings werden seine Einzel-Qubit-Gates durch parametrisierte Gates ersetzt, um die vorgeschriebenen Annotierungen zu implementieren (Gate- und Messungs-Twirling in diesem Beispiel). Das Samplex kodiert alle Informationen, die benötigt werden, um randomisierte Parameter für den Template-Circuit zu generieren.

Nachdem du das Template-Circuit- und Samplex-Paar generiert hast, verwende die Methode append_samplex_item, um das Paar zum Programm hinzuzufügen.

Die vollständigen Details zu samplomatic.samplex.Samplex und seinen Argumenten findest du in der Samplomatic-API-Dokumentation.

# Build the template circuit and the samplex
template_circuit, samplex = build(boxed_circuit)

# Append the template circuit and samplex as a `samplex_item`
program.append_samplex_item(
template_circuit,
samplex=samplex,
shape=(num_randomizations := 20,),
)

6. Executor aufrufen und Ergebnisse abrufen

Führe das QuantumProgram auf einem IBM®-Backend aus, indem du das Executor-Primitive mit Standardoptionen verwendest. Unter Executor-Optionen erfährst du mehr über die verfügbaren Optionen.

# Initialize an Executor with the default options
executor = Executor(mode=backend)

# Submit the job
job = executor.run(program)
job
<RuntimeJobV2('d8286580bvlc73d1vmsg', 'executor')>
# Retrieve the result
result = job.result()

Das Ergebnis ist vom Typ QuantumProgramResult. Unter Executor-Eingabe und -Ausgabe erfährst du mehr über das Ergebnisobjekt.

Nächste Schritte

Empfehlungen