Skip to main content
IBM Quantum Platform

Notas de la versión de Qiskit SDK 1.2


1.2.4

Preludio

Qiskit 1.2.4 es una versión de parche que corrige un problema de QPY introducido en la versión de corrección de errores de 1.2.3. En 1.2.3, se producía un error al cargar un archivo QPY generado con una versión de symengine distinta de la instalada en el momento de la carga.

Corrección de errores

  • Se solucionó un problema introducido en la versión de corrección de errores 1.2.3 ahora retirada, que causaba que se generara una excepción con el mensaje de error “Qiskit no admite la carga de una carga útil de Symengine generada con Symengine >= 1.0 ” cada vez que se cargaba un archivo QPY que se generó con una versión de Symengine diferente de la versión instalada durante la carga. Este problema sólo podía producirse en 1.2.3.

1.2.3

Preludio

Qiskit 1.2.3 es un parche que corrige un problema en QPY que podía provocar que los archivos generados por un entorno Python no se cargaran en un entorno Python diferente, a pesar de que el formato era supuestamente transferible. Esto está relacionado con diferencias en la versión de la biblioteca symengine, contra las que QPY debería haber protegido.

Problemas conocidos

  • Las versiones de Qiskit anteriores a 1.2.4 no podrán cargar archivos QPY volcados usando qpy.dump()incluso con version configurado adecuadamente, si:

    • hay objetos ParameterExpression en el archivo QPY,
    • se activó la bandera use_symengine=True (que es la predeterminada en Qiskit >= 1.0.0 ) en qpy.dump()y
    • la versión de symengine instalada en los entornos de generación y carga no se encuentran dentro de la misma versión menor.

    Esto se aplica independientemente de la versión de Qiskit utilizada en la generación (al menos hasta Qiskit 1.2.4 inclusive).

    Si desea maximizar la compatibilidad con las versiones de Qiskit < 1.2.3, you should set use_symengine=False. Versions of Qiskit > = 1.2.3 no debe requerir esto.

  • Los archivos QPY de la serie Qiskit 0.45 pueden, en un conjunto de circunstancias muy específicas y poco probables, no cargarse con cualquier versión más reciente de Qiskit, incluido Qiskit 1.2.4. Los criterios son:

    • el QuantumCircuit o ScheduleBlock a volcar contenían objetos ParameterExpression objetos,
    • la versión instalada de symengine pertenecía a la serie 0.9 (que era la versión más reciente durante el periodo de soporte de Qiskit 0.45 ), y
    • se activó la bandera use_symengine=True (que no era la predeterminada).

    Las versiones posteriores de Qiskit utilizadas durante la generación no se ven afectadas, ya que requerían versiones más recientes que symengine 0.9.

    En este caso, puede recuperar el archivo QPY recargándolo con un entorno con Qiskit 0.45.3 y symengine 0.9.2 instalados. A continuación, utilice qpy.dump() con use_symengine=False para volver a exportar el archivo. Esto será entonces legible por cualquier versión más reciente de Qiskit.

Notas de actualización

  • Las versiones soportadas de symengine se han limitado preventivamente a < 0.14.0 (que se espera que sea la próxima versión menor, a partir de esta versión de Qiskit). Esto se ha hecho para proteger contra una posible incompatibilidad en qpy al serializar objetos ParameterExpression objetos. La serialización utilizada en las versiones 10, 11 y 12 del formato QPY para los objetos ParameterExpression está ligada a la versión de symengine utilizada para generarla, y existe la posibilidad de que una futura versión de symengine no sea compatible. Este tope superior de versión es para evitar que una futura versión de symengine cause incompatibilidades al intentar cargar ficheros QPY usando qpy.load().

Corrección de errores

  • Se ha corregido un problema con qpy.load() al cargar un archivo QPY que contenía un ParameterExpressionsi las versiones de symengine instaladas en los entornos de generación y carga no eran iguales. Por ejemplo, si un archivo QPY que contiene objetos ParameterExpression objetos fue generado usando Qiskit 1.2.2 con symengine==0.11.0 instalado, Qiskit 1.2.2 con symengine==0.13.0 instalado sería incapaz de cargarlo.

    Anteriormente, se habría producido un error en symengine en relación con este desajuste de versión. Esto se ha solucionado para symengine 0.11 y 0.13 (no existía 0.12 ). Sin embargo, si intentas utilizar diferentes versiones de symengine y no coinciden, es posible que esta versión de Qiskit no funcione.


1.2.2

Preludio

Qiskit 1.2.2 es una versión de corrección de errores menores para la serie 1.2.

Corrección de errores

  • Se ha corregido un error en el paso del transpilador ElidePermutations por el que la asignación de qubits no se actualizaba correctamente en presencia de PermutationGates.

  • Corregida una fuente potencial de no determinismo en DenseLayout (y por extensión SabreLayout) cuando se apunta a un CouplingMap o Target que tiene más de un subgrafo con el mismo grado de conectividad. En estos casos, la disposición exacta de la salida del pase podría fluctuar previamente en función del número de CPU locales y de la velocidad de ejecución de los hilos.

  • El transpilador HighLevelSynthesis ya no lanza una excepción cuando encuentra una puerta personalizada que se llama "qft" pero no es una instancia de QFTGate. En su lugar, los plugins de síntesis para puertas QFT ignoran dicha puerta, y se utiliza la definición de la puerta (si se proporciona).

  • Se ha corregido un error en los cajones de circuitos, que podían fallar u omitir cables si idle_wires=False. Corregidos #13128 y #13146.

  • Se ha corregido un problema al llamar a transpile() o al método StagedPassManager.run() de un gestor de pases generado por generate_preset_pass_manager()utilizando optimization_level 2 o 3 cuando el argumento routing_method se establece en "none" para desactivar explícitamente el enrutamiento. Anteriormente, en estas condiciones, el transpilador ejecutaba el ElidePermutations como parte de la etapa init, ya que en condiciones normales se trata de una optimización útil para eliminar SwapGate y PermutationGate instancias del circuito. Pero en routing_method="none" no se esperaba esta optimización, ya que permuta el circuito de forma similar al enrutamiento, que no debería realizarse en routing_method="none". Esto se ha solucionado dejando de ejecutar ElidePermutations si routing_method="none" está configurado. Corregido #13144.

  • El exportador OpenQASM 3 ha restaurado su comportamiento de aceptar archivos de inclusión de bibliotecas no estándar en el argumento includes a qasm3.dump(), dumps()y Exporter. Éstas insertarán una sentencia include adecuada en la salida como antes, y el exportador seguirá sin conocer las puertas previstas en ese archivo de inclusión; deberá pasar las puertas que espera que defina en el argumento basis_gates a las mismas funciones.

    Esperamos mejorar el mecanismo de exportación contra archivos de inclusión no estándar en una futura versión de Qiskit.


1.2.1

Preludio

Qiskit 1.2.1 es una versión de corrección de errores menores para la serie 1.2.

Corrección de errores

  • Se ha corregido un problema con las visualizaciones de algunos backends/mapas de acoplamiento que se mostraban como plegados por sí solos. La configuración por defecto <https://graphviz.org/docs/layouts/neato/> funciona bien en la mayoría de los casos. Sin embargo, prism overlap devuelve un diseño más regular para otros escenarios.

  • Las puertas de la biblioteca estándar controladas por parámetros (como CRXGate) serán ahora extraídas correctamente a una puerta estándar del espacio Rust cuando se utilice QuantumCircuit.append() y el objeto puerta. Anteriormente existía una discrepancia en la que el uso del método QuantumCircuit.crx() provocaba una extracción correcta en el espacio Rust, pero la forma append() no. En general, el fallo no debería haber causado ninguna inseguridad en Python.

  • Se ha corregido un error en TwoQubitBasisDecomposer donde el código basado en Rust entraba en pánico si la puerta KAK dada no era una versión por defecto de las puertas estándar (por ejemplo, usando CXGate(ctrl_state=0)). Corregido #12998.

  • Se ha corregido un error por el que InstructionDurations.from_backend() no funcionaba para los backends BackendV2 backends. Corregido #12760.

  • Corregida la definición de la matriz CUGate en el espacio Rust. Aunque esto no se notaba cuando se manejaba el CUGate puramente en Python, esto tenía efectos en cadena cuando los pases del transpilador utilizaban la representación de Rust, como podía ocurrir en Consolidate2qBlocks. Corregido #13118.

  • Se ha corregido un error en HoareOptimizer por el que se simplificaba una puerta controlada eliminando sus controles, pero la nueva puerta no se gestionaba correctamente. Corregido #13079.

  • generate_preset_pass_manager() ahora lanza correctamente una excepción, si seed_transpiler se establece en un valor no válido (es decir, no es un entero no negativo). Corregido #12938.

  • Se ha corregido un caso extremo en SabreLayoutdonde, en raras ocasiones en dispositivos grandes y circuitos difíciles, el enrutamiento fallaba. Esto se debe a que la válvula de liberación hace enrutable más de una puerta de dos qubits, cuando sólo se esperaba una. Corregido #13081.

  • Se ha corregido un error en Split2QUnitaries que impedía su ejecución en circuitos con objetos Gate personalizados que no implementaban __array__. Ver #12970.

  • Se ha corregido un error en StatePreparation por el que se ignoraba el argumento normalize para las matrices de entrada. Corregido #12984.

  • Se ha corregido un error por el que varios métodos de síntesis creaban circuitos sin registros cuánticos o clásicos. Esto también afectó a las funciones que utilizaban internamente los métodos de síntesis, tales como Clifford.to_circuit(). Aunque los circuitos eran válidos, esto podía causar problemas al comparar circuitos con registros. Corregido #13041.

  • Se ha corregido un error que provocaba que el método Initialize.gates_to_uncompute() fallara. Corregido #12969.

  • Se ha corregido un caso extremo al transpilar un circuito con optimization_level 2 o 3 con un conjunto incompleto de puertas de base de 1 qubit en un circuito que contiene puertas de 2 qubits, que puede implementarse como un producto de puertas de un solo qubit. Este error se resuelve restringiendo Split2QUnitaries para que sólo tenga en cuenta los objetos UnitaryGate objetos. Corregido #12970.


1.2.0

Preludio

La versión de Qiskit 1.2.0 se centra principalmente en mejorar el rendimiento y la calidad del compilador. Además, es la última versión compatible con Python 3.8. En Qiskit 1.3.0 la versión mínima requerida de Python será 3.9. Entre una amplia gama de nuevas funciones, mejoras y correcciones, destacan las siguientes:

  • La infraestructura del circuito, incluidas las puertas y las operaciones, se traslada a Rust. Esto permite acelerar la construcción y manipulación de circuitos.
  • Aprovechando el punto anterior, partes de la biblioteca de síntesis construyen ahora circuitos en Rust. Esto supone un aumento significativo de la velocidad al sintetizar operaciones como Cliffords, permutaciones o funciones lineales. Por ejemplo, la descomposición de Cliffords de más de 50 qubits se beneficia de una aceleración aproximada de 1000 veces en el tiempo de ejecución.
  • La calidad de los circuitos compilados se mejora optimizando con una optimización de peephole unitaria en la fase inicial del flujo de trabajo de transpilación (en el nivel de optimización >1), y utilizando un trazado denso como prueba de trazado Sabre (en el nivel de optimización >0).

Nuevas funciones

  • Se ha añadido una nueva clase QFTGate para representar de forma nativa las transformadas cuánticas de Fourier (QFT). La forma más antigua de representar las QFT mediante circuitos cuánticos, véase QFTse mantiene por compatibilidad con versiones anteriores. La nueva forma de representar una QFT mediante una puerta evita sintetizar su circuito de definición cuando se declara la puerta, retrasando la síntesis real al transpilador. También permite elegir fácilmente entre varios algoritmos diferentes para sintetizar QFT, que están disponibles como plugins de síntesis de alto nivel.

  • Añadido un método de síntesis synth_qft_full() para construir un circuito QFT suponiendo una arquitectura totalmente conectada.

  • Añadidos dos plugins de síntesis de alto nivel para sintetizar un QFTGate. La clase QFTSynthesisFull se basa en synth_qft_full() y sintetiza una puerta QFT asumiendo una conectividad todo-a-todo. La clase QFTSynthesisLine se basa en synth_qft_line() y sintetiza una puerta QFT asumiendo una conectividad lineal-próximo-próximo.

  • Añadidos dos parámetros a GenericBackendV2 para excluir el error (noise_info) y la información del canal de impulsos (pulse_channels) de la construcción del backend. Estos parámetros son True por defecto, replicando el comportamiento inicial por defecto del constructor. Un usuario sensible a la memoria puede configurar estas opciones en False para reducir la sobrecarga de memoria en 40x al transpilar a gran escala GenericBackendV2.

  • La clase StabilizerState tiene ahora un nuevo método StabilizerState.probabilities_dict_from_bitstring() que permite al usuario pasar una única cadena de bits para medir un resultado. Anteriormente se utilizaba el StabilizerState.probabilities_dict() se utilizaba y en el peor de los casos calculaba ( 2n2^n ) un número de cálculos de probabilidad (dependiendo del estado), incluso si un usuario quería un único resultado. Con este nuevo método, el usuario puede calcular sólo el valor de la cadena de bits del resultado que pasa para medir la probabilidad. A medida que aumenta el número de qubits, más evidente puede ser la mejora del rendimiento (dependiendo del estado), ya que sólo se mide el resultado de 1 cadena de bits.

  • Implementado UniformSuperpositionGate clase, que permite la creación de un estado de superposición uniforme utilizando el algoritmo de Shukla-Vedula. Esta característica facilita la creación de circuitos cuánticos que producen un estado de superposición uniforme 1Mj=0M1j\frac{1}{\sqrt{M}} \sum_{j=0}^{M-1} |j\rangle, donde MM es un número entero positivo que representa el número de estados base computacionales con una amplitud de 1M\frac{1}{\sqrt{M}}. Esta implementación soporta la creación eficiente de estados de superposición uniforme, requiriendo sólo O(log2(M))O(\log_2 (M)) qubits y O(log2(M))O(\log_2 (M)) puertas. Ejemplo de uso:

    from qiskit import QuantumCircuit 
    from qiskit.circuit.library.data_preparation import UniformSuperpositionGate
    
    M = 5
    num_qubits = 3
    usp_gate = UniformSuperpositionGate(M, num_qubits)
    qc = QuantumCircuit(num_qubits)
    qc.append(usp_gate, list(range(num_qubits)))
    
    qc.draw()

Características de los circuitos

  • Añadida una nueva función random_clifford_circuit() a qiskit.circuitque permite generar un circuito Clifford pseudoaleatorio con puertas de la biblioteca estándar. Ejemplo de uso:

    from qiskit.circuit.random import random_clifford_circuit
    
    circ = random_clifford_circuit(num_qubits=2, num_gates=6)
    circ.draw(output='mpl')
    _images/release_notes-1.png
  • Se ha añadido compatibilidad con AnnotatedOperation.params y AnnotatedOperation.validate_parameter()que permiten el manejo de parámetros a nivel de circuito (como parámetros de enlace) para operaciones anotadas.

  • CircuitInstruction y DAGOpNode disponen de nuevos métodos para consultar diversas propiedades de su código interno Operationsin necesidad de acceder a él. Estos métodos son los siguientes:

    En su caso, utilizar cualquiera de estos métodos es significativamente más rápido que consultar CircuitInstruction.operation o DAGOpNode.op directamente, especialmente si la instrucción o nodo representa una puerta estándar de Qiskit. Esto se debe a que las puertas estándar se almacenan de forma nativa en Rust, y su representación Python sólo se crea cuando se solicita.

  • Se ha añadido una representación nativa en rust de la biblioteca de compuertas estándar de Qiskit. Cuando se añade una puerta estándar a un QuantumCircuit o DAGCircuit ahora se representa de una manera más eficiente directamente en Rust. Al acceder a ese objeto puerta desde un circuito o DAG se devolverá un nuevo objeto Python que representa la puerta estándar. Esto conduce a una transpilación y manipulación más rápida y eficiente de los circuitos para la funcionalidad escrita en Rust.

  • La función random_circuit() tiene una nueva característica en la que los usuarios pueden especificar una distribución num_operand_distribution (un dict) que especifica la proporción de puertas 1-qubit, 2-qubit, 3-qubit y 4-qubit en el circuito aleatorio. Por ejemplo, si se pasa num_operand_distribution = {1: 0.25, 2: 0.25, 3: 0.25, 4: 0.25} a la función, el circuito generado tendrá aproximadamente un 25% de puertas 1-qubit, 2-qubit, 3-qubit y 4-qubit. También debe tenerse en cuenta que si no se especifica num_operand_distribution entonces max_operands será por defecto 4 y se generará un circuito aleatorio con una distribución de puertas aleatoria. Si se especifican al mismo tiempo num_operand_distribution y max_operands , se utilizará num_operand_distribution para generar el circuito aleatorio.

    Ejemplo de uso:

    from qiskit.circuit.random import random_circuit
    
    circ = random_circuit(
      num_qubits=6, depth=5, num_operand_distribution={1: 0.25, 2: 0.25, 3: 0.25, 4: 0.25}
    )
    circ.draw(output="mpl")
    _images/release_notes-2.png
  • Mejora del rendimiento del método DAGCircuit.quantum_causal_cone() al no examinar el mismo nodo no directivo varias veces cuando se llega a él desde distintas rutas.

  • Se ha añadido el argumento insert_barriers al método QuantumCircuit.repeat() método. Si se configura en True , se insertarán barreras entre las repeticiones del circuito.

  • Sustituyendo el algoritmo de síntesis interno de StatePreparation y Initialize de Shende et al. por el algoritmo dado en Isometry de Iten et al. El nuevo algoritmo reduce el número de puertas CX y la profundidad del circuito en un factor de 2.

  • ParameterExpression ahora admite el operador unario + .

Características primitivas

  • Se ha añadido un nuevo método BitArray.postselect() que devuelve todas las tomas que contienen los valores de bits especificados. Ejemplo de uso:

    from qiskit.primitives.containers import BitArray
    
    ba = BitArray.from_counts({'110': 2, '100': 4, '000': 3})
    print(ba.postselect([0,2], [0,1]).get_counts())
    # {'110': 2, '100': 4}
  • Los metadatos de Primitives V2 implementaciones, es decir, StatevectorSampler, StatevectorEstimator, BackendSamplerV2 y BackendEstimatorV2se han actualizado para que coincidan con los de los dispositivos cuánticos de IBM.

    Obsérvese que los metadatos de StatevectorEstimator no tiene shots porque la clase calcula los valores de expectativa con Statevector y los disparos no se utilizan.

OpenQASM Características

  • La tabla de símbolos interna del exportador OpenQASM 3 (qiskit.qasm3) ha sido reescrita, lo que debería resultar en salidas más limpias cuando se utilizan puertas de la biblioteca estándar Qiskit que no están en las cabeceras de la biblioteca estándar OpenQASM 3, y salidas más deterministas. Por ejemplo, si se utilizan varios RZXGates dará lugar ahora a una única definición paramétrica, y cuando se produzcan colisiones de nombres, la tabla de símbolos asignará un contador determinista para que los nombres sean únicos, en lugar de un entero no determinista (antes se utilizaba la identidad del objeto).

  • La versión vendida de la biblioteca estándar OpenQASM 3.0 se ha actualizado para que coincida con el estado de la confirmación 4ca1d79383. En general, esto no debería afectar a tu uso de Qiskit, a menos que estés recuperando nuestro archivo vendido para tu propio uso.

Características de síntesis

  • MCXRecursive con kk qubits de control y un único qubit auxiliar limpio requiere ahora como máximo 16k816k-8 puertas CX.

  • MCXVChain tiene dos nuevos parámetros booleanos relative_phase y action_only. Si action_only es True el circuito no limpia los qubits sucios. Si relative_phase es True la puerta se implementa hasta una fase global. Ambos parámetros se utilizan para optimizar la descomposición de MCXVChain.

  • MCXVChain con kk controles y k2k-2 qubits auxiliares sucios ahora requiere 8k68k-6 puertas CX.

  • Portar synth_permutation_acg()utilizado para sintetizar permutaciones de qubits, a Rust. Esto produce una mejora aproximada del rendimiento de 3x en circuitos de 1000 qubits.

  • Portar synth_permutation_basic()utilizado para sintetizar permutaciones de qubits, a Rust.

  • Puerto synth_cnot_count_full_pmh()utilizado para sintetizar una función lineal en una red CX, a Rust. Esto produce un aumento de la velocidad de aproximadamente 44x, medido en circuitos de 100 qubits.

  • La función synth_cnot_count_full_pmh() permite ahora elegir el (heurísticamente) óptimo section_size fijándolo en None. A continuación, se elige un valor que intente minimizar el límite superior del número de puertas CX, es decir, αlog2(n)\alpha \log_2(n) donde nn es el número de qubits y α0.56\alpha \approx 0.56.

  • La función synth_clifford_bm() se ha portado a Rust. Recordemos que esta función sintetiza de forma óptima Clifford operadores en 1, 2 o 3 qubits con respecto al número de puertas CX. Esto se traduce en un aumento significativo del rendimiento. Para Cliffords de más de 3 qubits, el aumento de velocidad es del orden de 80 veces.

  • La función synth_clifford_greedy() que sintetiza los operadores Clifford fue portado a Rust, lo que lleva a un aumento significativo en el rendimiento para todos los números de qubits. Para Cliffords de más de 50 qubits, el aumento de velocidad es del orden de 1.000 veces.

  • Se ha añadido el argumento wrap a las clases ProductFormula que (cuando está activada) envuelve términos individuales de evolución de Pauli. Esto puede ser útil para visualizar circuitos.

  • El argumento atomic_evolution de ProductFormula (y sus subclases) tiene una nueva firma de función. En lugar de tomar un operador de Pauli y un coeficiente de tiempo y devolver el circuito de evolución, la nueva función toma un circuito existente y debe añadir la evolución del operador de Pauli proporcionado y el tiempo dado a este circuito. Esta nueva aplicación mejora considerablemente el rendimiento.

  • Mejorado el rendimiento de synth_permutation_depth_lnn_kms()utilizado para sintetizar permutaciones para conectividad lineal, portándolo a Rust.

Características del transpilador

  • Se ha añadido una nueva opción de ruta de importación para generate_preset_pass_manager()de modo que ahora se puede importar como:

    from qiskit import generate_preset_pass_manager

    en lugar de tener que escribir la ruta completa:

    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

    La función también se puede importar desde el módulo qiskit.transpiler como:

    from qiskit.transpiler import generate_preset_pass_manager
  • Añadida una nueva opción de archivo de configuración de usuario sabre_all_threads y una variable de entorno correspondiente QISKIT_SABRE_ALL_THREADS. Cuando esta bandera está activada, los gestores de pases preestablecidos ejecutarán el SabreLayout y SabreSwap utilizando todas las CPUs disponibles en el sistema local. Utilizar esta opción es un compromiso entre el determinismo de la salida entre diferentes ordenadores y una salida potencialmente mejor con menos SwapGates.

    Estos pases del transpilador ejecutan múltiples pruebas aleatorias en paralelo y eligen la salida que da como resultado el menor número de SwapGates. Como regla general, si realiza más pruebas, el algoritmo tendrá más oportunidades de encontrar un resultado mejor. Por defecto, los gestores de pases predefinidos utilizan un número fijo de pruebas, en esta versión 5 pruebas para los niveles 0 y 1, y 20 pruebas para los niveles 2 y 3, pero estos números pueden cambiar en futuras versiones (y eran diferentes en versiones históricas). Utilizando un número fijo de ensayos se obtienen resultados deterministas independientemente del sistema local, ya que incluso con una semilla fija si por defecto se tuviera en cuenta el número de CPUs locales disponibles los resultados serían diferentes al ejecutarse entre distintos ordenadores.

    Si el número de pruebas por defecto para un determinado nivel de optimización es superior al número de CPUs locales, se utilizará el nivel de optimización por defecto que sea superior.

  • Se ha añadido un nuevo paso Split2QUnitaries que itera sobre todas las puertas o unitarios de dos qubits de un circuito y los sustituye por dos unitarios de un solo qubit, si es posible sin introducir errores, es decir, la puerta/unitario de dos qubits es en realidad un producto tensorial de unitarios de un solo qubit.

  • Los pases Collect2qBlocks, ConsolidateBlocks y Split2QUnitaries se han añadido a la etapa init de los gestores de pases preestablecidos con nivel de optimización 2 y nivel de optimización 3. La modificación de la etapa init debería permitir un encaminamiento más eficaz de los circuitos cuánticos que:

    • contienen compuertas/unitarios de dos qubits que en realidad son un producto de compuertas de un solo qubit, o bien
    • contienen múltiples puertas de dos qubits en un bloque continuo de puertas de dos qubits.

    En el primer caso, el enrutamiento de la puerta de dos qubits puede simplemente omitirse, ya que no se produce ninguna interacción real entre un par de qubits. En este último caso, el espacio de espera de los algoritmos de encaminamiento no está "contaminado" por puertas superfluas de dos qubits, es decir, para el encaminamiento basta con considerar una sola puerta de dos qubits por bloque continuo de puertas de dos qubits. Estos pases no se ejecutan si los gestores de pases tienen como objetivo un Target que tiene un conjunto de puertas base discretas, es decir, todas las puertas base no están parametrizadas.

  • El rendimiento de StarPreRoutingutilizado para encontrar un subcircuito de conectividad de grafo estrella, se mejora realizando el trabajo pesado en el espacio Rust.

  • El transpilador SabreLayout transpiler pass se ha actualizado para ejecutar siempre una prueba adicional utilizando el mismo algoritmo que DenseLayout para elegir un punto de partida para el algoritmo de trazado de Sabre. El punto de partida utilizado por el algoritmo de trazado puede tener una gran influencia en la calidad de los resultados. Por defecto SabreLayout sigue comenzando con layout_trials pruebas aleatorias, pero además habrá una única prueba que utilizará el subgrafo más denso del grafo de conectividad como punto de partida. Esto puede dar mejores resultados en algunos casos, especialmente en casos con circuitos más pequeños para mapas de acoplamiento más grandes.

  • Se ha añadido un nuevo argumento dt a generate_preset_pass_manager() para que coincida con el conjunto de argumentos de transpile(). Esto permitirá la conversión interna de las restricciones de transpilación a una Target representación.

Funciones de visualización

  • El archivo de configuración de usuario tiene una nueva opción circuit_idle_wires, que toma un valor booleano. Esto permite a los usuarios establecer su comportamiento preferido por defecto de la opción idle_wires de los cajones de circuito QuantumCircuit.draw() y circuit_drawer(). Por ejemplo, añadiendo una sección a ~/.qiskit/settings.conf con:

    [default]
    circuit_idle_wires = false

    cambiará el valor por defecto para no mostrar los cables inactivos.

Herramientas Opciones

  • Se ha añadido una nueva variable de entorno en tiempo de compilación QISKIT_NO_CACHE_GATES que, cuando se establece en un valor de 1 (es decir, QISKIT_NO_CACHE_GATES=1) disminuye la sobrecarga de memoria de a CircuitInstruction y DAGOpNode a costa de aumentar el tiempo de ejecución en los accesos múltiples a los objetos CircuitInstruction.operation y DAGOpNode.op. Si se establece esta variable de entorno al compilar el paquete Qiskit Python desde el código fuente, se desactivará el almacenamiento en caché de la devolución de estos atributos.

Notas sobre la actualización de circuitos

  • El argumento annotated del método Gate.control() es ahora None por defecto, lo que permite a Qiskit elegir si anotar una operación controlada. Si la implementación concreta (annotated=False) está disponible, se devolverá por defecto. En caso contrario, se devolverá la implementación anotada (annotated=True). Esto permite, por ejemplo, aplazar la síntesis de puertas controladas y parametrizadas.

  • Las Operation instancias de DAGOpNode.op que se devuelvan ya no compartirán necesariamente una referencia común al objeto subyacente. Nunca se garantizaba que esto fuera así y mutar el DAGOpNode.op directamente por referencia no era adecuado y siempre era probable que corrompiera el seguimiento del estado interno del DAG QuantumCircuit y DAGCircuit para almacenar puertas estándar en Rust, el objeto de salida de DAGOpNode.op será ahora probablemente una copia en lugar de una instancia compartida. Si necesita mutar un elemento debe asegurarse de que lo hace:

    op = dag_node.op
    op.params[0] = 3.14159
    dag.substitute_node(dag_node, op)

    en lugar de hacer algo como:

    dag_node.op.params[0] = 3.14159

    que no funcionará para ninguna puerta estándar de esta versión. Probablemente habría funcionado por casualidad en una versión anterior, pero nunca fue una garantía de la API.

  • Las Operation instancias de CircuitInstruction.operation que se devuelvan ya no compartirán necesariamente una referencia común al objeto subyacente. Nunca se garantizaba que esto fuera así y mutar el CircuitInstruction.operation directamente por referencia no era correcto y siempre corría el riesgo de corromper el circuito, especialmente cuando se utilizaban parámetros. Debido a la refactorización interna del QuantumCircuit para almacenar puertas estándar en Rust, el objeto de salida de CircuitInstruction.operation será ahora probablemente una copia en lugar de una instancia compartida. Si necesitas mutar un elemento del circuito (lo que no se recomienda en absoluto, ya que es ineficaz y propenso a errores), debes asegurarte de hacerlo:

    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(1)
    qc.p(0)
    
    op = qc.data[0].operation
    op.params[0] = 3.14
    
    qc.data[0] = qc.data[0].replace(operation=op)

    en lugar de hacer algo como:

    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(1)
    qc.p(0)
    
    qc.data[0].operation.params[0] = 3.14

    que no funcionará para ninguna puerta estándar de esta versión. Probablemente habría funcionado por casualidad en una versión anterior, pero nunca fue una garantía de la API.

Notas sobre la actualización de primitivas

  • BitArray.slice_bits() y BitArray.slice_shots() ahora mostrará IndexError cuando los índices estén fuera de los límites. Solían subir ValueError en el caso.

  • BitArray.__getitem__() ahora mostrará IndexError cuando los índices estén fuera de los límites o el número de dimensiones de los índices no coincida con el de BitArray. Solían subir ValueError en el caso.

Notas sobre la actualización de Synthesis

  • LieTrotter y SuzukiTrotter ya no envolver los términos de Pauli individualmente evolucionados en definiciones de puerta. Si depende de un determinado nivel de descomposición de su circuito, deberá eliminar un nivel de QuantumCircuit.decompose() o añadir el argumento de la palabra clave wrap=True a su objeto de síntesis.

Notas sobre la actualización del transpilador

  • Los niveles de optimización 2 y 3 emplean ahora adicionalmente la optimización peephole se emplea ahora antes de la etapa de traducción/síntesis (antes sólo se hacía en la etapa de optimización). Los efectos de la optimización de la mirilla incluyen la eliminación de las puertas que están muy cerca de la identidad, por ejemplo, las puertas de fase controlada con un ángulo rotacional menor que 2π2252\pi \otimes 2^{-25}.

  • El paso de enrutamiento por defecto utilizado por el nivel de optimización 0 para generate_preset_pass_manager() y transpile() se ha cambiado de StochasticSwap a SabreSwap. El pase SabreSwap pass realiza exactamente la misma función, pero mejora tanto el tiempo de ejecución como la calidad del resultado (en número de puertas de intercambio y profundidad) en comparación con StochasticSwap. Para optimization_level=0 esto no debería importar porque no se espera que ejecute el enrutamiento para el caso de uso típico del nivel 0.

    Si por alguna razón confiaba en el algoritmo de enrutamiento por defecto anterior, puede utilizar el argumento routing_method para transpile() y generate_preset_pass_manager() a "stochastic" para utilizar el StochasticSwap pasar.

  • La función generate_preset_pass_manager() función se ha actualizado para que, cuando sea posible, convierta internamente las restricciones del transpilador en una Target instancia. Si se proporciona una entrada de tipo BackendV1 se convertirá a BackendV2 para exponer su Target. Este cambio no requiere ninguna acción por parte del usuario.

Herramientas Notas de actualización

  • La versión mínima de rustworkx necesaria para ejecutar esta versión ha pasado de 0.14.0 a 0.15.0. Esto es necesario porque Qiskit utiliza ahora una nueva funcionalidad añadida en la versión rustworkx 0.15.0 que mejora el rendimiento.

Circuitos obsoletos

Primitivas obsoletas

Proveedores obsoletos

Deprecaciones del transpilador

  • La función assemble() está obsoleta y se eliminará en la versión 2.0. La función se utilizaba principalmente para crear un Qobj, que ya no es necesario en BackendV2-flujos de trabajo basados en También se utilizaba para vincular parámetros, una funcionalidad totalmente cubierta por QuantumCircuit.assign_parameters().

Visualización Obsoleto

  • El argumento justify de circuit_drawer() o QuantumCircuit.draw()ya no admitirá valores no válidos (antes los cambiaba por defecto), y en una futura versión dará error. Los valores de justificación válidos son "left", "right" o "none".

  • La función visualize_transition() ha quedado obsoleta y se eliminará en la versión 2.0.0. Esta función tenía una serie de limitaciones que limitaban su utilidad a casos de uso muy concretos y no encajaba con el resto del módulo de visualización de Qiskit.

Corrección de errores

  • Se ha corregido una serie de problemas al controlar compuertas estándar parametrizadas. La versión controlada de algunas puertas (p. ej. RXXGate o RYGate para más de 1 control) no pueden sintetizarse si contienen parámetros no vinculados. Anteriormente, llamar a .control() en tal caso fallaba, pero ahora creamos un AnnotatedOperation como marcador de posición. Esto permite insertar la puerta controlada en un circuito, enlazar los parámetros en una fase posterior y, a continuación, sintetizar la operación. Correcciones #10311, #10697 y #12135.

  • En SGate y SdgGate ahora devuelven correctamente a CSGateresp. CSdgGate, si se controlan en un único qubit de control.

  • Fijar el cálculo de la desviación típica en BackendEstimatorV2teniendo en cuenta la co-varianza de los Paulis no conmutantes. Fijo Qiskit/qiskit-ibm-runtime#1751.

  • Se ha corregido un problema por el que circuit_drawer() o el método QuantumCircuit.draw() no emitía una advertencia cuando se pasaba un valor no válido al argumento justify , antes de cambiarlo al valor predeterminado. Ahora, aparecerá una advertencia si se pasa un valor no válido. Los valores de justificación válidos son "left", "right" o "none". Consulte el nº 12089 para más detalles.

  • Fijo SparsePauliOp.apply_layout() y Pauli.apply_layout() para que aparezca QiskitError si se proporcionan índices duplicados o índices negativos como parte de un diseño.

  • Se ha corregido un error en el ConsolidateBlocks cuando el circuito de entrada contenía una puerta opaca personalizada y no se establecían las opciones basis_gates o target , el pase producía un error de tipo QiskitError y fallaba. Esto se ha corregido para que en estas situaciones la pasada del transpilador no consolide el bloque identificado que contiene una puerta personalizada en lugar de fallar.

  • Se ha corregido un error en PadDynamicalDecouplingque anteriormente no mostraba correctamente el mensaje de error de que un retardo no está alineado con el pulso, si el nodo anterior o siguiente era un nodo de entrada/salida. Ahora, el mensaje de error se muestra correctamente.

  • La palabra clave argumento order de la función BitArray.from_bool_array() debe ser "little" o "big". Se han añadido comprobaciones para que aparezca un error si se introduce un valor no válido.

  • Mejorar la descomposición de la puerta generada por QuantumCircuit.mcx() sin utilizar qubits ancilla, de modo que el número de CXGates crezca cuadráticamente en el número de qubits, como era de esperar, y no exponencialmente.

  • Corregido SparsePauliOp.apply_layout() para que funcione correctamente con operadores de qubits cero. Por ejemplo, si previamente creaste un qubit 0 y le aplicaste un diseño como:

    op = SparsePauliOp("")
    op.apply_layout(None, 3)

    esto habría provocado previamente un error. Ahora esto devolverá correctamente un operador de la forma: SparsePauliOp(['III'], coeffs=[1.+0.j])

  • Se ha corregido un error de StatevectorSampler que ignoraba las compuertas con c_if. Se producirá un error porque Statevector no puede manejar c_if.

  • Se ha corregido un error en el Commuting2qGateRouter por el que las permutaciones del registro cuántico no se añadían al conjunto de propiedades del pase, por lo que el usuario tenía que hacer un seguimiento manual. Ahora es posible acceder a la permutación a través de la propiedad layout del circuito de salida e introducir el pase en cualquier canal de transpilación sin pérdida de información.

  • Se ha corregido una imprecisión en coma flotante al escalar determinadas unidades de pulso entre segundos y nanosegundos. Si el pulso se definía simbólicamente, podía introducirse un error de coma flotante innecesario por el escalado para ciertas construcciones de symengine, lo que podía manifestarse en resultados inesperados una vez que los símbolos estuvieran completamente ligados. Corregido #12392.

  • Se ha corregido un error en synth_cnot_count_full_pmh() por el que proporcionar un section_size que no dividiera el número de qubits sin resto podía dar lugar a resultados erróneos. Ahora, cualquier section_size (como máximo igual al número de qubits) sintetiza el circuito correcto. Para obtener un valor (heurísticamente) óptimo, establezca section_size=None.

  • PassManager.run() ya no perderá tiempo serializándose cuando se le den múltiples entradas si sólo va a trabajar en serie.

  • Se ha corregido un error en plot_coupling_map() que provocaba que los bordes del mapa de acoplamiento se colorearan incorrectamente. Corregido #12354.

  • El analizador OpenQASM 2.0 (qasm2.load() y qasm2.loads()) puede ahora evaluar expresiones puerta-ángulo que incluyan operandos enteros que desbordarían el tamaño entero del sistema. Se evaluarán en un contexto de coma flotante de doble precisión, como siempre se ha hecho con el resto de la expresión. Cuidado: un número entero arbitrariamente grande no será necesariamente representable con exactitud en coma flotante de doble precisión, por lo que existe la posibilidad de que, independientemente de cómo se haya generado el circuito, ya haya perdido toda la precisión numérica módulo 2π2\pi.

  • El exportador OpenQASM 3 (véase qiskit.qasm3) se equivocará correctamente cuando se le pida que utilice una palabra clave u otro identificador no válido como "puerta base", ya que no tiene forma de generar una salida correcta en estos casos.

  • El exportador de OpenQASM 3 (qiskit.qasm3) exportará ahora correctamente múltiples instancias de PauliEvolutionGate de un circuito. Anteriormente, sólo se exportaba una única instancia, y todas las demás instancias utilizaban silenciosamente la misma versión (incorrecta).

  • El exportador de OpenQASM 3 (qiskit.qasm3) ahora escapará correctamente los nombres de las puertas. Anteriormente, una puerta cuyo nombre era un identificador OpenQASM 3 inválido provocaba la generación de OpenQASM 3 inválido.

  • Una serie de incoherencias en el tratamiento de las entradas entre transpile() y generate_preset_pass_manager() se han corregido. Estas incoherencias darían lugar a diferentes resultados de transpilación para las mismas entradas, o a generate_preset_pass_manager() fallar para determinadas combinaciones de entradas aceptadas por transpile().

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