Notas de la versión de Qiskit 0.40
0.40.0
Esta versión deja oficialmente obsoleto el proyecto de proveedor IBMQ de Qiskit como parte del metapaquete Qiskit. Esto significa que, en una futura versión, pip install qiskit ya no incluirá automáticamente qiskit-ibmq-provider. Si actualmente está instalando o listando qiskit como una dependencia para obtener qiskit-ibmq-provider, debe actualizar para incluir explícitamente qiskit-ibmq-provider también. Esto se está haciendo a medida que el proyecto Qiskit avanza hacia un modelo en el que el paquete qiskit sólo contiene la funcionalidad básica común para construir y compilar circuitos cuánticos, programas y aplicaciones. Los paquetes que se basen en ese núcleo o vinculen Qiskit a hardware o simuladores podrán instalarse como paquetes independientes.
Terra 0.23.0
Preludio
Qiskit Terra 0.23.0 es una importante versión que incluye multitud de nuevas funciones y correcciones de errores. Los aspectos más destacados de esta versión son:
Soporte para importar programas OpenQASM 3 y crear
QuantumCircuitobjetos desde el programa de entrada mediante dos nuevas funcionesqiskit.qasm3.load()yqiskit.qasm3.loads().Mejoras en la biblioteca de algoritmos de síntesis incluidos en Qiskit. Esto incluye las siguientes nuevas funciones de síntesis:
Síntesis de Clifford
Síntesis de funciones lineales:
Síntesis de permutación:
SolovayKitaevDecompositiondetallado en: https://arxiv.org/abs/quant-ph/0505030Nuevos plugins para
HighLevelSynthesis:
ACGSynthesisPermutationKMSSynthesisPermutationBasicSynthesisPermutationNuevo plugin para
UnitarySynthesisMejoras de rendimiento para
SabreLayout. El pase está ahora escrito principalmente en Rust, lo que puede suponer una mejora en el tiempo de ejecución, sin embargo la mayor mejora está en la calidad del resultado (de media, menosSwapGatepuertas introducidas porSabreSwap). Por ejemplo, ejecutarSabreLayoutySabreSwapen los circuitos Bernstein Vazirani dirigidos al backendFakeSherbrookese obtienen los siguientes resultados:![]()
Esta versión también deja de ser compatible con Python 3.7. Ahora se emitirá un DeprecationWarning si ejecutas Qiskit con Python 3.7. La compatibilidad con Python 3.7 se eliminará como parte de la versión 0.25.0 (actualmente prevista para julio de 2023), momento en el que necesitará Python 3.8 o una versión más reciente para utilizar Qiskit.
Nuevas funciones
-
Los pulsos en
qiskit.pulse.librarypuede inicializarse con el nuevo parámetro
angle, de forma que podrían proporcionarse dos parámetros flotantes:ampyangle. La inicialización con el complejoampsigue siendo posible. -
La clase
AdaptVQEtiene un nuevo atributo,eigenvalue_historyque se utiliza para rastrear la energía más baja alcanzada por iteración de AdaptVQE. Por ejemplo:from qiskit.algorithms.minimum_eigensolvers import VQE from qiskit.algorithms.minimum_eigensolvers.adapt_vqe import AdaptVQE from qiskit.algorithms.optimizers import SLSQP from qiskit.circuit.library import EvolvedOperatorAnsatz from qiskit.opflow import PauliSumOp from qiskit.primitives import Estimator from qiskit.quantum_info import SparsePauliOp from qiskit.utils import algorithm_globals excitation_pool = [ PauliSumOp( SparsePauliOp(["IIIY", "IIZY"], coeffs=[0.5 + 0.0j, -0.5 + 0.0j]), coeff=1.0 ), PauliSumOp( SparsePauliOp(["ZYII", "IYZI"], coeffs=[-0.5 + 0.0j, 0.5 + 0.0j]), coeff=1.0 ), PauliSumOp( SparsePauliOp( ["ZXZY", "IXIY", "IYIX", "ZYZX", "IYZX", "ZYIX", "ZXIY", "IXZY"], coeffs=[ -0.125 + 0.0j, 0.125 + 0.0j, -0.125 + 0.0j, 0.125 + 0.0j, 0.125 + 0.0j, -0.125 + 0.0j, 0.125 + 0.0j, -0.125 + 0.0j, ], ), coeff=1.0, ), ] ansatz = EvolvedOperatorAnsatz(excitation_pool, initial_state=self.initial_state) optimizer = SLSQP() h2_op = PauliSumOp.from_list( [ ("IIII", -0.8105479805373266), ("ZZII", -0.2257534922240251), ("IIZI", +0.12091263261776641), ("ZIZI", +0.12091263261776641), ("IZZI", +0.17218393261915543), ("IIIZ", +0.17218393261915546), ("IZIZ", +0.1661454325638243), ("ZZIZ", +0.1661454325638243), ("IIZZ", -0.2257534922240251), ("IZZZ", +0.16892753870087926), ("ZZZZ", +0.17464343068300464), ("IXIX", +0.04523279994605788), ("ZXIX", +0.04523279994605788), ("IXZX", -0.04523279994605788), ("ZXZX", -0.04523279994605788), ] ) algorithm_globals.random_seed = 42 calc = AdaptVQE(VQE(Estimator(), ansatz, self.optimizer)) res = calc.compute_minimum_eigenvalue(operator=h2_op) print(calc.eigenvalue_history)el valor devuelto de
calc.historydebería ser aproximadamente[-1.85727503]ya que hay una única iteración. -
Se ha mejorado el registro en tiempo de ejecución cuando se ejecuta el
AdaptVQEse ha mejorado. Al ejecutar la clase ahora, se emitirán mensajes de registro de nivelDEBUGyINFOmientras se ejecuta la clase. -
Añadido un nuevo pase de transpilador,
CollectAndCollapse, para recoger y consolidar bloques de nodos en un circuito. Este pase está diseñado para ser una clase base general para la recopilación y consolidación de bloques combinados. Para ser completamente general, el trabajo de recoger y colapsar los bloques se realiza a través de funciones proporcionadas durante la instanciación del pase. Por ejemplo, elCollectLinearFunctionsse ha actualizado para heredar deCollectAndCollapsey recoge bloques deCXGateySwapGatey sustituye cada bloque por una puertaLinearFunction. ElCollectCliffordsque ahora también se basa enCollectAndCollapse, recoge bloques de puertas "Clifford" y sustituye cada bloque por unClifford.La interfaz también admite la opción
do_commutative_analysis, que permite explotar la conmutatividad entre puertas para reunir bloques de nodos más grandes. Por ejemplo, recogiendo bloques de puertas CX en el siguiente circuito:qc = QuantumCircuit(2) qc.cx(0, 1) qc.z(0) qc.cx(1, 0)el uso de
do_commutative_analysispermite consolidar las dos puertas CX, ya que la primera puerta CX y la puerta Z se conmutan. -
Añadida una nueva clase
BlockCollectorque implementa varias estrategias de recolección, y una nueva claseBlockCollapserque implementa varias estrategias de colapso. En la actualidadBlockCollectorincluye la estrategia de recopilar con avidez todas las compuertas que se adhieren a una función de filtro dada (por ejemplo, recopilar todas las compuertas Clifford), yBlockCollapserincluye la estrategia de consolidar todas las compuertas de un bloque en un único objeto (o ejemplo, un bloque de compuertas Clifford puede consolidarse en un únicoClifford). -
Se ha añadido un nuevo
CollectCliffordstranspilador que recoge bloques de puertas Clifford y los consolida en objetosqiskit.quantum_info.Cliffordobjetos. Este pase hereda deCollectAndCollapsey, en particular, admite la opcióndo_commutative_analysis. También admite dos opciones adicionalessplit_blocksymin_block_size. Consulte las notas de la versión deCollectAndCollapseyCollectLinearFunctionspara más detalles. -
El
CollectLinearFunctionstranspiler pass tiene varios argumentos nuevos en su constructor:-
do_commutative_analysispermite explotar la conmutatividad entre puertas para reunir bloques de nodos más grandes. -
split_blockspermite dividir los bloques recogidos en subbloques sobre subconjuntos disjuntos de qubits. Por ejemplo, en el siguiente circuito:qc = QuantumCircuit(4) qc.cx(0, 2) qc.cx(1, 3) qc.cx(2, 0) qc.cx(3, 1) qc.cx(1, 3)el bloque único de compuertas CX sobre qubits
{0, 1, 2, 3}puede dividirse en dos subbloques disjuntos, uno sobre qubits{0, 2}y otro sobre qubits{1, 3}. -
min_block_size: permite especificar el tamaño mínimo del bloque que se va a consolidar, los bloques con menos puertas no se modificarán. Por ejemplo, en el siguiente circuito:qc = QuantumCircuit(4) qc.cx(1, 2) qc.cx(2, 1)las dos puertas CX se consolidarán cuando
min_block_sizesea 1 ó 2, y permanecerán inalteradas cuandomin_block_sizesea 3 o mayor.
-
-
Añadido un algoritmo de síntesis de profundidad eficiente
synth_cnot_depth_line_kms()para circuitos lineales reversiblesLinearFunctionsobre la arquitectura lineal del vecino más próximo, siguiendo el artículo: https://arxiv.org/abs/quant-ph/0701194. -
El método
DAGCircuit.replace_block_with_op()devolverá el nuevo bloqueDAGOpNodeque se crea cuando se sustituye el bloque. Antes, llamar a este método no devolvía nada. -
Añadido un algoritmo de síntesis de profundidad eficiente
synth_permutation_depth_lnn_kms()paraPermutationsobre la arquitectura lineal de vecino más próximo, siguiendo el artículo: https://arxiv.org/abs/quant-ph/0701194 -
Se ha añadido una nueva clase
PermutationGatepara representar la lógica de permutación como un elemento de circuito. A diferencia del elementoPermutationque tenía una definición estática, esta nueva clase evita sintetizar un circuito de permutación cuando se declara. Esto retrasa la síntesis real al transpilador. También permite utilizar varios algoritmos diferentes para sintetizar permutaciones, que están disponibles como plugins de permutación de síntesis de alto nivel.Otra característica clave del
PermutationGatees que implementa la interfaz__array__para devolver eficientemente una matriz unitaria para una permutación. -
Añadidos varios plugins de síntesis de alto nivel para sintetizar permutaciones:
BasicSynthesisPermutationse aplica a arquitecturas totalmente conectadas y se basa en la clasificación. Este es el algoritmo utilizado anteriormente para construir circuitos cuánticos para permutaciones.ACGSynthesisPermutationse aplica a arquitecturas totalmente conectadas, pero se basa en el método de Alon, Chung y Graham. Sintetiza cualquier permutación en profundidad 2 (medida en términos de SWAPs).KMSSynthesisPermutation: se aplica a las arquitecturas lineales de vecino más próximo y corresponde al método Kutin, Moulton, Smithline recientemente añadido.
Por ejemplo:
from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import PermutationGate from qiskit.transpiler import PassManager from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig, HighLevelSynthesis from qiskit.transpiler.passes.synthesis.plugin import HighLevelSynthesisPluginManager # Create a permutation and add it to a quantum circuit perm = PermutationGate([4, 6, 3, 7, 1, 2, 0, 5]) qc = QuantumCircuit(8) qc.append(perm, range(8)) # Print available plugin names for synthesizing permutations # Returns ['acg', 'basic', 'default', 'kms'] print(HighLevelSynthesisPluginManager().method_names("permutation")) # Default plugin for permutations # Returns a quantum circuit with size 6 and depth 3 qct = PassManager(HighLevelSynthesis()).run(qc) print(f"Default: {qct.size() = }, {qct.depth() = }") # KMSSynthesisPermutation plugin for permutations # Returns a quantum circuit with size 18 and depth 6 # but adhering to the linear nearest-neighbor architecture. qct = PassManager(HighLevelSynthesis(HLSConfig(permutation=[("kms", {})]))).run(qc) print(f"kms: {qct.size() = }, {qct.depth() = }") # BasicSynthesisPermutation plugin for permutations # Returns a quantum circuit with size 6 and depth 3 qct = PassManager(HighLevelSynthesis(HLSConfig(permutation=[("basic", {})]))).run(qc) print(f"basic: {qct.size() = }, {qct.depth() = }") # ACGSynthesisPermutation plugin for permutations # Returns a quantum circuit with size 6 and depth 2 qct = PassManager(HighLevelSynthesis(HLSConfig(permutation=[("acg", {})]))).run(qc) print(f"acg: {qct.size() = }, {qct.depth() = }") -
Añadidas nuevas clases para los algoritmos Quantum Fisher Information (QFI) y Quantum Geometric Tensor (QGT) utilizando
primitives,qiskit.algorithms.gradients.QFIyqiskit.algorithms.gradients.LinCombQGTal módulo de gradientes:qiskit.algorithms.gradients. Por ejemplo:from qiskit.circuit import QuantumCircuit, Parameter from qiskit.algorithms.gradients import LinCombQGT, QFI estimator = Estimator() a, b = Parameter("a"), Parameter("b") qc = QuantumCircuit(1) qc.h(0) qc.rz(a, 0) qc.rx(b, 0) parameter_value = [[np.pi / 4, 0]] qgt = LinCombQGT(estimator) qgt_result = qgt.run([qc], parameter_value).result() qfi = QFI(qgt) qfi_result = qfi.run([qc], parameter_value).result() -
Se ha añadido un nuevo argumento de palabra clave,
derivative_type, al constructor de la funciónLinCombEstimatorGradient. Este argumento toma un enumDerivativeTypeque permite especificar calcular sólo las partes reales o imaginarias del gradiente. -
Añadida una nueva opción
circuit_reverse_bitsal archivo de configuración del usuario. Esto permite a los usuarios establecer un booleano para su comportamiento preferido por defecto del argumentoreverse_bitsde los dibujantes de circuitosQuantumCircuit.draw()ycircuit_drawer(). Por ejemplo, añadiendo una sección al archivo de configuración del usuario en la ubicación predeterminada~/.qiskit/settings.confcon:[default] circuit_reverse_bits = Truecambiará el valor por defecto para mostrar los bits en orden inverso.
-
Añadida una nueva clase
Z2Symmetriesaqiskit.quantum_infoque se utiliza para identificar cualquier simetrías de una entradaSparsePauliOp. -
Añadida una nueva directiva de pulso
TimeBlockade. Esta directiva se comporta de forma casi idéntica a la instrucción delay, pero se eliminará antes de la ejecución. Esta directiva está pensada para ser utilizada internamente dentro del constructor de pulsos y ayuda aScheduleBlocka representar instrucciones con intervalos de tiempo absolutos. Esto permite al constructor de impulsos convertirScheduleenScheduleBlock, en lugar de envolver conCallinstrucciones. -
Añadidos algoritmos con primitivas para la Evolución Cuántica Variable del Tiempo que implementan la interfaz para la Evolución Cuántica del Tiempo. La clase
qiskit.algorithms.VarQRTEse utiliza para la evolución real y la claseqiskit.algorithms.VarQITEclase se utiliza para la evolución del tiempo cuántico imaginario según un principio variacional pasado.Cada algoritmo acepta un principio variacional que implementa la
ImaginaryVariationalPrincipleinterfaz abstracta. Se incluyen las siguientes implementaciones:Por ejemplo:
from qiskit.algorithms import TimeEvolutionProblem, VarQITE from qiskit.algorithms.time_evolvers.variational import ImaginaryMcLachlanPrinciple from qiskit.circuit.library import EfficientSU2 from qiskit.quantum_info import SparsePauliOp import numpy as np observable = SparsePauliOp.from_list( [ ("II", 0.2252), ("ZZ", 0.5716), ("IZ", 0.3435), ("ZI", -0.4347), ("YY", 0.091), ("XX", 0.091), ] ) ansatz = EfficientSU2(observable.num_qubits, reps=1) init_param_values = np.zeros(len(ansatz.parameters)) for i in range(len(ansatz.parameters)): init_param_values[i] = np.pi / 2 var_principle = ImaginaryMcLachlanPrinciple() time = 1 evolution_problem = TimeEvolutionProblem(observable, time) var_qite = VarQITE(ansatz, var_principle, init_param_values) evolution_result = var_qite.evolve(evolution_problem) -
Añadidas reglas para convertir
XXPlusYYGateyXXMinusYYGatea otras puertas enSessionEquivalenceLibrary. Esto permite ejecutartranspile()apuntando a un backend oTargetque utilice estas puertas. -
Añadidos dos nuevos backends falsos
FakePragueyFakeSherbrookeal móduloqiskit.providers.fake_providermódulo.FakePragueproporciona un backend con una instantánea de las propiedades del backend IBM Garceta de Praga R1 yFakeSherbrookeproporciona un backend con una instantánea de las propiedades del backend IBM Águila de Sherbrooke R3. -
Se ha añadido un nuevo argumento de palabra clave,
allow_unknown_parameters, a los parámetrosParameterExpression.bind()yParameterExpression.subs()y. Este nuevo argumento permite pasar un diccionario con parámetros desconocidos a estos métodos sin que se produzca un error. Anteriormente, esto siempre generaba un error sin que hubiera forma de desactivar ese comportamiento. -
El argumento
BaseEstimator.run()del métodoobservablesacepta ahora un tipo de entradastro una secuencia destrademás de los otros tipos ya aceptados. Cuando se utiliza, el formato de la cadena de entrada debe coincidir con la representación de cadena Pauli aceptada por el constructor de objetosPauliobjetos. -
Se ha añadido un nuevo método constructor
QuantumCircuit.from_instructions()que permite crear unQuantumCircuita partir de un iterable de instrucciones. Por ejemplo:from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister from qiskit.circuit.quantumcircuitdata import CircuitInstruction from qiskit.circuit import Measure from qiskit.circuit.library import HGate, CXGate qr = QuantumRegister(2) cr = ClassicalRegister(2) instructions = [ CircuitInstruction(HGate(), [qr[0]], []), CircuitInstruction(CXGate(), [qr[0], qr[1]], []), CircuitInstruction(Measure(), [qr[0]], [cr[0]]), CircuitInstruction(Measure(), [qr[1]], [cr[1]]), ] circuit = QuantumCircuit.from_instructions(instructions) circuit.draw("mpl")
-
La clase
Cliffordtoma ahora un argumento opcional de la palabra clavecopyen su constructor. Si se establece enFalse, entonces unStabilizerTableproporcionado como entrada no se copiará, sino que se utilizará directamente. Esto puede tener ventajas de rendimiento, si los datos de la tabla no van a mutar nunca por ningún otro medio. -
El rendimiento de
Clifford.compose()ha mejorado mucho para todos los números de qubits. Para operadores de 20 qubits, el aumento de velocidad es del orden de 100 veces. -
Añadida una nueva función de síntesis
synth_clifford_layers()para sintetizar unClifforden capas. El algoritmo se basa en S. Bravyi, D. Maslov, Los circuitos sin Hadamard exponen la estructura del grupo de Clifford, arxiv:2003.09412. Esto descompone el Clifford en 8 capas de puertas, incluyendo dos capas de puertas CZ y una capa de puertas CX. Por ejemplo, un circuito Clifford de 5 qubits se descompone en las siguientes capas:┌─────┐┌─────┐┌────────┐┌─────┐┌─────┐┌─────┐┌─────┐┌────────┐ q_0: ┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├ │ ││ ││ ││ ││ ││ ││ ││ │ q_1: ┤1 ├┤1 ├┤1 ├┤1 ├┤1 ├┤1 ├┤1 ├┤1 ├ │ ││ ││ ││ ││ ││ ││ ││ │ q_2: ┤2 S2 ├┤2 CZ ├┤2 CX_dg ├┤2 H2 ├┤2 S1 ├┤2 CZ ├┤2 H1 ├┤2 Pauli ├ │ ││ ││ ││ ││ ││ ││ ││ │ q_3: ┤3 ├┤3 ├┤3 ├┤3 ├┤3 ├┤3 ├┤3 ├┤3 ├ │ ││ ││ ││ ││ ││ ││ ││ │ q_4: ┤4 ├┤4 ├┤4 ├┤4 ├┤4 ├┤4 ├┤4 ├┤4 ├ └─────┘└─────┘└────────┘└─────┘└─────┘└─────┘└─────┘└────────┘Este método permitirá descomponer un
Clifforden profundidad de 2 qubits para la conectividad del vecino más próximo lineal (LNN). -
Los tipos de retorno de los métodos
power()de varias clases de compuertas de la biblioteca estándar se han actualizado para devolver objetos de compuerta más específicos que dan como resultado una salida con menos pérdidas y más eficiente. Por ejemplo, ejecutarpower()devuelve ahora una instanciaIGateen lugar deUnitaryGatecomo se hacía anteriormente.La lista completa de los tipos de salida que se han mejorado son:
-
El
EquivalenceLibraryse representa ahora internamente como unPyDiGraph, este objeto gráfico subyacente puede ser accedido desde el nuevo atributographatributo. Este atributo está pensado para su uso interno en Qiskit y, por lo tanto, debe copiarse siempre antes de ser modificado por el usuario para evitar posibles corrupciones del gráfico de equivalencia interno. -
El método constructor
Operator.from_circuit()invertirá ahora la permutación de salida causada por la etapa de enrutamiento/mapa de intercambio del transpilador. Por defecto, si un circuito transpilado tiene puertas Swap insertadas, la matriz de salida tendrá esa permutación invertida, por lo que la matriz devuelta será equivalente al circuito original no transpilado. Si desea desactivar este comportamiento por defecto, el argumento de la palabra claveignore_set_layoutpuede establecerse enTruepara hacerlo (además del comportamiento anterior de ignorar el diseño inicial de la transpilación). Si desea establecer manualmente una disposición final, puede utilizar el nuevo argumento de palabra clavefinal_layoutpara pasar un objetoLayoutpara la permutación de salida. -
Se ha añadido soporte al
GateDirectiontranspiler pass para manejar el simétricoRXXGate,RYYGateyRZZGatesimétricas. El pase ahora manejará correctamente estas puertas y simplemente invertirá el orden de qargs en su lugar sin ninguna otra modificación. -
Se ha añadido soporte para utilizar el operador de exponenciación Python,
**, con objetosGateahora es compatible. Equivale a ejecutar el métodoGate.power()en el objeto.Por ejemplo:
from qiskit.circuit.library import XGate sx = XGate() ** 0.5 -
Añadida nueva forma de pulso
GaussianSquareDragalqiskit.pulse.librarymódulo. Esta forma de pulso es similar aGaussianSquarepero utiliza la formaDragdurante su ascenso y descenso. La corrección de la forma del pulso DRAG puede suprimir parte del espectro de frecuencia de la subida y bajada del pulso, lo que puede ayudar a evitar excitar qubits espectadores cuando están cerca en frecuencia de la frecuencia de accionamiento del pulso. -
Se ha añadido un nuevo argumento de palabra clave,
method, a los constructores de los módulosFiniteDiffEstimatorGradientyFiniteDiffSamplerGradient. El argumentomethodacepta una cadena para indicar el método de cálculo a utilizar para el gradiente. Existen tres métodos:"central","forward"y"backward". La definición de los métodos son:MétodoCálculo"central""forward""backward"donde es el épsilon de desplazamiento.
-
Todas las clases de gradiente en
qiskit.algorithms.gradientsahora conservan las operaciones no parametrizadas en lugar de intentar desenrollarlas. Esto permite evaluar gradientes en puertas opacas personalizadas que las primitivas individuales pueden manejar y mantiene un mayor nivel de abstracción para la síntesis optimizada y la compilación después de que se hayan construido los circuitos de gradiente. -
Se ha añadido un
TranslateParameterizedGatespara asignar sólo puertas parametrizadas en un circuito a una base especificada, pero dejar las puertas no parametrizadas intactas. La pasada primero intenta desenrollar y finalmente traduce si una puerta parametrizada no puede desenrollarse más. -
El
CollectCliffordsse ha ampliado para recoger y combinar bloques de "puertas clifford" en objetos de tipoClifforddonde las "puertas clifford" ahora también pueden incluir objetos de tipoLinearFunction,CliffordyPauliGate. Por ejemplo:from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import LinearFunction, PauliGate from qiskit.quantum_info.operators import Clifford from qiskit.transpiler.passes import CollectCliffords from qiskit.transpiler import PassManager # Create a Clifford cliff_circuit = QuantumCircuit(2) cliff_circuit.cx(0, 1) cliff_circuit.h(0) cliff = Clifford(cliff_circuit) # Create a linear function lf = LinearFunction([[0, 1], [1, 0]]) # Create a pauli gate pauli_gate = PauliGate("XYZ") # Create a quantum circuit with the above and also simple clifford gates. qc = QuantumCircuit(4) qc.cz(0, 1) qc.append(cliff, [0, 1]) qc.h(0) qc.append(lf, [0, 2]) qc.append(pauli_gate, [0, 2, 1]) qc.x(2) # Run CollectCliffords transpiler pass qct = PassManager(CollectCliffords()).run(qc)Todas las puertas se recogerán y combinarán en una única
Clifford. Así, el circuito final consta de un únicoCliffordobjeto. -
CouplingMapes ahora implícitamente iterable, siendo la iteración idéntica a iterar a través de la salida deCouplingMap.get_edges(). En otras palabras,from qiskit.transpiler import CouplingMap coupling = CouplingMap.from_line(3) list(coupling) == list(coupling.get_edges())funcionará ahora como se espera, al igual que otras iteraciones. Esto es puramente una conveniencia sintáctica.
-
Añadida una nueva función
synth_cnot_count_full_pmh()que se utiliza para sintetizar circuitos lineales reversibles para arquitecturas todo-a-todo utilizando el método de Patel, Markov y Hayes. Esta función es idéntica a la disponible enqiskit.transpiler.synthesis.cnot_synth(), pero tiene un nombre más descriptivo y se sitúa de forma más lógica en el árbol de paquetes. Esta nueva función sustituye a la anterior, que probablemente quedará obsoleta en una futura versión. -
InstructionScheduleMapse ha actualizado para almacenar los datos de calibración del backend en el formato de PulseQobj JSON e invoca la conversión cuando se accede a los datos por primera vez, es decir, conversión perezosa. Esta actualización de la lógica interna mejora drásticamente el rendimiento del backend de carga, especialmente con muchas entradas de calibración. -
Se ha añadido el nuevo módulo
qiskit.pulse.calibration_entries. Contiene varias clases de envoltura para diferentes representaciones de la programación de impulsos.ScheduleDefCallableDefPulseQobjDef
Estas clases implementan los métodos
get_schedule()yget_signature()que devuelven el programa de pulsos y los nombres de los parámetros a asignar, respectivamente. Estas clases son gestionadas internamente por elInstructionScheduleMapo backendTargety, por tanto, no aparecerán en un programa de usuario típico. -
Introducida una nueva subclase
ScalableSymbolicPulse, como subclase deSymbolicPulse. La nueva subclase se comporta igual queSymbolicPulseexcepto que asume que la envolvente del pulso incluye un pre-factor de amplitud compleja de la forma . Esta forma de envolvente coincide con muchos pulsos comunes, incluyendo todos los pulsos de la librería Qiskit Pulse (que también fueron convertidos a la representaciónamp,angleen esta versión).La nueva subclase elimina la naturaleza no única de la representación
amp,angle, y compara correctamente los pulsos según su amplitud compleja. -
Se ha añadido un nuevo argumento de palabra clave,
dtype, al métodoPauliSumOp.from_list()método. Cuando se especifica este argumento se puede utilizar para especificar eldtypede la matriz numpy asignada para elSparsePauliOputilizado internamente por elPauliSumOp. -
Se ha añadido soporte para importar programas de OpenQASM 3 a Qiskit. Se puede acceder más fácilmente utilizando las funciones
qasm3.loads()yqasm3.load()para cargar un programa directamente a partir de una cadena e indirectamente a partir de un nombre de archivo, respectivamente. Por ejemplo, ahora se puede hacer:from qiskit import qasm3 circuit = qasm3.loads(""" OPENQASM 3.0; include "stdgates.inc"; qubit q; qubit[5] qr; bit c; bit[5] cr; h q; c = measure q; if (c) { h qr[0]; cx qr[0], qr[1]; cx qr[0], qr[2]; cx qr[0], qr[3]; cx qr[0], qr[4]; } else { h qr[4]; cx qr[4], qr[3]; cx qr[4], qr[2]; cx qr[4], qr[1]; cx qr[4], qr[0]; } cr = measure qr; """)Esto cargará el programa en una
QuantumCircuitinstancia en la variablecircuit.No todas las características de OpenQASM 3 son compatibles al principio, porque Qiskit todavía no tiene una forma de representar el procesamiento clásico avanzado de datos. Las capacidades del importador aumentarán junto con las del resto de Qiskit. El conjunto inicial de características del importador es aproximadamente el mismo que el del exportador (
qasm3.dump()yqasm3.dumps()).Ten en cuenta que la compatibilidad de Qiskit con OpenQASM 3 no pretende proporcionar una representación totalmente sin pérdidas de
QuantumCircuits. Para ello, considere la posibilidad de utilizarqiskit.qpy. -
Las clases de gradiente basadas en
primitives-basadas en las clases de gradiente definidas por elBaseEstimatorGradientyBaseSamplerGradientse han actualizado para simplificar la ampliación de la interfaz base. Hay tres nuevos métodos internos anulables,_preprocess(),_postprocess(), y_run_unique()._preprocess()permite a una subclase personalizar los circuitos y parámetros del gradiente de entrada,_postprocesspermite personalizar el resultado de salida, y_run_uniquepermite calcular el gradiente de un circuito con parámetros únicos. -
El transpilador
SabreLayouttranspiler pass ha mejorado mucho su rendimiento, ya que ha sido reescrito en Rust. Como parte de esta reescritura, el pase ha pasado de ser un pase de análisis a un pase de transformación que ejecutará tanto el diseño como el enrutamiento. Esto se hizo no sólo para mejorar el rendimiento en tiempo de ejecución, sino también para mejorar la calidad de los resultados. La funcionalidad anterior del pase como pase de análisis puede conservarse configurando manualmente el argumentorouting_passo utilizando el nuevo argumentoskip_routing. -
El
SabreLayouttranspiler pass tiene un nuevo argumento constructorlayout_trials. Este argumento se utiliza para controlar con cuántas semillas del generador de números aleatorios se intentará ejecutarSabreLayoutcon. Cuando se configura, el algoritmo de diseño SABRE se ejecutalayout_trialsnúmero de veces y se selecciona el resultado de mejor calidad (medido en el menor número de puertas de intercambio añadidas). Estos ensayos de semillas se ejecutan en paralelo utilizando multihilo para minimizar la posible sobrecarga de rendimiento de ejecutar el diseño varias veces. Por defecto, si no se especifica, elSabreLayoutpass utilizará por defecto el número de CPUs físicas disponibles en el sistema local. -
Añadidas dos nuevas clases
SciPyRealEvolverySciPyImaginaryEvolverque implementan métodos de integración para la evolución temporal de un estado cuántico. El valor y la desviación típica de los observables, así como los momentos en que se evalúan, pueden consultarse comoTimeEvolutionResult.observablesyTimeEvolutionResult.times. Por ejemplo:from qiskit.algorithms.time_evolvers.time_evolution_problem import TimeEvolutionProblem from qiskit.quantum_info import SparsePauliOp from qiskit.quantum_info.states.statevector import Statevector from qiskit.algorithms import SciPyImaginaryEvolver initial_state = Statevector.from_label("+++++") hamiltonian = SparsePauliOp("ZZZZZ") evolution_problem = TimeEvolutionProblem(hamiltonian, 100, initial_state, {"Energy":hamiltonian}) classic_evolver = SciPyImaginaryEvolver(num_timesteps=300) result = classic_evolver.evolve(evolution_problem) print(result.observables) -
Añadido el
SolovayKitaevpara ejecutar el algoritmo Solovay-Kitaev para aproximar unitarios de un solo qubit utilizando un conjunto de puertas discretas. En combinación con el traductor de bases, esto permite convertir cualquier circuito unitario en un conjunto universal de puertas discretas, que podría implementarse con tolerancia a fallos.Este pase puede utilizarse, por ejemplo, después de compilar en las puertas U y CX:
from qiskit import transpile from qiskit.circuit.library import QFT from qiskit.transpiler.passes.synthesis import SolovayKitaev qft = QFT(3) # optimize to general 1-qubit unitaries and CX transpiled = transpile(qft, basis_gates=["u", "cx"], optimization_level=1) skd = SolovayKitaev() # uses T Tdg and H as default basis discretized = skd(transpiled) print(discretized.count_ops())La descomposición también se puede utilizar con el plugin de síntesis unitaria, como el método "sk" en el
UnitarySynthesistranspiler pass:from qiskit import QuantumCircuit from qiskit.quantum_info import Operator from qiskit.transpiler.passes import UnitarySynthesis circuit = QuantumCircuit(1) circuit.rx(0.8, 0) unitary = Operator(circuit).data unitary_circ = QuantumCircuit(1) unitary_circ.unitary(unitary, [0]) synth = UnitarySynthesis(basis_gates=["h", "s"], method="sk") out = synth(unitary_circ) out.draw('mpl')
-
La generación de circuitos aleatorios con
qiskit.circuit.random.random_circuit()es ahora significativamente más rápida para circuitos grandes. -
La generación de circuitos aleatorios con
qiskit.circuit.random.random_circuit()generará ahora todas las puertas "estándar" de la librería de circuitos de Qiskit (qiskit.circuit.library). Esto incluye dos puertas 4-qubitC3SXGateyRC3XGatey los valores permitidos demax_operandsse han ampliado en consecuencia. -
El
Optimize1qGatesDecompositiontranspiler pass tiene un nuevo argumento de palabra clave,target, en su constructor. Este argumento puede utilizarse para especificar unTargetque representa el objetivo de compilación. Si se utiliza, sustituye al argumentobasispara determinar si una instrucción del circuito está presente en el backend de destino. -
El
UnrollCustomDefinitionstranspiler pass tiene un nuevo argumento de palabra clave,target, en su constructor. Este argumento puede utilizarse para especificar unTargetque representa el objetivo de compilación. Si se utiliza, sustituye al argumentobasis_gatespara determinar si una instrucción del circuito está presente en el backend de destino. -
Se ha añadido la clase
ReverseEstimatorGradientpara una evaluación clásica y rápida de gradientes de valor de expectativa basados en la retropropagación o en gradientes de modo inverso. Esta clase utiliza vectores de estado y, por tanto, proporciona gradientes exactos, pero se escala exponencialmente en el tamaño del sistema. Está diseñado para el cálculo rápido de referencias de sistemas de menor tamaño. Puede utilizarse, por ejemplo, como:from qiskit.circuit.library import EfficientSU2 from qiskit.quantum_info import SparsePauliOp from qiskit.algorithms.gradients import ReverseEstimatorGradient observable = SparsePauliOp.from_sparse_list([("ZZ", [0, 1], 1)], num_qubits=10) circuit = EfficientSU2(num_qubits=10) values = [i / 100 for i in range(circuit.num_parameters)] gradient = ReverseEstimatorGradient() result = gradient.run([circuit], [observable], [values]).result() -
Añadido un nuevo argumento de palabra clave,
use_dagal constructor de la claseOneQubitEulerDecomposerclase. Siuse_dagestá configurado comoTrue, la salida del descomponedor será un objetoDAGCircuiten lugar de un objetoQuantumCircuitobjeto. Esto es útil para los pases de transpilador que utilizanOneQubitEulerDecomposer(comoOptimize1qGatesDecomposition), ya que al trabajar directamente conDAGCircuitevita la sobrecarga de convertir entreQuantumCircuityDAGCircuit. -
Se ha añadido la posibilidad de que los pases de análisis establezcan pesos heurísticos personalizados para el
VF2LayoutyVF2PostLayouttranspiladores. Si un pase de análisis establece la clavevf2_avg_error_mapen el conjunto de propiedades, su valor se utiliza para las ponderaciones de error en lugar de las tasas de error del backend deTarget(oBackendPropertiesparaBackendV1). El valor debe ser una instancia deErrorMap, donde cada valor representa la tasa de error media para todas las operaciones de 1 o 2 qubits en esos qubits. Si un valor esNaN, la arista correspondiente se trata como una arista ideal (o qubit para las operaciones 1q ). Por ejemplo, un mapa de error creado como:from qiskit.transpiler.passes.layout.vf2_utils import ErrorMap error_map = ErrorMap(3) error_map.add_error((0, 0), 0.0024) error_map.add_error((0, 1), 0.01) error_map.add_error((1, 1), 0.0032)describe un objetivo de 2 qubits, donde la tasa media de error 1q es
0.0024en el qubit 0 y0.0032en el qubit 1, la tasa media de error 2q para las puertas que operan en (0, 1) es 0.01, y (1, 0) no está soportado por el objetivo. Se utilizará para la puntuación si se establece para la clavevf2_avg_error_mapen el conjunto de propiedades cuandoVF2LayoutyVF2PostLayoutse ejecutan. Por ejemplo:from qiskit.transpiler import AnalysisPass, PassManager, Target from qiskit.transpiler.passes import VF2Layout from qiskit.transpiler.passes.layout.vf2_utils import ErrorMap from qiskit.circuit.library import CZGate, UGate from qiskit.circuit import Parameter class CustomVF2Scoring(AnalysisPass): """Set custom score for vf2.""" def run(self, dag): error_map = ErrorMap(3) error_map.add_error((0, 0), 0.0024) error_map.add_error((0, 1), 0.01) error_map.add_error((1, 1), 0.0032) self.property_set["vf2_avg_error_map"] = error_map target = Target(num_qubits=2) target.add_instruction( UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')), {(0,): None, (1,): None} ) target.add_instruction( CZGate(), {(0, 1): None} ) vf2_pass = VF2Layout(target=target, seed=1234568942) pm = PassManager([CustomVF2Scoring(), vf2_pass])Eso funcionará
VF2Layoutcon la puntuación personalizada deerror_mappara un 2 qubitTargetque no contiene ninguna tasa de error.
Notas de actualización
-
Al inicializar cualquiera de las clases de pulso en
qiskit.pulse.library:proporcionar un argumento complejo
ampcon unanglefinito dará como resultadoPulseErrorahora. Por ejemplo, en lugar de llamar aGaussian(duration=100,sigma=20,amp=0.5j)ahora se debería utilizarGaussian(duration=100,sigma=20,amp=0.5,angle=np.pi/2). La envolvente de impulsos que antes se definía comoamp * ...se define a su vez comoamp * exp(1j * angle) * .... Este cambio se hizo para soportar mejor los experimentos Qiskit en los que la amplitud y el ángulo de los pulsos se calibran en experimentos separados. -
Para Python 3.7 singledispatchmethod es ahora una dependencia. Se ha añadido para poder aprovechar el mecanismo de envío de métodos de la biblioteca estándar de las nuevas versiones de Python. Si está en Python >= 3.8 no se requiere ninguna dependencia adicional.
-
El anteriormente obsoleto
MSBasisDecomposertranspiler pass disponible a través del móduloqiskit.transpiler.passesha sido eliminado. Originalmente fue obsoleto como parte de la versión de Qiskit Terra 0.16.0 (10-16-2020). En cambio, elBasisTranslatorpara traducir un circuito a una base adecuada con un valor deRXXGate -
EquivalenceLibraryque se inicialicen con el atributobasedejarán de tener una referencia compartida con el objetoEquivalenceLibrarypasado. En versiones anteriores, si se mutababasedespués de haber sido utilizado para crear una nueva instancia, ambas instancias reflejarían el cambioEquivalenceLibraryambas instancias reflejarían ese cambio. Esto ya no es así y las actualizaciones debaseya no se reflejarán en el nuevoEquivalenceLibrary. Por ejemplo, si ha creado una biblioteca de equivalencias con:import math from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import XGate from qiskit.circuit.equivalence import EquivalenceLibrary original_lib = EquivalenceLibrary() qc = QuantumCircuit(1) qc.rx(math.pi, 0) original_lib.add_equivalence(XGate(), qc) new_lib = EquivalenceLibrary(base=original_lib)si modificó
original_libcon:import from qiskit.circuit.library import SXGate qc = QuantumCircuit(1) qc.rx(math.pi / 2, 0) original_lib.add_equivalence(SXGate(), qc)en versiones anteriores,
new_libtambién incluía la definición deSXGatedespués de añadirla aoriginal_lib, pero en esta versión ya no será así. Este cambio se hizo debido al cambio en la estructura interna de datos para ser un gráfico, lo que mejoró el rendimiento de laEquivalenceLibraryclase, especialmente cuando hay múltiples ejecuciones delBasisTranslatorpase del transpilador. -
El argumento
initial_statepara el constructor de la claseNLocalclase junto con la asignación directa al atrributoNLocal.initial_statedebe ser unQuantumCircuitahora. Ya no es posible utilizar otros tipos para este argumento y atributo. La compatibilidad con otros tipos quedó obsoleta como parte de la versión de Qiskit Terra 0.18.0 (julio de 2021). -
Los cajones de matrices LaTeX (por ejemplo,
array_to_latex,Statevector.draw('latex')) utilizan ahora la misma función sympy que el cajón ket-convention. Esto significa que puede que algunos números se muestren de forma diferente a las versiones anteriores, pero proporcionará una experiencia más coherente. Por ejemplo, puede identificar nuevos factores o racionalizar denominadores donde antes no lo hacía. El valor por defectoprecisionse ha cambiado de 5 a 10. -
La versión del formato QPY emitida por
dump()se ha aumentado a la versión 6. Esta nueva versión del formato es incompatible con las versiones anteriores y producirá un error al intentar cargarlo con un deserializador que no sea capaz de manejar la versión 6 de QPY. Este cambio era necesario para soportar la introducción deScalableSymbolicPulse, que se gestionaba añadiendo un atributoclass_name_sizea la cabecera de los objetos volcadosSymbolicPulsevolcados. -
El método
__hash__para laSymbolicPulsefue eliminado. Esto se hizo para reflejar la naturaleza mutable (a través de la asignación de parámetros) de esta clase que podría dar lugar a errores cuando se utilizaSymbolicPulseen situaciones en las que se requería un objeto hashable. Esto significa que el método incorporadohash()y el uso deSymbolicPulsecomo claves en diccionarios o miembros de conjuntos ya no funcionarán. -
Los nombres de
Register(que incluyen instancias deQuantumRegisteryClassicalRegigster) ya no están limitados a ser identificadores válidos de OpenQASM 2. Esto se hace porque la restricción es demasiado estricta a medida que Qiskit se desvincula más de OpenQASM 2, e incluso la especificación OpenQASM 3 no es tan restrictiva. Si confiaba en que los registros tuvieran nombres de identificador válidos en OpenQASM 2, tendrá que empezar a escapar los nombres. Una versión simplista de esto podría hacerse, por ejemplo:import re import string def escape(name: str) -> str: out = re.sub(r"\W", "_", name, flags=re.ASCII) if not out or out[0] not in string.ascii_lowercase: return "reg_" + out return out -
Los métodos
QuantumCircuitu1,u2,u3, y sus variantes controladascu1,cu3ymcu1se han eliminado tras su desaprobación en Qiskit Terra 0.16.0. Con ello se pretendía eliminar los nombres de las puertas, que solían ser específicos de IBM, en favor de los métodos más generalesp(),u(),cp()ycu(). Las clases de puertaU1Gate,U2GateyU3Gatesiguen estando disponibles para su uso conQuantumCircuit.append()por lo que los backends pueden seguir soportando bases con estas puertas explícitamente dadas. -
Los métodos
QuantumCircuitcombineyextendse han eliminado tras su desaparición en Qiskit Terra 0.17.0. Esto se hizo porque estas funciones eran simplemente versiones menos potentes deQuantumCircuit.compose()que deberían utilizarse en su lugar.La supresión de
extendsignifica también que los operadores+y+=ya no están definidos para los operadoresQuantumCircuit. En su lugar, puede utilizar los operadores&y&=respectivamente, que utilizanQuantumCircuit.compose(). -
Se han eliminado las funciones anteriormente obsoletas:
qiskit.circuit.measure.measure()yqiskit.circuit.reset.reset(). Estas funciones quedaron obsoletas en la versión de Qiskit Terra 0.19.0 (diciembre de 2021). En su lugar, debe utilizar las etiquetasQuantumCircuit.measure()yQuantumCircuit.reset()del objetoQuantumCircuital que desea añadir unMeasureoResetal objeto. -
Los métodos
ParameterViewanteriormente obsoletos que se heredaban desetse han eliminado deParameterView, el tipo devuelto porQuantumCircuit.parameters. Los métodos específicos que se han eliminado son:add()difference()difference_update()discard()intersection()intersection_update()issubset()issuperset()symmetric_difference()symmetric_difference_update()union()update()
junto con el apoyo a los operadores de Python :
ixor:^=isub:-=ior:|=
Estos fueron obsoletos en la versión de Qiskit Terra 0.17.0 (Abril, 2021). El tipo
ParameterViewes ahora un tipo de vista de secuencia general y ya no admite estas operacionesset. -
Los métodos de conversión NetworkX para los métodos
DAGCircuityDAGDependency:DAGCircuit.to_networkx(),DAGCircuit.from_networkx(), yDAGDependency.to_networkx()han sido eliminados. Estos métodos fueron originalmente obsoletos como parte de la versión de Qiskit Terra 0.21.0 (Junio, 2022). Qiskit ha estado utilizando rustworkx como su biblioteca de gráficos desde la versión qiskit-terra 0.12.0 y desde entonces la función de convertidor NetworkX han sido un proceso con pérdidas. Se añadieron originalmente para que los usuarios pudieran aprovechar la biblioteca de algoritmos NetworkX’s para aprovechar funcionalidades no presentes enDAGCircuity/o rustworkx. Sin embargo, desde entonces tantoDAGCircuity rustworkx han madurado y ofrecen más funcionalidad y elDAGCircuitestá estrechamente acoplado a rustworkx para su funcionamiento y tener estos métodos convertidores proporcionaba una funcionalidad limitada y por lo tanto han sido eliminados. -
tweedledumse ha eliminado como requisito básico de Qiskit Terra. La funcionalidad proporcionada (qiskit.circuit.classicalfunction) sigue estando disponible, sitweedledumse instala manualmente, como por:pip install tweedledumEste cambio se hizo porque el desarrollo de
tweedledumse ha ralentizado hasta el punto de no seguir el ritmo de las nuevas versiones de Python y OS, y estaba bloqueando a algunos usuarios de Qiskit la instalación de Qiskit. -
Los verificadores opcionales perezosos
HAS_MATPLOTLIB,HAS_PIL,HAS_PYLATEXyHAS_PDFTOCAIROya no se exponen desdeqiskit.visualizational haber sido obsoletos en Qiskit Terra 0.21. La ubicación canónica de estos (y muchos otros comprobadores perezosos) esqiskit.utils.optionalsy los cuatro objetos pueden encontrarse allí. -
Se ha eliminado el argumento
gate, anteriormente obsoleto, del constructor delDecomposejunto con su atributo correspondienteDecompose.gate. El argumento y el atributo quedaron obsoletos como parte de la versión de Qiskit Terra 0.19.0 (diciembre de 2021). En su lugar, debe utilizarse el argumentogates_to_decomposepara el constructor junto con el atributoDecompose.gates_to_decompose. El argumento y atributogates_to_decomposedebería funcionar igual, pero tiene un nombre más explícito y también permite especificar listas de puertas en lugar de admitir una sola puerta. -
El argumento anteriormente obsoleto
labelpara el constructor de la funciónMCMTyMCMTVChainha sido eliminado. Fue obsoleto a partir de la versión de Qiskit Terra 0.19.0 (diciembre de 2021). El uso del argumentolabelen estas clases tenía un comportamiento indefinido ya que son subclases deQuantumCircuiten lugar deInstruction. El resultado sería que la etiqueta asignada generalmente se ignoraría. Si necesita asignar unlabela una instancia deMCMToMCMTVChaindebe convertirlos en unaGateconto_gate()y luego asignar la etiqueta deseada al atributolabelatributo. Por ejemplo:from qiskit.circuit.library import MCMT, XGate mcmt_circuit = MCMT(XGate(), 3, 2) mcmt_gate = mcmt_circuit.to_gate() mcmt_gate.label = "Custom MCMT X" -
La dependencia
retworkxpara Qiskit ha sido eliminada y sustituida por la bibliotecarustworkx. Se trata de los mismos paquetes, perorustworkxes el nuevo nombre deretworkx, que fue rebautizado como parte de su versión combinada 0.12.0. Si antes utilizabas retworkx 0.12.0 con Qiskit, entonces ya has instalado rustworkx (retworkx 0.12.0 era sólo un calce de redirección para compatibilidad con versiones anteriores). Este cambio se ha realizado para migrar al nuevo nombre del paquete, que será el único admitido en el futuro. -
El comportamiento por defecto del
SabreLayoutpass del compilador ha cambiado. El pase ya no es unAnalysisPassy por defecto calculará el layout inicial, lo aplicará al circuito, y también ejecutaráSabreSwapinternamente y aplicará el mapeado swap y establecerá la propiedadfinal_layoutcon la permutación causada por las inserciones swap. Esto significa para los usuarios que ejecutanSabreLayoutcomo parte de un sistema personalizadoPassManagertendrán que ajustar el gestor de pases para tener esto en cuenta (a menos que estuvieran configurando el argumentorouting_passparaSabreLayout). Este cambio se ha realizado con el fin de mejorar la calidad de los resultadosSabreLayoutpara calcular qué semilla proporciona los mejores resultados es necesario realizar el trazado y el enrutamiento conjuntamente. Hay tres formas de ajustar el uso en el gestor de pases personalizados. La primera es evitar el uso de la incrustación en el gestor de pases predefinidos. Si anteriormente estaba ejecutando algo como:from qiskit.transpiler import PassManager from qiskit.transpiler.preset_passmanagers import common from qiskit.transpiler.passes.SabreLayout pm = PassManager() pm.append(SabreLayout(coupling_map) pm += common.generate_embed_passmanager(coupling_map)para calcular el trazado y luego aplicarlo (que normalmente iba seguido del enrutamiento) se puede ajustar el uso para que simplemente sea:
from qiskit.transpiler import PassManager from qiskit.transpiler.preset_passmanagers import common from qiskit.transpiler.passes.SabreLayout pm = PassManager() pm.append(SabreLayout(coupling_map)como
SabreLayoutaplicará el diseño y ya no necesitará la etapa de incrustación. Alternativamente, puede especificar el argumentorouting_passque revertiráSabreLayouta su comportamiento anterior. Por ejemplo, si desea ejecutarSabreLayouttal y como se ejecutaba en versiones anteriores puedes hacer algo comofrom qiskit.transpiler.passes import SabreSwap, SabreLayout routing_pass = SabreSwap( coupling_map, "decay", seed=seed, fake_run=True ) layout_pass = SabreLayout(coupling_map, routing_pass=routing_pass, seed=seed)que tendrá
SabreLayoutejecutado como un pase de análisis y sólo establecerá el conjunto de propiedadeslayout. El enfoque final es aprovechar el argumentoskip_routingenSabreLayout, cuando este argumento se establece enTrueomitirá la aplicación del diseño encontrado y la inserción de las puertas de intercambio de enrutamiento. Sin embargo, hacer esto tiene una penalización en tiempo de ejecución ya queSabreLayoutseguirá calculando el enrutamiento y simplemente no utiliza estos datos. Los dos primeros enfoques descritos no llevan asociados gastos generales adicionales. -
Los diseños calculados por el pase
SabreLayoutpass (cuando se ejecuta sin el argumentorouting_pass) con un valor de semilla fijo pueden cambiar con respecto a versiones anteriores. Esto es causado por un nuevo generador de números aleatorios que se utiliza como parte de la reescritura de laSabreLayouten Rust, lo que ha mejorado significativamente el rendimiento. Si confías en tener una salida consistente puedes ejecutar el pase en una versión anterior de Qiskit y aprovecharqiskit.qpypara guardar el circuito y luego cargarlo utilizando la versión actual. También puede establecer explícitamente el argumentorouting_passen una instancia deSabreSwappara reflejar el comportamiento anterior deSabreLayout:from qiskit.transpiler.passes import SabreSwap, SabreLayout routing_pass = SabreSwap( coupling_map, "decay", seed=seed, fake_run=True ) layout_pass = SabreLayout(coupling_map, routing_pass=routing_pass, seed=seed)que reflejará el comportamiento del pase en la versión anterior. Tenga en cuenta que si en versiones anteriores utilizaba el argumento
swap_trialsenSabreLayouten versiones anteriores al ajustar el uso a esta forma, deberá establecer el argumentotrialsen el constructorSabreSwapsi desea conservar la salida anterior con una semilla fija. -
El circuito exacto devuelto por
qiskit.circuit.random.random_circuitpara una semilla dada ha cambiado. Esto se debe a mejoras de eficiencia en la generación interna de números aleatorios para la función. -
El requisito de versión para el paquete de funciones opcionales
qiskit-toqm, instalable a través depip install qiskit-terra[toqm], se ha actualizado de la versión0.0.4a0.1.0. Para utilizar el método de enrutamientotoqmcontranspile()ahora debe utilizar qiskit-toqm versión0.1.0o más reciente. Las versiones anteriores ya no son detectables por el transpilador. -
La salida
QuasiDistributiondel métodoSampler.runse ha actualizado para filtrar los estados con probabilidad cero. Ahora, si falta un estado válido en la salida del diccionario, se puede suponer que tiene una probabilidad 0. Anteriormente, todos los resultados posibles para un número determinado de bits (por ejemplo, para un resultado de 3 bits000,001,010,011,100,101,110, y111) aunque la probabilidad de un estado determinado fuera 0. Este cambio se realizó para reducir el tamaño de la salida, ya que para un mayor número de bits el tamaño de la salida podía ser bastante grande. Además, el filtrado de los resultados de probabilidad cero hace que la salida sea coherente con otras implementaciones deBaseSampler. -
Se ha actualizado el comportamiento del generador de impulsos cuando se llama a
Scheduleha sido actualizado. Los horarios llamados se convierten internamente enScheduleBlocky ahora se aplica siempre el mecanismo de referencia en lugar de añadir los horarios envueltos por la instrucciónCallinstrucción. Tenga en cuenta que el bloque convertido no tiene por qué recuperar el contexto de alineación original. Se trata simplemente de una secuencia alineada ASAP de instrucciones de pulso con intervalos de tiempo absolutos. Se trata de una actualización de la representación interna de los programas de pulsos llamados y, por tanto, no hay cambios en la API. No obstante, laCallinstrucción yScheduleya no aparecen en el programa de pulso del constructor. Este cambio garantiza que los bloques de programación generados sean siempre compatibles con QPY. Si filtra las instrucciones de programación de salida porCallpuede acceder aScheduleBlock.referencesen su lugar para recuperar el programa llamado. -
RZXCalibrationBuilderyRZXCalibrationBuilderNoEchotranspiler pass se han actualizado para generarScheduleBlock. Este cambio garantiza que los circuitos transpilados sean siempre compatibles con QPY. Si está utilizando directamenterescale_cr_inst()de otro programa o de una subclase del pase para reescalar el pulso de resonancia cruzada del dispositivo, ahora este método se ha convertido en una macro del constructor de pulsos, y necesita utilizar este método dentro del contexto del constructor de pulsos para adoptar la nueva versión. La llamada al método inyecta una instrucción de reproducción al programa de pulso contextual, en lugar de devolver unaPlayinstrucción con el pulso estirado.
Notas sobre características en desuso
-
El soporte para ejecutar Qiskit con Python 3.7 ha sido obsoleto y será eliminado en la versión qiskit-terra 0.25.0. Esto significa que a partir de la versión 0.25.0 deberá actualizar la versión Python que esté utilizando a Python 3.8 o superior.
-
La clase
LinearFunctionsSynthesisestá obsoleta y se eliminará en una futura versión. Ha sido sustituida por la clase más generalHighLevelSynthesisque debe utilizarse en su lugar. Por ejemplo, puede instanciar una instancia deHighLevelSynthesisque se comportará de la misma manera queLinearFunctionSynthesiscon:from qiskit.transpiler.passes import HighLevelSynthesis from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig HighLevelSynthesis( HLSConfig( linear_function=[("default", {})], use_default_on_unspecified=False, ) ) -
El soporte para pasar listas de valores de argumentos a la función
transpile()está obsoleta y se eliminará en la versión 0.25.0. Esto se hace para facilitar en gran medida la reducción de la sobrecarga de ejecución paralela para transpilar varios circuitos a la vez. Si está utilizando esta funcionalidad actualmente, puede llamar atranspile()varias veces. Por ejemplo, si antes hacías algo como:from qiskit.transpiler import CouplingMap from qiskit import QuantumCircuit from qiskit import transpile qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) qc.measure_all() cmaps = [CouplingMap.from_heavy_hex(d) for d in range(3, 15, 2)] results = transpile([qc] * 6, coupling_map=cmaps)en su lugar debe ejecutar algo como:
from itertools import cycle from qiskit.transpiler import CouplingMap from qiskit import QuantumCircuit from qiskit import transpile qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) qc.measure_all() cmaps = [CouplingMap.from_heavy_hex(d) for d in range(3, 15, 2)] results = [] for qc, cmap in zip(cycle([qc]), cmaps): results.append(transpile(qc, coupling_map=cmap))También puede aprovechar
parallel_map()omultiprocessingde la biblioteca estándar Python si desea ejecutar esto en paralelo. -
La versión heredada del cajón de pulsos presente en
qiskit.visualization.pulseha quedado obsoleta y se eliminará en una futura versión. Esto incluye las clasesScheduleDrawery :class`WaveformDrawer`. Este módulo ha sido sustituido por el cajónqiskit.visualization.pulse_v2y la API de usuario típicapulse_drawer()yPulseBlock.draw()ya están actualizadas internamente para utilizarqiskit.visualization.pulse_v2. -
El método
pulse.Instruction.draw()ha quedado obsoleto y se eliminará en una futura versión. La necesidad de este método ha sido sustituida por el cajónqiskit.visualization.pulse_v2que no requiere que los objetosInstruciontengan su propio método de dibujo. Si necesitas dibujar una instrucción de pulso debes aprovechar el botónpulse_drawer()en su lugar. -
La importación
qiskit.circuit.qpy_serializationestá obsoleta, ya que QPY ha sido promocionado al nivel superior. Debería importar los mismos objetos deqiskit.qpyen su lugar. El antiguo camino se eliminará en un futuro de Qiskit Terra. -
El objeto
qiskit.IBMQestá obsoleto. Este objeto alias redirige perezosamente el acceso a los atributos aqiskit.providers.ibmq.IBMQ. Dado que el paqueteqiskit-ibmq-providerha sido sustituido por el paqueteqiskit-ibm-provider, que mantiene su propio espacio de nombres, el mantenimiento de este alias ya no es relevante con el nuevo paquete. Si dependía del aliasqiskit.IBMQ, debería actualizar su uso para utilizar directamenteqiskit.providers.ibmq.IBMQen su lugar (y también considerar la migración aqiskit-ibm-provider, consulte la guía de migración para obtener más detalles). -
Varios métodos públicos de los conversores pulse Qobj han quedado obsoletos y en una futura versión ya no se podrán llamar directamente. La lista de métodos es:
En
InstructionToQobjConverter,convert_acquire()convert_bundled_acquires()convert_set_frequency()convert_shift_frequency()convert_set_phase()convert_shift_phase()convert_delay()convert_play()convert_snapshot()
En
QobjToInstructionConverter,convert_acquire()convert_set_phase()convert_shift_phase()convert_set_frequency()convert_shift_frequency()convert_delay()bind_pulse()convert_parametric()convert_snapshot()
En lugar de llamar directamente a cualquiera de estos métodos, se seleccionarán implícitamente cuando se llame directamente a una instancia del conversor. Por ejemplo:
converter = QobjToInstructionConverter() converter(pulse_qobj) -
Las funciones
qiskit.visualization.state_visualization.num_to_latex_ket()yqiskit.visualization.state_visualization.num_to_latex_terms()han quedado obsoletas y se eliminarán en una futura versión. Esta función era utilizada principalmente a nivel interno por la salida LaTeX deStatevector.draw()yDensityMatrix.draw()que ya no utilizan esta función y en su lugar utilizan sympy. Si estabas usando estas funciones deberías cosinder usar las funciones nsimplify() latex() de Sympy. -
El método
Register.qasm()está obsoleto y se eliminará en una futura versión. Este método se encuentra en las subclasesQuantumRegisteryClassicalRegister. La desaprobación se debe a que el métodoqasm()promueve una falsa visión del responsable de la conversión segura a OpenQASM 2; un único objeto por sí solo no tiene el contexto para proporcionar una conversión segura, como por ejemplo si su nombre choca después de escaparlo para producir un identificador válido. -
La expresión regular class-variable
Register.name_formatestá obsoleta y se eliminará en una futura versión. Ahora se permite que los nombres de los registros sean cualquier cadena válida de Python, por lo que la expresión regular ya no tiene utilidad. -
Las funciones
qiskit.quantum_info.synthesis.decompose_clifford()yqiskit.quantum_info.synthesis.decompose_cnot_dihedral()están obsoletas y se eliminarán en una futura versión. Se sustituyen por las dos funcionesqiskit.synthesis.synth_clifford_full()yqiskit.synthesis.synth_cnotdihedral_full()respectivamente.
Corrección de errores
-
Se ha corregido un problema en el método
PauliOp.adjoint()por el que devolvía el valor correcto para Paulis con coeficientes complejos, por ejemplo:PauliOp(Pauli("iX")). Corregido #9433. -
Se ha corregido un problema con los algoritmos de estimación de amplitud en el módulo
qiskit.algorithms.amplitude_estimators(véaseamplitude_estimators) para el uso con primitivas construidas a partir de la primitiva abstractaBaseSampler(comoSampleryBackendSampler). Anteriormente, los resultados de las mediciones se ampliaban a más bits de los realmente medidos, lo que en el caso de los oráculos con más de un qubit conducía a posibles errores en la detección de los estados cuánticos "buenos" para los oráculos. -
Se ha solucionado un problema por el que los métodos
QuantumCircuit.add_calibrations()yDAGCircuit.add_calibrations()no coincidían en su comportamiento de la lógica de formato de parámetros. AnteriormenteDAGCircuit.add_calibrations()intentaba convertir cada parámetro enfloat,QuantumCircuit.add_calibrations()utilizaba los parámetros dados tal cual. Esto podría causar un error cuando se ejecutatranspile()en unQuantumCircuitcon puertas de impulsos, ya que los parámetros de las calibraciones podrían mantenerse como objetos deParameterExpresion. -
Se ha corregido un problema de deserialización en el archivo (
qiskit.qpy)load()donde los circuitos que contienen puertas de claseMCXGate,MCXGrayCode,MCXRecursiveyMCXVChainno se deserializarían. Corregido #9390. -
Se ha corregido un problema en
TensoredOp.to_matrix()donde el coeficiente global del operador se multiplicaba a la matriz final más de una vez. Ahora, el coeficiente global se aplica correctamente, independientemente del número de operadores o estados tensados. Corregido #9398. -
La salida del método
run()de la claseBackendSamplerestablece ahora los atributosshotsystddev_upper_boundde la clase devueltaQuasiDistribution. Anteriormente faltaban estos atributos, lo que impedía algunos postprocesamientos con la salida. Corregido #9311 -
El método de exportación OpenQASM 2
QuantumCircuit.qasm()emitirá por defecto números de coma flotante de mayor precisión para los parámetros de la puerta. Además, se utiliza un límite más estricto ( en lugar de ) para comprobar si un parámetro dado está cerca de una fracción/potencia de . Corregido #7166. -
Soporte fijo en el módulo
primitivespara ejecutarQuantumCircuitcon instrucciones de flujo de control (p. ej.IfElseOp). Anteriormente, las clases baseBaseSampleryBaseEstimatorno podían normalizar correctamente este tipo de circuitos. Sin embargo, la ejecución de estos circuitos depende de la implementación concreta de la primitiva que soporta las instrucciones de flujo de control. Esto sólo fija el soporte para permitir que una implementación particular deBaseSampleroBaseEstimatorutilice instrucciones de flujo de control. -
Se ha corregido un problema con el método
PauliOp.matmul()que devolvía resultados incorrectos coniI. Corregido #8680. -
Se ha corregido un problema con la clase Compilador Cuántico Aproximado (
AQC) que provocaba que devolviera un circuito incorrecto cuando el unitario de entrada tenía un determinante de -1. Corregido #9327 -
Se ha corregido un problema con el método
QuantumCircuit.compose()que rechazaba incorrectamente especificadores qubit o clbit válidos. Esto se ha corregido para que el método acepte ahora el mismo conjunto de especificadores qubit y clbit que otros métodosQuantumCircuitcomoappend(). Corregido #8691. -
Se ha corregido un problema con el método
QuantumCircuit.compose()que asignaba incorrectamente registros en condiciones en el circuito dado a registros completos en la base. Anteriormente, el mapeo era muy impreciso; los bits utilizados dentro de cada condición no estaban sujetos al mapeo y, en su lugar, se intentaba encontrar un registro correspondiente de forma imprecisa. Esto también podría dar lugar a una condición en un registro más pequeño que se expande para estar en un registro más grande, que no es una transformación válida. Ahora, una condición sobre un solo bit o un registro se compondrá para estar precisamente sobre los bits definidos por el argumentoclbits. Se añadirá un nuevo registro de aliasing al circuito base para facilitarlo, si es necesario. Corregido #6583. -
Se ha corregido un problema con la función
transpile()cuando se ejecutaba conoptimization_levelestablecido en1,2, o3y no se especificaba ningún argumentobackend,basis_gates, otarget. Si el circuito de entrada tuviera pasadas de compuertas de un solo qubit que pudieran simplificarse, el circuito de salida no estaría lo más optimizado posible, ya que esas pasadas de compuertas de un solo qubit no se habrían eliminado. Esto podría haberse corregido anteriormente especificando los argumentosbackend,basis_gates, otargeten la llamadatranspile()pero ahora la salida será lo más simplificada posible sin conocer las puertas de destino permitidas. Corregido #9217 -
Se ha corregido un problema con la función
transpile()cuando se ejecutaba conoptimization_level=3y no se especificaba ningún argumentobackend,basis_gatesotarget. Si el circuito de entrada contuviera algún bloque de 2 qubits equivalente a una matriz identidad, el circuito de salida no estaría lo más optimizado posible y seguiría conteniendo ese bloque identidad. Esto podría haberse corregido anteriormente especificando los argumentosbackend,basis_gates, otargeten la llamadatranspile()pero ahora la salida será lo más simplificada posible sin conocer las puertas de destino permitidas. Corregido #9217 -
Se ha corregido un problema con
LinCombSamplerGradientque podía generar un error cuando se ejecutaba con la claseSamplerdeqiskit-aer. -
Se ha corregido un problema con
NumPyEigensolvery por extensiónNumPyMinimumEigensolverpor el que la resolución de subclases deBaseOperatordistintas deOperatorprovocaba un error. -
Se ha corregido un problema en la salida de metadatos de
primitivesdonde la lista hacía copias por referencia y todos los elementos se actualizaban con el mismo valor en cada iteración. -
Se ha solucionado un problema con
QobjToInstructionConvertercuando se llama a varios backends y accidentalmente tienen el mismo nombre de pulso en la biblioteca de pulsos. Se trataba de un caso extremo que sólo podía producirse cuando se reutilizaba una instancia de convertidor en varios backends (no era un patrón de uso típico). -
Se ha corregido un problema con la clase
PVQDpor el que la función de pérdida elevaba incorrectamente al cuadrado la fidelidad. Esto se ha corregido para que la función de pérdida coincida con la definición del algoritmo original. -
Se ha corregido un error en QPY (
qiskit.qpy) por el que los circuitos que contenían registros cuyos bits ocurrían en el circuito después de bits sueltos fallaban al deserializar. Ver #9094. -
La clase
TwoQubitWeylDecompositiones ahora compatible con el protocolopickle. Anteriormente, fallaba la deserialización y aparecía el mensajeTypeError. Ver #7312. -
Se ha corregido un problema con el método
LocalReadoutMitigator.quasi_probabilities()por el que no se utilizaba el argumentoshots. Ahora se utiliza para establecer el número de disparos en el objeto de retorno. -
Corregida una regresión en la construcción de
Cliffordobjetos deQuantumCircuitsque contienen otrosCliffordobjetos. -
Se ha corregido un problema con la clase
TwoQubitWeylDecomposition(y sus subclases) para permitir que la biblioteca estándar Pythonpickleserialice estas clases. Se ha corregido parcialmente #7312 -
QuantumCircuit.qasm()ahora escapará correctamente los nombres de puertas y registros que colisionen con palabras clave reservadas de OpenQASM 2. Correcciones #5043. -
Se ha corregido un problema en el
RZXCalibrationBuilderdonde la secuencia de pulsos ECR estaba desalineada. Corregido #9013. -
Se ha solucionado un problema con el
pulse_drawer()por el que, en algunos casos, la visualización de salida omitía algunos de los canales de una programación. Corregido #8981.
Aer 0.11.2
No cambia
IBM Proveedor Q 0.19.2
No cambia