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()yBitArray.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 opcionalnum_bits. Ahora producen unBitArrayconBitArray.num_bitsa 1. -
Se ha corregido un decorador que faltaba en
C3SXGateque hacía que fallara siGate.to_matrix()era llamado. La matriz de la puerta ahora se devuelve como se esperaba. -
Añadidas las puertas Clifford que faltaban al
CollectCliffordstranspilador. En particular, hemos añadido las puertasECRGate,DCXGate,iSWAPGate,SXGateySXdgGatea este paso del transpilador. -
El atributo
QuantumCircuit.parametersestará vacío cuando se utiliceQuantumCircuit.copy_empty_like()en un circuito paramétrico. Anteriormente, una caché interna se copiaba sin invalidarse. Corrección #12617. -
Arreglar el
SolovayKitaeval 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()yDAGCircuit.draw()cuando se intentaba visualizar una instanciaDAGCircuitque conteníaVarcables. 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
GenericBackendV2anteriormente 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ónn-qubit en un bloque demqubits, dejando el DAG en un estado inválido. Este comportamiento se ha corregido, y cualquier intento de hacer esto ahora levantará unDAGCircuitErrorcomo 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
Isometrydebido a una aserción innecesaria, que provocaba un error enUnitaryGate.control()cuandoUnitaryGatetenía más de dos qubits. -
QuantumCircuit.depth()manejará ahora correctamente las operaciones que no tengan operandos, como por ejemploGlobalPhaseGate. -
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 unBackendV2argumento. 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
VF2Layoutpass lanzaría una excepción cuando se le proporcionara unaTargetsin restricciones de conectividad. Este sería el caso de los objetivos de Aer 0.13. El problema se ha solucionado. -
ParameterExpressionse actualizó para que las instancias totalmente vinculadas que se comparan con instancias de los tipos numéricos incorporados de Python (comofloatyint) 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 unaGate.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 haceOperatorlo 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 conNonepara 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 unQuantumCircuitdonde 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
UnitarySynthesishan 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ónUnitarySynthesisconllevaba históricamente una gran sobrecarga de tiempo de ejecución. Esta versión también comienza a ejecutarseUnitarySynthesiscomo 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
Isometryse 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 paraXGateyPhaseGatese 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,
ElidePermutationsyStarPreRoutinghan demostrado tener un impacto significativo en la calidad de salida de los circuitos y en el tiempo de ejecución yRemoveFinalResetpueden 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_managery utilizado internamente portranspile()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,
BackendEstimatorV2yBackendSamplerV2para 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 deGate(como ofSGate) tienen un argumento adicionalannotatedque se utiliza para devolver un objetoAnnotatedOperationcuando se aplica una potencia a una puerta o circuito. El valor por defecto deFalsecorresponde al comportamiento existente. Además, para las puertas estándar con un métodopowerdefinido explícitamente, el argumentoannotatedno tiene ningún efecto. Por ejemplo, tantoSGate().power(1.5, annotated=False)comoSGate().power(1.5, annotated=True)devuelven unPhaseGate. Una diferencia en el valor deannotatedse manifiesta para las puertas sin un método de potencia explícitamente definido. El valor deFalsedevuelve unUnitaryGateigual que antes, mientras que el valor deTruedevuelve unAnnotatedOperationque representa la instrucción modificada con el "modificador de potencia". -
Se ha añadido un nuevo argumento
ctrl_stateaQuantumCircuit.mcp()yMCPhaseGate.El método
QuantumCircuit.mcp()y la claseMCPhaseGatese han actualizado para incluir un parámetroctrl_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_stateaQuantumCircuit.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
QuantumCircuitpuede 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
Varnodo, 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 utilizandoQuantumCircuit.add_var()yQuantumCircuit.add_input()o en un nivel inferior utilizandoVar.new().Las variables pueden almacenarse manualmente en, utilizando la
Storey su correspondiente método de circuitoQuantumCircuit.store(). Esto incluye escribir aClbityClassicalRegisterenvueltas en nodosVarnodos.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 (verQuantumCircuit.draw()).NotaLas 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.classicalpuede ahora representar la indexación y el desplazamiento de bits de enteros sin signo y similares a bits (por ejemploClassicalRegister). 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))): passQiskit 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
NLocaly sus subclases de bibliotecas de circuitos derivadas (p. ej.EfficientSU2yRealAmplitudes) 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 clavecopy, que por defecto esTrue. 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 siQuantumCircuit.assign_parameters()intenta mutar la instrucción en su lugar, no afecta a otras referencias a la misma instrucción. Ahora, configurarcopy=Falsele 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 clavecopy, que por defecto esTrue. Por defectocompose()copia todas las instrucciones, de modo que las mutaciones de un circuito no afectan a ningún otro. Sicopy=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
QuantumVolumecircuitos 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. -
QuantumVolumeahora tiene un argumento de palabra claveflatten. Por defecto esFalse, donde el circuito construido contiene una única instrucción que a su vez contiene la estructura real del volumen. Si se fijaTrue, el circuito dispondrá directamente de las matrices volumétricas SU4. -
UnitaryGateahora acepta un argumento opcionalnum_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. -
QuantumCircuittiene varios métodos nuevos para trabajar e inspeccionar variables manualesVarvariables.Consulte Trabajar con datos clásicos mecanografiados en tiempo real para profundizar en todos ellos.
Los nuevos métodos son:
add_var()add_input()add_capture()add_uninitialized_var()get_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()store()
Además, hay varios atributos dinámicos nuevos en
QuantumCircuitque rodean a estas variables: -
ControlFlowOpy sus subclases tienen ahora un métodoiter_captured_vars()que devolverá un iterador sobre las variables únicas capturadas en cualquiera de sus bloques inmediatos. -
DAGCircuittiene varios métodos nuevos para trabajar e inspeccionar variables manualesVarvariables. Estos son en gran medida equivalentes a susQuantumCircuitsalvo que losDAGCircuitestán optimizados para el acceso programático con objetos ya definidos, mientras que losQuantumCircuitmétodos están más enfocados al uso humano interactivo.Los nuevos métodos son:
add_input_var()add_captured_var()add_declared_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()
También hay nuevos atributos públicos:
-
DAGCircuit.wiresahora también contendrá cualquierVarvariables 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_remapyinline_capturespara soportar mejor las variables clásicas en tiempo real.var_remappuede utilizarse para reescribirVarnodos en el argumento del circuito a medida que sus instrucciones se alinean en el circuito base. Puede utilizarse para evitar conflictos de nombres.inline_capturespuede establecerse enTrue(por defectoFalse) para vincular todos losVarnodos rastreados como "capturas" en el circuito argumento con los mismosVarnodos en el circuito base, sin intentar volver a declarar las variables. Esto se puede utilizar, en combinación conQuantumCircuit.copy_empty_like()devars_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 enTruepara alinear los nodos "capturados" en el circuito base sin volver a declararlosVarcapturados" en el circuito del argumento en el circuito base sin volver a declararlos. Junto con la opciónvars_mode="captures"de varios métodosDAGCircuitse puede utilizar para combinar DAGs que operan sobre las mismas variables. -
QuantumCircuit.copy_empty_like()yDAGCircuit.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 memoriaVaren 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 concompose()) o"drop"para eliminarlas. -
Se ha añadido un nuevo argumento de palabra clave
vars_modea los métodosDAGCircuitmé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 enTwoLocalcomoRealAmplitudesyEfficientSU2.
Características primitivas
-
La aplicación
BackendEstimatorV2deBaseEstimatorV2se ha añadido. Este estimador admiteBackendV1yBackendV2.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
BackendSamplerV2deBaseSamplerV2se ha añadido. Este muestreador admiteBackendV1yBackendV2que permiten la opciónmemorypara 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
BitArrayobjetos a lo largo de varios ejes.concatenate(): unen matrices a lo largo de un eje existente de las matrices.concatenate_bits(): unen matrices a lo largo del eje de bits.concatenate_shots(): unen matrices a lo largo del eje de tomas.
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
BitArrayobjeto 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 unBitArray.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] -
DataBinsatisface ahora elShapedprotocolo. Esto significa que cadaDataBininstancia tiene ahora los atributos adicionalesshape(tupleint[,...])la forma inicial de cada entrada de la instanciandim(int): la longitud deshapesize(int): el producto de las entradas deshape
La forma se puede pasar al constructor.
-
Se han añadido funciones de mapeo a
DataBines decir,__getitem__,__contains__,__iter__,keys(),values()yitems().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
SamplerPubResultdePubResultqueBaseSamplerV2pueden devolver las implementaciones. La principal característica añadida en esta nueva subclase esjoin_data()que une (un subconjunto de) los contenidos dedataen 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
- El simulador basado en python
BasicSimulatorsimulador basado en python incluido enbasic_providerahora permite ejecutar todas las puertas estándar de hasta 3 qubits definidas enqiskit.circuit.library.
Características de Pulse
-
Ahora es posible asignar parámetros a los pulsos
ScheduleyScheduleBlockespecificando 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ámetrosScheduleoScheduleBlockque tengan el mismo nombre. Además, el parámetroParameterVectorpuede 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_parametersdeScheduleyScheduleBlockpermiten ahora asignar unParameterVectora una lista de valores de parámetros simultáneamente además de asignar instancias individuales deParametera valores individuales.
OpenQASM Características
- El exportador OpenQASM 3 admite el almacenamiento manual
Varen 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 memoriaVarde 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 aapply_layout(). Este método se utiliza para aplicar unTranspileLayoutdiseño del transpilador a unPauliobservable que se construyó para un circuito de entrada. Esto permite trabajar conBaseEstimator/BaseEstimatorV2y la transpilación local cuando la entrada es de tipoPauli. 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 debackend) y permuta su disposición, que se aplica a continuación aH1utilizandoapply_layout()para reflejar las transformaciones realizadas porpm.run(). -
Añade las etiquetas
PauliList.noncommutation_graph()ySparsePauliOp.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 porSparsePauliOp.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 entornoRAYON_NUM_THREADS. Puede forzar temporalmente la ejecución en serie utilizando el nuevo argumento booleanoforce_serialparato_matrix().
Características de síntesis
-
El plugin
KMSSynthesisLinearFunctionplugin para sintetizar objetosLinearFunctionacepta ahora dos opciones adicionalesuse_invertedyuse_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
PMHSynthesisLinearFunctioncomplemento para sintetizar objetosLinearFunctionacepta ahora varias opciones adicionales. La opciónsection_sizese pasa al método de síntesis subyacente. Las opcionesuse_invertedyuse_transposedmodifican 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ónTwoQubitBasisDecomposer.__call__()yXXDecomposer.__call__()y. Este argumento se utiliza para controlar si se devuelve unDAGCircuitcuando se llama aTwoQubitBasisDecomposeroXXDecomposeren lugar de la instancia por defectoQuantumCircuit. 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
DAGCircuital llamar a la instanciaTwoQubitBasisDecomposerinstanciadecomposer. -
LieTrotter.synthesize()utiliza ahoraQuantumCircuit.repeat()para generar repeticiones adicionales de un paso Trotter después del primer paso Trotter. Esto reduce el número deQuantumCircuit.compose()llamadas por un factor derepsy 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 qubits sobre una arquitectura lineal de vecino más cercano utilizando puertas CX con profundidad . -
La clase
TwoQubitBasisDecomposerse ha reescrito en Rust, lo que mejora enormemente el rendimiento en tiempo de ejecución. -
La clase de síntesis
TwoQubitWeylDecompositionha sido reescrita en Rust para mejorar su rendimiento.
Características del transpilador
-
Ampliado el análisis de conmutación realizado por
CommutationCheckerpara 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 siAnnotatedOperationconmutar. Esto permite que los pases del transpilador que dependen internamente deCommutationChecker, como por ejemploCommutativeCancellationse ejecuten durante las primeras etapas de un proceso de transpilación predeterminado (antes de la traducción básica). -
El pase del transpilador
ElidePermutationsse ejecuta por defecto en la fase de inicio para los niveles de optimización 2 y 3. Intuitivamente, la eliminación deSwapGates yPermutationGates 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. ComoOptimizeSwapBeforeMeasurees un caso especial deElidePermutationsha sido sustituido por el paseElidePermuationscomo 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 tipoSwapGates yPermutationGates en un circuito permutando qubits virtuales. Por ejemplo, tomando un circuito conSwapGates:
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")
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
HLSConfigtiene ahora dos argumentos opcionales adicionales. El argumentoplugin_selectionpuede ajustarse a"sequential"o a"all". Si se establece en "secuencial" (por defecto), para cada objeto de nivel superior elHighLevelSynthesispass 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únplugin_evaluation_fn. El argumentoplugin_evaluation_fnes un callable opcional que evalúa la calidad del circuito cuántico sintetizado; un valor menor significa un circuito mejor. Cuando se establece enNone, 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
CommutativeCancellationpase a la etapainitde 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
Targetgracias a un nuevo argumento de entradatarget: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 objetoLayoutobjeto. Añadido un nuevo métodoLayout.compose()que se utiliza para componer dosLayoutobjetos juntos. Se ha añadido un nuevo métodoLayout.to_permutation()que se utiliza para crear una permutación correspondiente a unLayoutobjeto. -
Se ha añadido una nueva reducción al
OptimizeAnnotatedpaso del transpilador. Esta reducción busca operaciones anotadas (objetos de tipoAnnotatedOperationque constan de una operación base y una lista de modificadores de control, inversos y de potencia) con las siguientes propiedades:- la operación base debe sintetizarse (es decir, no está ya soportada por el objetivo o pertenece a la biblioteca de equivalencias)
- el circuito de definición de puede expresarse como - - con
En este caso, los modificadores sólo pueden desplazarse a la parte . Como ejemplo concreto, los sumadores controlados basados en QFT tienen la forma
control - [QFT -- U -- IQFT], que puede simplificarse aQFT -- control-[U] -- IQFT. Al eliminar los controles sobreQFTyIQFTpartes del circuito, se obtiene un número significativamente menor de puertas en el circuito transpilado. -
Añadidos dos nuevos métodos a la
DAGCircuitclase:qiskit.dagcircuit.DAGCircuit.op_successors()devuelve un iterador aDAGOpNodesucesores de un nodo, yqiskit.dagcircuit.DAGCircuit.op_successors()devuelve un iterador a losDAGOpNodepredecesores de un nodo. -
Añadido un nuevo pase transpiler,
RemoveFinalResetque eliminará cualquier operaciónResetque sea la última instrucción en un cable qubit. Por ejemplo, tomando un circuito con finalResets:
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")
-
Añadido un nuevo pase de transpilador
StarPreRoutingdiseñ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:
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")
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")
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ónStorey 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 MatplotlibAxesaplot_histogramy aplicar posteriormente cualquier personalización. -
La función
transpile()se ha actualizado para convertir internamente las entradas de tipoBackendV1aBackendV2lo que permite que el proceso de transpilación acceda ahora a las restricciones del backend a través de una entrada de tipoTarget. 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
QuantumVolumeha 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
UnitaryGateen la definición de unQuantumVolumecircuito ya no tendrán unlabelcampo establecido. Anteriormente se establecía en la cadenasu4_<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étodoGate.to_matrix()método.
Notas sobre la actualización de primitivas
- La función
make_data_bin()ya no crea y devuelve unaDataBinsubclase. En su lugar, devuelve siempre laDataBinclase. Sin embargo, sigue existiendo por compatibilidad con versiones anteriores, aunque con el tiempo dejará de utilizarse. Todos los usuarios deberían migrar para construirDataBininstancias directamente, en lugar de instanciar subclases como salida demake_data_bin().
Notas de actualización para proveedores
-
Implementación de
BackendV2(yBackendV1) pueden desear actualizar sus métodosrun()para rechazar ansiosamente entradas que contengan variables clásicas tipadas (véaseqiskit.circuit.classical) y la instrucciónStoresi no tienen soporte para ellas. La nueva instrucciónStorees tratada por el transpilador como una "directiva" siempre disponible (comoBarrier); si sus backends no la soportan, no será detectada por la directivatranspiler.Consulte Variables en tiempo real para obtener más información.
Notas sobre la actualización de QPY
- El valor de
qiskit.qpy.QPY_VERSIONes ahora 12.QPY_COMPATIBILITY_VERSIONse mantiene en 10.
Notas sobre la actualización de Synthesis
- El
TwoQubitWeylDecompositionya no se autoespecializará en una subclase al crearse. Este era un detalle interno de la subclaseTwoQubitWeylDecompositionanteriormente, 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 deTwoQubitWeylDecompositionserá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
StagedPassManagerdevuelto para el nivel de optimización 2 porgenerate_preset_pass_manager()ylevel_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 conqpypara 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.
Proveedores obsoletos
-
Las clases base abstractas
ProvideryProviderV1está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 atributosname,backends, y unget_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 eliminandoProviderV1como clase padre de su implementación. Como parte de esto, es probable que desee añadir una implementación deget_backendpara 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 nuevoTwoQubitWeylDecompositionobjeto. 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á unNotImplementedErrorcuando 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.CXCancellationha quedado obsoleto en favor deInverseCancellationque es más genérico.CXCancellationes totalmente equivalente semánticamente aInverseCancellation([CXGate()]). -
El pase de transpilación
qiskit.transpiler.passes.ALAPScheduleha quedado obsoleto. Estaba pendiente de depreciación desde Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. El pase se sustituye porALAPScheduleAnalysisque es un pase de análisis. -
El pase de transpilación
qiskit.transpiler.passes.ASAPScheduleha quedado obsoleto. Estaba pendiente de depreciación desde Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. Ha sido sustituido porASAPScheduleAnalysisy el nuevo flujo de trabajo de programación. -
El pase de transpilación
qiskit.transpiler.passes.DynamicalDecouplingha quedado obsoleto. Estaba pendiente de depreciación desde Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. En su lugar, utilicePadDynamicalDecouplingque 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.AlignMeasuresha quedado obsoleto. Estaba pendiente de depreciación desde Qiskit 0.37 (con Terra 0.21 ), publicado en junio de 2022. En su lugar, utiliceConstrainedRescheduleque realiza la misma función y también admite la alineación con restricciones temporales adicionales.
Visualización Obsoleto
- Los parámetros
show_idleyshow_barrierde los cajones cronológicos se han sustituido poridle_wiresyplot_barriersrespectivamente 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 indicadoruse_symenginese establecía en un objeto verdadero que se evaluaba comoTruepero no era realmente el booleanoTrue, la carga útil QPY generada se corrompía. Por ejemplo, si defineuse_symenginecomoHAS_SYMENGINEeste objeto se evalúa comoTruecuando se convierte en bool, pero en realidad no esTrue. -
Se ha solucionado un problema con la función
circuit_drawer()y el métodoQuantumCircuit.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
ConstrainedRescheduleerror si el circuito contenía una instrucciónResetinstrucció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 muestraRuntimeWarningsi encuentra un circuito que contenga cualquiera de los dos elementos. Corregido #10354 -
Se ha solucionado un problema con la clase
CommutationCheckerpor el que se producía un error si el atributo de una puertanameestaba 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()yPauli.apply_layout()cuando se pasaba una matriz no válida con índices duplicados o negativos para el argumentolayout. 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 mensajeQiskitErrorsi se proporcionan índices duplicados o índices negativos como parte de un diseño. -
Se ha solucionado un problema de rendimiento en el
BackendSamplerV2yBackendEstimatorV2. 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 atributoBackendConfiguration.supported_instructions, que es la ubicación típica en la que se especifican las instrucciones de flujo de control en un objetoBackendConfigurationobjeto. Corregido #11872. -
Se ha solucionado un problema con la función
circuit_drawer()oQuantumCircuit.draw()cuando se utilizaba la opción de salidampl, por la que el programa se colgaba si el circuito que se dibujaba tenía una operación ControlFlow y la opciónfoldestaba 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.qobjheredado. 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 aWaveformcomo debería. Corregido #11828. -
Se ha corregido un error en
transpile()se ha corregido un error por el que las restricciones personalizadasinstruction_durations,dtybackend_propertiesse ignoraban cuando se proporcionaban al mismo tiempo que un backend de tipoBackendV2. El comportamiento después de la corrección es ahora independiente de si el backend proporcionado es de tipoBackendV1o del tipoBackendV2. Del mismo modo, las entradas detargetanulan ahora las entradas personalizadas detiming_constraints, pero tienen prioridad sobreBackendV1yBackendV2entradas. -
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 comoBasisTranslatorseguirían utilizando las reglas antiguas. Corregido #11958. -
La página
EvolvedOperatorAnsatzahora 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
EvolvedOperatorAnsatzno tendrá ningún qregs cuando thera son cero qubits, en lugar de tener unaQuantumRegisterinstancia con cero qubits. Este comportamiento es más coherente con su superclaseQuantumCircuit. -
El método
Instruction.repeat()ahora mueve un conjuntoconditional exterior devueltoInstructiony deja incondicionales las puertas interiores de su definición. Anteriormente, el método dejabaClassicalRegisterinstancias 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
InverseCancellationpor 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
MCXGateyMCPhaseGatesin utilizar qubits ancilla, de modo que el número deCXGatecrezca 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 enQubitPropertiesse rellenan conNone. -
BasePassManager.run()ya no filtrará elPropertySeten nuevos flujos de trabajo cuando se llama más de una vez. Anteriormente, se utilizaba el mismoPropertySetque 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 predeterminadaframe='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_alignmentargumento debuild(). Las entradas de tipoAlignmentKindse 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
QDriftdonde 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 adten 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
Commuting2qGateRouterpor 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 propiedadlayoutdel 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
initno generaba correctamente un errorTranspilerErrorcuando 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 unOperatorno 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 elPassManager(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. -
Parameterse actualizó para que las instancias que se comparan igual siempre tengan el mismo hash. Anteriormente, sólo se comparaba elParameter.uuidse comparaba, por lo queParametercon nombres diferentes podían compararse igual si se habían construido utilizando un valor común para el parámetrouuid(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()yqasm2.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 . -
Parameterlas instancias utilizadas como sustituciones de variables deinputen 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()concopy=True(por defecto) ahora copiará correctamente las instrucciones parametrizadas porParameterExpressiony no sólo por instanciasParameterinstancias. -
El manejo interno de las calibraciones de circuitos personalizados y
InstructionDurationsse ha transferido de la funcióntranspile()función a los pases individuales del transpilador:DynamicalDecouplingDynamicalDecoupling. 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 argumentonum_processessólo se utilizaba si se proporcionabadtoinstruction_durations.
Otras notas
-
El soporte de la plataforma arm64 macOS ha pasado de Tier 3 a Tier 1. Anteriormente, la plataforma se encontraba en el nivel 3 porque no había ningún entorno CI disponible para probar Qiskit en la plataforma. Ahora que Github ha puesto un entorno arm64 macOS a disposición de los proyectos de código abierto [1], estamos probando la plataforma junto con las demás plataformas compatibles de nivel 1.
[1 ]
1.0.0rc1
Notas de actualización para proveedores
-
El módulo obsoleto
qiskit.providers.fake_providerse ha migrado al paqueteqiskit-ibm-runtimePython. Por esta razón, los siguientes elementos delqiskit.providers.fake_providerse han eliminado tras su desaparición en Qiskit 0.46:qiskit.providers.fake_provider.FakeProviderqiskit.providers.fake_provider.FakeProviderForBackendV2qiskit.providers.fake_provider.FakeProviderFactoryqiskit.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.FakeQasmSimulatorqiskit.providers.fake_provider.FakeJobqiskit.providers.fake_provider.FakeQobj
Para utilizar el nuevo módulo de proveedor falso, puede ejecutar
pip install qiskit-ibm-runtimey 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
GenericBackendV2y 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.FakeBackendV2LegacyQubitPropsqiskit.providers.fake_provider.fake_backend_v2.FakeBackend5QV2qiskit.providers.fake_provider.fake_backend_v2.FakeBackendSimple
Ejemplo de migración a la nueva
GenericBackendV2clase:# 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