Skip to main content
IBM Quantum Platform

Qiskit SDK 1.2 notes de mise à jour


1.2.4

Prélude

Qiskit 1.2.4 est une version corrective qui corrige un problème de QPY introduit dans la version corrective de 1.2.3 . Dans 1.2.3, une erreur se produisait lors du chargement d'un fichier QPY généré avec une version de symengine différente de celle installée lors du chargement.

Corrections des erreurs

  • Correction d'un problème introduit dans la version corrigée de 1.2.3 qui provoquait une exception avec le message d'erreur "Qiskit doesn't support loading a symengine payload generated with symengine >= 1.0 " lors du chargement d'un fichier QPY généré avec une version de symengine différente de la version installée lors du chargement. Ce problème ne peut se produire que sur le site 1.2.3.

1.2.3

Prélude

Qiskit 1.2.3 est un correctif corrigeant un problème dans QPY qui pouvait faire en sorte que les fichiers générés par un environnement Python ne se chargent pas dans un environnement Python différent, bien que le format soit censé être transférable. Ceci est lié à des différences dans la version de la bibliothèque symengine, contre lesquelles QPY aurait dû se prémunir.

Problèmes connus

  • Les versions de Qiskit antérieures à 1.2.4 ne pourront pas charger les fichiers QPY vidés à l'aide de qpy.dump()même si version est configuré de manière appropriée, si :

    • il y a des objets non liés ParameterExpression dans le fichier QPY,
    • le drapeau use_symengine=True a été activé (ce qui est le cas par défaut dans Qiskit >= 1.0.0 ) dans qpy.dump()et
    • la version de symengine installée dans les environnements de génération et de chargement n'est pas la même version mineure.

    Ceci s'applique quelle que soit la version de Qiskit utilisée dans la génération (au moins jusqu'à Qiskit 1.2.4 inclus).

    Si vous voulez maximiser la compatibilité avec les versions de Qiskit < 1.2.3, you should set use_symengine=False. Versions of Qiskit > = 1.2.3, vous ne devriez pas avoir besoin de cela.

  • Les fichiers QPY de la série Qiskit 0.45 peuvent, dans des circonstances très spécifiques et peu probables, ne pas se charger avec une version plus récente de Qiskit, y compris Qiskit 1.2.4. Les critères sont les suivants :

    • le QuantumCircuit ou ScheduleBlock à déverser contenait des objets non liés ParameterExpression objets,
    • la version installée de symengine faisait partie de la série 0.9 (qui était la version la plus récente pendant la fenêtre de support de Qiskit 0.45 ), et
    • le use_symengine=True l'indicateur a été défini (ce qui n'était pas la valeur par défaut).

    Les versions ultérieures de Qiskit utilisées lors de la génération ne sont pas affectées, car elles nécessitaient des versions plus récentes que symengine 0.9.

    Dans ce cas, vous pouvez récupérer le fichier QPY en le rechargeant dans un environnement où Qiskit 0.45.3 et symengine 0.9.2 sont installés. Ensuite, utilisez qpy.dump() avec use_symengine=False pour réexporter le fichier. Il sera alors lisible par toute version plus récente de Qiskit.

Mise à niveau

  • Les versions supportées de symengine ont été préventivement plafonnées à < 0.14.0 (qui devrait être la prochaine version mineure, à partir de cette version de Qiskit). Ceci a été fait pour se prémunir contre une incompatibilité potentielle en qpy lors de la sérialisation des objets ParameterExpression des objets. La sérialisation utilisée dans les versions 10, 11 et 12 du format QPY pour ParameterExpression les objets sont liés à la version symengine utilisée pour les générer, et il est possible qu'une future version de symengine ne soit pas compatible. Cette limite supérieure de version a pour but d'éviter qu'une future version de symengine ne provoque des incompatibilités en essayant de charger des fichiers QPY à l'aide de qpy.load().

Corrections des erreurs

  • Correction d'un problème avec qpy.load() lors du chargement d'un fichier QPY contenant un ParameterExpressionsi les versions de symengine installées dans les environnements de génération et de chargement n'étaient pas les mêmes. Par exemple, si un fichier QPY contenant des objets ParameterExpression a été généré à l'aide de Qiskit 1.2.2 avec symengine==0.11.0 installé, Qiskit 1.2.2 avec symengine==0.13.0 installé ne pourra pas le charger.

    Auparavant, une erreur aurait été soulevée par symengine pour contourner cette incompatibilité de version. Ce problème a été résolu pour symengine 0.11 et 0.13 (il n'y avait pas de 0.12 ). Cependant, si vous essayez d'utiliser différentes versions de symengine et qu'il y a une incompatibilité, cette version de Qiskit pourrait ne pas fonctionner.


1.2.2

Prélude

Qiskit 1.2.2 est une version mineure de correction de bugs pour la série 1.2.

Corrections des erreurs

  • Correction d'un bug dans la passe de transposition ElidePermutations où le mappage des qubits n'était pas mis à jour correctement en présence de PermutationGates.

  • Correction d'une source potentielle de non-déterminisme dans DenseLayout (et par extension SabreLayout) lors du ciblage d'un CouplingMap ou Target qui a plus d'un sous-graphe avec le même degré de connectivité. Dans ce cas, la présentation exacte de la sortie de la passe peut fluctuer en fonction du nombre d'unités centrales locales et de la vitesse d'exécution des threads.

  • La passe de HighLevelSynthesis ne soulève plus d'exception lorsqu'il rencontre une porte personnalisée appelée "qft" mais qui n'est pas une instance de QFTGate. Au lieu de cela, les plugins de synthèse pour les portes QFT ignorent une telle porte, et la définition de la porte est utilisée (si elle est fournie).

  • Correction d'un bug dans les tiroirs de circuits, qui pouvaient échouer ou omettre des fils si idle_wires=False. Correction de #13128 et #13146.

  • Correction d'un problème lors de l'appel de la méthode transpile() ou la méthode StagedPassManager.run() d'un gestionnaire de passe généré par generate_preset_pass_manager()utilisant optimization_level 2 ou 3 lorsque l'argument routing_method est défini à "none" pour désactiver explicitement le routage. Auparavant, dans ces conditions, le transpileur exécutait la passe ElidePermutations dans le cadre de l'étape init, car dans des conditions normales, il s'agit d'une optimisation utile pour supprimer SwapGate et PermutationGate du circuit. Mais cette optimisation n'était pas attendue sur le site routing_method="none" , car elle modifie le circuit de la même manière que le routage, qui ne devrait pas être effectué sur le site routing_method="none". Ce problème a été corrigé en n'exécutant plus ElidePermutations si routing_method="none" est défini. Correction #13144.

  • L'exportateur OpenQASM 3 a rétabli son comportement d'acceptation des fichiers d'inclusion de bibliothèques non standard dans l'argument includes de la commande qasm3.dump(), dumps(), et Exporter. Celles-ci insèrent une déclaration include appropriée dans la sortie, comme précédemment, et l'exportateur ne connaît pas les portes prévues dans ce fichier d'inclusion; vous devez transmettre les portes que vous souhaitez qu'il définisse dans l'argument basis_gates aux mêmes fonctions.

    Nous prévoyons d'améliorer le mécanisme d'exportation contre les fichiers include non standard dans une prochaine version de Qiskit.


1.2.1

Prélude

Qiskit 1.2.1 est une version mineure de correction de bugs pour la série 1.2.

Corrections des erreurs

  • Correction d'un problème avec les visualisations de certaines cartes de backends/couplages qui s'affichaient comme étant repliées sur elles-mêmes. Le paramètre par défaut <https://graphviz.org/docs/layouts/neato/> fonctionne bien dans la plupart des cas. Toutefois, prism overlap permet d'obtenir une présentation plus régulière pour d'autres scénarios.

  • Les portes de la bibliothèque standard contrôlées par des paramètres (telles que CRXGate) seront désormais correctement extraites vers une porte standard de l'espace Rust lors de l'utilisation de QuantumCircuit.append() et l'objet gate. Auparavant, il y avait un problème lorsque l'utilisation de la méthode QuantumCircuit.crx() entraînait une extraction correcte dans l'espace rouille, mais pas la forme append() . En règle générale, le bogue ne devrait pas avoir causé de problèmes sur le site Python.

  • Correction d'un bug dans TwoQubitBasisDecomposer où le code basé sur Rust paniquait si la porte KAK donnée n'était pas une version par défaut des portes standard (par exemple, en utilisant CXGate(ctrl_state=0)). Correction #12998.

  • Correction d'un bug où InstructionDurations.from_backend() ne fonctionnait pas pour les backends BackendV2 ne fonctionnait pas. Correction #12760.

  • Correction de la définition de la matrice CUGate dans l'espace Rust. Bien que cela ne soit pas perceptible lorsque l'on manipule le code CUGate purement du côté de Python, cela avait des répercussions lorsque les passes de transpilation utilisaient la représentation Rust, comme cela pouvait se produire dans Consolidate2qBlocks. Correction #13118.

  • Correction d'un bug dans HoareOptimizer où une porte contrôlée était simplifiée en supprimant ses contrôles, mais la nouvelle porte n'était pas gérée correctement. Correction #13079.

  • generate_preset_pass_manager() lève désormais correctement une exception si seed_transpiler a une valeur invalide (c'est-à-dire si ce n'est pas un entier non négatif). Correction #12938.

  • Correction d'un cas limite dans SabreLayoutoù, dans de rares cas, sur des appareils de grande taille et des circuits difficiles, le routage échouait. Cela s'explique par le fait que la soupape de décharge rend plus d'une porte à deux qubits routable, alors qu'une seule était attendue. Correction #13081.

  • Correction d'un bug dans Split2QUnitaries où il ne fonctionnait pas sur les circuits avec des objets personnalisés Gate qui n'implémentaient pas __array__. Voir #12970.

  • Correction d'un bogue dans StatePreparation où l'argument normalize était ignoré pour les tableaux d'entrée. Correction #12984.

  • Correction d'un bogue dans lequel diverses méthodes de synthèse créaient des circuits sans registres quantiques ou classiques. Cela a également affecté les fonctions qui utilisent en interne les méthodes de synthèse, telles que Clifford.to_circuit(). Bien que les circuits soient valables, cela peut poser des problèmes lors de la comparaison des circuits avec les registres. Correction #13041.

  • Correction d'un bug qui provoquait l'échec de la méthode Initialize.gates_to_uncompute() échouait. Correction #12969.

  • Correction d'un cas particulier lors de la transposition d'un circuit avec optimization_level 2 ou 3 avec un ensemble incomplet de portes de base à 1 qubit sur un circuit contenant des portes à 2 qubits, qui peut être implémenté comme un produit de portes à un seul qubit. Ce problème est résolu en limitant Split2QUnitaries à ne prendre en compte que les objets UnitaryGate objets. Correction #12970.


1.2.0

Prélude

La version de Qiskit 1.2.0 se concentre principalement sur l'amélioration des performances et de la qualité du compilateur. Il s'agit également de la dernière version prenant en charge Python 3.8. Dans Qiskit 1.3.0, la version minimale requise de Python sera 3.9. Parmi un large éventail de nouvelles fonctionnalités, d'améliorations et de corrections, les points forts de la version sont les suivants :

  • L'infrastructure du circuit, y compris les portes et les opérations, est transférée à Rust. Cela permet une série d'accélérations dans la construction et la manipulation des circuits.
  • En s'appuyant sur le point précédent, certaines parties de la bibliothèque de synthèse construisent désormais des circuits en Rust. Cela permet d'accélérer considérablement la synthèse d'opérations telles que les cliffords, les permutations ou les fonctions linéaires. Par exemple, la décomposition de cliffords de plus de 50 qubits bénéficie d'une accélération d'environ 1000 fois en temps d'exécution.
  • La qualité des circuits compilés est améliorée par l'optimisation à l'aide d'un peephole unitaire au stade initial du processus de transpilation (au niveau d'optimisation >1), et par l'utilisation d'une disposition dense comme essai de disposition Sabre (au niveau d'optimisation >0).

Nouvelles fonctions

  • Ajout d'une nouvelle classe QFTGate pour représenter nativement les transformées de Fourier quantiques (QFT). L'ancienne façon de représenter les QFT par des circuits quantiques, voir QFTest conservée pour des raisons de compatibilité ascendante. La nouvelle façon de représenter une QFT via une porte évite de synthétiser son circuit de définition lorsque la porte est déclarée, ce qui retarde la synthèse proprement dite au niveau du transpondeur. Il permet également de choisir facilement entre plusieurs algorithmes différents pour synthétiser les QFT, qui sont disponibles sous forme de plugins de synthèse de haut niveau.

  • Ajout d'une méthode de synthèse synth_qft_full() pour construire un circuit QFT en supposant une architecture entièrement connectée.

  • Ajout de deux plugins de synthèse de haut niveau permettant de synthétiser un QFTGate. La classe QFTSynthesisFull est basée sur synth_qft_full() et synthétise une porte QFT en supposant une connectivité totale. La classe QFTSynthesisLine est basée sur synth_qft_line() et synthétise une porte QFT en supposant une connectivité linéaire au plus proche voisin.

  • Ajout de deux paramètres à GenericBackendV2 pour exclure l'erreur (noise_info) et l'information sur le canal d'impulsion (pulse_channels) de la construction du backend. Ces paramètres sont True par défaut, reproduisant ainsi le comportement initial par défaut du constructeur. Un utilisateur sensible à la mémoire peut définir ces options sur False pour réduire la charge de mémoire de 40x lors de la transpilation sur des systèmes à grande échelle GenericBackendV2.

  • La classe StabilizerState dispose désormais d'une nouvelle méthode StabilizerState.probabilities_dict_from_bitstring() permettant à l'utilisateur de passer une chaîne de bits unique pour mesurer un résultat. Auparavant, l'outil StabilizerState.probabilities_dict() était utilisée et, dans le pire des cas, calculait ( 2n2^n ) un certain nombre de probabilités (en fonction de l'état), même si l'utilisateur souhaitait un résultat unique. Avec cette nouvelle méthode, l'utilisateur peut calculer uniquement la valeur de la chaîne de bits du résultat qu'il transmet pour mesurer la probabilité. Plus le nombre de qubits augmente, plus l'amélioration des performances peut être importante (en fonction de l'état) car seul le résultat d'une chaîne de bits est mesuré.

  • Implémentation de la classe UniformSuperpositionGate , qui permet de créer un état de superposition uniforme à l'aide de l'algorithme de Shukla-Vedula. Cette caractéristique facilite la création de circuits quantiques qui produisent un état de superposition uniforme 1Mj=0M1j\frac{1}{\sqrt{M}} \sum_{j=0}^{M-1} |j\rangle, où MM est un nombre entier positif représentant le nombre d'états de base de calcul avec une amplitude de 1M\frac{1}{\sqrt{M}}. Cette mise en œuvre permet la création efficace d'états de superposition uniformes, ne nécessitant que des qubits O(log2(M))O(\log_2 (M)) et des portes O(log2(M))O(\log_2 (M)). Exemple d'utilisation :

    from qiskit import QuantumCircuit 
    from qiskit.circuit.library.data_preparation import UniformSuperpositionGate
    
    M = 5
    num_qubits = 3
    usp_gate = UniformSuperpositionGate(M, num_qubits)
    qc = QuantumCircuit(num_qubits)
    qc.append(usp_gate, list(range(num_qubits)))
    
    qc.draw()

Caractéristiques des circuits

  • Ajout d'une nouvelle fonction random_clifford_circuit() à qiskit.circuitqui permet de générer un circuit de Clifford pseudo-aléatoire avec des portes de la bibliothèque standard. Exemple d'utilisation :

    from qiskit.circuit.random import random_clifford_circuit
    
    circ = random_clifford_circuit(num_qubits=2, num_gates=6)
    circ.draw(output='mpl')
    _images/release_notes-1.png
  • Ajout de la prise en charge de AnnotatedOperation.params et AnnotatedOperation.validate_parameter()qui permettent de gérer les paramètres au niveau du circuit (tels que les paramètres de liaison) pour les opérations annotées.

  • CircuitInstruction et DAGOpNode ont tous deux de nouvelles méthodes pour interroger diverses propriétés de leurs données internes Operationsans avoir nécessairement besoin d'y accéder. Ces méthodes sont les suivantes

    Le cas échéant, l'utilisation de l'une de ces méthodes est nettement plus rapide que l'interrogation de CircuitInstruction.operation ou DAGOpNode.op directement, surtout si l'instruction ou le nœud représente une porte standard Qiskit. En effet, les portes standard sont stockées nativement dans Rust, et leur représentation Python n'est créée qu'à la demande.

  • Une représentation native en rouille de la bibliothèque de portes standard de Qiskit a été ajoutée. Lorsqu'une porte standard est ajoutée à une porte QuantumCircuit ou DAGCircuit elle est maintenant représentée d'une manière plus efficace directement en Rust. L'accès à cet objet de porte à partir d'un circuit ou d'un DAG renverra un nouvel objet Python représentant la porte standard. Cela permet une transposition et une manipulation plus rapides et plus efficaces des circuits pour les fonctionnalités écrites en Rust.

  • La fonction random_circuit() est dotée d'une nouvelle fonction qui permet aux utilisateurs de spécifier une distribution num_operand_distribution (un dict) qui spécifie le ratio des portes 1-qubit, 2-qubit, 3-qubit et 4-qubit dans le circuit aléatoire. Par exemple, si num_operand_distribution = {1: 0.25, 2: 0.25, 3: 0.25, 4: 0.25} est transmis à la fonction, le circuit généré comportera environ 25 % de portes 1-qubit, 2-qubit, 3-qubit et 4-qubit. Il convient également de noter que si num_operand_distribution n'est pas spécifié, max_operands prendra par défaut la valeur 4 et un circuit aléatoire avec une distribution aléatoire des portes sera généré. Si num_operand_distribution et max_operands sont spécifiés en même temps, num_operand_distribution sera utilisé pour générer le circuit aléatoire.

    Exemple d'utilisation :

    from qiskit.circuit.random import random_circuit
    
    circ = random_circuit(
      num_qubits=6, depth=5, num_operand_distribution={1: 0.25, 2: 0.25, 3: 0.25, 4: 0.25}
    )
    circ.draw(output="mpl")
    _images/release_notes-2.png
  • Amélioration des performances de la méthode DAGCircuit.quantum_causal_cone() en n'examinant pas plusieurs fois le même nœud non directif lorsqu'il est atteint par des chemins différents.

  • Ajout du mot-clé insert_barriers comme argument à la méthode QuantumCircuit.repeat() méthode. Le réglage sur True permet d'insérer des barrières entre les répétitions du circuit.

  • En remplaçant l'algorithme de synthèse interne de StatePreparation et Initialize de Shende et al. par l'algorithme donné dans Isometry de Iten et al. Le nouvel algorithme réduit le nombre de portes CX et la profondeur du circuit d'un facteur 2.

  • ParameterExpression supporte désormais l'opérateur unaire + .

Fonctionnalités primitives

  • Ajout d'une nouvelle méthode BitArray.postselect() qui renvoie tous les plans contenant les valeurs de bits spécifiées. Exemple d'utilisation :

    from qiskit.primitives.containers import BitArray
    
    ba = BitArray.from_counts({'110': 2, '100': 4, '000': 3})
    print(ba.postselect([0,2], [0,1]).get_counts())
    # {'110': 2, '100': 4}
  • Les métadonnées des Primitives V2 implémentations, c'est-à-dire, StatevectorSampler, StatevectorEstimator, BackendSamplerV2 et BackendEstimatorV2ont été mises à jour pour correspondre à celles des dispositifs quantiques IBM.

    Notez que les métadonnées de StatevectorEstimator n'ont pas shots parce que la classe calcule les valeurs d'espérance avec Statevector et les tirs ne sont pas utilisés.

OpenQASM Caractéristiques

  • La table de symboles interne de l'exportateur OpenQASM 3 (qiskit.qasm3) a été réécrite, ce qui devrait permettre d'obtenir des résultats plus propres lors de l'utilisation de portes de la bibliothèque standard Qiskit qui ne se trouvent pas dans les en-têtes de la bibliothèque standard OpenQASM 3, ainsi que des résultats plus déterministes. Par exemple, l'utilisation de plusieurs RZXGatene donnera plus qu'une seule définition paramétrique et, en cas de collision de noms, la table des symboles attribuera un compteur déterministe pour rendre les noms uniques, plutôt qu'un entier non déterministe (auparavant, l'identité de l'objet était utilisée).

  • La version vendue de la bibliothèque standard OpenQASM 3.0 a été mise à jour pour correspondre à l' état de la livraison 4ca1d79383. Cela ne devrait généralement pas avoir d'effet sur votre utilisation de Qiskit, à moins que vous ne récupériez notre fichier vendu pour votre propre usage.

Caractéristiques de la synthèse

  • MCXRecursive avec kk qubits de contrôle et un seul qubit auxiliaire propre ne nécessite plus que 16k816k-8 portes CX.

  • MCXVChain comporte deux nouveaux paramètres booléens : relative_phase et action_seule. Si action_only est True , le circuit ne nettoie pas les qubits sales. Si relative_phase est True , la porte est mise en œuvre jusqu'à une phase globale. Les deux paramètres sont utilisés pour optimiser la décomposition de MCXVChain.

  • MCXVChain avec les contrôles kk et les qubits auxiliaires sales k2k-2 nécessite maintenant des portes CX 8k68k-6.

  • Port synth_permutation_acg()utilisé pour synthétiser des permutations de qubits, à Rust. On obtient ainsi une amélioration des performances d'environ 3x sur des circuits de 1000 qubits.

  • Port synth_permutation_basic()utilisé pour synthétiser des permutations de qubits, à Rust.

  • Port synth_cnot_count_full_pmh()la fonction CX, utilisée pour synthétiser une fonction linéaire en un réseau CX, à Rust. On obtient ainsi une accélération d'environ 44x, mesurée sur des circuits de 100 qubits.

  • La fonction synth_cnot_count_full_pmh() permet maintenant de choisir le site (heuristiquement) optimal section_size en le fixant à None. On choisit ensuite une valeur qui tente de minimiser la limite supérieure du nombre de portes CX, c'est-à-dire αlog2(n)\alpha \log_2(n)nn est le nombre de qubits et α0.56\alpha \approx 0.56.

  • La fonction synth_clifford_bm() a été portée en Rust. Rappelons que cette fonction synthétise de manière optimale les opérateurs sur 1, 2 ou 3 qubits en fonction du nombre de portes CX Clifford des opérateurs sur 1, 2 ou 3 qubits en fonction du nombre de portes CX. Cela se traduit par une augmentation significative des performances. Pour les Cliffords de plus de 3 qubits, l'accélération est de l'ordre de 80 fois.

  • La fonction synth_clifford_greedy() qui synthétise les opérateurs Clifford a été portée en Rust, ce qui a conduit à une augmentation significative des performances pour tous les nombres de qubits. Pour les Cliffords de plus de 50 qubits, l'accélération est de l'ordre de 1000 fois.

  • Ajout du mot-clé wrap aux classes ProductFormula qui, lorsqu'il est activé, englobe les termes d'évolution de Pauli individuels. Cela peut être utile pour visualiser des circuits.

  • L'argument atomic_evolution de ProductFormula (et ses sous-classes) a une nouvelle signature de fonction. Plutôt que de prendre un opérateur de Pauli et un coefficient de temps et de renvoyer le circuit d'évolution, la nouvelle fonction prend en compte un circuit existant et doit y ajouter l'évolution de l'opérateur de Pauli fourni et du temps donné. Cette nouvelle mise en œuvre est nettement plus performante.

  • Amélioration des performances de synth_permutation_depth_lnn_kms()utilisé pour synthétiser des permutations pour la connectivité linéaire, en le portant sur Rust.

Fonctionnalités du transpilateur

  • Ajout d'une nouvelle option de chemin d'importation pour generate_preset_pass_manager()afin qu'il puisse être importé en tant que :

    from qiskit import generate_preset_pass_manager

    au lieu d'avoir à saisir le chemin complet :

    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

    La fonction est également importable à partir du module qiskit.transpiler en tant que :

    from qiskit.transpiler import generate_preset_pass_manager
  • Ajout d'une nouvelle option dans le fichier de configuration de l'utilisateur sabre_all_threads et d'une variable d'environnement correspondante QISKIT_SABRE_ALL_THREADS. Lorsque cet indicateur est activé, les gestionnaires de laissez-passer prédéfinis exécutent les fonctions SabreLayout et SabreSwap en utilisant tous les processeurs disponibles sur le système local. L'utilisation de cette option est un compromis entre le déterminisme de la sortie entre différents ordinateurs et une sortie potentiellement meilleure avec moins de SwapGates.

    Ces passes de transpilation exécutent plusieurs essais aléatoires en parallèle et choisissent la sortie qui produit le moins de SwapGates. En règle générale, si vous effectuez davantage d'essais, l'algorithme aura plus d'occasions de trouver un meilleur résultat. Par défaut, les gestionnaires de passage prédéfinis utilisent un nombre fixe d'essais, dans cette version 5 essais pour les niveaux 0 et 1, et 20 essais pour les niveaux 2 et 3, mais ces nombres peuvent changer dans les versions futures (et étaient différents dans les versions antérieures). L'utilisation d'un nombre fixe d'essais permet d'obtenir des résultats déterministes quel que soit le système local, car même avec une graine fixe, si vous deviez utiliser par défaut le nombre d'unités centrales locales disponibles, les résultats seraient différents selon l'ordinateur utilisé.

    Si le nombre d'essais par défaut pour un niveau d'optimisation donné est supérieur au nombre de CPU locaux, il utilisera le niveau d'optimisation par défaut qui est le plus élevé.

  • Ajout d'une nouvelle passe Split2QUnitaries qui passe en revue toutes les portes ou unités à deux qubits d'un circuit et les remplace par deux unités à un qubit, si possible sans introduire d'erreurs, c'est-à-dire que la porte ou l'unité à deux qubits est en fait un produit tensoriel d'unités à un qubit.

  • Les laissez-passer Collect2qBlocks, ConsolidateBlocks et Split2QUnitaries ont été ajoutées à l'étape init des gestionnaires de passes prédéfinis avec le niveau d'optimisation 2 et le niveau d'optimisation 3. La modification de l'étape init devrait permettre un routage plus efficace des circuits quantiques qui soit :

    • contiennent des portes unitaires à deux qubits qui sont en fait un produit de portes à un qubit, ou
    • contiennent plusieurs portes à deux qubits dans un bloc continu de portes à deux qubits.

    Dans le premier cas, l'acheminement de la porte à deux qubits peut simplement être ignoré car il n'y a pas d'interaction réelle entre une paire de qubits. Dans ce dernier cas, l'espace d'anticipation des algorithmes de routage n'est pas "pollué" par des portes à deux qubits superflues, c'est-à-dire que pour le routage, il suffit de ne considérer qu'une seule porte à deux qubits par bloc continu de portes à deux qubits. Ces passes ne sont pas exécutées si les gestionnaires de passes ciblent une porte de base discrète, c'est-à-dire que toutes les portes de base n'ont pas de paramètres Target qui a un ensemble de portes de base discret, c'est-à-dire que toutes les portes de base ne sont pas paramétrées.

  • La performance de StarPreRoutingutilisé pour trouver un sous-circuit de connectivité de graphe en étoile, est améliorée en effectuant les opérations lourdes dans l'espace Rust.

  • La passe de SabreLayout le transpiler pass a été mis à jour afin de toujours effectuer un essai supplémentaire en utilisant le même algorithme que celui utilisé par Sabre pour choisir le point de départ de l'algorithme de mise en page DenseLayout afin de choisir un point de départ pour l'algorithme de mise en page de Sabre. Le point de départ utilisé par l'algorithme de mise en page peut avoir une grande influence sur la qualité des résultats. Par défaut SabreLayout commence toujours par layout_trials essais aléatoires, mais il y aura en plus un seul essai qui utilisera le sous-graphe le plus dense du graphe de connectivité comme point de départ. Cela peut donner de meilleurs résultats dans certains cas, en particulier lorsque les circuits sont plus petits pour des cartes de couplage plus grandes.

  • Un nouvel argument dt a été ajouté à generate_preset_pass_manager() pour correspondre à l'ensemble des arguments de transpile(). Cela permettra la conversion interne des contraintes de transpilation en une représentation Target représentation.

Fonctionnalités de visualisation

  • Le fichier de configuration de l'utilisateur comporte une nouvelle option circuit_idle_wires, qui prend une valeur booléenne. Cela permet aux utilisateurs de définir leur comportement par défaut préféré de l'option idle_wires des tiroirs de circuits QuantumCircuit.draw() et circuit_drawer(). Par exemple, l'ajout d'une section à ~/.qiskit/settings.conf avec :

    [default]
    circuit_idle_wires = false

    modifiera la valeur par défaut pour ne pas afficher les fils inactifs.

Divers. Fonctions

  • Ajout d'une nouvelle variable d'environnement QISKIT_NO_CACHE_GATES qui, lorsqu'elle est définie à une valeur de 1 (c'est-à-dire QISKIT_NO_CACHE_GATES=1), permet d'améliorer la qualité de l'environnement diminue l'encombrement de la mémoire d'un CircuitInstruction et DAGOpNode au prix d'une augmentation de la durée d'exécution lors des accès multiples à CircuitInstruction.operation et DAGOpNode.op. Si cette variable d'environnement est définie lors de la construction du paquetage Qiskit Python à partir des sources, la mise en cache du retour de ces attributs sera désactivée.

Notes sur la mise à niveau des circuits

  • L'argument annotated de la méthode Gate.control() est désormais None par défaut, ce qui permet à Qiskit de choisir d'annoter ou non une opération contrôlée. Si l'implémentation concrète (annotated=False) est disponible, elle sera renvoyée par défaut. Dans le cas contraire, l'implémentation annotée sera renvoyée (annotated=True). Cela permet, par exemple, de différer la synthèse de portes contrôlées et paramétrées.

  • Les Operation instances de DAGOpNode.op renvoyées ne partageront plus nécessairement une référence commune à l'objet sous-jacent. Il n'a jamais été garanti que ce soit le cas et la mutation de l'élément DAGOpNode.op directement par référence n'était pas judicieux et risquait toujours de corrompre le suivi de l'état interne du DAG. En raison du refactoring interne de l'élément QuantumCircuit et DAGCircuit pour stocker des portes standard en Rust, l'objet de sortie de DAGOpNode.op sera probablement une copie au lieu d'une instance partagée. Si vous devez muter un élément, veillez à le faire :

    op = dag_node.op
    op.params[0] = 3.14159
    dag.substitute_node(dag_node, op)

    au lieu de faire quelque chose comme :

    dag_node.op.params[0] = 3.14159

    qui ne fonctionnera pour aucune porte standard dans cette version. Cela aurait probablement fonctionné par hasard dans une version précédente mais n'a jamais été une garantie de l'API.

  • Les Operation instances de CircuitInstruction.operation renvoyées ne partageront plus nécessairement une référence commune à l'objet sous-jacent. Cela n'a jamais été garanti et la mutation de l'élément CircuitInstruction.operation directement par référence n'était pas judicieux et risquait toujours de corrompre le circuit, en particulier lorsque des paramètres étaient utilisés. En raison du refactor interne de l'objet QuantumCircuit pour stocker les portes standard en Rust, l'objet de sortie de CircuitInstruction.operation sera probablement une copie au lieu d'une instance partagée. Si vous devez faire muter un élément du circuit (ce qui est fortement déconseillé car inefficace et source d'erreurs), vous devez vous en assurer :

    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(1)
    qc.p(0)
    
    op = qc.data[0].operation
    op.params[0] = 3.14
    
    qc.data[0] = qc.data[0].replace(operation=op)

    au lieu de faire quelque chose comme :

    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(1)
    qc.p(0)
    
    qc.data[0].operation.params[0] = 3.14

    qui ne fonctionnera pour aucune porte standard dans cette version. Cela aurait probablement fonctionné par hasard dans une version précédente mais n'a jamais été une garantie de l'API.

Notes de mise à niveau des primitives

  • BitArray.slice_bits() et BitArray.slice_shots() affichent désormais IndexError lorsque les indices sont hors limites. Ils avaient l'habitude de collecter ValueError dans le cadre de cette affaire.

  • BitArray.__getitem__() soulèvera désormais IndexError lorsque les indices sont hors limites ou que le nombre de dimensions des indices ne correspond pas à celui de BitArray. Ils avaient l'habitude de collecter ValueError dans le cadre de cette affaire.

Notes de mise à niveau de Synthesis

  • LieTrotter et SuzukiTrotter et ne plus envelopper les termes de Pauli évolués individuellement dans des définitions de portes. Si vous vous fiez à un certain niveau de décomposition de votre circuit, vous devez supprimer un niveau de QuantumCircuit.decompose() ou ajouter l'argument du mot-clé wrap=True à votre objet de synthèse.

Notes de mise à niveau du transpilateur

  • Les niveaux d'optimisation 2 et 3 emploient désormais en plus l'optimisation peephole avant l' étape de traduction/synthèse (auparavant, elle n'était effectuée qu'au cours de l'étape d'optimisation). Les effets de l'optimisation du judas comprennent l'élimination des portes qui sont très proches de l'identité, par exemple les portes à phase contrôlée dont l'angle de rotation est inférieur à 2π2252\pi \otimes 2^{-25}.

  • La passe de routage par défaut utilisée par le niveau d'optimisation 0 pour les generate_preset_pass_manager() et transpile() est passé de StochasticSwap à SabreSwap. La passe SabreSwap exécute exactement la même fonction mais est plus performante en termes de temps d'exécution et de qualité de sortie (en termes de nombre de portes d'échange et de profondeur) par rapport à la passe StochasticSwap. Pour optimization_level=0 , cela ne devrait pas avoir d'importance car il n'est pas prévu d'exécuter le routage pour le cas d'utilisation typique du niveau 0.

    Si vous utilisiez l'algorithme de routage par défaut précédent pour une raison quelconque, vous pouvez utiliser l'argument routing_method pour transpile() et generate_preset_pass_manager() à "stochastic" pour utiliser le StochasticSwap passer.

  • La fonction generate_preset_pass_manager() a été améliorée pour, lorsque cela est possible, convertir en interne les contraintes du transpondeur en une instance de Target instance. Si une entrée backend de type BackendV1 est fournie, elle sera convertie en BackendV2 pour exposer son Target. Cette modification ne nécessite aucune action de la part de l'utilisateur.

Divers. Mise à niveau

  • La version minimale de rustworkx requise pour exécuter cette version a été augmentée de 0.14.0 à 0.15.0. Ceci est nécessaire car Qiskit utilise maintenant une nouvelle fonctionnalité ajoutée dans la version rustworkx 0.15.0 qui améliore les performances.

Circuits obsolètes

Primitives obsolètes

Avertissements aux fournisseurs

Dépréciations du transcompilateur

  • La fonction assemble() est désormais obsolète et sera supprimée dans la version 2.0. La fonction était principalement utilisée pour créer un site Qobj, ce qui n'est plus nécessaire dans les flux de travail basés sur la technologie BackendV2-les flux de travail basés sur l'utilisation de l'Internet ne sont plus nécessaires dans les flux de travail basés sur l'Internet. Il a également été utilisé pour lier des paramètres, une fonctionnalité entièrement couverte par la norme QuantumCircuit.assign_parameters().

Dépréciations de la visualisation

  • L'argument justify de circuit_drawer() ou QuantumCircuit.draw()ne prend plus en charge les valeurs non valides (il les remplaçait auparavant par la valeur par défaut) et, dans une prochaine version, il y aura une erreur. Les valeurs justifiées valables sont "left", "right" ou "none".

  • La fonction visualize_transition() est obsolète et sera supprimée dans la version 2.0.0. Cette fonction présentait un certain nombre de limitations qui restreignaient son utilité à des cas d'utilisation très spécifiques et ne s'intégrait pas au reste du module de visualisation de Qiskit.

Corrections des erreurs

  • Correction d'une série de problèmes lors du contrôle des portes standard paramétrées. La version contrôlée de certains portails (par ex. RXXGate ou RYGate pour plus d'un contrôle) ne peuvent pas être synthétisés s'ils contiennent des paramètres non liés. Auparavant, l'appel à .control() dans un tel cas échouait, mais nous créons désormais un fichier AnnotatedOperation en guise d'espace réservé. Cela permet d'insérer la porte contrôlée dans un circuit, de lier les paramètres à un stade ultérieur, puis de synthétiser l'opération. Corrige #10311, #10697, et #12135.

  • Les SGate et SdgGate renvoient maintenant correctement a CSGate, resp. CSdgGate, s'ils sont contrôlés par un seul qubit de contrôle.

  • Fixer le calcul de l'écart-type en BackendEstimatorV2en tenant compte de la covariance des Paulis non commutatifs. Fixé Qiskit/qiskit-ibm-runtime#1751.

  • Correction d'un problème où circuit_drawer() ou la méthode QuantumCircuit.draw() n'émettait pas d'avertissement lorsqu'une valeur invalide était transmise à l'argument justify , avant de la remplacer par la valeur par défaut. Désormais, il émettra un avertissement si une valeur non valide est transmise. Les valeurs justifiées valables sont "left", "right" ou "none". Voir #12089 pour plus de détails.

  • Fixe SparsePauliOp.apply_layout() et Pauli.apply_layout() pour soulever QiskitError si des indices en double ou des indices négatifs sont fournis dans le cadre d'une mise en page.

  • Correction d'un bug dans la passe ConsolidateBlocks lorsque le circuit d'entrée contient une porte opaque personnalisée et que les options basis_gates ou target ne sont pas activées, la passe soulevait un QiskitError et échouait. Cette erreur a été corrigée de sorte que, dans ces situations, la passe de transpondeur ne consolide pas le bloc identifié comme contenant une porte personnalisée au lieu d'échouer.

  • Correction d'un bogue dans PadDynamicalDecouplingqui n'affichait pas correctement le message d'erreur indiquant qu'un délai n'est pas aligné sur les impulsions, si le nœud précédent ou suivant était un nœud d'entrée/sortie. Le message d'erreur s'affiche maintenant correctement.

  • L'argument du mot-clé order de la fonction BitArray.from_bool_array() doit être "little" ou "big". Des contrôles ont été ajoutés pour déclencher une erreur si une valeur non valide est saisie.

  • Améliorer la décomposition de la porte générée par QuantumCircuit.mcx() sans utiliser de qubits ancillaires, de sorte que le nombre de CXGateaugmente quadratiquement en fonction du nombre de qubits, comme prévu, et non de manière exponentielle.

  • Corrigé SparsePauliOp.apply_layout() pour qu'il fonctionne correctement avec les opérateurs zéro-qubit. Par exemple, si vous avez créé un qubit 0 et que vous avez appliqué une disposition du type :

    op = SparsePauliOp("")
    op.apply_layout(None, 3)

    ce qui aurait auparavant provoqué une erreur. Cela renverra correctement un opérateur de la forme : SparsePauliOp(['III'], coeffs=[1.+0.j])

  • Correction d'un bug de StatevectorSampler qui ignorait les portes avec c_if. Une erreur se produira parce que Statevector ne peut pas gérer c_if.

  • Correction d'un oubli dans la passe de Commuting2qGateRouter où les permutations du registre quantique n'étaient pas ajoutées à l'ensemble des propriétés de la passe, de sorte qu'elles devaient être suivies manuellement par l'utilisateur. Il est désormais possible d'accéder à la permutation par le biais de la propriété layout du circuit de sortie et d'insérer la passe dans n'importe quel pipeline de transpilation sans perte d'informations.

  • Correction d'une imprécision en virgule flottante lors de la mise à l'échelle de certaines unités d'impulsion entre les secondes et les nanosecondes. Si l'impulsion était définie symboliquement, une erreur inutile en virgule flottante pourrait être introduite par la mise à l'échelle pour certaines constructions de symengine, ce qui pourrait se traduire par des résultats inattendus une fois que les symboles sont entièrement liés. Correction #12392.

  • Correction d'un bug dans synth_cnot_count_full_pmh() où le fait de fournir une adresse section_size qui ne divise pas le nombre de qubits sans reste pouvait conduire à des résultats erronés. Maintenant, n'importe quel section_size (au plus égal au nombre de qubits) synthétise le circuit correct. Pour une valeur (heuristiquement) optimale, fixer section_size=None.

  • PassManager.run() ne perdra plus de temps à se sérialiser lorsqu'il recevra plusieurs entrées s'il ne doit travailler qu'en série.

  • Correction d'un bug dans plot_coupling_map() qui provoquait une coloration incorrecte des bords de la carte de couplage. Correction #12354.

  • L'analyseur OpenQASM 2.0 (qasm2.load() et qasm2.loads()) peut maintenant évaluer les expressions gate-angle comprenant des opérandes entiers qui déborderaient de l'entier de taille système. Ceux-ci seront évalués dans un contexte de virgule flottante en double précision, comme le reste de l'expression l'a toujours été. Attention : un nombre entier arbitrairement grand ne sera pas nécessairement représentable exactement en virgule flottante double précision, de sorte qu'il est possible que, quelle que soit la manière dont le circuit a été généré, il ait déjà perdu toute précision numérique modulo 2π2\pi.

  • L'exportateur OpenQASM 3 (voir qiskit.qasm3) se trompera désormais correctement lorsqu'on lui demandera d'utiliser un mot-clé ou un autre identifiant non valide comme "porte de base", car il n'a aucun moyen de générer une sortie correcte dans ces cas-là.

  • L'exportateur OpenQASM 3 (qiskit.qasm3) exportera désormais correctement plusieurs instances de PauliEvolutionGate d'un circuit. Auparavant, une seule instance était exportée et toutes les autres instances utilisaient silencieusement la même version (incorrecte).

  • L'exportateur OpenQASM 3 (qiskit.qasm3) échappe désormais correctement les noms de portes. Auparavant, une porte dont le nom était un identifiant non valide OpenQASM 3 entraînait la génération de OpenQASM 3 non valides.

  • Une série d'incohérences dans le traitement des données d'entrée entre transpile() et generate_preset_pass_manager() ont été corrigées. Ces incohérences entraîneraient des résultats de transpilation différents pour les mêmes entrées, ou generate_preset_pass_manager() l'échec de certaines combinaisons d'entrées acceptées par transpile().

Cette page a-t-elle été utile ?
Signaler un bogue, une coquille ou proposer du contenu sur GitHub.