Zum Hauptinhalt springen

Erste Schritte mit Qiskit Functions

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-catalog qiskit-ibm-runtime
# This cell is hidden from users
# It gets these details programmatically so we can test this notebook
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.circuit.random import random_circuit
from qiskit_ibm_catalog import QiskitFunctionsCatalog

service = QiskitRuntimeService()
instance = service.active_account()["instance"]
backend_name = service.least_busy().name
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
qesem_function = catalog.load("qedma/qesem")
circuit = random_circuit(num_qubits=2, depth=2, seed=42)
observable = "Z" * circuit.num_qubits

Premium-, Flex- und On-Prem-Plan-Nutzer (über die IBM Quantum Platform API) können kostenlos mit IBM Qiskit Functions beginnen oder eine Lizenz von einem der Partner erwerben, die eine Funktion zum Katalog beigetragen haben.

Eine kostenlose Testversion für Qiskit Functions von Drittanbietern anfordern

Um eine kostenlose Testversion anzufordern, navigiere zum Qiskit Functions Catalog und öffne das Detailfenster. Klicke auf Request a free trial und fülle die vom Functions-Partner benötigten Informationen aus, einschließlich der IBM Cloud AccessGroupId:

  1. Navigiere zu IBM Cloud IAM.

  2. Überprüfe die Berechtigung.

    • Wechsle in der Menüleiste im Header dein Konto zu einem im folgenden Format: XXXXXXX - [Organization Name]

    • Stelle sicher, dass die Organisation dieselbe ist, die mit deinem Premium-Konto verknüpft ist.

    • Wenn du "[Your Name]'s Account" siehst, verwendest du dein persönliches Konto, das nicht für den Premium-Zugriff berechtigt ist.

  3. Finde deine Access-Group-ID.

    • Klicke auf einen Gruppennamen.

    • Klicke auf Details.

    • Kopiere die Access-Group-ID. Sie sollte mit AccessGroup- beginnen.

Den Qiskit Functions Catalog-Client installieren

  1. Um mit der Nutzung von Qiskit Functions zu beginnen, installiere den IBM Qiskit Functions Catalog-Client:

    pip install qiskit-ibm-catalog
  2. Rufe deinen API-Schlüssel vom IBM Quantum Platform-Dashboard ab und aktiviere deine virtuelle Python-Umgebung. Sieh dir die Installationsanweisungen an, falls du noch keine virtuelle Umgebung eingerichtet hast.

    If you are working in a trusted Python environment (such as on a personal laptop or workstation), use the save_account() method to save your credentials locally. (Skip to the next step if you are not using a trusted environment, such as a shared or public computer, to authenticate to IBM Quantum Platform.)

    Die Instanz, mit der du dich authentifizierst, muss Zugriff auf Qiskit Functions aktiviert haben. Um dies auf einer bestehenden Instanz zu konfigurieren, siehe Zugriff auf Qiskit Functions auf einer Instanz konfigurieren.

    Um save_account() zu verwenden, führe python in deiner Shell aus und gib dann Folgendes ein:

    from qiskit_ibm_catalog import QiskitFunctionsCatalog

    QiskitFunctionsCatalog.save_account(channel="ibm_quantum_platform", token="<your-token>", instance="<instance-crn>")

    Gib exit() ein. Von nun an kannst du deine Anmeldedaten jedes Mal, wenn du dich beim Dienst authentifizieren musst, wie folgt laden:

    from qiskit_ibm_catalog import QiskitFunctionsCatalog
    catalog = QiskitFunctionsCatalog()

    Zum Beispiel:

# Load saved credentials
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

Avoid executing code on an untrusted machine or an external cloud Python environment to minimize security risks. If you must use an untrusted environment (on, for example, a public computer), change your API key after each use by deleting it on the IBM Cloud API keys page to reduce risk. Learn more in the Managing user API keys topic. To initialize the service in this situation, use this code:

from qiskit_ibm_catalog import QiskitFunctionsCatalog

# After using the following code, delete your API key on the
# IBM Quantum Platform home dashboard
catalog = QiskitFunctionsCatalog(token="<YOUR_API_KEY>") # Use the 44-character
# API_KEY you created and saved from the IBM Quantum Platform Home dashboard
Schütze deinen API-Schlüssel

Füge deinen Schlüssel niemals in Quellcode, Python-Skripte oder Notebook-Dateien ein. Wenn du Code mit anderen teilst, stelle sicher, dass dein API-Schlüssel nicht direkt in das Python-Skript eingebettet ist. Teile das Skript stattdessen ohne den Schlüssel und gib Anweisungen zur sicheren Einrichtung.

Solltest du deinen Schlüssel versehentlich mit jemandem teilen oder ihn in eine Versionsverwaltung wie Git aufnehmen, widerrufe ihn sofort, indem du ihn auf der Seite IBM Cloud API-Schlüssel löschst, um das Risiko zu verringern. Weitere Informationen findest du im Thema Verwalten von Benutzer-API-Schlüsseln.

Die Funktionen auflisten, auf die du zugreifen kannst

Nachdem du dich authentifiziert hast, kannst du die Funktionen aus dem Qiskit Functions Catalog auflisten, auf die du Zugriff hast:

catalog.list()
[QiskitFunction(qunova/hivqe-chemistry),
QiskitFunction(global-data-quantum/quantum-portfolio-optimizer),
QiskitFunction(algorithmiq/tem),
QiskitFunction(qedma/qesem),
QiskitFunction(multiverse/singularity),
QiskitFunction(ibm/circuit-function),
QiskitFunction(q-ctrl/optimization-solver),
QiskitFunction(colibritd/quick-pde),
QiskitFunction(q-ctrl/performance-management),
QiskitFunction(kipu-quantum/iskay-quantum-optimizer)]

Aktivierte Funktionen ausführen

Nachdem ein Catalog-Objekt instanziiert wurde, kannst du mit catalog.load("<provider/function-name>") eine Funktion auswählen:

qesem_function = catalog.load("qedma/qesem")

Jede Qiskit Function hat eigene Eingaben, Optionen und Ausgaben. Weitere Informationen findest du auf den spezifischen Dokumentationsseiten für die Funktion, die du ausführen möchtest. Standardmäßig kann jeder Nutzer jeweils nur einen Funktions-Job gleichzeitig ausführen:

from qiskit.quantum_info import SparsePauliOp

avg_magnetization = SparsePauliOp.from_sparse_list(
[("Z", [q], 1 / 5) for q in range(5)], num_qubits=5
)

job = qesem_function.run(
pubs=[(circuit, [avg_magnetization, observable])],
backend_name=backend_name, # example: "ibm_fez"
# options = {
# "estimate_time_only": "empirical",
# "default_precision": 0.2, # Default precision is applied to all pubs that don't have a precision specified, see API reference for more details
# "max_execution_time": 3600, # You can specify a maximum QPU time in seconds, see API reference for more details
# "transpilation_level": "standard", # "minimal_with_layout_opt" for minimal transpilation, see API reference for more details
# "parallel_execution": True, # True for parallel execution, see API reference for more details
# },
)
job.job_id
'7f08c9d5-471b-4da2-92e7-4f2cb94c23a8'
tipp

run() prüft deine verbleibende Kapazität und den Backend-Zugriff, bevor der Job eingereicht wird. Wenn deine Instanz keine Kapazität mehr hat oder das genannte Backend nicht zugänglich ist, löst run() sofort einen Fehler aus, statt den Job in der Warteschlange fehlschlagen zu lassen. Bei niedriger Kapazität gibt run() eine Warnung aus. Übergib suppress_low_usage_warning=True, um sie zu unterdrücken.

job = qesem_function.run(
pubs=[(circuit, [avg_magnetization, observable])],
backend_name=backend_name, # example: "ibm_fez"
suppress_low_usage_warning=True,
# options = {
# "estimate_time_only": "empirical",
# "default_precision": 0.2, # Default precision is applied to all pubs that don't have a precision specified, see API reference for more details
# "max_execution_time": 3600, # You can specify a maximum QPU time in seconds, see API reference for more details
# "transpilation_level": "standard", # "minimal_with_layout_opt" for minimal transpilation, see API reference for more details
# "parallel_execution": True, # True for parallel execution, see API reference for more details
# },
)

Job-Status prüfen

Mit der job_id deiner Qiskit Function kannst du den Status laufender Jobs prüfen. Dazu gehören die folgenden Status:

  • QUEUED: Das Remote-Programm befindet sich in der Qiskit-Function-Warteschlange. Die Priorität in der Warteschlange richtet sich danach, wie viel du Qiskit Functions bereits genutzt hast.

  • INITIALIZING: Das Remote-Programm startet; dies umfasst das Einrichten der Remote-Umgebung und das Installieren von Abhängigkeiten.

  • RUNNING: Das Programm läuft. Dies umfasst auch mehrere detailliertere Status, sofern von bestimmten Funktionen unterstützt.

    • RUNNING: MAPPING: Die Funktion mappt aktuell deine klassischen Eingaben auf Quanten-Eingaben.

    • RUNNING: OPTIMIZING_FOR_HARDWARE: Die Funktion optimiert für die ausgewählte QPU. Dies kann Circuit-Transpilation, QPU-Charakterisierung, Observable-Backpropagation und Ähnliches umfassen.

    • RUNNING: WAITING_FOR_QPU: Die Funktion hat einen Job beim IBM Quantum Compute Service eingereicht und wartet in der Warteschlange.

    • RUNNING: EXECUTING_QPU: Die Funktion hat einen aktiven Quantum-Compute-Job.

    • RUNNING: POST_PROCESSING: Die Funktion verarbeitet Ergebnisse nach, was Fehlerminderung, das Mapping von Quantenergebnissen auf klassische Werte und Ähnliches umfassen kann.

  • DONE: Das Programm ist abgeschlossen, und du kannst die Ergebnisdaten mit job.result() abrufen.

  • ERROR: Das Programm wurde aufgrund eines Problems gestoppt. Verwende job.result(), um die Fehlermeldung abzurufen.

  • CANCELED: Das Programm wurde von einem Nutzer, dem Dienst oder dem Server abgebrochen.

job.status()
'QUEUED'

Ergebnisse abrufen

Nachdem ein Programm DONE ist, kannst du mit job.result() das Ergebnis abrufen. Das Ausgabeformat variiert je nach Funktion, achte daher darauf, der jeweiligen Dokumentation zu folgen:

result = job.result()
print(result)
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(), dtype=float64>), stds=np.ndarray(<shape=(), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(), dtype=float64>)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': True, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})

Du kannst einen Job auch jederzeit abbrechen:

job.cancel()
'Job has been stopped.'

Auf die zugehörigen Quantum-Compute-Jobs zugreifen

Eine Qiskit Function kann während der Ausführung einen oder mehrere Quantum-Compute-Jobs an eine QPU senden. Um die IDs dieser Runtime-Jobs abzurufen, verwende job.runtime_jobs(). Mit diesen IDs kannst du die Runtime-Job-Objekte aus einer QiskitRuntimeService-Instanz abrufen oder die Workloads im IBM Quantum® Platform-Dashboard finden.

runtime_job_ids = job.runtime_jobs()
runtime_job_ids

Wenn eine Funktion ihre Runtime-Jobs in Sessions oder Batches gruppiert, verwende job.runtime_sessions(), um die Session-IDs aufzulisten. Übergib eine Session-ID an job.runtime_jobs(), um nur die Runtime-Jobs dieser Session zurückzugeben:

sessions = job.runtime_sessions()
if sessions:
session_runtime_jobs = job.runtime_jobs(runtime_session=sessions[0])
print(session_runtime_jobs)
else:
print("No runtime sessions for this job.")
hinweis

Die zurückgegebene Liste kann leer sein. Eine Funktion meldet ihre Runtime-Jobs nur, wenn sie diese über den Runtime-Service übermittelt, den die Funktion zur Laufzeit erhält, und manche Funktionen übermitteln Runtime-Jobs nicht direkt.

Job-Logs anzeigen

Verwende job.logs(), um die Log-Ausgabe abzurufen, die eine Funktion während der Ausführung erzeugt. Logs sind nützlich, um den Fortschritt zu verfolgen und einen Job zu debuggen, der im Status ERROR endet.

print(job.logs().splitlines())

Verwende bei einem lange laufenden Job, der viele Log-Zeilen erzeugt, job.filtered_logs(), um nur die gewünschten Zeilen zurückzugeben. Übergib einen regulären Ausdruck an include, um passende Zeilen zu behalten, oder an exclude, um passende Zeilen zu verwerfen:

print(job.filtered_logs(include="iteration"))

Zuvor ausgeführte Qiskit-Functions-Jobs auflisten

Mit jobs() kannst du alle bei Qiskit Functions eingereichten Jobs auflisten:

old_jobs = catalog.jobs()
old_jobs
[<Job | f6c29f49-4d5f-4fff-aca6-2e9a115b9763>,
<Job | 7f08c9d5-471b-4da2-92e7-4f2cb94c23a8>,
<Job | 62fe9176-d1e5-467e-b2bd-7a3f3c7be4e5>,
<Job | af525b2e-16b1-45a1-80bb-dbd94ce30258>,
<Job | b95a7a57-c1ad-4958-b7ac-953e4e1ee824>,
<Job | 7bfa33da-0f17-4e67-84b6-f556f7eeb436>,
<Job | ca46c191-9eb9-4de6-bfa7-b60d7eb29b5e>,
<Job | 6ac0ba93-3831-43fb-9fb9-760da2225e06>,
<Job | f0e38071-060d-47e8-988d-9cc1f69358e3>,
<Job | 629cf110-e490-4675-8a07-f6d298d166b0>]

Um die Ergebnisse einzugrenzen, übergib Filter. Filtere nach Funktion mit function, nach Status mit status und nach Einreichungsdatum mit created_after. Blättere mit limit und offset durch die Ergebnisse:

recent_errors = catalog.jobs(
function=qesem_function,
status="ERROR",
created_after="2024-01-01T00:00:00Z",
limit=5,
)
recent_errors

Wenn du bereits die Job-ID für einen bestimmten Job hast, kannst du den Job mit catalog.job() abrufen:

# First, get the most recent job that has been executed.
latest_job = old_jobs[0]

# We can also get that same job with `catalog.job`
job_by_id = catalog.job(latest_job.job_id)

# Verify that the job is the same using both retrieval methods.
assert job_by_id.job_id == latest_job.job_id

# Print the job_id for this job.
print(job_by_id.job_id)
f6c29f49-4d5f-4fff-aca6-2e9a115b9763

Fehlermeldungen abrufen

Wenn der Status eines Programms ERROR ist, verwende job.error_message(), um die Fehlermeldung wie folgt abzurufen:

job.error_message()
qiskit.exceptions.QiskitError: 'Workflow execution failed -- https://docs.quantum.ibm.com/errors#9999'

Nächste Schritte

Empfehlungen