Release Notes

0.6.0

New Features

  • In run(), added a check to whether the input circuits are actually dynamic. Issue a warning if the user specifies dynamic=False, while the circuits are actually dynamic.

  • Python 3.11 is now supported.

Deprecation Notes

  • Removed support for input circuit as Schedule to IBMBackend.run(). Use pulse gates instead. See tutorial on how to use pulse gates.

Bug Fixes

  • Fix mapping for qubit registers when padding for fast-path cases, after transpiling. This mapping is required due to qiskit-terra #9332 <https://github.com/Qiskit/qiskit-terra/issues/9332>

  • Fixed a bug where the backend target qubit_properties were not being decoded correctly.

  • Allow for users to retrieve all backends even if one of the backends has a missing configuration. The backend without a configuration will not be returned.

0.5.3

Upgrade Notes

  • If the dynamic parameter is set to True in run() and the backend being used does not support dymamic circuits, a warning will be raised.

  • When constructing a backend qiskit.transpiler.Target, faulty qubits and gates from the backend configuration will be filtered out.

Bug Fixes

  • Match the adjustment of measurements for devices with odd short gate lengths.

  • Fixed a bug where status() was not returning pending jobs.

  • An unnecessary call to refresh() has been removed from status(). Circuits and other job attributes were being re-fetched unnecessarily, causing slow job retrieval times.

  • The dynamic circuit odd cycle delay has been bumped from 1 cycle to 4 cycles to address hardware limitations.

0.5.2

New Features

  • run() now checks if the input circuits use a faulty qubit or a faulty edge.

Bug Fixes

  • Fixed an issue where instances were not being set when backend configurations were loaded in get_backend() and backends().

0.5.1

Upgrade Notes

0.5.0

New Features

  • Added the method target_history(). This method is similar to target(). The difference is that the new method enables the user to pass a datetime parameter, to retrieve historical data from the backend.

Upgrade Notes

  • There will now be a warning if a boolean is passed in for the init_circuit parameter in run().

Bug Fixes

  • Removed additional decomposition of BlueprintCircuits in the JSON encoder. This was introduced as a bugfix, but has since been fixed. Still doing the decomposition led to possible problems if the decomposed circuit was not in the correct basis set of the backend anymore.

0.4.0

Bug Fixes

  • ECRGate and CZGate mappings have been added to the Target constructor to fix a tranpile bug.

0.3.0

New Features

  • Support has been added for applying scheduling and dynamical decoupling for circuits with new format control flow (including nested control-flow).

    from qiskit.circuit import ClassicalRegister, QuantumCircuit, QuantumRegister
    from qiskit.circuit.library import XGate
    from qiskit.transpiler.passmanager import PassManager
    
    from qiskit_ibm_provider.transpiler.passes.scheduling import DynamicCircuitInstructionDurations
    from qiskit_ibm_provider.transpiler.passes.scheduling import ALAPScheduleAnalysis
    from qiskit_ibm_provider.transpiler.passes.scheduling import PadDynamicalDecoupling
    from qiskit.providers.fake_provider import FakeJakarta
    
    backend = FakeJakarta()
    
    durations = DynamicCircuitInstructionDurations.from_backend(backend)
    
    qc = QuantumCircuit(2, 2)
    with qc.if_test((0, 1)):
        qc.x(0)
        qc.measure(0, 1)
        with qc.if_test((1, 1)):
          qc.measure(1, 1)
    
    dd_sequence = [XGate(), XGate()]
    
    pm = PassManager(
      [
          ALAPScheduleAnalysis(durations),
          PadDynamicalDecoupling(durations, dd_sequence),
      ]
    )
    
    qc_dd = pm.run(qc)
    

Upgrade Notes

  • Scheduling support for c_if has been removed. Please run the pass qiskit.transpiler.passes.ConvertConditionsToIfOps on your circuit before scheduling to convert all old format c_if statements to new format if_test control-flow that may be scheduled.

    from qiskit.circuit import ClassicalRegister, QuantumCircuit, QuantumRegister
    from qiskit.transpiler.passes import ConvertConditionsToIfOps
    from qiskit.transpiler.passmanager import PassManager
    
    
    from qiskit_ibm_provider.transpiler.passes.scheduling import DynamicCircuitInstructionDurations
    from qiskit_ibm_provider.transpiler.passes.scheduling import ALAPScheduleAnalysis
    from qiskit_ibm_provider.transpiler.passes.scheduling import PadDynamicalDecoupling
    from qiskit.providers.fake_provider import FakeJakarta
    
    backend = FakeJakarta()
    
    durations = DynamicCircuitInstructionDurations.from_backend(backend)
    
    
    qc = QuantumCircuit(1, 1)
    qc.x(0).c_if(0, 1)
    
    pm = PassManager(
      [
          ConvertConditionsToIfOps(),
          ALAPScheduleAnalysis(durations),
          PadDelay(),
      ]
    )
    
    qc_dd = pm.run(qc)
    
  • The IBMBackend now returns the ibm_dynamic_circuits translation stage as its plugin translation stage. This will automatically add custom transformations when calling the transpiler that are tuned for IBM quantum hardware.

  • If an instance is passed in when initializing IBMProvider, the instance will be used for filtering backends and jobs in backends() and jobs().

Bug Fixes

  • jobs() and retrieve_job() now only retrieve jobs that are run with the circuit-runner or qasm3-runner programs. Jobs run from qiskit-ibm-runtime will not be retrievable because their results are in an unsupported format.

0.2.1

Bug Fixes

  • Fixed a bug where users could not initialize IBMProvider if they were in a h/g/p without any backends.

0.2.0

New Features

  • The meth:~qiskit_ibm_provider.IBMProvider.instances was added to list all the available instances in a provider instance.

  • A new transpiler pass qiskit_ibm_provider.transpiler.passes.basis.ConvertIdToDelay was added which converts an :class:`qiskit.circuit.library.IGate to qiskit.circuit.Delay. This was added to the default transpiler plugin qiskit_ibm_provider.transpiler.plugin.IBMTranslationPlugin.

Upgrade Notes

  • Users can now retrieve jobs run from the previous provider, qiskit-ibmq-provider with retrieve_job(). There is also a new legacy parameter in jobs() for retrieving these jobs in bulk.

Bug Fixes

  • A bug was fixed in qiskit.transpiler.passes.scheduling.LAPScheduleAnalysis which was caused by an bad interaction between duration-less gates such as rz and barrier.

  • A bug was fixed where conditional qiskit.circuit.library.IGate were being converted to unconditional qiskit.circuit.Delay operations rather than conditional operations.

  • Fixed an issue where filtering by instance with jobs() was not working correctly.

  • Filtering backends with the parameter input_allowed in backends() has been removed because it is no longer in use and not supported by the runtime api.

0.1.0

Prelude

A transpiler module has been added. It will contain routines that are specific to IBM hardware backends and which consequently can not be placed directly within Qiskit Terra.

qiskit-ibm-provider is a new Python API client for accessing the quantum systems and simulators at IBM Quantum. This new package is built upon the work already done in qiskit.providers.ibmq.backend module in the qiskit-ibmq-provider package and replaces it going forward. The backend module in qiskit-ibmq-provider package is now deprecated. Please take a look at the mirgraion guide here. qiskit-ibm-provider is not included as part of Qiskit meta package and thereby you have to install it separately using pip install qiskit-ibm-provider.

New Features

  • A scheduling analysis pass, ASAPScheduleAnalysis has been added for Qiskit dynamic circuit (OpenQASM 3) backends. This is capable of handling scheduling for deterministic regions of a quantum circuit and may combined with a padding pass such as PadDelay to pad schedulable sections of a circuit with delays.

    For an example see the scheduling module’s documentation.

  • Measurements no longer interrupt scheduling regions on dynamic circuit backends using the ASAPScheduleAnalysis

  • The module transpiler` has been added.

    Primarily, it will contain all specialized Qiskit routines for running applications on IBM’s next-generation quantum devices that support dynamic capabilities such as control-flow(feedforward) and classical compute.

  • Python 3.10 is now supported.

  • You can now use the dynamic_circuits parameter in qiskit_ibm_provider.ibm_backend_service.IBMBackendService.backends() to find backends that support dynamic circuits.

  • It is now possible to select the Qiskit runtime program ID to use for run() through the input argument program_id.

Upgrade Notes

  • The IBMQ global variable which was an instance of the IBMQFactory has been removed. IBMQFactory and AccountProvider classes have been removed and the functionality provided by these two classes have been combined and refactored in the new IBMProvider class. This class will provide a simplified interface as shown below and serve as the entrypoint going forward.

    save_account() - Save your account to disk for future use and optionally set a default instance (hub/group/project) to be used when loading your account.

    IBMProvider() - Load account using saved credentials.

    saved_accounts() - View the accounts saved to disk.

    delete_account() - Delete the saved account from disk.

    IBMProvider(token="<insert_api_token>") - Enable your account in the current session.

    active_account() - List the account currently active in the session.

    Use the examples below to migrate your existing code:

    • Load Account using Saved Credentials

      Before:

      from qiskit import IBMQ
      IBMQ.save_account(token='MY_API_TOKEN')
      provider = IBMQ.load_account() # loads saved account from disk
      

      After:

      from qiskit_ibm_provider import IBMProvider
      IBMProvider.save_account(token='MY_API_TOKEN')
      provider = IBMProvider() # loads saved account from disk
      
    • Load Account using Environment Variables

      Before:

      # export QE_TOKEN='MY_API_TOKEN' (bash command)
      
      from qiskit import IBMQ
      provider = IBMQ.load_account() # loads account from env variables
      

      After:

      # export QISKIT_IBM_TOKEN='MY_API_TOKEN' (bash command)
      
      from qiskit_ibm_provider import IBMProvider
      provider = IBMProvider() # loads account from env variables
      
    • Saved Account

      Before:

      from qiskit import IBMQ
      IBMQ.stored_account() # get saved account from qiskitrc file
      

      After:

      from qiskit_ibm_provider import IBMProvider
      IBMProvider.saved_accounts() # get saved accounts from qiskit-ibm.json file
      
    • Delete Account

      Before:

      from qiskit import IBMQ
      IBMQ.delete_account() # delete saved account from qiskitrc file
      

      After:

      from qiskit_ibm_provider import IBMProvider
      IBMProvider.delete_account() # delete saved account from saved credentials
      
    • Enable Account

      Before:

      from qiskit import IBMQ
      provider = IBMQ.enable_account(token='MY_API_TOKEN') # enable account for current session
      

      After:

      from qiskit_ibm_provider import IBMProvider
      provider = IBMProvider(token='MY_API_TOKEN') # enable account for current session
      
    • Active Account

      Before:

      from qiskit import IBMQ
      provider = IBMQ.load_account() # load saved account
      IBMQ.active_account() # check active account
      

      After:

      from qiskit_ibm_provider import IBMProvider
      provider = IBMProvider() # load saved account
      provider.active_account() # check active account
      
  • IBMBackend class now implements the qiskit.providers.BackendV2 interface and provides flatter access to the configuration of a backend, for example:

    # BackendV1:
    backend.configuration().n_qubits
    
    # BackendV2:
    backend.num_qubits
    

    Only breaking change when compared to BackendV1 is backend.name is now an attribute instead of a method.

    Refer to the IBMBackend class doc string for a list of all available attributes.

  • It is now optional to specify a hub/group/project upfront when connecting to the IBM Quantum account. The hub/group/project is selected in the following order.

    • hub/group/project if passed via instance parameter when calling get_backend()

    • hub/group/project if passed via instance parameter when initializing IBMProvider

    • the default set previously via save_account()

    • a premium hub/group/project in your account

    • open access hub/group/project

  • You can now use run() to submit a long list of circuits/schedules like you would for a single circuit/schedule. If the number of circuits/schedules exceeds the backend limit, run() will automatically divide the list into multiple sub-jobs and return a single IBMCompositeJob instance. You can use this IBMCompositeJob instance the same way you used IBMJob before. For example, you can use status() to get job status, result() to get job result, and cancel() to cancel the job. You can also use the job() and jobs() methods to retrieve a single IBMCompositeJob (by passing its job ID) or multiple jobs.

    IBMCompositeJob also has a rerun_failed() method that will re-run any failed or cancelled sub jobs and a report() method that returns a report on current sub-job statuses.

    This feature replaces the IBMQJobManager class in qiskit-ibmq-provider, which is the predecessor of qiskit-ibm-provider.

    Before:

    from qiskit.providers.ibmq.managed import IBMQJobManager
    
    job_manager = IBMQJobManager()
    job_set = job_manager.run(long_list_of_circuits, backend=backend)
    results = job_set.results()
    

    After:

    job = backend.run(long_list_of_circuits)
    result = job.result()
    
  • The dynamic circuits scheduling class (DynamicCircuitScheduleAnalysis) has been renamed to ASAPScheduleAnalysis.

  • run() has been updated so circuits with id instructions that are replaced with delay instructions do not mutate the original circuit.

  • Floats can now be used when setting the number of shots in run(). Now instead of having to type larger values like 100000 you can just do 1e5.

  • Scheduling has been updated to reflect dynamic circuit backends. Measurements no longer interrupt scheduling. ALAP scheduling has now been implemented in ALAPScheduleAnalysis and should be the standard scheduling policy that is used.

  • A custom instruction durations class has been added for dynamic circuit backends DynamicCircuitInstructionDurations.

    Currently it only patches the durations of measurement instructions.

    This should be used temporarily while we port legacy backends to dynamic circuit backends.

  • run() has been updated to give a warning if the backend selected is paused.

  • Methods jobs(), job(), job_ids(), and my_reservations() have been added to IBMProvider so they can all be directly accessible from the provider.

  • qiskit.providers.ibmq.IBMQBackend.retrieve_job() and qiskit.providers.ibmq.IBMQBackend.jobs() have been removed. The IBMBackendService methods job() and jobs() can be used instead.

  • Passing a QasmQobj and PulseQobj in the run() method has been removed. QuantumCircuit and Schedule should now be used instead.

  • The db_filter parameter has been removed from jobs() due to low adoption.

  • The deprecated qiskit.providers.ibmq.IBMQDeprecatedBackendService has now been removed. Backends can still be returned with backends() method.

  • Job share level is no longer supported due to low adoption and the corresponding interface has been removed. This means you can no longer pass share_level when creating a job. The qiskit.providers.ibmq.job.IBMQJob.share_level method to get a job’s share level has also been removed.

  • The deprecated timeout keyword in backends() method has now been removed.

  • The default number of shots (represents the number of repetitions of each circuit, for sampling) in run(), has been increased from 1024 to 4000.

Deprecation Notes

  • The reservations, job_limit, and remaining_jobs_count methods have been removed from IBMBackend. The BackendJobLimit and BackendReservation classes have also been removed.

Bug Fixes

  • When dynamic=True, run() now submits the shots argument correctly.

  • A warning log message when loading an invalid backend has had the core message switched to a debug log message as certain backends were causing issues for all users upon loading the provider. Now a much less verbose message is emitted.