Vai al contenuto principale

Inizia con le 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

Gli utenti dei piani Premium, Flex e On-Prem (tramite l'API di IBM Quantum Platform) possono iniziare a usare le IBM Qiskit Functions gratuitamente, oppure possono procurarsi una licenza da uno dei partner che hanno contribuito con una funzione al catalogo.

Richiedi una prova gratuita per le Qiskit Functions di terze parti

Per richiedere una prova gratuita, vai al Catalogo delle Qiskit Functions ed esplora il pannello dei dettagli. Fai clic su Request a free trial e compila le informazioni richieste dal partner della funzione, incluso l'AccessGroupId di IBM Cloud:

  1. Vai su IBM Cloud IAM.

  2. Verifica l'idoneità.

    • Cambia il tuo account nel menu nell'intestazione con uno che abbia il seguente formato: XXXXXXX - [Organization Name]

    • Assicurati che l'organizzazione sia la stessa associata al tuo account Premium.

    • Se vedi "[Il tuo nome]'s Account", stai usando il tuo account personale, che non è idoneo per l'accesso premium.

  3. Trova l'ID del tuo gruppo di accesso.

    • Fai clic su un nome di gruppo.

    • Fai clic su Details.

    • Copia l'ID del gruppo di accesso. Dovrebbe iniziare con AccessGroup-.

Installa il client del Catalogo delle Qiskit Functions

  1. Per iniziare a usare le Qiskit Functions, installa il client del Catalogo IBM Qiskit Functions:

    pip install qiskit-ibm-catalog
  2. Recupera la tua chiave API dalla dashboard di IBM Quantum Platform e attiva il tuo ambiente virtuale Python. Consulta le istruzioni di installazione se non hai già configurato un ambiente virtuale.

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

    L'istanza con cui ti autentichi deve avere l'accesso a Qiskit Functions abilitato. Per configurarlo su un'istanza esistente, consulta Configura l'accesso a Qiskit Functions su un'istanza.

    Per usare save_account(), esegui python nella tua shell, quindi inserisci quanto segue:

    from qiskit_ibm_catalog import QiskitFunctionsCatalog

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

    Digita exit(). Da questo momento in poi, ogni volta che devi autenticarti al servizio, puoi caricare le tue credenziali con quanto segue:

    from qiskit_ibm_catalog import QiskitFunctionsCatalog
    catalog = QiskitFunctionsCatalog()

    Ad esempio:

# 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
Proteggi la tua chiave API

Non includere mai la tua chiave nel codice sorgente, negli script Python o nei file notebook. Quando condividi il codice con altri, assicurati che la tua chiave API non sia incorporata direttamente nello script Python. Al contrario, condividi lo script senza la chiave e fornisci istruzioni per configurarla in modo sicuro.

Se condividi accidentalmente la tua chiave con qualcuno o la includi in un sistema di controllo di versione come Git, revoca immediatamente la chiave eliminandola nella pagina IBM Cloud API keys per ridurre il rischio. Scopri di più nell'argomento Managing user API keys.

Elenca le funzioni a cui puoi accedere

Dopo l'autenticazione, puoi elencare le funzioni del Catalogo delle Qiskit Functions a cui hai accesso:

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)]

Esegui le funzioni abilitate

Dopo aver istanziato un oggetto catalog, puoi selezionare una funzione usando catalog.load("<provider/function-name>"):

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

Ogni Qiskit Function ha input, opzioni e output personalizzati. Consulta le pagine di documentazione specifiche della funzione che vuoi eseguire per maggiori informazioni. Per impostazione predefinita, tutti gli utenti possono eseguire solo un job di funzione alla volta:

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'
suggerimento

run() controlla la tua capacità residua e l'accesso al backend prima di inviare il job. Se la tua istanza non ha capacità disponibile, o il backend indicato non è accessibile, run() genera immediatamente un errore invece di lasciare che il job fallisca in coda. Quando la capacità è bassa, run() emette un avviso. Passa suppress_low_usage_warning=True per disattivarlo.

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
# },
)

Controlla lo stato del job

Con il job_id della tua Qiskit Function, puoi controllare lo stato dei job in esecuzione. Questo include i seguenti stati:

  • QUEUED: il programma remoto è nella coda delle Qiskit Functions. La priorità in coda si basa su quanto hai usato le Qiskit Functions.

  • INITIALIZING: il programma remoto si sta avviando; questo include la configurazione dell'ambiente remoto e l'installazione delle dipendenze.

  • RUNNING: il programma è in esecuzione. Questo include anche diversi stati più dettagliati se supportati da funzioni specifiche.

    • RUNNING: MAPPING: la funzione sta attualmente mappando i tuoi input classici in input quantistici.

    • RUNNING: OPTIMIZING_FOR_HARDWARE: la funzione sta ottimizzando per la QPU selezionata. Questo può includere il transpiling del circuito, la caratterizzazione della QPU, la backpropagation degli osservabili e così via.

    • RUNNING: WAITING_FOR_QPU: la funzione ha inviato un job al Servizio di Calcolo IBM Quantum, ed è in attesa in coda.

    • RUNNING: EXECUTING_QPU: la funzione ha un job di Quantum Compute attivo.

    • RUNNING: POST_PROCESSING: la funzione sta post-elaborando i risultati, che può includere la mitigazione degli errori, la mappatura dei risultati quantistici in classici e così via.

  • DONE: il programma è completo e puoi recuperare i dati del risultato con job.result().

  • ERROR: il programma ha smesso di funzionare a causa di un problema. Usa job.result() per ottenere il messaggio di errore.

  • CANCELED: il programma è stato annullato da un utente, dal servizio o dal server.

job.status()
'QUEUED'

Recupera i risultati

Dopo che un programma è DONE, puoi usare job.result() per recuperare il risultato. Questo formato di output varia a seconda della funzione, quindi assicurati di seguire la documentazione specifica:

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})

Puoi anche annullare un job in qualsiasi momento:

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

Accedi ai job di Quantum Compute associati

Una Qiskit Function può inviare uno o più job di Quantum Compute a una QPU mentre è in esecuzione. Per recuperare gli ID di quei job runtime, usa job.runtime_jobs(). Puoi usare questi ID per recuperare gli oggetti dei job runtime da un'istanza di QiskitRuntimeService, oppure per trovare i workload nella dashboard di IBM Quantum® Platform.

runtime_job_ids = job.runtime_jobs()
runtime_job_ids

Se una funzione raggruppa i suoi job runtime in session o batch, usa job.runtime_sessions() per elencare gli ID delle session. Passa un ID di session a job.runtime_jobs() per restituire solo i job runtime in quella session:

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.")
nota

L'elenco restituito può essere vuoto. Una funzione segnala i propri job di runtime solo quando li invia tramite il servizio runtime che la funzione riceve in fase di esecuzione, e alcune funzioni non inviano job di runtime direttamente.

Visualizza i log dei job

Usa job.logs() per recuperare l'output di log prodotto da una funzione durante la sua esecuzione. I log sono utili per monitorare i progressi e per il debug di un job che termina in uno stato ERROR.

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

Per un job di lunga durata che produce molte righe di log, usa job.filtered_logs() per restituire solo le righe che desideri. Passa un'espressione regolare a include per mantenere le righe corrispondenti, oppure a exclude per scartare le righe corrispondenti:

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

Elenca i job delle Qiskit Functions eseguiti in precedenza

Puoi usare jobs() per elencare tutti i job inviati alle Qiskit Functions:

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>]

Per restringere i risultati, passa dei filtri. Filtra per funzione con function, per stato con status e per data di invio con created_after. Sfoglia i risultati con limit e offset:

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

Se hai già l'ID del job per un determinato job, puoi recuperarlo con catalog.job():

# 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

Recupera i messaggi di errore

Se lo stato di un programma è ERROR, usa job.error_message() per recuperare il messaggio di errore come segue:

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

Prossimi passi

Consigli