Skip to main content
IBM Quantum Platform

Notas de la versión de Qiskit 0.45

Esta página contiene las notas de la versión de Qiskit 0.45, la primera versión tras la eliminación completa de la estructura de "elementos" heredada. Para consultar todas las notas de la versión, incluidas las que se remontan a la antigua estructura de "metapaquetes" de Qiskit, véase Notas de la versión. Para obtener una tabla de versiones de metapaquetes, consulte las notas de la versión de Qiskit 0.44.


0.45.3

Preludio

Qiskit 0.45.3 es una versión puntual sin más cambios en el código que la aparición de un error ImportError si detecta que se ha instalado en un entorno no válido con Qiskit >= 1.0.

Lee nuestra guía de migración sobre el nuevo paquete para obtener ayuda sobre errores, preparación para Qiskit 1.0, e información de fondo más detallada.

Nota

El lanzamiento de Qiskit 1.0 está previsto aproximadamente dos semanas después de Qiskit 0.45.3, el 15 de febrero de 2024, y es posible que aún no esté disponible cuando leas este mensaje. Este cambio se realiza de forma proactiva.

La estructura de empaquetado de Qiskit está cambiando en Qiskit 1.0, y desafortunadamente los requisitos cambiados no se pueden comunicar completamente a pip, especialmente si los comandos pip install --upgrade se ejecutan después de que el entorno se haya configurado inicialmente. Todas las versiones de Qiskit anteriores a 1.0 (incluida ésta) tienen un conflicto de instalación con Qiskit 1.0 que pip no resolverá.

Si import qiskit te lanza un ImportError para ti, tu entorno está en un estado inválido, y las versiones de Qiskit 0.45/0.46 y 1.0 son accesibles, lo que resultará en un código sutilmente roto. Deberá crear un nuevo entorno virtual y asegurarse de que sólo está instalada una de las dos versiones. En particular, si pretende instalar Qiskit 1.0, no debe tener instalados paquetes que dependan de qiskit-terra ; estos paquetes son incompatibles con Qiskit 1.0 y deben actualizarse. Si pretende instalar Qiskit 0.45 o 0.46, debe asegurarse de que no tiene nada que intentar instalar qiskit>=1.0.

Si desarrollas una librería basada en Qiskit y todavía dependes de qiskit-terra, debes liberar urgentemente un nuevo paquete que dependa únicamente de qiskit. Desde la versión 0.44, el paquete qiskit sólo contenía el núcleo del compilador qiskit-terra (el componente que ahora se llama simplemente "Qiskit"), por lo que si su versión mínima es 0.44, puede cambiar con seguridad una dependencia de qiskit-terra>=0.44 a qiskit>=0.44 sin cambios en lo que se instalará. Para más detalles y recomendaciones sobre pruebas y preparación, consulte la sección para desarrolladores de la guía de migración.


0.45.2

Preludio

Qiskit 0.45.2 es un pequeño parche que corrige varios errores encontrados en la versión 0.45.

Corrección de errores

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

  • 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 no válido que podía fallar en lugares inusuales.

  • Se ha corregido un error que provocaba un error cuando un usuario intentaba cargar los datos de calibración de una puerta en 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 se puede construir, lo que resulta 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.

  • Se ha solucionado un problema con el Optimize1qGatesDecomposition por el que se podía resintetizar una única puerta ideal (lo que significa que la tasa de error es 0.0) que estaba presente en el archivo Target. Esto se ha corregido para que el paso Optimize1qGatesDecomposition pasará a la puerta del circuito si la tasa de error (que incluye el número de puertas) es la misma. Corregido #10568

  • 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. Esta confirmación corrige el error cambiando DAGCircuit.successors() por DAGCircuit.descendants(). Además, he añadido un par de pruebas adicionales para asegurarme de que el error está solucionado. 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 ciruit está correctamente optimizado para:

    q_0: ──────
         ┌─┐┌─┐
    q_1: ┤M├┤M├
         └╥┘└╥┘
    c: 1/═╩══╩═
          0  0
  • Corrección de un error en la StabilizerState representación de cadenas.


0.45.1

Preludio

Qiskit Terra 0.45.1 es una pequeña versión de parche que corrige varios errores encontrados en la serie de versiones 0.45. También es la primera versión compatible oficialmente con Python 3.12. La versión 0.45.1 es compatible con Python 3.8, 3.9, 3.10, 3.11 y 3.12.

Nuevas funciones

  • Se ha añadido soporte para utilizar Qiskit con Python 3.12. A partir de esta versión, Qiskit puede funcionar con las versiones Python 3.8, 3.9, 3.10, 3.11, y 3.12.

Corrección de errores

  • QuantumCircuit.barrier() generará ahora una salida correcta cuando se le dé un set como una de sus entradas. Anteriormente, añadía una operación no válida al circuito, aunque en la práctica esto no solía causar problemas observables. Corregido #11208

  • La propiedad Instruction.condition_bits manejará ahora correctamente las expresiones clásicas en tiempo de ejecución (qiskit.circuit.classical).

  • Corregido el hash() de los objetos Qiskit Pulse Channel (como DriveChannel) en los casos en que el canal se transfería de un proceso Python a otro que utilizaba una semilla hash diferente.

  • Las puertas personalizadas condicionadas importadas de OpenQASM 2 conservarán ahora correctamente sus condiciones al ser decapadas y copiadas en profundidad. Anteriormente, cualquier puerta personalizada condicional (definida por una sentencia gate en un archivo OpenQASM 2) perdía su condición al ser copiada o decapada.

  • Corregida la deserialización QPY de los archivos StatePreparation y Initialize con parámetros de cadena y entero (en lugar de un vector de estado explícito, que ya funcionaba). Corregido #11158.

  • Se ha corregido un error en SabreLayout por el que no se añadía la información de registro al objeto Layout objeto utilizado para TranspileLayout.initial_layout. Esto afectó a la visualización del circuito con QuantumCircuit.draw() y circuit_drawer() tras la transpilación, que mostraría una etiqueta de qubit virtual de la forma Qubit[QuantumRegister(6, 'q', 0)] en lugar de la etiqueta de qubit virtual esperada utilizando el nombre del registro (por ejemplo, q0). Corregido #11038

  • Se ha corregido un problema con qpy.dump() por el que la función podía ignorar el valor de use_symengine al serializar un objeto ScheduleBlock objeto. Esto daría lugar a la generación de una carga útil QPY no válida, ya que informaría de que estaba utilizando symengine para expresiones simbólicas, pero en realidad contendría datos serializados sympy.

  • Se ha corregido un error que provocaba UnitaryOverlap fallara al inicializarse si se le daba un circuito de entrada que contuviera una barrera.


0.45.0

Preludio

Qiskit 0.45.0 es la última versión antes de 1.0. Prepara el terreno para los cambios de la API que estamos planeando para nuestro primer gran lanzamiento de la versión, incluyendo muchas eliminaciones de funcionalidades previamente obsoletas, así como una serie de nuevas obsoletas.

Nota

Si tu proyecto depende de Qiskit, es posible que dependa de una funcionalidad que ya no será compatible con Qiskit 1.0. Por este motivo, le recomendamos que, de forma proactiva, limite su versión compatible a <1.0.

Algunas de las características más destacadas de Qiskit 0.45.0 son:

  • A partir de esta versión, todas las puertas no parametrizadas en la biblioteca de circuitos estándar Qiskit son ahora singletons. Por defecto, estas puertas comparten una única instancia en memoria, por lo que una vez que una puerta de un tipo específico, digamos XGatecualquier instancia posterior de XGate será una referencia a la primera. De este modo se reduce el uso de memoria y la sobrecarga de construcción cuando se utilizan varias puertas del mismo tipo en un circuito. Para realizar esta función, se han introducido nuevas clases base SingletonInstruction y SingletonGate. Consulte las notas de características para obtener más detalles.
  • Hemos añadido una nueva interfaz genérica de gestión de pases que puede encontrarse en el nuevo módulo qiskit.passmanager módulo. Se trata de una generalización del gestor de pases que se utilizó para construir el transpilador Qiskit, e introduce un marco genérico para permitir a los usuarios crear nuevos gestores de pases que utilicen diferentes representaciones intermedias (RI). El módulo incluye una clase base genérica de gestor de pases, controladores de flujo y la infraestructura necesaria para gestionar la ejecución de las tareas del gestor de pases. La nueva interfaz se utilizó para reconstruir el gestor de pases existente en el módulo qiskit.transpiler limpiando la deuda técnica del código y mejorando la usabilidad y el rendimiento. Consulte las notas sobre funciones y actualizaciones para obtener más información.
  • 0.45.0 permite a los usuarios interactuar mejor con las permutaciones de diseño realizadas por el transpilador. Los datos contenidos en la clase TranspileLayout son ahora más accesibles gracias a una serie de nuevos métodos y atributos. Y un nuevo SparsePauliOp.apply_layout() método permite aplicar una permutación de disposición específica a un SparsePauliOp observable que se construyó para un circuito de entrada al transpilador. Consulte las notas de características para obtener más detalles.
  • Por último, hemos introducido operaciones anotadas con la nueva clase AnnotatedOperation que permite formular instrucciones de circuito complejas como una instrucción base con un conjunto de modificadores. Por ejemplo, en lugar de un tipo de operación específico que implemente la inversa controlada de a RXGatepodemos utilizar un tipo de operación RXGate con atributos de inversa y control. Consulte las notas de características para obtener más detalles.

Características de los circuitos

  • Añadida una nueva clase AnnotatedOperation que es una subclase de Operation y representa alguna "operación base" modificada por una lista de "modificadores". La operación base es del tipo Operation y los modificadores admitidos actualmente son de tipo InverseModifier, ControlModifier y PowerModifier. Los modificadores se aplican en el orden en que aparecen en la lista.

    Por ejemplo:

    gate = AnnotatedOperation(
      base_op=SGate(),
      modifiers=[
          InverseModifier(),
          ControlModifier(1),
          InverseModifier(),
          PowerModifier(2),
      ],
    )

    es lógicamente equivalente a gate = SGate().inverse().control(1).inverse().power(2), o a:

    gate = AnnotatedOperation(
      AnnotatedOperation(SGate(), [InverseModifier(), ControlModifier(1)]),
      [InverseModifier(), PowerModifier(2)],
    )

    Sin embargo, esta equivalencia es sólo lógica, las representaciones internas son muy diferentes.

    Por comodidad, también se puede pasar directamente un único modificador, por lo que AnnotatedGate(SGate(), [ControlModifier(1)]) equivale a AnnotatedGate(SGate(), ControlModifier(1)).

    Una característica distintiva de una operación anotada es que la definición del circuito no se construye cuando se declara la operación, sino que ocurre sólo durante la transpilación, concretamente durante la pasada del HighLevelSynthesis transpilador.

    Una operación anotada también puede considerarse un objeto de "nivel superior" o "más abstracto" que puede añadirse a un circuito cuántico. Esto permite escribir pases de optimización del transpilador que hacen uso de esta representación de alto nivel, por ejemplo, eliminando una puerta que es seguida inmediatamente por su inversa (tenga en cuenta que esta reducción podría no ser posible si tanto la puerta como su inversa se sintetizan primero en puertas más simples).

    En cierto sentido, una operación anotada puede verse como una extensión de ControlledGateque también permite añadir control a la operación base. En el futuro tenemos previsto sustituir ControlledGate por AnnotatedOperation. De forma similar a las compuertas controladas, el transpilador sintetiza las operaciones anotadas antes de que tenga lugar el trazado/encaminamiento.

    Por ahora, las operaciones anotadas sólo pueden aparecer en el nivel superior de un circuito cuántico, es decir, no pueden aparecer dentro del circuito definido recursivamente definition . Tenemos previsto eliminar esta limitación más adelante.

  • Se ha añadido una nueva opción max_num_qubits a qiskit.circuit.CommutationChecker.commute() que especifica el número máximo de qubits a considerar para la comprobación de conmutatividad basada en la multiplicación de matrices, más costosa. Esto evita tener que asignar internamente matrices de tamaño 2N×2N2^N \times 2^N. Las versiones más sencillas de la comprobación de conmutatividad (por ejemplo, dos operaciones cuánticas conmutan cuando son sobre conjuntos disjuntos de qubits) siguen funcionando sin este límite.

  • Se ha añadido un nuevo argumento, check_input, al constructor de la clase UnitaryGate clase. Esta bandera se utiliza para desactivar la inicialización por defecto comprueba que el objeto de entrada representa una matriz unitaria. Esto se puede utilizar para acelerar la creación de UnitaryGate objetos si se sabe que la entrada ya es una matriz unitaria. Esta nueva opción sólo debe utilizarse en estos casos, ya que si se establece en False y la entrada no es unitaria, se obtendrá un objeto UnitaryGate no válido.

  • Se ha añadido un nuevo método Parameter.assign() nuevo. Este método sirve principalmente como vía rápida para mejorar el rendimiento de QuantumCircuit.assign_parameters() para el caso común de circuitos que contienen predominantemente "expresiones" que en realidad son sólo parámetros individuales que se asignarán más tarde.

  • Se ha mejorado el rendimiento de QuantumCircuit.assign_parameters() a la hora de asignar un único parámetro de un circuito en el que intervienen muchos parámetros.

  • Introducidas dos nuevas clases SingletonInstruction y SingletonGateque son subclases de Instruction y Gate respectivamente, que utilizan una única instancia para todos los objetos de ese tipo. La intención detrás de esta clase es minimizar la memoria y la sobrecarga de construcción del uso de múltiples puertas en un circuito con la compensación de tener un estado global compartido. Por esta razón, esta clase sólo es aplicable a las puertas que no tienen ningún estado único y/o mutable almacenado en una instancia. Por ejemplo, el mejor ejemplo de esto es XGate no contiene ningún estado y podría utilizar SingletonGate (y lo hace a partir de esta versión), mientras que RXGate almacena un parámetro angular en una instancia y, por tanto, no puede utilizar SingletonGate porque una única instancia global compartida no puede representar los valores de los parámetros.

    El otro problema potencial a tener en cuenta cuando se utilizan clases singleton es que el modelo de datos Instruction soporta cierto estado mutable. En concreto, el label, duration, unity condition son accesibles y mutables en la clase Instruction y sus subclases directas. Sin embargo, esto es incompatible con tener un objeto compartido mediante SingletonInstruction. Para las instancias de SingletonInstructionno está permitido establecer estos atributos directamente y se producirá una excepción. Si se necesitan para una instancia en particular, debe asegurarse de que tiene una instancia mutable utilizando Instruction.to_mutable() (o utilizar Instruction.c_if() para condition). label, duration y unit también pueden darse como argumentos de palabra clave durante la construcción de la clase.

  • Las siguientes puertas de la biblioteca estándar son ahora instancias de SingletonGate:

    Esto significa que si estas clases se instancian como (por ejemplo) XGate() utilizando todos los constructores por defecto, todos ellos compartirán una única instancia global. El resultado es una gran reducción de la sobrecarga de memoria para > 1 objeto de estos tipos y un tiempo de construcción de objetos significativamente más rápido.

  • Introducida una nueva clase SingletonControlledGate que es una subclase de ControlledGate que utiliza una única instancia para todos los objetos de ese tipo. La intención detrás de esta clase es minimizar la memoria y la sobrecarga de construcción de la utilización de múltiples puertas en un circuito con la compensación de tener un estado global compartido. Por esta razón, esta clase sólo es aplicable a las puertas que no tienen ningún estado único y/o mutable almacenado en una instancia. Por ejemplo, un CXGate no contiene ningún estado y, por tanto, puede utilizar SingletonControlledGate (y lo hace a partir de esta versión). Por el contrario, CRXGate almacena un parámetro angular como parte de sus datos de instancia y, por tanto, no puede utilizar SingletonControlledGate.

    El otro problema potencial que hay que tener en cuenta al utilizar SingletonControlledGate es que el modelo de datos original de ControlledGate admite la mutación. En concreto, el label, duration, unit, conditiony ctrl_state son accesibles y mutables en el ControlledGatepero la mutación de estos atributos en las subclases SingletonControlledGate no está permitida y provocará una excepción. Estos atributos pueden personalizarse, pero sólo en el momento de la creación (es decir, a través del constructor). En ese caso, la puerta recién construida será una instancia independiente con el estado personalizado en lugar de la instancia compartida globalmente. También puedes utilizar el método SingletonControlledGate.to_mutable() para obtener una copia mutable de un objeto gate y luego mutar los atributos como lo harías en cualquier otro objeto Instruction objeto.

  • Las siguientes puertas de la biblioteca estándar son ahora instancias de SingletonControlledGate:

    Esto significa que, a menos que se establezca label, condition, duration, unit, o ctrl_state en la instancia en el momento de la creación, todos compartirán una única instancia global cada vez que se cree un nuevo objeto de puerta. El resultado es una gran reducción de la sobrecarga de memoria para > 1 objeto de estos tipos.

  • Añadido un nuevo método Instruction.to_mutable() y atributo Instruction.mutable que se utiliza para obtener una copia mutable y comprobar si un objeto Instruction es mutable. Con la introducción de SingletonGate estos métodos pueden utilizarse para disponer de una interfaz unificada para tratar la mutabilidad de los objetos de instrucción.

  • Se ha añadido un atributo Instruction.base_classque obtiene el tipo "base" de una instrucción. Muchas instrucciones satisfarán type(obj) == obj.base_class, sin embargo las instancias únicas de SingletonInstruction y SingletonGate son subclases de su tipo base. Puede utilizar el atributo new base_class para encontrar la clase base de estos. Consulte la documentación sobre atributos para obtener consideraciones sobre cuándo otras subclases pueden modificar su base_classy lo que esto significa para la ejecución.

  • Añadido el UnitaryOverlap circuito a la biblioteca de circuitos Qiskit. Se puede utilizar para calcular la fidelidad de los estados generados por unitarios observando la probabilidad de la distribución de salida en el estado de todos los ceros o, de forma equivalente, calculando el valor de la expectativa del proyector sobre el estado de todos los ceros. Esto resulta útil en aplicaciones como el aprendizaje automático y el cálculo de estados excitados en química cuántica, por citar algunas.

Características de Pulse

  • Habilitada la programación circuito a pulso mediante BackendV2.

    # import a fake backend which is a sub-class of BackendV2
    from qiskit.providers.fake_provider import FakePerth
    from qiskit.compiler.scheduler import schedule
    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(1, 1)
    qc.x(0)
    qc.measure(0,0)
    sched = schedule(circuits=qc, backend=FakePerth())

    Dado que BackendV2 no era compatible con la función schedule() esto provocaba un error en el método schedule() cuando el argumento backend se suministraba con una instancia de BackendV2. Consulte el nº 10837 para obtener más información.

OpenQASM Características

  • El módulo OpenQASM 2 qiskit.qasm2 ha obtenido las funciones de exportación dump() y dumps(). Se utilizan de forma muy similar a los anteriores QuantumCircuit.qasm():

    from qiskit import qasm2, QuantumCircuit
    qc = QuantumCircuit(2, 2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure([0, 1], [0, 1])
    print(qasm2.dumps(qc))

    Las nuevas funciones proceden del mismo código que QuantumCircuit.qasm()que poco a poco se irá eliminando y sustituyendo por las nuevas rutas, para ofrecer una interfaz más coherente en comparación con las de OpenQASM 3 (qiskit.qasm3) y QPY (qiskit.qpy). Esto es particularmente importante ya que el nombre del método qasm() no daba ninguna indicación de la versión de OpenQASM, y desde que se añadió originalmente, Qiskit ha ganado varios módulos de serialización que podrían confundirse fácilmente.

Características de QPY

  • QPY admite ahora el uso de serialización y deserialización nativas de symengine para objetos de tipo ParameterExpression , así como expresiones simbólicas en bloques de programación Pulse. Esta es una alternativa de serialización más rápida, pero no es compatible con todas las plataformas. Por favor, comprueba que tu plataforma de destino está soportada por la librería symengine antes de configurar esta opción, ya que será requerida por qpy para deserializar la carga útil.

    La función puede activarse a través del parámetro use_symengine en qpy.dump():

    from qiskit.circuit import QuantumCircuit, Parameter
    from qiskit import qpy
    
    theta = Parameter("theta")
    phi = Parameter("phi")
    sum_param = theta + phi
    
    qc = QuantumCircuit(1)
    qc.rz(sum_param, 0)
    qc.measure_all()
    
    with open('bell.qpy', 'wb') as fd:
        qpy.dump(qc, fd, use_symengine=True)
    
    with open('bell.qpy', 'rb') as fd:
        new_qc = qpy.load(fd)[0]

Características de la información cuántica

  • Añadido Clifford.from_linear_function() y Clifford.from_permutation() que crean un objeto Clifford objeto a partir de LinearFunction y de PermutationGate respectivamente. En consecuencia, a Clifford puede ahora construirse directamente a partir de a LinearFunction, a PermutationGateo de un circuito cuántico que contenga tales puertas.

  • La clase Operator tiene ahora un método draw() que permite visualizarla como matriz de texto, objeto IPython LaTeX o fuente LaTeX. El tipo de dibujo por defecto sigue siendo el ASCII __repr__ del operador.

  • Añadido un nuevo método, apply_layout()a la clase SparsePauliOp clase. Este método se utiliza para aplicar un TranspileLayout diseño del transpilador a un SparsePauliOp observable que se construyó para un circuito de entrada al transpilador. Esto permite trabajar con BaseEstimator y la transpilación local con mayor facilidad. Por ejemplo:

    from qiskit.circuit.library import RealAmplitudes
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.primitives import BackendEstimator
    from qiskit.compiler import transpile
    from qiskit.providers.fake_provider import FakeNairobiV2
    
    psi = RealAmplitudes(num_qubits=2, reps=2)
    H1 = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
    backend = FakeNairobiV2()
    estimator = BackendEstimator(backend=backend, skip_transpilation=True)
    
    thetas = [0, 1, 1, 2, 3, 5]
    transpiled_psi = transpile(psi, backend, optimization_level=3)
    permuted_op = H1.apply_layout(transpiled_psi.layout)
    res = estimator.run(transpiled_psi, permuted_op, thetas)

    donde un circuito de entrada se transpila localmente antes de pasarlo a run. La transpilación amplía el circuito original de 2 a 7 qubits (el tamaño de backend) y permuta su disposición, que se aplica a continuación a H1 utilizando apply_layout() para reflejar las transformaciones realizadas por transpile().

Características del transpilador

  • La clase HighLevelSynthesis para sintetizar circuitos con objetos de tipo AnnotatedOperation.

  • Se ha añadido un nuevo qiskit.passmanager a la biblioteca Qiskit. Este módulo implementa un gestor de pases genérico y controladores de flujo, y proporciona infraestructura para gestionar la ejecución de las tareas del gestor de pases. El módulo proporciona clases base para pases (GenericPass) y controladores de flujo (BaseController), así como una nueva clase de interfaz, passmanager.Task, para gestionar la ejecución del gestor de pases (véase el método Task.execute() ). Estas nuevas clases siguen el patrón compuesto, ya que los controladores de flujo son colecciones de pases, y un controlador puede anidarse recursivamente en el canal de tareas. También hay que tener en cuenta que las clases base no son conscientes de los tipos de objetos de entrada y salida, y deben ser subclasificadas para un tipo de programa concreto a optimizar. Este diseño unificado reduce la complejidad del gestor de pases convencional y ya no requiere el uso de clases como RunningPassManager para gestionar el envío de la lógica de ejecución y la renormalización de la estructura de tareas. El módulo qiskit.transpiler ha sido reorganizado para reconstruir los gestores de pases existentes basándose en el gestor de pases genérico. Consulte las notas de actualización para obtener más información.

  • Se ha añadido un nuevo pase de análisis SabrePreLayout que crea un diseño inicial para SabreLayoutescribiendo el diseño en el valor del conjunto de propiedades sabre_starting_layouts.

    El pase funciona aumentando el mapa de acoplamiento con más y más aristas "extra" hasta que VF2Layout consiga encontrar un isomorfismo perfecto del grafo. Más concretamente, el mapa de acoplamiento aumentado contiene aristas entre nodos que se encuentran a una distancia determinada d en el mapa de acoplamiento original, y el valor de d se incrementa hasta que se encuentra un isomorfismo. La pasada también minimiza opcionalmente el número de aristas adicionales implicadas en el trazado hasta encontrar un mínimo local. Esto implica eliminar aristas adicionales y llamar a VF2Layout para comprobar si sigue existiendo un isomorfismo.

    He aquí un ejemplo de llamada a la función SabrePreLayout antes de SabreLayout:

    import math
    from qiskit.transpiler import CouplingMap, PassManager
    from qiskit.circuit.library import EfficientSU2
    from qiskit.transpiler.passes import SabrePreLayout, SabreLayout
    
    qc = EfficientSU2(16, entanglement='circular', reps=6, flatten=True)
    qc.assign_parameters([math.pi / 2] * len(qc.parameters), inplace=True)
    qc.measure_all()
    
    coupling_map = CouplingMap.from_heavy_hex(7)
    
    pm = PassManager(
        [
            SabrePreLayout(coupling_map=coupling_map),
            SabreLayout(coupling_map),
        ]
    )
    
    pm.run(qc)
  • Añadidos los argumentos coupling_map, target y use_qubit_indices al HighLevelSynthesis transpiler pass. El argumento target especifica el backend de destino, permitiendo a los plugins de síntesis llamados dentro del pase acceder a toda la información específica del destino, como el mapa de acoplamiento y el conjunto de puertas soportado. El argumento coupling_map sólo especifica el mapa de acoplamiento, y sólo se utiliza cuando no se especifica target . El argumento use_qubit_indices indica si el pase de síntesis de alto nivel se ejecuta antes o después de establecer el diseño, es decir, si los índices de qubits de los objetos de alto nivel se corresponden con los índices de qubits del backend de destino.

  • Se han añadido los argumentos coupling_map, target y qubits a HighLevelSynthesisPlugin. El argumento posicional target especifica el backend de destino, permitiendo al plugin acceder a toda la información específica del destino, como el mapa de acoplamiento, el conjunto de puertas soportado, etc. El argumento posicional coupling_map sólo especifica el mapa de acoplamiento, y sólo se utiliza cuando no se especifica target . El argumento posicional qubits especifica la lista de qubits sobre la que se define el objeto de nivel superior, en caso de que la síntesis se realice sobre el circuito físico. El valor de None indica que aún no se ha elegido el diseño.

    Esto permite una separación más limpia de las opciones de los plugins de síntesis en opciones generales de interfaz para plugins (es decir, coupling_map, target, y qubits) y en opciones específicas de plugins (un diccionario de configuración de forma libre especificado a través de options). Cabe señalar que este cambio es compatible con versiones anteriores, si las opciones coupling_map, etc. no se añaden explícitamente al método run() del complemento, aparecerán como parte de options.

  • Los métodos DAGCircuit métodos apply_operation_back() y apply_operation_front() han ganado un argumento de palabra clave check que puede establecerse False para omitir la validación de que las entradas cumplen las invariantes de estructura de datos DAGCircuit invariantes de la estructura de datos. Esto es útil como optimización del rendimiento cuando el DAG se construye a partir de datos conocidos, como durante las pasadas del transpilador.

  • El método CouplingMap.reduce() acepta ahora un argumento adicional check_if_connected, por defecto True. Esto corresponde al comportamiento anterior, comprobando si el mapa de acoplamiento reducido sigue conectado y lanzando un CouplingError en caso contrario. Cuando se establece en False, se omite la comprobación, lo que permite mapas de acoplamiento reducido desconectados.

  • El constructor de HighLevelSynthesis transpiler pass acepta ahora argumentos adicionales equivalence_library, basis_gates, y min_qubits. El pase puede ahora desenrollar definiciones personalizadas de forma similar a UnrollCustomDefinitionsy, como tal, subsume por completo la funcionalidad de este último. En particular, HighLevelSynthesis es ahora recursivo, corrigiendo un error en la implementación inicial. Así, cuando se especifica target o basis_gates , HighLevelSynthesis sintetiza recursivamente todos los objetos de alto nivel, operaciones anotadas y compuertas personalizadas del circuito, dejando sólo las compuertas soportadas por el objetivo o que pertenecen a la biblioteca de equivalencias. Esto permite utilizar HighLevelSynthesis como sustituto de UnrollCustomDefinitions. Por otra parte, cuando no se especifican ni target ni basis_gates , el pase sintetiza únicamente los objetos de alto nivel "de nivel superior" y las operaciones anotadas, es decir, no desciende recursivamente al campo de puertas personalizadas definition . Esto es compatible tanto con UnrollCustomDefinitions (que no haría nada) como con el comportamiento más antiguo del pase de síntesis de alto nivel, que permite utilizarlo como una transformación intermedia, sintetizando únicamente objetos de alto nivel según lo especificado por HLSConfig.

  • Mejorado significativamente el rendimiento del MergeAdjacentBarriers paso del transpilador, que solía reconstruir el DAG completo para fusionar las barreras.

  • Se ha añadido un nuevo argumento de palabra clave, min_qubits, al constructor del BasisTranslator transpiler pass. Cuando se establece en un valor distinto de cero se utiliza para establecer un número mínimo de qubits para filtrar las operaciones a traducir en el circuito. Por ejemplo, si se define min_qubits=3 , la instancia BasisTranslator sólo traducirá las puertas del circuito que operen con 3 o más qubits.

  • Se ha añadido un nuevo argumento de palabra clave, min_qubits, al constructor del UnrollCustomDefinitions transpiler pass. Cuando se establece en un valor distinto de cero se utiliza para establecer un número mínimo de qubits para filtrar las operaciones a traducir en el circuito. Por ejemplo, si se define min_qubits=3 , la instancia UnrollCustomDefinitions sólo traducirá las puertas del circuito que operen con 3 o más qubits.

  • Se ha añadido soporte a la función SabreLayout para añadir pruebas con diseños iniciales especificados. El transpilador SabreLayout transpiler suele ejecutar múltiples pruebas de diseño que comienzan con diseños totalmente aleatorios que luego utilizan un pase de enrutamiento para permutar ese diseño en lugar de insertar intercambios para encontrar un diseño que dará lugar a menos puertas de intercambio. Esta nueva función permite ejecutar un AnalysisPass antes de SabreLayout que establece el campo "sabre_starting_layout" en el conjunto de propiedades para proporcionar al SabreLayout con diseños iniciales adicionales para utilizar en sus pruebas internas. Por ejemplo, si desea ejecutar DenseLayout como punto de partida de una prueba en SabreLayout harías algo como

    from qiskit.providers.fake_provider import FakeSherbrooke
    from qiskit.transpiler import AnalysisPass, PassManager
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    from qiskit.transpiler.passes import DenseLayout
    
    class SabreDenseLayoutTrial(AnalysisPass):
    
      def __init__(self, target):
          self.dense_pass = DenseLayout(target=target)
          super().__init__()
    
      def run(self, dag):
          self.dense_pass.run(dag)
          self.property_set["sabre_starting_layouts"] = [self.dense_pass.property_set["layout"]]
    
    backend = FakeSherbrooke()
    opt_level_1 = generate_preset_pass_manager(1, backend)
    pre_layout = PassManager([SabreDenseLayoutTrial(backend.target)])
    opt_level_1.pre_layout = pre_layout

    Entonces, cuando el opt_level_1 StagedPassManager se ejecuta con un circuito la salida del DenseLayout pass se utilizará para uno de los SabreLayout ensayos además de los 5 ensayos totalmente aleatorios que se ejecutan por defecto en el nivel de optimización 1.

  • Se añaden dos nuevos pases de transpilador para generar calibraciones de puerta RX de un solo pulso sobre la marcha. Estas calibraciones RX de un solo pulso reducirán el tiempo de compuerta a la mitad, como se describe en P.Gokhale et al, Optimized Quantum Compilation for Near-Term Algorithms with OpenPulse (2020), arXiv:2004.11205.

    Para reducir la cantidad de datos de calibración RX que es necesario generar, NormalizeRXAngle realiza tres optimizaciones: envolver los RXGate ángulos de rotación a [0, pi], sustituyendo RX(pi/2) y RX(pi) por SXGate y XGatey la cuantización de los ángulos de rotación. Este pase debe ejecutarse antes de RXCalibrationBuilderque genera calibraciones RX sobre la marcha.

    Las optimizaciones realizadas por NormalizeRXAngle reducen la cantidad de datos de calibración y nos permiten aprovechar los pulsos calibrados por hardware, más precisos. Las calibraciones generadas por RXCalibrationBuilder se obtienen a partir de la calibración SXGate que ya debería estar presente en el objetivo. La amplitud se escala linealmente para alcanzar el ángulo de rotación arbitrario deseado.

    Estas calibraciones de un solo pulso reducen el RXGate tiempo a la mitad, en comparación con la secuencia convencional que consta de dos SXGate pulsos. Podría haber una mejora de la fidelidad debido a esta reducción del tiempo de puerta.

  • Añadidos nuevos métodos a TranspileLayout, initial_index_layout() y routing_permutation()que se utilizan para generar una vista de lista de los archivos TranspileLayout.initial_layout y TranspileLayout.final_layout respectivamente. Por ejemplo, si el atributo final_layout atributo fuera:

    Layout({
      qr[0]: 2,
      qr[1]: 3,
      qr[2]: 0,
      qr[3]: 1,
    })

    entonces routing_permutation() volverá:

    [2, 3, 0, 1]
  • Añadido un nuevo método a TranspileLayout, initial_virtual_layout()que es equivalente al atributo TranspileLayout.initial_layout pero da la opción de filtrar los qubits ancilla que se añadieron al circuito. Por defecto, el TranspileLayout.initial_layout incluirá normalmente las ancillas añadidas por el transpilador.

  • Añadido un nuevo método, final_index_layout() y final_virtual_layout() a la TranspileLayout clase Estos métodos se utilizan para devolver una disposición final (el mapeado de los qubits del circuito de entrada a la posición final en la salida). Esto es distinto del atributo final_layout que es la permutación causada por el enrutamiento como un Layout objeto. El método final_index_layout() devuelve una lista que muestra la posición de salida de cada qubit en el circuito de entrada al transpilador. Por ejemplo, con un circuito original:

    qc = QuantumCircuit(3)
    qc.h(0)
    qc.cx(0, 1)
    qc.cx(0, 2)

    y la salida del transpilador era:

    tqc = QuantumCircuit(3)
    tqc.h(2)
    tqc.cx(2, 1)
    tqc.swap(0, 1)
    tqc.cx(2, 1)

    entonces la salida de final_index_layout() devolvería una lista de:

    [2, 0, 1]

    El sitio final_virtual_layout() devuelve esto como un objeto Layout por lo que el resultado del ejemplo anterior sería:

    Layout({
      qc.qubits[0]: 2,
      qc.qubits[1]: 0,
      qc.qubits[2]: 1,
    })

Funciones de visualización

  • Se ha añadido la posibilidad de mostrar condiciones como expresiones de Expr en el método QuantumCircuit.draw() método y la circuit_drawer() función al visualizar circuitos que tienen ControlFlowOp instrucciones.

  • Se han añadido los estilos de color "iqp" y "iqp-dark" para el cajón de circuitos matplotlib , que se basan en el esquema de color IBM Quantum Platform.

  • En TextDrawer, las operaciones construidas a partir de ControlFlowOpincluyendo if, else, while, for, y switch/case, ya sean instanciadas directamente o construidas usando métodos en QuantumCircuitmostrarán ahora completamente los circuitos definidos en ControlFlowOps con corchetes para delimitar los circuitos.

  • Al definir una hoja de estilo personalizada para el cajón de la línea de tiempo de pulsos qiskit.visualization.timeline_drawer()las funciones "generadoras" que tengan el atributo de objeto accepts_program establecido en True recibirán un argumento de palabra clave adicional program que contendrá la programación completa QuantumCircuit que se está dibujando.

  • Las visualizaciones del plot_gate_map(), plot_coupling_map(). plot_error_map(), y plot_circuit_layout() se han mejorado significativamente para renderizar diseños de backends con un gran número de qubits. Esto se logró aprovechando graphviz a través de la función graphviz_draw() de rustworkx para realizar un diseño de gráficos algorítmico más sofisticado que se adapta a un gran número de qubits.

    _images/release_notes-1.png

Herramientas Opciones

  • Añadido soporte para expresar el signo de un ParameterExpression. En lugar de asignar un valor concreto y utilizar numpy.sign u otras funciones de biblioteca, el usuario puede utilizar la instancia de la clase ParameterExpression para calcular el signo y puede trabajar con él antes de asignar completamente la expresión.

    Se puede utilizar de la siguiente manera:

    from qiskit.circuit import Parameter
    
    b = Parameter("phi")
    sign_value = b.sign()
    print("sign of an unassigned Parameter is: ", sign_value)
    print("Sign of a Parameter assigned to -3 is: ", sign_value.assign(b,-3))

    Consulte el nº 10360 para más detalles.

  • Parameter tiene ahora una palabra clave de uso avanzado uuid en su constructor, que puede utilizarse para hacer que el comparador Parameter sea igual a otro del mismo nombre. Los usuarios no suelen utilizar esta opción, que resulta muy útil para la serialización y deserialización personalizadas.

Notas sobre la actualización de circuitos

  • La dirección ControlledGate.definition de la salida del método Gate.control() puede ser diferente en comparación con versiones anteriores. La generación interna del método Gate.control() ya no utiliza el ahora obsoleto Unroller para generar su definición, lo que puede provocar que se genere una definición diferente. La definición del objeto ControlledGate será unitaria equivalente a la generada anteriormente. Pero si necesita la definición exacta de llamar a Gate.control() puede utilizar una versión anterior y guardar el circuito con qpy.dump() y luego cargarlo con una versión más reciente.

  • La propiedad num_ancilla_qubits de la clase PolynomialPauliRotations se ha eliminado, ya que está obsoleta en Qiskit 0.23.0. En su lugar, utilice la propiedad PolynomialPauliRotations.num_ancillas.

  • Las siguientes puertas de la biblioteca estándar:

    ya no pueden fijar label, condition, durationo unit (y ctrl_state para ControlledGate subclases) después de instanciar un objeto. Aún puede establecer condition mediante el uso c_if(). Puede utilizar to_mutable() para obtener una copia mutable de la instrucción y luego utilizar el setter en esa copia en lugar del objeto original. label, duration y unit pueden darse como argumentos de palabra clave a estas puertas en el momento de la construcción, y se devolverá automáticamente una instancia mutable. Este cambio fue necesario como parte de la conversión de estas clases en SingletonGate y SingletonControlledGate lo que reduce en gran medida la huella de memoria de las instancias repetidas de estas puertas.

  • Para cualquier cosa que interactúe con Gate, Operationo Instruction o trabaje con ellos como parte de un QuantumCircuit o DAGCircuit es importante tener en cuenta que el uso de referencias compartidas para instancias es mucho más común ahora. Anteriormente, era posible reutilizar y compartir una instancia de una operación de circuito, pero no se utilizaba con mucha frecuencia y una copia generaba una instancia única. Esto ha cambiado a partir de esta versión debido a SingletonInstruction y SingletonGate (y un gran número de puertas de bibliotecas estándar que ahora se basan en ellos). Si su uso de estos objetos supone instancias únicas para cada operación de circuito, esto se convierte en un problema potencial, ya que ahora se reutilizará un estado compartido entre operaciones del mismo tipo (que persistirá a través de copias y copias profundas). Puede utilizar el atributo Instruction.mutable para comprobar la mutabilidad de un objeto o utilizar Instruction.to_mutable() para obtener una copia mutable de cualquier instrucción.

  • Más Instruction (las que devuelven singletons) ya no satisfacen estrictamente (por ejemplo):

    type(XGate()) is XGate

    Sin embargo, el objeto devuelto seguirá siendo una subclase estándar, por lo que isinstance() (la forma correcta de realizar la comprobación de tipos) seguirá funcionando correctamente. Varias instrucciones ya tenían esta propiedad (por ejemplo MCXGate), pero ahora es más común, ya que muchas más puertas estándar lo hacen.

    Si por alguna razón necesita el tipo "base" de una puerta, omitiendo las subclases sintéticas singleton, que no pueden instanciarse, consulte Instruction.base_class.

  • La definición de UnitaryGate para unitarios de un solo qubit es ahora en términos de UGate en lugar de la clase U3Gate heredada.

Notas de actualización para proveedores

  • El simulador basado en python QasmSimulatorPy simulador basado en python incluido en qiskit.providers.basicaer incluye ahora 'h' (HGate), 'p' (PhaseGate) y 'u' (UGate) en su conjunto de puertas base.

  • El argumento channel del método PulseBackendConfiguration.control() se elimina. Quedó obsoleto en Qiskit 0.33 (con Terra 0.19 ), publicado en diciembre de 2021. En su lugar, utilice el argumento qubits .

  • Sustituido el argumento qobj[Qobj] en QasmSimulatorPy.run() por run_input[QuantumCircuit or list]

    He aquí un ejemplo para migrar su código:

    # Importing necessary Qiskit libraries
    from qiskit import transpile, QuantumCircuit
    from qiskit.aer import QasmSimulator
    
    # Defining the Quantum Circuit
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    # Transpile the circuit to optimize for the target simulator
    simulator = QasmSimulator()
    transpiled_circuit = transpile(qc, simulator)
    # Run the simulation
    job = simulator.run(transpiled_circuit, shots=1024)
    # Get the simulation result
    result = job.result()

    Todos ellos estaban obsoletos desde 0.22 (publicado el 13 de octubre de 2022) y ahora se han eliminado.

Notas sobre la actualización de Pulse

  • Las funciones qiskit.scheduler.utils.format_meas_map(), qiskit.scheduler.utils.measure(), y qiskit.scheduler.utils.measure_all() se han trasladado a qiskit.pulse.utils.format_meas_map(), qiskit.pulse.macros.measure(), y qiskit.pulse.macros.measure_all() respectivamente. La ubicación anterior fue obsoleta en Qiskit 0.20.0 (Terra 0.15.0, publicado el 2020-08-10) y ya no es compatible.

  • Los métodos to_dict en las clases pulse.transforms.AlignmentKind, pulse.transforms.AlignEquispacedy pulse.transforms.AlignFunc se eliminan. Quedaron obsoletos en Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022.

Notas sobre la actualización de QPY

  • El uso de la palabra clave circuits para el primer argumento posicional en la función qiskit.qpy.dump() ya que su uso quedó obsoleto en Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. En su lugar, se puede utilizar la palabra clave programs (o simplemente pasar el argumento posicionalmente), que se comporta de forma idéntica.

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

  • El método qiskit.quantum_info.pauli_basis() ya no acepta el argumento pauli_list . Quedó obsoleto en Qiskit 0.39 (con Terra 0.22 ), publicado en octubre de 2022.

  • Se elimina la función random_stabilizer_table del módulo qiskit.quantum_info.random . Quedó obsoleto en Qiskit 0.39 (con Terra 0.22 ), publicado en octubre de 2022. En su lugar, utilice qiskit.quantum_info.random.random_pauli_list().

  • Se eliminan las clases qiskit.quantum_info.PauliTable y qiskit.quantum_info.StabilizerTable . También se elimina la función random_pauli_table() . Quedaron obsoletos en Qiskit 0.43 (con Terra 0.24 ), publicado en mayo de 2023. En su lugar, debe utilizar PauliList y random_pauli_list().

  • Los argumentos z y x al inicializador de to Pauli fueron eliminados, como obsoletos en Qiskit Terra 0.17 (publicado en abril de 2021). Un par de x y z debe pasarse posicionalmente como una única tupla (Pauli((z, x))).

  • El argumento label para el inicializador de Pauli fue eliminado, como obsoleto en Qiskit Terra 0.17 (publicado en abril de 2021). En su lugar, pase la etiqueta posicionalmente, como Pauli("XYZ").

  • Importar desde qiskit.quantum_info.operators.pauli ya no está permitido, ya que fue obsoleto en Qiskit Terra 0.21 (publicado en junio de 2022). En su lugar, importe directamente desde qiskit.quantum_info .

Notas sobre la actualización de Synthesis

  • El parámetro order en synthesis.SuzukiTrotter genera una excepción en lugar de un aviso de obsoleto cuando se establece en un número impar. Las fórmulas del producto de Suzuki son simétricas y, por tanto, sólo están definidas para órdenes pares.

Notas sobre la actualización del transpilador

  • Como consecuencia de los esfuerzos de refactorización del gestor de pases, los controladores de flujo existentes: FlowControllerLinear, ConditionalControllery DoWhileController son ahora subclases de BaseController. Tenga en cuenta que estos controladores han abandonado la implementación del método __iter__() método Ahora sólo son iterables en el contexto de una ejecución de controlador de flujo, que enhebra el estado de compilación después de que se ejecute cada tarea interna.

  • La funcionalidad de la clase RunningPassManager ha sido sustituida por el nuevo marco de gestión de pases (BasePassManager y BaseController). El gestor de pases en ejecución es ahora un controlador de flujo sin estado (esencialmente, un alias de FlowControllerLinear), ya que el gestor de pases es responsable de la construcción del canal de tareas, mientras que el controlador es responsable de la ejecución de las tareas asociadas. Ya no se recomienda subclasificar RunningPassManager , y esta clase se sustituirá completamente por el controlador de flujo en futuras versiones.

  • Se ha introducido una nueva clase WorkflowStatuspara seguir el estado del flujo de trabajo del gestor de pases. Este objeto portátil se crea cuando se ejecuta el gestor de pases y se entrega a las tareas subyacentes. Anteriormente, RunningPassManager gestionaba dicho estado mediante variables de instancia.

  • El transpilador específico transpiler.PassManager (utilizado en transpile()) es ahora una subclase de passmanager.BasePassManager. Sin embargo, este cambio en la jerarquía de clases no introduce ningún cambio radical en la API pública.

  • Las excepciones que se producen durante la ejecución del gestor de pases heredan ahora de la nueva función PassManagerError. Un fallo genérico de la maquinaria del gestor de pases levantará PassManagerError para los gestores de pases generales, pero el transpilador específico transpile.PassManager envolverá actualmente esto en su específico TranspilerError por compatibilidad con versiones anteriores. Este envoltorio se eliminará en el futuro.

  • Se ha eliminado el uso de FencedObject en el marco del gestor de pases. Esta clase envolvente no puede proteger los atributos mutables de los objetos frente a modificaciones, y esto no debería ser un problema para un código correctamente implementado. Los pases de análisis no deben modificar un IR de entrada, los controladores no deben actualizar el conjunto de propiedades, etc. Es responsabilidad del desarrollador del gestor de pases asegurarse de que el pase no modifica los atributos del objeto,

  • El nombre de plugin default está reservado para las etapas de plugin init, layout, optimization, y scheduling. Estas etapas anteriormente no reservaban este nombre de plugin, pero el nombre default se utiliza ahora para representar el método incorporado por defecto de Qiskit para estas etapas. Si estabas usando estos nombres para plugins en estos escenarios, entrarán en conflicto con el uso de Qiskit y deberás renombrar tu plugin.

  • Desactivado el uso de la clase RemoveResetInZeroState en los gestores de pases predefinidos. Anteriormente, cuando transpile() o generate_preset_pass_manager() se ejecutaba con optimization_level a nivel 1, 2 o 3, se ejecutaba RemoveResetInZeroState. Sin embargo, este pase prohibía la noción de estados iniciales arbitrarios a menos que se establecieran explícitamente en ceros con reinicios. Si necesita ejecutar el pase como parte de su proceso de compilación, puede ejecutar algo como:

    pm = generate_preset_pass_manager(1, backend)
    pm.init.append(RemoveResetInZeroState())
    pm.run(circuit)

    para conservar esta funcionalidad para la compilación de su circuito.

  • Se ha eliminado el paso de enrutamiento del transpilador obsoleto, BIPMapping . Se marcó como obsoleto en la versión de Qiskit 0.43.0. Se ha sustituido por un paquete de complementos externo: qiskit-bip-mapper. Los detalles de este nuevo paquete pueden consultarse en el repositorio github del paquete:

    https://github.com/qiskit-community/qiskit-bip-mapper

    El pase se convirtió en un paquete plugin separado por dos razones: en primer lugar, la dependencia de CPLEX hace que sea más difícil de usar, y en segundo lugar, el paquete plugin se integra más limpiamente con transpile(). El extra opcional bip-mapper para instalar cplex y docplex para soportar este pase ha sido eliminado ya que nada en Qiskit lo requiere opcionalmente.

  • El argumento qubits en el método InstructionDurations.get()ya no acepta Qubit (o una lista de ellos). Esta funcionalidad quedó obsoleta en Qiskit 0.33 (con Terra 0.19 ), publicado en diciembre de 2021. En su lugar, utiliza un número entero para los índices de los qubits.

  • Eliminado el argumento qubit_channel_mapping en RZXCalibrationBuilderque estaba obsoleto en Qiskit 0.39 (publicado en octubre de 2022, con qiskit-terra 0.22 )

  • En transpiler.CouplingMap método subgraph se suprime como obsoleto en 0.20. reduce() puede utilizarse en lugar del método subgraph.

Notas sobre la actualización de la visualización

  • Se ha eliminado la posibilidad de utilizar la palabra clave rho para el primer argumento posicional en plot_state_hinton(), plot_bloch_multivector(), plot_state_city(), plot_state_paulivec()y plot_state_qsphere(). El uso de rho ha sido sustituido por state, que puede utilizarse en su lugar. Eliminado qiskit.scheduler.utils ya que todas las funciones contenidas se trasladaron a qiskit.pulse.macros y qiskit.pulse.utils. Todos ellos estaban obsoletos desde 0.15 (publicado el 06 de agosto de 2020) y ahora se han eliminado.

  • Se eliminan los argumentos del constructor de clase qregs, cregs, layout y global_phase para visualization.QCircuitImage , ya que quedaron obsoletos en 0.20.

  • Las funciones de visualización: plot_gate_map(), plot_coupling_map(). plot_error_map()y plot_circuit_layout() dependen ahora de que graphviz esté instalado para funcionar. Este cambio era necesario para poder visualizar backends con mayor número de qubits. Este requisito externo adicional se suma a las dependencias opcionales existentes que estas funciones requerían anteriormente. Encontrará información detallada sobre cómo instalar graphviz aquí: https://graphviz.org/download/

Herramientas Notas de actualización

  • Los valores de QuasiDistribution valores pueden incluir errores de coma flotante. QuasiDistribution.__repr__ rondas utilizando numpy.round() y el parámetro ndigits puede manipularse con el atributo de clase __ndigits__. Por defecto es 15.

  • Se elimina la clase qiskit.qobj.Qobj . Quedó obsoleto en Qiskit 0.33 (con Terra 0.19 ), publicado en diciembre de 2021. En su lugar, utilice qiskit.qobj.QasmQobj o qiskit.qobj.PulseQobj.

  • El decorador qiskit.utils.deprecation.deprecate_function() está obsoleto desde Qiskit 0.39.0 (publicado en octubre de 2022, con qiskit-terra 0.22.0 ) y ahora se ha eliminado. Utilice qiskit.utils.deprecate_func() en su lugar.

  • La función execute() ya no acepta los argumentos qobj_id y qobj_header . Su uso quedó obsoleto en Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022.

  • Se retira el pase de transpilación qiskit.transpiler.passes.CXDirection . Su uso quedó obsoleto en Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. En su lugar, utilice el método más genérico GateDirection pasar.

  • Se retira el pase de transpilación qiskit.transpiler.passes.CheckCXDirection . Su uso quedó obsoleto en Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. En su lugar, utilice el método más genérico CheckGateDirection pasar.

  • La compilación de Qiskit a partir del código fuente requiere ahora un compilador de Rust compatible con la versión del lenguaje 1.64. Esto se ha incrementado desde la anterior versión mínima soportada de Rust de 1.61 para la construcción de versiones anteriores de Qiskit.

Desuso de algoritmos

  • Las utilidades de algoritmo de qiskit.utils.validation y qiskit.utils.algorithm_globals están obsoletas y se eliminarán en un plazo no inferior a 3 meses a partir de la fecha de publicación. Estas utilidades se introdujeron con el módulo qiskit.algorithms para dar soporte a flujos de trabajo de algoritmos heredados y basados en primitivas. Ahora que qiskit.algorithms está obsoleto y la base de código de los algoritmos basados en primitivas se ha migrado a una biblioteca independiente, estas utilidades ya no se utilizan en el contexto de Qiskit. Si tu aplicación lo permite, te recomendamos que migres tu código para utilizar qiskit_algorithms, donde podrás importar las utilidades relevantes en algorithm_globals y validation desde qiskit_algorithms.utils. Tenga en cuenta que las funciones heredadas no se han migrado al nuevo paquete.

Circuitos obsoletos

Deprecaciones del transpilador

  • El método de fábrica del regulador de caudal FlowController.controller_factory() queda obsoleto junto con FlowController.add_flow_controller() y FlowController.remove_flow_controller(). En el futuro, la construcción de tareas con argumentos de palabra clave en el método BasePassManager.append() también quedará obsoleta. Los controladores deben instanciarse explícitamente y adjuntarse al gestor de pases. Por ejemplo, la sintaxis convencional utilizada anteriormente

    pm.append([task1, task2], condition=lambda x: x["value1"] > 10)

    debe sustituirse por

    controller = ConditionalController([task1, task2], condition=lambda x: x["value1"] > 10)
    pm.append(controller)

    Esto último permite un control más preciso del orden de los controladores, especialmente cuando se especifican juntos varios argumentos de palabra clave, y permite la construcción de controladores de flujo generales que pueden tener más de una canalización o no tomar una única función condicional simple en sus constructores.

  • En FlowControllerLinear.append(), DoWhileController.append()y ConditionalController.append() quedan inmediatamente obsoletos. La construcción de la canalización de tareas del gestor de pases es ahora función de BasePassManagery los controladores de flujo individuales no necesitan este método. Para un controlador de flujo, todos los pases deben especificarse de una sola vez directamente en el constructor.

  • El nombre general de atributo y variable passes se sustituye por tasks en todo el qiskit.passmanager módulo. Tenga en cuenta que una tarea debe indicar una unión de pass y controller, y la forma singular pass entra en conflicto con la palabra clave Python. En este sentido, el uso de tareas es mucho más preferible.

  • El pase de transpilador Unroller transpiler pass ha quedado obsoleto y se eliminará en una futura versión. El sitio Unroller ha sido sustituido por el BasisTranslator que proporciona un conjunto similar de funciones, pero las ofrece de una manera más general, de modo que se puede traducir un circuito a cualquier conjunto de bases universales. La clase Unroller sólo funciona en situaciones en las que las definiciones de puerta del circuito se definen recursivamente en términos de la base objetivo; para las puertas de la biblioteca estándar de Qiskit esto significa UGate y CXGate. Si está utilizando el Unroller pass se puede reemplazar utilizando un gestor de pass personalizado del formulario:

    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import UnrollCustomDefinitions, BasisTranslator
    from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
    
    pm = PassManager(
        [
            UnrollCustomDefinitions(sel, basis_gates=basis_gates),
            BasisTranslator(sel, target_basis=basis_gates),
        ]
    )
    pm.run(circuit)
  • El uso del valor "unroller" para el argumento de la palabra clave translation_method en las etiquetas transpile() y generate_preset_pass_manager() ha quedado obsoleto. Este plugin de etapa de traducción será eliminado de Qiskit en una futura versión, ya que ha sido sustituido por el método por defecto "translator" que funcionará de manera similar al plugin "unroller" pero soportará un conjunto más amplio de backends de destino.

Visualización Obsoleto

  • La configuración por defecto del cajón matplotlib emite ahora un FutureWarning, ya que el estilo por defecto está cambiando al estilo "iqp" (anteriormente conocido como "iqx"). El antiguo estilo predeterminado está disponible en "clifford" . Para silenciar la advertencia, puede establecer explícitamente el estilo deseado, e. g.:

    from qiskit import QuantumCircuit
    
    circuit = QuantumCircuit(2)
    circuit.x(0)
    circuit.h(0)
    circuit.cp(0.5, 0, 1)
    
    circuit.draw("mpl", style="clifford")  # or style="iqp"
  • Pasar un circuito a qiskit.visualization.timeline_drawer() que no tenga información sobre la hora de inicio del nodo programado está obsoleto. Sólo los circuitos que han pasado por una de las pasadas de análisis de programación (por ejemplo ALAPScheduleAnalysis o ASAPScheduleAnalysis). Si ha utilizado uno de los antiguos pases de programación (por ejemplo ALAPSchedule o ASAPSchedule), puede propagar la información de programación ejecutando

    from qiskit import transpile
    from qiskit.transpiler import InstructionDurations
    
    scheduled = transpile(
      my_old_style_circuit,
      optimization_level=0,
      scheduling_method="alap",
      instruction_durations=InstructionDurations(),
    )

    Anteriormente se había previsto que este comportamiento quedara obsoleto en Qiskit 0.37, pero debido a un error en la advertencia, no se mostraba a los usuarios hasta ahora. Este comportamiento se eliminará en Qiskit 1.0.

Corrección de errores

  • El número máximo de qubits a considerar para la comprobación de conmutatividad basada en la multiplicación de matrices en CommutationChecker se limita ahora a 3 por defecto. Corregido #10488

  • El transpilador GateDirection transpiler pass utilizará ahora traducciones de base discreta en lugar de depender de una base continua RYGatelo que debería ayudar a que algunos objetivos de base discreta sean ligeramente más fiables. En general, transpile() sólo tiene soporte parcial para los conjuntos de bases que no contienen una operación de parametrización continua, por lo que no siempre puede tener éxito en estas situaciones, y casi seguro que no producirá resultados óptimos.

  • Fijo CommutationAnalysis para agrupar las puertas de un cable en conjuntos, y que cada conjunto sólo contenga puertas que se conmuten por pares. Esto evita que CommutationCancellation realice optimizaciones poco acertadas. Ver #8020

  • CUGate se comportará ahora correctamente durante las llamadas a QuantumCircuit.assign_parameters(). Anteriormente, provocaba varios errores extraños, a menudo algún tiempo después de la asignación inicial del circuito. Véanse los números 7326, 7410, 9627, 10002 y 10131.

  • La interfaz del constructor de flujo de control (las formas de gestor de contexto de QuantumCircuit.if_test(), while_loop(), for_loop() y switch()) registrarán ahora correctamente un avance de fase global independiente dentro de ese bloque. Puede añadir un avance de fase global a un bloque interno asignando a QuantumCircuit.global_phase dentro del ámbito de un constructor:

    from math import pi
    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(3, 3)
    qc.global_phase = pi / 2  # Set the outer circuit's global phase.
    
    with qc.if_test((qc.clbits[0], False)) as else_:
      # The global phase advancement in a control-flow block begins at 0,
      # because it represents how much the phase will be advanced by an
      # execution of the block.  The defined phase of the outer scope is not
      # affected by this set.
      qc.global_phase = pi
    with else_:
      # Similarly, the `else` block may induce a different global-phase
      # advancement to the `if`, so it can also be set separately.
      qc.global_phase = 1.5 * pi
    
    # The phase advancement caused directly by the outer scope is independent
    # of the phase advancement conditionally caused by each control-flow path.
    assert qc.global_phase == pi / 2

    El significado de QuantumCircuit.global_phase es el avance de fase global inherente a una única ejecución del bloque. Sigue siendo un avance de fase global, en el sentido de que si se introduce el bloque, se avanzará la fase de todos los qubits de todo el programa.

  • Arreglar el coloreado de los esquemas de color matplotlib "iqx" y "iqx-dark" , que anteriormente dibujaban el RZGate, RZZGate(multi)controlados PhaseGatey iSwapGate en el color incorrecto.

  • El hash de a Parameter es ahora igual a los hashes de cualquier ParameterExpression con el que se compara. Antes los hashes eran diferentes, lo que provocaba entradas adicionales falsas en los hashmaps cuando Parameter y ParameterExpression se mezclaban en el mismo mapa, lo que violaba el modelo de datos de Python.

  • Se ha corregido un error en la serialización de QPY (qiskit.qpy) por el que las compuertas unitarias controladas de un circuito podían provocar fallos en la deserialización. Corregido #10802.

  • Corrige la implementación de random_statevector() para que tome muestras de la distribución uniforme.

  • El pase NoiseAdaptiveLayout toma ahora CouplingMap como argumento opcional. Esto es usado por el plugin para controlar la inconsistencia entre configuration() y properties()como en el caso de FakeMelbourne. Corregido #7677.

  • Los métodos QuantumCircuit.copy() y copy_empty_like() emitirán ahora un error si el argumento name está mal escrito, en lugar de generar un circuito no válido.

  • La heurística "decay" de SabreSwap y SabreLayout ahora rastrea la profundidad correctamente en los qubits físicos en lugar de rastrear erróneamente la "profundidad" de los intercambios en los qubits virtuales.

  • Se ha corregido un error en el ECRGate que impedía establecer un atributo ECRGate.label en el momento de construir el objeto. Todas las demás Gate permiten establecer un argumento de palabra clave label en el constructor.

  • Se ha corregido un error en el constructor de Gate (y las subclases de la biblioteca estándar) en el que los parámetros duration y unit no podían establecerse como argumentos de palabra clave durante la construcción. La clase padre Instruction admitía esta configuración, pero Gate no exponía esta interfaz correctamente.

  • Se ha añadido soporte para permitir la inicialización por defecto de SparsePauliOp pasando un iterable vacío a los métodos estáticos from_list() y from_sparse_list(). Corregido #10159.

  • El uso de la clase (obsoleta) Optimizer en AQC no tenía una ruta alternativa no obsoleta, que debería haberse introducido en Qiskit 0.44. Ahora acepta una llamada que implemente el protocolo Minimizer como se indica explícitamente en la advertencia de desaprobación. La llamada puede tener el siguiente aspecto:

    from scipy.optimize import minimize
    from qiskit.transpiler.synthesis.aqc.aqc import AQC
    
    optimizer = partial(minimize, args=(), method="L-BFGS-B", options={"maxiter": 200})
    aqc = AQC(optimizer=optimizer)
  • Se ha corregido un problema con la clase Barrier clase. Al añadir una Barrier a una instancia QuantumCircuit con el método QuantumCircuit.append() no se validaba que el tamaño de la barrera coincidiera con los qargs especificados.

  • El transpilador BlockCollapser ahora maneja correctamente los circuitos que contienen más de una condición en el mismo registro clásico.

  • BlueprintCircuit ahora las subclases se comportarán correctamente cuando se utilice el método semipúblico QuantumCircuit._append() con el plano en un estado sin construir, es decir, el circuito se construirá antes de intentar la anexión.

  • Se han ajustado el zoom, el tamaño de las fuentes y los márgenes en plot_state_city() para ajustar mejor el gráfico a más tamaños de figura. Se ha corregido el comportamiento de ordenación en Z de las barras y el plano de amplitud cero, y se ha corregido la visualización de las barras de valor real negativo.

Otras notas

  • Esta versión de Qiskit está explícitamente vinculada a la serie Numpy 1.x, ya que incluye extensiones compiladas que aún no se han compilado con la serie Numpy 2.x aún no publicada. Lanzaremos una nueva versión de Qiskit compatible con Numpy 2.x tan pronto como sea posible.

    No podemos evitar que tu gestor de paquetes resuelva a versiones anteriores de Qiskit (que no tienen el mismo pin, pero aún así es probable que sean incompatibles) si intentas instalar Qiskit a la fuerza junto con Numpy 2, antes de que hayamos publicado una versión compatible.

  • Modificado el comportamiento de los VF2Layout y VF2PostLayout que anteriormente ejecutaban su puntuación interna utilizando multihilo si los circuitos de entrada eran suficientemente grandes. El uso de multihilos se ha eliminado de los pases, ya que se demostró que causaba una regresión del rendimiento en lugar de una mejora como se pretendía en un principio.

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