Package: qiskit-ibm-runtime
Qiskit Runtime IBM ClientQiskitis an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.Qiskit IBM Runtimeis a new environment offered by IBM Quantum that streamlines quantum computations and provides optimal
implementations of the Qiskit primitivessamplerandestimatorfor IBM Quantum hardware. It is designed to use additional classical compute resources to execute quantum circuits with more efficiency on quantum processors, by including near-time computations such as error suppression and error mitigation. Examples of error suppression include dynamical decoupling, noise-aware compilation, error mitigation including readout mitigation, zero-noise extrapolation (ZNE), and probabilistic error cancellation (PEC).Using the runtime service, a research team at IBM Quantum was able to achieve a 120x speedup
in their lithium hydride simulation. For more information, see theIBM Research blog.This module provides the interface to access the Qiskit Runtime service on IBM Quantum Platform or IBM Cloud.InstallationYou can install this package using pip:pipinstallqiskit-ibm-runtimeAccount setupQiskit Runtime service on IBM Quantum PlatformYou will need your IBM Quantum API token to authenticate with the runtime service:Create an IBM Quantum account or log in to your existing account by visiting theIBM Quantum login page.Copy (and optionally regenerate) your API token from yourIBM Quantum account page.Qiskit Runtime service on IBM CloudThe runtime service is now part of the IBM Quantum Services on IBM Cloud. To use this service, you'll
need to create an IBM Cloud account and a quantum service instance.This guidecontains step-by-step instructions, including how to find your
IBM Cloud API key and Cloud Resource Name (CRN), which you will need for authentication.Save your account on diskOnce you have the account credentials, you can save them on disk, so you won't have to input
them each time. The credentials are saved in the$HOME/.qiskit/qiskit-ibm.jsonfile, where$HOMEis your home directory.:warning: Account credentials are saved in plain text, so only do so if you are using a trusted device.fromqiskit_ibm_runtimeimportQiskitRuntimeService# Save an IBM Cloud account.QiskitRuntimeService.save_account(channel="ibm_cloud",token="MY_IBM_CLOUD_API_KEY",instance="MY_IBM_CLOUD_CRN")# Save an IBM Quantum account.QiskitRuntimeService.save_account(channel="ibm_quantum",token="MY_IBM_QUANTUM_TOKEN")Once the account is saved on disk, you can instantiate the service without any arguments:fromqiskit_ibm_runtimeimportQiskitRuntimeServiceservice=QiskitRuntimeService()Loading account from environment variablesAlternatively, the service can discover credentials from environment variables:exportQISKIT_IBM_TOKEN="MY_IBM_CLOUD_API_KEY"exportQISKIT_IBM_INSTANCE="MY_IBM_CLOUD_CRN"exportQISKIT_IBM_CHANNEL="ibm_cloud"Then instantiate the service without any arguments:fromqiskit_ibm_runtimeimportQiskitRuntimeServiceservice=QiskitRuntimeService()Enabling account for current Python sessionAs another alternative, you can also enable an account just for the current session by instantiating the
service with your credentials.fromqiskit_ibm_runtimeimportQiskitRuntimeService# For an IBM Cloud account.ibm_cloud_service=QiskitRuntimeService(channel="ibm_cloud",token="MY_IBM_CLOUD_API_KEY",instance="MY_IBM_CLOUD_CRN")# For an IBM Quantum account.ibm_quantum_service=QiskitRuntimeService(channel="ibm_quantum",token="MY_IBM_QUANTUM_TOKEN")PrimitivesAll quantum applications and algorithms level are fundamentally built using three steps:Choose a quantum circuit to encode the quantum state.Define the observable or the classical register to be measured.Execute the quantum circuits by using a primitive (Estimator or Sampler).Primitivesare base-level functions that serve as building blocks for many quantum algorithms and applications. Theprimitive interfacesare defined in Qiskit.The IBM Runtime service offers these primitives with additional features, such as built-in error suppression and mitigation.There are several different options you can specify when calling the primitives. Seeqiskit_ibm_runtime.Optionsclass for more information.SamplerThis primitive takes a list of user circuits (including measurements) as input and generates an error-mitigated readout of quasi-probability distributions. This provides users a way to better evaluate shot results using error mitigation, and enables them to more efficiently evaluate the possibility of multiple relevant data points in the context of destructive interference.To invoke theSamplerprimitivefromqiskit_ibm_runtimeimportQiskitRuntimeService,Options,SamplerfromqiskitimportQuantumCircuitservice=QiskitRuntimeService()options=Options(optimization_level=1)options.execution.shots=1024# Options can be set using auto-complete.# 1. A quantum circuit for preparing the quantum state (|00> + |11>)/rt{2}bell=QuantumCircuit(2)bell.h(0)bell.cx(0,1)# 2. Map the qubits to a classical register in ascending orderbell.measure_all()# 3. Execute using the Sampler primitivebackend=service.get_backend('ibmq_qasm_simulator')sampler=Sampler(backend=backend,options=options)job=sampler.run(circuits=bell)print(f"Job ID is{job.job_id()}")print(f"Job result is{job.result()}")EstimatorThis primitive takes circuits and observables as input, to evaluate expectation values and variances for a given parameter input. This Estimator allows users to efficiently calculate and interpret expectation values of quantum operators required for many algorithms.To invoke theEstimatorprimitive:fromqiskit_ibm_runtimeimportQiskitRuntimeService,Options,Estimatorfromqiskit.quantum_infoimportSparsePauliOpfromqiskitimportQuantumCircuitfromqiskit.circuitimportParameterimportnumpyasnpservice=QiskitRuntimeService()options=Options(optimization_level=1)options.execution.shots=1024# Options can be set using auto-complete.# 1. A quantum circuit for preparing the quantum state (|000> + e^{itheta} |111>)/rt{2}theta=Parameter('θ')qc_example=QuantumCircuit(3)qc_example.h(0)# generate superpositionqc_example.p(theta,0)# add quantum phaseqc_example.cx(0,1)# condition 1st qubit on 0th qubitqc_example.cx(0,2)# condition 2nd qubit on 0th qubit# 2. the observable to be measuredM1=SparsePauliOp.from_list([("XXY",1),("XYX",1),("YXX",1),("YYY",-1)])# batch of theta parameters to be executedpoints=50theta1=[]forxinrange(points):theta=[x*2.0*np.pi/50]theta1.append(theta)# 3. Execute using the Estimator primitivebackend=service.get_backend('ibmq_qasm_simulator')estimator=Estimator(backend,options=options)job=estimator.run(circuits=[qc_example]*points,observables=[M1]*points,parameter_values=theta1)print(f"Job ID is{job.job_id()}")print(f"Job result is{job.result().values}")This code batches together 50 parameters to be executed in a single job. If a user wanted to find thethetathat optimized the observable, they could plot and observe it occurs attheta=np.pi/2. For speed we recommend batching results together (note that depending on your access, there may be limits on the number of circuits, objects, and parameters that you can send).SessionIn many algorithms and applications, an Estimator needs to be called iteratively without incurring queuing delays on each iteration. To solve this, the IBM Runtime service provides aSession. A session starts when the first job within the session is started, and subsequent jobs within the session are prioritized by the scheduler.You can use theqiskit_ibm_runtime.Sessionclass to start a
session. Consider the same example above and try to find the optimaltheta. The following example uses thegolden search methodto iteratively find the optimal theta that maximizes the observable.To invoke theEstimatorprimitive within a session:fromqiskit_ibm_runtimeimportQiskitRuntimeService,Session,Options,Estimatorfromqiskit.quantum_infoimportSparsePauliOpfromqiskitimportQuantumCircuitfromqiskit.circuitimportParameterimportnumpyasnpservice=QiskitRuntimeService()options=Options(optimization_level=1)options.execution.shots=1024# Options can be set using auto-complete.# 1. A quantum circuit for preparing the quantum state (|000> + e^{itheta} |111>)/rt{2}theta=Parameter('θ')qc_example=QuantumCircuit(3)qc_example.h(0)# generate superpostionqc_example.p(theta,0)# add quantum phaseqc_example.cx(0,1)# condition 1st qubit on 0th qubitqc_example.cx(0,2)# condition 2nd qubit on 0th qubit# 2. the observable to be measuredM1=SparsePauliOp.from_list([("XXY",1),("XYX",1),("YXX",1),("YYY",-1)])gr=(np.sqrt(5)+1)/2# golden ratiothetaa=0# lower range of thetathetab=2*np.pi# upper range of thetatol=1e-1# tol# 3. Execute iteratively using the Estimator primitivewithSession(service=service,backend="ibmq_qasm_simulator")assession:estimator=Estimator(session=session,options=options)#next test rangethetac=thetab-(thetab-thetaa)/grthetad=thetaa+(thetab-thetaa)/grwhileabs(thetab-thetaa)>tol:print(f"max value of M1 is in the range theta ={[thetaa,thetab]}")job=estimator.run(circuits=[qc_example]*2,observables=[M1]*2,parameter_values=[[thetac],[thetad]])test=job.result().valuesiftest[0]>test[1]:thetab=thetadelse:thetaa=thetacthetac=thetab-(thetab-thetaa)/grthetad=thetaa+(thetab-thetaa)/gr# Final job to evaluate Estimator at midpoint found using golden search methodtheta_mid=(thetab+thetaa)/2job=estimator.run(circuits=qc_example,observables=M1,parameter_values=theta_mid)print(f"Session ID is{session.session_id}")print(f"Final Job ID is{job.job_id()}")print(f"Job result is{job.result().values}at theta ={theta_mid}")This code returnsJob result is [4.] at theta = 1.575674623307102using only nine iterations. This is a very powerful extension to the primitives. However, using too much code between iterative calls can lock the QPU and use excessive QPU time, which is expensive. We recommend only using sessions when needed. The Sampler can also be used within a session, but there are not any well-defined examples for this.InstancesAccess to IBM Quantum Platform channel is controlled by the instances (previously called providers) to which you are assigned. An instance is defined by a hierarchical organization of hub, group, and project. A hub is the top level of a given hierarchy (organization) and contains within it one or more groups. These groups are in turn populated with projects. The combination of hub/group/project is called an instance. Users can belong to more than one instance at any time.NOTE:IBM Cloud instances are different from IBM Quantum Platform instances.  IBM Cloud does not use the hub/group/project structure for user management. To view and create IBM Cloud instances, visit theIBM Cloud Quantum Instances page.To view a list of your instances, visit youraccount settings pageor use theinstances()method.You can specify an instance when initializing the service or provider, or when picking a backend:# Optional: List all the instances you can access.service=QiskitRuntimeService(channel='ibm_quantum')print(service.instances())# Optional: Specify the instance at service level. This becomes the default unless overwritten.service=QiskitRuntimeService(channel='ibm_quantum',instance="hub1/group1/project1")backend1=service.backend("ibmq_manila")# Optional: Specify the instance at the backend level, which overwrites the service-level specification when this backend is used.backend2=service.backend("ibmq_manila",instance="hub2/group2/project2")sampler1=Sampler(backend=backend1)# this will use hub1/group1/project1sampler2=Sampler(backend=backend2)# this will use hub2/group2/project2If you do not specify an instance, then the code will select one in the following order:If your account only has access to one instance, it is selected by default.If your account has access to multiple instances, but only one can access the requested backend, the instance with access is selected.In all other cases, the code selects the first instance other than ibm-q/open/main that has access to the backend.Access your IBM Quantum backendsAbackendis a quantum device or simulator capable of running quantum circuits or pulse schedules.You can query for the backends you have access to. Attributes and methods of the returned instances
provide information, such as qubit counts, error rates, and statuses, of the backends.fromqiskit_ibm_runtimeimportQiskitRuntimeServiceservice=QiskitRuntimeService()# Display all backends you have access.print(service.backends())# Get a specific backend.backend=service.backend('ibmq_qasm_simulator')# Print backend coupling map.print(backend.coupling_map)Next StepsNow you're set up and ready to check out some of thetutorials.Contribution guidelinesIf you'd like to contribute to qiskit-ibm-runtime, please take a look at ourcontribution guidelines. This project adheres to Qiskit'scode of conduct.
By participating, you are expected to uphold to this code.We useGitHub issuesfor tracking requests and bugs. Please use ourslackfor discussion and simple questions. To join our Slack community use the
invite link atibm.com/quantum/qiskit. For questions that are more suited for a forum we
use theQiskittag inStack Exchange.LicenseApache License 2.0.