Skip to main content
IBM Quantum Platform

Integra risorse quantistiche esterne con Qiskit

Il sito Qiskit SDK è costruito per supportare terze parti nella creazione di fornitori esterni di risorse quantistiche.

Ciò significa che qualsiasi organizzazione che sviluppa o distribuisce risorse di calcolo quantistico può integrare i propri servizi in Qiskit e attingere alla sua base di utenti.

A tal fine è necessario creare un pacchetto che supporti le richieste di risorse di calcolo quantistico e le restituisca all'utente.

Inoltre, il pacchetto deve consentire agli utenti di inviare lavori e recuperare i risultati attraverso un'implementazione degli oggetti qiskit.primitives .


Fornitura dell'accesso ai backend

Per poter transpilare ed eseguire gli oggetti di QuantumCircuit utilizzando risorse esterne, gli utenti devono istanziare un oggetto contenente un parametro Target che fornisce informazioni sui vincoli di una QPU, come la connettività, le porte di base e il numero di qubit. Questo può essere fornito attraverso un'interfaccia simile a quella QiskitRuntimeService attraverso la quale un utente può fare richieste per una QPU. Questo oggetto dovrebbe, come minimo, contenere un Target, ma un approccio più semplice sarebbe quello di restituire un'istanza BackendV2 istanza.

Un esempio di implementazione può essere simile a questo:

from qiskit.transpiler import Target
from qsikit.providers import BackendV2

class ProviderService:
    """ Class for interacting with a provider's service"""

    def __init__(
        self,
        #Receive arguments for authentication/instantiation
    ):
        """ Initiate a connection with the provider service, given some method 
                of authentication """

    def return_target(name: Str) -> Target:
        """ Interact with the service and return a Target object """
        return target

    def return_backend(name: Str) -> BackendV2:
        """ Interact with the service and return a BackendV2 object """
        return backend

Fornitura di un'interfaccia per l'esecuzione

Oltre a fornire un servizio che restituisce le configurazioni hardware, un servizio che consente l’accesso a risorse QPU esterne potrebbe anche supportare l’esecuzione di carichi di lavoro quantistici. È possibile rendere disponibile tale funzionalità creando implementazioni delle classi base primitive di Qiskit; ad esempio BasePrimitiveJob, e BaseEstimatorV2 BaseSamplerV2 tra le altre. Come minimo, queste interfacce dovrebbero essere in grado di fornire un metodo per l'esecuzione, la consultazione dello stato del processo e la restituzione dei risultati del processo.

Per gestire lo stato e i risultati dei lavori, il sito Qiskit SDK mette a disposizione un'opzione DataBin, PubResult, PrimitiveResult, e BasePrimitiveJob da utilizzare.

Vedi il qiskit.primitives Documentazione API e implementazioni di riferimento BackendEstimatorV2 E BackendSampleV2 per maggiori informazioni.

Un esempio di implementazione della primitiva Estimator può apparire come segue:

from qiskit.primitives import BaseEstimatorV2, BaseSamplerV2, EstimatorPubLike
from qiskit.primitives import DataBin, PubResult, PrimitiveResult, BasePrimitiveJob
from qiskit.providers import BackendV2

class EstimatorImplementation(BaseEstimatorV2):
    """ Class for interacting with the provider's Estimator service """

    def __init__(
        self,
        *,
        backend: BackendV2,
        options: dict
        # Receive other arguments to instantiate an Estimator primitive with the service
    ):
        self._backend = backend
        self._options = options
        self._default_precision = 0.01

    @property
    def backend(self) -> BackendV2:
        """ Return the backend """
        return self._backend

    def run(
        self, pubs: Iterable[EstimatorPubLike], *, precision: float | None = None
    ) -> BasePrimitiveJob[PrimitiveResult[PubResult]]:
    """ Steps to implement: 
            1. Define a default precision if none is given 
            2. Validate pub format
            3. Instantiate an object which inherits from BasePrimitiveJob 
                containing pub and runtime information
            4. Send the job to the execution service of the provider
    """
    job = BasePrimitiveJob(pubs, precision)
    job_with_results = job.submit()
    return job_with_results

Un'implementazione della primitiva Sampler può essere simile:

class SamplerImplementation(BaseSamplerV2):
    """ Class for interacting with the provider's Sampler service """

    def __init__(
        self,
        *,
        backend: BackendV2,
        options: dict
        # Receive other arguments to instantiate an Estimator primitive with the service
    ):
        self._backend = backend
        self._options = options
        self._default_shots = 1024

    @property
    def backend(self) -> BackendV2:
        """ Return the Sampler's backend """
        return self._backend

    def run(
        self, pubs: Iterable[SamplerPubLike], *, shots: int | None = None
    ) -> BasePrimitiveJob[PrimitiveResult[SamplerPubResult]]:
    """ Steps to implement: 
            1. Define a default number of shots if none is given 
            2. Validate pub format
            3. Instantiate an object which inherits from BasePrimitiveJob 
                containing pub and runtime information
            4. Send the job to the execution service of the provider
            5. Return the data in some format
    """
    job = BasePrimitiveJob(pubs, shots)
    job_with_results = job.submit()
    return job_with_results
Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.