Skip to main content
IBM Quantum Platform

Notas de la versión de Qiskit SDK 1.1


1.1.2

Preludio

Qiskit 1.1.2 es una versión de corrección de errores menores para la serie 1.1.

Corrección de errores

  • Se ha corregido un error en BitArray.from_counts() y BitArray.from_samples(). Anteriormente, se producía un error si se proporcionaban datos que sólo contenían ceros y ningún valor para el argumento opcional num_bits. Ahora producen un BitArray con BitArray.num_bits a 1.

  • Se ha corregido un decorador que faltaba en C3SXGate que hacía que fallara si Gate.to_matrix() era llamado. La matriz de la puerta ahora se devuelve como se esperaba.

  • Añadidas las puertas Clifford que faltaban al CollectCliffords transpilador. En particular, hemos añadido las puertas ECRGate, DCXGate, iSWAPGate, SXGate y SXdgGate a este paso del transpilador.

  • El atributo QuantumCircuit.parameters estará vacío cuando se utilice QuantumCircuit.copy_empty_like() en un circuito paramétrico. Anteriormente, una caché interna se copiaba sin invalidarse. Corrección #12617.

  • Arreglar el SolovayKitaev al cargar aproximaciones básicas a partir de un archivo existente en .npy . Anteriormente, cargar una aproximación almacenada que permitía reducciones adicionales (por ejemplo, debido a cancelaciones de puertas) podía provocar un fallo en tiempo de ejecución. Además, la diferencia de fase global del producto de compuerta U(2) y la representación SO(3) se perdió durante un procedimiento de guardar-recargar. Arregla Qiskit/qiskit#12576.

  • Se ha solucionado un problema con dag_drawer() y DAGCircuit.draw() cuando se intentaba visualizar una instancia DAGCircuit que contenía Var cables. El visualizador lanzaba una excepción al intentar hacer esto, lo cual se ha corregido para que se genere la visualización esperada.

  • El constructor GenericBackendV2 anteriormente permitía construir backends malformados porque aceptaba puertas base que no podían ser asignadas dado el tamaño del backend. Por ejemplo, un backend con un solo qubit podría aceptar previamente una base con puertas de dos qubits.

  • El analizador OpenQASM 2 (qiskit.qasm2) ahora puede manejar condicionales con enteros que no caben en un entero de 64 bits. Corregido #12773.

  • Anteriormente, DAGCircuit.replace_block_with_op() permitía colocar una operación n-qubit en un bloque de m qubits, dejando el DAG en un estado inválido. Este comportamiento se ha corregido, y cualquier intento de hacer esto ahora levantará un DAGCircuitError como se esperaba.


1.1.1

Preludio

Qiskit 1.1.1 es una versión de corrección de errores menores para la serie 1.1.

Corrección de errores

  • Corrección de un error en Isometry debido a una aserción innecesaria, que provocaba un error en UnitaryGate.control() cuando UnitaryGate tenía más de dos qubits.

  • QuantumCircuit.depth() manejará ahora correctamente las operaciones que no tengan operandos, como por ejemplo GlobalPhaseGate.

  • QuantumCircuit.depth() contará ahora las variables y clbits utilizados en las expresiones en tiempo real como parte del cálculo de profundidad.

  • Se ha corregido un error en qiskit.visualization.pulse_v2.interface.draw() que no dibujaba los programas de pulsos cuando se llamaba a la función dibujar con un BackendV2 argumento. Dado que el backend V2 no informa de las frecuencias de los canales hardware, el dibujo generado mostrará 'no freq' debajo de cada etiqueta de canal.

  • El pase VF2Layout pass lanzaría una excepción cuando se le proporcionara una Target sin restricciones de conectividad. Este sería el caso de los objetivos de Aer 0.13. El problema se ha solucionado.

  • ParameterExpression se actualizó para que las instancias totalmente vinculadas que se comparan con instancias de los tipos numéricos incorporados de Python (como float y int) también tengan valores hash que coincidan con los de las otras instancias. Este cambio garantiza que estos tipos puedan utilizarse indistintamente como claves de diccionario. Ver #12488.

  • Las compuertas personalizadas (aquellas derivadas de una sentencia gate ) en programas importados de OpenQASM 2 tendrán ahora una Gate.to_matrix() implementación. Antes no tenían definición de matriz, lo que significaba que los viajes de ida y vuelta a través de OpenQASM 2 podían perder innecesariamente la capacidad de derivar la matriz de la puerta. Nótese, sin embargo, que la matriz se calcula encontrando recursivamente las matrices de las definiciones de las puertas internas, como hace Operator lo que puede ser menos eficaz que antes de la ida y vuelta.

  • Target.has_calibration() se ha actualizado para que no lance una excepción para una instrucción que se ha añadido al objetivo con None para sus propiedades de instrucción. Correcciones #12525.


1.1.0

Preludio

La versión de Qiskit 1.1.0 es una versión de características menores que incluye una miríada de nuevas funciones y correcciones de errores. Los aspectos más destacados de este lanzamiento son:

  • Se ha añadido soporte para variables clásicas tipadas al módulo QuantumCircuit. Estas variables clásicas pueden especificarse como entradas o como variables de alcance en un QuantumCircuit donde almacenan, por ejemplo, la salida de las mediciones de qubits o las operaciones de control de flujo objetivo. En el futuro se añadirá soporte para, por ejemplo, establecer parámetros de puerta o variables de salida.

  • Los dos métodos de síntesis qubit por defecto que son utilizados internamente por el transpilador en el UnitarySynthesis han sido reimplementados en Rust. De este modo se obtienen importantes mejoras en el tiempo de ejecución al descomponer matrices unitarias de dos qubits. Como consecuencia, el tiempo de ejecución de la transpilación con el nivel de optimización 3 se mejoró significativamente en los casos en los que la ejecución UnitarySynthesis conllevaba históricamente una gran sobrecarga de tiempo de ejecución. Esta versión también comienza a ejecutarse UnitarySynthesis como parte de la etapa de optimización en el nivel de optimización 2 debido a estas mejoras de rendimiento en tiempo de ejecución.

    Además, los métodos numéricos utilizados en Isometry se han trasladado a Rust, lo que permite una gran aceleración del tiempo de ejecución, en particular para la síntesis de puertas unitarias controladas. La descomposición para XGate y PhaseGate se ha mejorado, lo que ha permitido reducir en más de dos órdenes de magnitud el número de puertas utilizadas en la síntesis.

  • Se han introducido en Qiskit una serie de nuevos pases de transpilador que proporcionan un aumento significativo de la velocidad de ejecución, al tiempo que reducen el tamaño de los circuitos cuánticos transpilados en muchos casos. Específicamente, ElidePermutations y StarPreRouting han demostrado tener un impacto significativo en la calidad de salida de los circuitos y en el tiempo de ejecución y RemoveFinalReset pueden mejorar los circuitos cuánticos que incluyen reinicios.

  • Se han mejorado los gestores de pases por defecto ampliándolos con los nuevos pases de transpilador introducidos. En concreto, el gestor de pases preestablecidos de nivel de optimización 2 de generate_preset_pass_manager y utilizado internamente por transpile() ha sido refactorizado para tener un mejor equilibrio entre el tiempo de ejecución y el esfuerzo de optimización con el fin de servir como gestor de pases por defecto en futuras versiones. Aunque esta versión no cambia el uso por defecto del nivel 2, suele ser una opción mejor que los niveles 1 o 3.

  • Se han añadido nuevas implementaciones de la primitiva genérica V2, BackendEstimatorV2 y BackendSamplerV2para complementar las implementaciones basadas en vectores de estado.

  • Cambios en el soporte de plataformas: Python 3.8 queda obsoleto a partir de Qiskit 1.1.0 y dejará de estar soportado en 1.3.0, y arm64 macOS ha sido promocionado a soporte de nivel 1.

Características de los circuitos

  • Los métodos QuantumCircuit.power(), Gate.power()así como los métodos similares de las subclases de las subclases de Gate (como of SGate) tienen un argumento adicional annotated que se utiliza para devolver un objeto AnnotatedOperation cuando se aplica una potencia a una puerta o circuito. El valor por defecto de False corresponde al comportamiento existente. Además, para las puertas estándar con un método power definido explícitamente, el argumento annotated no tiene ningún efecto. Por ejemplo, tanto SGate().power(1.5, annotated=False) como SGate().power(1.5, annotated=True) devuelven un PhaseGate. Una diferencia en el valor de annotated se manifiesta para las puertas sin un método de potencia explícitamente definido. El valor de False devuelve un UnitaryGateigual que antes, mientras que el valor de True devuelve un AnnotatedOperation que representa la instrucción modificada con el "modificador de potencia".

  • Se ha añadido un nuevo argumento ctrl_state a QuantumCircuit.mcp() y MCPhaseGate.

    El método QuantumCircuit.mcp() y la clase MCPhaseGate se han actualizado para incluir un parámetro ctrl_state . Esta mejora permite a los usuarios especificar el estado de control de la puerta de fase multicontrolada. El parámetro puede aceptar un valor entero o una cadena de bits y, por defecto, controla el estado "1" si no se proporciona.

    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(4)
    qc.mcp(0.2,[0,1,2],3,ctrl_state=2)
  • Se ha añadido un nuevo argumento ctrl_state a QuantumCircuit.mcx().

    El método QuantumCircuit.mcx() de la biblioteca de circuitos cuánticos se ha mejorado para incluir un parámetro ctrl_state, que permite a los usuarios especificar el estado de control de la puerta X multicontrolada. Este parámetro puede aceptar un valor decimal o una cadena de bits y controla por defecto el estado "1" si no se proporciona.

    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(3, 3)
    qc.mcx([0, 1], 2, ctrl_state="00")
  • A QuantumCircuit puede contener ahora variables clásicas tipificadas:

    from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister
    from qiskit.circuit.classical import expr, types
    
    qr = QuantumRegister(2, "q")
    cr = ClassicalRegister(2, "c")
    qc = QuantumCircuit(qr, cr)
    # Add two input variables to the circuit with different types.
    a = qc.add_input("a", types.Bool())
    mask = qc.add_input("mask", types.Uint(2))
    
    # Test whether the input variable was true at runtime.
    with qc.if_test(a) as else_:
        qc.x(0)
    with else_:
        qc.h(0)
    
    qc.cx(0, 1)
    qc.measure(qr, cr)
    
    # Add a typed variable manually, initialized to the same value as the classical register.
    b = qc.add_var("b", expr.lift(cr))
    
    qc.reset([0, 1])
    qc.h(0)
    qc.cx(0, 1)
    qc.measure(qr, cr)
    
    # Store some calculated value into the `b` variable.
    qc.store(b, expr.bit_and(b, cr))
    # Test whether we had equality, up to a mask.
    with qc.if_test(expr.equal(expr.bit_and(b, mask), mask)):
        qc.x(0)

    Estas variables pueden especificarse como entradas del circuito o como variables de ámbito. El objeto circuito aún no tiene soporte para representar salidas de variables clásicas tipadas, pero esto se añadirá más adelante cuando el hardware y las interfaces de resultados estén en mejores condiciones de soportarlo. Los circuitos que representan un bloque de un ámbito interno también pueden capturar variables de ámbitos externos.

    Una variable es un Var nodo, que ahora puede contener un tipo arbitrario, y representa una única posición de memoria dentro de su rango vivo cuando se añade a un circuito. Se pueden construir en un circuito utilizando QuantumCircuit.add_var() y QuantumCircuit.add_input()o en un nivel inferior utilizando Var.new().

    Las variables pueden almacenarse manualmente en, utilizando la Store y su correspondiente método de circuito QuantumCircuit.store(). Esto incluye escribir a Clbit y ClassicalRegister envueltas en nodos Var nodos.

    Las variables pueden utilizarse siempre que sean válidas las expresiones clásicas (véase qiskit.circuit.classical.expr) son válidas. En la actualidad, se trata de las expresiones de destino de las operaciones de flujo de control, aunque tenemos previsto ampliarlo a los parámetros de puerta en el futuro, a medida que se amplíen el sistema de tipos y expresiones.

    Para más información sobre estas variables y el modelo de datos asociado, véase Cálculo clásico en tiempo real.

    Estos son compatibles con todo el transpilador, a través de la serialización QPY (qiskit.qpy), la exportación OpenQASM 3 (qiskit.qasm3), y tienen soporte inicial a través de los visualizadores de circuitos (ver QuantumCircuit.draw()).

    Nota

    Las nuevas variables clásicas y el almacenamiento tardarán algún tiempo en ser compatibles con el hardware y los backends de los simuladores. No se admiten en las interfaces de las primitivas (qiskit.primitives), pero es probable que se incorporen a estas interfaces a medida que evolucionen.

  • El módulo clásico de expresiones en tiempo real qiskit.circuit.classical puede ahora representar la indexación y el desplazamiento de bits de enteros sin signo y similares a bits (por ejemplo ClassicalRegister). Por ejemplo, ahora es posible comparar un registro con el desplazamiento de bits de otro:

    from qiskit.circuit import QuantumCircuit, ClassicalRegister
    from qiskit.circuit.classical import expr
    
    cr1 = ClassicalRegister(4, "cr1")
    cr2 = ClassicalRegister(4, "cr2")
    qc = QuantumCircuit(cr1, cr2)
    with qc.if_test(expr.equal(cr1, expr.shift_left(cr2, 2))):
        pass

    Qiskit también puede representar una condición que indexa dinámicamente en un registro:

    with qc.if_test(expr.index(cr1, cr2)):
        pass
  • El rendimiento de construcción de NLocal y sus subclases de bibliotecas de circuitos derivadas (p. ej. EfficientSU2 y RealAmplitudes) ha mejorado significativamente, cuando los subbloques de rotación y/o entrelazamiento son simples aplicaciones de una única puerta de la biblioteca estándar Qiskit. Dado que estos circuitos se construyen de forma perezosa, es posible que no vea la mejora inmediatamente al instanciar la clase, sino en el primer acceso a su estructura interna. Las mejoras de rendimiento son del orden de diez veces más rápidas.

  • QuantumCircuit.append() ahora tiene un argumento de palabra clave copy , que por defecto es True. Cuando una instrucción con parámetros de ejecución (ParameterExpressions) se añade a un circuito, por defecto, el circuito siempre ha creado una copia de la instrucción de modo que si QuantumCircuit.assign_parameters() intenta mutar la instrucción en su lugar, no afecta a otras referencias a la misma instrucción. Ahora, configurar copy=False le permite anular esto, por lo que puede evitar la penalización por copia si sabe que sus instrucciones no se utilizarán en otras ubicaciones.

  • QuantumCircuit.compose() ahora tiene un argumento de palabra clave copy , que por defecto es True. Por defecto compose() copia todas las instrucciones, de modo que las mutaciones de un circuito no afectan a ningún otro. Si copy=False, entonces las instrucciones del otro circuito pasarán a pertenecer directamente al nuevo circuito, lo que puede implicar mutarlas en su lugar. En este caso, el otro circuito no debe utilizarse después.

  • El tiempo de construcción de QuantumVolume circuitos se ha mejorado notablemente, del orden de 10x o un poco más. Las compuertas internas de SU4 también utilizarán ahora más bits de aleatoriedad durante su generación, lo que dará lugar a circuitos de volumen más representativos, especialmente a grandes anchuras y profundidades.

  • QuantumVolume ahora tiene un argumento de palabra clave flatten . Por defecto es False, donde el circuito construido contiene una única instrucción que a su vez contiene la estructura real del volumen. Si se fija True, el circuito dispondrá directamente de las matrices volumétricas SU4.

  • UnitaryGate ahora acepta un argumento opcional num_qubits . El único efecto de esto es omitir la inferencia del recuento de qubits, lo que puede ser útil para el rendimiento cuando se construyen muchas puertas.

  • QuantumCircuit tiene varios métodos nuevos para trabajar e inspeccionar variables manuales Var variables.

    Consulte Trabajar con datos clásicos mecanografiados en tiempo real para profundizar en todos ellos.

    Los nuevos métodos son:

    Además, hay varios atributos dinámicos nuevos en QuantumCircuit que rodean a estas variables:

  • ControlFlowOp y sus subclases tienen ahora un método iter_captured_vars() que devolverá un iterador sobre las variables únicas capturadas en cualquiera de sus bloques inmediatos.

  • DAGCircuit tiene varios métodos nuevos para trabajar e inspeccionar variables manuales Var variables. Estos son en gran medida equivalentes a sus QuantumCircuit salvo que los DAGCircuit están optimizados para el acceso programático con objetos ya definidos, mientras que los QuantumCircuit métodos están más enfocados al uso humano interactivo.

    Los nuevos métodos son:

    También hay nuevos atributos públicos:

  • DAGCircuit.wires ahora también contendrá cualquier Var variables manuales en el circuito, ya que éstas también son flujo de datos clásico.

  • Se añade un nuevo método Var.new()se añade para construir manualmente una variable clásica en tiempo real que posea su memoria.

  • QuantumCircuit.compose() tiene dos argumentos de palabra clave necesarios, var_remap y inline_captures para soportar mejor las variables clásicas en tiempo real.

    var_remap puede utilizarse para reescribir Var nodos en el argumento del circuito a medida que sus instrucciones se alinean en el circuito base. Puede utilizarse para evitar conflictos de nombres.

    inline_captures puede establecerse en True (por defecto False) para vincular todos los Var nodos rastreados como "capturas" en el circuito argumento con los mismos Var nodos en el circuito base, sin intentar volver a declarar las variables. Esto se puede utilizar, en combinación con QuantumCircuit.copy_empty_like()de vars_mode="captures" , para construir un circuito capa por capa, conteniendo variables.

  • DAGCircuit.compose() tiene un nuevo argumento de palabra clave, inline_captures, que se puede establecer en True para alinear los nodos "capturados" en el circuito base sin volver a declararlos Var capturados" en el circuito del argumento en el circuito base sin volver a declararlos. Junto con la opción vars_mode="captures" de varios métodos DAGCircuit se puede utilizar para combinar DAGs que operan sobre las mismas variables.

  • QuantumCircuit.copy_empty_like() y DAGCircuit.copy_empty_like() tienen un nuevo argumento de palabra clave, vars_mode , que controla cómo se rastrean en la salida los nodos que poseen memoria Var en la salida. Por defecto ("alike"), las variables se declaran en el mismo modo de entrada/captura/local que la fuente. Se puede establecer en "captures" para convertir todas las variables en capturas (útil con compose()) o "drop" para eliminarlas.

  • Se ha añadido un nuevo argumento de palabra clave vars_mode a los métodos DAGCircuit métodos:

    que tiene el mismo significado que para copy_empty_like().

  • Todas las "puertas estándar" de la biblioteca de circuitos (qiskit.circuit.library) pueden ahora especificarse por nombre de cadena para las operaciones de enredo en TwoLocal como RealAmplitudes y EfficientSU2.

Características primitivas

  • La aplicación BackendEstimatorV2 de BaseEstimatorV2 se ha añadido. Este estimador admite BackendV1 y BackendV2.

    import numpy as np
    from qiskit import transpile
    from qiskit.circuit.library import IQP
    from qiskit.primitives import BackendEstimatorV2
    from qiskit.providers.fake_provider import Fake7QPulseV1
    from qiskit.quantum_info import SparsePauliOp, random_hermitian
    
    backend = Fake7QPulseV1()
    estimator = BackendEstimatorV2(backend=backend)
    n_qubits = 5
    mat = np.real(random_hermitian(n_qubits, seed=1234))
    circuit = IQP(mat)
    observable = SparsePauliOp("Z" * n_qubits)
    isa_circuit = transpile(circuit, backend=backend, optimization_level=1)
    isa_observable = observable.apply_layout(isa_circuit.layout)
    job = estimator.run([(isa_circuit, isa_observable)], precision=0.01)
    result = job.result()
    print(f"> Expectation value: {result[0].data.evs}")
    print(f"> Standard error: {result[0].data.stds}")
    print(f"> Metadata: {result[0].metadata}")
  • La aplicación BackendSamplerV2 de BaseSamplerV2 se ha añadido. Este muestreador admite BackendV1 y BackendV2 que permiten la opción memory para calcular cadenas de bits.

    import numpy as np
    from qiskit import transpile
    from qiskit.circuit.library import IQP
    from qiskit.primitives import BackendSamplerV2
    from qiskit.providers.fake_provider import Fake7QPulseV1
    from qiskit.quantum_info import random_hermitian
    
    backend = Fake7QPulseV1()
    sampler = BackendSamplerV2(backend=backend)
    n_qubits = 5
    mat = np.real(random_hermitian(n_qubits, seed=1234))
    circuit = IQP(mat)
    circuit.measure_all()
    isa_circuit = transpile(circuit, backend=backend, optimization_level=1)
    job = sampler.run([isa_circuit], shots=100)
    result = job.result()
    print(f"> bitstrings: {result[0].data.meas.get_bitstrings()}")
    print(f"> counts: {result[0].data.meas.get_counts()}")
    print(f"> Metadata: {result[0].metadata}")
  • Añadidos métodos para unir múltiples BitArray objetos a lo largo de varios ejes.

    ba = BitArray.from_samples(['00', '11'])
    print(ba)
    # BitArray(<shape=(), num_shots=2, num_bits=2>)
    
    # reshape the bit array because `concatenate` requires an axis.
    ba_ = ba.reshape(1, 2)
    print(ba_)
    # BitArray(<shape=(1,), num_shots=2, num_bits=2>)
    
    ba2 = BitArray.concatenate([ba_, ba_])
    print(ba2.get_bitstrings())
    # ['00', '11', '00', '11']
    
    # `concatenate_bits` and `concatenates_shots` do not require any axis.
    
    ba3 = BitArray.concatenate_bits([ba, ba])
    print(ba3.get_bitstrings())
    # ['0000', '1111']
    
    ba4 = BitArray.concatenate_shots([ba, ba])
    print(ba4.get_bitstrings())
    # ['00', '11', '00', '11']
  • Se han añadido métodos para generar un subconjunto de BitArray objeto cortando a lo largo de varios ejes.

    • __getitem__(): corta la matriz a lo largo de un eje existente de la matriz.
    • slice_bits()corta la matriz a lo largo del eje de bits.
    • slice_shots()corta la matriz a lo largo del eje de disparo.
    ba = BitArray.from_samples(['0000', '0001', '0010', '0011'], 4)
    print(ba)
    # BitArray(<shape=(), num_shots=4, num_bits=4>)
    print(ba.get_bitstrings())
    # ['0000', '0001', '0010', '0011']
    
    ba2 = ba.reshape(2, 2)
    print(ba2)
    # BitArray(<shape=(2,), num_shots=2, num_bits=2>)
    print(ba2[0].get_bitstrings())
    # ['0000', '0001']
    print(ba2[1].get_bitstrings())
    # ['0010', '0011']
    
    ba3 = ba.slice_bits([0, 2])
    print(ba3.get_bitstrings())
    # ['00', '01', '00', '01']
    
    ba4 = ba.slice_shots([0, 2])
    print(ba3.get_bitstrings())
    # ['0000', '0010']
  • Añadido un método transpose() para transponer un BitArray.

    ba = BitArray.from_samples(['00', '11']).reshape(2, 1, 1)
    print(ba)
    # BitArray(<shape=(2, 1), num_shots=1, num_bits=2>)
    print(ba.transpose())
    # BitArray(<shape=(1, 2), num_shots=1, num_bits=2>)
  • Añadido un método expectation_values() para calcular los valores de las expectativas de los operadores diagonales.

    ba = BitArray.from_samples(['01', '11'])
    print(ba.expectation_values(["IZ", "ZI", "01"]))
    # [-1.   0.   0.5]
  • DataBin satisface ahora el Shaped protocolo. Esto significa que cada DataBin instancia tiene ahora los atributos adicionales

    • shape (tupleint[,...])la forma inicial de cada entrada de la instancia
    • ndim (int): la longitud de shape
    • size (int): el producto de las entradas de shape

    La forma se puede pasar al constructor.

  • Se han añadido funciones de mapeo a DataBines decir, __getitem__, __contains__, __iter__, keys(), values()y items().

    from qiskit import QuantumCircuit
    from qiskit.primitives import StatevectorSampler
    
    circuit = QuantumCircuit(1)
    circuit.h(0)
    circuit.measure_all()
    
    sampler = StatevectorSampler()
    result = sampler.run([circuit]).result()
    databin = result[0].data
    for creg, arr in databin.items():
        print(creg, arr)
    for creg in databin:
        print(creg, databin[creg])
  • La subclase SamplerPubResult de PubResult que BaseSamplerV2 pueden devolver las implementaciones. La principal característica añadida en esta nueva subclase es join_data()que une (un subconjunto de) los contenidos de data en un único objeto. Esto permite los siguientes patrones:

    job_result =  sampler.run([pub1, pub2, pub3], shots=123).result()
    
    # assuming all returned data entries are BitArrays
    counts1 = job_result[0].join_data().get_counts()
    bistrings2 = job_result[1].join_data().get_bitstrings()
    array3 = job_result[2].join_data().array

Características de los proveedores

Características de Pulse

  • Ahora es posible asignar parámetros a los pulsos Schedule y ScheduleBlock especificando el nombre del parámetro como cadena. El nombre del parámetro se puede utilizar para asignar valores a todos los parámetros dentro de los parámetros Schedule o ScheduleBlock que tengan el mismo nombre. Además, el parámetro ParameterVector puede utilizarse para asignar todos los valores del vector simultáneamente (la lista de valores debe, por tanto, coincidir con la longitud del vector).

  • Los métodos assign_parameters de Schedule y ScheduleBlock permiten ahora asignar un ParameterVector a una lista de valores de parámetros simultáneamente además de asignar instancias individuales de Parameter a valores individuales.

OpenQASM Características

  • El exportador OpenQASM 3 admite el almacenamiento manual Var en los circuitos.

Características de QPY

  • SE HA AÑADIDO LA VERSIÓN 12 DEL FORMATO QPY (qiskit.qpy) se ha añadido la versión 12 del formato, que incluye soporte para variables que poseen memoria Var de memoria. Para más información sobre los cambios de formato, véase la versión 12.

Características de la información cuántica

  • Se ha añadido un nuevo método apply_layout() equivalente a apply_layout(). Este método se utiliza para aplicar un TranspileLayout diseño del transpilador a un Pauli observable que se construyó para un circuito de entrada. Esto permite trabajar con BaseEstimator / BaseEstimatorV2 y la transpilación local cuando la entrada es de tipo Pauli. Por ejemplo:

    from qiskit.circuit.library import RealAmplitudes
    from qiskit.primitives import BackendEstimatorV2
    from qiskit.providers.fake_provider import GenericBackendV2
    from qiskit.quantum_info import Pauli
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    
    psi = RealAmplitudes(num_qubits=2, reps=2)
    H1 = Pauli("XI")
    backend = GenericBackendV2(num_qubits=7)
    estimator = BackendEstimatorV2(backend=backend)
    thetas = [0, 1, 1, 2, 3, 5]
    pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
    transpiled_psi = pm.run(psi)
    permuted_op = H1.apply_layout(transpiled_psi.layout)
    res = estimator.run([(transpiled_psi, permuted_op, thetas)]).result()

    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 pm.run().

  • Añade las etiquetas PauliList.noncommutation_graph() y SparsePauliOp.noncommutation_graph() métodos, exponiendo la construcción de grafos de no conmutación, refundiendo el problema de agrupación de operadores de medida en un problema de coloreado de grafos. Esto permite a los usuarios trabajar directamente con estos grafos, por ejemplo para explorar algoritmos de coloreado distintos del utilizado por SparsePauliOp.group_commuting().

  • El rendimiento de SparsePauliOp.to_matrix() ha mejorado considerablemente tanto para las formas densas como para las dispersas. Por defecto, ambos aprovecharán el paralelismo de hilos disponible en su sistema, sujeto a la variable de entorno RAYON_NUM_THREADS . Puede forzar temporalmente la ejecución en serie utilizando el nuevo argumento booleano force_serial para to_matrix().

Características de síntesis

  • El plugin KMSSynthesisLinearFunction plugin para sintetizar objetos LinearFunction acepta ahora dos opciones adicionales use_inverted y use_transposed. Estas opciones modifican la matriz sobre la que se ejecuta el algoritmo de síntesis subyacente, posiblemente invirtiéndola y/o transponiéndola, y luego ajustan adecuadamente el circuito sintetizado. Variando estas opciones, generalmente obtenemos circuitos sintetizados diferentes, y en casos podemos obtener mejores resultados que para sus valores por defecto.

  • El plugin PMHSynthesisLinearFunction complemento para sintetizar objetos LinearFunction acepta ahora varias opciones adicionales. La opción section_size se pasa al método de síntesis subyacente. Las opciones use_inverted y use_transposed modifican la matriz sobre la que se ejecuta el algoritmo de síntesis subyacente, posiblemente invirtiéndola y/o transponiéndola, y luego ajustan adecuadamente el circuito sintetizado. Variando estas opciones, generalmente obtenemos circuitos sintetizados diferentes, y en casos podemos obtener mejores resultados que para sus valores por defecto.

  • Se ha añadido un nuevo argumento, use_dag, a la función TwoQubitBasisDecomposer.__call__() y XXDecomposer.__call__() y. Este argumento se utiliza para controlar si se devuelve un DAGCircuit cuando se llama a TwoQubitBasisDecomposer o XXDecomposer en lugar de la instancia por defecto QuantumCircuit. Por ejemplo:

    from qiskit.circuit.library import CXGate
    from qiskit.quantum_info import random_unitary
    from qiskit.synthesis import TwoQubitBasisDecomposer
    
    decomposer = TwoQubitBasisDecomposer(CXGate(), euler_basis="PSX")
    decomposer(random_unitary(4), use_dag=True)

    devolverá un DAGCircuit al llamar a la instancia TwoQubitBasisDecomposer instancia decomposer.

  • LieTrotter.synthesize() utiliza ahora QuantumCircuit.repeat() para generar repeticiones adicionales de un paso Trotter después del primer paso Trotter. Esto reduce el número de QuantumCircuit.compose() llamadas por un factor de reps y reduce significativamente el tiempo de ejecución para los operadores más grandes.

  • Añade un nuevo método de síntesis synth_permutation_reverse_lnn_kms() de permutaciones inversas para arquitecturas lineales de vecino más próximo utilizando el método Kutin, Moulton, Smithline. Este algoritmo sintetiza la permutación inversa en nn qubits sobre una arquitectura lineal de vecino más cercano utilizando puertas CX con profundidad 2n+22 * n + 2.

  • La clase TwoQubitBasisDecomposer se ha reescrito en Rust, lo que mejora enormemente el rendimiento en tiempo de ejecución.

  • La clase de síntesis TwoQubitWeylDecomposition ha sido reescrita en Rust para mejorar su rendimiento.

Características del transpilador

  • Ampliado el análisis de conmutación realizado por CommutationChecker para trabajar también con circuitos abstractos, es decir, cada operación en el circuito cuántico de entrada se comprueba ahora por su representación matricial antes de proceder al paso de análisis. Anteriormente, el análisis de la conmutación sólo se realizaba en circuitos físicos. Además, ahora se comprueba si cada operación puede almacenarse en caché en la biblioteca de conmutación de sesiones. Por ejemplo, esto permite ahora calcular si AnnotatedOperation conmutar. Esto permite que los pases del transpilador que dependen internamente de CommutationChecker , como por ejemplo CommutativeCancellationse ejecuten durante las primeras etapas de un proceso de transpilación predeterminado (antes de la traducción básica).

  • El pase del transpilador ElidePermutations se ejecuta por defecto en la fase de inicio para los niveles de optimización 2 y 3. Intuitivamente, la eliminación de SwapGates y PermutationGates en un circuito virtual casi siempre es beneficioso, ya que hace que el circuito sea más corto y más fácil de enrutar. Como OptimizeSwapBeforeMeasure es un caso especial de ElidePermutationsha sido sustituido por el pase ElidePermuations como parte de la etapa init en los gestores de pases de optimización de nivel 3.

  • Se ha añadido un nuevo paso de optimización del transpilador, ElidePermutationsque está diseñado para ejecutarse antes de la fase de maquetación y que eliminará de forma óptima cualquier error de tipo SwapGates y PermutationGates en un circuito permutando qubits virtuales. Por ejemplo, tomando un circuito con SwapGates:

    _images/release_notes-1.png

    eliminará los intercambios cuando se ejecute el pase:

    from qiskit.transpiler.passes import ElidePermutations
    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(3)
    qc.h(0)
    qc.swap(0, 1)
    qc.swap(2, 0)
    qc.cx(1, 0)
    qc.measure_all()
    
    ElidePermutations()(qc).draw("mpl")
    _images/release_notes-2.png

    El pase también establece el conjunto de propiedades virtual_permutation_layout , almacenando la permutación de los qubits virtuales al final del circuito que fue optimizado.

  • La página HLSConfig tiene ahora dos argumentos opcionales adicionales. El argumento plugin_selection puede ajustarse a "sequential" o a "all". Si se establece en "secuencial" (por defecto), para cada objeto de nivel superior el HighLevelSynthesis pass considerará los métodos especificados secuencialmente, en el orden en que aparecen en la lista, deteniéndose en el primer método que sea capaz de sintetizar el objeto. Si se ajusta a "todos", se tendrán en cuenta todos los métodos especificados y se elegirá el mejor circuito sintetizado, según plugin_evaluation_fn . El argumento plugin_evaluation_fn es un callable opcional que evalúa la calidad del circuito cuántico sintetizado; un valor menor significa un circuito mejor. Cuando se establece en None, la calidad del circuito es su tamaño (es decir, el número de puertas que contiene).

    El siguiente ejemplo ilustra la nueva funcionalidad:

    from qiskit import QuantumCircuit
    from qiskit.circuit.library import LinearFunction
    from qiskit.synthesis.linear import random_invertible_binary_matrix
    from qiskit.transpiler.passes import HighLevelSynthesis, HLSConfig
    
    # Create a circuit with a linear function
    mat = random_invertible_binary_matrix(7, seed=37)
    qc = QuantumCircuit(7)
    qc.append(LinearFunction(mat), [0, 1, 2, 3, 4, 5, 6])
    
    # Run different methods with different parameters,
    # choosing the best result in terms of depth.
    hls_config = HLSConfig(
        linear_function=[
            ("pmh", {}),
            ("pmh", {"use_inverted": True}),
            ("pmh", {"use_transposed": True}),
            ("pmh", {"use_inverted": True, "use_transposed": True}),
            ("pmh", {"section_size": 1}),
            ("pmh", {"section_size": 3}),
            ("kms", {}),
            ("kms", {"use_inverted": True}),
        ],
        plugin_selection="all",
        plugin_evaluation_fn=lambda circuit: circuit.depth(),
    )
    
    # synthesize
    qct = HighLevelSynthesis(hls_config=hls_config)(qc)

    En el ejemplo, ejecutamos múltiples métodos de síntesis con diferentes parámetros, eligiendo el mejor circuito en términos de profundidad. Tenga en cuenta que si optimizara circuit.size() en su lugar elegiría un circuito diferente.

  • Se ha añadido el CommutativeCancellation pase a la etapa init de los gestores de pases preestablecidos para los niveles de optimización 2 y 3. Esto permite a los gestores de pases predefinidos cancelar operaciones lógicas adicionales al principio del canal de compilación.

  • Los siguientes pases de análisis aceptan ahora restricciones codificadas en un Target gracias a un nuevo argumento de entrada target :

    Las restricciones de destino tendrán prioridad sobre las restricciones proporcionadas por el usuario, por coherencia con el resto del transpilador.

  • Se ha añadido un nuevo método Layout.inverse() que se utiliza para tomar la inversa de un objeto Layout objeto. Añadido un nuevo método Layout.compose() que se utiliza para componer dos Layout objetos juntos. Se ha añadido un nuevo método Layout.to_permutation() que se utiliza para crear una permutación correspondiente a un Layout objeto.

  • Se ha añadido una nueva reducción al OptimizeAnnotated paso del transpilador. Esta reducción busca operaciones anotadas (objetos de tipo AnnotatedOperation que constan de una operación base BB y una lista MM de modificadores de control, inversos y de potencia) con las siguientes propiedades:

    • la operación base BB debe sintetizarse (es decir, no está ya soportada por el objetivo o pertenece a la biblioteca de equivalencias)
    • el circuito de definición de BB puede expresarse como PP - QQ - RR con R=P1R = P^{-1}

    En este caso, los modificadores sólo pueden desplazarse a la parte QQ. Como ejemplo concreto, los sumadores controlados basados en QFT tienen la forma control - [QFT -- U -- IQFT], que puede simplificarse a QFT -- control-[U] -- IQFT. Al eliminar los controles sobre QFT y IQFT partes del circuito, se obtiene un número significativamente menor de puertas en el circuito transpilado.

  • Añadidos dos nuevos métodos a la DAGCircuit clase: qiskit.dagcircuit.DAGCircuit.op_successors() devuelve un iterador a DAGOpNode sucesores de un nodo, y qiskit.dagcircuit.DAGCircuit.op_successors() devuelve un iterador a los DAGOpNode predecesores de un nodo.

  • Añadido un nuevo pase transpiler, RemoveFinalResetque eliminará cualquier operación Reset que sea la última instrucción en un cable qubit. Por ejemplo, tomando un circuito con final Resets:

    _images/release_notes-3.png

    eliminará los reinicios finales cuando se ejecute el pase:

    from qiskit.transpiler.passes import RemoveFinalReset
    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(3, 1)
    qc.reset(0)
    qc.h(range(3))
    qc.cx(1, 0)
    qc.measure(0, 0)
    qc.reset(range(3))
    RemoveFinalReset()(qc).draw("mpl")
    _images/release_notes-4.png
  • Añadido un nuevo pase de transpilador StarPreRouting diseñado para identificar los subcircuitos de conectividad en estrella y sustituirlos por una ruta lineal óptima. Esto es útil para ciertos circuitos que se componen de esta conectividad de circuito como Bernstein-Vazirani y QFT. Por ejemplo:

    _images/release_notes-5.png
    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler.passes import StarPreRouting
    
    qc = QuantumCircuit(5)
    qc.h(0)
    qc.cx(0, range(1, 5))
    StarPreRouting()(qc).draw("mpl")
    _images/release_notes-6.png

    También se puede ampliar un gestor de pases predefinidos existente:

    from qiskit import QuantumCircuit
    from qiskit.transpiler import CouplingMap
    from qiskit.transpiler.passes import StarPreRouting
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    
    cm = CouplingMap.from_line(5)
    qc = QuantumCircuit(5)
    qc.h(0)
    qc.cx(0, range(1, 5))
    pm = generate_preset_pass_manager(2, coupling_map=cm)
    pm.init += StarPreRouting()
    result = pm.run(qc)
    result.draw("mpl")
    _images/release_notes-7.png

Funciones de visualización

  • Los cajones de texto y Matplotlib cajones de circuitos (QuantumCircuit.draw()) tienen un soporte mínimo para mostrar expresiones que implican variables manuales en tiempo real. La operación Store y las inicializaciones de variables aún no están soportadas; para circuitos dinámicos a gran escala, recomendamos utilizar las capacidades de exportación de OpenQASM 3 (qasm3.dumps()) para obtener una representación textual de un circuito.

Herramientas Opciones

  • Esta versión de Qiskit finaliza la compatibilidad con NumPy 2.0. Qiskit seguirá siendo compatible con NumPy 1.x y 2.x en el futuro inmediato.

Notas de actualización

  • Elimina la codificación de las opciones de estilo para los archivos plot_histogram(). Esto permite aplicar fielmente a las figuras los archivos de estilo de Matplotlib. Los usuarios que deseen ir más allá de los valores predeterminados establecidos por Matplotlib pueden crear sus propios archivos de estilo, o pasar un objeto Matplotlib Axes a plot_histogram y aplicar posteriormente cualquier personalización.

  • La función transpile() se ha actualizado para convertir internamente las entradas de tipo BackendV1 a BackendV2lo que permite que el proceso de transpilación acceda ahora a las restricciones del backend a través de una entrada de tipo Target. Este cambio no requiere ninguna acción por parte del usuario.

Notas sobre la actualización de circuitos

  • El uso de números aleatorios de QuantumVolume ha cambiado, por lo que obtendrás un circuito diferente para una semilla fija entre versiones anteriores de Qiskit y esta versión. La generación aleatoria-unitaria utiliza ahora más bits de entropía, por lo que los circuitos grandes estarán menos sesgados.

  • Las instancias UnitaryGate en la definición de un QuantumVolume circuito ya no tendrán un label campo establecido. Anteriormente se establecía en la cadena su4_<seed> donde <seed> era un número de tres dígitos que denotaba la semilla de una instancia interna de Numpy pRNG para esa puerta. Hacer esto era un serio problema de rendimiento, y la semilla no debería haber sido útil; si necesitas recuperar la matriz de la puerta, simplemente usa el método Gate.to_matrix() método.

Notas sobre la actualización de primitivas

  • La función make_data_bin() ya no crea y devuelve una DataBin subclase. En su lugar, devuelve siempre la DataBin clase. Sin embargo, sigue existiendo por compatibilidad con versiones anteriores, aunque con el tiempo dejará de utilizarse. Todos los usuarios deberían migrar para construir DataBin instancias directamente, en lugar de instanciar subclases como salida de make_data_bin().

Notas de actualización para proveedores

  • Implementación de BackendV2 (y BackendV1) pueden desear actualizar sus métodos run() para rechazar ansiosamente entradas que contengan variables clásicas tipadas (véase qiskit.circuit.classical) y la instrucción Store si no tienen soporte para ellas. La nueva instrucción Store es tratada por el transpilador como una "directiva" siempre disponible (como Barrier); si sus backends no la soportan, no será detectada por la directiva transpiler.

    Consulte Variables en tiempo real para obtener más información.

Notas sobre la actualización de QPY

Notas sobre la actualización de Synthesis

  • El TwoQubitWeylDecomposition ya no se autoespecializará en una subclase al crearse. Este era un detalle interno de la subclase TwoQubitWeylDecomposition anteriormente, y no era un comportamiento público documentado ya que todas las subclases se comportaban igual y sólo se utilizaban para el envío interno. Sin embargo, como se trataba de un comportamiento detectable, esta nota de la versión pretende documentar que esto ya no ocurrirá y que todas las instancias de TwoQubitWeylDecomposition serán del mismo tipo. No hay cambios en el comportamiento de los métodos públicos de la clase.

Notas sobre la actualización del transpilador

  • El preajuste StagedPassManager devuelto para el nivel de optimización 2 por generate_preset_pass_manager() y level_2_pass_manager() se han reelaborado para ofrecer un mejor equilibrio entre tiempo de ejecución y optimización. Esto significa que los circuitos de salida cambiarán en comparación con versiones anteriores. Si necesita un gestor de pases exacto del nivel 2 en versiones anteriores, puede construirlo manualmente o utilizarlo de una versión anterior y guardar los circuitos con qpy para cargarlo con una versión más reciente.

Herramientas Notas de actualización

  • La versión mínima compatible de Windows es ahora Windows 10. En versiones anteriores no indicábamos explícitamente una versión mínima compatible de Windows e implícitamente Windows 7, 8 y 8.1 podrían haber funcionado (pero nunca se probaron). Pero debido a que Rust 1.78 ha dejado de soportar versiones antiguas de Windows, los binarios publicados de Qiskit en PyPI no soportarán versiones antiguas de Windows a partir de esta versión. Si usas una versión antigua de Windows, es probable que puedas compilar Qiskit desde el código fuente usando un compilador Rust antiguo (la versión mínima de Rust soportada por Qiskit para compilar desde el código fuente es actualmente 1.70 ), pero las versiones antiguas de Windows no son una plataforma soportada y no están probadas.

Notas sobre características en desuso

  • El soporte para ejecutar Qiskit con Python 3.8 ha sido obsoleto y será eliminado en la versión de Qiskit 1.3.0. 1.3.0 es la primera versión después de que Python 3.8 llegue al final de su vida útil y deje de recibir soporte. [1] Esto significa que a partir de la versión 1.3.0 deberá actualizar la versión Python que esté utilizando a Python 3.9 o superior.

    [1] https://devguide.python.org/versions/

Proveedores obsoletos

  • Las clases base abstractas Provider y ProviderV1 están ahora obsoletas y serán eliminadas en Qiskit 2.0.0. La abstracción que ofrecían estas definiciones de interfaz no aportaba un valor sustancial; únicamente encapsulaba los atributos name, backends, y un get_backend(). Un _provider_, como concepto, seguirá existiendo como una colección de backends. Si está implementando un proveedor actualmente, puede ajustar su código simplemente eliminando ProviderV1 como clase padre de su implementación. Como parte de esto, es probable que desee añadir una implementación de get_backend para la compatibilidad con versiones anteriores. Por ejemplo:

    def get_backend(self, name=None, **kwargs):
      backends = self.backends(name, **kwargs)
      if len(backends) > 1:
          raise QiskitBackendNotFoundError("More than one backend matches the criteria")
      if not backends:
          raise QiskitBackendNotFoundError("No backend matches the criteria")
      return backends[0]

Sintesis Obsoletas

  • El método TwoQubitWeylDecomposition.specialize() está obsoleto y se eliminará en la versión de Qiskit 2.0.0. Este método nunca tuvo un propósito público y no era seguro para un usuario final llamarlo ya que mutaría la descomposición calculada en el objeto y produciría campos inválidos en el objeto. Sólo se utilizaba internamente para construir un nuevo TwoQubitWeylDecomposition objeto. A pesar de ello, seguía siendo una parte documentada de la API pública para la clase y ahora está siendo obsoleta sin ningún reemplazo potencial. Esta versión siempre lanzará un NotImplementedError cuando se llama porque la subclase de especialización se ha eliminado como parte de la reescritura Rust de la clase.

Deprecaciones del transpilador

  • El pase qiskit.transpiler.passes.CXCancellation ha quedado obsoleto en favor de InverseCancellationque es más genérico. CXCancellation es totalmente equivalente semánticamente a InverseCancellation([CXGate()]).

  • El pase de transpilación qiskit.transpiler.passes.ALAPSchedule ha quedado obsoleto. Estaba pendiente de depreciación desde Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. El pase se sustituye por ALAPScheduleAnalysisque es un pase de análisis.

  • El pase de transpilación qiskit.transpiler.passes.ASAPSchedule ha quedado obsoleto. Estaba pendiente de depreciación desde Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. Ha sido sustituido por ASAPScheduleAnalysis y el nuevo flujo de trabajo de programación.

  • El pase de transpilación qiskit.transpiler.passes.DynamicalDecoupling ha quedado obsoleto. Estaba pendiente de depreciación desde Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. En su lugar, utilice PadDynamicalDecouplingque realiza la misma función, pero requiere la ejecución previa de pases de programación y análisis de alineación.

  • El pase de transpilación qiskit.transpiler.passes.AlignMeasures ha quedado obsoleto. Estaba pendiente de depreciación desde Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. En su lugar, utilice ConstrainedRescheduleque realiza la misma función y también admite la alineación con restricciones temporales adicionales.

Visualización Obsoleto

  • Los parámetros show_idle y show_barrier de los cajones cronológicos se han sustituido por idle_wires y plot_barriers respectivamente para que coincidan con los parámetros de los cajones de circuitos. Sus nombres anteriores han quedado obsoletos y se eliminarán en la próxima versión principal. Los nuevos parámetros son totalmente equivalentes.

Corrección de errores

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

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

  • Se ha solucionado un problema por el que el ConstrainedReschedule error si el circuito contenía una instrucción Reset instrucción. Esto se ha corregido para que el pase ya no de errores, sin embargo un hardware real puede comportarse de manera diferente de lo que Qiskit planificador asume especialmente para las mediciones de mitad de circuito y reinicios. El programador de Qiskit muestra RuntimeWarning si encuentra un circuito que contenga cualquiera de los dos elementos. Corregido #10354

  • Se ha solucionado un problema con la clase CommutationChecker por el que se producía un error si el atributo de una puerta name estaba codificado en UTF8. Antes sólo funcionaban los nombres de puerta con codificación ascii. Corregido #12501

  • Se ha solucionado un problema con los botones SparsePauliOp.apply_layout() y Pauli.apply_layout() cuando se pasaba una matriz no válida con índices duplicados o negativos para el argumento layout . Antes esto no daba lugar a un error y la transformación realizada no era válida. A partir de ahora, estos métodos mostrarán un mensaje QiskitError si se proporcionan índices duplicados o índices negativos como parte de un diseño.

  • Se ha solucionado un problema de rendimiento en el BackendSamplerV2 y BackendEstimatorV2. Corregido #12290

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

  • Se ha solucionado un problema con la función circuit_drawer() o QuantumCircuit.draw() cuando se utilizaba la opción de salida mpl , por la que el programa se colgaba si el circuito que se dibujaba tenía una operación ControlFlow y la opción fold estaba establecida en -1 (lo que significa que no había pliegue). Corregido #12012.

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

  • Se ha corregido un error en transpile() se ha corregido un error por el que las restricciones personalizadas instruction_durations, dt y backend_properties se ignoraban cuando se proporcionaban al mismo tiempo que un backend de tipo BackendV2. El comportamiento después de la corrección es ahora independiente de si el backend proporcionado es de tipo BackendV1 o del tipo BackendV2. Del mismo modo, las entradas de target anulan ahora las entradas personalizadas de timing_constraints , pero tienen prioridad sobre BackendV1 y BackendV2 entradas.

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

  • La página EvolvedOperatorAnsatz ahora maneja correctamente el caso en que el argumento del operador es una lista vacía. Antes, esto daba lugar a un error.

  • A partir de ahora EvolvedOperatorAnsatz no tendrá ningún qregs cuando thera son cero qubits, en lugar de tener una QuantumRegister instancia con cero qubits. Este comportamiento es más coherente con su superclase QuantumCircuit.

  • El método Instruction.repeat() ahora mueve un conjunto condition al exterior devuelto Instruction y deja incondicionales las puertas interiores de su definición. Anteriormente, el método dejaba ClassicalRegister instancias dentro de la definición interna, lo cual era un estado no válido, y se manifestaba como errores aparentemente no relacionados más tarde, como durante la transpilación o la exportación. Corregido #11935.

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

  • Mejorar la descomposición de las puertas MCXGate y MCPhaseGate sin utilizar qubits ancilla, de modo que el número de CXGate crezca cuadráticamente en el número de qubits y no exponencialmente.

  • Se ha corregido un error que bloqueaba la función convert_to_target() cuando faltaban las propiedades de los qubits ( T1, T2 o la frecuencia). Los valores de propiedad que faltan en QubitProperties se rellenan con None.

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

  • Pauli.evolve() ahora maneja correctamente los circuitos cuánticos que contienen puertas ECR. Antes no se reconocían como Clifford gates, y se producía un error.

  • Se ha corregido un error en Pauli.evolve() por el que evolucionar mediante un circuito con un nombre que coincidiera con ciertas puertas Clifford ('cx', 'cz', etc) haría evolucionar al Pauli según el nombre del circuito, no según el contenido del circuito. Este error sólo se producía con la opción no predeterminada frame='s'.

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

  • Corregido un error en el manejo de default_alignment argumento de build(). Las entradas de tipo AlignmentKind se procesan ahora correctamente como alineaciones por defecto.

  • Se ha corregido un error de la función qiskit.pulse.utils.format_parameter_value() que convertía involuntariamente números enteros suficientemente grandes en valores flotantes o provocaba redondeos inesperados. Véase el nº 11971 para más detalles.

  • Solucionado un problema en la clase QDrift donde los coeficientes del Hamiltoniano eran previamente forzados a ser positivos tomando el valor absoluto de cada coeficiente. Se ha corregido para volver a añadir los signos de los coeficientes negativos.

  • Se ha corregido un error en convert_durations_to_dt() por el que la función aplicaba ciegamente una conversión de segundos a dt en las duraciones de los circuitos, independientemente de las unidades originales del atributo. Esto podría dar lugar a órdenes de magnitud erróneos en las duraciones de circuito notificadas.

  • 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 en el Commuting2qGateRouter por el que las permutaciones qreg no se añadían al conjunto de propiedades del pase, por lo que el usuario tenía que seguirlas manualmente. Ahora es posible acceder a la permutación a través de la propiedad layout del circuito de salida y conectar el pase a 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.

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

  • El método qiskit.instruction.Instruction.soft_compare() sirve para comparar si dos puertas coinciden en su nombre, número de qubits, número de clbits y número de parámetros. Sin embargo, había un error tipográfico por el que no comprobaba el número de qubits y el número de clbits para una coincidencia. Esto resuelve el aparente error tipográfico.

  • El complemento predeterminado init no generaba correctamente un error TranspilerError cuando se invocaba con un nivel de optimización no válido.

  • Se ha corregido un problema con el método Operator.from_circuit() por el que se interpretaba incorrectamente la permutación del diseño final, lo que provocaba que se construyera un Operator no válido. Anteriormente, el trazado final se procesaba sin tener en cuenta el trazado inicial, es decir, la inicialización era incorrecta para todos los circuitos cuánticos que tuvieran un trazado inicial no trivial.

  • Se ha corregido un problema de rendimiento en PassManager.run() cuando se ejecuta en varios circuitos en paralelo. Ya no perderá tiempo serializando el PassManager (que es un requisito para la ejecución paralela) cuando se le dan múltiples entradas si sólo va a procesar las entradas en serie.

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

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

  • El analizador OpenQASM 2.0 (qasm2.load() y qasm2.loads()) puede ahora evaluar expresiones de ángulo de puerta 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. Sin embargo, 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.

  • Parameter las instancias utilizadas como sustituciones de variables de input en programas de OpenQASM 3 ahora tendrán sus nombres escapados para evitar colisiones con puertas incorporadas durante la exportación a OpenQASM 3. Antes podía haber un conflicto de nombres y el exportador generaba un OpenQASM 3 no válido.

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

  • QuantumCircuit.append() con copy=True (por defecto) ahora copiará correctamente las instrucciones parametrizadas por ParameterExpression y no sólo por instancias Parameter instancias.

  • El manejo interno de las calibraciones de circuitos personalizados y InstructionDurations se ha transferido de la función transpile() función a los pases individuales del transpilador: DynamicalDecoupling DynamicalDecoupling. Antes, las duraciones de las instrucciones de las calibraciones de circuitos no se tenían en cuenta a menos que se incorporaran manualmente al argumento de entrada instruction_durations, pero los pases que lo necesitan ahora analizan el circuito y eligen el valor de duración más relevante según el siguiente orden de prioridad: objetivo > entrada personalizada > calibraciones de circuitos.

  • Se ha corregido un error en transpile() por el que el argumento num_processes sólo se utilizaba si se proporcionaba dt o instruction_durations .

Otras notas


1.0.0rc1

Notas de actualización para proveedores

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

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

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

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

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

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

    Ejemplo de migración a la nueva GenericBackendV2 clase:

    # Legacy path
    from qiskit.providers.fake_provider import FakeBackend5QV2
    backend = FakeBackend5QV2()
    
    # New path
    from qiskit.providers.fake_provider import GenericBackendV2
    backend = GenericBackendV2(num_qubits=5)
    # note that this class will generate 5q backend with generic
    # properties that serves the same purpose as FakeBackend5QV2
    # but will generate different results
¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.