Qiskit SDK 2.3 notes de mise à jour
2.3.1
Prélude
La version v2.3.1 de Qiskit corrige plusieurs bogues identifiés depuis la sortie de la version v2.3.0 de Qiskit.
Corrections des erreurs
-
Le plugin de synthèse
permutation.kmsintégré dansqiskit.synthesisgère désormais correctement les permutations de longueur nulle. Problème n° 15550 résolu. -
Valeur fixe
synth_clifford_depth_lnn()pour les Cliffords à un qubit. Voir n° 15780. -
Correction d'un bug dans le passage
HighLevelSynthesisdu transpileur qui empêchait la mise à jour correcte des états des qubits après la synthèse récursive d'une opération. Dans certains cas, cela pourrait entraîner la génération de circuits erronés par le passeur. -
Correction d'un problème dans la
qs_decomposition()fonction où des problèmes de tolérance potentiels dans les routines internes d'algèbre linéaire provoquaient une erreur fatale, entraînant le plantage du programme. Ce problème a été corrigé; désormais, dans ces situations, une exception appropriéeQiskitErrorou une sous-classe de celle-ci est déclenchée à la place.Problème n° 15610 résolu.
-
La synthèse par défaut des portes
UnitaryGate« when access »UnitaryGate.definitionet « callingUnitaryGate.control()» impliquant plus de deux qubits s'appuiera en interne sur laqs_decomposition()fonction. Dans certaines situations, en raison de la tolérance inhérente au calcul en virgule flottante utilisée dans les routines d'algèbre linéaire de la décomposition itérative de Shannon-Quantum, le calcul peut ne pas toujours aboutir. Pour éviter que ces attributs ou méthodes ne génèrent une erreur, on utilise à laIsometryplace la décomposition de dans de telles situations. Même si cela donne lieu à une décomposition moins efficace,qs_decomposition()cela servira de solution de secours en casqs_decomposition()d'échec. -
Correction d'un bug dans
ParameterExpression.sympify()lequel les opérations arithmétiques asymétriques (telles que ** ou -) pouvaient inverser les opérandes avec certaines combinaisons deParameter,ParameterExpressionet de valeurs numériques. Voir n° 15642. -
Corrigé
qk_obs_term()lors de l'accès à un terme observable d'identité. Voir n° 15536. -
Correction d'un artefact de visualisation dans
plot_state_qsphere()lequel les états intriqués symétriques (tels que les états de Bell) subissaient une rotation arbitraire due au bruit lié au calcul en virgule flottante. -
Corrigé
QuantumCircuit.repeat()pour les circuits à portes paramétrées.Voir n° 15645.
-
Corrige un bug qui provoquait
qpy.load()un plantage de sur les circuits créés à l'aide deQuantumCircuit.ensure_physical()lorsqu'un registre créé par l'utilisateur et nommé « ancilla » était présent. -
Corrigé
BreakLoopOp: certaines opérations de contrôle deContinueLoopOpflux étaient considérées à tort comme telles lors de certains passages du transcompilateur, ce qui pouvait se traduire par le déclenchementAttributeErrord'une exception. Voir n° 15579. -
Corrige un bug qui provoquait
qpy.load()un plantage de sur les circuits créés à l'aide deSabreLayoutlorsqu'un registre créé par l'utilisateur et nommé « ancilla » était présent. -
La version minimale requise d' NumPy est désormais correctement indiquée comme étant 1.21 (au lieu de 1.17 ). Cette restriction est effective depuis plusieurs versions en raison de l'utilisation de
numpy.typing.NDArray, qui a été introduit dans NumPy 1.21; par conséquent, l'importation de Qiskit échouerait avec les anciennes versions de NumPy. -
L'exportateur « 3 » de l' OpenQASM e (
qasm3.dumps()etdump()) effectue désormais correctement l'échappement des caractères Unicode de type « nombre » autres que les chiffres ASCII, lorsqu'ils sont utilisés dans des identifiants. Auparavant, les caractères tels que les exposants figuraient toujours dans le résultat, ce qui n'est pas conforme à la norme OpenQASM e 3. -
L'exportateur « 3 » de l' OpenQASM (
qasm3.dumps()etdump()) échappe désormais correctement les identifiants dont le nom commence par un chiffre ASCII. -
Les méthodes
SparsePauliOp.from_list()et déduisentSparsePauliOp.from_sparse_list()désormais automatiquement le type de données des coefficients sidtypel'argument n'est pas spécifié.Par exemple :
from qiskit.quantum_info import SparsePauliOp from qiskit.circuit import Parameter theta = Parameter("theta") # Previously required manually setting dtype=object op_list = SparsePauliOp.from_list([("X", theta)]) op_sparse = SparsePauliOp.from_sparse_list([("X", [0], theta)], num_qubits=1)
2.3.0
Prélude
Qiskit v2.3.0 est une nouvelle fonctionnalité de l' Qiskit SDK.
Cette nouvelle version étend considérablement l'API C pour la transpilation, Target rendant davantage de (QkTarget) accessibles à l'inspection depuis le C et permettant de créer et de manipuler les DAGCircuit (QkDag). Cela permet d'écrire des passes de transcompilation personnalisées lors de la compilation par rapport à l'objet libqiskit autonome. L'API C propose des fonctions spécifiques à chaque étape de la transcompilation (par exemple, qk_transpile_stage_layout()), afin de faciliter l'intégration d'une logique personnalisée dans la transcompilation sans avoir à recréer manuellement l'ensemble du pipeline.
Les performances et les fonctionnalités de la transpilation vers des cibles tolérantes aux pannes précoces ont également été améliorées. Grâce à cette nouvelle PauliProductMeasurement instruction, qui correspond à une transformation projective vers une base de produit de Pauli, Qiskit prend désormais pleinement en charge la transcompilation des circuits vers une base de calcul de type Pauli à l'aide du pass LitinskiTransformation existant. La nouvelle méthode de synthèse unitaire, RossSelingerSynthesis, qui peut être configurée dans le transpileur à l'aide de unitary_synthesis_method="gridsynth", permet d'utiliser l'algorithme de Ross-Selinger, asymptotiquement optimal, pour la synthèse Clifford+T à un seul qubit. Parmi les autres améliorations, on peut citer, par exemple, une meilleure OptimizeCliffordT pass ou la CommutativeOptimization pass, qui tient compte des optimisations commutatives des circuits basés sur Pauli.
En interne, la représentation des ControlFlowOp objets a été adaptée pour être native à Rust. Cette transformation n'est pas encore achevée; vous pourriez constater une légère baisse de performances dans les 2.3 s Qiskit liées aux opérations de contrôle de flux. Les prochaines versions de Qiskit devraient aller plus loin en apportant une réponse aux problèmes de performances et d'API qui persistent depuis longtemps concernant les opérations de contrôle de flux.
Veuillez noter qu'à partir de cette version, Python 3.9 n'est plus pris en charge car sa fin de vie est prévue en octobre 2025, et macOS sur les processeurs Intel a été rétrogradé au niveau 2 de prise en charge de la plateforme, Apple ayant commencé à abandonner cette plateforme. Toutes les versions de CPython à partir de 3.10 sont prises en charge. Consultez la section Prise en charge des systèmes d'exploitation pour connaître les niveaux de prise en charge actuels des différentes plateformes.
D'autres fonctionnalités seront ajoutées à Qiskit dans la série d' 2.x s; nous ne prévoyons pas de publier Qiskit 3.0 avant 2026, car il n'y a actuellement aucun besoin de modifications importantes.
Fonctionnalités de l'API C
-
Ajout d'une fonction
qk_target_instruction_supported()permettant de vérifier la compatibilité de n'importe quelle porte ou instruction avec l'instance deQkTarget. Cette vérification est effectuée en fonction du nom de l'instruction fournie, des qargs et des paramètres. -
Ajout d'une fonction
qk_target_entry_set_name()permettant de définir le nom d'une entrée de cible existante. -
Ajout d'une nouvelle fonction
qk_circuit_library_quantum_volume()permettant de générer un circuit de modèle de volume quantique. -
Ajout de méthodes pour itérer et vérifier la carte de portes d'un
QkTarget. Les méthodes suivantes ont été ajoutées :qk_target_op_num_properties()qk_target_op_index()qk_target_op_name()qk_target_op_qargs_index()qk_target_op_qargs()qk_target_op_props()
Et la représentation suivante a été ajoutée :
QkInstructionProperties: pour représenter leInstructionProperties.
Exemple :
// Create Target with a mix of global and non-global gates. QkTarget *target = qk_target_new(2); // Create a CX entry QkTargetEntry *cx_entry = qk_target_entry_new(QkGate_CX); uint32_t qarg_samples[2][2] = { {0, 1}, {1, 0}, }; double props[2][2] = { {2.7022e-11, 0.00713}, {3.0577e-11, 0.00713} }; for (int i = 0; i < 2; i++) { qk_target_entry_add_property(cx_entry, qarg_samples[i], 2, props[i][0], props[i][1]); } qk_target_add_instruction(target, cx_entry); // Create an SX entry QkTargetEntry *sx_entry = qk_target_entry_new(QkGate_SX); for (int i = 0; i < 2; i++) { uint32_t qargs[1] = {i}; qk_target_entry_add_property(sx_entry, qargs, 1, 35.5e-9, 0.); } qk_target_add_instruction(target, sx_entry); // Create an H entry qk_target_add_instruction(target, qk_target_entry_new(QkGate_H)); // Get the size of the size_t target_length = qk_target_num_instructions(target); for (size_t op_idx = 0; op_idx < target_length; op_idx++) { // Allocate space for qargs and props uint32_t *qargs; uint32_t qargs_len; QkInstructionProperties props; // Retrieve the operation's name char *name = qk_target_op_name(target, op_idx); size_t num_props = qk_target_op_num_properties(target, op_idx); for (size_t props_idx = 0; props_idx < num_props; props_idx++) { // Populate qargs qk_target_op_qargs(target, op_idx, props_idx, &qargs, &qargs_len); // Populate properties qk_target_op_props(target, op_idx, props_idx, &props); } // Free the name string qk_str_free(name); } -
QkTargetoffre désormais à ses utilisateurs la possibilité de récupérer des opérations directement à partir de celui-ci. Les méthodes suivantes ont été ajoutées :Et la représentation suivante a été ajoutée :
QkTargetOp: Pour représenter une opération dans leQkTarget.
-
L'API C expose
QkParamdésormais pour représenter les paramètres de porte, y compris les symboles et les expressions paramétrées. L'interfaceQkParamelle-même prend en charge les calculs symboliques, y compris les opérations arithmétiques standard et les fonctions trigonométriques. Par exemple :QkParam *x = qk_symbol_new("x"); // a symbol called "x" QkParam *y = qk_symbol_new("y"); // a symbol called "y" QkParam *val = qk_symbol_from_double(2.0); // the value 2.0 QkParam *out = qk_symbol_zero(); // to store the final expression // build 2 sin(x + y) qk_param_add(out, x, y); // out = x + y qk_param_sin(out, out); // out = sin(out) qk_param_mul(out, out, val); // out = out * 2 qk_param_free(x); qk_param_free(y); qk_param_free(val); qk_param_free(out); -
L'API C peut désormais représenter et manipuler
DAGCircuiten tant qu'objet opaqueQkDag. Les fonctions suivantes ont été ajoutées concernant le DAG :qk_dag_new()qk_dag_add_quantum_register()qk_dag_add_classical_register()qk_dag_free()qk_dag_copy_empty_like()qk_dag_num_qubits()qk_dag_num_clbits()qk_dag_num_op_nodes()qk_dag_node_type()qk_dag_qubit_in_node()qk_dag_qubit_out_node()qk_dag_clbit_in_node()qk_dag_clbit_out_node()qk_dag_wire_node_value()qk_dag_op_node_clbits()qk_dag_op_node_gate_op()qk_dag_op_node_kind()qk_dag_op_node_num_clbits()qk_dag_op_node_num_params()qk_dag_op_node_num_qubits()qk_dag_op_node_qubits()qk_dag_op_node_unitary()qk_dag_apply_barrier()qk_dag_apply_gate()qk_dag_apply_measure()qk_dag_apply_reset()qk_dag_apply_unitary()qk_dag_get_instruction()qk_dag_compose()qk_dag_topological_op_nodes()qk_dag_substitute_node_with_dag()qk_dag_predecessors()qk_dag_successors()
-
Ajout de
QkDagNodeTypel'énumération permettant de distinguer le type d'un nœud DAG. Il s'agit du type de retour deqk_dag_node_type(). -
Ajout de
QkOperationKindl'énumération permettant de distinguer les différents types d'opérations natives. Il s'agit du type de retour deqk_dag_op_node_kind(). -
Ajouté
qk_circuit_copy_empty_like()pour créer une copie du circuit indiqué, en tant que reflet de celui-ciQuantumCircuit.copy_empty_like(). -
Ajout de nouvelles énumérations à utiliser avec certaines fonctions API de circuit et DAG pour spécifier les modes de copie :
-
Ajout de
QkDagNeighborsla structure, qui est le type de retour deqk_dag_successors()etqk_dag_predecessors()de, ainsi que de sa fonction de libérationqk_dag_neighbors_clear()associée. -
Une nouvelle structure,
QkNeighbors, est ajoutée; il s'agit d'une représentation du graphe de couplage à deux qubits sous-jacent à unTarget. Elle est initialisée par la nouvelle fonctionqk_neighbors_from_target(), réinitialisée avecqk_neighbors_clear(), et dispose d'une fonction d'aideqk_neighbors_is_all_to_all(). -
Ajout des
qk_dag_to_circuit()fonctionsqk_circuit_to_dag()et pour prendre en charge respectivement les conversions de DAG en circuit et de circuit en DAG. -
Les
qk_transpiler_pass_standalone_unitary_synthesis()qk_transpile()fonctions et permettent désormais de synthétiser des objetsUnitaryGatede 3 qubits ou plus dans un circuit. Dans Qiskit 2.2, cette fonctionnalité n'était pas prise en charge, car l'algorithme de synthèseqs_decomposition()sous-jacent utilisé pour la synthèse unitaire de 3 qubits ou plus avait initialement été écrit en Python. Cependant, maintenant qu'il a été porté en Rust, cette fonctionnalité est accessible depuis le langage C. -
Ajout de nouvelles fonctions pour exécuter les étapes du transcompilateur à l'API C. Ces fonctions sont les suivantes :
Ces fonctions sont utilisées pour exécuter ces étapes à partir du gestionnaire de passes prédéfini sur un
QkDagobjet. L'objectif de ces fonctions est de permettre des workflows de transpilation composables à partir de C lorsqu'elles sont combinées avec des passes de transpilateur personnalisées. -
Ajout d'une nouvelle fonction
qk_transpile_layout_generate_from_mapping()permettant de générer un élément personnaliséQkTranspileLayoutdont la mise en page initiale est définie à partir d'un tableau de correspondance. Cette fonction a pour but de permettre la création d'un objet de mise en page destiné aux passes de transcompilation de mise en page personnalisées. -
Les deux formes de sélection de mise en page « parfaite » via l'algorithme d'isomorphisme de sous-graphe VF2 sont désormais disponibles en tant que passes de transcompilateur autonomes dans l'API C. Ces fonctions sont les suivantes :
Ces deux approches diffèrent dans la manière dont la directionnalité et les ensembles de portes des interactions sont gérés;
exactexige que les correspondances prennent directement en charge toutes les portes de manière native, tandis queaverages'attend à ce que des passages supplémentaires du transcompilateur décomposent les portes en un ensemble pris en charge par un qubit ou une liaison donné(e).Ces fonctions utilisent une version encapsulée de la configuration VF2 (
QkVF2LayoutConfiguration), qui dispose de méthodes de définition pour chacune des options. Cela inclut l'accès à la nouvelle forme à deux limites decall_limitl'argument.
Caractéristiques des circuits
-
Ajout d'une nouvelle classe d'instructions,
PauliProductMeasurement, qui représente une mesure projective conjointe sur plusieurs qubits, où l'observable mesurée est un produit tensoriel d'opérateurs de Pauli. Le résultat de cette mesure est une valeur propre unique, soit soit , qui indique l'état propre du produit de Pauli.Pour plus d'informations, consultez l'article « A Game of Surface Codes: Large-Scale Quantum Computing with Lattice Surgery » (Un jeu de codes de surface : l'informatique quantique à grande échelle avec la chirurgie des réseaux) de Daniel Litinski.
Un
PauliProductMeasurementpeut être instancié à partir d'unPauli, où le Pauli peut inclure une phase de , mais pas de ou . L'instruction comporte le même nombre de qubits que le Pauli, ainsi qu'un seul bit classique.Exemple :
from qiskit.circuit import QuantumCircuit from qiskit.quantum_info import Pauli from qiskit.circuit.library import PauliProductMeasurement ppm = PauliProductMeasurement(Pauli("XZ")) qc = QuantumCircuit(6, 2) qc.append(ppm, [4, 1], [1]) -
Une nouvelle
QuantumCircuit.to_dag()méthode offre désormais une interface pratique pourcircuit_to_dag(). -
ParameterExpressiondispose désormais d'unnum_parametersattribut dont la valeur correspond à la longueur de sonparametersensemble, mais qui est calculée avec moins de surcharge.
OpenQASM Caractéristiques
- L'exportateur OpenQASM 2(
qasm2.dumps()) prend désormais en charge la génération de blocs simplesIfElseOpà instruction unique, à condition qu'il s'agisse d'un simple test d'égalité entre un registre et un entier. Cela correspond à ce que le langage de l' OpenQASM e 2 permet de représenter.
Caractéristiques du QPY
- La version 17 de QPY inclut désormais des formats de sérialisation pour
SparseObservableles objets utilisés comme paramètres d'autres objets. Cela permet notamment de sérialiserPauliEvolutionGateles objets qui utilisent cet opérateur en interne, et la charge utile de la porte d'évolution est mise à jour.
Caractéristiques de l'information quantique
-
Ajouté
Statevector.from_circuit()en tant que miroir deOperator.from_circuit(). Cela permet d'instancier directement unStatevectordans l'espace des qubits virtuels, même pour les circuits qui ont été transposés dans un espace de qubits physiques. -
Amélioration des performances de
Clifford.dot()et deClifford.compose()lorsqu'elles sont appelées avecfront=Trueet un neQuantumCircuitcontenant que des portes de Clifford. Auparavant, le circuit était d'abord entièrement intégré dans unCliffordobjet, puis les deux objets étaient combinés. Désormais, la baseCliffordest mise à jour de manière itérative, ce qui est nettement plus rapide pour les petits circuits. -
Ajout de la
PauliLindbladMap.parity_sample()méthode. Cette méthode est très similaire à la méthodePauliLindbladMap.signed_sample()existante, mais elle utilise une convention de signe plus cohérente avec le reste de Qiskit; c'est donc celle qu'il est préférable d'utiliser à l'avenir. Elle dispose d'arguments facultatifs supplémentaires permettant d'appliquer des mises à l'échelle aux taux lors de l'échantillonnage sans modifier l'instance. -
Plusieurs fonctions de type
quantum_info« prédicats », telles queis_identity_matrix(), ont été optimisées afin d'éviter des allocations de matrices inutiles.
Caractéristiques de la synthèse
-
Ajouté
gridsynth_rz(): cette fonction construit un circuit quantique à un qubit qui approxime une rotation RZ d'un angle donné. L'algorithme est décrit dans l'article « Optimal ancilla-free Clifford+T approximation of z-rotations » de Neil J. Ross et Peter Selinger, et est implémenté sur https://github.com/qiskit-community/rsgridsynth. -
Ajouté
gridsynth_unitary(), qui construit un circuit quantique à un qubit approximant une matrice unitaire à un qubit donnée. L'algorithme fonctionne en décomposant la matrice unitaire en une rotation RZ, une rotation RX et une autre rotation RZ, puis en appliquant l'algorithme de Ross-Selinger à chacune de ces trois rotations. -
L'algorithme général de synthèse
qs_decomposition()unitaire a été réécrit en Rust, ce qui a considérablement amélioré les performances d'exécution de la fonction.
Fonctionnalités du transpilateur
-
Ajout d'un nouveau passage de transcompilation,
CommutativeOptimization, qui effectue l'annulation et la fusion de portes en exploitant les relations de commutativité. Ce pass regroupe et étend les fonctionnalités de etCommutativeCancellationdeCommutativeInverseCancellation.Plus précisément, le laissez-passer :
- Annule les paires de portes inversées, y compris les paires qui sont inversées jusqu'à une phase globale (en ajustant la phase globale si nécessaire).
- Tente de fusionner les portes consécutives lorsque cela est possible, par exemple les séquences de portes RZ, RX, les rotations de Pauli, etc.
-
Ajout d'une nouvelle option,
fallback_on_default, au passage duUnitarySynthesistranspileur. Cette option s'applique lorsque le passage est appelé avec un plugin de synthèse autre que celui par défaut, spécifié via l'argumentmethod.Par défaut, le plugin spécifié est utilisé pour synthétiser chaque opération unitaire du circuit (à condition que ce plugin soit applicable; par exemple, il ne s'exécutera pas s'il ne prend pas en charge le nombre de qubits sur lequel l'opération unitaire est définie). Si le plugin ne parvient pas à synthétiser l'opérateur unitaire et renvoie
None, l'opérateur unitaire d'origine reste inchangé dans le circuit. Lorsquefallback_on_defaultest défini surTrue, le filtre appellera plutôtDefaultUnitarySynthesisle plugin en cas d'échec de la méthode spécifiée.Cette fonctionnalité est particulièrement utile lorsque les plugins personnalisés sont destinés à traiter uniquement un sous-ensemble de toutes les unités : les utilisateurs peuvent s'appuyer sur leur logique personnalisée lorsqu'elle s'applique et utiliser la synthèse par défaut lorsqu'elle ne s'applique pas.
-
Ajout d'un nouveau module de synthèse unitaire,
RossSelingerSynthesis, qui synthétise des portes unitaires à un qubit à l'aide de l'algorithme de Ross-Selinger et génère un circuit quantique à un qubit composé de portes de type Clifford, et .Le plugin est appelé par le passage
UnitarySynthesisdu transpileur lorsque le paramètremethodest défini sur"gridsynth". -
Lors de la transcompilation vers la base Clifford+T, le passage
UnitarySynthesisde transcompilation utilise désormais par défaut un algorithme de synthèse Clifford+T pour approximer les opérateurs unitaires à un seul qubit.De même, le
DefaultUnitarySynthesisplugin utilise désormais le même algorithme de synthèse Clifford+T pour approximer les opérateurs unitaires à un qubit. -
Une nouvelle
DAGCircuit.to_circuit()méthode offre désormais une interface pratique pourdag_to_circuit(). -
Ajout d'un nouveau passage de
SubstitutePi4Rotationstranscompilation qui convertit les portes deRYGaterotationRXGateà un seulRZGatequbit dont les angles sont des multiples entiers de en ensembles discrets de portesTdgGatedeTGateClifford. Il convient de noter que les multiples impairs de nécessitent une porteTGateetTdgGateune porte, ainsi que certaines portes de Clifford, tandis que les multiples pairs de , ou, de manière équivalente, les multiples entiers de , peuvent s'écrire en utilisant uniquement des portes de Clifford. -
Le passage du
LitinskiTransformationtranspileur a été étendu pour prendre en charge les mesures. Ainsi, la transformation s'applique désormais à un circuit comprenant des portes de rotation RZ de Clifford à un seul qubit (notamment et ) ainsi que des mesures Z standard, et déplace les portes de Clifford à la fin du circuit. Ce faisant, il transforme les rotations RZ en rotations de Pauli combinées (implémentées sous forme dePauliEvolutionGateportes logiques) et les mesures Z en mesures de Pauli combinées (implémentées à l'aidePauliProductMeasurementd'instructions). -
Le cycle d'optimisation du
OptimizeCliffordTtranspileur a été considérablement amélioré et réimplémenté en Rust.Ce passage effectue une optimisation par judas sur les circuits exprimés à l'aide du jeu de portes Clifford+T. Plus précisément, il réduit toutes les chaînes de portes à un seul qubit contenant Clifford+T à une utilisation minimale d' (ou ). Le passage s'exécute sur une chaîne en un temps proportionnel au nombre de portes dans la chaîne.
-
Ajouté
WrapAngles.DEFAULT_REGISTRYcontenant le registre par défaut pourWrapAngles. Cet attribut remplace l'ancienWRAP_ANGLE_REGISTRY, et nous encourageons les utilisateurs en aval à adopter la nouvelle forme dès que possible. -
Les méthodes
DAGCircuit.topological_op_nodes()DAGCircuit.topological_nodes()et prennent désormais en charge unreverseargument de type booléen. Lorsqu'elles sont définies surTrue, ces méthodes renvoient les nœuds dans un ordre topologique inverse, depuis les sorties du circuit vers les entrées. Cela offre un moyen direct et efficace de parcourir un DAG à rebours sans avoir à inverser explicitement la liste des nœuds renvoyée par les fonctions, ce qui permet de créer un nouveau DAG dont la structure est inversée à l'aide deDAGCircuit.reverse_ops(). -
Le
CommutationCheckerpermet désormais de vérifier efficacement la commutation entre les portes basées sur les opérateursPauliGatede Pauli,PauliEvolutionGateetPauliProductMeasurementen vérifiant si les opérateurs de Pauli générateurs commutent. Cela permet des optimisations, notamment pour les circuits utilisant le format de calcul basé sur Pauli, exprimés en termes d'évolutions de Pauli et de mesures de produits de Pauli. Il convient de noter que les commutations entre ces portes basées sur les opérateurs de Pauli et d'autres portes standard ne sont pas encore gérées avec la même efficacité. -
Ajout d'un nouvel argument,
matrix_max_num_qubits, àCommutationChecker.commute(). Cela permet de limiter la taille des instructions pour lesquelles le vérificateur de commutation est autorisé à calculer la représentation matricielle, dont le coût est exponentiellement élevé. Ce nouvel argument permet de faire la distinction entre la limite de taille des instructions à traiter (définie viamax_num_qubitsqui est désormaisNonepar défaut, ce qui signifie qu'il n'y a pas de limite) et la limite de taille de la matrice. -
Les fonctions
generate_preset_pass_manager()et prennenttranspile()désormais enunitary_synthesis_methodcompte l'argument lors de la compilation dans l'ensemble de bases Clifford+T, ce qui permet d'utiliser des plugins de synthèse unitaire personnalisés. -
VF2Layoutet suivreVF2PostLayoutdésormais les scores partiels des dispositions candidates lors de la mise en correspondance des isomorphismes de sous-graphes. Cela n'a pas d'effet notable lorsqu'il n'existe pas de configuration parfaite à trouver, mais peut réduire considérablement le coût de l'évaluation des configurations pour sélectionner la meilleure candidate dans les cas présentant une forte symétrie. -
L'argument
call_limitdeVF2LayoutetVF2PostLayoutpeut désormais être un tuple à deux éléments, dont le premier est utilisé avant que la première correspondance ne soit trouvée, puis la limite passe au second élément par la suite. Il s'agit d'un limiteur de durée d'exécution plus fiable quemax_trialsl'argument, maintenant que les dispositions sont évaluées à la volée avec un élagage plus agressif.
Fonctionnalités diverses
- Ajout de la possibilité de calculer la valeur attendue d'un
SparseObservableà partir de chaînes de bits échantillonnées dans la base Z à l'aide de lasampled_expectation_value()fonction.
Mise à niveau
ConsolidateBlockslit désormais unePropertySetcléConsolidateBlocks_qubit_mapà l'entrée. Cette clé et sa valeur ne sont pas publiques et ne doivent pas être lues ni modifiées par d'autres passes.
Notes de mise à niveau de l'API C
qk_target_entry_new_fixed()dispose d'un paramètrenamesupplémentaire permettant de définir le nom de l'entrée cible. Les entrées à angle fixe nécessitent presque toujours de remplacer le nom de la porte standard pour fonctionner correctement.
Notes sur la mise à niveau des circuits
-
Les noms des circuits produits en tant que définitions des portes de la bibliothèque de circuits standard sont désormais définis sur
None. Auparavant, ces circuits portaient le même nom que la porte, ce qui facilitait grandement la construction de portes opaques dont les noms correspondaient à ceux des portes standard. Cela va à l'encontre d'une hypothèse courante dans Qiskit, selon laquelle les noms des portes standard doivent être uniques. -
La représentation interne des
ControlFlowOps a changé lorsqu'ils ont été ajoutés à aQuantumCircuitouDAGCircuità. L'objet stocké dans le circuit et renvoyé lors d'un accès ultérieur ne sera pas nécessairement la même instance que celle qui a été ajoutée au circuit. Les utilisateurs ne doivent pas tenter de modifier des objets in situ une fois qu'ils ont été ajoutés à un circuit. Cela risque d'endommager le circuit, qu'il s'agisse du flux de contrôle ou d'un autre élément.Comme pour toutes les modifications effectuées sur place sur des objets de type
Pythonstockés dans unQuantumCircuitou unDAGCircuit, vous devez réaffecter l'instruction au circuit pour que l'espace Rust puisse prendre en compte les modifications. Par exemple, lorsqu'on ajoute des annotations à un élémentBoxOpqui se trouve déjà dans un circuit, un passage du transpilateur doit veiller à utiliserDAGCircuit.substitute_node()pour mettre à jour l'objet dans l'espace Rust :from qiskit.circuit import QuantumCircuit, Annotation class MyAnnotation(Annotation): namespace = "my" qc = QuantumCircuit(2) with qc.box(): qc.cx(0, 1) dag = qc.to_dag() # Modifications to the box's annotations in-place require # writing back the information to Rust space. box_node = next(dag.topological_op_nodes()) box_node.op.annotations.append(MyAnnotation()) # Write back the operation. dag.substitute_node(box_node, box_node.op) -
Les performances du transpileur en présence
ControlFlowOpd'instructions, notammentBoxOp, devraient être temporairement moins bonnes dans la version 2.3 de Qiskit, car nous sommes en train de faire passer la représentation interne du flux de contrôle d'une version axée sur le format « Python » à une version native de Rust. Nous espérons que les performances s'amélioreront encore dans une prochaine version de Qiskit, ce qui nous permettra de remédier aux lacunes de longue date de l'API concernant les passes du transcompilateur qui agissent sur les opérations de flux de contrôle. -
Les blocs
ControlFlowOpd'instances ne suivront plusnamelesmetadatachamps. Ces éléments ne pouvaient déjà pas être définis via l'interface du générateur de flux de contrôle, et leur existence relevait d'un détail d'implémentation involontaire plutôt que d'une API intentionnelle. -
La méthode
Gate.control()ne renvoie plus de résultatAnnotatedOperationlorsque l'argumentannotatedest défini surTrueet qu'une classe native de porte contrôlée est disponible. Cette modification s'inscrit dans la lignée de l'utilisationannotatedde cet argument dans l'ensemble de la bibliothèque de circuits standard et permet une décomposition plus efficace des portes annotées en termes de contrôle. Les portes concernées sont les suivantes :- Portes à commande unique
H``CZ,S,Sdg,U3Y,Z,SX,RX,RY,RZ,Swapet; - Double contrôle -
Zporte; - portes arbitrairement
MCMTcontrôléesPhase,CPhase,MCPhase,U1,CU1,MCU1et.
- Portes à commande unique
-
La valeur par défaut de l'argument
annotateddansQuantumCircuit.control()est désormaisNoneau lieu deFalse. Cela n'a aucune incidence sur les circuits eux-mêmes, mais est conforme à la valeur par défaut utilisée dans l'ensemble deannotatedla bibliothèque de circuits.
Notes de mise à niveau QPY
- La version par défaut de QPY (
QPY_VERSION) utilisée dansqpy.dump()est désormais la 17.
Notes de mise à jour sur les informations quantiques
- Les performances ont été améliorées pour les opérateurs de Pauli
Statevector.expectation_value()identiques à tous les états, en s'appuyant sur l'implémentation optimisée pour le cas général plutôt que sur un raccourci dédié qui évoluait mal avec le nombre de qubits.
Notes de mise à niveau du transpilateur
-
Les limites maximales d'appels et d'itérations pour la série de
VF2PostLayoutcalculs par correspondance exacte suroptimization_level=3ont été réduites afin d'éviter des durées d'exécution excessives lorsque des circuits d'itération hautement symétriques sont mappés sur des cartes de couplage de grande taille. -
L'emplacement par défaut du registre pour le passage
WrapAnglesdu transpileur est désormaisWrapAngles.DEFAULT_REGISTRY. L'ancien chemin d'accès, trèsWRAP_ANGLE_REGISTRYimbriqué, continuera de fonctionner pour des raisons de compatibilité ascendante, mais nous encourageons les paquets en aval à utiliser le nouvel emplacement. Le chemin précédent était une erreur dans la documentation de Qiskit 2.2 et parcourt des modules qui n'étaient pas censés faire partie de l'API publique. -
Bien que l'interface de
VF2LayoutetVF2PostLayoutreste logiquement inchangée,max_trialsl'argument n'a désormais plus qu'un effet très limité en tant que limiteur d'exécution, sauf lorsqu'il est défini sur la valeur1. En effet, grâce au nouvel algorithme de calcul et d'élagage à la volée utilisé en interne par la classe, les configurations « complètes » sont beaucoup plus rares, et le nombre d'« essais » n'augmente que lorsqu'une nouvelle configuration est trouvée qui présente un meilleur taux d'erreur que la précédente. Vous devriez plutôt utilisercall_limitcomme limiteur de temps d'exécution déterministe; oùmax_trialsmesure les dispositions complètes rencontrées,call_limittandis que mesure les extensions de disposition partielle.
Notes diverses sur la mise à niveau
-
La version minimale prise en charge d' Python est désormais 3.10, suite à la fin de vie de Python3.9 en octobre 2025 et aux avertissements de dépréciation dans Qiskit depuis la version 2.1.
-
La prise en charge d' macOS x86-64 (Intel) a été rétrogradée du niveau 1 au niveau 2. Qiskit continuera à fournir des roues testées et précompilées pour cette plateforme, mais les tests ne seront effectués qu'au moment de la publication, et non à chaque modification. Cela pourrait entraîner des retards dans la mise à disposition des roues pour cette plateforme.
Ce changement a été apporté car Apple a commencé à abandonner progressivement la plateforme, et l'équipe Qiskit ne dispose plus des ressources nécessaires en termes de développeurs ou d'intégration continue pour continuer à assurer le support de niveau 1. Nous ne pouvons prendre en charge que macOS x86-64 tant que GitHub continue à fournir des runners pour celui-ci, et nous prévoyons que cette prise en charge sera supprimée au cours du second semestre 2027.
Dépréciations de l'API C
-
Cette fonction
qk_transpiler_pass_standalone_vf2_layout()est obsolète; les utilisateurs doivent désormais utiliserqk_transpiler_pass_standalone_vf2_layout_average(). Le nouveau nom de la fonction décrit mieux l'heuristique de notation, et l'API permet un accès encapsulé à l'ensemble du nouvel objet de configuration, y compris la forme à deux limites decall_limit.Cette dépréciation n'est pas tout à fait nécessaire pour les utilisateurs, mais comme l'API C est encore explicitement instable, nous l'utilisons comme un essai de gestion des dépréciations et des avertissements spécifiques au compilateur dans l'API C, avant d'atteindre des garanties de stabilité.
Circuits obsolètes
-
Depuis la version 1.0 de Qiskit, les méthodes
Gate.control()etQuantumCircuit.control()acceptent l'argument,annotatedqui peut prendre la valeurFalse,TrueouNone. Actuellement, une porte contrôlée est représentée à l'aide d'une classe dédiée aux portes contrôlées lorsqu'elle existe, quelle que soit la valeur deannotated; par exemple, une version à deux sorties contrôlées d'uneXGateest uneCCXGate. Si aucune classe dédiée aux portes contrôlées n'existe, la porte contrôlée est représentée par unControlledGatelorsqueannotated=Falseet par unAnnotatedOperationlorsqueannotated=True. La valeur par défautannotated=Noneest traitée exactement de la même manière queFalse.Dans Qiskit 3.0, nous n'autoriserons plus la configuration de
annotated=Noneet remplacerons la valeur par défaut parannotated=True. Cette approche est recommandée, car elle reporte la construction du circuit contrôlé du circuit vers le transcompilateur et permet des optimisations supplémentaires des portes contrôlées, ce qui conduit généralement à des circuits de meilleure qualité (en particulier pour les circuits hiérarchiques).Cependant, vous pourrez toujours définir
annotated=Falseexplicitement pour conserver le comportement précédent.
Dépréciations du transcompilateur
- Le format de sérialisation hérité utilisé dans
SolovayKitaevDecomposition, qui reposait sur la conversion en format pickle des approximations de base sous la forme d'un objet Pythondict, a été déprécié. Le processus de chargement constitue une faille de sécurité potentielle et ne doit être utilisé qu'avec des fichiers fiables. Le nouveau format de sérialisation permet d'éviter cette vulnérabilité. Les fonctions permettant de générer le format hérité,generate_basic_approximations(), et de le charger,SolovayKitaevDecomposition.load_basic_approximations()ainsi que dans l'initialiseur deSolovayKitaevDecomposition, ont été dépréciées. Utilisez plutôtSolovayKitaevDecomposition.save_basic_approximations()pour générer un format pouvant être chargé en toute sécurité dans l'initialiseur de classe.
Modifications du système de compilation
- Lors de la compilation ou de l'empaquetage de Qiskit à partir du code source, la version requise de setuptools est désormais au moins la version 77.0 (publiée en mars 2025). Ceci vise à prendre en charge les nouvelles spécifications relatives aux métadonnées de licence de la norme PEP 639. Cette dépendance est spécifiée dans les exigences de compilation, aucune action manuelle ne devrait donc être nécessaire.
Corrections des erreurs
-
Corrige la mise en œuvre de
__deepcopy__()dansQuantumCircuitqui n'effectuait pas de copie en profondeur des paramètres du circuit. Par conséquent, la modification d'un élémentBoxOpdans un circuit copié n'affecte plus le circuit d'origine. -
DAGCircuit.apply_operation_back(),apply_operation_back()etcircuit_to_dag()va désormais ajouter de nouvelles arêtes dans un ordre déterministe. Ce comportement pouvait entraîner certaines phases du transcompilateur (telles queSabreSwap) à parcourir le DAG selon des ordres non déterministes. -
DAGCircuit.apply_operation_front()Il n'est plus possible d'insérer des boucles récursives non valides lors du traitement de nœuds contenant des conditions classiques. -
Correction d'un problème survenant
Optimize1qGatesDecompositionlorsque le passage était initialisé avec unTargetensemble contenant des portes de type « 1q » dotées de paramètres d'angle fixes. Auparavant, le passage pouvait potentiellement générer des portes en dehors de la cible, car il ne vérifiait pas si la porte de la cible prenait en charge des valeurs de paramètres arbitraires. Correction du ticket n° 14743. -
Correction d'un comportement incorrect dans le
BasisTranslatorpassage où une porte multi-qubits au sein d'unControlFlowOpbloc suivait les indices de qubits locaux au lieu d'utiliser les indices absolus du circuit source. -
Correction de la réutilisation d'une même
ConsolidateBlocksinstance sur plusieurs circuits, y compris lorstranspile()d'appels impliquant plusieurs circuits et en l'absence de parallélisation au niveau des processus. Un bug introduit dans la méthode2.2.2de Qiskit provoquait une exception de panique ou générait une sortie invalide si la même instance était réutilisée sur des circuits différents. -
Le passage du
ConsolidateBlockstranspileur va désormais déterminer correctement si une porte donnée est prise en charge par le matériel lors de la récursion dans les opérations de flux de contrôle. -
qpy.dump()peut désormais gérer l'écriture dans.gzdes fichiers ouverts à l'aide du modulegzipde la bibliothèque standard avec les versions 16 ou supérieures de QPY. Voir le n° 15157 pour plus de détails. -
Correction des méthodes
MCPhaseGate.inverse()etMCU1Gate.inverse()afin de préserver les états de contrôle des portes à commande ouverte lors du calcul de leurs inverses. -
ConsolidateBlocksrenverra désormais une exception de type « Python -space » au lieu de déclencher une panique lorsqu'il détecte une analyse non valide ou obsolète dans les clés legacyrun_list``block_listPropertySetou. -
Optimize1qGatesDecompositionprovoquera désormais uneTranspilerErrorau lieu d'une panique liée à l'espace de noms Rust lorsqu'on tentera de l'exécuter sur un circuit trop grand pour leTarget. -
Correction d'un problème lié à
picklela prise en charge de l'instanceSabreSwap, quiSabreSwapprovoquait une erreur lors de sa sérialisation après l'exécution deSabreSwap.run()la méthode. Problème n° 15071 résolu. -
Les passes de planification
ALAPScheduleAnalysisetASAPScheduleAnalysisgèrent désormais correctement les circuits ne contenant aucune opération. Auparavant, ils affichaient une erreurTranspilerErrorindiquant à tort « Aucune durée fournie ». Correction du problème n° 15145. -
Correction d'un problème qui
is_unitary()empêchait de respecter correctement les valeurs de tolérance d'entrée lors de la vérification du caractère unitaire d'un opérateur. La méthode utilise désormais correctement les paramètresrtoletatolfournis lors de la simplification de l'opérateur et de la vérification de son égalité avec l'identité. Cela corrige le ticket n° 14107. -
Correction d'un bug dans le passage
UnitarySynthesisdu transpileur, lorsqu'il est appelé avec un plugin de synthèse non par défaut (spécifié viamethod) qui prend en chargebasis_gatesmais pastarget. Le flux transmet désormais correctement les signaux de base dutargetvers le plugin. -
Correction d'un problème dans l'éditeur de texte de circuit, qui pouvait se produire lorsque des blocs de circuit situés à l'intérieur d'opérations de flux de contrôle étaient définis sur des registres différents de ceux du circuit externe. Cette situation peut par exemple se produire lors de l'ajout direct
ControlFlowOpd'opérations, ou pour les circuits après la transcompilation. -
Correction de la prise en charge de la sérialisation
PauliEvolutionGateà l'aide d'opérateurs de typeSparseObservable, lors de l'utilisation de la version 17 de QPY. -
Correction d'une incohérence dans
QkTargetOplaquelle la longueur du tableau stocké dansQkTargetOp.paramsne correspondait pas au nombre indiqué parQkTargetOp.num_params. Les paramètres génériques sont désormais représentés parNAN, et la longueur du tableau sera toujoursQkTargetOp.num_params. Ce bug n'était présent que dans la version 2.3.0rc1. -
Correction d'une régression dans la représentation classique des expressions de
ValuetypeUintd'une largeur supérieure à 64 bits. Auparavant, la valeur des expressions de ces types était convertie de manière involontaire en une valeur à virgule flottante de type double en interne, ce qui entraînait une perte de précision. -
Cette
HighLevelSynthesisopération sélectionnera désormais correctement la métrique d'optimisation en fonction de l'ensemble de bases : le nombre de portes à deux qubits pour les bases continues et le nombre de T pour les bases Clifford+T. Auparavant, ces informations n'étaient pas correctement transmises, ce qui entraînait des taux de T inférieurs aux prévisions. -
Correction du dessinateur de texte de circuit afin que les instructions de circuit avec des fils classiques soient dessinées dans des couches distinctes.
-
La multiplication matricielle (
@) entreOperatoretStatevectorva désormais appliquer l'opérateur à l'état et renvoyer le résultatStatevector. -
Correction d'un bug dans le passage
ElidePermutationsdu transpileur qui provoquait un plantage lors du traitement des permutations d'un seul qubit. -
Correction d'un problème de blocage potentiel lors de l'exécution de passes de mise en page, par exemple
SabreLayoutavec une connectivité disjointe dans leTargetet dans un contexte de multitraitement, résultant de l'exécution dePassManager.run()outranspile()avec plusieurs circuits. Sous Linux, c'est le comportement par défaut lors de l'exécution dePassManager.run()outranspile()avec plusieurs circuits; sur toutes les autres plateformes, vous devez activer manuellement l'utilisation d'un contexte de multitraitement.Cela était dû à un problème sous-jacent dans CPython détecté lors python/cpython#84559 du mélange du multitraitement et du multithreading. En règle générale, Qiskit empêche le mélange des deux méthodes de parallélisme, mais dans le cas du traitement de graphes de connectivité disjoints, cette protection faisait défaut autour du code Rust multithread.
-
La méthode
Statevector.to_dict()tiendra désormais compte de son argumentdecimalsde mot-clé, qu'elle ignorait auparavant. -
Correction d'un problème avec la fonction
timeline_drawer()de visualisation qui provoquait une erreur lors de la visualisation d'un circuit planifié à partir d'une cible comportant des portes paramétrées dont la durée était définie. -
Génération d'étiquettes fixes pour les
SparseObservableopérateursPauliEvolutionGate« with ». Les étiquettes affichent désormais les opérateurs de Pauli avec des indices de qubits (par exemple,"X0 X2") au lieu du format de chaîne concaténée (par exemple,"XX"), ce qui permet de distinguer plus clairement les différents opérateurs. -
Pauli.evolve()gère désormais correctement les circuits quantiques contenant certaines portes de rotation paramétrées, lorsque l'angle est un multiple de , par exempleRZGate(math.pi/2)ouRZZGate(math.pi/2). Auparavant, elles n'étaient pas reconnues comme des portes de Clifford, ce qui a généré une erreur. -
BasePassManagerne remplace plus les résultats « falsy » mais valides des passes par le programme d'entrée d'origine. Une valeur de retour0« pass »Falseou toute autre valeur fausse sera désormais conservée, et seule la valeurNone« fail » indiquera un échec. -
QuantumCircuit.compose()remappera désormais correctement toutes les variables et tous les étirements utilisés dansDelayles instructions lorsquevar_remapl'argument est spécifié.