Qiskit SDK 1.1 notes de mise à jour
1.1.2
Prélude
Qiskit 1.1.2 est une version mineure de correction de bugs pour la série 1.1.
Corrections des erreurs
-
Correction d'un bug dans
BitArray.from_counts()etBitArray.from_samples(). Jusqu'à présent, ces fonctions soulevaient une erreur si les données fournies ne contenaient que des zéros et aucune valeur pour l'argument facultatifnum_bits. Aujourd'hui, ils produisent unBitArrayavec la valeurBitArray.num_bitsdont la valeur est fixée à 1. -
Correction d'un décorateur manquant dans
C3SXGatequi le faisait échouer siGate.to_matrix()était appelé. La matrice de la porte est maintenant retournée comme prévu. -
Ajout des portes de Clifford manquantes à la passe de
CollectCliffordstranspiler pass. En particulier, nous avons ajouté les portesECRGate,DCXGate,iSWAPGate,SXGateetSXdgGateà cette passe de transpileur. -
L'attribut
QuantumCircuit.parameterssera désormais correctement vide lors de l'utilisation deQuantumCircuit.copy_empty_like()sur un circuit paramétrique. Auparavant, un cache interne était copié sans être invalidé. Correction #12617. -
Correction de la passe de
SolovayKitaevlors du chargement des approximations de base à partir d'un fichier.npyexistant. Auparavant, le chargement d'une approximation stockée qui permettait des réductions supplémentaires (par exemple, en raison d'annulations de portes) pouvait entraîner un échec de l'exécution. En outre, la différence de phase globale du produit de porte U(2) et de la représentation SO(3) a été perdue au cours d'une procédure de sauvegarde et de rechargement. Corrections Qiskit/qiskit#12576. -
Correction d'un problème avec
dag_drawer()etDAGCircuit.draw()lors de la visualisation d'une instanceDAGCircuitcontenant desVarfils. Le visualiseur soulevait une exception en essayant de le faire, ce qui a été corrigé afin que la visualisation attendue soit générée. -
Le constructeur
GenericBackendV2permettait auparavant de construire des backends malformés parce qu'il acceptait des portes de base qui ne pouvaient pas être allouées compte tenu de la taille du backend. Par exemple, un backend avec un seul qubit pouvait auparavant accepter une base avec des portes à deux qubits. -
L'analyseur OpenQASM 2 (
qiskit.qasm2) peut maintenant gérer les conditionnelles avec des entiers qui ne tiennent pas dans un entier de 64 bits. Correction #12773. -
Précédemment,
DAGCircuit.replace_block_with_op()permettait de placer une opérationn-qubit sur un bloc demqubits, laissant le DAG dans un état invalide. Ce comportement a été corrigé, et toute tentative de faire cela lèvera désormais unDAGCircuitErrorcomme prévu.
1.1.1
Prélude
Qiskit 1.1.1 est une version mineure de correction de bugs pour la série 1.1.
Corrections des erreurs
-
Correction d'un bogue dans
Isometrydû à une assertion inutile, qui conduisait à une erreur dansUnitaryGate.control()lorsqueUnitaryGateavait plus de deux qubits. -
QuantumCircuit.depth()traitera désormais correctement les opérations qui n'ont pas d'opérandes, telles queGlobalPhaseGate. -
QuantumCircuit.depth()comptera désormais les variables et les clbits utilisés dans les expressions en temps réel dans le cadre du calcul de la profondeur. -
Correction d'un bogue dans
qiskit.visualization.pulse_v2.interface.draw()qui ne dessinait pas les horaires de pouls lorsque la fonction de dessin était appelée avec un argumentBackendV2en argument. Comme le backend V2 ne signale pas les fréquences des canaux matériels, le dessin généré indiquera "no freq" (pas de fréquence) sous l'étiquette de chaque canal. -
La passe
VF2Layoutlèverait une exception si on lui fournissait une instanceTargetsans contraintes de connectivité. Ce serait le cas pour les cibles d'Aer 0.13. Le problème est maintenant corrigé. -
ParameterExpressiona été mis à jour de manière à ce que les instances entièrement liées qui se comparent à des instances des types numériques intégrés de Python (commefloatetint) aient également des valeurs de hachage qui correspondent à celles des autres instances. Cette modification garantit que ces types peuvent être utilisés de manière interchangeable comme clés de dictionnaire. Voir #12488. -
Les portes personnalisées (celles qui découlent d'une déclaration
gate) dans les programmes importés de OpenQASM 2 auront désormais uneGate.to_matrix()mise en œuvre. Auparavant, ils n'avaient pas de définition matricielle, ce qui signifie que les allers-retours sur le site OpenQASM 2 pouvaient perdre inutilement la possibilité de dériver la matrice de la porte. Notez cependant que la matrice est calculée en trouvant récursivement les matrices des définitions des portes internes, comme le faitOperatorce qui peut être moins performant qu'avant l'aller-retour. -
Target.has_calibration()a été mis à jour afin qu'il ne soulève pas d'exception pour une instruction qui a été ajoutée à la cible avecNonepour ses propriétés d'instruction. Corrige #12525.
1.1.0
Prélude
La version de Qiskit 1.1.0 est une version mineure qui inclut une myriade de nouvelles fonctionnalités et de corrections de bugs. Les points forts de cette version sont les suivants :
La prise en charge des variables classiques typées a été ajoutée à l'interface de Qiskit
QuantumCircuit. Ces variables classiques peuvent être spécifiées en tant qu'entrées ou variables de portée dans un système d'informationQuantumCircuitoù elles stockent, par exemple, la sortie des mesures de qubits ou des opérations de flux de contrôle ciblées. La prise en charge, par exemple, de la définition des paramètres de la porte ou des variables de sortie sera ajoutée à l'avenir.Les méthodes de synthèse de deux qubits par défaut qui sont utilisées en interne par le transpileur dans la passe
UnitarySynthesisont été réimplémentées en Rust. Cela permet d'accélérer considérablement le temps d'exécution lors de la décomposition de matrices unitaires à deux qubits. Par conséquent, la durée d'exécution de la transpilation avec le niveau d'optimisation 3 a été considérablement améliorée lorsque l'exécutionUnitarySynthesisentraînait historiquement un surcoût d'exécution important. Cette version commence également à fonctionnerUnitarySynthesisdans le cadre de l'étape d'optimisation au niveau d'optimisation 2 en raison de ces améliorations des performances d'exécution.En outre, les méthodes numériques utilisées en
Isometryont été transférées à Rust, ce qui a permis d'accélérer considérablement le temps d'exécution, en particulier pour la synthèse de portes unitaires contrôlées. La décomposition pour le contrôle multipleXGateetPhaseGatea été améliorée, ce qui a permis de réduire le nombre de portes utilisées dans la synthèse de plus de deux ordres de grandeur.Un certain nombre de nouvelles passes de transpilation ont été introduites dans Qiskit et permettent d'accélérer considérablement l'exécution tout en réduisant la taille des circuits quantiques transposés dans de nombreux cas. En particulier,
ElidePermutationsetStarPreRoutingont démontré qu'elles avaient un impact significatif sur la qualité des résultats du routage et sur la durée d'exécutionRemoveFinalResetpeuvent améliorer les circuits quantiques qui incluent des réinitialisations.Les gestionnaires de passes par défaut ont été améliorés en les étendant aux passes de transpilation nouvellement introduites. En particulier, le gestionnaire de passes prédéfini de niveau d'optimisation 2 provenant de
generate_preset_pass_manageret utilisé en interne partranspile()a été remanié pour obtenir un meilleur compromis entre la durée d'exécution et l'effort d'optimisation afin de servir de gestionnaire de passe par défaut dans les prochaines versions. Bien que cette version ne modifie pas l'utilisation par défaut du niveau 2, il s'agit généralement d'un meilleur choix que l'utilisation du niveau 1 ou 3.De nouvelles implémentations de la primitive générique V2 ont été ajoutées,
BackendEstimatorV2etBackendSamplerV2pour compléter les implémentations existantes basées sur le vecteur d'état complet.Changements dans la prise en charge des plateformes : Python 3.8 est obsolète à partir de Qiskit 1.1.0 et ne sera plus pris en charge dans 1.3.0, et arm64 macOS a été promu à la prise en charge de niveau 1.
Caractéristiques des circuits
-
Les méthodes
QuantumCircuit.power(),Gate.power()ainsi que les méthodes similaires sur les sous-classes de sous-classes deGate(telles que deSGate) ont toutes un nouvel argument supplémentaireannotatedqui est utilisé pour renvoyer un objetAnnotatedOperationlors de l'application d'une puissance à une porte ou à un circuit. La valeur par défaut deFalsecorrespond au comportement existant. En outre, pour les portes standard dont la méthodepowerest explicitement définie, l'argumentannotatedn'a aucun effet. Par exemple,SGate().power(1.5, annotated=False)etSGate().power(1.5, annotated=True)renvoient tous deux unPhaseGate. Une différence dans la valeur deannotatedse manifeste pour les portes qui n'ont pas de méthode de puissance explicitement définie. La valeur deFalserenvoie unUnitaryGatecomme précédemment, tandis que la valeur deTruerenvoie unAnnotatedOperationqui représente l'instruction modifiée avec le "power modifier". -
Ajout d'un nouvel argument
ctrl_stateàQuantumCircuit.mcp()etMCPhaseGate.La méthode
QuantumCircuit.mcp()et la classeMCPhaseGateont été mises à jour pour inclure un paramètrectrl_state. Cette amélioration permet aux utilisateurs de spécifier l'état de contrôle de la porte de phase multicontrôlée. Le paramètre peut accepter une valeur entière ou une chaîne de bits et contrôle par défaut l'état "1" s'il n'est pas fourni.from qiskit import QuantumCircuit qc = QuantumCircuit(4) qc.mcp(0.2,[0,1,2],3,ctrl_state=2) -
Ajout d'un nouvel argument
ctrl_stateàQuantumCircuit.mcx().La méthode
QuantumCircuit.mcx()de la bibliothèque de circuits quantiques a été améliorée pour inclure un paramètre ctrl_state, permettant aux utilisateurs de spécifier l'état de contrôle de la porte X multicontrôlée. Ce paramètre peut accepter une valeur décimale ou une chaîne de bits et contrôle par défaut l'état "1" s'il n'est pas fourni.from qiskit import QuantumCircuit qc = QuantumCircuit(3, 3) qc.mcx([0, 1], 2, ctrl_state="00") -
A
QuantumCircuitpeut désormais contenir des variables classiques typées :from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister from qiskit.circuit.classical import expr, types qr = QuantumRegister(2, "q") cr = ClassicalRegister(2, "c") qc = QuantumCircuit(qr, cr) # Add two input variables to the circuit with different types. a = qc.add_input("a", types.Bool()) mask = qc.add_input("mask", types.Uint(2)) # Test whether the input variable was true at runtime. with qc.if_test(a) as else_: qc.x(0) with else_: qc.h(0) qc.cx(0, 1) qc.measure(qr, cr) # Add a typed variable manually, initialized to the same value as the classical register. b = qc.add_var("b", expr.lift(cr)) qc.reset([0, 1]) qc.h(0) qc.cx(0, 1) qc.measure(qr, cr) # Store some calculated value into the `b` variable. qc.store(b, expr.bit_and(b, cr)) # Test whether we had equality, up to a mask. with qc.if_test(expr.equal(expr.bit_and(b, mask), mask)): qc.x(0)Ces variables peuvent être spécifiées soit en tant qu' entrées dans le circuit, soit en tant que variables cadrées. L'objet circuit ne prend pas encore en charge la représentation des sorties de variables classiques typées, mais cela sera ajouté ultérieurement lorsque le matériel et les interfaces de résultats seront mieux en mesure de le prendre en charge. Les circuits qui représentent un bloc d'une portée intérieure peuvent également capturer des variables de portées extérieures.
Une variable est un
Varqui peut désormais contenir un type arbitraire et représente un emplacement de mémoire unique dans sa plage de vie lorsqu'il est ajouté à un circuit. Ceux-ci peuvent être construits dans un circuit utilisantQuantumCircuit.add_var()etQuantumCircuit.add_input()ou à un niveau inférieur en utilisantVar.new().Les variables peuvent être stockées manuellement dans, en utilisant l'instruction
Storeet la méthode de circuit correspondanteQuantumCircuit.store(). Il s'agit notamment d'écrire àClbitetClassicalRegisterenveloppées dans des nœudsVarnœuds.Les variables peuvent être utilisées partout où les expressions classiques (voir
qiskit.circuit.classical.expr) sont valables. Actuellement, il s'agit des expressions cibles des opérations de flux de contrôle, mais nous prévoyons de les étendre aux paramètres des portes à l'avenir, à mesure que le système de types et d'expressions sera développé.Voir Calcul classique en temps réel pour plus de détails sur ces variables et le modèle de données associé.
Ceux-ci sont pris en charge par l'ensemble du transpileur, par le biais de la sérialisation QPY (
qiskit.qpy), OpenQASM 3 export (qiskit.qasm3), et sont initialement supportés par les visualisateurs de circuits (voirQuantumCircuit.draw()).RemarqueIl faudra un certain temps pour que les nouvelles variables classiques et le stockage soient pris en charge par le matériel et les backends des simulateurs. Elles ne sont pas prises en charge par les interfaces de primitives (
qiskit.primitives), mais elles seront probablement intégrées à ces interfaces au fur et à mesure de leur évolution. -
Le module classique d'expressions en temps réel
qiskit.circuit.classicalpeut maintenant représenter l'indexation et le décalage de bits d'entiers non signés et de bits similaires (par ex.ClassicalRegister). Par exemple, il est désormais possible de comparer un registre avec le décalage de bits d'un autre registre :from qiskit.circuit import QuantumCircuit, ClassicalRegister from qiskit.circuit.classical import expr cr1 = ClassicalRegister(4, "cr1") cr2 = ClassicalRegister(4, "cr2") qc = QuantumCircuit(cr1, cr2) with qc.if_test(expr.equal(cr1, expr.shift_left(cr2, 2))): passQiskit peut également représenter une condition qui indexe dynamiquement un registre :
with qc.if_test(expr.index(cr1, cr2)): pass -
Les performances de construction de
NLocalet de ses sous-classes de bibliothèques de circuits dérivées (par ex.EfficientSU2etRealAmplitudes) s'est considérablement améliorée lorsque les sous-blocs de rotation et/ou d'enchevêtrement sont de simples applications d'une seule porte de la bibliothèque standard Qiskit. Étant donné que ces circuits sont construits paresseusement, il se peut que l'amélioration ne soit pas visible immédiatement lors de l'instanciation de la classe, mais plutôt lors du premier accès à sa structure interne. Les améliorations de performance sont de l'ordre de dix fois plus rapides. -
QuantumCircuit.append()dispose désormais d'un mot-clécopy, dont la valeur par défaut estTrue. Lorsqu'une instruction avec des paramètres d'exécution (ParameterExpression) est ajoutée à un circuit, par défaut, le circuit a toujours créé une copie de l'instruction, de sorte que si l'on tente de muter l'instruction en place, cela n'affecte pas les autres références à la même instructionQuantumCircuit.assign_parameters()tente de muter l'instruction en place, cela n'affecte pas les autres références à la même instruction. L'optioncopy=Falsevous permet d'outrepasser cette règle, de sorte que vous pouvez éviter la pénalité de copie si vous savez que vos instructions ne seront pas utilisées dans d'autres lieux. -
QuantumCircuit.compose()dispose désormais d'un mot-clécopy, dont la valeur par défaut estTrue. Par défaut,compose()copie toutes les instructions, de sorte que les mutations d'un circuit n'affectent pas les autres. Sicopy=False, les instructions de l'autre circuit seront directement détenues par le nouveau circuit, ce qui peut impliquer leur mutation sur place. Dans ce cas, l'autre circuit ne doit pas être utilisé par la suite. -
Le temps de construction des
QuantumVolumea été considérablement amélioré, de l'ordre de 10x ou un peu plus. Les portes internes de SU4 utiliseront désormais davantage de bits d'aléa lors de leur génération, ce qui permettra d'obtenir des circuits en volume plus représentatifs, en particulier pour les grandes largeurs et profondeurs. -
QuantumVolumedispose désormais d'un argument de mot-cléflatten. La valeur par défaut estFalse, où le circuit construit contient une seule instruction qui, à son tour, contient la structure réelle du volume. S'il est réglé surTrue, le circuit aura directement les matrices volumétriques SU4. -
UnitaryGateaccepte désormais un argument facultatifnum_qubits. Le seul effet est de sauter la déduction du nombre de qubits, ce qui peut être utile pour les performances lorsque de nombreuses portes sont construites. -
QuantumCircuitdispose de plusieurs nouvelles méthodes pour travailler et inspecter les variables manuellesVarmanuelles.Voir Travailler avec des données classiques typées en temps réel pour une discussion plus approfondie sur tous ces points.
Les nouvelles méthodes sont les suivantes
add_var()add_input()add_capture()add_uninitialized_var()get_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()store()
En outre, plusieurs nouveaux attributs dynamiques entourent ces variables
QuantumCircuitentourant ces variables : -
ControlFlowOpet ses sous-classes ont désormais une méthodeiter_captured_vars()qui renvoie un itérateur sur les variables uniques capturées dans n'importe lequel de ses blocs immédiats. -
DAGCircuitdispose de plusieurs nouvelles méthodes pour travailler et inspecter les variables manuellesVarmanuelles. Ils sont en grande partie équivalents à leursQuantumCircuitsauf que lesDAGCircuitsont optimisées pour un accès programmatique avec des objets déjà définis, tandis que les méthodesQuantumCircuitsont plus axées sur une utilisation humaine interactive.Les nouvelles méthodes sont les suivantes
add_input_var()add_captured_var()add_declared_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()
Il existe également de nouveaux attributs publics :
-
DAGCircuit.wirescontiendra désormais également toutes les variables manuelles du circuit, puisqu'il s'agit également d'un flux de données classiqueVarles variables manuelles du circuit, puisqu'il s'agit également d'un flux de données classique. -
Une nouvelle méthode,
Var.new()est ajoutée pour construire manuellement une variable classique en temps réel qui possède sa propre mémoire. -
QuantumCircuit.compose()a deux arguments de mots-clés nécessaires,var_remapetinline_captures, pour mieux prendre en charge les variables classiques en temps réel.var_remappeut être utilisé pour réécrire les nœudsVardans l'argument du circuit au fur et à mesure que ses instructions sont intégrées au circuit de base. Cela permet d'éviter les conflits de noms.inline_capturespeut être fixé àTrue(valeur par défaut :False) pour lier tous les nœudsVarnœuds suivis comme "captures" dans le circuit argument avec les mêmes nœuds dans le circuit de base, sans tenter de redéclarer les variablesVardans le circuit de base, sans essayer de redéclarer les variables. Ceci peut être utilisé, en combinaison avec la gestion deQuantumCircuit.copy_empty_like()vars_mode="captures", pour construire un circuit couche par couche, contenant des variables. -
DAGCircuit.compose()dispose d'un nouveau mot-clé,inline_captures, qui peut être défini àTruepour intégrer les nœuds "capturés" du circuit argument dans le circuit de base sans les redéclarerVarcapturés sur le circuit de l'argument sur le circuit de base sans les redéclarer. En conjonction avec l'optionvars_mode="captures"de plusieurs méthodesDAGCircuitcette option peut être utilisée pour combiner des DAGs qui opèrent sur les mêmes variables. -
QuantumCircuit.copy_empty_like()etDAGCircuit.copy_empty_like()ont un nouveau mot-clé,vars_mode, qui contrôle la façon dont les nœuds possédant de la mémoire sont suivis dans la sortieVarsont suivis dans la sortie. Par défaut ("alike"), les variables sont déclarées dans le même mode input/captured/local que la source. Cette valeur peut être fixée à"captures"pour convertir toutes les variables en captures (utile aveccompose()) ou"drop"pour les supprimer. -
Un nouvel argument
vars_modea été ajouté au mot-cléDAGCircuitméthodes :qui a la même signification que pour
copy_empty_like(). -
Toutes les "portes standard" de la bibliothèque de circuits (
qiskit.circuit.library) peuvent maintenant être spécifiées par un nom de chaîne de caractères pour les opérations d'enchevêtrement dans les circuitsTwoLocaltels queRealAmplitudesetEfficientSU2.
Fonctionnalités primitives
-
La mise en œuvre
BackendEstimatorV2deBaseEstimatorV2a été ajoutée. Cet estimateur prend en chargeBackendV1etBackendV2.import numpy as np from qiskit import transpile from qiskit.circuit.library import IQP from qiskit.primitives import BackendEstimatorV2 from qiskit.providers.fake_provider import Fake7QPulseV1 from qiskit.quantum_info import SparsePauliOp, random_hermitian backend = Fake7QPulseV1() estimator = BackendEstimatorV2(backend=backend) n_qubits = 5 mat = np.real(random_hermitian(n_qubits, seed=1234)) circuit = IQP(mat) observable = SparsePauliOp("Z" * n_qubits) isa_circuit = transpile(circuit, backend=backend, optimization_level=1) isa_observable = observable.apply_layout(isa_circuit.layout) job = estimator.run([(isa_circuit, isa_observable)], precision=0.01) result = job.result() print(f"> Expectation value: {result[0].data.evs}") print(f"> Standard error: {result[0].data.stds}") print(f"> Metadata: {result[0].metadata}") -
La mise en œuvre
BackendSamplerV2deBaseSamplerV2a été ajoutée. Cet échantillonneur prend en chargeBackendV1etBackendV2qui permettent à l'optionmemoryde calculer des chaînes de bits.import numpy as np from qiskit import transpile from qiskit.circuit.library import IQP from qiskit.primitives import BackendSamplerV2 from qiskit.providers.fake_provider import Fake7QPulseV1 from qiskit.quantum_info import random_hermitian backend = Fake7QPulseV1() sampler = BackendSamplerV2(backend=backend) n_qubits = 5 mat = np.real(random_hermitian(n_qubits, seed=1234)) circuit = IQP(mat) circuit.measure_all() isa_circuit = transpile(circuit, backend=backend, optimization_level=1) job = sampler.run([isa_circuit], shots=100) result = job.result() print(f"> bitstrings: {result[0].data.meas.get_bitstrings()}") print(f"> counts: {result[0].data.meas.get_counts()}") print(f"> Metadata: {result[0].metadata}") -
Ajout de méthodes pour joindre plusieurs objets
BitArrayobjets le long de différents axes.concatenate(): joint des tableaux le long d'un axe existant des tableaux.concatenate_bits(): joint des tableaux le long de l'axe des bits.concatenate_shots(): permet de joindre des tableaux le long de l'axe des plans.
ba = BitArray.from_samples(['00', '11']) print(ba) # BitArray(<shape=(), num_shots=2, num_bits=2>) # reshape the bit array because `concatenate` requires an axis. ba_ = ba.reshape(1, 2) print(ba_) # BitArray(<shape=(1,), num_shots=2, num_bits=2>) ba2 = BitArray.concatenate([ba_, ba_]) print(ba2.get_bitstrings()) # ['00', '11', '00', '11'] # `concatenate_bits` and `concatenates_shots` do not require any axis. ba3 = BitArray.concatenate_bits([ba, ba]) print(ba3.get_bitstrings()) # ['0000', '1111'] ba4 = BitArray.concatenate_shots([ba, ba]) print(ba4.get_bitstrings()) # ['00', '11', '00', '11'] -
Ajout de méthodes pour générer un sous-ensemble de l'objet
BitArrayen le découpant selon différents axes.__getitem__(): découpe le tableau le long d'un axe existant du tableau.slice_bits(): coupe le tableau le long de l'axe des bits.slice_shots(): coupe le tableau le long de l'axe de prise de vue.
ba = BitArray.from_samples(['0000', '0001', '0010', '0011'], 4) print(ba) # BitArray(<shape=(), num_shots=4, num_bits=4>) print(ba.get_bitstrings()) # ['0000', '0001', '0010', '0011'] ba2 = ba.reshape(2, 2) print(ba2) # BitArray(<shape=(2,), num_shots=2, num_bits=2>) print(ba2[0].get_bitstrings()) # ['0000', '0001'] print(ba2[1].get_bitstrings()) # ['0010', '0011'] ba3 = ba.slice_bits([0, 2]) print(ba3.get_bitstrings()) # ['00', '01', '00', '01'] ba4 = ba.slice_shots([0, 2]) print(ba3.get_bitstrings()) # ['0000', '0010'] -
Ajout d'une méthode
transpose()pour transposer unBitArray.ba = BitArray.from_samples(['00', '11']).reshape(2, 1, 1) print(ba) # BitArray(<shape=(2, 1), num_shots=1, num_bits=2>) print(ba.transpose()) # BitArray(<shape=(1, 2), num_shots=1, num_bits=2>) -
Ajout d'une méthode
expectation_values()pour calculer les valeurs d'espérance des opérateurs diagonaux.ba = BitArray.from_samples(['01', '11']) print(ba.expectation_values(["IZ", "ZI", "01"])) # [-1. 0. 0.5] -
DataBinsatisfait désormais auShapedprotocole. Cela signifie que chaqueDataBinpossède désormais les attributs supplémentaires suivantsshape(tupleint[,...])la forme initiale de chaque entrée de l'instancendim(int) : la longueur deshapesize(int) : le produit des entrées deshape
La forme peut être transmise au constructeur.
-
Ajout de fonctionnalités similaires à celles de la cartographie à
DataBinc'est-à-dire__getitem__,__contains__,__iter__,keys(),values(), etitems().from qiskit import QuantumCircuit from qiskit.primitives import StatevectorSampler circuit = QuantumCircuit(1) circuit.h(0) circuit.measure_all() sampler = StatevectorSampler() result = sampler.run([circuit]).result() databin = result[0].data for creg, arr in databin.items(): print(creg, arr) for creg in databin: print(creg, databin[creg]) -
La sous-classe
SamplerPubResultdePubResulta été ajoutée, que les implémentations deBaseSamplerV2peuvent renvoyer. La principale caractéristique ajoutée à cette nouvelle sous-classe est la suivantejoin_data()qui rassemble (un sous-ensemble) le contenu dedataen un seul objet. Cela permet d'obtenir les modèles suivants :job_result = sampler.run([pub1, pub2, pub3], shots=123).result() # assuming all returned data entries are BitArrays counts1 = job_result[0].join_data().get_counts() bistrings2 = job_result[1].join_data().get_bitstrings() array3 = job_result[2].join_data().array
Fonctionnalités des fournisseurs
- Le simulateur
BasicSimulatorle simulateur basé sur python inclus dansbasic_providerpermet maintenant d'exécuter toutes les portes standard jusqu'à 3 qubits définies dans le documentqiskit.circuit.library.
Fonctionnalités Pulse
-
Il est désormais possible d'attribuer des paramètres aux impulsions
ScheduleetScheduleBlocken spécifiant le nom du paramètre sous la forme d'une chaîne de caractères. Le nom du paramètre peut être utilisé pour attribuer des valeurs à tous les paramètres à l'intérieur de la zoneScheduleouScheduleBlockqui portent le même nom. De plus, le nom de paramètre d'unParameterVectorpeut être utilisé pour assigner toutes les valeurs du vecteur simultanément (la liste des valeurs doit donc correspondre à la longueur du vecteur). -
Les méthodes
assign_parametersdeScheduleetScheduleBlockprennent désormais en charge l'affectation simultanée d'unParameterVectorà une liste de valeurs de paramètres simultanément, en plus de l'affectation d'instances individuelles deParameterà des valeurs individuelles.
OpenQASM Caractéristiques
- L'exportateur OpenQASM 3 prend en charge les nœuds de stockage manuel sur les circuits
Varsur les circuits.
Caractéristiques du QPY
- LA VERSION 12 DU FORMAT QPY (
qiskit.qpy), la version 12 a été ajoutée, ce qui inclut la prise en charge des variables à mémoireVarpossédant de la mémoire. Voir la version 12 pour plus de détails sur les changements de format.
Caractéristiques de l'information quantique
-
Ajout d'une nouvelle méthode
apply_layout()qui est équivalente àapply_layout(). Cette méthode est utilisée pour appliquer uneTranspileLayoutdu transpileur à un observable qui a été construit pour un circuit d'entréePauliobservable qui a été construit pour un circuit d'entrée. Cela permet de travailler avecBaseEstimator/BaseEstimatorV2et la transpilation locale lorsque l'entrée est de typePauli. Par exemple :from qiskit.circuit.library import RealAmplitudes from qiskit.primitives import BackendEstimatorV2 from qiskit.providers.fake_provider import GenericBackendV2 from qiskit.quantum_info import Pauli from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager psi = RealAmplitudes(num_qubits=2, reps=2) H1 = Pauli("XI") backend = GenericBackendV2(num_qubits=7) estimator = BackendEstimatorV2(backend=backend) thetas = [0, 1, 1, 2, 3, 5] pm = generate_preset_pass_manager(optimization_level=3, backend=backend) transpiled_psi = pm.run(psi) permuted_op = H1.apply_layout(transpiled_psi.layout) res = estimator.run([(transpiled_psi, permuted_op, thetas)]).result()où un circuit d'entrée est transposé localement avant d'être transmis à
run(). La transpilation fait passer le circuit original de 2 à 7 qubits (la taille debackend) et permute sa disposition, qui est ensuite appliquée àH1à l'aide deapply_layout()pour refléter les transformations effectuées parpm.run(). -
Ajoute les
PauliList.noncommutation_graph()etSparsePauliOp.noncommutation_graph()en exposant la construction de graphes de non-commutation, en refondant le problème de regroupement des opérateurs de mesure en un problème de coloration de graphes. Cela permet aux utilisateurs de travailler directement avec ces graphes, par exemple pour explorer des algorithmes de coloration autres que celui utilisé parSparsePauliOp.group_commuting(). -
Les performances de
SparsePauliOp.to_matrix()a été grandement améliorée, tant pour les formes denses que pour les formes éparses. Par défaut, les deux prendront désormais avantage du parallélisme threadé disponible sur votre système, sous réserve de la variable d'environnementRAYON_NUM_THREADS. Vous pouvez temporairement forcer l'exécution en série en utilisant le nouvel argument booléenforce_serialde la commandeto_matrix().
Caractéristiques de la synthèse
-
Le
KMSSynthesisLinearFunctionpour synthétiser des objetsLinearFunctionaccepte désormais deux options supplémentaires :use_invertedetuse_transposed. Ces options modifient la matrice sur laquelle tourne l'algorithme de synthèse sous-jacent, éventuellement en l'inversant et/ou en la transposant, et ajustent ensuite de manière appropriée le circuit synthétisé. En faisant varier ces options, nous obtenons généralement des circuits synthétisés différents, et dans certains cas, nous pouvons obtenir de meilleurs résultats qu'avec leurs valeurs par défaut. -
Le
PMHSynthesisLinearFunctionpour synthétiser des objetsLinearFunctionaccepte désormais plusieurs options supplémentaires. L'optionsection_sizeest transmise à la méthode de synthèse sous-jacente. Les optionsuse_invertedetuse_transposedmodifient la matrice sur laquelle tourne l'algorithme de synthèse sous-jacent en l'inversant et/ou en la transposant éventuellement, puis ajustent de manière appropriée le circuit synthétisé. En faisant varier ces options, nous obtenons généralement des circuits synthétisés différents, et dans certains cas, nous pouvons obtenir de meilleurs résultats qu'avec leurs valeurs par défaut. -
Ajout d'un nouvel argument,
use_dag, à la méthodeTwoQubitBasisDecomposer.__call__()etXXDecomposer.__call__()méthodes. Cet argument est utilisé pour contrôler si unDAGCircuitest retourné lors de l'appel d'unTwoQubitBasisDecomposerouXXDecomposerau lieu de l'instance par défautQuantumCircuit. Par exemple :from qiskit.circuit.library import CXGate from qiskit.quantum_info import random_unitary from qiskit.synthesis import TwoQubitBasisDecomposer decomposer = TwoQubitBasisDecomposer(CXGate(), euler_basis="PSX") decomposer(random_unitary(4), use_dag=True)renverra un
DAGCircuitlors de l'appel de l'instanceTwoQubitBasisDecomposerinstancedecomposer. -
LieTrotter.synthesize()utilise désormaisQuantumCircuit.repeat()pour générer des répétitions supplémentaires d'un pas de Trotter après le premier pas de Trotter. Cela permet de réduire le nombre d'appelsQuantumCircuit.compose()par un facteur derepset réduit considérablement la durée d'exécution pour les opérateurs les plus importants. -
Ajouter une nouvelle méthode de synthèse
synth_permutation_reverse_lnn_kms()de permutations inversées pour les architectures linéaires à plus proche voisin en utilisant la méthode Kutin, Moulton, Smithline. Cet algorithme synthétise la permutation inverse sur qubits sur une architecture linéaire à plus proche voisin utilisant des portes CX de profondeur . -
La classe
TwoQubitBasisDecomposera été réécrite en rouille, ce qui améliore considérablement les performances d'exécution. -
La classe
TwoQubitWeylDecompositiona été réécrite en Rust pour de meilleures performances.
Fonctionnalités du transpilateur
-
Extension de l'analyse de commutation effectuée par
CommutationCheckerpour qu'elle fonctionne également avec des circuits abstraits, c'est-à-dire que chaque opération dans le circuit quantique d'entrée est maintenant vérifiée pour sa représentation matricielle avant de procéder à l'étape d'analyse. Auparavant, l'analyse de commutation n'était effectuée que sur des circuits physiques. En outre, il est désormais vérifié que chaque opération peut être mise en cache dans la bibliothèque de commutation de la session. Par exemple, cela permet maintenant de calculer siAnnotatedOperationcommute. Cela permet aux passes de transpilation qui s'appuient surCommutationCheckeren interne, telles queCommutativeCancellationde s'exécuter au cours des premières étapes d'un pipeline de transpilation par défaut (avant la traduction de la base). -
La passe de transpilation
ElidePermutationss'exécute par défaut dans l'étape init pour les niveaux d'optimisation 2 et 3. Intuitivement, en supprimantSwapGateetPermutationGatedans un circuit virtuel est presque toujours bénéfique, car elle rend le circuit plus court et plus facile à acheminer. CommeOptimizeSwapBeforeMeasureest un cas particulier deElidePermutationsil a été remplacé par la passeElidePermuationsdans le cadre de l'étape init des gestionnaires de passes d'optimisation de niveau 3. -
Ajout d'une nouvelle passe de transposition d'optimisation,
ElidePermutationsqui est conçue pour être exécutée avant l' étape de mise en page et qui optimisera tous lesSwapGateetPermutationGatedans un circuit en permutant les qubits virtuels. Par exemple, en prenant un circuit avecSwapGates :
supprimera les échanges lors de l'exécution de la passe :
from qiskit.transpiler.passes import ElidePermutations from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(3) qc.h(0) qc.swap(0, 1) qc.swap(2, 0) qc.cx(1, 0) qc.measure_all() ElidePermutations()(qc).draw("mpl")
La passe définit également l'ensemble de propriétés
virtual_permutation_layout, qui stocke la permutation des qubits virtuels à la fin du circuit qui a été optimisé. -
L'option
HLSConfigdispose désormais de deux arguments facultatifs supplémentaires. L'argumentplugin_selectionpeut être défini comme"sequential"ou"all". Si la valeur est "séquentielle" (par défaut), pour chaque objet de niveau supérieur, la passeHighLevelSynthesisconsidérera les méthodes spécifiées séquentiellement, dans l'ordre où elles apparaissent dans la liste, en s'arrêtant à la première méthode capable de synthétiser l'objet. Si elle est réglée sur "toutes", toutes les méthodes spécifiées seront prises en compte et le meilleur circuit synthétisé, selonplugin_evaluation_fn, sera choisi. L'argumentplugin_evaluation_fnest un appel facultatif qui évalue la qualité du circuit quantique synthétisé; une valeur plus petite signifie un meilleur circuit. Lorsqu'il est fixé àNone, la qualité du circuit est sa taille (c'est-à-dire le nombre de portes qu'il contient).L'exemple suivant illustre la nouvelle fonctionnalité :
from qiskit import QuantumCircuit from qiskit.circuit.library import LinearFunction from qiskit.synthesis.linear import random_invertible_binary_matrix from qiskit.transpiler.passes import HighLevelSynthesis, HLSConfig # Create a circuit with a linear function mat = random_invertible_binary_matrix(7, seed=37) qc = QuantumCircuit(7) qc.append(LinearFunction(mat), [0, 1, 2, 3, 4, 5, 6]) # Run different methods with different parameters, # choosing the best result in terms of depth. hls_config = HLSConfig( linear_function=[ ("pmh", {}), ("pmh", {"use_inverted": True}), ("pmh", {"use_transposed": True}), ("pmh", {"use_inverted": True, "use_transposed": True}), ("pmh", {"section_size": 1}), ("pmh", {"section_size": 3}), ("kms", {}), ("kms", {"use_inverted": True}), ], plugin_selection="all", plugin_evaluation_fn=lambda circuit: circuit.depth(), ) # synthesize qct = HighLevelSynthesis(hls_config=hls_config)(qc)Dans l'exemple, nous utilisons plusieurs méthodes de synthèse avec différents paramètres, en choisissant le meilleur circuit en termes de profondeur. Notez qu'en optimisant
circuit.size(), vous choisirez un circuit différent. -
Ajout du
CommutativeCancellationà l'étapeinitdes gestionnaires de passe prédéfinis pour les niveaux d'optimisation 2 et 3. Cela permet aux gestionnaires de passes prédéfinies d'annuler des opérations logiques supplémentaires au début du pipeline de compilation. -
Les passes d'analyse suivantes acceptent désormais les contraintes encodées dans une balise
Targetgrâce à un nouvel argument d'entréetarget:Les contraintes cibles auront la priorité sur les contraintes fournies par l'utilisateur, par souci de cohérence avec le reste du pipeline du transpilateur.
-
Ajout d'une nouvelle méthode
Layout.inverse()qui est utilisée pour prendre l'inverse d'unLayoutobjet. Ajout d'une nouvelle méthodeLayout.compose()utilisée pour composer deux objetsLayoutensemble. Ajout d'une nouvelle méthodeLayout.to_permutation()qui permet de créer une permutation correspondant à un objetLayoutobjet. -
Ajout d'une nouvelle réduction à la passe de
OptimizeAnnotatedtranspiler. Cette réduction recherche des opérations annotées (objets de typeAnnotatedOperationconstitués d'une opération de base et d'une liste de modificateurs de contrôle, d'inverse et de puissance) ayant les propriétés suivantes :- l'opération de base doit être synthétisée (c'est-à-dire qu'elle n'est pas déjà supportée par la cible ou qu'elle appartient à la bibliothèque d'équivalence)
- le circuit de définition de peut être exprimé comme suit : - - avec
Dans ce cas, les modificateurs peuvent être déplacés vers la partie uniquement. À titre d'exemple, les additionneurs contrôlés basés sur la QFT ont la forme
control - [QFT -- U -- IQFT], qui peut être simplifiée enQFT -- control-[U] -- IQFT. En supprimant les contrôles sur les partiesQFTetIQFTdu circuit, on obtient beaucoup moins de portes dans le circuit transposé. -
Ajout de deux nouvelles méthodes à la
DAGCircuitdeux nouvelles méthodes :qiskit.dagcircuit.DAGCircuit.op_successors()retourne un itérateur vers lesDAGOpNodesuccesseurs d'un noeud, etqiskit.dagcircuit.DAGCircuit.op_successors()renvoie un itérateur vers lesDAGOpNodeprédécesseurs d'un noeud. -
Ajout d'une nouvelle passe de transpilation,
RemoveFinalResetqui supprimera toute opérationResetqui est la dernière instruction sur un fil de qubit. Par exemple, en prenant un circuit avec finalResets :
supprimera les réinitialisations finales lors de l'exécution de la passe :
from qiskit.transpiler.passes import RemoveFinalReset from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(3, 1) qc.reset(0) qc.h(range(3)) qc.cx(1, 0) qc.measure(0, 0) qc.reset(range(3)) RemoveFinalReset()(qc).draw("mpl")
-
Ajout d'une nouvelle passe de transpilation
StarPreRoutingqui est conçue pour identifier les sous-circuits de connectivité en étoile et les remplacer par un routage linéaire optimal. Ceci est utile pour certains circuits qui sont composés de cette connectivité de circuit comme Bernstein-Vazirani et QFT. Par exemple :
from qiskit.circuit import QuantumCircuit from qiskit.transpiler.passes import StarPreRouting qc = QuantumCircuit(5) qc.h(0) qc.cx(0, range(1, 5)) StarPreRouting()(qc).draw("mpl")
Il est également possible d'étendre un gestionnaire de laissez-passer préréglé existant :
from qiskit import QuantumCircuit from qiskit.transpiler import CouplingMap from qiskit.transpiler.passes import StarPreRouting from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager cm = CouplingMap.from_line(5) qc = QuantumCircuit(5) qc.h(0) qc.cx(0, range(1, 5)) pm = generate_preset_pass_manager(2, coupling_map=cm) pm.init += StarPreRouting() result = pm.run(qc) result.draw("mpl")
Fonctionnalités de visualisation
- Les tiroirs de texte et de Matplotlib tiroirs de circuits (
QuantumCircuit.draw()) offrent un support minimal pour l'affichage d'expressions impliquant des variables manuelles en temps réel. L'opérationStoreet les initialisations de variables ne sont pas encore prises en charge; pour les circuits dynamiques à grande échelle, nous recommandons d'utiliser les capacités d'exportation de OpenQASM 3 (qasm3.dumps()) pour obtenir une représentation textuelle d'un circuit.
Divers. Fonctions
- Cette version de Qiskit finalise la prise en charge de NumPy 2.0. Qiskit continuera à soutenir les sites NumPy 1.x et 2.x dans un avenir proche.
Mise à niveau
-
Supprime le codage en dur des options de style pour les fichiers
plot_histogram(). Cela permet d'appliquer fidèlement les fichiers de style Matplotlib aux figures. Les utilisateurs qui souhaitent aller au-delà des valeurs par défaut définies par Matplotlib peuvent créer leurs propres fichiers de style ou transmettre un objet MatplotlibAxesàplot_histogramet appliquer a posteriori toute personnalisation. -
La fonction
transpile()a été mise à jour pour convertir en interne les entrées backend de typeBackendV1enBackendV2ce qui permet au pipeline de transpilation d'accéder aux contraintes de l'arrière-plan par le biais d'un élément de typeTarget. Cette modification ne nécessite aucune action de la part de l'utilisateur.
Notes sur la mise à niveau des circuits
-
L'utilisation des nombres aléatoires de
QuantumVolumea changé, vous obtiendrez donc un circuit différent pour une graine fixe entre les anciennes versions de Qiskit et cette version. La génération aléatoire-unitaire utilise maintenant plus de bits d'entropie, de sorte que les grands circuits seront moins biaisés. -
Les instances
UnitaryGatedans la définition d'unQuantumVolumen'auront plus de champlabelne sera plus défini. Auparavant, il s'agissait de la chaînesu4_<seed>, où<seed>était un nombre à trois chiffres indiquant la graine d'une instance interne de Numpy pRNG pour cette porte. Cela posait un sérieux problème de performance, et la graine n'aurait pas dû être utile; si vous avez besoin de récupérer la matrice à partir de la porte, utilisez simplement la méthodeGate.to_matrix()méthode.
Notes de mise à niveau des primitives
- La fonction
make_data_bin()ne crée plus et ne renvoie plus deDataBinsous-classe. En revanche, il renvoie toujours laDataBinclasse. Cependant, il continue d'exister pour des raisons de rétrocompatibilité, mais il sera à terme obsolète. Tous les utilisateurs devraient migrer pour construire directement des instancesDataBindirectement, au lieu d'instancier des sous-classes comme le faitmake_data_bin().
Notes de mise à niveau des fournisseurs
-
La mise en œuvre de
BackendV2(etBackendV1) peuvent souhaiter mettre à jour leurs méthodesrun()pour rejeter avec empressement les entrées contenant des variables classiques typées (voirqiskit.circuit.classical) et l'instructionStoresi elles ne les prennent pas en charge. La nouvelle instructionStoreest traitée par le transpileur comme une "directive" toujours disponible (commeBarrier); si vos backends ne la supportent pas, elle ne sera pas prise en compte par la directivetranspiler.Voir Variables en temps réel pour plus d'informations.
Notes de mise à niveau QPY
- La valeur de
qiskit.qpy.QPY_VERSIONest maintenant de 12.QPY_COMPATIBILITY_VERSIONreste inchangée à 10.
Notes de mise à niveau de Synthesis
- Les
TwoQubitWeylDecompositionne s'auto-spécialise plus dans une sous-classe à la création. Il s'agit d'un détail interne de la classeTwoQubitWeylDecompositionet n'était pas un comportement public documenté car toutes les sous-classes se comportaient de la même manière et n'étaient utilisées que pour l'envoi interne. Cependant, comme ce comportement a été découvert, cette note de mise à jour a pour but de documenter le fait que cela ne se produira plus et que toutes les instances deTwoQubitWeylDecompositionseront du même type. Il n'y a pas de changement de comportement pour les méthodes publiques de la classe.
Notes de mise à niveau du transpilateur
- Le préréglage
StagedPassManagerretourné pour le niveau d'optimisation 2 pargenerate_preset_pass_manager()etlevel_2_pass_manager()ont été retravaillés pour offrir un meilleur équilibre entre la durée d'exécution et l'optimisation. Cela signifie que les circuits de sortie seront modifiés par rapport aux versions précédentes. Si vous avez besoin d'un gestionnaire de passes exact du niveau 2 dans des versions antérieures, vous pouvez soit le construire manuellement, soit l'utiliser à partir d'une version antérieure et sauvegarder les circuits à l'aide de la commandeqpypour le charger dans une version plus récente.
Divers. Mise à niveau
- La version minimale de Windows prise en charge est désormais Windows 10. Dans les versions précédentes, nous ne mentionnions pas explicitement une version minimale de Windows et, implicitement, Windows 7, 8 et 8.1 auraient pu fonctionner (mais n'ont jamais été testés). Mais en raison de l'abandon par Rust 1.78 de la prise en charge des anciennes versions de Windows, les binaires publiés par Qiskit sur PyPI ne prendront plus en charge les anciennes versions de Windows à partir de cette version. Si vous utilisez une ancienne version de Windows, vous pouvez probablement encore compiler Qiskit à partir des sources en utilisant un compilateur Rust plus ancien (la version Rust minimale supportée par Qiskit pour la compilation à partir des sources est actuellement 1.70 ), mais les anciennes versions de Windows ne sont pas une plateforme supportée et ne sont pas testées.
Remarques concernant la dépréciation
-
La prise en charge de l'exécution de Qiskit avec Python 3.8 est obsolète et sera supprimée dans la version de Qiskit 1.3.0. Le site 1.3.0 est la première version après que le site Python 3.8 a atteint sa fin de vie et n'est plus pris en charge. [1] Cela signifie qu'à partir de la version 1.3.0, vous devrez mettre à jour la version Python que vous utilisez vers Python 3.9 ou une version supérieure.
Avertissements aux fournisseurs
-
Les classes de base abstraites
ProvideretProviderV1sont désormais obsolètes et seront supprimées dans Qiskit 2.0.0. L'abstraction offerte par ces définitions d'interface n'apportait pas de valeur substantielle; elle encapsulait uniquement les attributsname,backends, et aget_backend(). Un fournisseur, en tant que concept, continuera d'exister en tant que collection de backends. Si vous implémentez actuellement un fournisseur, vous pouvez adapter votre code en supprimant simplementProviderV1en tant que classe parente de votre implémentation. Dans ce cadre, vous voudrez probablement ajouter une implémentation deget_backendpour assurer la compatibilité ascendante. Par exemple :def get_backend(self, name=None, **kwargs): backends = self.backends(name, **kwargs) if len(backends) > 1: raise QiskitBackendNotFoundError("More than one backend matches the criteria") if not backends: raise QiskitBackendNotFoundError("No backend matches the criteria") return backends[0]
Dépréciations de synthèse
- La méthode
TwoQubitWeylDecomposition.specialize()est désormais obsolète et sera supprimée dans la version de Qiskit 2.0.0. Cette méthode n'a jamais eu d'utilité publique et n'était pas sûre pour un utilisateur final, car elle aurait modifié la décomposition calculée dans l'objet et produit des champs non valides dans l'objet. Il n'a été utilisé qu'en interne pour construire un nouvel objetTwoQubitWeylDecompositionobjet. Malgré cela, il s'agissait toujours d'une partie documentée de l'API publique de la classe et il est maintenant déprécié sans aucun remplacement potentiel. Cette version lèvera toujoursNotImplementedErrorlorsqu'elle sera appelée car le sous-classement de la spécialisation a été supprimé dans le cadre de la réécriture Rust de la classe.
Dépréciations du transcompilateur
-
Le pass
qiskit.transpiler.passes.CXCancellationa été déprécié en faveur deInverseCancellationqui est plus générique.CXCancellationest pleinement équivalent sémantiquement àInverseCancellation([CXGate()]). -
La passe de transpilation
qiskit.transpiler.passes.ALAPScheduleest désormais obsolète. Il était en attente de dépréciation depuis Qiskit 0.37 (avec Terra 0.21 ), publié en juin 2022. La passe est remplacée parALAPScheduleAnalysisqui est une passe d'analyse. -
La passe de transpilation
qiskit.transpiler.passes.ASAPScheduleest désormais obsolète. Il était en attente de dépréciation depuis Qiskit 0.37 (avec Terra 0.21 ), publié en juin 2022. Il a été remplacé parASAPScheduleAnalysiset le nouveau flux de travail de programmation. -
La passe de transpilation
qiskit.transpiler.passes.DynamicalDecouplingest désormais obsolète. Il était en attente de dépréciation depuis Qiskit 0.37 (avec Terra 0.21 ), publié en juin 2022. Au lieu de cela, utilisezPadDynamicalDecouplingqui remplit la même fonction, mais nécessite l'exécution préalable de passes d'analyse de l'ordonnancement et de l'alignement. -
La passe de transpilation
qiskit.transpiler.passes.AlignMeasuresest désormais obsolète. Il était en attente de dépréciation depuis Qiskit 0.37 (avec Terra 0.21 ), publié en juin 2022. Au lieu de cela, utilisezConstrainedReschedulequi remplit la même fonction et permet également de s'aligner sur des contraintes de temps supplémentaires.
Dépréciations de la visualisation
- Les paramètres
show_idleetshow_barrierdes tiroirs chronologiques ont été remplacés paridle_wiresetplot_barriersrespectivement pour correspondre aux paramètres des tiroirs de circuits. Leurs noms précédents sont désormais obsolètes et seront supprimés dans la prochaine version majeure. Les nouveaux paramètres sont parfaitement équivalents.
Corrections des erreurs
-
Correction d'un problème avec la fonction
qpy.dump()où, lorsque l'indicateuruse_symengineétait défini sur un objet véridique évalué àTruemais qui n'était pas en fait le booléenTrue, la charge utile QPY générée était corrompue. Par exemple, si vous attribuez àuse_symenginela valeurHAS_SYMENGINEcet objet est évalué àTruelorsqu'il est converti en bool, mais n'est pas réellementTrue. -
Correction d'un problème avec la fonction
circuit_drawer()fonction etQuantumCircuit.draw()lors du chargement d'un style matplotlib via le fichier de configuration utilisateur. -
Correction d'un problème où la passe de
ConstrainedRescheduletranspiler pass provoquait auparavant une erreur si le circuit contenait uneResetinstruction. Cela a été corrigé de sorte que la passe ne provoque plus d'erreurs, mais le matériel réel peut se comporter différemment de ce que suppose l'ordonnanceur Qiskit, en particulier pour les mesures en milieu de circuit et les réinitialisations. Le planificateur Qiskit lèveRuntimeWarnings'il rencontre un circuit contenant l'un ou l'autre de ces éléments. Corrigé #10354 -
Correction d'un problème avec la classe
CommutationCheckerqui provoquait une erreur si l'attributnamed'une porte était encodé en UTF8. Auparavant, seuls les noms de porte codés en ascii fonctionnaient. Corrigé #12501 -
Correction d'un problème avec les
SparsePauliOp.apply_layout()etPauli.apply_layout()lorsqu'un tableau invalide avec des indices dupliqués ou négatifs était transmis pour l'argumentlayout. Auparavant, cela n'entraînait pas d'erreur et la transformation effectuée n'était pas valide. Ces méthodes lèveront désormais unQiskitErrorsi des indices en double ou des indices négatifs sont fournis dans le cadre d'une mise en page. -
Correction d'un problème de performance dans les
BackendSamplerV2etBackendEstimatorV2. Corrigé #12290 -
Correction d'un problème avec l'attribut
convert_to_target()où le convertisseur ignorait à tort les instructions de flux de contrôle si elles étaient spécifiées dans l'attributBackendConfiguration.supported_instructions, qui est l'emplacement typique où les instructions de flux de contrôle sont spécifiées dans un objetBackendConfigurationobjet. Correction #11872. -
Correction d'un problème avec la fonction
circuit_drawer()ouQuantumCircuit.draw()lors de l'utilisation de l'option de sortiempl. Le programme se bloquait si le circuit dessiné contenait une opération ControlFlow et que l'optionfoldétait réglée sur -1 (ce qui signifie pas de pli). Correction #12012. -
Correction d'un bogue dans la conversion des instructions d'impulsion personnalisées au format legacy
qiskit.qobjancien. Le bogue a été introduit dans Qiskit 1.0.0 et provoquait une erreur lors de la conversion d'instructions avec des formes d'impulsion personnalisées. Après la correction, la conversion s'effectue correctement et l'impulsion personnalisée est convertie enWaveformcomme il se doit. Correction #11828. -
Un bogue dans
transpile()a été corrigé : les contraintes personnaliséesinstruction_durations,dtetbackend_propertiesétaient ignorées lorsqu'elles étaient fournies en même temps qu'un backend de typeBackendV2. Le comportement après la correction est maintenant indépendant du fait que le backend fourni soit de typeBackendV1ou de typeBackendV2. De même, les entrées personnaliséestiming_constraintssont désormais remplacées par les entréestarget, mais ont la priorité sur les entréesBackendV1etBackendV2les entrées. -
L'appel à
EquivalenceLibrary.set_entry()mettra désormais correctement à jour l'objet graphique interne de la bibliothèque. Auparavant, les métadonnées étaient mises à jour, mais la structure du graphe restait inchangée, ce qui signifiait que des utilisateurs tels queBasisTranslatorcontinueraient à utiliser les anciennes règles. Correction #11958. -
La fonction
EvolvedOperatorAnsatzgère désormais correctement le cas où l'argument des opérateurs est une liste vide. Auparavant, cela entraînait une erreur. -
A partir de maintenant,
EvolvedOperatorAnsatzn'aura pas de qregs quand il y a zéro qubit, au lieu d'avoir une instance avec zéro qubitQuantumRegisteravec zéro qubit. Ce comportement est plus cohérent avec celui de la superclasseQuantumCircuit. -
La méthode
Instruction.repeat()déplace maintenant un ensembleconditionvers l'extérieur retournéInstructionet laisse les portes intérieures de sa définition inconditionnelles. Auparavant, la méthode laissait les instancesClassicalRegisterdans la définition interne, ce qui était un état invalide et se manifestait par des bogues apparemment sans rapport par la suite, par exemple lors de la transpilation ou de l'exportation. Correction #11935. -
Correction d'un problème dans la passe
InverseCancellationqui, dans certains cas, annulait incorrectement une porte paramétrée auto-inverse même si la valeur du paramètre ne correspondait pas. Corrigé #11815 -
Améliorer la décomposition des portes
MCXGateetMCPhaseGatesans utiliser de qubits ancillaires, de sorte que le nombre deCXGatecroîtra quadratiquement en fonction du nombre de qubits et non pas exponentiellement. -
Un bogue qui faisait planter la fonction
convert_to_target()lorsque les propriétés du qubit (soit T1, T2 ou la fréquence) sont manquantes a été corrigé. Les valeurs de propriété manquantes dansQubitPropertiessont remplies parNone. -
BasePassManager.run()ne laissera plus échapper l'ancienPropertySetdans les nouveaux flux de travail lorsqu'elle est appelée plusieurs fois. Auparavant, les mêmesPropertySetque précédemment était utilisée pour initialiser les exécutions suivantes, ce qui pouvait signifier que des informations non valides sur les propriétés étaient communiquées aux tâches. Le comportement correspond désormais à celui de Qiskit 0.44. Correction #11784. -
Pauli.evolve()gère désormais correctement les circuits quantiques contenant des portes ECR. Auparavant, ils n'étaient pas reconnus comme des portes Clifford, et une erreur a été soulevée. -
Correction d'un bug dans
Pauli.evolve()où l'évolution par un circuit dont le nom correspondait à certaines portes de Clifford ('cx', 'cz', etc) faisait évoluer le Pauli en fonction du nom du circuit, et non en fonction du contenu du circuit. Ce bogue ne s'est produit qu'avec l'option par défautframe='s'. -
Correction d'un problème de performance dans la fonction
qpy.load()lors de la désérialisation de charges utiles QPY avec un grand nombre de qubits ou de clbits dans un circuit. -
Correction d'un bug dans la gestion de l'argument
default_alignmentde la commandebuild(). Les entrées de typeAlignmentKindsont désormais correctement traitées comme des alignements par défaut. -
Correction d'un bogue dans la fonction
qiskit.pulse.utils.format_parameter_value()qui convertissait involontairement des nombres entiers suffisamment grands en valeurs flottantes ou provoquait des arrondis inattendus. Voir #11971 pour plus de détails. -
Correction d'un problème dans la classe
QDriftoù les coefficients de l'hamiltonien étaient auparavant forcés d'être positifs en prenant la valeur absolue de chaque coefficient. Cette erreur a été corrigée de manière à ce que les signes des coefficients négatifs soient rajoutés. -
Un bogue a été corrigé dans
convert_durations_to_dt()où la fonction appliquait aveuglément une conversion de secondes àdtsur les durées de circuit, indépendamment des unités originales de l'attribut. Cela pourrait conduire à des ordres de grandeur erronés dans les durées de circuit rapportées. -
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 oubli dans la passe
Commuting2qGateRouteroù les permutations qreg 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élayoutdu 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. -
Les gestionnaires de passage prédéfinis de
transpile()n'échoueront plus sur les circuits avec flux de contrôle, si aucune cible matérielle ou aucun ensemble de portes de base n'est spécifié. Ils traiteront désormais ces cibles abstraites comme autorisant toutes les opérations de flux de contrôle. Correction #11906. -
La méthode
qiskit.instruction.Instruction.soft_compare()a pour but de comparer si deux portes correspondent dans leur nom, leur nombre de qubits, leur nombre de clbits et leur nombre de paramètres. Cependant, il y avait une faute de frappe qui empêchait de vérifier le nombre de qubits et le nombre de clbits pour une correspondance. Cela résout l'apparente coquille. -
Le plugin par défaut
initne soulevait pas correctement une erreur de typeTranspilerErrorlorsqu'il était appelé avec un niveau d'optimisation invalide. -
Correction d'un problème avec la méthode
Operator.from_circuit()qui interprétait de manière incorrecte la permutation finale de la disposition, ce qui entraînait la construction d'un fichierOperatorinvalide. Auparavant, la disposition finale était traitée sans tenir compte de la disposition initiale, c'est-à-dire que l'initialisation était incorrecte pour tous les circuits quantiques dont la disposition initiale n'était pas triviale. -
Correction d'un problème de performance dans
PassManager.run()lorsqu'il fonctionne sur plusieurs circuits en parallèle. Il ne passera plus de temps à sérialiser lePassManager(ce qui est une condition de l'exécution parallèle) lorsqu'il reçoit des entrées multiples s'il ne va traiter les entrées que de manière sérielle. -
Parametera été mis à jour de manière à ce que les instances qui se comparent entre elles aient toujours le même hachage. Auparavant, seul leParameter.uuidétait comparée, de sorte que les instancesParameteravec des noms différents pouvaient être comparées entre elles si elles avaient été construites en utilisant une valeur commune pour le paramètreuuid(qui n'est généralement pas transmis explicitement). -
Correction d'un bug dans
plot_coupling_map()qui provoquait une coloration incorrecte des bords de la carte de couplage. Correction #12369. -
L'analyseur OpenQASM 2.0 (
qasm2.load()etqasm2.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é. Toutefois, un nombre entier arbitrairement grand ne sera pas nécessairement représentable avec exactitude 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 . -
Parameterles instances utilisées comme substituts des variablesinputdans les programmes OpenQASM 3 verront désormais leur nom échappé afin d'éviter les collisions avec les portes intégrées lors de l'exportation vers OpenQASM 3. Auparavant, il pouvait y avoir un conflit d'appellation et l'exportateur générait une version invalide de OpenQASM 3. -
Correction d'un bogue dans
QuantumCircuit.draw()qui entraînait la modification des dictionnaires de styles personnalisés pour le tiroir Matplotlib lors de l'exécution. -
QuantumCircuit.append()aveccopy=True(sa valeur par défaut) copiera désormais correctement les instructions paramétrées par desParameterExpressionet non plus seulement par des instancesParameterinstances. -
Le traitement interne des étalonnages de circuits personnalisés et des
InstructionDurationsa été déchargé de la fonctiontranspile()aux différentes passes du transpondeur :DynamicalDecoupling,DynamicalDecoupling. Auparavant, les durées d'instruction des calibrages de circuits n'étaient pas prises en compte à moins qu'elles ne soient incorporées manuellement dans l'argument d'entrée instruction_durations, mais les passes qui en ont besoin analysent désormais le circuit et choisissent la valeur de durée la plus pertinente selon l'ordre de priorité suivant : cible > entrée personnalisée > calibrages de circuits. -
Correction d'un bogue dans
transpile()où l'argumentnum_processesn'était utilisé que sidtouinstruction_durationsétait fourni.
Autres remarques
-
Le support de la plateforme arm64 macOS a été promu de Tier 3 à Tier 1. Auparavant, la plateforme était au niveau 3 parce qu'il n'y avait pas d'environnement CI disponible pour tester Qiskit sur la plateforme. Maintenant que Github a mis un environnement arm64 macOS à la disposition des projets open source [1], nous testons la plateforme avec les autres plateformes supportées par le Tier 1.
[1 ]
1.0.0rc1
Notes de mise à niveau des fournisseurs
-
Le module
qiskit.providers.fake_providera été migré vers le paquetqiskit-ibm-runtimePython. Pour cette raison, les éléments suivants de la sectionqiskit.providers.fake_provideront été supprimés à la suite de leur dépréciation dans Qiskit 0.46:qiskit.providers.fake_provider.FakeProviderqiskit.providers.fake_provider.FakeProviderForBackendV2qiskit.providers.fake_provider.FakeProviderFactoryqiskit.providers.fake_provider.fake_backends.FakeBackendV2- tout faux backend contenu dans
qiskit.providers.fake_provider.backends(accessible via le fournisseur) qiskit.providers.fake_provider.FakeQasmSimulatorqiskit.providers.fake_provider.FakeJobqiskit.providers.fake_provider.FakeQobj
Pour utiliser le nouveau module "fake provider", vous pouvez lancer
pip install qiskit-ibm-runtimeet remplacer le chemin d'importation de qiskit (qiskit.providers.fake_provider) par le nouveau chemin d'importation (qiskit_ibm_runtime.fake_provider). Exemple de migration :# Legacy path from qiskit.providers.fake_provider import FakeProvider, FakeSherbrooke backend1 = FakeProvider().get_backend("fake_ourense") backend2 = FakeSherbrooke() # New path # run "pip install qiskit-ibm-runtime" from qiskit_ibm_runtime.fake_provider import FakeProvider, FakeSherbrooke backend1 = FakeProvider().get_backend("fake_ourense") backend2 = FakeSherbrooke()En outre, les faux backends suivants, conçus à des fins de test spéciales, ont été remplacés par la nouvelle classe
GenericBackendV2et sont également supprimés suite à leur dépréciation dans Qiskit 0.46:qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2`qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2LegacyQubitPropsqiskit.providers.fake_provider.fake_backend_v2.FakeBackend5QV2qiskit.providers.fake_provider.fake_backend_v2.FakeBackendSimple
Exemple de migration vers la nouvelle
GenericBackendV2classe :# Legacy path from qiskit.providers.fake_provider import FakeBackend5QV2 backend = FakeBackend5QV2() # New path from qiskit.providers.fake_provider import GenericBackendV2 backend = GenericBackendV2(num_qubits=5) # note that this class will generate 5q backend with generic # properties that serves the same purpose as FakeBackend5QV2 # but will generate different results