Qiskit SDK 2.2 notas de la versión
2.2.3
Preludio
Qiskit 2.2.3 corrige un error introducido por Qiskit 2.2.2 al utilizar el run() método en un PassManager para más de un circuito.
Notas de actualización
ConsolidateBlocksahora lee unaPropertySetclaveConsolidateBlocks_qubit_mapal entrar. Esta clave y su valor no son públicos y no deben ser leídos ni escritos por otros pases.
Corrección de errores
- Reutilización fija de la misma
ConsolidateBlocksinstancia en múltiples circuitos, incluidas las llamadas atranspile()con más de un circuito y sin paralelización basada en procesos. Un error introducido en Qiskit 2.2.2 provocaba que el paso entrara en pánico o produjera resultados no válidos si se reutilizaba la misma instancia en circuitos diferentes.
2.2.2
Preludio
Qiskit 2.2.2 es una versión de corrección de errores para la serie de versiones menores v2.2.
Corrección de errores
-
Se ha corregido la implementación de
__deepcopy__()enQuantumCircuitque no realizaba una copia profunda de los parámetros del circuito. Como consecuencia, la mutación de unBoxOpen un circuito copiado ya no afecta al circuito original. -
Se ha corregido un problema en el
Optimize1qGatesDecompositionpaso cuando este se inicializa con unTargetque contiene puertas de 1 qubit con parámetros de ángulo fijos. Anteriormente, el pase podía generar puertas no incluidas en el objetivo, ya que no comprobaba si las puertas del objetivo admitían valores de parámetros arbitrarios. Corregido #14743. -
Se ha corregido un comportamiento incorrecto en el
BasisTranslatorpaso en el que una puerta de múltiples qubits dentro de unControlFlowOpbloque realizaba el seguimiento utilizando sus índices de qubits locales en lugar de utilizar los índices absolutos del circuito de origen. -
El paso del
ConsolidateBlockstranspilador ahora evaluará correctamente si una puerta determinada es compatible con el hardware mientras recurre a operaciones de flujo de control. -
qpy.dump()Ahora puede gestionar la escritura en.gzarchivos abiertos utilizando el módulo degzipla biblioteca estándar con versiones QPY 16 o superiores. Véase el n.º 15157 para más detalles. -
Se ha corregido el método
MCPhaseGate.inverse()para conservar los estados de control de las puertas controladas por apertura al calcular sus inversas. -
ConsolidateBlocksAhora devolverá una excepción « Python -space» en lugar de entrar en pánico cuando detecte un análisis no válido u obsoleto en las claves heredadasrun_list``block_listPropertySeto. Corregido #14646. -
Optimize1qGatesDecompositionAhora generará unTranspilerErroren lugar de un pánico del espacio Rust al intentar ejecutarse en un circuito que es demasiado grande para elTarget. Corregido #15116. -
Los pases de programación,
ALAPScheduleAnalysisyASAPScheduleAnalysis, ahora gestionarán correctamente los circuitos que no contengan operaciones. Anteriormente, plantearon unaTranspilerErrorafirmando falsamente que «no se proporcionaban duraciones». Corregido #15145. -
Se ha corregido un fallo en el cajón de texto del circuito, que podía producirse cuando los bloques de circuito dentro de las operaciones de flujo de control se definían en registros diferentes a los del circuito exterior. Esta situación podría darse, por ejemplo, al añadir
ControlFlowOpoperaciones directamente o en circuitos tras la transpilación.
2.2.1
Preludio
Qiskit 2.2.1 es un pequeño parche que corrige varios errores detectados en la versión 2.2.0.
Notas sobre la actualización del transpilador
- Los límites máximos de llamadas y pruebas para la ejecución de coincidencia exacta de
VF2PostLayoutenoptimization_level=3se han reducido para evitar tiempos de ejecución excesivos en circuitos de prueba altamente simétricos que se asignan a mapas de acoplamiento grandes.
Corrección de errores
-
DAGCircuit.apply_operation_back(),apply_operation_back()y ahoracircuit_to_dag()añadirá nuevos bordes en un orden determinista. El comportamiento anterior podía provocar que ciertas pasadas del transpilador (comoSabreSwap) recorrieran el DAG en órdenes no deterministas. -
DAGCircuit.apply_operation_front()Ya no se pueden insertar bucles autoinválidos al manejar nodos que incluyen condiciones clásicas. -
Se ha corregido un problema con
picklela compatibilidad con enSabreSwapel que unaSabreSwapinstancia daba error al ser encurtida después de ejecutar elSabreSwap.run()método. Corregido #15071. -
Se ha corregido un problema por el
is_unitary()que no respetaba correctamente los valores de tolerancia de entrada al comprobar si un operador era unitario. El método ahora utiliza correctamente los parámetrosrtolyatolproporcionados al simplificar el operador y comprobar si es igual a la identidad. Esto corrige el error n.º 14107.
2.2.0
Preludio
Qiskit v2.2 añade varias mejoras para la API de C y el transpilador, así como muchas otras mejoras y correcciones de errores. Las principales características de esta nueva versión son:
- Función de transpilación de la API C: La API C ahora incluye una función para transpilación de un circuito cuántico:
qk_transpile(). Esta función es equivalente a la función de Pythontranspile()para un contexto C independiente.- Paso de transformación Litinski: un nuevo paso de transformación
LitinskiTransformationque implementa la transformación descrita arXiv:1808.02892. Este paso se utiliza normalmente en la compilación para arquitecturas tolerantes a fallos.- Soporte de límites angulares para objetivos: La
Targetclase ahora admite la especificación de límites para los valores permitidos para las operaciones parametrizadas añadidas al objetivo. Cuando se añade una instrucción al,Targetse puede añadir el argumento opcional angle_bounds para especificar los límites superior e inferior de las puertas de rotación parametrizadas. Se ha añadidoWrapAnglesuna nueva pasada del transpilador para aplicar las restricciones de ángulo como parte de un proceso de transpilación.
La serie de versiones v2.2 es la última serie de versiones menores compatibles con Python 3.9. La versión mínima de Rust soportada para compilar Qiskit desde el código fuente es ahora Rust v1.85, subida desde 1.79 en 2.1.0. Para obtener más información sobre estos y otros cambios, consulte las notas de la versión y la documentación actualizada.
Características de la API C
-
Se han añadido nuevas funciones independientes de paso de transpilador a la API de C. Estas funciones toman un
QkCircuitpara ejecutar el pase y son equivalentes a llamar a un pase instanciado. -
El
QkTargettipo ahora puede representar objetivos que admiten tiposQkGateparametrizados que aceptan cualquier valor de parámetro. Anteriormente, estas puertas solo se podían añadir al objetivo con un valor de ángulo fijo compatible mediante el uso deqk_target_entry_new_fixed()para crear elQkTargetEntry. Ahora, laqk_target_entry_new()función se puede utilizar con puertas parametrizadas. Cuando se utiliza con puertas parametrizadas, esta función indica que la puerta del objetivo admite cualquier valor para todos los parámetros de la puerta. Por ejemplo:#include <qiskit.h> QkTarget *target = qk_target_new(5); QkTargetEntry *rz_entry = qk_target_entry_new(QkGate_RZ); for (uint32_t i = 0; i < 5; i++) { uint32_t qargs[1] = {i}; qk_target_entry_add_property(rz_entry, qargs, 1, 1.2e-6, 1.3e-9); } qk_target_add_instruction(target, rz_entry); // Clean up after using target qk_target_free(target);Esto crea un objetivo de 5 qubits que aceptará una puerta RZ en cualquier qubit con cualquier valor de parámetro soportado por esa puerta.
-
Añadido
qk_obs_apply_layout()para aplicar nuevos diseños de qubits a unQkObsobservable. Esta función toma el observable, los nuevos índices de qubits y un número de qubits de salida. Es importante destacar que esta función permite aplicar diseños de transpilación, normalmente proporcionados porQkTranspileLayoutuna pasada de transpilador, a un observable. Por ejemplo:// get the number of output qubits -- transpile_layout is a QkTranspileLayout* uint32_t num_output_qubits = qk_transpile_layout_num_output_qubits(transpile_layout); // get the layout including the ancillas (hence the ``false`` in the function call) uint32_t *layout = malloc(sizeof(uint32_t) * num_output_qubits); qk_transpile_layout_final_layout(transpile_layout, false, layout); // apply the layout -- obs is a QkObs* int exit = qk_obs_apply_layout(obs, layout, num_output_qubits); // free the layout array free(layout); -
Se ha añadido una nueva función
qk_transpile()a la API C de Qiskit. Esta función se utiliza para transpilear circuitos cuánticos en un contexto C independiente sin utilizar Python. Este es el último componente importante que se necesita en la API C para los flujos de trabajo típicos de ejecución de hardware que utilizan Qiskit.Esta función refleja los gestores de pases preestablecidos que se utilizan para el transpilador Python excepto en algunos pases y la funcionalidad se omite si no es relevante para los circuitos construidos utilizando la API de C. Esto hace que la función sólo sea adecuada para contextos C autónomos.
-
Añadido un nuevo tipo
QkTranspileLayouta la API de C. Este tipo se utiliza para razonar sobre las permutaciones causadas por el transpilador.
Características de los circuitos
-
Se proporciona un nuevo método para garantizar que un circuito se defina sobre qubits físicos,
QuantumCircuit.ensure_physical()con los índices de qubits haciendo referencia a qubits físicos. Consulte el nuevo debate sobre representaciones abstractas y de circuitos físicos en la documentación para obtener más detalles sobre los conceptos de metadatos. Los conceptos de circuitos «abstractos» y «físicos» no son nada nuevo para Qiskit, solo la documentación explícita. -
La clase
Durationha ganado una nueva varianteps, que puede utilizarse para representar una duración en picosegundos. -
Mejorado
PauliEvolutionGate.control(),PauliEvolutionGate.power()yPauliEvolutionGate.inverse()para devolver representaciones más eficientes en términos de aPauliEvolutionGate. Para calcular las versiones controladas y exponenciales de la puerta de evolución, este cambio da lugar a circuitos significativamente menos profundos y a un menor número de puertas en comparación con los mecanismos genéricos utilizados anteriormente. La descomposición inversa no cambia, pero ahora se genera de forma más eficiente y permite mejores optimizaciones del compilador. -
Se ha
ParameterExpression.bind_all()añadido un nuevo método de ruta rápida para admitir el caso de uso de vincular muchas instanciasParameterExpressiondiferentes a valores numéricos utilizando el mismo diccionario de asignaciones. El métodobind()existente tiene una gran cantidad de sobrecarga y asignaciones innecesarias, ya que siempre devuelve unParameterExpressionpara mantener la coherencia tipográfica.
OpenQASM Características
-
Se ha añadido compatibilidad parcial con
defcalsímbolos en el exportador OpenQASM3. Esto permite que los paquetes posteriores exporten instrucciones personalizadas que operan tanto en bits cuánticos como clásicos utilizandoqiskit.qasm3.dumps(). Los usuarios ahora pueden definir instrucciones personalizadas (por ejemplo, unaCustomMeasureque actúa sobre un qubit y devuelve un bit clásico) y especificar su comportamiento utilizandoDefcalInstruction. Estos defcals se pasan al exportador a través delimplicit_defcalsargumento enqiskit.qasm3.dumps().Por ejemplo:
from qiskit.circuit import Instruction, QuantumCircuit from qiskit.qasm3 import dumps from qiskit.qasm3.exporter import DefcalInstruction, types custom_measure = Instruction("measure_2", 1, 1, []) qc = QuantumCircuit(1, 1) qc.h(0) qc.append(custom_measure, [0], [0]) qc.measure(0, 0) defcals = { "measure_2": DefcalInstruction("measure_2", 0, 1, types.Bool()), } out_qasm = dumps(qc, implicit_defcals=defcals) print(out_qasm)Daría como resultado la siguiente cadena válida OpenQASM3 :
OPENQASM 3.0; bit[1] c; qubit[1] q; h q[0]; c[0] = measure_2 q[0]; c[0] = measure q[0];Este enfoque asume que la definición de la gramática para el defcal se proporciona externamente (por ejemplo, en un archivo de cabecera), aunque dicho archivo no es estrictamente necesario para que el exportador funcione.
-
Las funciones
qasm3.loads()yqasm3.load()ahora tienen un argumento adicional llamadonum_qubits. Si se proporcionan, las funciones devolverán circuitos que tendrán qubits iguales anum_qubits. Si no se proporciona, el circuito devuelto tendrá qubits iguales al índice máximo visto en el circuito serializado. Consulte el n.º 14435 para obtener más detalles
Características de QPY
-
Se ha añadido una configuración denominada
min_qpy_versionen el archivo de configuración del usuario. Cuando se establece, define la versión mínima permitida de QPY paraqpy.load(). Si la versión de formato de un archivo QPY es inferior a laminimum_qpy_versionconfiguraciónminimum_qpy_version, se generará una excepción. -
Se introduce la versión 16 del formato QPY. Esta nueva versión introduce una nueva tabla de inicio de circuito en la cabecera del fichero que contiene los desplazamientos de byte del inicio de cada circuito en un fichero QPY. Esto permite una carga potencialmente más eficiente de circuitos desde archivos QPY, y una implementación potencialmente multihilo de Rust en el futuro. Además, la nueva versión del formato añade compatibilidad con la nueva variante
DURATIONde los picosegundos.
Características de la información cuántica
-
Se han añadido los
PauliLindbladMap.drop_qubits()métodosPauliLindbladMap.keep_qubits()y para rastrear subsistemas fuera de los mapas de Pauli Lindblad. -
Se han añadido los métodos
QubitSparsePauli.to_pauli()yQubitSparsePauliList.to_pauli_list(), que convierten los objetos dispersos en las versiones densas correspondientes,PauliyPauliList, respectivamente. -
Se han añadido las clases
PhasedQubitSparsePauliPhasedQubitSparsePauliListy. Estas clases representan un único operador de Pauli y una lista de operadores de Pauli, respectivamente, almacenados en formato qubit-sparse. Estas clases son muy similares aQubitSparsePauliyQubitSparsePauliList, excepto que además contienen información de fase. -
Se ha añadido el método
QubitSparsePauliList.to_dense_array(). Esto devuelve la lista como una matriz de números enteros con los valores dePauli.
Características de síntesis
-
Se ha añadido un nuevo algoritmo de síntesis para
ModularAdderGateque no requiere qubits auxiliares y tiene un mejor recuento CX en comparación conadder_qft_d00(): -
Se ha añadido un nuevo algoritmo de síntesis,
synth_mcx_noaux_hp24(), paraMCXGateque no requiere ningún qubit auxiliar. Este método produce un número lineal, en lugar de cuadrático, de puertas CX, en comparación con el algoritmosynth_mcx_noaux_v24()existente. En concreto, el nuevo método es mejor cuando el número de qubits de control es superior a cinco. El algoritmo se basa en el artículo «Compiling Conditional Quantum Gates without Using Helper Qubits» (Compilación de puertas cuánticas condicionales sin utilizar qubits auxiliares), de Huang y Palsberg ( https://dl.acm.org/doi/10.1145/3656436 ). -
Se ha mejorado la
qs_decomposition()función que originalmente se basaba en Shende et. et al. (https://arxiv.org/abs/quant-ph/0406176). El nuevo método de síntesis se basa en Krol y Al-Ars ( https://arxiv.org/abs/2403.13692 ), y reduce el número total deCXGates de un unitario general de n qubits por unCXGates. Con la descomposición mejorada, una unidad general de 3 qubits se puede descomponer utilizando 19CXGates (en lugar de 20). -
Añadido
synth_mcmt_xgate()para sintetizar la puerta multicontrol y multiobjetivo cuando la puerta base esXGate. Tiene una descomposición en un número lineal de puertas CX y 0 qubits auxiliares junto con el complemento de síntesis deMCMTSynthesisXGatealto nivel.
Características del transpilador
-
Se ha añadido un nuevo complemento de síntesis de alto nivel para sintetizar un
ModularAdderGate:ModularAdderSynthesisV17, basado enadder_modular_v17().
El también
ModularAdderSynthesisDefaultse ha actualizado para seguir la siguiente secuencia de sintetizadores sumadores modulares:"ModularAdder.qft_d00"cuando el número de qubits es ,"ModularAdder.modular_v17"en todos los demás casos. -
Se ha añadido una nueva pasada del
LitinskiTransformationtranspilador que implementa la transformación descrita en arXiv:1808.02892.La entrada al paso es un circuito con puertas Clifford y puertas de rotación RZ de un solo qubit, y la salida es un circuito con rotaciones Pauli de múltiples qubits (implementadas como
PauliEvolutionGatepuertas) seguidas de puertas Clifford. El paso genera unaTranspilerErrorexcepción si el circuito contiene puertas no compatibles.El pase admite todas las puertas Clifford de la lista devuelta por
get_clifford_gate_names(), es decir,["id", "x", "y", "z", "h", "s", "sdg", "sx", "sxdg", "cx", "cz", "cy", "swap", "iswap", "ecr", "dcx"]. La lista de rotaciones RZ compatibles es["t", "tdg", "rz"](convertimos automáticamente las puertas T y Tdg en rotaciones RZ).Además, el
LitinskiTransformationconstructor acepta un argumentofix_clifford. CuandoFalse(no predeterminado), el circuito devuelto contiene soloPauliEvolutionGatepuertas, omitiéndose las puertas Clifford finales. Tenga en cuenta que, en este caso, los operadores de los circuitos originales y sintetizados no serán equivalentes en general.Por ejemplo:
from qiskit.circuit import QuantumCircuit from qiskit.transpiler.passes import LitinskiTransformation from qiskit.quantum_info import Operator # The following quantum circuit consists of 5 Clifford gates # and two single-qubits RZ-rotation gates (note that Tdg is # an RZ-rotation). qc = QuantumCircuit(2) qc.cx(0, 1) qc.rz(0.1, 0) qc.cz(0, 1) qc.tdg(1) qc.h(1) qc.s(1) qc.cz(1, 0) # The transformed circuit consists of two PauliEvolution gates # and the same Clifford gates as in the original circuit. qct = LitinskiTransformation()(qc) # The circuits before and after the transformation are equivalent assert Operator(qc) == Operator(qct) -
Se ha añadido un nuevo complemento de síntesis de
MCXSynthesisNoAuxHP24alto nivel paraMCXGateobjetos. Además, se actualizó el complemento de síntesisMCXSynthesisDefaultpredeterminado paraMCXGateobjetos, de modo que siempre elija el mejor método de síntesis en función del número disponible de qubits auxiliares. -
Se ha añadido compatibilidad con para especificar
Targetlos límites angulares en las instrucciones. Antes de esta versión,Targetse podía especificar que una operación que tomaba un parámetro permitiera cualquier valor válido o un valor específico. Por ejemplo, siRZGate(Parameter("theta"))se añadiera al objetivo, eso indicaría que se permitiría unRZGatecon cualquier valor para theta. Mientras que siRZGate(math.pi)se añadiera al objetivo, eso indicaríaRZGateque solo es el único valor permitido en el objetivo. Esta nueva función permite restringir los ángulos permitidos a cualquierfloatvalor entre un límite inclusivo. Por ejemplo, puede añadirRZGate(math.pi)a unTargety restringir el valor del ángulo entre los valores 0 y .Hay varios métodos disponibles para trabajar con los límites angulares en el objetivo. El primero es
Target.add_instruction()que tiene un nuevo argumentoangle_boundsclave que se utiliza para añadir un límite angular a una instrucción en elTarget. Para trabajar con límites angulares, también querrás registrar una función de devolución de llamada en el registroWRAP_ANGLE_REGISTRYglobal que le dirá al transpilador yWrapAnglesle pasará cómo ajustar las puertas para los límites angulares. La función de devolución de llamada tomará una lista de valoresfloatarbitrarios que representan los ángulos de la puerta del circuito, así como los índices de qubit en el circuito en el que operaba la puerta, y devolverá unDAGCircuitque representa un circuito equivalente para la puerta con ese ángulo, pero respetando los límites del ángulo y otrasTargetrestricciones. Por ejemplo:import math from qiskit.dagcircuit import DAGCircuit from qiskit.transpiler import Target from qiskit.transpiler.passes.utils.wrap_angles import WRAP_ANGLE_REGISTRY target = Target(num_qubits=1) target.add_instruction(RZGate(Parameter("theta")), angle_bounds=[(-math.pi, math.pi)]) def callback(angles: List[float], qubits: List[int]) -> DAGCircuit: """Callback function to wrap RZ gate angles Args: angles: The list of floating point parameter values for the instance of RZGate in the circuit qubits: The physical qubit indices that this gate is operating on Returns: The DAGCircuit of the equivalent circuit""" angle = angles[0] dag = DAGCircuit() dag.add_qubits([Qubit()]) if angle > 0: divisor = math.pi else: divisor = -math.pi gate_counts = int(angles[0] // divisor) rem = angles[0] % divisor for _ in range(gate_counts): dag.apply_operation_back(RZGate(math.pi), [dag.qubits[0]], check=True) dag.apply_operation_back(rem, [dag.qubits[0]], check=True) WRAP_ANGLE_REGISTRY.add_wrapper("rz", callback)Target.has_angle_bounds()Se puede utilizar para comprobar si hay algún límite angular establecido en el objetivo, yTarget.gate_has_angle_bounds().Si desea aplicar los límites de ángulo de un objetivo a cualquier puerta de un circuito, debe utilizar la
WrapAnglespasada del transpilador para hacerlo. -
Se ha añadido un nuevo kwarg
check_angle_boundsalTarget.instruction_supported()método. Cuando se establece enTrue(el valor predeterminado), el método comprobará si el especificadoparameterstambién se ajusta a cualquier límite de ángulo que pueda existir para la instrucción que se consulta. -
Se ha añadido una nueva pasada del
WrapAnglestranspilador que se utiliza para aplicar restricciones angulares a las puertas en elTarget. Si seTargethan definido límites de ángulo, esta pasada analizará todos los parámetros de las puertas del circuito y los comparará con los límites especificados en el objetivo. Por ejemplo, si un objetivo contiene una puerta personalizada con límites angulares, el paso descompondrá esa puerta en una puerta que se ajuste a los límites:from qiskit.circuit import Gate, Parameter, QuantumCircuit, Qubit from qiskit.dagcircuit import DAGCircuit from qiskit.transpiler import Target, WrapAngleRegistry from qiskit.transpiler.passes import WrapAngles class MyCustomGate(Gate): def __init__(self, angle): super().__init__("my_custom", 1, [angle]) param = Parameter("a") circuit = QuantumCircuit(1) circuit.append(MyCustomGate(6.0), [0]) target = Target(num_qubits=1) target.add_instruction(MyCustomGate(param), angle_bounds=[(0, 0.5)]) def callback(angles, _qubits): angle = angles[0] if angle > 0: number_of_gates = angle / 0.5 else: number_of_gates = (6.28 - angle) / 0.5 dag = DAGCircuit() dag.add_qubits([Qubit()]) for _ in range(int(number_of_gates)): dag.apply_operation_back(MyCustomGate(0.5), [dag.qubits[0]]) return dag registry = WrapAngleRegistry() registry.add_wrapper("my_custom", callback) wrap_pass = WrapAngles(target, registry) res = wrap_pass(circuit) res.draw('mpl')
-
DAGCircuitahora tiene una implementación manual de__deepcopy__(). Esto es mucho más rápido que la implementación implícita anterior del protocolo pickle, especialmente para circuitos grandes. Esto también beneficia directamente al rendimiento de la compilación al ejecutartranspile()o al ejecutar los gestores de pasadas preestablecidos devueltos porgenerate_preset_pass_manager()enoptimization_level=3como nivel de optimización 3, ya que copia en profundidad internamente elDAGCircuitpara cada iteración del bucle de optimización en laoptimizationetapa. -
Se proporciona un nuevo método,
DAGCircuit.make_physical(), que sustituye eficazmente los qubits delDAGCircuitpor el registro canónico de qubits físicos, incluyendo potencialmente la expansión. También hay disponible unQuantumCircuit.ensure_physical()método similar. -
Se puede utilizar un nuevo método,
DAGCircuit.structurally_equal(), si se han creado y modificado dosDAGCircuitinstancias exactamente en el mismo orden. Esta es una prueba mucho más rigurosa que la comprobación de equivalencia semántica estándar de la==sobrecarga, y los autores de transpiladores pueden utilizarla para verificar que sus órdenes de modificación son deterministas. -
Las subclases personalizadas de ahora
BasePassManagerpueden modificar suproperty_setatributo durante su_passmanager_frontend()método para inicializar las propiedades iniciales. Esto proporciona simetría, ya que anteriormente solo era posible leer las propiedades finales durante_passmanager_backend(). -
Se ha añadido una nueva clase
OptimizationMetricque especifica el criterio de optimización en laHighLevelSynthesispasada. Actualmente, las dos métricas compatibles son:COUNT_2Q: optimiza el número de puertas de dos qubits.COUNT_Toptimiza el número de puertas T al transpilar a un conjunto de bases Clifford+T.
El transpilador selecciona automáticamente la métrica de destino basándose en el conjunto de puertas base, por ejemplo, utilizará
COUNT_Tsi se detecta un conjunto de bases Clifford+T. Sin embargo, esta clase no se puede configurar manualmente actualmente al ejecutartranspile()o al ejecutar un administrador de pases preestablecido generado porgenerate_preset_pass_manager(). -
Se ha añadido un nuevo argumento
optimization_metrical constructor para la pasadaHighLevelSynthesisdel transpilador que toma unOptimizationMetricobjeto. Cuando se establece enCOUNT_T, el paso elige descomposiciones que son más adecuadas para el conjunto de puertas Clifford+T. -
Los complementos de síntesis de alto nivel predeterminados para
ModularAdderGateyMultiplierGateproducen mejores recuentos T al transpilarlos al conjunto de bases Clifford+T. -
El complemento de síntesis de alto nivel predeterminado para
MCXGateproduce mejores recuentos T al transpilación al conjunto de bases Clifford+T, siempre que haya al menos 1 qubit auxiliar disponible. -
Se ha añadido un conjunto predeterminado de puertas inversas para la
InverseCancellationpasada del transpilador. Anteriormente, era necesario proporcionar una lista explícita de puertas o pares de puertas que se debían cancelar como argumento para el constructor del objeto de paso. Ahora bien, esta lista es opcional y, si no se proporciona ninguna lista, las puertas inversas automáticas son:y los pares inversos:
será anulado por el pase.
-
Se ha añadido un nuevo argumento al
InverseCancellationconstructor,run_default, que cuando se establece enTrueejecutará la nueva lista de puertas de cancelación inversa predeterminada, además de cualquier puerta personalizada proporcionada. Esto está pensado para casos en los que se desea ejecutar un conjunto personalizado de cancelaciones inversas además de las puertas predeterminadas. -
TranspileLayouttiene dos nuevos métodos:from_property_set()ywrite_into_property_set(), que formalizan la estructura ad hoc actual de las propiedades de transpilación y cómo se convierten en unTranspileLayout. Esto permite que los pases durante un proceso de transpilación accedan a lo queTranspileLayoutserá el, lo modifiquen en su forma totalmente estructurada y luego lo vuelvan a escribir en forma canónica.Se espera que en la futura versión 3.0 de Qiskit, el
TranspileLayout(o algo similar) sea un atributo directo de laDAGCircuitrepresentación intermedia del transpilador, y que las pasadas lo requieran para mantenerse sincronizadas con el resto delDAGCircuit. -
Rehabilitó la ejecución del
VF2PostLayoutpaso del transpilador en laoptimizationetapa paraoptimization_level=3con latranspile()función y los objetos del gestor de pasos generados devueltos por lagenerate_preset_pass_manager()función. El paso se ejecuta constrict_direction=Truedespués de todas las optimizaciones físicas realizadas en la etapa para intentar mejorar el diseño una última vez con el circuito de salida exacto. Esto estaba habilitado anteriormente en Qiskit v2.1.0, pero se revirtió en 2.1.2 debido a problemas con la implementación inicial. Estos problemas se han solucionado y el diseño se aplicará correctamente si se encuentra uno mejor.
Funciones de visualización
-
Se ha añadido una nueva opción,
measure_arrows, a los backendsmpl``texty para el dibujante de circuitosqiskit.visualization.circuit_drawer()yqiskit.circuit.QuantumCircuit.draw(). Cuando esta opción está activadaTrue, el cajón dibujará una flecha desde elmeasurecuadro hasta los bits clásicos que se encuentran debajo. Este era el comportamiento anterior en los cajones. Si se establece enFalse, no se dibujarán flechas y, en su lugar, el registro clásico y el bit utilizado por elmeasurese indicarán dentro delmeasurecuadro. Esto permite apilarmeasurecajas en una capa vertical.Si no se establece ninguna opción, el valor predeterminado es
True. El usuario puede cambiar el valor predeterminado en el archivo de configuración de usuario, por defecto en el directorio~/.qiskit, en el archivosettings.conf. En el apartado[Default], el usuario puede introducircircuit_measure_arrows = Falsepara cambiar el valor por defecto.
Notas de actualización
- La versión mínima de Rust para compilar Qiskit desde el código fuente (incluida la compilación de la API en C en modo autónomo) ha pasado de Rust 1.79 a Rust 1.85. Este cambio fue necesario para permitir el uso de una versión más reciente de la biblioteca de álgebra lineal de Rust faer que se utiliza dentro de Qiskit. Se han detectado problemas al ejecutar Qiskit en Windows con la versión anterior de faer. Sin embargo, se requiere una nueva versión del compilador de Rust para compilar la nueva versión de faer.
Notas sobre la actualización de circuitos
-
La definición del circuito de
ModularAdderGatese ha actualizado para utilizaradder_modular_v17(). Para obtener el comportamiento anterior, utilice la definición deadder_qft_d00()en su lugar. -
Los métodos
XGate.control(),CXGate.control(),CCXGate.control()C3XGate.control(),C4XGate.control(), y yaMCXGate.control()no devuelven unAnnotatedOperationcuando el argumentoannotatedse establece enTrue, sino que devuelven el mismo explícitoMCXGateque se obtendría cuandoannotatedesFalse. Esto es coherente con el uso del argumentoannotateden toda la biblioteca de circuitos estándar, donde generalmente evitamos introducir unAnnotatedOperationcuando ya existe una clase de puerta nativa disponible. En la práctica, esto conduce a descomposiciones más eficientes de las puertas con anotaciones de control en la familia MCX.
Notas sobre la actualización de la API C
-
La mayor parte del uso de
uintptr_tse ha cambiado porsize_t. En concreto, se han modificado los siguientes usos:QkOpCount.countQkOpCounts.lenQkObsTerm.len- El tipo de retorno de
qk_circuit_num_instructions(). - El
indexargumento enqk_circuit_get_instruction(). - El
boundariesargumento enqk_obs_new(). - Los tipos de retorno de
qk_obs_num_terms(),qk_obs_len(), yqk_obs_boundaries(). - El tipo de retorno de
qk_target_entry_num_properties(), yqk_target_num_instructions().
Este cambio fue necesario porque la herramienta utilizada para generar los archivos de cabecera C desde el código rust de Qiskit, cbindgen estaba utilizando
uintptr_tpor defecto en lugares dondesize_tse alineaba con mayor precisión con el uso de tipos en Rust. Este cambio se ha realizado para dejar más claro cómo se pretende utilizar los valores de la API C.
Notas sobre la actualización de QPY
- La versión predeterminada de QPY emitida por ahora
qpy.dump()es la versión 16 del formato QPY. Si necesita una versión de formato diferente, puede utilizar elversionargumento para especificar una versión de formato anterior.
Notas sobre la actualización de la información cuántica
SparsePauliOp.assign_parameters()Ahora establecerá el tipo de datos (dtype) de la matriz decoeffssalida encomplexsi todos los parámetros están completamente vinculados a valores numéricos.
Notas sobre la actualización de Synthesis
- Los valores predeterminados de los argumentos
opt_a1yopt_a2de ahoraqs_decomposition()opt_a1 = Noneson yopt_a2 = None. Los nuevos valores predeterminados elegirán el valor óptimo en función de si la unidad de entrada para elmatargumento está controlada o no, con el fin de obtener el recuentoCXGatemínimo por defecto. Si necesita el comportamiento anterior, puede llamar explícitamente aopt_a1 = Trueyopt_a2 = Truepara mantener el mismo comportamiento que en versiones anteriores.
Notas sobre la actualización del transpilador
- El circuito
PassManagerahora siempre establece las propiedadesoriginal_circuit_indicesynum_input_qubitsantes de que comience la ejecución en pasadas individuales. Estas son propiedades del circuito de entrada, que anteriormente dependían de cada paso individual para configurarlas, a menudo como un efecto secundario de su propósito principal.
Circuitos obsoletos
-
Las siguientes clases de la librería de circuitos están obsoletas a partir de Qiskit 2.2 y serán eliminadas en Qiskit 3.0. Se han sustituido por puertas equivalentes modernas.
Corrección de errores
-
ApplyLayoutAhora gestionará correctamente el caso de aplicar un qubit ceroLayout. Anteriormente, afirmaba que no se había establecido ningún diseño, incluso si el"layout"campo delPropertySetera igual aLayout(). -
Se han solucionado los problemas de pérdida de memoria durante la creación de una
QkOpCountsinstancia y durante cualquier llamada aqk_opcounts_clear()siempre que se pasa una instancia vacía. -
Anteriormente se podía definir un inválido
PauliEvolutionGatea partir de una lista de operadores, en la que los operadores no estaban todos definidos en el mismo número de qubits. Esto ya está solucionado, y ahora generamos un error cuando se define la puerta:from qiskit.quantum_info import Pauli, SparsePauliOp from qiskit.circuit.library import PauliEvolutionGate pauli = Pauli("XYZ") # 3 qubits op = SparsePauliOp(["XYIZ"], [1]) # 4 qubits evo = PauliEvolutionGate([pauli, op], time=1) -
Se ha corregido un problema en la
VF2Layoutpasada del transpilador por el que, incluso con un conjunto de semillas fijo, el resultado de la pasada podía ser no determinista; concretamente, si el circuito de entrada tenía algún qubit activo que solo contuviera operaciones de un solo qubit. Corregido #14729 -
Se ha corregido un error por
PassManager.run()el que lacallbackfunción no se invocaba al ejecutarse con múltiples circuitos. Ahora la devolución de llamada se activa correctamente para cada pasada en cada circuito, incluida la ejecución en paralelo. -
Se han solucionado varios problemas en la
CommutativeInverseCancellationpasada del transpilador. El pase ahora funciona correctamente en circuitos que contienenCliffordoperaciones, operaciones de flujo de control y operaciones no invertibles, comoInitialize.Además, ahora el pase siempre realiza primero una comprobación sintáctica (no basada en matrices) al identificar pares de puertas inversas. Si las puertas no son sintácticamente iguales, el argumento
matrix_basedse establece enTrue, y la operación no actúa sobre más demax_qubitsqubits, entonces también se realiza una comprobación basada en la matriz. Esto mejora ligeramente el potencial de reducción del paso. -
Se han corregido varios problemas en la
CommutativeCancellationpasada del transpilador (y, por lo tanto, entranspile()), donde la fase global del circuito no se actualizaba correctamente. En concreto, la fusión de una puerta X y una puerta RX introdujo un desajuste de fase, mientras que la eliminación de una puerta de rotación de Pauli con un ángulo de la forma , produjo incorrectamente un cambio de fase de . -
Se ha corregido un problema en
CommutationCheckerel que las puertas controladas estándar no se gestionaban correctamente si se controlaban en un estado distinto al estado «todo unos». Corregido #14974 -
Se ha corregido un problema de indeterminismo en
CommutativeCancellation. Esto no afectó al orden devuelto porDAGCircuit.topological_nodes()otopological_op_nodes(), que normalmente se deben utilizar cuando el determinismo del orden de los nodos es importante, debido a su función de ordenación canónica integrada. Sin embargo, si se inspeccionan los nodos en orden arbitrario (DAGCircuit.op_nodes()) o la estructura de aristas (DAGCircuit.edges()), el orden de iteración sería no determinista tras una llamada aCommutativeCancellation. -
Se ha corregido un error en
MCXGate.control()el que al añadir más controles a un control abiertoMCXGateno se tenía en cuenta elctrl_statede la puerta MCX controlada, lo que provocaba un incorrectoctrl_statede la puerta MCX ampliada. Tenga en cuenta que las clases MCXCXGateexplícitas,CCXGate,C3XGatey yaC4XGatese gestionaban correctamente. -
Corregido el aviso de obsoleto para Python 3.9 para que se identifique correctamente como causado por código de usuario al importar Qiskit. Anteriormente, no se identificaba como causado por código de usuario y esto significaba que los filtros de advertencia predeterminados de Python no mostraban la advertencia al usuario.
-
Se ha corregido un error en
PhaseOracle,PhaseOracleGateyBitFlipOracleGatedonde al intentar cargar desde un archivo dimacs se producía unTypeError. -
Se ha corregido un error en la
ElidePermutationspasada del transpilador, en la que el mapeo de qubits no se actualizaba correctamente en presencia dePermutationGates, lo que provocaba circuitos incorrectos y actualizaciones en el conjunto de propiedades del gestor de pasadas. -
El transpilador integrado que establece la
final_layoutpropiedad ahora gestionará correctamente la actualización de este campo si ya estaba establecido. Esto se puede observar en que el métodoTranspileLayout.routing_permutationahora devuelve una permutación correcta después de ejecutar más de una pasada que establecefinal_layout.Esto no afectó a ninguna llamada normal a
transpile()ogenerate_preset_pass_manager()que utilizara los complementos integrados de Qiskit; ninguna canalización construida de esta forma intentaría establecerfinal_layoutmás de una vez. -
Se ha corregido un error en el
HighLevelSynthesispaso por el que, si el circuito contenía objetos de alto nivel con registros clásicos, estos se asignaban al índice relativo del objeto en lugar del índice correspondiente del circuito externo. Los registros clásicos ahora están correctamente asignados al índice del circuito externo. -
Se ha corregido un error en
Target.instruction_supported()por el que se omitía la comprobación del orden de los qubits de la instrucción cuando se llamaba al método conoperation_nameyparametersargumentos que coincidían con una instrucción existente. -
Se ha corregido el comportamiento del
max_trialsargumento cuandoVF2Layoutse establece enNoneo en un número negativo. Se documentó que el pase limitaba la búsqueda basándose en el tamaño del circuito o del objetivo si la opción estaba establecida enNoney aceptaba valores negativos para especificar una búsqueda ilimitada. Sin embargo, en 2.1.0 este comportamiento se modificó incorrectamente, de modo queNonerealizaba una búsqueda ilimitada y al intentar utilizar un número negativo se producía un error. Estos descuidos se han corregido para que el pase funcione como está documentado y sea coherente con las versiones anteriores. -
Se ha solucionado un problema en los complementos de síntesis de
MCXSynthesis1DirtyKG24alto nivel yMCXSynthesis2DirtyKG24paraMCXGate, en los que los complementos no consideraban los qubits auxiliares limpios disponibles como qubits auxiliares sucios disponibles. En concreto, el complemento noMCXSynthesis2DirtyKG24se aplicaba cuando había disponible un qubit auxiliar limpio y otro sucio. -
El
PauliEvolutionGate.to_matrix()método ahora devuelve la exponencial matricial exacta , donde es eloperatory es eltimepasados a la puerta. Esto corrige un comportamiento inesperado, ya quePauliEvolutionGatese ha documentado que representa la evolución temporal exacta, pero anteriormente la matriz dependía de cómo el compilador aproximaba la evolución temporal. Elto_matrixmétodo ahora es coherente con la documentación. -
Se ha corregido una regresión del rendimiento al compilar de forma
ParameterExpressionincremental a partir de la combinación de un gran número de subexpresiones. Corregido #14653 -
Se ha corregido un error de corrección al exportar circuitos con instrucciones de retardo utilizando unidades 'ps' a QASM3.
-
Se ha corregido un caso extremo en la visualización del
QFTcircuito. Anteriormente, cuandoQFT.inverse()se llamaba y luego se modificaban los atributos del circuito QFT, el QFT se mostraba como"IQFT_dg". Esto era incorrecto, y ahora se muestra correctamente"IQFT". Corregido #14758. -
Se ha corregido un error en el
PauliEvolutionSynthesisRustiqcomplemento que generaba circuitos incorrectos en el caso de que el operador de unPauliEvolutionGatecontuviera objetos de tipoSparseObservable.Por ejemplo:
from qiskit.circuit.library import PauliEvolutionGate from qiskit.quantum_info import SparseObservable, Operator from qiskit.transpiler.passes.synthesis.hls_plugins import PauliEvolutionSynthesisRustiq obs = SparseObservable.from_sparse_list([("1+XY", (0, 1, 2, 3), 1.5)], num_qubits=4) evo = PauliEvolutionGate(obs, 1) qct = PauliEvolutionSynthesisRustiq().run(evo) assert Operator(qct) == Operator(evo) -
Se ha corregido un problema con la
generate_preset_pass_manager()función que ignoraba incorrectamente los datos de restricciones de tiempo contenidos en unTargetobjeto proporcionado cuando no se establecía elbackendargumento. Corregido #14329 -
Se ha corregido un error en
ObservablesArray.coerce_observable()por el que se disparaba en exceso una excepción de que un observable no era hermitiano. Los observables iguales azerono están permitidos y ahora invocan un fallo graceful. -
qiskit.circuit.library.quantum_volume()Se actualizó para manejar unnumpy.random.Generatorcomo entrada para suseedargumento. Anteriormente, tal argumento generador daría como resultado unTypeError. -
QuantumCircuit.compose()Ahora reasignará correctamente las variables y los tramos utilizados enDelaylas instrucciones cuando se especifique elvar_remapargumento. -
SabreLayoututiliza un diseño de «subconjunto denso» como una de sus pruebas, siguiendo el mismo algoritmo queDenseLayout. Sin embargo, anteriormente, la versión utilizada por Sabre asignaba todos los qubits virtuales, incluidos los ancillas ficticios, a un qubit físico, lo que comprometía la eficacia del algoritmo, pero no su corrección. Sabre ahora solo utilizará los qubits virtuales definidos por el usuario para esta prueba inicial, lo que puede dar lugar a pequeñas mejoras en la selección del diseño cuando se promedia en grandes clases de circuitos. -
Se ha corregido un error en
SparsePauliOp.simplify()por el que el método eliminaba los términos de Pauli en función de la magnitud de sus coeficientes antes de combinar los duplicados. Esto provocó un comportamiento incorrecto en dos casos extremos clave:- Cuando varios términos de Pauli idénticos tenían coeficientes pequeños que individualmente estaban por debajo del umbral de simplificación pero cuya suma superaba el umbral, esos términos se eliminaban incorrectamente.
- Cuando múltiples términos de Pauli idénticos tenían coeficientes por encima del umbral pero sumados a casi cero, se mantenían incorrectamente.
Ver #14194 para más detalles.
-
TranspileLayout.initial_index_layout()Ahora gestionará correctamente elfilter_ancillas=Trueargumento si los qubits virtuales en el noinitial_layoutfueron especificados por el constructor en orden de índice. -
VF2Layouty ahoraVF2PostLayoutincluirá correctamente asignaciones de diseño (arbitrarias) para qubits completamente inactivos. Anteriormente, esto se podía observar por las llamadas aTranspileLayout.initial_index_layout()que fallaban después de una compilación. -
Se ha corregido un problema en la
VF2PostLayoutpasada del transpilador. En determinadas situaciones, cuando se ejecuta el paso con el argumento,strict_direction=Trueexistía un posible problema de escalado del tiempo de ejecución cuando el gráfico de interacción del circuito contenía qubits que solo tenían operaciones de 1 qubit. Estos problemas de mapeo dan lugar a una complejidad combinatoria para la puntuación que haría que el pase casi siempre alcanzara el tiempo límite de puntuación y, por lo general, no mejorara el diseño. Enstrict_direction=Falseel modo existe una implementación de búsqueda optimizada para estos problemas, pero las restricciones adicionales parastrict_direction=Trueno hacen que este enfoque sea viable. En cambio, en estos casos ahoraVF2PostLayoutse omitirá la búsqueda, ya que el problema de diseño no es viable para el pase.
Otras notas
- La implementación del enrutamiento Sabre utilizado por
SabreLayoutySabreSwapahora comprime las secuencias de nodos que automáticamente serán elegibles para el enrutamiento al mismo tiempo dentro de su representación de interacción virtual interna. Esto mejora la eficiencia del enrutamiento, reduce el uso de memoria intermedia y evita que las puertas e 2q es sesguen loslookaheadcomponentes heurísticos.
2.1.0rc1
Notas sobre características en desuso
-
El soporte para ejecutar Qiskit con Python 3.9 ha sido obsoleto y será eliminado en la versión de Qiskit 2.3.0. 2.3.0 es la primera versión después de que Python 3.9 llegue al final de su vida útil y deje de recibir soporte. [1] Esto significa que a partir de la versión 2.3.0 deberá actualizar la versión Python que esté utilizando a Python 3.9 o superior.