Skip to main content
IBM Quantum Platform

Notas de la versión de Qiskit 1.0


1.0.2

Preludio

Qiskit 1.0.2 es una versión de corrección de errores menores para la serie 1.0.

Corrección de errores

  • Se ha corregido un problema con convert_to_target() por el que el conversor ignoraba incorrectamente las instrucciones de flujo de control si se especificaban en el atributo BackendConfiguration.supported_instructions , que es la ubicación típica en la que se especifican las instrucciones de flujo de control en un objeto BackendConfiguration objeto. Corregido #11872.

  • Al llamar a EquivalenceLibrary.set_entry() actualizará correctamente el objeto gráfico interno de la biblioteca. Antes, los metadatos se actualizaban, pero la estructura del grafo permanecía inalterada, lo que significaba que usuarios como BasisTranslator seguirían utilizando las reglas antiguas. Corregido #11958.

  • La función EvolvedOperatorAnsatz ahora maneja correctamente el caso en que el argumento operators es una lista vacía. Antes, esto daba lugar a un error.

  • Se ha corregido un problema de coherencia con EvolvedOperatorAnsatz con qubits cero. Anteriormente, estas instancias contenían un único elemento QuantumRegister en qregs con cero qubits, pero ahora no se crean registros. Este comportamiento es más coherente con su superclase QuantumCircuit.

  • Se ha corregido un fallo en convert_to_target() que se producía cuando faltaban propiedades de qubit ( T1, T2 o frecuencia). Los valores de propiedad que faltan en QubitProperties se rellenan ahora con None.

  • Se ha corregido un problema de rendimiento en la función qpy.load() al deserializar cargas útiles QPY con un gran número de qubits o clbits en un circuito.

  • Se ha corregido un error por el que EstimatorPub.coerce() y SamplerPub.coerce() manejaban incorrectamente un parámetro de tipo BindingsArray. Anteriormente se lanzaba falsamente una excepción ValueError .

  • Los gestores de paso preestablecidos utilizados por transpile() ya no fallarán en circuitos con flujo de control cuando no se especifique un objetivo de hardware o un conjunto de puertas base. Ahora tratarán dichos objetivos abstractos como si permitieran todas las operaciones de flujo de control. Corregido #11906.

  • Corregido coerce() para que devuelva una matriz 0-d cuando la entrada es un único observable no anidado. Anteriormente, se actualizaba erróneamente a una sola dimensión, con la forma (1,).

  • Parameter se actualizó para que las instancias que se comparan igual siempre tengan el mismo hash. Anteriormente, sólo se comparaba el Parameter.uuid se comparaba, por lo que Parameter con nombres diferentes podían compararse igual si se habían construido utilizando un valor común para el parámetro uuid (que normalmente no se pasa explícitamente).

  • Se ha corregido un error en QuantumCircuit.draw() que provocaba que los diccionarios de estilos personalizados del cajón Matplotlib se modificaran al ejecutarse.


1.0.1

Preludio

Qiskit 1.0.1 es un parche que corrige un pequeño número de errores detectados en la versión de Qiskit 1.0.0.

Corrección de errores

  • Se ha corregido un error en la conversión de instrucciones de pulso personalizadas al formato heredado qiskit.qobj heredado. El error se introdujo en Qiskit 1.0.0 y provocaba que la conversión de instrucciones con formas de pulso personalizadas generara un error. Tras la corrección, la conversión se realiza correctamente y el pulso personalizado se convierte a pulse.Waveform como debería. Corregido #11828.

  • Se ha corregido un problema en el InverseCancellation por el que, en algunos casos, se cancelaba incorrectamente una puerta autoinversa parametrizada aunque el valor del parámetro no coincidiera. Corregido #11815.

  • BasePassManager.run() ya no filtrará el PropertySet en nuevos flujos de trabajo cuando se llama más de una vez. Anteriormente, se utilizaba el mismo PropertySet que antes se utilizaba para inicializar las ejecuciones sucesivas, lo que podía significar que se estaba dando a las tareas información de propiedades no válida. El comportamiento coincide ahora con el de Qiskit 0.44. Corregido #11784.

  • Se ha corregido un error en convert_durations_to_dt() por el que la función asumía que sus entradas estaban todas en segundos, en lugar de leer la unidad real. Esto podría dar lugar a órdenes de magnitud erróneos en las duraciones de circuito notificadas.


1.0.0

Preludio

Nos complace lanzar Qiskit 1.0.0. Esta versión es la culminación de 7 años de desarrollo para convertir Qiskit en un SDK estable y de alto rendimiento para la computación cuántica, y es el comienzo de una nueva era para el proyecto y la comunidad Qiskit. Además de las mejoras generales de rendimiento y estabilidad, los cambios más significativos de la versión 1.0.0 se refieren a la política de estabilidad, los ciclos de publicación y el control de versiones. Qiskit utiliza ahora formalmente el versionado semántico, lo que significa que, durante todo el ciclo de vida de la serie de versiones 1.x, el proyecto se compromete a mantener la compatibilidad con versiones anteriores en sus API públicas documentadas. También estamos empezando a ofrecer soporte de corrección de errores para las versiones principales, de modo que siga disponiendo de una rama soportada durante 6 meses después del lanzamiento de la siguiente versión principal. Esto empieza ahora con las series principales 1.x y 0.x : la versión 0.46.x seguirá recibiendo soporte, con lanzamientos periódicos de parches que contienen correcciones de errores, durante 6 meses después del lanzamiento de 1.0. Es decir, 0.46.x se mantendrá hasta 2024-08. Puede consultar todos los detalles de la nueva política aquí:

start/install#qiskit-versioning

Otro aspecto importante de esta versión es el cambio de embalaje. Desde el lanzamiento de Qiskit 0.7 en 2018-12, cuando Qiskit introdujo su modelo de elementos, el paquete qiskit que instalarías ha sido un meta-paquete (o paquete de paquetes) que instala los elementos combinados que componen Qiskit. Como ya se anunció en versiones anteriores (para más detalles, véase la página 0.44.0, 0.45.3 y 0.46.0 junto con esta entrada de blog ) con la versión 1.0 estamos completando una transición para tener un único paquete qiskit que exponga sólo el SDK central (lo que antes era qiskit-terra). Esto significa que para las versiones >= 1.0.0, hemos dejado de utilizar el paquete qiskit-terra y sólo publicaremos qiskit. Como este cambio en la estructura de los paquetes no es totalmente compatible con el instalador de paquetes Python pip, no es posible utilizar simplemente pip install -U qiskit para actualizar de qiskit 0.46.0 a 1.0.0. Se recomienda encarecidamente que para actualizar a Qiskit 1.0.0 se cree un entorno virtual independiente para aislar la instalación. Hay una guía de migración detallada que explica los cambios de empaquetado y cómo instalar Qiskit 1.0.0 en diferentes escenarios que se puede encontrar aquí:

https://qisk.it/1-0-packaging-migration

Como todas nuestras grandes versiones, Qiskit 1.0.0 también tiene una plétora de nuevas características, los aspectos más destacados de esta versión son:

  • La clase QuantumCircuit estructura interna de la clase data ha sido reescrita en Rust para mejorar enormemente la eficiencia de memoria de los objetos QuantumCircuit almacenando en caché los argumentos de las instrucciones.
  • Una nueva versión de la definición de la interfaz de primitivas en qiskit.primitives con las BaseSamplerV2 y BaseEstimatorV2 clases abstractas. Esta nueva versión de la interfaz añade soporte para realizar llamadas vectorizadas a la primitiva, de forma que se puedan especificar de forma eficiente barridos sobre conjuntos de valores de parámetros y observables.
  • Un nuevo analizador sintáctico nativo experimental OpenQASM 3 qiskit.qasm3.loads_experimental() y qiskit.qasm3.load_experimental(). Este nuevo analizador sintáctico está aún en fase de desarrollo, presenta varias limitaciones y es todavía experimental. Sin embargo, para donde es utilizable, el nuevo analizador sintáctico es significativamente más rápido y tiene un mejor mensaje de error de diagnóstico que permite depurar donde un programa OpenQASM 3 no es válido. Este nuevo analizador sintáctico está escrito en Rust y se basa en una biblioteca de Rust recientemente desarrollada para analizar OpenQASM3 que puede encontrarse aquí: https://github.com/Qiskit/openqasm3_parser

Por último, el lanzamiento de Qiskit 1.0.0 fue una oportunidad para limpiar algunas deudas técnicas acumuladas durante los últimos 7 años de desarrollo. Observará que la versión de Qiskit 1.0.0 prácticamente no emite DeprecationWarnings y, al mismo tiempo, la sección de actualización de las notas de la versión 1.0.0 es más larga de lo habitual. Son consecuencias directas de la limpieza de la deuda técnica. Para ayudar con la migración de 0.46.x a 1.0.0, además de las notas de la versión, también hemos publicado una guía de migración dedicada que se puede encontrar aquí:

Qiskit 1.0 cambios en las funciones

Esta guía pretende complementar las notas de la versión y ofrecer consejos específicos sobre cómo migrar los cambios de la API tras la eliminación de la funcionalidad obsoleta de la versión 0.46.0.

Características de los circuitos

  • Se ha añadido un nuevo argumento, annotated, a los métodos QuantumCircuit.inverse(), circuit.Instruction.inverse() y .inverse() de las subclases Instruction (como SwapGate o SGate) para devolver opcionalmente un AnnotatedOperation. El valor por defecto de annotated es False y corresponde al comportamiento preexistente del método. Además, para las puertas estándar con un método inverse definido explícitamente, el argumento annotated no tiene ningún efecto, por ejemplo, ambos:

    SwapGate().inverse(annotated=False)
    SwapGate().inverse(annotated=True)

    devolver a SwapGatey ambos:

    SGate().inverse(annotated=False)
    SGate().inverse(annotated=True)

    devolver un SdgGate. La diferencia se manifiesta para las instrucciones personalizadas sin una inversa definida explícitamente. Con annotated=False, el método devuelve una nueva instrucción con la definición invertida recursivamente, igual que antes. Mientras que annotated=True devuelve un AnnotatedOperation que representa la instrucción modificada con la instrucción InverseModifier.

  • Añadida una biblioteca de conmutación al CommutationChecker. Esta biblioteca almacena todas las relaciones de conmutación de puertas estándar no parametrizables en un diccionario que permite una búsqueda eficiente en tiempo de ejecución. Esto acelera la ejecución de la clase CommutationChecker y, por extensión, del CommutationAnalysis ya que en lugar de calcular si dos puertas estándar no parametrizables conmutan sólo tiene que buscarlo en la biblioteca.

    Además, el CommutationChecker se ha refactorizado y ahora tiene un límite superior establecido en el número de relaciones de conmutación almacenadas en caché que no están en la biblioteca de conmutación. Esto abordó: #8020 y #7101

  • QuantumCircuit.assign_parameters() ahora acepta claves de cadena en la forma de mapeo de entrada. Estos nombres se utilizan para buscar la instancia correspondiente Parameter correspondiente utilizando get_parameter(). Esto te permite hacer:

    from qiskit.circuit import QuantumCircuit, Parameter
    
    a = Parameter("a")
    qc = QuantumCircuit(1)
    qc.rx(a, 0)
    
    qc.assign_parameters({"a": 1}) == qc.assign_parameters({a: 1})
  • QuantumCircuit tiene dos nuevos métodos get_parameter() y has_parameter()que recuperan respectivamente una instancia Parameter instancia utilizada en el circuito por su nombre, y devuelven un booleano de si un parámetro con un nombre coincidente (o la instancia exacta dada) se utiliza en el circuito.

  • A uuid propiedad a la clase qiskit.circuit.Parameter clase. En casos de uso avanzado, esta propiedad puede utilizarse para crear qiskit.circuit.Parameter instancias iguales entre sí.

  • Se ha añadido un nuevo método ParameterExpression.numeric()que convierte una expresión de parámetro completamente ligada en el tipo numérico incorporado Python más restrictivo que describa con precisión el resultado de la evaluación simbólica. Por ejemplo, un número entero simbólico se convertirá en un intmientras que un número real simbólico se convertirá en un float y un número complejo se convertirá en complex. Este método incluye varias soluciones para las peculiaridades de los contextos de evaluación de symengine, que a veces pueden dar lugar a resultados falsos al llamar a complex o float sobre una expresión directamente.

Características primitivas

  • La versión 2 de las primitivas se introduce a través de una nueva clase base tanto para el muestreador como para el estimador, junto con nuevos tipos para sus entradas y salidas. El énfasis de esta nueva versión está en realizar llamadas vectorizadas a los métodos primitivos de run() , de forma que los barridos sobre conjuntos de valores de parámetros y observables puedan ser especificados eficientemente. Véase StatevectorSampler y StatevectorEstimator para las implementaciones de referencia de las primitivas V2.

    Además, el estimador ha ganado un argumento precision en el método run() que especifica la precisión deseada de las estimaciones del valor de la expectativa. De forma análoga, el muestreador ha desplazado shots de las opciones a los argumentos del método run() método. También se ha modificado el muestreador para que devuelva las salidas (por ejemplo, cadenas de bits) de cada disparo, en lugar de proporcionar un Counts-como retorno, y también para almacenar datos de distintos ClassicalRegisters. Esto permite a las clases derivadas implementar soporte sampler para circuitos con flujo de control clásico.

    Las clases base primitivas de V2 son:

    Los nuevos tipos que se utilizan para las entradas y salidas son:

    • SamplerPubLikebloque unificado primitivo ( PUB ) de entradas de muestreador; un tipo de unión de entradas permitidas para un muestreador
    • EstimatorPubLike: Bloque unificado primitivo ( PUB ) de entradas del estimador; un tipo de unión de entradas permitidas para un estimador
    • PubResultlos datos y metadatos resultantes de la ejecución de un único PUB
    • DataBin: Un espacio de nombres para guardar los datos de la ejecución de un único PUB
    • BitArrayuna colección de valores de bits en forma de matriz con un formato denso
    • PrimitiveResultun iterable de PubResults junto con metadatos
  • La aplicación de referencia StatevectorEstimator de BaseEstimatorV2 se ha añadido. Como se ve en el ejemplo siguiente, este estimador (y todos los estimadores de V2 ) admite proporcionar matrices de observables y/o matrices de conjuntos de valores de parámetros que se adjuntan a circuitos concretos.

    Cada tupla de (circuit, observables, <optional> parameter values, <optional> precision), denominada bloque unificado primitivo del estimador ( PUB ), produce su propio resultado basado en matrices. El método run() se puede aplicar a muchos bares a la vez.

    from qiskit.circuit import Parameter, QuantumCircuit
    from qiskit.primitives import StatevectorEstimator
    from qiskit.quantum_info import Pauli, SparsePauliOp
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Define a circuit with two parameters.
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.ry(Parameter("a"), 0)
    circuit.rz(Parameter("b"), 0)
    circuit.cx(0, 1)
    circuit.h(0)
    
    # Define a sweep over parameter values, where the second axis is over
    # the two parameters in the circuit.
    params = np.vstack([
        np.linspace(-np.pi, np.pi, 100),
        np.linspace(-4 * np.pi, 4 * np.pi, 100)
    ]).T
    
    # Define three observables. Many formats are supported here including
    # classes such as qiskit.quantum_info.SparsePauliOp. The inner length-1
    # lists cause this array of observables to have shape (3, 1), rather
    # than shape (3,) if they were omitted.
    observables = [
        [SparsePauliOp(["XX", "IY"], [0.5, 0.5])],
        [Pauli("XX")],
        [Pauli("IY")]
    ]
    
    # Instantiate a new statevector simulation based estimator object.
    estimator = StatevectorEstimator()
    
    # Estimate the expectation value for all 300 combinations of
    # observables and parameter values, where the pub result will have
    # shape (3, 100). This shape is due to our array of parameter
    # bindings having shape (100,), combined with our array of observables
    # having shape (3, 1)
    pub = (circuit, observables, params)
    job = estimator.run([pub])
    
    # Extract the result for the 0th pub (this example only has one pub).
    result = job.result()[0]
    
    # Error-bar information is also available, but the error is 0
    # for this StatevectorEstimator.
    result.data.stds
    
    # Pull out the array-based expectation value estimate data from the
    # result and plot a trace for each observable.
    for idx, pauli in enumerate(observables):
        plt.plot(result.data.evs[idx], label=pauli)
    plt.legend()
  • La aplicación de referencia StatevectorSampler de BaseSamplerV2 se ha añadido. Como se puede ver en el ejemplo siguiente, este muestreador (y todos los muestreadores de V2 ) permite proporcionar matrices de conjuntos de valores de parámetros para vincularlos a un único circuito.

    Cada tupla de (circuit, <optional> parameter values, <optional> shots), denominada bloque unificado primitivo de muestreo ( PUB ), produce su propio resultado basado en matrices. El método run() se puede aplicar a muchos bares a la vez.

    from qiskit.circuit import (
        Parameter, QuantumCircuit, ClassicalRegister, QuantumRegister
    )
    from qiskit.primitives import StatevectorSampler
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Define our circuit registers, including classical registers
    # called 'alpha' and 'beta'.
    qreg = QuantumRegister(3)
    alpha = ClassicalRegister(2, "alpha")
    beta = ClassicalRegister(1, "beta")
    
    # Define a quantum circuit with two parameters.
    circuit = QuantumCircuit(qreg, alpha, beta)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.cx(1, 2)
    circuit.ry(Parameter("a"), 0)
    circuit.rz(Parameter("b"), 0)
    circuit.cx(1, 2)
    circuit.cx(0, 1)
    circuit.h(0)
    circuit.measure([0, 1], alpha)
    circuit.measure([2], beta)
    
    # Define a sweep over parameter values, where the second axis is over.
    # the two parameters in the circuit.
    params = np.vstack([
        np.linspace(-np.pi, np.pi, 100),
        np.linspace(-4 * np.pi, 4 * np.pi, 100)
    ]).T
    
    # Instantiate a new statevector simulation based sampler object.
    sampler = StatevectorSampler()
    
    # Start a job that will return shots for all 100 parameter value sets.
    pub = (circuit, params)
    job = sampler.run([pub], shots=256)
    
    # Extract the result for the 0th pub (this example only has one pub).
    result = job.result()[0]
    
    # There is one BitArray object for each ClassicalRegister in the
    # circuit. Here, we can see that the BitArray for alpha contains data
    # for all 100 sweep points, and that it is indeed storing data for 2
    # bits over 256 shots.
    assert result.data.alpha.shape == (100,)
    assert result.data.alpha.num_bits == 2
    assert result.data.alpha.num_shots == 256
    
    # We can work directly with a binary array in performant applications.
    raw = result.data.alpha.array
    
    # For small registers where it is anticipated to have many counts
    # associated with the same bitstrings, we can turn the data from,
    # for example, the 22nd sweep index into a dictionary of counts.
    counts = result.data.alpha.get_counts(22)
    
    # Or, convert into a list of bitstrings that preserve shot order.
    bitstrings = result.data.alpha.get_bitstrings(22)
    print(bitstrings)

Características de los proveedores

  • Añadida una nueva clase GenericBackendV2al módulo qiskit.providers.fake_provider módulo. Esta clase es configurable, y construye un BackendV2 que puede ejecutarse localmente (en el espíritu de los falsos backends). Los usuarios pueden configurar el número de qubits, las puertas base, el mapa de acoplamiento, la capacidad de ejecutar circuitos dinámicos (instrucciones de flujo de control), las calibraciones de las instrucciones y el paso de tiempo de medición del backend sin tener que ocuparse de la construcción manual de objetivos. Las propiedades del Qubit y de la puerta (duración, error) se generan mediante muestreo aleatorio a partir de rangos predeterminados. La semilla para esta generación aleatoria puede fijarse para garantizar la reproducibilidad de la salida del backend. Es importante tener en cuenta que este backend sólo admite puertas en la biblioteca estándar. Si necesitas un backend más flexible, siempre existe la opción de instanciar directamente un objeto Target para utilizarlo en la transpilación.

    Ejemplo de uso 1:

    from qiskit import QuantumCircuit, transpile
    from qiskit.providers.fake_provider import GenericBackendV2
    
    # Create a simple circuit
    circuit = QuantumCircuit(3)
    circuit.h(0)
    circuit.cx(0,1)
    circuit.cx(0,2)
    circuit.measure_all()
    circuit.draw('mpl')
    
    # Define backend with 3 qubits
    backend = GenericBackendV2(num_qubits=3)
    
    # Transpile and run
    transpiled_circuit = transpile(circuit, backend)
    result = backend.run(transpiled_circuit).result()

    Ejemplo de uso 2:

    from qiskit import QuantumCircuit, ClassicalRegister, transpile
    from qiskit.providers.fake_provider import GenericBackendV2
    
    # Create a circuit with classical control
    creg = ClassicalRegister(19)
    qc = QuantumCircuit(25)
    qc.add_register(creg)
    qc.h(0)
    for i in range(18):
        qc.cx(0, i + 1)
    for i in range(18):
        qc.measure(i, creg[i])
    with qc.if_test((creg, 0)):
        qc.ecr(20, 21)
    
    # Define backend with custom basis gates and control flow instructions
    backend = GenericBackendV2(
        num_qubits=25,
        basis_gates=["ecr", "id", "rz", "sx", "x"],
        control_flow=True,
      )
    
    #Transpile
    transpiled_qc = transpile(qc, backend)
    Nota

    Las propiedades de ruido generadas por esta clase no imitan ningún dispositivo cuántico concreto, y no deben utilizarse para medir ningún comportamiento concreto. Se trata de "valores predeterminados razonables" que pueden utilizarse para probar la funcionalidad de interconexión con el backend y que no están vinculados a valores de ruido específicos de sistemas cuánticos reales. Para una simulación más precisa de los dispositivos existentes, puede construir manualmente un modelo de ruido a partir del backend real utilizando la funcionalidad ofrecida en qiskit_aer.

  • El módulo qiskit.providers.fake_provider módulo incluye ahora una serie de falsos backends genéricos que siguen la BackendV1 interfaz. Se han introducido como alternativa a los falsos backends basados en instantáneas expuestos en el obsoleto FakeProvider (FakeVigo, FakeTokyo, etc). La lista de nuevos backends falsos incluye:

    Pueden importarse siguiendo el patrón: from qiskit.providers.fake_provider import Fake5QV1. Puede encontrar más detalles sobre las propiedades de backend en la documentación de la API de cada backend.

OpenQASM Características

  • El paquete qiskit.qasm3 contiene ahora un analizador integrado basado en Rust para leer programas OpenQASM 3 en QuantumCircuits, que se encuentra en qiskit.qasm3.load_experimental() y loads_experimental(). Suelen ser varias veces más rápidas que las existentes y puras Python load() y loads() que, además, requieren la instalación de qiskit-qasm3-import .

    Por ejemplo, podemos crear un enredo de 20.000 instrucciones QuantumCircuit:

    import numpy as np
    import qiskit.qasm3
    from qiskit.circuit.library import RealAmplitudes
    
    qc = RealAmplitudes(100, reps=100, flatten=True)
    qc = qc.assign_parameters(np.random.rand(qc.num_parameters))
    oq3 = qiskit.qasm3.dumps(qc)

    El antiguo qasm3.loads() tardaba aproximadamente 7.3s en cargar el programa OpenQASM 3 resultante, mientras que qasm3.loads_experimental() tardó menos de 300ms en un Macbook Pro de consumo ( i7, 2020)-¡una aceleración de 25x!

    El conjunto de características soportadas por el analizador experimental es muy limitado en esta versión preliminar, pero se irá ampliando a medida que mejoren tanto Qiskit como el analizador nativo basado en Rust.

    Uno de nuestros principales objetivos con este nuevo analizador sintáctico, además de las enormes mejoras de velocidad, es ofrecer un diagnóstico de errores de máxima calidad. Al igual que con otras partes del analizador, se trata de un trabajo en curso, pero empezarás a ver mensajes de error de mucha más calidad cuando analices programas no válidos de OpenQASM 3 con el analizador experimental.

  • El exportador OpenQASM 3 (véase dump() y dumps() en qiskit.qasm3) soporta ahora por defecto la sintaxis estabilizada de la sentencia switch en OpenQASM 3. La sintaxis previa a la certificación de la declaración switch sigue estando disponible utilizando la bandera ExperimentalFeatures.SWITCH_CASE_V1 en el argumento experimental del exportador. Para la sintaxis estabilizada no se requiere ningún indicador de función, pero si está interactuando con otras herramientas que aún no están actualizadas, puede que necesite pasar el indicador experimental.

    La sintaxis de la forma estabilizada es ligeramente diferente en lo que respecta a la terminación de las sentencias break (ya no es necesaria ni está permitida), y los casos múltiples se combinan ahora en una única línea case , en lugar de utilizar el fall-through al estilo C. Para más detalles, consulte la documentación de OpenQASM 3 sobre la construcción switch-case.

Características de QPY

  • Añadida una nueva clase de aviso, QPYLoadingDeprecatedFeatureWarningal módulo QPY. Esta clase permite que las advertencias de desaprobación aparezcan incluso si se accede a la función desaprobada en un punto variable de la pila de llamadas, como es el caso de muchas funciones de carga de QPY que se llaman de forma recursiva.

  • Se ha añadido un nuevo indicador, version, a la función qpy.dump() función Esto permite qpy.dump() tomar opcionalmente un valor entero para la versión del formato QPY a emitir. Esto es útil si necesitas generar un archivo QPY que será cargado por una versión anterior de Qiskit. Sin embargo, las versiones soportadas para emitir son limitadas, sólo se pueden utilizar versiones entre la última versión QPY (que es la predeterminada), y la versión QPY de compatibilidad que es la Versión 10 (que se introdujo en Qiskit 0.45.0 ). La versión de compatibilidad permanecerá fija durante toda la serie de versiones principales de 1.x.y. Esto no cambia las garantías de compatibilidad con versiones anteriores del formato QPY al llamar a qpy.load()sólo permite a los usuarios emitir una versión anterior de QPY para mantener la compatibilidad y la interoperabilidad entre las series de versiones 0.x y 1.x.

Características de la información cuántica

  • Se ha añadido un qiskit.quantum_info.StabilizerState.from_stabilizer_list() que genera un estado estabilizador a partir de una lista de estabilizadores:

    from qiskit.quantum_info import StabilizerState
    
    stabilizer_list = ["ZXX", "-XYX", "+ZYY"]
    stab = StabilizerState.from_stabilizer_list(stabilizer_list)
  • SparsePauliOp.from_operator() utiliza ahora una implementación del "algoritmo tensorizado de descomposición de Pauli" presentado en Hatznko, Binkowski y Gupta (2023). El método es ahora varios órdenes de magnitud más rápido; por ejemplo, es posible descomponer un operador aleatorio de 10 qubits en alrededor de 250ms en un Macbook Pro de consumo (Intel i7, 2020).

Características de síntesis

  • Se ha añadido una qiskit.synthesis.synth_circuit_from_stabilizers() que devuelve un circuito que produce el estado estabilizado por una serie de estabilizadores dados.

  • El método del plugin de síntesis unitaria AQC utiliza ahora por defecto una evaluación más rápida de la función objetivo, lo que se traduce en una mejora sustancial del tiempo de síntesis.

  • Añade un nuevo método de síntesis synth_qft_line() de un circuito QFT para conectividad lineal de vecino más cercano, que reduce significativamente el número de SWAPs para grandes cantidades de qubits en comparación con SABRE.

  • La clase TwoQubitWeylDecomposition se ha añadido a la API pública en qiskit.synthesis. Esta clase permite aplicar la descomposición de Weyl de unitarios de dos qubits. Si anteriormente importaba esto cuando era una clase no pública en el módulo qiskit.quantum_info.synthesis , ahora eliminado, debe actualizar sus rutas de importación.

Características del transpilador

  • Añadida una nueva clase de excepción: InvalidLayoutError. Se trata de una subclase TranspilerError que se activa cuando un diseño proporcionado por el usuario no es válido (tamaño incorrecto, qubits duplicados, etc.).

  • Se ha añadido un nuevo argumento de palabra clave, num_processes, a transpile() y al método PassManager.run() método. Esto permite anular tanto QISKIT_NUM_PROCS como el campo num_processes en los archivos de configuración del usuario para cada transpile. Por ejemplo:

    from qiskit import transpile, QuantumCircuit
    
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    transpile([qc]*10, basis_gates=['u', 'cz'], num_processes=2)

    ejecutará el transpile sobre los 10 circuitos de entrada utilizando sólo 2 procesos y anulará el valor predeterminado del sistema, la variable de entorno o el archivo de configuración del usuario para esa transpile() llamada.

  • Añadido un nuevo transpiler pass, OptimizeAnnotatedque optimiza las operaciones anotadas en un circuito cuántico.

    Consulte el ejemplo siguiente:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.annotated_operation import (
        AnnotatedOperation,
        InverseModifier,
        ControlModifier,
    )
    from qiskit.circuit.library import CXGate, SwapGate
    from qiskit.transpiler.passes import OptimizeAnnotated
    
    # Create a quantum circuit with multiple annotated gates
    gate1 = AnnotatedOperation(
        SwapGate(),
        [InverseModifier(), ControlModifier(2), InverseModifier(), ControlModifier(1)],
    )
    gate2 = AnnotatedOperation(
        SwapGate(),
        [InverseModifier(), InverseModifier()]
    )
    gate3 = AnnotatedOperation(
        AnnotatedOperation(CXGate(), ControlModifier(2)),
        ControlModifier(1)
    )
    qc = QuantumCircuit(6)
    qc.append(gate1, [3, 2, 4, 0, 5])
    qc.append(gate2, [1, 5])
    qc.append(gate3, [5, 4, 3, 2, 1])
    
    # Optimize the circuit using OptimizeAnnotated transpiler pass
    qc_optimized = OptimizeAnnotated()(qc)
    
    # This is how the optimized circuit should look like
    gate1_expected = AnnotatedOperation(SwapGate(), ControlModifier(3))
    gate2_expected = SwapGate()
    gate3_expected = AnnotatedOperation(CXGate(), ControlModifier(3))
    qc_expected = QuantumCircuit(6)
    qc_expected.append(gate1_expected, [3, 2, 4, 0, 5])
    qc_expected.append(gate2_expected, [1, 5])
    qc_expected.append(gate3_expected, [5, 4, 3, 2, 1])
    
    assert qc_optimized == qc_expected

    En el caso de gate1, los modificadores de la puerta de intercambio anotada se llevan a la forma canónica: las dos InverseModifiers se anulan, y los dos ControlModifiers se combinan. En el caso de gate2, se eliminan todos los modificadores y la operación anotada se sustituye por su operación base. En el caso de gate3, se combinan varias capas de anotaciones en una sola.

    El constructor del OptimizeAnnotated pass acepta argumentos opcionales target, equivalence_library, basis_gates y recurse. Cuando recurse es True (el valor por defecto) y cuando se especifica target o basis_gates , el pase desciende recursivamente a los circuitos definition de la puerta, con la excepción de las puertas que ya están soportadas por el objetivo o que pertenecen a la biblioteca de equivalencias. Por otra parte, cuando no se especifican ni target ni basis_gates , o cuando recurse se establece en False, el pase sintetiza sólo las operaciones anotadas de "nivel superior", es decir, no desciende recursivamente a los circuitos definition . Este comportamiento es coherente con el del HighLevelSynthesis que necesita ser llamado para "desenrollar" las operaciones anotadas en puertas de 1qubit y 2qubits.

  • Se ha añadido un nuevo HighLevelSynthesisPlugin para PermutationGate basado en el algoritmo de intercambio de tokens de Qiskit. Para utilizar este complemento, especifique token_swapper al definir la configuración de síntesis de alto nivel.

    Este plugin de síntesis puede ejecutarse antes o después de establecer el diseño. Cuando la síntesis tiene éxito, el plugin produce un circuito cuántico formado únicamente por puertas de intercambio. Cuando la síntesis no tiene éxito, el plugin emite None.

    El siguiente código ilustra cómo puede ejecutarse el nuevo plugin:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PermutationGate
    from qiskit.transpiler import PassManager, CouplingMap
    from qiskit.transpiler.passes.synthesis.high_level_synthesis import HighLevelSynthesis, HLSConfig
    
    # This creates a circuit with a permutation gate.
    qc = QuantumCircuit(8)
    perm_gate = PermutationGate([0, 1, 4, 3, 2])
    qc.append(perm_gate, [3, 4, 5, 6, 7])
    
    # This defines the coupling map.
    coupling_map = CouplingMap.from_ring(8)
    
    # This high-level-synthesis config specifies that we want to use
    # the "token_swapper" plugin for synthesizing permutation gates,
    # with the option to use 10 trials.
    synthesis_config = HLSConfig(permutation=[("token_swapper", {"trials": 10})])
    
    # This creates the pass manager that runs high-level-synthesis on our circuit.
    # The option use_qubit_indices=True indicates that synthesis is run after the layout is set,
    # and hence should preserve the specified coupling map.
    pm = PassManager(
        HighLevelSynthesis(
            synthesis_config, coupling_map=coupling_map, target=None, use_qubit_indices=True
        )
    )
    
    qc_transpiled = pm.run(qc)
  • Añadidos dos nuevos argumentos, matrix_based y max_qubits, al constructor del CommutativeInverseCancellation transpiler pass. Cuando matrix_based es True, el pase utiliza representaciones matriciales para comprobar si dos operaciones son la inversa de la otra. Esto hace que las comprobaciones sean más potentes y, además, permite anular pares de operaciones que son inversas hasta una fase, al tiempo que se actualiza la fase global del circuito en consecuencia. Por lo general, esto conlleva más reducciones a costa de un mayor tiempo de ejecución. El argumento max_qubits limita el número de qubits en las comprobaciones de conmutatividad e inversa basadas en matrices. Por ejemplo:

    import numpy as np
    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import CommutativeInverseCancellation
    
    circuit = QuantumCircuit(1)
    circuit.rz(np.pi / 4, 0)
    circuit.p(-np.pi / 4, 0)
    
    passmanager = PassManager(CommutativeInverseCancellation(matrix_based=True))
    new_circuit = passmanager.run(circuit)

    El paso consigue anular las compuertas RZ y P , al tiempo que ajusta la fase global del circuito a 15π8\frac{15 \pi}{8}.

  • Se ha añadido una nueva función, high_level_synthesis_plugin_names()que puede utilizarse para obtener la lista de plugins de síntesis de alto nivel instalados para un nombre de operación dado.

Funciones de visualización

  • Las salidas text y mpl para el QuantumCircuit.draw() y circuit_drawer() mostrarán ahora información detallada para las operaciones de AnnotatedOperation. Si la dirección AnnotatedOperation.modifiers contiene un ControlModifierla operación se mostrará del mismo modo que las puertas controladas. Si el InverseModifier o PowerModifier se indicarán con el nombre de la operación base. Por ejemplo:

    from qiskit.circuit import (
        AnnotatedOperation,
        ControlModifier,
        PowerModifier,
        InverseModifier,
        QuantumCircuit
    )
    from qiskit.circuit.library import SGate
    
    annotated_op = AnnotatedOperation(SGate(), [PowerModifier(3.4), ControlModifier(3), InverseModifier()])
    qc = QuantumCircuit(4)
    qc.append(annotated_op, range(4))
    qc.draw("mpl")
    _images/release_notes-1.png

Herramientas Opciones

  • Añadida una nueva clase base de advertencia, QiskitWarning. Aunque Qiskit seguirá utilizando las advertencias integradas en Python (como DeprecationWarning) cuando sean las más apropiadas, para los casos más específicos de Qiskit, las advertencias serán subclases de QiskitWarning.

  • Los comprobadores de funcionalidad opcional (qiskit.utils.optionals) distinguirán ahora una dependencia opcional que no se ha encontrado en absoluto (una situación normal) de otra que sí se ha encontrado, pero que ha provocado errores durante su importación. En este último caso, ahora emitirán un OptionalDependencyImportWarning informándole de lo sucedido, ya que podría indicar una instalación fallida o una versión incompatible.

Notas de actualización

  • Qiskit 1.0 requiere ahora la versión 0.14.0 de rustworkx. La versión mínima requerida se ha aumentado para soportar el nuevo plugin de síntesis token_swapper PermutationGate de síntesis para HighLevelSynthesisPlugin.

  • La versión mínima de Rust soportada para construir Qiskit desde el código fuente es ahora 1.70. Esto se ha incrementado desde la anterior versión mínima soportada de Rust de 1.64 en las series de versiones de Qiskit 0.45.x y 0.46.0.

  • Se ha eliminado la dependencia de psutil. Anteriormente, la biblioteca psutil sólo se utilizaba para detectar el número de CPU físicas y la memoria total del sistema, sin embargo, esta información proporcionada no añade suficiente valor para justificar las dependencias adicionales y la sobrecarga, por lo que se ha eliminado. Esto significa que el número predeterminado de procesos utilizados por parallel_map() y las funciones que internamente pueden utilizar parallel_map() como transpile() y PassManager.run() pueden utilizar más o menos procesos paralelos que en versiones anteriores. Si quieres ajustar el número de procesos usados puedes usar el nuevo argumento num_processes para esas funciones, o la variable de entorno QISKIT_NUM_PROCS o el campo num_processes en un archivo de configuración de usuario (ver la guía de configuración local para más detalles) si necesitas ajustar el número de procesos que Qiskit usa potencialmente.

  • Se han eliminado los métodos scoped_parameters y search_parameters de la clase ScheduleBlock clase. Estos métodos devolvían Parameter objetos parcialmente vinculados a los parámetros de la ScheduleBlock pero la asignación de valores mediante estos objetos no funcionaba correctamente. Los usuarios deben utilizar ScheduleBlock.parameters e iterar a través de ScheduleBlock.references y comparar con los atributos Schedule.parameters de las subreferencias cuando necesiten distinguir en qué subrutina se utiliza un parámetro. Ver #11654 para más información.

  • Eliminada la lógica para inyectar QuantumCircuit y Gate en el contexto del pulso (como en pulse.builder.call()), que era un comportamiento heredado obsoleto en Qiskit 0.46. Los programas de pulsos deben construirse como un contexto de programa completo; los circuitos y las puertas son un nivel superior de abstracción.

    Esto incluye la eliminación de las funciones relacionadas:

    • pulse.builder.call_gate
    • pulse.builder.cx
    • pulse.builder.u1
    • pulse.builder.u2
    • pulse.builder.u3
    • pulse.builder.x
    • pulse.builder.active_transpiler_settings
    • pulse.builder.active_circuit_scheduler_settings
    • pulse.builder.transpiler_settings
    • pulse.builder.circuit_scheduler_settings

    Los argumentos default_transpiler_settings y default_circuit_scheduler_settings de pulse.builder.build() se eliminan de forma similar.

    from qiskit import transpile, schedule, QuantumCircuit, pulse
    from qiskit.providers.fake_provider import Fake7QPulseV1
    
    backend = Fake7QPulseV1()
    
    # Create a schedule from a hardware-based circuit.
    qc = QuantumCircuit(2)
    qc.cx(0, 1)
    qc = transpile(qc, backend)
    sched = schedule(qc, backend)
    
    # These pulse schedules can still be called in builder contexts.
    with pulse.build(backend) as qc_sched:
      pulse.call(sched)
    
    # Schedules for certain operations can also be directly retrieved
    # from BackendV1 instances:
    sched = backend.defaults().instruction_schedule_map.get('x', (0,))
    
    # ... and from BackendV2 instances:
    sched = backend.target['x'][(0,)].calibration
  • La versión mínima requerida para symengine ha pasado a ser >= 0.11.

Notas sobre la actualización de circuitos

  • Eliminado el método Instruction.qasm , obsoleto en Qiskit 0.45.0. Utilice qiskit.qasm2.dump() con un QuantumCircuit en su lugar.

  • Se eliminan las propiedades Bit.register y Bit.index . Quedaron obsoletos en Qiskit 0.25 (publicado en 2021-04). Los qubits y los bits viven ahora sólo en el contexto de un QuantumCircuit. La alternativa a las propiedades es utilizar QuantumCircuit.find_bit() para encontrar todos los registros que contienen un circuito y el índice del bit dentro del circuito.

  • El método QuantumCircuit.bind_parameters ha sido eliminado, tras su desaprobación en Qiskit 0.45. Puede utilizar QuantumCircuit.assign_parameters() como un reemplazo directo con todos sus valores predeterminados, y también expone características adicionales sobre el método antiguo.

  • La importación de Int1, Int2, BooleanFunction, classical_function() desde qiskit.circuit está desactivada. En su lugar, importe los objetos del submódulo qiskit.circuit.classicalfunction que requiere el paquete tweedledum .

  • Los atributos de sólo datos header y extension_lib de QuantumCircuit se eliminan tras su desaparición en Qiskit 0.45. Se trataba de datos internos del exportador OpenQASM 2 que ya no se utilizan.

  • Se ha eliminado el módulo qiskit.extensions , que ha estado pendiente de eliminación desde la versión 0.45 y ha quedado totalmente obsoleto en la versión 0.46. Las siguientes operaciones de este módulo están disponibles en qiskit.circuit.library:

    Se han eliminado los siguientes objetos:

    • SingleQubitUnitary (utilice en su lugar library.UnitaryGate),
    • Snapshot (sustituido por las instrucciones de guardado de Aer),
    • ExtensionError,

    junto con los siguientes métodos de circuito:

    • QuantumCircuit.snapshot,
    • QuantumCircuit.squ,
    • QuantumCircuit.diagonal,
    • QuantumCircuit.hamiltonian,
    • QuantumCircuit.isometry y QuantumCircuit.iso,
    • QuantumCircuit.uc,
    • QuantumCircuit.ucrx,
    • QuantumCircuit.ucry,
    • QuantumCircuit.ucrz.

    Estas operaciones pueden seguir realizándose añadiendo la instrucción adecuada a un circuito cuántico.

  • Se han eliminado métodos QuantumCircuit duplicados. Esto incluye:

  • Ya no se puede establecer QuantumCircuit.metadata para que sea None, tras la desaparición de Qiskit 0.43.0. Su tipo es dictpor lo que, para borrarlo, hay que ponerlo en {}.

  • El atributo .Register.name_format se ha eliminado tras su desaparición en Qiskit 0.40.0. Ya no existe ninguna restricción para los nombres de registro, y la expresión regular era simplemente [a-z][a-zA-Z0-9_]*.

Notas sobre la actualización de primitivas

Notas de actualización para proveedores

  • Cambiado el valor por defecto de dos argumentos (add_delay y filter_faulty) en la función convert_to_target() función Esta función de conversión ahora añade instrucciones de retardo y elimina las instrucciones defectuosas por defecto.

  • En BackendProperties y PulseDefaults utilizados por el FakeOpenPulse2Q se han actualizado para ser coherentes internamente y añadir las instrucciones que faltan. Si confiaba en los objetos del modelo anterior como objetivo de compilación, puede utilizar el backend con Qiskit 0.46 y exportar un archivo QuantumCircuit generado con transpile() y serializarlo usando qpy.dump para acceder a él en esta versión.

  • El módulo qiskit.providers.basicaer , expuesto como qiskit.BasicAer, ha sido eliminado tras su desaparición en la versión 0.46. Su funcionalidad ha sido sustituida por el módulo qiskit.quantum_info y el nuevo módulo qiskit.providers.basic_provider módulo.

    La migración de la utilización de qiskit.providers.basicaer (qiskit.BasicAer) a qiskit.providers.basic_provider puede realizarse del siguiente modo:

    Migrar de
    Sustituir por
    qiskit.BasicAerEl nuevo proveedor no tiene una instancia global, las importaciones deben ser de qiskit.providers.basic_provider
    qiskit.providers.basicaerbasic_provider
    BasicAerProviderBasicProvider
    BasicAerJobBasicProviderJob
    QasmSimulatorPyBasicSimulator
    UnitarySimulatorPyutilice Operator
    StatevectorSimulatorPyutilice Statevector

    Una diferencia notable es que el nuevo proveedor ya no se expone a través de una instancia global (como BasicAer), por lo que no será válido hacer from qiskit import BasicProvider. En su lugar, la clase del proveedor debe importarse desde su submódulo e instanciarse manualmente:

    from qiskit.providers.basic_provider import BasicProvider
    
    provider = BasicProvider()
    backend = provider.get_backend("basic_simulator")

    Los siguientes ejemplos muestran las rutas de migración de los tres simuladores en BasicAer.

    1. Simulador de vector de estado:

      from qiskit import QuantumCircuit
      qc = QuantumCircuit(3)
      qc.h(0)
      qc.h(1)
      qc.cx(1,2)
      
      # Former path
      from qiskit import BasicAer
      backend = BasicAer.get_backend("statevector_simulator")
      statevector = backend.run(qc).result().get_statevector()
      
      # New path
      from qiskit.quantum_info import Statevector
      statevector = Statevector(qc)
    2. Simulador unitario:

      from qiskit import QuantumCircuit
      qc = QuantumCircuit(3)
      qc.h(0)
      qc.h(1)
      qc.cx(1,2)
      
      # Former path
      from qiskit import BasicAer
      backend = BasicAer.get_backend("unitary_simulator")
      result = backend.run(qc).result()
      
      # New path
      from qiskit.quantum_info import Operator
      result = Operator(qc).data
    3. Simulador Qasm:

      from qiskit import QuantumCircuit
      qc = QuantumCircuit(3)
      qc.h(0)
      qc.h(1)
      qc.cx(1,2)
      qc.measure_all()
      
      # Former path
      from qiskit import BasicAer
      backend = BasicAer.get_backend("qasm_simulator")
      result = backend.run(qc).result()
      
      # New path
      from qiskit.providers.basic_provider import BasicProvider
      backend = BasicProvider().get_backend("basic_simulator")
      result = backend.run(qc).result()
      # or, directly
      from qiskit.providers.basic_provider import BasicSimulator
      backend = BasicSimulator()
      result = backend.run(qc).result()
  • Eliminada la clase ConfigurableFakeBackend obsoleta en Qiskit 0.46.0. En su lugar, puede utilizarse un FakeBackend adecuado.

  • El módulo obsoleto qiskit.providers.fake_provider se ha migrado al paquete qiskit-ibm-runtime Python. Por esta razón, los siguientes elementos del qiskit.providers.fake_provider se han eliminado tras su desaparición en Qiskit 0.46:

    • qiskit.providers.fake_provider.FakeProvider
    • qiskit.providers.fake_provider.FakeProviderForBackendV2
    • qiskit.providers.fake_provider.FakeProviderFactory
    • qiskit.providers.fake_provider.fake_backends.FakeBackendV2
    • cualquier backend falso contenido en qiskit.providers.fake_provider.backends (accesible a través del proveedor)
    • qiskit.providers.fake_provider.FakeQasmSimulator
    • qiskit.providers.fake_provider.FakeJob
    • qiskit.providers.fake_provider.FakeQobj

    Para utilizar el nuevo módulo de proveedor falso, puede ejecutar pip install qiskit-ibm-runtime y sustituir la ruta de importación de qiskit (qiskit.providers.fake_provider) por la nueva ruta de importación (qiskit_ibm_runtime.fake_provider). Ejemplo de migración:

    # Legacy path
    from qiskit.providers.fake_provider import FakeProvider, FakeSherbrooke
    backend1 = FakeProvider().get_backend("fake_ourense")
    backend2 = FakeSherbrooke()
    
    # New path
    # run "pip install qiskit-ibm-runtime"
    from qiskit_ibm_runtime.fake_provider import FakeProvider, FakeSherbrooke
    backend1 = FakeProvider().get_backend("fake_ourense")
    backend2 = FakeSherbrooke()

    Además, los siguientes backends falsos diseñados para pruebas especiales han sido sustituidos por la nueva clase GenericBackendV2 y también se han eliminado tras su desaparición en Qiskit 0.46:

    • qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2
    • `qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2LegacyQubitProps
    • qiskit.providers.fake_provider.fake_backend_v2.FakeBackend5QV2
    • qiskit.providers.fake_provider.fake_backend_v2.FakeBackendSimple

    Ejemplo de migración a la nueva GenericBackendV2 clase:

    # Legacy path
    from qiskit.providers.fake_provider import FakeBackend5QV2
    backend = FakeBackend5QV2()
    
    # New path
    from qiskit.providers.fake_provider import GenericBackendV2
    backend = GenericBackendV2(num_qubits=5)
    # note that this class will generate 5q backend with generic
    # properties that serves the same purpose as FakeBackend5QV2
    # but will generate different results

Notas sobre la actualización de Pulse

  • Eliminada la clase obsoleta qiskit.pulse.instructions.Call No se proporciona ninguna instrucción de pulso alternativa.

  • Eliminados métodos obsoletos en InstructionToQobjConverter y QobjToInstructionConverter. Esto incluye

    • InstructionToQobjConverter.convert_acquire()
    • InstructionToQobjConverter.convert_bundled_acquires()
    • InstructionToQobjConverter.convert_set_frequency()
    • InstructionToQobjConverter.convert_shift_frequency()
    • InstructionToQobjConverter.convert_set_phase()
    • InstructionToQobjConverter.convert_shift_phase()
    • InstructionToQobjConverter.convert_delay()
    • InstructionToQobjConverter.convert_play()
    • InstructionToQobjConverter.convert_snapshot()
    • QobjToInstructionConverter.convert_acquire()
    • QobjToInstructionConverter.convert_set_phase()
    • QobjToInstructionConverter.convert_shift_phase()
    • QobjToInstructionConverter.convert_set_frequency()
    • QobjToInstructionConverter.convert_shift_frequency()
    • QobjToInstructionConverter.convert_delay()
    • QobjToInstructionConverter.bind_pulse()
    • QobjToInstructionConverter.convert_parametric()
    • QobjToInstructionConverter.convert_snapshot()

    Todos estos métodos públicos se sustituyen por otros protegidos que se llaman implícitamente desde el punto de entrada único, es decir, llamando a la clase como si fuera una función.

  • Se elimina la clase qiskit.pulse.library.ParametricPulse y todas las subclases. Estos fueron obsoletos desde Qiskit 0.39 (con qiskit-terra 0.22 ), publicado en 2022-10. En su lugar, utilice SymbolicPulse y consulte su documentación para más detalles.

OpenQASM Notas sobre la actualización

Notas sobre la actualización de QPY

  • La última versión de formato de QPY es ahora la versión 11 y esto es lo que se emite por defecto al ejecutar qpy.dump().

  • Se ha eliminado la ruta del módulo qiskit.circuit.qpy_serialization , tras su desaparición en Qiskit 0.40.0. Para la serialización QPY, utilice qiskit.qpyque es la nueva ubicación.

Notas sobre la actualización de la información cuántica

  • Eliminados los métodos mágicos obsoletos __getitem__/__setitem__ de Clifford. Los métodos fueron obsoletos desde Qiskit 0.44, publicado en 2023-07. En su lugar, indexe o itere a través del atributo Clifford.tableau .

  • Se ha eliminado el módulo qiskit.quantum_info.synthesis , obsoleto desde la versión 0.46. Los siguientes objetos se han trasladado a qiskit.synthesis:

    Esta función se ha eliminado, puesto que ya ha quedado obsoleta en la versión 0.46 : * cnot_rxx_decompose

    Estas funciones se han eliminado, puesto que ya han quedado obsoletas en una versión anterior: * decompose_clifford (utilice synth_clifford_full() en su lugar) * decompose_cnotdihedral (utilice synth_cnotdihedral_full() en su lugar)

  • Las funciones process_fidelity(), average_gate_fidelity(), gate_error() y diamond_norm() ya no intentarán coaccionar entradas arbitrarias a sus tipos esperados marcados, siguiendo la desaprobación en Qiskit 0.25.0. Pasar entradas de los tipos marcados a cada argumento directamente.

Notas sobre la actualización de Synthesis

Notas sobre la actualización del transpilador

  • Se ha eliminado el método obsoleto Target.aquire_alignment . Se marcó como obsoleto en Qiskit 0.43 (publicado en 2023-05). En su lugar debe utilizarse el método Target.acquire_alignment() .

  • Eliminada la función obsoleta qiskit.transpiler.preset_passmanagers.common.get_vf2_call_limit. En su lugar, utilice get_vf2_limits().

  • El uso implícito de approximation_degree!=1.0 por defecto en la función generate_preset_pass_manager() se ha desactivado. El valor predeterminado anterior podría causar aproximaciones indebidas e inesperadas, especialmente en cargas de trabajo que implican Trotterización o ejecuciones similares de operaciones que están cerca, pero decididamente no son iguales, a la identidad.

    Este cambio hace que los valores por defecto de generación del gestor de pases interno estén en línea con transpile()que fue siempre la intención. Ver #8595 para más detalles.

  • Eliminada la clase Unroller obsoleta en qiskit.transpiler.passes.basis. Esta clase fue obsoleta en Qiskit 0.45 y su uso puede ser reemplazado por el uso combinado de BasisTranslator y UnrollCustomDefinitions.

    Tenga en cuenta que BasisTranslator y UnrollCustomDefinitions toman argumentos diferentes que Unroller, ya que requieren que se pase un objeto EquivalenceLibrary .

    Donde antes se podía utilizar Unroller(basis_gates) , ahora se puede utilizar:

    from qiskit.circuit.library.standard_gates.equivalence_library import (
        StandardEquivalenceLibrary as std_eqlib,
    )
    pm = PassManager([
        UnrollCustomDefinitions(std_eqlib, basis_gates)
        BasisTranslator(std_eqlib, basis_gates),
    ])
    translated = pm.run(circuit)
  • Se ha eliminado el paso de transpilador NoiseAdaptiveLayout , que estaba obsoleto. Fue marcado como obsoleto en Qiskit 0.46.0. Este pase ha sido sustituido en gran medida por VF2Layout y VF2PostLayout que establece un diseño basado en las características de ruido de un backend. Junto con el pase, se ha eliminado el plugin layout_method "noise_adaptive" .

  • Se ha eliminado el paso de transpilador CrosstalkAdaptiveSchedule , que estaba obsoleto. Se marcó como obsoleto en Qiskit 0.46.0. Este pase ya no se podía utilizar porque su funcionamiento interno dependía de que se establecieran propiedades personalizadas en el archivo BackendProperties de una instancia BackendV1 instancia. Como ningún backend establece estos campos, se ha eliminado el pase. Si dependes del pase para un flujo de trabajo personalizado, puedes utilizar la versión en Qiskit 0.46.x.

  • Se ha eliminado el módulo qiskit.transpiler.synthesis , obsoleto desde la versión 0.46. Se han movido los siguientes objetos:

  • El alias de palabra clave target al llamar a TwoQubitBasisDecomposer como funciones ha sido eliminada tras su desaparición en Qiskit 0.40.0. Debe pasar el argumento posicionalmente como primer argumento, o utilizar el nuevo nombre unitary.

  • El pase especializado del transpilador LinearFunctionsSynthesis se ha eliminado tras su desaprobación en Qiskit 0.40.0. Desde su desaprobación sólo ha sido una envoltura muy delgada alrededor de HighLevelSynthesisque deberías utilizar en su lugar.

  • Se elimina la ruta de importación qiskit.transpiler.passes.scheduling.calibration_creators . El transpilador lo pasa alojado, RZXCalibrationBuilder y RZXCalibrationBuilderNoEcho puede importarse directamente desde qiskit.transpiler.passes.

  • Se elimina la ruta de importación qiskit.transpiler.passes.scheduling.rzx_templates . Debe importar rzx_templates() de qiskit.transpiler.passes directamente.

  • Se actualizó un patrón para la construcción de la línea de pie de paso. Se ha eliminado el azúcar sintáctico que se muestra a continuación para la instanciación del controlador de flujo.

    from qiskit.transpiler import PassManager
    
    pm = PassManager()
    pm.append(my_pass, condition=condition_callable, do_while=do_while_callable)

    En lugar de utilizar este patrón de argumento de palabra clave, debe instanciar explícitamente el controlador de flujo.

    from qiskit.passmanager import ConditionalController, DoWhileController
    from qiskit.transpiler import PassManager
    
    pm = PassManager()
    pm.append(
      ConditionalController(
        DoWhileController(my_pass, do_while=do_while_callable),
        condition=condition_callable,
      )
    )

    Tenga en cuenta que puede gestionar el orden jerárquico de los controladores cuando desee anidarlos, lo que no era posible con los argumentos de palabra clave. También puede construir la tubería con el constructor del gestor de pases como a continuación porque no hay razón para llamar al método append ahora.

    pm = PassManager(
      ConditionalController(
        DoWhileController(my_pass, do_while=do_while_callable),
        condition=condition_callable,
      )
    )
  • Se ha eliminado el método append de los reguladores de caudal incorporados. Esto incluye

    • ConditionalController.append
    • DoWhileController.append
    • FlowControllerLinear.append

    El canal de tareas en un controlador de flujo está congelado, y debe pasarse cuando se crea la instancia del controlador.

  • Eliminados los métodos passess de PassManager y StagedPassManager que devolvían una representación de los pases incluidos en forma de lista de diccionarios. Sin embargo, este formato no representa de forma eficiente una cadena de pases más complicada, que puede incluir bifurcaciones condicionales y condiciones anidadas. En lugar de utilizar esta representación, utilice el siguiente patrón

    pm = PassManager(...)
    pm.to_flow_controller().tasks

    Esto devuelve directamente una base linealizada de instancias de tareas en formato de tupla.

  • Se ha eliminado el argumento max_iteration de PassManager.append() y PassManager.replace().

  • Las siguientes clases heredadas se han eliminado de los módulos de gestión de pases y transpilador tras su desaparición en Qiskit 0.46:

    • qiskit.passmanager.flow_controllers.FlowController
    • qiskit.transpiler.fencedobjs.FencedObject
    • qiskit.transpiler.fencedobjs.FencedPropertySet
    • qiskit.transpiler.fencedobjs.FencedDAGCircuit
    • qiskit.transpiler.runningpassmanager.RunningPassManager

Notas sobre la actualización de la visualización

  • El estilo predeterminado para la visualización de circuitos mediante Matplotlib se ha cambiado a "iqp", en consonancia con la plataforma Quantum IBM.

  • Se ha eliminado el módulo obsoleto qiskit.visualization.qcstyle . Este módulo ha sido marcado como obsoleto desde Qiskit 0.39.0. En su lugar, debe utilizar la dirección qiskit.visualization.circuit.qcstyle.

  • El soporte obsoleto para pasar a QuasiDistribution, ProbDistributiono un diccionario de distribución al argumento data de la visualización plot_histogram() ha sido eliminado. Esta funcionalidad se marcó como obsoleta en la versión de Qiskit 0.39.0 (2022-10). En cambio, si desea trazar un histograma a partir de a QuasiDistribution, ProbDistributiono un diccionario de distribución, debe utilizar la función plot_distribution() en su lugar.

  • Se ha eliminado la clave link_interval_dt de QiskitTimelineStyle . Debe utilizar el nuevo nombre link_interval_percent.

Herramientas Notas de actualización

  • El objeto qiskit.Aer se ha eliminado tras su desaparición en Qiskit 0.46. En su lugar, puede utilizar qiskit_aer.Aer, que es un sustituto directo.

  • La importación desde qiskit.providers.aer ya no funcionará, tras su desaparición en Qiskit 0.46. En su lugar, debe importar desde qiskit_aer, que es un sustituto directo.

  • Las tareas de pulso ya no son compatibles con los backends falsos, tras la eliminación de la funcionalidad de simulación subyacente en Aer. Para la simulación a nivel de pulso, fuera del contexto de los objetos de circuito, considere el uso de una biblioteca de propósito especial como Qiskit Dynamics.

  • Se elimina la función execute() de Qiskit. Esta función servía como una envoltura de alto nivel para transpilar un circuito con algunas opciones de transpilación y ejecutarlo en un backend con algunas opciones de ejecución. Para hacer lo mismo, puede utilizar explícitamente la función transpile() (con las opciones de transpilación adecuadas) seguida de backend.run() (con las opciones de ejecución adecuadas).

    Por ejemplo, en lugar de correr:

    from qiskit import execute
    job = execute(circuit, backend)

    puedes correr:

    from qiskit import transpile
    new_circuit = transpile(circuit, backend)
    job = backend.run(new_circuit)

    Alternativamente, la primitiva Sampler es semánticamente equivalente a la función obsoleta execute() . La clase BackendSampler es una envoltura genérica para backends que no soportan primitivas:

    from qiskit.primitives import BackendSampler
    sampler = BackendSampler(backend)
    job = sampler.run(circuit)
  • Se ha eliminado el objeto obsoleto qiskit.IBMQ . Este objeto alias se marcó como obsoleto en la versión de Qiskit 0.40.0. Este objeto alias redirige perezosamente el acceso a los atributos a qiskit.providers.ibmq.IBMQ. Dado que el paquete qiskit-ibmq-provider ha sido retirado y sustituido por el paquete qiskit-ibm-provider , que mantiene su propio espacio de nombres, mantener este alias ya no es relevante. Si utilizaba el alias qiskit.IBMQ , debe migrar su uso al paquete qiskit-ibm-provider . Consulte la guía de migración para obtener más información.

  • Eliminado el módulo obsoleto qiskit.tools.jupyter que anteriormente incluía Jupyter magics y widgets para visualizar interactivamente algunos datos de Qiskit. Este módulo quedó obsoleto en Qiskit 0.46.0. La mayor parte de esta funcionalidad estaba directamente vinculada al antiguo paquete qiskit-ibmq-provider y ya no era válida, por lo que se eliminó el módulo. El módulo qiskit_ibm_provider.jupyter del paquete qiskit-ibm-provider ofrece una funcionalidad similar.

  • Eliminado el módulo obsoleto qiskit.tools.monitor que anteriormente incluía herramientas para rastrear JobV1 instancias de trabajo, principalmente del paquete heredado qiskit-ibm-provider . Este módulo se marcó como obsoleto en Qiskit 0.46.0. Se elimina porque estaba directamente vinculado al paquete heredado qiskit-ibm-provider .

  • Se ha eliminado la ruta de importación obsoleta qiskit.test.mock que se utilizaba anteriormente para redirigir las importaciones de los backends simulados a su nueva ubicación en el directorio qiskit.providers.fake_provider. Este módulo se marcó como obsoleto en Qiskit 0.37.0. Si estaba utilizando este módulo, debería actualizar sus importaciones de qiskit.test.mock a qiskit.providers.fake_provider en su lugar.

  • El módulo qiskit.test ya no es un módulo público. Nunca se pretendió que fuera público, ni que se utilizara fuera del propio conjunto de pruebas de Qiskit. Toda la funcionalidad era específica de Qiskit y no se proporciona ninguna alternativa; si necesitara una funcionalidad similar, debería incluirla en sus propios arneses de prueba.

  • Se ha eliminado el módulo obsoleto qiskit.tools.visualization . Este módulo quedó obsoleto en la versión de Qiskit 0.46.0. Este módulo era una redirección heredada de la ubicación original del módulo de visualización de Qiskit y se trasladó a qiskit.visualization en Qiskit 0.8.0. Si sigues utilizando esta ruta, puedes actualizar tus importaciones de qiskit.tools.visualization a qiskit.visualization.

  • Se ha eliminado el módulo obsoleto qiskit.tools.events y la correspondiente utilidad qiskit.tools.progressbar que exponía. Quedó obsoleto en la versión de Qiskit 0.46.0. La funcionalidad de este módulo no era muy utilizada y estaba mejor cubierta por paquetes dedicados como tqdm.

  • Se ha retirado el módulo qiskit.tools . Este módulo quedó obsoleto en Qiskit 0.46.0. Se ha eliminado todo el contenido de este módulo excepto la función qiskit.tools.parallel_map , que ahora puede utilizarse desde qiskit.utils.parallel_map() en su lugar.

Primitivas obsoletas

  • Los métodos PrimitiveJob.submit() y PrimitiveJob.wait_for_final_state() se han eliminado tras su desaprobación en Qiskit 0.46. No se pretendía que fueran métodos públicos, sino que eran un legado de una estructura de herencia incorrecta.

Corrección de errores

  • Se ha corregido la devolución de programas de medición inadecuados cuando sólo se solicitaba un subconjunto de qubits. Anteriormente, se devolvía un programa de medición para todos los qubits.

  • Se ha corregido un problema en el cajón de circuitos de text cuando se mostraban operaciones que no eran de circuit.instruction.Instruction clase. Estas operaciones harían fallar el cajón. Ejemplos Clifford y AnnotatedOperation.

  • Se ha solucionado un problema con el SetLayout por el que una entrada de lista de enteros no válida que contuviera entradas duplicadas provocaba que se generara un Layout y los siguientes pases del transpilador fallaban con un error críptico. Esto se detecta ahora cuando SetLayout.run() se produce un error InvalidLayoutError error indicando que hay entradas duplicadas en la lista de enteros.

  • QPY (utilizando qpy.dump() y qpy.load()) ahora serializará y deserializará correctamente circuitos cuánticos con operaciones anotadas (AnnotatedOperation).

  • Llamando a copy() o copy_empty_like() en BlueprintCircuit se propagará correctamente la función global_phase a la copia. Antes, la fase global siempre era cero después de la copia.

  • QuantumCircuit.compose() genera ahora correctamente un error CircuitError cuando haya duplicados en los argumentos qubits o clbits .

  • QPY (utilizando qpy.dump() y qpy.load()) ahora serializará y deserializará correctamente circuitos cuánticos con operadores Clifford (Clifford).

  • Se ha corregido un problema en el cajón del circuito mpl por el que el texto se imprimía más allá del final del cajón para un SwitchCaseOp si la caja por defecto estaba vacía.

  • La emisión de argumentos qubit de QuantumCircuit.delay() produce ahora correctamente instrucciones Delay instrucciones para cada qubit, como se pretendía. Anteriormente, cuando se le daban ciertos iterables (como sets), producía silenciosamente un circuito inválido que podía fallar en lugares inusuales.

  • Se ha solucionado un problema al utilizar transpile() o al ejecutar un gestor de pases preestablecido (como el generado por generate_preset_pass_manager()) cuando se dirige a un backend que tiene conectividad disjunta añadiendo barreras adicionales a la salida QuantumCircuit. En algunos casos, varias directivas Barrier se incluirían en el circuito de salida justo antes de cualquier medida final en el circuito. Se trataba de un estado interno generado por el procesamiento interno para la conectividad disjunta que se añadía incorrectamente al circuito de salida. Corregido #11649

  • Se ha corregido un error cuando un usuario intenta cargar los datos de calibración de una puerta de Target en una situación particular. Esto ocurre cuando el backend informa sólo de datos de calibración parciales, por ejemplo haciendo referencia a un pulso de forma de onda en una definición de comando pero sin incluir ese pulso de forma de onda en la biblioteca de pulsos. En esta situación, el objeto de pulso Qiskit no pudo ser construido, resultando en una falla para construir el programa de pulso para la calibración. Ahora, cuando los datos de calibración están incompletos, el Target lo trata como equivalente a que no se informe de ninguna calibración y no lanza una excepción.

  • El método Operator.power() funciona ahora con exponentes de coma flotante, de acuerdo con la descripción documentada.

  • Se ha solucionado un problema con el paso OptimizeSwapBeforeMeasure por el que se optimizaban incorrectamente los circuitos que incluían instrucciones de intercambio y medida. Por ejemplo:

    from qiskit import QuantumCircuit
    from qiskit.transpiler.passes import OptimizeSwapBeforeMeasure
    pass_ = OptimizeSwapBeforeMeasure()
    qc = QuantumCircuit(2, 1)
    qc.swap(0, 1)
    qc.measure(0, 0)
    qc.measure(0, 0)
    print(qc.draw())
    print(pass_(qc).draw())

    se imprimiría antes:

            ┌─┐┌─┐
    q_0: ─X─┤M├┤M├
          │ └╥┘└╥┘
    q_1: ─X──╫──╫─
             ║  ║
    c: 1/════╩══╩═
             0  0
         ┌─┐
    q_0: ┤M├───
         └╥┘┌─┐
    q_1: ─╫─┤M├
          ║ └╥┘
    c: 1/═╩══╩═
          0  0

    y ahora el segundo circuito está correctamente optimizado para:

    q_0: ──────
         ┌─┐┌─┐
    q_1: ┤M├┤M├
         └╥┘└╥┘
    c: 1/═╩══╩═
          0  0
  • Se ha corregido un problema con la serialización de QPY cuando un archivo QuantumCircuit contenía varias instancias de instrucciones personalizadas que tenían el mismo atributo name atributo. En las versiones del formato QPY anteriores a la versión 11, la carga útil QPY no diferenciaba entre estas instancias y sólo serializaba las propiedades de la primera instancia de un circuito. Esto podría causar potencialmente una deserialización incorrecta si las otras propiedades de la instrucción personalizada fueran diferentes pero los nombres fueran los mismos. Esto se ha corregido en la versión 11 de QPY para que cada instancia de una instrucción personalizada se serialice individualmente y ya no haya un conflicto potencial con nombres superpuestos. Corrige #8941.

  • Se ha solucionado un problema con la función qpy.dump() por el que, cuando el indicador use_symengine se establecía en un objeto verdadero que se evaluaba como True pero no era realmente el booleano True, la carga útil QPY generada se corrompía. Por ejemplo, si define use_symengine como HAS_SYMENGINEeste objeto se evalúa como True cuando se convierte en bool, pero en realidad no es True.

  • Corrección de un error en la StabilizerState representación de cadenas.

  • Un error donde convert_to_target() y BackendV2Converter provocaban un error inesperado. El error se producía cuando el backend a convertir incluía calibraciones para una puerta que no tenía definición en las propiedades del backend. Dicha puerta se difunde ahora a todos los qubits como una instrucción ideal libre de errores, incluso cuando se informa de calibraciones para un conjunto finito de qubits.

  • Se ha solucionado un problema con la función circuit_drawer() y el método QuantumCircuit.draw() al cargar un estilo matplotlib a través del archivo de configuración del usuario.

  • InstructionDurations.from_backend() devuelve ahora una instancia de cualquier subclase de InstructionDurations en lugar de la clase base.

  • El transpilador UnitarySynthesis transpiler pass generará ahora un error en la inicialización cuando se especifique un plugin de síntesis inexistente, en lugar de esperar hasta el tiempo de ejecución para que se produzca. Corregido #11355.

  • Los exportadores de OpenQASM 3 qasm3.dump() y dumps() mostrarán ahora correctamente los archivos de la versión 3.0 en lugar de la versión sin calificar 3, ya que el proyecto OpenQASM 3 ha estandarizado el sistema de versiones.

  • La forma paramétrica de XXPlusYYGate y XXMinusYYGate devuelta por get_standard_gate_name_mapping() incluye ahora correctamente el parámetro β\beta así como la rotación inicial θ\theta.

  • El pase TemplateOptimization pass devolverá ahora expresiones paramétricas utilizando el formato nativo de expresión simbólica de ParameterExpressionen lugar de utilizar siempre Sympy. Para la mayoría de las plataformas soportadas, esto significa que las expresiones serán objetos Symengine. Anteriormente, el pase podía devolver objetos no coincidentes, lo que podía provocar fallos posteriores en el código de gestión de parámetros.

¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.