Notas de la versión de Qiskit 1.0
1.0.2
Preludio
Qiskit 1.0.2 es una versión de corrección de errores menores para la serie 1.0.
Corrección de errores
-
Se ha corregido un problema con
convert_to_target()por el que el conversor ignoraba incorrectamente las instrucciones de flujo de control si se especificaban en el 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. -
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 función
EvolvedOperatorAnsatzahora maneja correctamente el caso en que el argumentooperatorses una lista vacía. Antes, esto daba lugar a un error. -
Se ha corregido un problema de coherencia con
EvolvedOperatorAnsatzcon qubits cero. Anteriormente, estas instancias contenían un único elementoQuantumRegisterenqregscon cero qubits, pero ahora no se crean registros. Este comportamiento es más coherente con su superclaseQuantumCircuit. -
Se ha corregido un fallo en
convert_to_target()que se producía cuando faltaban propiedades de qubit ( T1, T2 o frecuencia). Los valores de propiedad que faltan enQubitPropertiesse rellenan ahora conNone. -
Se ha corregido un problema de rendimiento en la función
qpy.load()al deserializar cargas útiles QPY con un gran número de qubits o clbits en un circuito. -
Se ha corregido un error por el que
EstimatorPub.coerce()ySamplerPub.coerce()manejaban incorrectamente un parámetro de tipoBindingsArray. Anteriormente se lanzaba falsamente una excepciónValueError. -
Los gestores de paso preestablecidos utilizados por
transpile()ya no fallarán en circuitos con flujo de control cuando no se especifique un objetivo de hardware o un conjunto de puertas base. Ahora tratarán dichos objetivos abstractos como si permitieran todas las operaciones de flujo de control. Corregido #11906. -
Corregido
coerce()para que devuelva una matriz 0-d cuando la entrada es un único observable no anidado. Anteriormente, se actualizaba erróneamente a una sola dimensión, con la forma(1,). -
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
QuantumCircuit.draw()que provocaba que los diccionarios de estilos personalizados del cajón Matplotlib se modificaran al ejecutarse.
1.0.1
Preludio
Qiskit 1.0.1 es un parche que corrige un pequeño número de errores detectados en la versión de Qiskit 1.0.0.
Corrección de errores
-
Se ha corregido un error en la conversión de instrucciones de pulso personalizadas al formato heredado
qiskit.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 apulse.Waveformcomo debería. Corregido #11828. -
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. -
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. -
Se ha corregido un error en
convert_durations_to_dt()por el que la función asumía que sus entradas estaban todas en segundos, en lugar de leer la unidad real. Esto podría dar lugar a órdenes de magnitud erróneos en las duraciones de circuito notificadas.
1.0.0
Preludio
Nos complace lanzar Qiskit 1.0.0. Esta versión es la culminación de 7 años de desarrollo para convertir Qiskit en un SDK estable y de alto rendimiento para la computación cuántica, y es el comienzo de una nueva era para el proyecto y la comunidad Qiskit. Además de las mejoras generales de rendimiento y estabilidad, los cambios más significativos de la versión 1.0.0 se refieren a la política de estabilidad, los ciclos de publicación y el control de versiones. Qiskit utiliza ahora formalmente el versionado semántico, lo que significa que, durante todo el ciclo de vida de la serie de versiones 1.x, el proyecto se compromete a mantener la compatibilidad con versiones anteriores en sus API públicas documentadas. También estamos empezando a ofrecer soporte de corrección de errores para las versiones principales, de modo que siga disponiendo de una rama soportada durante 6 meses después del lanzamiento de la siguiente versión principal. Esto empieza ahora con las series principales 1.x y 0.x : la versión 0.46.x seguirá recibiendo soporte, con lanzamientos periódicos de parches que contienen correcciones de errores, durante 6 meses después del lanzamiento de 1.0. Es decir, 0.46.x se mantendrá hasta 2024-08. Puede consultar todos los detalles de la nueva política aquí:
start/install#qiskit-versioning
Otro aspecto importante de esta versión es el cambio de embalaje. Desde el lanzamiento de Qiskit 0.7 en 2018-12, cuando Qiskit introdujo su modelo de elementos, el paquete qiskit que instalarías ha sido un meta-paquete (o paquete de paquetes) que instala los elementos combinados que componen Qiskit. Como ya se anunció en versiones anteriores (para más detalles, véase la página 0.44.0, 0.45.3 y 0.46.0 junto con esta entrada de blog ) con la versión 1.0 estamos completando una transición para tener un único paquete qiskit que exponga sólo el SDK central (lo que antes era qiskit-terra). Esto significa que para las versiones >= 1.0.0, hemos dejado de utilizar el paquete qiskit-terra y sólo publicaremos qiskit. Como este cambio en la estructura de los paquetes no es totalmente compatible con el instalador de paquetes Python pip, no es posible utilizar simplemente pip install -U qiskit para actualizar de qiskit 0.46.0 a 1.0.0. Se recomienda encarecidamente que para actualizar a Qiskit 1.0.0 se cree un entorno virtual independiente para aislar la instalación. Hay una guía de migración detallada que explica los cambios de empaquetado y cómo instalar Qiskit 1.0.0 en diferentes escenarios que se puede encontrar aquí:
https://qisk.it/1-0-packaging-migration
Como todas nuestras grandes versiones, Qiskit 1.0.0 también tiene una plétora de nuevas características, los aspectos más destacados de esta versión son:
- La clase
QuantumCircuitestructura interna de la clasedataha sido reescrita en Rust para mejorar enormemente la eficiencia de memoria de los objetosQuantumCircuitalmacenando en caché los argumentos de las instrucciones.- Una nueva versión de la definición de la interfaz de primitivas en
qiskit.primitivescon lasBaseSamplerV2yBaseEstimatorV2clases abstractas. Esta nueva versión de la interfaz añade soporte para realizar llamadas vectorizadas a la primitiva, de forma que se puedan especificar de forma eficiente barridos sobre conjuntos de valores de parámetros y observables.- Un nuevo analizador sintáctico nativo experimental OpenQASM 3
qiskit.qasm3.loads_experimental()yqiskit.qasm3.load_experimental(). Este nuevo analizador sintáctico está aún en fase de desarrollo, presenta varias limitaciones y es todavía experimental. Sin embargo, para donde es utilizable, el nuevo analizador sintáctico es significativamente más rápido y tiene un mejor mensaje de error de diagnóstico que permite depurar donde un programa OpenQASM 3 no es válido. Este nuevo analizador sintáctico está escrito en Rust y se basa en una biblioteca de Rust recientemente desarrollada para analizar OpenQASM3 que puede encontrarse aquí: https://github.com/Qiskit/openqasm3_parser
Por último, el lanzamiento de Qiskit 1.0.0 fue una oportunidad para limpiar algunas deudas técnicas acumuladas durante los últimos 7 años de desarrollo. Observará que la versión de Qiskit 1.0.0 prácticamente no emite DeprecationWarnings y, al mismo tiempo, la sección de actualización de las notas de la versión 1.0.0 es más larga de lo habitual. Son consecuencias directas de la limpieza de la deuda técnica. Para ayudar con la migración de 0.46.x a 1.0.0, además de las notas de la versión, también hemos publicado una guía de migración dedicada que se puede encontrar aquí:
Qiskit 1.0 cambios en las funciones
Esta guía pretende complementar las notas de la versión y ofrecer consejos específicos sobre cómo migrar los cambios de la API tras la eliminación de la funcionalidad obsoleta de la versión 0.46.0.
Características de los circuitos
-
Se ha añadido un nuevo argumento,
annotated, a los métodosQuantumCircuit.inverse(),circuit.Instruction.inverse()y.inverse()de las subclasesInstruction(comoSwapGateoSGate) para devolver opcionalmente unAnnotatedOperation. El valor por defecto deannotatedesFalsey corresponde al comportamiento preexistente del método. Además, para las puertas estándar con un métodoinversedefinido explícitamente, el argumentoannotatedno tiene ningún efecto, por ejemplo, ambos:SwapGate().inverse(annotated=False) SwapGate().inverse(annotated=True)devolver a
SwapGatey ambos:SGate().inverse(annotated=False) SGate().inverse(annotated=True)devolver un
SdgGate. La diferencia se manifiesta para las instrucciones personalizadas sin una inversa definida explícitamente. Conannotated=False, el método devuelve una nueva instrucción con la definición invertida recursivamente, igual que antes. Mientras queannotated=Truedevuelve unAnnotatedOperationque representa la instrucción modificada con la instrucciónInverseModifier. -
Añadida una biblioteca de conmutación al
CommutationChecker. Esta biblioteca almacena todas las relaciones de conmutación de puertas estándar no parametrizables en un diccionario que permite una búsqueda eficiente en tiempo de ejecución. Esto acelera la ejecución de la claseCommutationCheckery, por extensión, delCommutationAnalysisya que en lugar de calcular si dos puertas estándar no parametrizables conmutan sólo tiene que buscarlo en la biblioteca.Además, el
CommutationCheckerse ha refactorizado y ahora tiene un límite superior establecido en el número de relaciones de conmutación almacenadas en caché que no están en la biblioteca de conmutación. Esto abordó: #8020 y #7101 -
QuantumCircuit.assign_parameters()ahora acepta claves de cadena en la forma de mapeo de entrada. Estos nombres se utilizan para buscar la instancia correspondienteParametercorrespondiente utilizandoget_parameter(). Esto te permite hacer:from qiskit.circuit import QuantumCircuit, Parameter a = Parameter("a") qc = QuantumCircuit(1) qc.rx(a, 0) qc.assign_parameters({"a": 1}) == qc.assign_parameters({a: 1}) -
QuantumCircuittiene dos nuevos métodosget_parameter()yhas_parameter()que recuperan respectivamente una instanciaParameterinstancia utilizada en el circuito por su nombre, y devuelven un booleano de si un parámetro con un nombre coincidente (o la instancia exacta dada) se utiliza en el circuito. -
A
uuidpropiedad a la claseqiskit.circuit.Parameterclase. En casos de uso avanzado, esta propiedad puede utilizarse para crearqiskit.circuit.Parameterinstancias iguales entre sí. -
Se ha añadido un nuevo método
ParameterExpression.numeric()que convierte una expresión de parámetro completamente ligada en el tipo numérico incorporado Python más restrictivo que describa con precisión el resultado de la evaluación simbólica. Por ejemplo, un número entero simbólico se convertirá en unintmientras que un número real simbólico se convertirá en unfloaty un número complejo se convertirá encomplex. Este método incluye varias soluciones para las peculiaridades de los contextos de evaluación desymengine, que a veces pueden dar lugar a resultados falsos al llamar acomplexofloatsobre una expresión directamente.
Características primitivas
-
La versión 2 de las primitivas se introduce a través de una nueva clase base tanto para el muestreador como para el estimador, junto con nuevos tipos para sus entradas y salidas. El énfasis de esta nueva versión está en realizar llamadas vectorizadas a los métodos primitivos de
run(), de forma que los barridos sobre conjuntos de valores de parámetros y observables puedan ser especificados eficientemente. VéaseStatevectorSampleryStatevectorEstimatorpara las implementaciones de referencia de las primitivas V2.Además, el estimador ha ganado un argumento
precisionen el métodorun()que especifica la precisión deseada de las estimaciones del valor de la expectativa. De forma análoga, el muestreador ha desplazadoshotsde las opciones a los argumentos del métodorun()método. También se ha modificado el muestreador para que devuelva las salidas (por ejemplo, cadenas de bits) de cada disparo, en lugar de proporcionar unCounts-como retorno, y también para almacenar datos de distintosClassicalRegisters. Esto permite a las clases derivadas implementar soporte sampler para circuitos con flujo de control clásico.Las clases base primitivas de V2 son:
Los nuevos tipos que se utilizan para las entradas y salidas son:
SamplerPubLikebloque unificado primitivo ( PUB ) de entradas de muestreador; un tipo de unión de entradas permitidas para un muestreadorEstimatorPubLike: Bloque unificado primitivo ( PUB ) de entradas del estimador; un tipo de unión de entradas permitidas para un estimadorPubResultlos datos y metadatos resultantes de la ejecución de un único PUBDataBin: Un espacio de nombres para guardar los datos de la ejecución de un único PUBBitArrayuna colección de valores de bits en forma de matriz con un formato densoPrimitiveResultun iterable dePubResults junto con metadatos
-
La aplicación de referencia
StatevectorEstimatordeBaseEstimatorV2se ha añadido. Como se ve en el ejemplo siguiente, este estimador (y todos los estimadores de V2 ) admite proporcionar matrices de observables y/o matrices de conjuntos de valores de parámetros que se adjuntan a circuitos concretos.Cada tupla de
(circuit, observables, <optional> parameter values, <optional> precision), denominada bloque unificado primitivo del estimador ( PUB ), produce su propio resultado basado en matrices. El métodorun()se puede aplicar a muchos bares a la vez.from qiskit.circuit import Parameter, QuantumCircuit from qiskit.primitives import StatevectorEstimator from qiskit.quantum_info import Pauli, SparsePauliOp import matplotlib.pyplot as plt import numpy as np # Define a circuit with two parameters. circuit = QuantumCircuit(2) circuit.h(0) circuit.cx(0, 1) circuit.ry(Parameter("a"), 0) circuit.rz(Parameter("b"), 0) circuit.cx(0, 1) circuit.h(0) # Define a sweep over parameter values, where the second axis is over # the two parameters in the circuit. params = np.vstack([ np.linspace(-np.pi, np.pi, 100), np.linspace(-4 * np.pi, 4 * np.pi, 100) ]).T # Define three observables. Many formats are supported here including # classes such as qiskit.quantum_info.SparsePauliOp. The inner length-1 # lists cause this array of observables to have shape (3, 1), rather # than shape (3,) if they were omitted. observables = [ [SparsePauliOp(["XX", "IY"], [0.5, 0.5])], [Pauli("XX")], [Pauli("IY")] ] # Instantiate a new statevector simulation based estimator object. estimator = StatevectorEstimator() # Estimate the expectation value for all 300 combinations of # observables and parameter values, where the pub result will have # shape (3, 100). This shape is due to our array of parameter # bindings having shape (100,), combined with our array of observables # having shape (3, 1) pub = (circuit, observables, params) job = estimator.run([pub]) # Extract the result for the 0th pub (this example only has one pub). result = job.result()[0] # Error-bar information is also available, but the error is 0 # for this StatevectorEstimator. result.data.stds # Pull out the array-based expectation value estimate data from the # result and plot a trace for each observable. for idx, pauli in enumerate(observables): plt.plot(result.data.evs[idx], label=pauli) plt.legend() -
La aplicación de referencia
StatevectorSamplerdeBaseSamplerV2se ha añadido. Como se puede ver en el ejemplo siguiente, este muestreador (y todos los muestreadores de V2 ) permite proporcionar matrices de conjuntos de valores de parámetros para vincularlos a un único circuito.Cada tupla de
(circuit, <optional> parameter values, <optional> shots), denominada bloque unificado primitivo de muestreo ( PUB ), produce su propio resultado basado en matrices. El métodorun()se puede aplicar a muchos bares a la vez.from qiskit.circuit import ( Parameter, QuantumCircuit, ClassicalRegister, QuantumRegister ) from qiskit.primitives import StatevectorSampler import matplotlib.pyplot as plt import numpy as np # Define our circuit registers, including classical registers # called 'alpha' and 'beta'. qreg = QuantumRegister(3) alpha = ClassicalRegister(2, "alpha") beta = ClassicalRegister(1, "beta") # Define a quantum circuit with two parameters. circuit = QuantumCircuit(qreg, alpha, beta) circuit.h(0) circuit.cx(0, 1) circuit.cx(1, 2) circuit.ry(Parameter("a"), 0) circuit.rz(Parameter("b"), 0) circuit.cx(1, 2) circuit.cx(0, 1) circuit.h(0) circuit.measure([0, 1], alpha) circuit.measure([2], beta) # Define a sweep over parameter values, where the second axis is over. # the two parameters in the circuit. params = np.vstack([ np.linspace(-np.pi, np.pi, 100), np.linspace(-4 * np.pi, 4 * np.pi, 100) ]).T # Instantiate a new statevector simulation based sampler object. sampler = StatevectorSampler() # Start a job that will return shots for all 100 parameter value sets. pub = (circuit, params) job = sampler.run([pub], shots=256) # Extract the result for the 0th pub (this example only has one pub). result = job.result()[0] # There is one BitArray object for each ClassicalRegister in the # circuit. Here, we can see that the BitArray for alpha contains data # for all 100 sweep points, and that it is indeed storing data for 2 # bits over 256 shots. assert result.data.alpha.shape == (100,) assert result.data.alpha.num_bits == 2 assert result.data.alpha.num_shots == 256 # We can work directly with a binary array in performant applications. raw = result.data.alpha.array # For small registers where it is anticipated to have many counts # associated with the same bitstrings, we can turn the data from, # for example, the 22nd sweep index into a dictionary of counts. counts = result.data.alpha.get_counts(22) # Or, convert into a list of bitstrings that preserve shot order. bitstrings = result.data.alpha.get_bitstrings(22) print(bitstrings)
Características de los proveedores
-
Añadida una nueva clase
GenericBackendV2al móduloqiskit.providers.fake_providermódulo. Esta clase es configurable, y construye unBackendV2que puede ejecutarse localmente (en el espíritu de los falsos backends). Los usuarios pueden configurar el número de qubits, las puertas base, el mapa de acoplamiento, la capacidad de ejecutar circuitos dinámicos (instrucciones de flujo de control), las calibraciones de las instrucciones y el paso de tiempo de medición del backend sin tener que ocuparse de la construcción manual de objetivos. Las propiedades del Qubit y de la puerta (duración, error) se generan mediante muestreo aleatorio a partir de rangos predeterminados. La semilla para esta generación aleatoria puede fijarse para garantizar la reproducibilidad de la salida del backend. Es importante tener en cuenta que este backend sólo admite puertas en la biblioteca estándar. Si necesitas un backend más flexible, siempre existe la opción de instanciar directamente un objetoTargetpara utilizarlo en la transpilación.Ejemplo de uso 1:
from qiskit import QuantumCircuit, transpile from qiskit.providers.fake_provider import GenericBackendV2 # Create a simple circuit circuit = QuantumCircuit(3) circuit.h(0) circuit.cx(0,1) circuit.cx(0,2) circuit.measure_all() circuit.draw('mpl') # Define backend with 3 qubits backend = GenericBackendV2(num_qubits=3) # Transpile and run transpiled_circuit = transpile(circuit, backend) result = backend.run(transpiled_circuit).result()Ejemplo de uso 2:
from qiskit import QuantumCircuit, ClassicalRegister, transpile from qiskit.providers.fake_provider import GenericBackendV2 # Create a circuit with classical control creg = ClassicalRegister(19) qc = QuantumCircuit(25) qc.add_register(creg) qc.h(0) for i in range(18): qc.cx(0, i + 1) for i in range(18): qc.measure(i, creg[i]) with qc.if_test((creg, 0)): qc.ecr(20, 21) # Define backend with custom basis gates and control flow instructions backend = GenericBackendV2( num_qubits=25, basis_gates=["ecr", "id", "rz", "sx", "x"], control_flow=True, ) #Transpile transpiled_qc = transpile(qc, backend)NotaLas propiedades de ruido generadas por esta clase no imitan ningún dispositivo cuántico concreto, y no deben utilizarse para medir ningún comportamiento concreto. Se trata de "valores predeterminados razonables" que pueden utilizarse para probar la funcionalidad de interconexión con el backend y que no están vinculados a valores de ruido específicos de sistemas cuánticos reales. Para una simulación más precisa de los dispositivos existentes, puede construir manualmente un modelo de ruido a partir del backend real utilizando la funcionalidad ofrecida en
qiskit_aer. -
El módulo
qiskit.providers.fake_providermódulo incluye ahora una serie de falsos backends genéricos que siguen laBackendV1interfaz. Se han introducido como alternativa a los falsos backends basados en instantáneas expuestos en el obsoletoFakeProvider(FakeVigo,FakeTokyo, etc). La lista de nuevos backends falsos incluye:-
Backends sin capacidad de pulso:
-
Backends con capacidades de pulso:
Pueden importarse siguiendo el patrón:
from qiskit.providers.fake_provider import Fake5QV1. Puede encontrar más detalles sobre las propiedades de backend en la documentación de la API de cada backend. -
OpenQASM Características
-
El paquete
qiskit.qasm3contiene ahora un analizador integrado basado en Rust para leer programas OpenQASM 3 enQuantumCircuits, que se encuentra enqiskit.qasm3.load_experimental()yloads_experimental(). Suelen ser varias veces más rápidas que las existentes y puras Pythonload()yloads()que, además, requieren la instalación deqiskit-qasm3-import.Por ejemplo, podemos crear un enredo de 20.000 instrucciones
QuantumCircuit:import numpy as np import qiskit.qasm3 from qiskit.circuit.library import RealAmplitudes qc = RealAmplitudes(100, reps=100, flatten=True) qc = qc.assign_parameters(np.random.rand(qc.num_parameters)) oq3 = qiskit.qasm3.dumps(qc)El antiguo
qasm3.loads()tardaba aproximadamente 7.3s en cargar el programa OpenQASM 3 resultante, mientras queqasm3.loads_experimental()tardó menos de 300ms en un Macbook Pro de consumo ( i7, 2020)-¡una aceleración de 25x!El conjunto de características soportadas por el analizador experimental es muy limitado en esta versión preliminar, pero se irá ampliando a medida que mejoren tanto Qiskit como el analizador nativo basado en Rust.
Uno de nuestros principales objetivos con este nuevo analizador sintáctico, además de las enormes mejoras de velocidad, es ofrecer un diagnóstico de errores de máxima calidad. Al igual que con otras partes del analizador, se trata de un trabajo en curso, pero empezarás a ver mensajes de error de mucha más calidad cuando analices programas no válidos de OpenQASM 3 con el analizador experimental.
-
El exportador OpenQASM 3 (véase
dump()ydumps()enqiskit.qasm3) soporta ahora por defecto la sintaxis estabilizada de la sentenciaswitchen OpenQASM 3. La sintaxis previa a la certificación de la declaraciónswitchsigue estando disponible utilizando la banderaExperimentalFeatures.SWITCH_CASE_V1en el argumentoexperimentaldel exportador. Para la sintaxis estabilizada no se requiere ningún indicador de función, pero si está interactuando con otras herramientas que aún no están actualizadas, puede que necesite pasar el indicador experimental.La sintaxis de la forma estabilizada es ligeramente diferente en lo que respecta a la terminación de las sentencias
break(ya no es necesaria ni está permitida), y los casos múltiples se combinan ahora en una única líneacase, en lugar de utilizar el fall-through al estilo C. Para más detalles, consulte la documentación de OpenQASM 3 sobre la construcción switch-case.
Características de QPY
-
Añadida una nueva clase de aviso,
QPYLoadingDeprecatedFeatureWarningal módulo QPY. Esta clase permite que las advertencias de desaprobación aparezcan incluso si se accede a la función desaprobada en un punto variable de la pila de llamadas, como es el caso de muchas funciones de carga de QPY que se llaman de forma recursiva. -
Se ha añadido un nuevo indicador,
version, a la funciónqpy.dump()función Esto permiteqpy.dump()tomar opcionalmente un valor entero para la versión del formato QPY a emitir. Esto es útil si necesitas generar un archivo QPY que será cargado por una versión anterior de Qiskit. Sin embargo, las versiones soportadas para emitir son limitadas, sólo se pueden utilizar versiones entre la última versión QPY (que es la predeterminada), y la versión QPY de compatibilidad que es la Versión 10 (que se introdujo en Qiskit 0.45.0 ). La versión de compatibilidad permanecerá fija durante toda la serie de versiones principales de 1.x.y. Esto no cambia las garantías de compatibilidad con versiones anteriores del formato QPY al llamar aqpy.load()sólo permite a los usuarios emitir una versión anterior de QPY para mantener la compatibilidad y la interoperabilidad entre las series de versiones 0.x y 1.x.
Características de la información cuántica
-
Se ha añadido un
qiskit.quantum_info.StabilizerState.from_stabilizer_list()que genera un estado estabilizador a partir de una lista de estabilizadores:from qiskit.quantum_info import StabilizerState stabilizer_list = ["ZXX", "-XYX", "+ZYY"] stab = StabilizerState.from_stabilizer_list(stabilizer_list) -
SparsePauliOp.from_operator()utiliza ahora una implementación del "algoritmo tensorizado de descomposición de Pauli" presentado en Hatznko, Binkowski y Gupta (2023). El método es ahora varios órdenes de magnitud más rápido; por ejemplo, es posible descomponer un operador aleatorio de 10 qubits en alrededor de 250ms en un Macbook Pro de consumo (Intel i7, 2020).
Características de síntesis
-
Se ha añadido una
qiskit.synthesis.synth_circuit_from_stabilizers()que devuelve un circuito que produce el estado estabilizado por una serie de estabilizadores dados. -
El método del plugin de síntesis unitaria AQC utiliza ahora por defecto una evaluación más rápida de la función objetivo, lo que se traduce en una mejora sustancial del tiempo de síntesis.
-
Añade un nuevo método de síntesis
synth_qft_line()de un circuito QFT para conectividad lineal de vecino más cercano, que reduce significativamente el número de SWAPs para grandes cantidades de qubits en comparación con SABRE. -
La clase
TwoQubitWeylDecompositionse ha añadido a la API pública enqiskit.synthesis. Esta clase permite aplicar la descomposición de Weyl de unitarios de dos qubits. Si anteriormente importaba esto cuando era una clase no pública en el móduloqiskit.quantum_info.synthesis, ahora eliminado, debe actualizar sus rutas de importación.
Características del transpilador
-
Añadida una nueva clase de excepción:
InvalidLayoutError. Se trata de una subclaseTranspilerErrorque se activa cuando un diseño proporcionado por el usuario no es válido (tamaño incorrecto, qubits duplicados, etc.). -
Se ha añadido un nuevo argumento de palabra clave,
num_processes, atranspile()y al métodoPassManager.run()método. Esto permite anular tantoQISKIT_NUM_PROCScomo el camponum_processesen los archivos de configuración del usuario para cada transpile. Por ejemplo:from qiskit import transpile, QuantumCircuit qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) qc.measure_all() transpile([qc]*10, basis_gates=['u', 'cz'], num_processes=2)ejecutará el transpile sobre los 10 circuitos de entrada utilizando sólo 2 procesos y anulará el valor predeterminado del sistema, la variable de entorno o el archivo de configuración del usuario para esa
transpile()llamada. -
Añadido un nuevo transpiler pass,
OptimizeAnnotatedque optimiza las operaciones anotadas en un circuito cuántico.Consulte el ejemplo siguiente:
from qiskit.circuit import QuantumCircuit from qiskit.circuit.annotated_operation import ( AnnotatedOperation, InverseModifier, ControlModifier, ) from qiskit.circuit.library import CXGate, SwapGate from qiskit.transpiler.passes import OptimizeAnnotated # Create a quantum circuit with multiple annotated gates gate1 = AnnotatedOperation( SwapGate(), [InverseModifier(), ControlModifier(2), InverseModifier(), ControlModifier(1)], ) gate2 = AnnotatedOperation( SwapGate(), [InverseModifier(), InverseModifier()] ) gate3 = AnnotatedOperation( AnnotatedOperation(CXGate(), ControlModifier(2)), ControlModifier(1) ) qc = QuantumCircuit(6) qc.append(gate1, [3, 2, 4, 0, 5]) qc.append(gate2, [1, 5]) qc.append(gate3, [5, 4, 3, 2, 1]) # Optimize the circuit using OptimizeAnnotated transpiler pass qc_optimized = OptimizeAnnotated()(qc) # This is how the optimized circuit should look like gate1_expected = AnnotatedOperation(SwapGate(), ControlModifier(3)) gate2_expected = SwapGate() gate3_expected = AnnotatedOperation(CXGate(), ControlModifier(3)) qc_expected = QuantumCircuit(6) qc_expected.append(gate1_expected, [3, 2, 4, 0, 5]) qc_expected.append(gate2_expected, [1, 5]) qc_expected.append(gate3_expected, [5, 4, 3, 2, 1]) assert qc_optimized == qc_expectedEn el caso de
gate1, los modificadores de la puerta de intercambio anotada se llevan a la forma canónica: las dosInverseModifiers se anulan, y los dosControlModifiers se combinan. En el caso degate2, se eliminan todos los modificadores y la operación anotada se sustituye por su operación base. En el caso degate3, se combinan varias capas de anotaciones en una sola.El constructor del
OptimizeAnnotatedpass acepta argumentos opcionalestarget,equivalence_library,basis_gatesyrecurse. CuandorecurseesTrue(el valor por defecto) y cuando se especificatargetobasis_gates, el pase desciende recursivamente a los circuitosdefinitionde la puerta, con la excepción de las puertas que ya están soportadas por el objetivo o que pertenecen a la biblioteca de equivalencias. Por otra parte, cuando no se especifican nitargetnibasis_gates, o cuandorecursese establece enFalse, el pase sintetiza sólo las operaciones anotadas de "nivel superior", es decir, no desciende recursivamente a los circuitosdefinition. Este comportamiento es coherente con el delHighLevelSynthesisque necesita ser llamado para "desenrollar" las operaciones anotadas en puertas de 1qubit y 2qubits. -
Se ha añadido un nuevo
HighLevelSynthesisPluginparaPermutationGatebasado en el algoritmo de intercambio de tokens de Qiskit. Para utilizar este complemento, especifiquetoken_swapperal definir la configuración de síntesis de alto nivel.Este plugin de síntesis puede ejecutarse antes o después de establecer el diseño. Cuando la síntesis tiene éxito, el plugin produce un circuito cuántico formado únicamente por puertas de intercambio. Cuando la síntesis no tiene éxito, el plugin emite
None.El siguiente código ilustra cómo puede ejecutarse el nuevo plugin:
from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import PermutationGate from qiskit.transpiler import PassManager, CouplingMap from qiskit.transpiler.passes.synthesis.high_level_synthesis import HighLevelSynthesis, HLSConfig # This creates a circuit with a permutation gate. qc = QuantumCircuit(8) perm_gate = PermutationGate([0, 1, 4, 3, 2]) qc.append(perm_gate, [3, 4, 5, 6, 7]) # This defines the coupling map. coupling_map = CouplingMap.from_ring(8) # This high-level-synthesis config specifies that we want to use # the "token_swapper" plugin for synthesizing permutation gates, # with the option to use 10 trials. synthesis_config = HLSConfig(permutation=[("token_swapper", {"trials": 10})]) # This creates the pass manager that runs high-level-synthesis on our circuit. # The option use_qubit_indices=True indicates that synthesis is run after the layout is set, # and hence should preserve the specified coupling map. pm = PassManager( HighLevelSynthesis( synthesis_config, coupling_map=coupling_map, target=None, use_qubit_indices=True ) ) qc_transpiled = pm.run(qc) -
Añadidos dos nuevos argumentos,
matrix_basedymax_qubits, al constructor delCommutativeInverseCancellationtranspiler pass. Cuandomatrix_basedesTrue, el pase utiliza representaciones matriciales para comprobar si dos operaciones son la inversa de la otra. Esto hace que las comprobaciones sean más potentes y, además, permite anular pares de operaciones que son inversas hasta una fase, al tiempo que se actualiza la fase global del circuito en consecuencia. Por lo general, esto conlleva más reducciones a costa de un mayor tiempo de ejecución. El argumentomax_qubitslimita el número de qubits en las comprobaciones de conmutatividad e inversa basadas en matrices. Por ejemplo:import numpy as np from qiskit.circuit import QuantumCircuit from qiskit.transpiler import PassManager from qiskit.transpiler.passes import CommutativeInverseCancellation circuit = QuantumCircuit(1) circuit.rz(np.pi / 4, 0) circuit.p(-np.pi / 4, 0) passmanager = PassManager(CommutativeInverseCancellation(matrix_based=True)) new_circuit = passmanager.run(circuit)El paso consigue anular las compuertas
RZyP, al tiempo que ajusta la fase global del circuito a . -
Se ha añadido una nueva función,
high_level_synthesis_plugin_names()que puede utilizarse para obtener la lista de plugins de síntesis de alto nivel instalados para un nombre de operación dado.
Funciones de visualización
-
Las salidas
textymplpara elQuantumCircuit.draw()ycircuit_drawer()mostrarán ahora información detallada para las operaciones deAnnotatedOperation. Si la direcciónAnnotatedOperation.modifierscontiene unControlModifierla operación se mostrará del mismo modo que las puertas controladas. Si elInverseModifieroPowerModifierse indicarán con el nombre de la operación base. Por ejemplo:from qiskit.circuit import ( AnnotatedOperation, ControlModifier, PowerModifier, InverseModifier, QuantumCircuit ) from qiskit.circuit.library import SGate annotated_op = AnnotatedOperation(SGate(), [PowerModifier(3.4), ControlModifier(3), InverseModifier()]) qc = QuantumCircuit(4) qc.append(annotated_op, range(4)) qc.draw("mpl")
Herramientas Opciones
-
Añadida una nueva clase base de advertencia,
QiskitWarning. Aunque Qiskit seguirá utilizando las advertencias integradas en Python (comoDeprecationWarning) cuando sean las más apropiadas, para los casos más específicos de Qiskit, las advertencias serán subclases deQiskitWarning. -
Los comprobadores de funcionalidad opcional (
qiskit.utils.optionals) distinguirán ahora una dependencia opcional que no se ha encontrado en absoluto (una situación normal) de otra que sí se ha encontrado, pero que ha provocado errores durante su importación. En este último caso, ahora emitirán unOptionalDependencyImportWarninginformándole de lo sucedido, ya que podría indicar una instalación fallida o una versión incompatible.
Notas de actualización
-
Qiskit 1.0 requiere ahora la versión 0.14.0 de
rustworkx. La versión mínima requerida se ha aumentado para soportar el nuevo plugin de síntesistoken_swapperPermutationGatede síntesis paraHighLevelSynthesisPlugin. -
La versión mínima de Rust soportada para construir Qiskit desde el código fuente es ahora 1.70. Esto se ha incrementado desde la anterior versión mínima soportada de Rust de 1.64 en las series de versiones de Qiskit 0.45.x y 0.46.0.
-
Se ha eliminado la dependencia de psutil. Anteriormente, la biblioteca psutil sólo se utilizaba para detectar el número de CPU físicas y la memoria total del sistema, sin embargo, esta información proporcionada no añade suficiente valor para justificar las dependencias adicionales y la sobrecarga, por lo que se ha eliminado. Esto significa que el número predeterminado de procesos utilizados por
parallel_map()y las funciones que internamente pueden utilizarparallel_map()comotranspile()yPassManager.run()pueden utilizar más o menos procesos paralelos que en versiones anteriores. Si quieres ajustar el número de procesos usados puedes usar el nuevo argumentonum_processespara esas funciones, o la variable de entornoQISKIT_NUM_PROCSo el camponum_processesen un archivo de configuración de usuario (ver la guía de configuración local para más detalles) si necesitas ajustar el número de procesos que Qiskit usa potencialmente. -
Se han eliminado los métodos
scoped_parametersysearch_parametersde la claseScheduleBlockclase. Estos métodos devolvíanParameterobjetos parcialmente vinculados a los parámetros de laScheduleBlockpero la asignación de valores mediante estos objetos no funcionaba correctamente. Los usuarios deben utilizarScheduleBlock.parameterse iterar a través deScheduleBlock.referencesy comparar con los atributosSchedule.parametersde las subreferencias cuando necesiten distinguir en qué subrutina se utiliza un parámetro. Ver #11654 para más información. -
Eliminada la lógica para inyectar
QuantumCircuityGateen el contexto del pulso (como enpulse.builder.call()), que era un comportamiento heredado obsoleto en Qiskit 0.46. Los programas de pulsos deben construirse como un contexto de programa completo; los circuitos y las puertas son un nivel superior de abstracción.Esto incluye la eliminación de las funciones relacionadas:
pulse.builder.call_gatepulse.builder.cxpulse.builder.u1pulse.builder.u2pulse.builder.u3pulse.builder.xpulse.builder.active_transpiler_settingspulse.builder.active_circuit_scheduler_settingspulse.builder.transpiler_settingspulse.builder.circuit_scheduler_settings
Los argumentos
default_transpiler_settingsydefault_circuit_scheduler_settingsdepulse.builder.build()se eliminan de forma similar.from qiskit import transpile, schedule, QuantumCircuit, pulse from qiskit.providers.fake_provider import Fake7QPulseV1 backend = Fake7QPulseV1() # Create a schedule from a hardware-based circuit. qc = QuantumCircuit(2) qc.cx(0, 1) qc = transpile(qc, backend) sched = schedule(qc, backend) # These pulse schedules can still be called in builder contexts. with pulse.build(backend) as qc_sched: pulse.call(sched) # Schedules for certain operations can also be directly retrieved # from BackendV1 instances: sched = backend.defaults().instruction_schedule_map.get('x', (0,)) # ... and from BackendV2 instances: sched = backend.target['x'][(0,)].calibration -
La versión mínima requerida para symengine ha pasado a ser >= 0.11.
Notas sobre la actualización de circuitos
-
Eliminado el método
Instruction.qasm, obsoleto en Qiskit 0.45.0. Utiliceqiskit.qasm2.dump()con unQuantumCircuiten su lugar. -
Se eliminan las propiedades
Bit.registeryBit.index. Quedaron obsoletos en Qiskit 0.25 (publicado en 2021-04). Los qubits y los bits viven ahora sólo en el contexto de unQuantumCircuit. La alternativa a las propiedades es utilizarQuantumCircuit.find_bit()para encontrar todos los registros que contienen un circuito y el índice del bit dentro del circuito. -
El método
QuantumCircuit.bind_parametersha sido eliminado, tras su desaprobación en Qiskit 0.45. Puede utilizarQuantumCircuit.assign_parameters()como un reemplazo directo con todos sus valores predeterminados, y también expone características adicionales sobre el método antiguo. -
La importación de
Int1,Int2,BooleanFunction,classical_function()desdeqiskit.circuitestá desactivada. En su lugar, importe los objetos del submóduloqiskit.circuit.classicalfunctionque requiere el paquetetweedledum. -
Los atributos de sólo datos
headeryextension_libdeQuantumCircuitse eliminan tras su desaparición en Qiskit 0.45. Se trataba de datos internos del exportador OpenQASM 2 que ya no se utilizan. -
Se ha eliminado el módulo
qiskit.extensions, que ha estado pendiente de eliminación desde la versión 0.45 y ha quedado totalmente obsoleto en la versión 0.46. Las siguientes operaciones de este módulo están disponibles enqiskit.circuit.library:DiagonalGate,HamiltonianGateGate,Initialize,Isometry,MCGupDiag,UCGate,UCPauliRotGate,UCRXGate,UCRYGate,UCRZGate,UnitaryGate.
Se han eliminado los siguientes objetos:
SingleQubitUnitary(utilice en su lugarlibrary.UnitaryGate),Snapshot(sustituido por las instrucciones de guardado de Aer),ExtensionError,
junto con los siguientes métodos de circuito:
QuantumCircuit.snapshot,QuantumCircuit.squ,QuantumCircuit.diagonal,QuantumCircuit.hamiltonian,QuantumCircuit.isometryyQuantumCircuit.iso,QuantumCircuit.uc,QuantumCircuit.ucrx,QuantumCircuit.ucry,QuantumCircuit.ucrz.
Estas operaciones pueden seguir realizándose añadiendo la instrucción adecuada a un circuito cuántico.
-
Se han eliminado métodos
QuantumCircuitduplicados. Esto incluye:QuantumCircuit.cnot, en su lugar utilizaQuantumCircuit.cx(),QuantumCircuit.toffoli, en su lugar utilizaQuantumCircuit.ccx(),QuantumCircuit.fredkin, en su lugar utilizaQuantumCircuit.cswap(),QuantumCircuit.mct, en su lugar utilizaQuantumCircuit.mcx(),QuantumCircuit.iutilice en su lugarQuantumCircuit.id().
-
Ya no se puede establecer
QuantumCircuit.metadatapara que seaNone, tras la desaparición de Qiskit 0.43.0. Su tipo esdictpor lo que, para borrarlo, hay que ponerlo en{}. -
El atributo
.Register.name_formatse ha eliminado tras su desaparición en Qiskit 0.40.0. Ya no existe ninguna restricción para los nombres de registro, y la expresión regular era simplemente[a-z][a-zA-Z0-9_]*.
Notas sobre la actualización de primitivas
- Añadida la
BasePrimitiveJobclase como una clase abstracta de trabajo para primitivas y hechoPrimitiveJobheredarBasePrimitiveJoben lugar deJobV1.
Notas de actualización para proveedores
-
Cambiado el valor por defecto de dos argumentos (
add_delayyfilter_faulty) en la funciónconvert_to_target()función Esta función de conversión ahora añade instrucciones de retardo y elimina las instrucciones defectuosas por defecto. -
En
BackendPropertiesyPulseDefaultsutilizados por elFakeOpenPulse2Qse han actualizado para ser coherentes internamente y añadir las instrucciones que faltan. Si confiaba en los objetos del modelo anterior como objetivo de compilación, puede utilizar el backend con Qiskit 0.46 y exportar un archivoQuantumCircuitgenerado contranspile()y serializarlo usandoqpy.dumppara acceder a él en esta versión. -
El módulo
qiskit.providers.basicaer, expuesto comoqiskit.BasicAer, ha sido eliminado tras su desaparición en la versión 0.46. Su funcionalidad ha sido sustituida por el móduloqiskit.quantum_infoy el nuevo móduloqiskit.providers.basic_providermódulo.La migración de la utilización de
qiskit.providers.basicaer(qiskit.BasicAer) aqiskit.providers.basic_providerpuede realizarse del siguiente modo:Migrar deSustituir porqiskit.BasicAerEl nuevo proveedor no tiene una instancia global, las importaciones deben ser de qiskit.providers.basic_providerqiskit.providers.basicaerbasic_providerBasicAerProviderBasicProviderBasicAerJobBasicProviderJobQasmSimulatorPyBasicSimulatorUnitarySimulatorPyutilice OperatorStatevectorSimulatorPyutilice StatevectorUna diferencia notable es que el nuevo proveedor ya no se expone a través de una instancia global (como
BasicAer), por lo que no será válido hacerfrom qiskit import BasicProvider. En su lugar, la clase del proveedor debe importarse desde su submódulo e instanciarse manualmente:from qiskit.providers.basic_provider import BasicProvider provider = BasicProvider() backend = provider.get_backend("basic_simulator")Los siguientes ejemplos muestran las rutas de migración de los tres simuladores en
BasicAer.-
Simulador de vector de estado:
from qiskit import QuantumCircuit qc = QuantumCircuit(3) qc.h(0) qc.h(1) qc.cx(1,2) # Former path from qiskit import BasicAer backend = BasicAer.get_backend("statevector_simulator") statevector = backend.run(qc).result().get_statevector() # New path from qiskit.quantum_info import Statevector statevector = Statevector(qc) -
Simulador unitario:
from qiskit import QuantumCircuit qc = QuantumCircuit(3) qc.h(0) qc.h(1) qc.cx(1,2) # Former path from qiskit import BasicAer backend = BasicAer.get_backend("unitary_simulator") result = backend.run(qc).result() # New path from qiskit.quantum_info import Operator result = Operator(qc).data -
Simulador Qasm:
from qiskit import QuantumCircuit qc = QuantumCircuit(3) qc.h(0) qc.h(1) qc.cx(1,2) qc.measure_all() # Former path from qiskit import BasicAer backend = BasicAer.get_backend("qasm_simulator") result = backend.run(qc).result() # New path from qiskit.providers.basic_provider import BasicProvider backend = BasicProvider().get_backend("basic_simulator") result = backend.run(qc).result() # or, directly from qiskit.providers.basic_provider import BasicSimulator backend = BasicSimulator() result = backend.run(qc).result()
-
-
Eliminada la clase
ConfigurableFakeBackendobsoleta en Qiskit 0.46.0. En su lugar, puede utilizarse unFakeBackendadecuado. -
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
Notas sobre la actualización de Pulse
-
Eliminada la clase obsoleta
qiskit.pulse.instructions.CallNo se proporciona ninguna instrucción de pulso alternativa. -
Eliminados métodos obsoletos en
InstructionToQobjConverteryQobjToInstructionConverter. Esto incluyeInstructionToQobjConverter.convert_acquire()InstructionToQobjConverter.convert_bundled_acquires()InstructionToQobjConverter.convert_set_frequency()InstructionToQobjConverter.convert_shift_frequency()InstructionToQobjConverter.convert_set_phase()InstructionToQobjConverter.convert_shift_phase()InstructionToQobjConverter.convert_delay()InstructionToQobjConverter.convert_play()InstructionToQobjConverter.convert_snapshot()QobjToInstructionConverter.convert_acquire()QobjToInstructionConverter.convert_set_phase()QobjToInstructionConverter.convert_shift_phase()QobjToInstructionConverter.convert_set_frequency()QobjToInstructionConverter.convert_shift_frequency()QobjToInstructionConverter.convert_delay()QobjToInstructionConverter.bind_pulse()QobjToInstructionConverter.convert_parametric()QobjToInstructionConverter.convert_snapshot()
Todos estos métodos públicos se sustituyen por otros protegidos que se llaman implícitamente desde el punto de entrada único, es decir, llamando a la clase como si fuera una función.
-
Se elimina la clase
qiskit.pulse.library.ParametricPulsey todas las subclases. Estos fueron obsoletos desde Qiskit 0.39 (con qiskit-terra 0.22 ), publicado en 2022-10. En su lugar, utiliceSymbolicPulsey consulte su documentación para más detalles.
OpenQASM Notas sobre la actualización
- Los métodos
qasm()de las clasesQuantumRegisteryClassicalRegisterhan sido eliminados. No es necesario sustituirlos; eran un detalle interno de una implementación heredada del exportador OpenQASM 2. Para exportar un programa a OpenQASM 2, utiliceqasm2.dump()oqasm2.dumps().
Notas sobre la actualización de QPY
-
La última versión de formato de QPY es ahora la versión 11 y esto es lo que se emite por defecto al ejecutar
qpy.dump(). -
Se ha eliminado la ruta del módulo
qiskit.circuit.qpy_serialization, tras su desaparición en Qiskit 0.40.0. Para la serialización QPY, utiliceqiskit.qpyque es la nueva ubicación.
Notas sobre la actualización de la información cuántica
-
Eliminados los métodos mágicos obsoletos
__getitem__/__setitem__deClifford. Los métodos fueron obsoletos desde Qiskit 0.44, publicado en 2023-07. En su lugar, indexe o itere a través del atributoClifford.tableau. -
Se ha eliminado el módulo
qiskit.quantum_info.synthesis, obsoleto desde la versión 0.46. Los siguientes objetos se han trasladado aqiskit.synthesis:OneQubitEulerDecomposerse ha trasladado aqiskit.synthesis.one_qubitTwoQubitBasisDecomposerse ha trasladado aqiskit.synthesis.two_qubitsXXDecomposerse ha trasladado aqiskit.synthesis.two_qubitstwo_qubit_cnot_decompose()se ha trasladado aqiskit.synthesis.two_qubits
Esta función se ha eliminado, puesto que ya ha quedado obsoleta en la versión 0.46 : *
cnot_rxx_decomposeEstas funciones se han eliminado, puesto que ya han quedado obsoletas en una versión anterior: *
decompose_clifford(utilicesynth_clifford_full()en su lugar) *decompose_cnotdihedral(utilicesynth_cnotdihedral_full()en su lugar) -
Las funciones
process_fidelity(),average_gate_fidelity(),gate_error()ydiamond_norm()ya no intentarán coaccionar entradas arbitrarias a sus tipos esperados marcados, siguiendo la desaprobación en Qiskit 0.25.0. Pasar entradas de los tipos marcados a cada argumento directamente.
Notas sobre la actualización de Synthesis
-
Las siguientes funciones obsoletas que antes estaban en
qiskit.quantum_infohan sido eliminadas. Estas funciones se marcaron como obsoletas en la versión 2023-01 de Qiskit 0.40.0.decompose_clifforddebe utilizar la funciónqiskit.synthesis.synth_clifford_full()en su lugar.decompose_cnotdihedraldebe utilizar la funciónqiskit.synthesis.synth_cnotdihedral_full()en su lugar.
Notas sobre la actualización del transpilador
-
Se ha eliminado el método obsoleto
Target.aquire_alignment. Se marcó como obsoleto en Qiskit 0.43 (publicado en 2023-05). En su lugar debe utilizarse el métodoTarget.acquire_alignment(). -
Eliminada la función obsoleta
qiskit.transpiler.preset_passmanagers.common.get_vf2_call_limit. En su lugar, utiliceget_vf2_limits(). -
El uso implícito de
approximation_degree!=1.0por defecto en la funcióngenerate_preset_pass_manager()se ha desactivado. El valor predeterminado anterior podría causar aproximaciones indebidas e inesperadas, especialmente en cargas de trabajo que implican Trotterización o ejecuciones similares de operaciones que están cerca, pero decididamente no son iguales, a la identidad.Este cambio hace que los valores por defecto de generación del gestor de pases interno estén en línea con
transpile()que fue siempre la intención. Ver #8595 para más detalles. -
Eliminada la clase
Unrollerobsoleta enqiskit.transpiler.passes.basis. Esta clase fue obsoleta en Qiskit 0.45 y su uso puede ser reemplazado por el uso combinado deBasisTranslatoryUnrollCustomDefinitions.Tenga en cuenta que
BasisTranslatoryUnrollCustomDefinitionstoman argumentos diferentes queUnroller, ya que requieren que se pase un objetoEquivalenceLibrary.Donde antes se podía utilizar
Unroller(basis_gates), ahora se puede utilizar:from qiskit.circuit.library.standard_gates.equivalence_library import ( StandardEquivalenceLibrary as std_eqlib, ) pm = PassManager([ UnrollCustomDefinitions(std_eqlib, basis_gates) BasisTranslator(std_eqlib, basis_gates), ]) translated = pm.run(circuit) -
Se ha eliminado el paso de transpilador
NoiseAdaptiveLayout, que estaba obsoleto. Fue marcado como obsoleto en Qiskit 0.46.0. Este pase ha sido sustituido en gran medida porVF2LayoutyVF2PostLayoutque establece un diseño basado en las características de ruido de un backend. Junto con el pase, se ha eliminado el pluginlayout_method"noise_adaptive". -
Se ha eliminado el paso de transpilador
CrosstalkAdaptiveSchedule, que estaba obsoleto. Se marcó como obsoleto en Qiskit 0.46.0. Este pase ya no se podía utilizar porque su funcionamiento interno dependía de que se establecieran propiedades personalizadas en el archivoBackendPropertiesde una instanciaBackendV1instancia. Como ningún backend establece estos campos, se ha eliminado el pase. Si dependes del pase para un flujo de trabajo personalizado, puedes utilizar la versión en Qiskit 0.46.x. -
Se ha eliminado el módulo
qiskit.transpiler.synthesis, obsoleto desde la versión 0.46. Se han movido los siguientes objetos:qiskit.transpiler.synthesis.aqcse ha trasladado aqiskit.synthesis.unitary.aqc(excepto enqiskit.synthesis.unitary.aqc.AQCSynthesisPlugin).qiskit.synthesis.unitary.aqc.AQCSynthesisPluginse ha trasladado aqiskit.transpiler.passes.synthesis.AQCSynthesisPlugin.qiskit.transpiler.synthesis.graysynth()se ha trasladado aqiskit.synthesis.synth_cnot_phase_aam().qiskit.transpiler.synthesis.cnot_synth()se ha trasladado aqiskit.synthesis.synth_cnot_count_full_pmh().
-
El alias de palabra clave
targetal llamar aTwoQubitBasisDecomposercomo funciones ha sido eliminada tras su desaparición en Qiskit 0.40.0. Debe pasar el argumento posicionalmente como primer argumento, o utilizar el nuevo nombreunitary. -
El pase especializado del transpilador
LinearFunctionsSynthesisse ha eliminado tras su desaprobación en Qiskit 0.40.0. Desde su desaprobación sólo ha sido una envoltura muy delgada alrededor deHighLevelSynthesisque deberías utilizar en su lugar. -
Se elimina la ruta de importación
qiskit.transpiler.passes.scheduling.calibration_creators. El transpilador lo pasa alojado,RZXCalibrationBuilderyRZXCalibrationBuilderNoEchopuede importarse directamente desdeqiskit.transpiler.passes. -
Se elimina la ruta de importación
qiskit.transpiler.passes.scheduling.rzx_templates. Debe importarrzx_templates()deqiskit.transpiler.passesdirectamente. -
Se actualizó un patrón para la construcción de la línea de pie de paso. Se ha eliminado el azúcar sintáctico que se muestra a continuación para la instanciación del controlador de flujo.
from qiskit.transpiler import PassManager pm = PassManager() pm.append(my_pass, condition=condition_callable, do_while=do_while_callable)En lugar de utilizar este patrón de argumento de palabra clave, debe instanciar explícitamente el controlador de flujo.
from qiskit.passmanager import ConditionalController, DoWhileController from qiskit.transpiler import PassManager pm = PassManager() pm.append( ConditionalController( DoWhileController(my_pass, do_while=do_while_callable), condition=condition_callable, ) )Tenga en cuenta que puede gestionar el orden jerárquico de los controladores cuando desee anidarlos, lo que no era posible con los argumentos de palabra clave. También puede construir la tubería con el constructor del gestor de pases como a continuación porque no hay razón para llamar al método append ahora.
pm = PassManager( ConditionalController( DoWhileController(my_pass, do_while=do_while_callable), condition=condition_callable, ) ) -
Se ha eliminado el método append de los reguladores de caudal incorporados. Esto incluye
ConditionalController.appendDoWhileController.appendFlowControllerLinear.append
El canal de tareas en un controlador de flujo está congelado, y debe pasarse cuando se crea la instancia del controlador.
-
Eliminados los métodos
passessdePassManageryStagedPassManagerque devolvían una representación de los pases incluidos en forma de lista de diccionarios. Sin embargo, este formato no representa de forma eficiente una cadena de pases más complicada, que puede incluir bifurcaciones condicionales y condiciones anidadas. En lugar de utilizar esta representación, utilice el siguiente patrónpm = PassManager(...) pm.to_flow_controller().tasksEsto devuelve directamente una base linealizada de instancias de tareas en formato de tupla.
-
Se ha eliminado el argumento
max_iterationdePassManager.append()yPassManager.replace(). -
Las siguientes clases heredadas se han eliminado de los módulos de gestión de pases y transpilador tras su desaparición en Qiskit 0.46:
qiskit.passmanager.flow_controllers.FlowControllerqiskit.transpiler.fencedobjs.FencedObjectqiskit.transpiler.fencedobjs.FencedPropertySetqiskit.transpiler.fencedobjs.FencedDAGCircuitqiskit.transpiler.runningpassmanager.RunningPassManager
Notas sobre la actualización de la visualización
-
El estilo predeterminado para la visualización de circuitos mediante Matplotlib se ha cambiado a
"iqp", en consonancia con la plataforma Quantum IBM. -
Se ha eliminado el módulo obsoleto
qiskit.visualization.qcstyle. Este módulo ha sido marcado como obsoleto desde Qiskit 0.39.0. En su lugar, debe utilizar la direcciónqiskit.visualization.circuit.qcstyle. -
El soporte obsoleto para pasar a
QuasiDistribution,ProbDistributiono un diccionario de distribución al argumentodatade la visualizaciónplot_histogram()ha sido eliminado. Esta funcionalidad se marcó como obsoleta en la versión de Qiskit 0.39.0 (2022-10). En cambio, si desea trazar un histograma a partir de aQuasiDistribution,ProbDistributiono un diccionario de distribución, debe utilizar la funciónplot_distribution()en su lugar. -
Se ha eliminado la clave
link_interval_dtdeQiskitTimelineStyle. Debe utilizar el nuevo nombrelink_interval_percent.
Herramientas Notas de actualización
-
El objeto
qiskit.Aerse ha eliminado tras su desaparición en Qiskit 0.46. En su lugar, puede utilizarqiskit_aer.Aer, que es un sustituto directo. -
La importación desde
qiskit.providers.aerya no funcionará, tras su desaparición en Qiskit 0.46. En su lugar, debe importar desdeqiskit_aer, que es un sustituto directo. -
Las tareas de pulso ya no son compatibles con los backends falsos, tras la eliminación de la funcionalidad de simulación subyacente en Aer. Para la simulación a nivel de pulso, fuera del contexto de los objetos de circuito, considere el uso de una biblioteca de propósito especial como Qiskit Dynamics.
-
Se elimina la función
execute()de Qiskit. Esta función servía como una envoltura de alto nivel para transpilar un circuito con algunas opciones de transpilación y ejecutarlo en un backend con algunas opciones de ejecución. Para hacer lo mismo, puede utilizar explícitamente la funcióntranspile()(con las opciones de transpilación adecuadas) seguida debackend.run()(con las opciones de ejecución adecuadas).Por ejemplo, en lugar de correr:
from qiskit import execute job = execute(circuit, backend)puedes correr:
from qiskit import transpile new_circuit = transpile(circuit, backend) job = backend.run(new_circuit)Alternativamente, la primitiva
Sampleres semánticamente equivalente a la función obsoletaexecute(). La claseBackendSampleres una envoltura genérica para backends que no soportan primitivas:from qiskit.primitives import BackendSampler sampler = BackendSampler(backend) job = sampler.run(circuit) -
Se ha eliminado el objeto obsoleto
qiskit.IBMQ. Este objeto alias se marcó como obsoleto en la versión de Qiskit 0.40.0. Este objeto alias redirige perezosamente el acceso a los atributos aqiskit.providers.ibmq.IBMQ. Dado que el paqueteqiskit-ibmq-providerha sido retirado y sustituido por el paqueteqiskit-ibm-provider, que mantiene su propio espacio de nombres, mantener este alias ya no es relevante. Si utilizaba el aliasqiskit.IBMQ, debe migrar su uso al paqueteqiskit-ibm-provider. Consulte la guía de migración para obtener más información. -
Eliminado el módulo obsoleto
qiskit.tools.jupyterque anteriormente incluía Jupyter magics y widgets para visualizar interactivamente algunos datos de Qiskit. Este módulo quedó obsoleto en Qiskit 0.46.0. La mayor parte de esta funcionalidad estaba directamente vinculada al antiguo paqueteqiskit-ibmq-providery ya no era válida, por lo que se eliminó el módulo. El móduloqiskit_ibm_provider.jupyterdel paquete qiskit-ibm-provider ofrece una funcionalidad similar. -
Eliminado el módulo obsoleto
qiskit.tools.monitorque anteriormente incluía herramientas para rastrearJobV1instancias de trabajo, principalmente del paquete heredadoqiskit-ibm-provider. Este módulo se marcó como obsoleto en Qiskit 0.46.0. Se elimina porque estaba directamente vinculado al paquete heredadoqiskit-ibm-provider. -
Se ha eliminado la ruta de importación obsoleta
qiskit.test.mockque se utilizaba anteriormente para redirigir las importaciones de los backends simulados a su nueva ubicación en el directorioqiskit.providers.fake_provider. Este módulo se marcó como obsoleto en Qiskit 0.37.0. Si estaba utilizando este módulo, debería actualizar sus importaciones deqiskit.test.mockaqiskit.providers.fake_provideren su lugar. -
El módulo
qiskit.testya no es un módulo público. Nunca se pretendió que fuera público, ni que se utilizara fuera del propio conjunto de pruebas de Qiskit. Toda la funcionalidad era específica de Qiskit y no se proporciona ninguna alternativa; si necesitara una funcionalidad similar, debería incluirla en sus propios arneses de prueba. -
Se ha eliminado el módulo obsoleto
qiskit.tools.visualization. Este módulo quedó obsoleto en la versión de Qiskit 0.46.0. Este módulo era una redirección heredada de la ubicación original del módulo de visualización de Qiskit y se trasladó aqiskit.visualizationen Qiskit 0.8.0. Si sigues utilizando esta ruta, puedes actualizar tus importaciones deqiskit.tools.visualizationaqiskit.visualization. -
Se ha eliminado el módulo obsoleto
qiskit.tools.eventsy la correspondiente utilidadqiskit.tools.progressbarque exponía. Quedó obsoleto en la versión de Qiskit 0.46.0. La funcionalidad de este módulo no era muy utilizada y estaba mejor cubierta por paquetes dedicados como tqdm. -
Se ha retirado el módulo
qiskit.tools. Este módulo quedó obsoleto en Qiskit 0.46.0. Se ha eliminado todo el contenido de este módulo excepto la funciónqiskit.tools.parallel_map, que ahora puede utilizarse desdeqiskit.utils.parallel_map()en su lugar.
Primitivas obsoletas
- Los métodos
PrimitiveJob.submit()yPrimitiveJob.wait_for_final_state()se han eliminado tras su desaprobación en Qiskit 0.46. No se pretendía que fueran métodos públicos, sino que eran un legado de una estructura de herencia incorrecta.
Corrección de errores
-
Se ha corregido la devolución de programas de medición inadecuados cuando sólo se solicitaba un subconjunto de qubits. Anteriormente, se devolvía un programa de medición para todos los qubits.
-
Se ha corregido un problema en el cajón de circuitos de
textcuando se mostraban operaciones que no eran decircuit.instruction.Instructionclase. Estas operaciones harían fallar el cajón. EjemplosCliffordyAnnotatedOperation. -
Se ha solucionado un problema con el
SetLayoutpor el que una entrada de lista de enteros no válida que contuviera entradas duplicadas provocaba que se generara unLayouty los siguientes pases del transpilador fallaban con un error críptico. Esto se detecta ahora cuandoSetLayout.run()se produce un errorInvalidLayoutErrorerror indicando que hay entradas duplicadas en la lista de enteros. -
QPY (utilizando
qpy.dump()yqpy.load()) ahora serializará y deserializará correctamente circuitos cuánticos con operaciones anotadas (AnnotatedOperation). -
Llamando a
copy()ocopy_empty_like()enBlueprintCircuitse propagará correctamente la funciónglobal_phasea la copia. Antes, la fase global siempre era cero después de la copia. -
QuantumCircuit.compose()genera ahora correctamente un errorCircuitErrorcuando haya duplicados en los argumentosqubitsoclbits. -
QPY (utilizando
qpy.dump()yqpy.load()) ahora serializará y deserializará correctamente circuitos cuánticos con operadores Clifford (Clifford). -
Se ha corregido un problema en el cajón del circuito
mplpor el que el texto se imprimía más allá del final del cajón para unSwitchCaseOpsi la caja por defecto estaba vacía. -
La emisión de argumentos qubit de
QuantumCircuit.delay()produce ahora correctamente instruccionesDelayinstrucciones para cada qubit, como se pretendía. Anteriormente, cuando se le daban ciertos iterables (comosets), producía silenciosamente un circuito inválido que podía fallar en lugares inusuales. -
Se ha solucionado un problema al utilizar
transpile()o al ejecutar un gestor de pases preestablecido (como el generado porgenerate_preset_pass_manager()) cuando se dirige a un backend que tiene conectividad disjunta añadiendo barreras adicionales a la salidaQuantumCircuit. En algunos casos, varias directivasBarrierse incluirían en el circuito de salida justo antes de cualquier medida final en el circuito. Se trataba de un estado interno generado por el procesamiento interno para la conectividad disjunta que se añadía incorrectamente al circuito de salida. Corregido #11649 -
Se ha corregido un error cuando un usuario intenta cargar los datos de calibración de una puerta de
Targeten una situación particular. Esto ocurre cuando el backend informa sólo de datos de calibración parciales, por ejemplo haciendo referencia a un pulso de forma de onda en una definición de comando pero sin incluir ese pulso de forma de onda en la biblioteca de pulsos. En esta situación, el objeto de pulso Qiskit no pudo ser construido, resultando en una falla para construir el programa de pulso para la calibración. Ahora, cuando los datos de calibración están incompletos, elTargetlo trata como equivalente a que no se informe de ninguna calibración y no lanza una excepción. -
El método
Operator.power()funciona ahora con exponentes de coma flotante, de acuerdo con la descripción documentada. -
Se ha solucionado un problema con el paso
OptimizeSwapBeforeMeasurepor el que se optimizaban incorrectamente los circuitos que incluían instrucciones de intercambio y medida. Por ejemplo:from qiskit import QuantumCircuit from qiskit.transpiler.passes import OptimizeSwapBeforeMeasure pass_ = OptimizeSwapBeforeMeasure() qc = QuantumCircuit(2, 1) qc.swap(0, 1) qc.measure(0, 0) qc.measure(0, 0) print(qc.draw()) print(pass_(qc).draw())se imprimiría antes:
┌─┐┌─┐ q_0: ─X─┤M├┤M├ │ └╥┘└╥┘ q_1: ─X──╫──╫─ ║ ║ c: 1/════╩══╩═ 0 0 ┌─┐ q_0: ┤M├─── └╥┘┌─┐ q_1: ─╫─┤M├ ║ └╥┘ c: 1/═╩══╩═ 0 0y ahora el segundo circuito está correctamente optimizado para:
q_0: ────── ┌─┐┌─┐ q_1: ┤M├┤M├ └╥┘└╥┘ c: 1/═╩══╩═ 0 0 -
Se ha corregido un problema con la serialización de QPY cuando un archivo
QuantumCircuitcontenía varias instancias de instrucciones personalizadas que tenían el mismo atributonameatributo. En las versiones del formato QPY anteriores a la versión 11, la carga útil QPY no diferenciaba entre estas instancias y sólo serializaba las propiedades de la primera instancia de un circuito. Esto podría causar potencialmente una deserialización incorrecta si las otras propiedades de la instrucción personalizada fueran diferentes pero los nombres fueran los mismos. Esto se ha corregido en la versión 11 de QPY para que cada instancia de una instrucción personalizada se serialice individualmente y ya no haya un conflicto potencial con nombres superpuestos. Corrige #8941. -
Se ha solucionado un problema con la función
qpy.dump()por el que, cuando el 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. -
Corrección de un error en la
StabilizerStaterepresentación de cadenas. -
Un error donde
convert_to_target()yBackendV2Converterprovocaban un error inesperado. El error se producía cuando el backend a convertir incluía calibraciones para una puerta que no tenía definición en las propiedades del backend. Dicha puerta se difunde ahora a todos los qubits como una instrucción ideal libre de errores, incluso cuando se informa de calibraciones para un conjunto finito de qubits. -
Se ha solucionado un problema con la función
circuit_drawer()y el métodoQuantumCircuit.draw()al cargar un estilo matplotlib a través del archivo de configuración del usuario. -
InstructionDurations.from_backend()devuelve ahora una instancia de cualquier subclase deInstructionDurationsen lugar de la clase base. -
El transpilador
UnitarySynthesistranspiler pass generará ahora un error en la inicialización cuando se especifique un plugin de síntesis inexistente, en lugar de esperar hasta el tiempo de ejecución para que se produzca. Corregido #11355. -
Los exportadores de OpenQASM 3
qasm3.dump()ydumps()mostrarán ahora correctamente los archivos de la versión3.0en lugar de la versión sin calificar3, ya que el proyecto OpenQASM 3 ha estandarizado el sistema de versiones. -
La forma paramétrica de
XXPlusYYGateyXXMinusYYGatedevuelta porget_standard_gate_name_mapping()incluye ahora correctamente el parámetro así como la rotación inicial . -
El pase
TemplateOptimizationpass devolverá ahora expresiones paramétricas utilizando el formato nativo de expresión simbólica deParameterExpressionen lugar de utilizar siempre Sympy. Para la mayoría de las plataformas soportadas, esto significa que las expresiones serán objetos Symengine. Anteriormente, el pase podía devolver objetos no coincidentes, lo que podía provocar fallos posteriores en el código de gestión de parámetros.