Notes de publication de Qiskit 0.40
0.40.0
Cette version met officiellement fin au projet de fournisseur IBMQ de Qiskit, qui fait partie du métapackage Qiskit. Cela signifie que dans une prochaine version, pip install qiskit n'inclura plus automatiquement qiskit-ibmq-provider. Si vous installez ou listez actuellement qiskit comme une dépendance pour obtenir qiskit-ibmq-provider, vous devez mettre à jour pour inclure explicitement qiskit-ibmq-provider également. Cette démarche s'inscrit dans le cadre de l'évolution du projet Qiskit vers un modèle dans lequel le paquet qiskit ne contient que les fonctionnalités de base communes pour la construction et la compilation de circuits, de programmes et d'applications quantiques. Les paquets qui s'appuient sur ce noyau ou qui lient Qiskit à du matériel ou à des simulateurs seront installables en tant que paquets séparés.
Terra 0.23.0
Prélude
Qiskit Terra 0.23.0 est une version majeure qui inclut une multitude de nouvelles fonctionnalités et de corrections de bugs. Les points forts de cette version sont les suivants :
Prise en charge de l'importation de programmes OpenQASM 3 et de la création d'objets à partir du programme d'entrée grâce à deux nouvelles fonctions
QuantumCircuità partir du programme d'entrée grâce à deux nouvelles fonctionsqiskit.qasm3.load()etqiskit.qasm3.loads().Amélioration de la bibliothèque d'algorithmes de synthèse inclus dans Qiskit. Il s'agit notamment des nouvelles fonctions de synthèse suivantes :
Synthèse de Clifford
Synthèse de fonctions linéaires :
Synthèse de permutation :
SolovayKitaevDecompositiondétaillée dans : https://arxiv.org/abs/quant-ph/0505030Nouveaux plugins pour
HighLevelSynthesis:
ACGSynthesisPermutationKMSSynthesisPermutationBasicSynthesisPermutationNouveau plugin pour
UnitarySynthesisAmélioration des performances de
SabreLayout. La passe est maintenant principalement écrite en Rust, ce qui peut conduire à une amélioration du temps d'exécution, mais l'amélioration la plus importante concerne la qualité de la sortie (en moyenne, moins deSwapGateportes introduites parSabreSwap). Par exemple, l'exécution deSabreLayoutetSabreSwapsur les circuits Bernstein Vazirani en ciblant le backendFakeSherbrookedonne les résultats suivants :![]()
Cette version met également fin à la prise en charge de l'exécution avec Python 3.7. Un DeprecationWarning sera désormais émis si vous exécutez Qiskit avec Python 3.7. La prise en charge de Python 3.7 sera supprimée dans le cadre de la version 0.25.0 (actuellement prévue pour juillet 2023), et vous aurez alors besoin de Python 3.8 ou d'une version plus récente pour utiliser Qiskit.
Nouvelles fonctions
-
Les impulsions en
qiskit.pulse.librarypeut être initialisé avec le nouveau paramètre
angle, de sorte que deux paramètres flottants peuvent être fournis :ampetangle. L'initialisation à l'aide deampcomplexes est toujours prise en charge. -
La classe
AdaptVQEpossède un nouvel attribut,eigenvalue_historyqui est utilisé pour suivre l'énergie la plus basse atteinte par itération de AdaptVQE. Par exemple :from qiskit.algorithms.minimum_eigensolvers import VQE from qiskit.algorithms.minimum_eigensolvers.adapt_vqe import AdaptVQE from qiskit.algorithms.optimizers import SLSQP from qiskit.circuit.library import EvolvedOperatorAnsatz from qiskit.opflow import PauliSumOp from qiskit.primitives import Estimator from qiskit.quantum_info import SparsePauliOp from qiskit.utils import algorithm_globals excitation_pool = [ PauliSumOp( SparsePauliOp(["IIIY", "IIZY"], coeffs=[0.5 + 0.0j, -0.5 + 0.0j]), coeff=1.0 ), PauliSumOp( SparsePauliOp(["ZYII", "IYZI"], coeffs=[-0.5 + 0.0j, 0.5 + 0.0j]), coeff=1.0 ), PauliSumOp( SparsePauliOp( ["ZXZY", "IXIY", "IYIX", "ZYZX", "IYZX", "ZYIX", "ZXIY", "IXZY"], coeffs=[ -0.125 + 0.0j, 0.125 + 0.0j, -0.125 + 0.0j, 0.125 + 0.0j, 0.125 + 0.0j, -0.125 + 0.0j, 0.125 + 0.0j, -0.125 + 0.0j, ], ), coeff=1.0, ), ] ansatz = EvolvedOperatorAnsatz(excitation_pool, initial_state=self.initial_state) optimizer = SLSQP() h2_op = PauliSumOp.from_list( [ ("IIII", -0.8105479805373266), ("ZZII", -0.2257534922240251), ("IIZI", +0.12091263261776641), ("ZIZI", +0.12091263261776641), ("IZZI", +0.17218393261915543), ("IIIZ", +0.17218393261915546), ("IZIZ", +0.1661454325638243), ("ZZIZ", +0.1661454325638243), ("IIZZ", -0.2257534922240251), ("IZZZ", +0.16892753870087926), ("ZZZZ", +0.17464343068300464), ("IXIX", +0.04523279994605788), ("ZXIX", +0.04523279994605788), ("IXZX", -0.04523279994605788), ("ZXZX", -0.04523279994605788), ] ) algorithm_globals.random_seed = 42 calc = AdaptVQE(VQE(Estimator(), ansatz, self.optimizer)) res = calc.compute_minimum_eigenvalue(operator=h2_op) print(calc.eigenvalue_history)la valeur retournée de
calc.historydevrait être approximativement[-1.85727503]puisqu'il n'y a qu'une seule itération. -
La journalisation de l'exécution lors de l'exécution de la fonction
AdaptVQEa été améliorée. Lors de l'exécution de la classe, des messages de niveauDEBUGetINFOseront émis lors de l'exécution de la classe. -
Ajout d'une nouvelle passe de transpilation,
CollectAndCollapse, pour collecter et consolider les blocs de nœuds dans un circuit. Cette passe est conçue comme une classe de base générale pour la collecte et la consolidation de blocs combinés. Pour être tout à fait général, le travail de collecte et de regroupement des blocs est effectué par des fonctions fournies lors de l'instanciation de la passe. Par exemple, leCollectLinearFunctionsa été mis à jour pour hériter deCollectAndCollapseet rassemble les blocs deCXGateetSwapGateet remplace chaque bloc par unLinearFunction. LeCollectCliffordsqui est maintenant également basé surCollectAndCollapse, rassemble des blocs de portes "Clifford" et remplace chaque bloc par une porte "Clifford"Clifford.L'interface prend également en charge l'option
do_commutative_analysis, qui permet d'exploiter la commutativité entre les portes afin de collecter des blocs de nœuds plus importants. Par exemple, rassembler des blocs de portes CX dans le circuit suivant :qc = QuantumCircuit(2) qc.cx(0, 1) qc.z(0) qc.cx(1, 0)l'utilisation de
do_commutative_analysispermet de consolider les deux portes CX, la première porte CX et la porte Z faisant la navette. -
Ajout d'une nouvelle classe
BlockCollectorqui met en œuvre diverses stratégies de collecte, et d'une nouvelle classeBlockCollapserqui met en œuvre diverses stratégies de regroupement. Actuellement,BlockCollectorcomprend la stratégie consistant à collecter avec avidité toutes les portes adhérant à une fonction de filtrage donnée (par exemple, collecter toutes les portes de Clifford), etBlockCollapsercomprend la stratégie consistant à consolider toutes les portes d'un bloc en un seul objet (par exemple, un bloc de portes de Clifford peut être consolidé en un seul objetClifford). -
Ajout d'une nouvelle passe de
CollectCliffordsqui collecte des blocs de portes de Clifford et les consolide en objetsqiskit.quantum_info.Cliffordobjets. Cette passe hérite deCollectAndCollapseet supporte en particulier l'optiondo_commutative_analysis. Il prend également en charge deux options supplémentaires :split_blocksetmin_block_size. Voir les notes de mise à jour pourCollectAndCollapseetCollectLinearFunctionspour plus de détails. -
La passe
CollectLinearFunctionstranspiler pass a plusieurs nouveaux arguments dans son constructeur :-
do_commutative_analysisl'utilisation de la commutativité entre les portes permet de collecter des blocs de nœuds plus importants. -
split_blocksil permet de diviser les blocs collectés en sous-blocs sur des sous-ensembles disjoints de qubits. Par exemple, dans le circuit suivant :qc = QuantumCircuit(4) qc.cx(0, 2) qc.cx(1, 3) qc.cx(2, 0) qc.cx(3, 1) qc.cx(1, 3)le bloc unique de portes CX sur les qubits
{0, 1, 2, 3}peut être divisé en deux sous-blocs disjoints, l'un sur les qubits{0, 2}et l'autre sur les qubits{1, 3}. -
min_block_sizepermet de spécifier la taille minimale du bloc à consolider; les blocs comportant moins de portes ne seront pas modifiés. Par exemple, dans le circuit suivant :qc = QuantumCircuit(4) qc.cx(1, 2) qc.cx(2, 1)les deux portes CX seront consolidées lorsque
min_block_sizeest 1 ou 2, et resteront inchangées lorsquemin_block_sizeest 3 ou plus.
-
-
Ajout d'un algorithme de synthèse efficace en profondeur
synth_cnot_depth_line_kms()pour les circuits linéaires réversiblesLinearFunctionsur l'architecture linéaire du plus proche voisin, conformément à l'article : https://arxiv.org/abs/quant-ph/0701194. -
La méthode
DAGCircuit.replace_block_with_op()renvoie désormais le nouveauDAGOpNodequi est créé lorsque le bloc est remplacé. Auparavant, l'appel à cette méthode ne renvoyait rien. -
Ajout d'un algorithme de synthèse efficace en profondeur
synth_permutation_depth_lnn_kms()pourPermutationpar rapport à l'architecture linéaire du plus proche voisin, conformément à l'article : https://arxiv.org/abs/quant-ph/0701194 -
Ajout d'une nouvelle classe
PermutationGatepour représenter la logique de permutation en tant qu'élément de circuit. Contrairement à l'élément de bibliothèquePermutationqui avait une définition statique, cette nouvelle classe évite de synthétiser un circuit de permutation lorsqu'elle est déclarée. Cela retarde la synthèse proprement dite au niveau du transpondeur. Il permet également d'utiliser plusieurs algorithmes différents pour synthétiser les permutations, qui sont disponibles en tant que plugins de permutation de synthèse de haut niveau.Une autre caractéristique clé du
PermutationGateest qu'il implémente l'interface__array__pour retourner efficacement une matrice unitaire pour une permutation. -
Ajout de plusieurs plugins de synthèse de haut niveau pour la synthèse de permutations :
BasicSynthesisPermutationil s'applique aux architectures entièrement connectées et est basé sur le tri. Il s'agit de l'algorithme précédemment utilisé pour construire des circuits quantiques pour les permutations.ACGSynthesisPermutationil s'applique aux architectures entièrement connectées mais est basé sur la méthode Alon, Chung, Graham. Il synthétise n'importe quelle permutation en profondeur 2 (mesurée en termes de SWAP).KMSSynthesisPermutationla méthode Kutin, Moulton, Smithline, récemment ajoutée, s'applique aux architectures linéaires à plus proche voisin et correspond à la méthode Kutin, Moulton, Smithline.
Par exemple :
from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import PermutationGate from qiskit.transpiler import PassManager from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig, HighLevelSynthesis from qiskit.transpiler.passes.synthesis.plugin import HighLevelSynthesisPluginManager # Create a permutation and add it to a quantum circuit perm = PermutationGate([4, 6, 3, 7, 1, 2, 0, 5]) qc = QuantumCircuit(8) qc.append(perm, range(8)) # Print available plugin names for synthesizing permutations # Returns ['acg', 'basic', 'default', 'kms'] print(HighLevelSynthesisPluginManager().method_names("permutation")) # Default plugin for permutations # Returns a quantum circuit with size 6 and depth 3 qct = PassManager(HighLevelSynthesis()).run(qc) print(f"Default: {qct.size() = }, {qct.depth() = }") # KMSSynthesisPermutation plugin for permutations # Returns a quantum circuit with size 18 and depth 6 # but adhering to the linear nearest-neighbor architecture. qct = PassManager(HighLevelSynthesis(HLSConfig(permutation=[("kms", {})]))).run(qc) print(f"kms: {qct.size() = }, {qct.depth() = }") # BasicSynthesisPermutation plugin for permutations # Returns a quantum circuit with size 6 and depth 3 qct = PassManager(HighLevelSynthesis(HLSConfig(permutation=[("basic", {})]))).run(qc) print(f"basic: {qct.size() = }, {qct.depth() = }") # ACGSynthesisPermutation plugin for permutations # Returns a quantum circuit with size 6 and depth 2 qct = PassManager(HighLevelSynthesis(HLSConfig(permutation=[("acg", {})]))).run(qc) print(f"acg: {qct.size() = }, {qct.depth() = }") -
Ajout de nouvelles classes pour les algorithmes Quantum Fisher Information (QFI) et Quantum Geometric Tensor (QGT) à l'aide de
primitives,qiskit.algorithms.gradients.QFIetqiskit.algorithms.gradients.LinCombQGTau module de gradients :qiskit.algorithms.gradients. Par exemple :from qiskit.circuit import QuantumCircuit, Parameter from qiskit.algorithms.gradients import LinCombQGT, QFI estimator = Estimator() a, b = Parameter("a"), Parameter("b") qc = QuantumCircuit(1) qc.h(0) qc.rz(a, 0) qc.rx(b, 0) parameter_value = [[np.pi / 4, 0]] qgt = LinCombQGT(estimator) qgt_result = qgt.run([qc], parameter_value).result() qfi = QFI(qgt) qfi_result = qfi.run([qc], parameter_value).result() -
Ajout d'un nouveau mot-clé,
derivative_type, dans le constructeur de la classeLinCombEstimatorGradient. Cet argument prend une énumérationDerivativeTypequi permet de spécifier de calculer uniquement les parties réelles ou imaginaires du gradient. -
Ajout d'une nouvelle option
circuit_reverse_bitsau fichier de configuration de l'utilisateur. Cela permet aux utilisateurs de définir un booléen pour le comportement par défaut qu'ils préfèrent pour l'argumentreverse_bitsdes tiroirs de circuitsQuantumCircuit.draw()etcircuit_drawer(). Par exemple, l'ajout d'une section au fichier de configuration de l'utilisateur dans l'emplacement par défaut~/.qiskit/settings.confavec :[default] circuit_reverse_bits = Truemodifiera la valeur par défaut pour afficher les bits dans l'ordre inverse.
-
Ajout d'une nouvelle classe
Z2Symmetriestoqiskit.quantum_infoqui est utilisée pour identifier les symétries à partir d'une entréeSparsePauliOp. -
Ajout d'une nouvelle directive pulse
TimeBlockade. Cette directive a un comportement presque identique à celui de l'instruction delay, mais elle sera supprimée avant l'exécution. Cette directive est destinée à être utilisée en interne par le constructeur d'impulsions et permet de représenter des instructions avec des intervalles de temps absolusScheduleBlockde représenter des instructions avec des intervalles de temps absolus. Cela permet au constructeur d'impulsions de convertirScheduleenScheduleBlock, plutôt que de l'envelopper d'instructionsCallinstructions. -
Ajout d'algorithmes compatibles avec les primitives pour l'évolution variationnelle du temps quantique qui implémentent l'interface de l'évolution du temps quantique. La classe
qiskit.algorithms.VarQRTEest utilisée pour l'évolution du temps quantique réel et la classeqiskit.algorithms.VarQITEest utilisée pour l'évolution du temps quantique imaginaire selon un principe variationnel passé.Chaque algorithme accepte un principe variationnel qui met en œuvre l'interface abstraite
ImaginaryVariationalPrincipleinterface abstraite. Les implémentations suivantes sont incluses :Par exemple :
from qiskit.algorithms import TimeEvolutionProblem, VarQITE from qiskit.algorithms.time_evolvers.variational import ImaginaryMcLachlanPrinciple from qiskit.circuit.library import EfficientSU2 from qiskit.quantum_info import SparsePauliOp import numpy as np observable = SparsePauliOp.from_list( [ ("II", 0.2252), ("ZZ", 0.5716), ("IZ", 0.3435), ("ZI", -0.4347), ("YY", 0.091), ("XX", 0.091), ] ) ansatz = EfficientSU2(observable.num_qubits, reps=1) init_param_values = np.zeros(len(ansatz.parameters)) for i in range(len(ansatz.parameters)): init_param_values[i] = np.pi / 2 var_principle = ImaginaryMcLachlanPrinciple() time = 1 evolution_problem = TimeEvolutionProblem(observable, time) var_qite = VarQITE(ansatz, var_principle, init_param_values) evolution_result = var_qite.evolve(evolution_problem) -
Ajout de règles pour la conversion des
XXPlusYYGateetXXMinusYYGatevers d'autres portes du siteSessionEquivalenceLibrary. Cela permet d'exécutertranspile()ciblant un backend ouTargetqui utilise ces portes. -
Ajout de deux nouveaux faux backends,
FakePragueetFakeSherbrookeau moduleqiskit.providers.fake_providermodule.FakePraguefournit un backend avec un instantané des propriétés du backend IBM Prague Egret R1 etFakeSherbrookefournit un backend avec un instantané des propriétés du backend IBM Aigle de Sherbrooke R3. -
Ajout d'un nouveau mot-clé,
allow_unknown_parameters, à l'optionParameterExpression.bind()etParameterExpression.subs()aux méthodes. Lorsqu'il est défini, ce nouvel argument permet de passer un dictionnaire contenant des paramètres inconnus à ces méthodes sans provoquer d'erreur. Auparavant, cela entraînait toujours une erreur sans qu'il soit possible de désactiver ce comportement. -
L'argument de la méthode
BaseEstimator.run()l'argumentobservablesde la méthode accepte désormais un type d'entréestrou une séquence destren plus des autres types déjà acceptés. Lorsqu'il est utilisé, le format de la chaîne d'entrée doit correspondre à la représentation de la chaîne de Pauli acceptée par le constructeur des objetsPaulides objets. -
Ajout d'une nouvelle méthode de construction
QuantumCircuit.from_instructions()qui permet de créer un objetQuantumCircuità partir d'une table itérative d'instructions. Par exemple :from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister from qiskit.circuit.quantumcircuitdata import CircuitInstruction from qiskit.circuit import Measure from qiskit.circuit.library import HGate, CXGate qr = QuantumRegister(2) cr = ClassicalRegister(2) instructions = [ CircuitInstruction(HGate(), [qr[0]], []), CircuitInstruction(CXGate(), [qr[0], qr[1]], []), CircuitInstruction(Measure(), [qr[0]], [cr[0]]), CircuitInstruction(Measure(), [qr[1]], [cr[1]]), ] circuit = QuantumCircuit.from_instructions(instructions) circuit.draw("mpl")
-
La classe
Cliffordprend désormais un argument optionnelcopydans son constructeur. S'il est défini surFalse, unStabilizerTablefourni en entrée ne sera pas copié, mais utilisé directement. Cela peut présenter des avantages en termes de performances, si les données du tableau ne sont jamais modifiées par d'autres moyens. -
Les performances de
Clifford.compose()a été grandement améliorée pour tous les nombres de qubits. Pour les opérateurs de 20 qubits, l'accélération est de l'ordre de 100 fois. -
Ajout d'une nouvelle fonction de synthèse
synth_clifford_layers()pour synthétiser unClifforden couches. L'algorithme est basé sur S. Bravyi, D. Maslov, Les circuits sans Hadamard exposent la structure du groupe de Clifford, arxiv:2003.09412. Cela permet de décomposer le Clifford en 8 couches de portes, dont deux couches de portes CZ et une couche de portes CX. Par exemple, un circuit de Clifford à 5 qubits est décomposé dans les couches suivantes :┌─────┐┌─────┐┌────────┐┌─────┐┌─────┐┌─────┐┌─────┐┌────────┐ q_0: ┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├┤0 ├ │ ││ ││ ││ ││ ││ ││ ││ │ q_1: ┤1 ├┤1 ├┤1 ├┤1 ├┤1 ├┤1 ├┤1 ├┤1 ├ │ ││ ││ ││ ││ ││ ││ ││ │ q_2: ┤2 S2 ├┤2 CZ ├┤2 CX_dg ├┤2 H2 ├┤2 S1 ├┤2 CZ ├┤2 H1 ├┤2 Pauli ├ │ ││ ││ ││ ││ ││ ││ ││ │ q_3: ┤3 ├┤3 ├┤3 ├┤3 ├┤3 ├┤3 ├┤3 ├┤3 ├ │ ││ ││ ││ ││ ││ ││ ││ │ q_4: ┤4 ├┤4 ├┤4 ├┤4 ├┤4 ├┤4 ├┤4 ├┤4 ├ └─────┘└─────┘└────────┘└─────┘└─────┘└─────┘└─────┘└────────┘Cette méthode permettra de décomposer un
Clifforden profondeur de 2 qubits pour la connectivité du plus proche voisin linéaire (LNN). -
Les types de retour des méthodes
power()de plusieurs classes de portes de la bibliothèque standard ont été mis à jour pour renvoyer des objets de portes plus spécifiques, ce qui permet d'obtenir un résultat plus efficace et avec moins de pertes. Par exemple, l'exécution depower()renvoie désormais une instanceIGateau lieu deUnitaryGatecomme c'était le cas auparavant.La liste complète des types de sortie qui ont été améliorés est la suivante :
-
Le
EquivalenceLibraryest désormais représenté en interne sous la forme d'unPyDiGraph, cet objet graphique sous-jacent est accessible à partir du nouvel attributgraphattribut. Cet attribut est destiné à une utilisation interne dans Qiskit et doit donc toujours être copié avant d'être modifié par l'utilisateur afin d'éviter une éventuelle corruption du graphe d'équivalence interne. -
La méthode du constructeur
Operator.from_circuit()va maintenant inverser la permutation de sortie causée par l'étape de routage/mise en correspondance du transpileur. Par défaut, si des portes Swap ont été insérées dans un circuit transpilé, la matrice de sortie aura cette permutation inversée, de sorte que la matrice renvoyée sera équivalente au circuit original non transpilé. Si vous souhaitez désactiver ce comportement par défaut, l'argument du mot-cléignore_set_layoutpeut être défini àTruepour le faire (en plus du comportement précédent consistant à ignorer la disposition initiale de la transpilation). Si vous souhaitez définir manuellement une disposition finale, vous pouvez utiliser le nouveau mot-cléfinal_layoutpour transmettre un objetLayoutà utiliser pour la permutation de sortie. -
Ajout d'un support à la passe
GateDirectionpour gérer la passe de transpilation symétriqueRXXGate,RYYGate, etRZZGatesymétriques. La passe traitera maintenant correctement ces portes et inversera simplement l'ordre des qargs en place sans aucune autre modification. -
L'utilisation de l'opérateur d'exponentiation Python,
**, avec les objets est désormais prise en chargeGateest désormais pris en charge. Cela équivaut à exécuter la méthodeGate.power()sur l'objet.Par exemple :
from qiskit.circuit.library import XGate sx = XGate() ** 0.5 -
Ajout d'une nouvelle forme d'impulsion
GaussianSquareDragau moduleqiskit.pulse.librarymodule. Cette forme d'impulsion est similaire àGaussianSquaremais utilise la formeDragpendant sa montée et sa descente. La correction de la forme de l'impulsion DRAG peut supprimer une partie du spectre de fréquence de la montée et de la descente de l'impulsion, ce qui permet d'éviter d'exciter les qubits spectateurs lorsque leur fréquence est proche de la fréquence d'entraînement de l'impulsion. -
Ajout d'un nouveau mot-clé,
method, dans les constructeurs pour lesFiniteDiffEstimatorGradientetFiniteDiffSamplerGradient. L'argumentmethodaccepte une chaîne de caractères indiquant la méthode de calcul à utiliser pour le gradient. Trois méthodes sont disponibles :"central","forward", et"backward". Les définitions des méthodes sont les suivantes :MéthodeCalcul"central""forward""backward"où est l'epsilon du décalage.
-
Toutes les classes de gradient dans
qiskit.algorithms.gradientspréservent désormais les opérations non paramétrées au lieu d'essayer de les dérouler. Cela permet d'évaluer les gradients sur des portes personnalisées et opaques que les primitives individuelles peuvent gérer et de conserver un niveau d'abstraction plus élevé pour une synthèse et une compilation optimisées après la construction des circuits de gradient. -
Ajout d'une
TranslateParameterizedGatespour faire correspondre uniquement les portes paramétrées d'un circuit à une base spécifiée, sans toucher aux portes non paramétrées. La passe tente d'abord de dérouler et traduit finalement si une porte paramétrée ne peut pas être déroulée davantage. -
Le passage du transpondeur
CollectCliffordsla passe de transposition a été étendue pour collecter et combiner des blocs de "portes de clifford" en objetsCliffordoù les "portes de clifford" peuvent maintenant aussi inclure des objets de typeLinearFunction,Clifford, etPauliGate. Par exemple :from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import LinearFunction, PauliGate from qiskit.quantum_info.operators import Clifford from qiskit.transpiler.passes import CollectCliffords from qiskit.transpiler import PassManager # Create a Clifford cliff_circuit = QuantumCircuit(2) cliff_circuit.cx(0, 1) cliff_circuit.h(0) cliff = Clifford(cliff_circuit) # Create a linear function lf = LinearFunction([[0, 1], [1, 0]]) # Create a pauli gate pauli_gate = PauliGate("XYZ") # Create a quantum circuit with the above and also simple clifford gates. qc = QuantumCircuit(4) qc.cz(0, 1) qc.append(cliff, [0, 1]) qc.h(0) qc.append(lf, [0, 2]) qc.append(pauli_gate, [0, 2, 1]) qc.x(2) # Run CollectCliffords transpiler pass qct = PassManager(CollectCliffords()).run(qc)Toutes les portes seront rassemblées et combinées en une seule
Clifford. Le circuit final est donc constitué d'un seul objetCliffordobjet. -
CouplingMapest maintenant implicitement itérable, l'itération étant identique à l'itération sur la sortie deCouplingMap.get_edges(). En d'autres termes,from qiskit.transpiler import CouplingMap coupling = CouplingMap.from_line(3) list(coupling) == list(coupling.get_edges())fonctionnera désormais comme prévu, de même que les autres itérations. Il s'agit d'une simple commodité syntaxique.
-
Ajout d'une nouvelle fonction
synth_cnot_count_full_pmh()qui est utilisée pour synthétiser des circuits linéaires réversibles pour des architectures "all-to-all" en utilisant les méthodes de Patel, Markov et Hayes. Cette fonction est identique à la fonctionqiskit.transpiler.synthesis.cnot_synth()disponible, mais elle porte un nom plus descriptif et est placée plus logiquement dans l'arborescence du paquet. Cette nouvelle fonction remplace l'ancienne fonction qui sera probablement supprimée dans une prochaine version. -
InstructionScheduleMapa été mis à jour pour stocker les données d'étalonnage du backend dans le format PulseQobj JSON et invoque la conversion lorsque les données sont consultées pour la première fois, c'est-à-dire une conversion paresseuse. Cette mise à jour de la logique interne améliore considérablement les performances du chargement du backend, en particulier avec de nombreuses entrées d'étalonnage. -
Le nouveau module
qiskit.pulse.calibration_entriesa été ajouté. Il contient plusieurs classes d'enveloppe pour différentes représentations de l'horaire des impulsions.ScheduleDefCallableDefPulseQobjDef
Ces classes mettent en œuvre les méthodes
get_schedule()etget_signature()qui renvoient respectivement le calendrier des impulsions et les noms des paramètres à affecter. Ces classes sont gérées en interne par le systèmeInstructionScheduleMapou le backendTargetet n'apparaissent donc pas dans un programme utilisateur typique. -
Introduction d'une nouvelle sous-classe
ScalableSymbolicPulse, en tant que sous-classe deSymbolicPulse. La nouvelle sous-classe se comporte de la même manière queSymbolicPulsesauf qu'elle suppose que l'enveloppe de l'impulsion comprend un pré-facteur d'amplitude complexe de la forme . Cette forme d'enveloppe correspond à de nombreuses impulsions courantes, y compris toutes les impulsions de la bibliothèque Qiskit Pulse (qui ont également été converties en représentationamp,angledans cette version).La nouvelle sous-classe supprime la nature non unique de la représentation
amp,angleet compare correctement les impulsions en fonction de leur amplitude complexe. -
Ajout d'un nouveau mot-clé,
dtype, à la méthodePauliSumOp.from_list()méthode. Lorsqu'il est spécifié, cet argument peut être utilisé pour spécifier l'adressedtypedu tableau numpy alloué pour l'objet de la constructionSparsePauliOputilisé en interne par l'algorithme construitPauliSumOp. -
La prise en charge de l'importation des programmes OpenQASM 3 dans Qiskit a été ajoutée. On peut y accéder plus facilement en utilisant les fonctions
qasm3.loads()etqasm3.load()pour charger un programme directement à partir d'une chaîne de caractères et indirectement à partir d'un nom de fichier, respectivement. Par exemple, on peut maintenant faire :from qiskit import qasm3 circuit = qasm3.loads(""" OPENQASM 3.0; include "stdgates.inc"; qubit q; qubit[5] qr; bit c; bit[5] cr; h q; c = measure q; if (c) { h qr[0]; cx qr[0], qr[1]; cx qr[0], qr[2]; cx qr[0], qr[3]; cx qr[0], qr[4]; } else { h qr[4]; cx qr[4], qr[3]; cx qr[4], qr[2]; cx qr[4], qr[1]; cx qr[4], qr[0]; } cr = measure qr; """)Cela chargera le programme dans une instance
QuantumCircuitdans la variablecircuit.Toutes les fonctionnalités de OpenQASM 3 ne sont pas prises en charge dans un premier temps, car Qiskit ne dispose pas encore d'un moyen de représenter le traitement classique avancé des données. Les capacités de l'importateur augmenteront en même temps que celles du reste de Qiskit. L'ensemble initial de caractéristiques de l'importateur est approximativement le même ensemble de caractéristiques que celui qui serait produit par l'exportateur (
qasm3.dump()etqasm3.dumps()).Notez que la prise en charge de OpenQASM 3 par Qiskit n'a pas pour but de fournir une représentation totalement sans perte de
QuantumCircuits. Pour cela, envisagez d'utiliserqiskit.qpy. -
Les classes de gradient
primitives-définies par les classes de gradient basées sur lesBaseEstimatorGradientetBaseSamplerGradientont été mises à jour pour simplifier l'extension de l'interface de base. Il y a trois nouvelles méthodes internes qui peuvent être remplacées,_preprocess(),_postprocess(), et_run_unique()._preprocess()permet à une sous-classe de personnaliser les circuits et les paramètres du gradient d'entrée,_postprocesspermet de personnaliser le résultat de sortie, et_run_uniquepermet de calculer le gradient d'un circuit avec des paramètres uniques. -
La passe de
SabreLayoutest beaucoup plus performant car il a été réécrit en Rust. Dans le cadre de cette réécriture, la passe a été transformée d'une passe d'analyse en une passe de transformation qui exécutera à la fois la mise en page et le routage. Cela a été fait non seulement pour améliorer les performances d'exécution, mais aussi pour améliorer la qualité des résultats. La fonctionnalité précédente de la passe en tant que passe d'analyse peut être conservée en définissant manuellement l'argumentrouting_passou en utilisant le nouvel argumentskip_routing. -
La passe
SabreLayouta un nouvel argument de constructionlayout_trials. Cet argument est utilisé pour contrôler le nombre de graines du générateur de nombres aléatoires que l'on essaiera d'utiliserSabreLayoutavec. Lorsque cette option est activée, l'algorithme de mise en page SABRE est exécutélayout_trialsun certain nombre de fois et la meilleure qualité de sortie (mesurée par le plus petit nombre de portes de permutation ajoutées) est sélectionnée. Ces essais de semences sont exécutés en parallèle en utilisant le multithreading afin de minimiser les surcharges de performance potentielles liées à l'exécution de la mise en page plusieurs fois. Par défaut, si ce paramètre n'est pas spécifié, leSabreLayoututilisera par défaut le nombre de CPU physiques disponibles sur le système local. -
Ajout de deux nouvelles classes
SciPyRealEvolveretSciPyImaginaryEvolverqui mettent en œuvre des méthodes d'intégration pour l'évolution temporelle d'un état quantique. La valeur et l'écart-type des observables ainsi que les moments auxquels ils sont évalués peuvent être interrogés comme suitTimeEvolutionResult.observablesetTimeEvolutionResult.times. Par exemple :from qiskit.algorithms.time_evolvers.time_evolution_problem import TimeEvolutionProblem from qiskit.quantum_info import SparsePauliOp from qiskit.quantum_info.states.statevector import Statevector from qiskit.algorithms import SciPyImaginaryEvolver initial_state = Statevector.from_label("+++++") hamiltonian = SparsePauliOp("ZZZZZ") evolution_problem = TimeEvolutionProblem(hamiltonian, 100, initial_state, {"Energy":hamiltonian}) classic_evolver = SciPyImaginaryEvolver(num_timesteps=300) result = classic_evolver.evolve(evolution_problem) print(result.observables) -
Ajout de la passe
SolovayKitaevpour exécuter l'algorithme Solovay-Kitaev pour l'approximation des unitaires d'un seul qubit en utilisant un ensemble de portes discrètes. En combinaison avec le traducteur de base, cela permet de convertir n'importe quel circuit unitaire en un ensemble de portes discrètes universelles, qui pourrait être mis en œuvre de manière tolérante aux pannes.Cette passe peut par exemple être utilisée après la compilation vers les portes U et CX :
from qiskit import transpile from qiskit.circuit.library import QFT from qiskit.transpiler.passes.synthesis import SolovayKitaev qft = QFT(3) # optimize to general 1-qubit unitaries and CX transpiled = transpile(qft, basis_gates=["u", "cx"], optimization_level=1) skd = SolovayKitaev() # uses T Tdg and H as default basis discretized = skd(transpiled) print(discretized.count_ops())La décomposition peut également être utilisée avec le plugin de synthèse unitaire, comme la méthode "sk" sur la passe de
UnitarySynthesistranspiler pass :from qiskit import QuantumCircuit from qiskit.quantum_info import Operator from qiskit.transpiler.passes import UnitarySynthesis circuit = QuantumCircuit(1) circuit.rx(0.8, 0) unitary = Operator(circuit).data unitary_circ = QuantumCircuit(1) unitary_circ.unitary(unitary, [0]) synth = UnitarySynthesis(basis_gates=["h", "s"], method="sk") out = synth(unitary_circ) out.draw('mpl')
-
La génération de circuits aléatoires avec
qiskit.circuit.random.random_circuit()est désormais nettement plus rapide pour les circuits de grande taille. -
La génération de circuits aléatoires avec
qiskit.circuit.random.random_circuit()produira désormais toutes les portes "standard" de la bibliothèque de circuits de Qiskit (qiskit.circuit.library). Cela inclut deux portes à 4 qubitsC3SXGateetRC3XGateet les valeurs autorisées demax_operandsont été étendues en conséquence. -
La passe
Optimize1qGatesDecompositiontranspiler pass a un nouvel argument de mot-clé,target, dans son constructeur. Cet argument peut être utilisé pour spécifier un objetTargetqui représente la cible de la compilation. S'il est utilisé, il supplante l'argumentbasispour déterminer si une instruction du circuit est présente sur le backend cible. -
La passe
UnrollCustomDefinitionstranspiler pass a un nouvel argument de mot-clé,target, dans son constructeur. Cet argument peut être utilisé pour spécifier un objetTargetqui représente la cible de la compilation. S'il est utilisé, il supplante l'argumentbasis_gatespour déterminer si une instruction du circuit est présente sur le backend cible. -
Ajout de la classe
ReverseEstimatorGradientpour une évaluation classique et rapide des gradients de la valeur d'espérance basée sur la rétropropagation ou les gradients en mode inverse. Cette classe utilise des vecteurs d'état et fournit donc des gradients exacts, mais elle s'étend de manière exponentielle à la taille du système. Il est conçu pour un calcul de référence rapide des systèmes de petite taille. Il peut par exemple être utilisé comme :from qiskit.circuit.library import EfficientSU2 from qiskit.quantum_info import SparsePauliOp from qiskit.algorithms.gradients import ReverseEstimatorGradient observable = SparsePauliOp.from_sparse_list([("ZZ", [0, 1], 1)], num_qubits=10) circuit = EfficientSU2(num_qubits=10) values = [i / 100 for i in range(circuit.num_parameters)] gradient = ReverseEstimatorGradient() result = gradient.run([circuit], [observable], [values]).result() -
Ajout d'un nouveau mot-clé argument,
use_dagau constructeur de laOneQubitEulerDecomposerclasse. Lorsqueuse_dagest défini surTrue, le résultat du décomposeur sera un objetDAGCircuitau lieu deQuantumCircuitobjet. Ceci est utile pour les passes de transpilation qui utilisentOneQubitEulerDecomposer(commeOptimize1qGatesDecomposition), car le fait de travailler directement avec unDAGCircuitévite le surcoût de la conversion entreQuantumCircuitetDAGCircuit. -
Ajout de la possibilité pour les passes d'analyse de définir des pondérations heuristiques personnalisées pour les variables
VF2LayoutetVF2PostLayoutpour les passes de transpilation. Si une passe d'analyse définit la clévf2_avg_error_mapdans l'ensemble de propriétés, sa valeur est utilisée pour les pondérations d'erreur au lieu des taux d'erreur provenant de l'ensemble de propriétés du backendTarget(ouBackendPropertiespourBackendV1). La valeur doit être une instanceErrorMap, où chaque valeur représente le taux d'erreur moyen pour toutes les opérations à 1 ou 2 qubits sur ces qubits. Si une valeur estNaN, l'arête correspondante est traitée comme une arête idéale (ou un qubit pour les opérations 1q ). Par exemple, une carte des erreurs créée comme suit :from qiskit.transpiler.passes.layout.vf2_utils import ErrorMap error_map = ErrorMap(3) error_map.add_error((0, 0), 0.0024) error_map.add_error((0, 1), 0.01) error_map.add_error((1, 1), 0.0032)décrit une cible à 2 qubits, où le taux d'erreur moyen de 1q est de
0.0024sur le qubit 0 et de0.0032sur le qubit 1, le taux d'erreur moyen de 2q pour les portes qui opèrent sur (0, 1) est de 0.01, et (1, 0) n'est pas pris en charge par la cible. Elle sera utilisée pour la notation si elle est définie pour la clévf2_avg_error_mapdans l'ensemble des propriétés lorsqueVF2LayoutetVF2PostLayoutsont exécutés. Par exemple :from qiskit.transpiler import AnalysisPass, PassManager, Target from qiskit.transpiler.passes import VF2Layout from qiskit.transpiler.passes.layout.vf2_utils import ErrorMap from qiskit.circuit.library import CZGate, UGate from qiskit.circuit import Parameter class CustomVF2Scoring(AnalysisPass): """Set custom score for vf2.""" def run(self, dag): error_map = ErrorMap(3) error_map.add_error((0, 0), 0.0024) error_map.add_error((0, 1), 0.01) error_map.add_error((1, 1), 0.0032) self.property_set["vf2_avg_error_map"] = error_map target = Target(num_qubits=2) target.add_instruction( UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')), {(0,): None, (1,): None} ) target.add_instruction( CZGate(), {(0, 1): None} ) vf2_pass = VF2Layout(target=target, seed=1234568942) pm = PassManager([CustomVF2Scoring(), vf2_pass])Cela fonctionnera
VF2Layoutavec la notation personnalisée deerror_mappour un qubit 2Targetqui ne contient pas de taux d'erreur.
Mise à niveau
-
Lors de l'initialisation de l'une des classes d'impulsions dans
qiskit.pulse.library:fournir un argument complexe
ampavec uneanglefinie résultera enPulseErrormaintenant. Par exemple, au lieu d'appelerGaussian(duration=100,sigma=20,amp=0.5j), il faut maintenant utiliserGaussian(duration=100,sigma=20,amp=0.5,angle=np.pi/2). L'enveloppe d'impulsion qui était définie commeamp * ...est à son tour définie commeamp * exp(1j * angle) * .... Cette modification a été apportée pour mieux prendre en charge les expériences Qiskit dans lesquelles l'amplitude et l'angle des impulsions sont calibrés dans des expériences distinctes. -
Pour Python 3.7 singledispatchmethod est maintenant une dépendance. Cela a été ajouté pour permettre de tirer parti du mécanisme de répartition des méthodes dans la bibliothèque standard des versions plus récentes de Python. Si vous êtes sur Python >= 3.8, aucune dépendance supplémentaire n'est nécessaire.
-
La passe de transpilation
MSBasisDecomposerdisponible via le moduleqiskit.transpiler.passesa été supprimée. Il a été déprécié à l'origine dans le cadre de la version de Qiskit Terra 0.16.0 (10-16-2020). Au lieu de cela, la passeBasisTranslatordoit être utilisé pour traduire un circuit en une base appropriée avec unRXXGate -
EquivalenceLibraryqui sont initialisés avec l'attributbasen'auront plus de référence partagée avec l'objetEquivalenceLibrarypassé dans l'attribut. Dans les versions précédentes, si vous modifiezbaseaprès qu'il a été utilisé pour créer une nouvelle instance, les deux instances refléteront ce changementEquivalenceLibraryles deux instances reflétaient ce changement. Ce n'est plus le cas et les mises à jour debasene seront plus reflétées dans le nouveau fichierEquivalenceLibrary. Par exemple, si vous avez créé une bibliothèque d'équivalence avec :import math from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import XGate from qiskit.circuit.equivalence import EquivalenceLibrary original_lib = EquivalenceLibrary() qc = QuantumCircuit(1) qc.rx(math.pi, 0) original_lib.add_equivalence(XGate(), qc) new_lib = EquivalenceLibrary(base=original_lib)si vous avez modifié
original_libavec :import from qiskit.circuit.library import SXGate qc = QuantumCircuit(1) qc.rx(math.pi / 2, 0) original_lib.add_equivalence(SXGate(), qc)dans les versions précédentes,
new_libincluait également la définition deSXGateaprès qu'elle ait été ajoutée àoriginal_lib, mais ce n'est plus le cas dans cette version. Ce changement a été effectué en raison de la modification de la structure interne des données, qui est devenue un graphique, ce qui a permis d'améliorer les performances de la classe, en particulier lorsqu'il y a plusieurs exécutionsEquivalenceLibraryperformance de la classe, en particulier lorsqu'il y a plusieurs exécutions de la passe deBasisTranslatortranspiler. -
L'argument
initial_statedu constructeur de la classeNLocalainsi que l'assignation directe à l'attributNLocal.initial_statedoit être unQuantumCircuitmaintenant. L'utilisation d'autres types pour cet argument et cet attribut n'est plus prise en charge. La prise en charge d'autres types a été supprimée lors de la publication de Qiskit Terra 0.18.0 (juillet 2021). -
Les tiroirs du tableau LaTeX (par exemple
array_to_latex,Statevector.draw('latex')) utilisent désormais la même fonction sympy que le tiroir de la convention ket. Cela signifie que certains chiffres peuvent être rendus différemment par rapport aux versions précédentes, mais que l'expérience sera plus cohérente. Par exemple, il peut identifier de nouveaux facteurs ou rationaliser les dénominateurs là où il ne le faisait pas auparavant. La valeur par défaut deprecisiona été modifiée de 5 à 10. -
La version du format QPY émise par
dump()est passé à la version 6. Cette nouvelle version du format est incompatible avec les versions précédentes et provoquera une erreur si l'on essaie de la charger avec un désérialiseur qui n'est pas capable de gérer la version 6 de QPY. Cette modification était nécessaire pour prendre en charge l'introduction deScalableSymbolicPulse, qui a été gérée en ajoutant un attributclass_name_sizeà l'en-tête des objets vidésSymbolicPulsevidés. -
La méthode
__hash__pour leSymbolicPulsea été supprimée. Ceci a été fait pour refléter la nature mutable (via l'assignation de paramètres) de cette classe qui pouvait entraîner des erreurs lors de l'utilisation deSymbolicPulsedans des situations où un objet hachable était nécessaire. Cela signifie que la méthode intégréehash()et l'utilisation deSymbolicPulsecomme clés dans les dictionnaires ou les membres d'un ensemble ne fonctionneront plus. -
Les noms des
Register(ce qui inclut les instances deQuantumRegisteretClassicalRegigster) ne sont plus contraints d'être des identifiants OpenQASM 2 valides. Cette mesure est prise car la restriction est trop stricte à mesure que Qiskit se découple de OpenQASM 2, et même la spécification de OpenQASM 3 n'est pas aussi restrictive. Si vous comptiez sur le fait que les registres aient des noms d'identificateurs valides OpenQASM 2, vous devrez commencer à échapper les noms. Une version simpliste de cette méthode pourrait être réalisée, par exemple, par :import re import string def escape(name: str) -> str: out = re.sub(r"\W", "_", name, flags=re.ASCII) if not out or out[0] not in string.ascii_lowercase: return "reg_" + out return out -
Les méthodes
QuantumCircuitu1,u2,u3, et leurs variantes contrôléescu1,cu3etmcu1ont été supprimées suite à leur dépréciation dans Qiskit Terra 0.16.0. Il s'agissait de supprimer les noms de portes qui étaient généralement spécifiques à IBM, en faveur de méthodes plus généralesp(),u(),cp()etcu(). Les classes de portesU1Gate,U2GateetU3Gatesont toujours disponibles pour être utilisées avecQuantumCircuit.append()les backends peuvent donc toujours prendre en charge les bases pour lesquelles ces portes sont explicitement indiquées. -
Les méthodes
QuantumCircuitles méthodescombineetextendont été supprimées suite à leur dépréciation dans Qiskit Terra 0.17.0. Cela s'explique par le fait que ces fonctions sont simplement des versions moins puissantes deQuantumCircuit.compose()qui devraient être utilisées à la place.La suppression de
extendsignifie également que les opérateurs+et+=ne sont plus définis pourQuantumCircuit. Au lieu de cela, vous pouvez utiliser les opérateurs&et&=, qui utilisent respectivementQuantumCircuit.compose(). -
Les fonctions précédemment obsolètes :
qiskit.circuit.measure.measure()etqiskit.circuit.reset.reset()ont été supprimées. Ces fonctions ont été supprimées dans la version de Qiskit Terra 0.19.0 (décembre 2021). Au lieu de cela, vous devez utiliser les boutonsQuantumCircuit.measure()etQuantumCircuit.reset()de l'objetQuantumCircuitque vous souhaitez ajouter unMeasureouResetà une opération. -
Les méthodes
ParameterViewprécédemment dépréciées et héritées desetont été supprimées deParameterView, le type retourné parQuantumCircuit.parameters. Les méthodes spécifiques qui ont été supprimées sont les suivantesadd()difference()difference_update()discard()intersection()intersection_update()issubset()issuperset()symmetric_difference()symmetric_difference_update()union()update()
ainsi qu'un soutien aux opérateurs Python :
ixor:^=isub:-=ior:|=
Ils ont été supprimés dans la version de Qiskit Terra 0.17.0 (avril 2021). Le type
ParameterViewest désormais un type de vue de séquence générale et ne prend plus en charge ces opérationsset. -
Les méthodes de conversion NetworkX précédemment obsolètes pour les méthodes de conversion
DAGCircuitetDAGDependencyont été supprimées :DAGCircuit.to_networkx(),DAGCircuit.from_networkx(), etDAGDependency.to_networkx()ont été supprimées. Ces méthodes ont été initialement dépréciées dans le cadre de la version de Qiskit Terra 0.21.0 (juin 2022). Qiskit utilise rustworkx comme bibliothèque de graphes depuis la version qiskit-terra 0.12.0 et depuis lors, la fonction de conversion NetworkX est un processus avec perte. Ils ont été ajoutés à l'origine pour permettre aux utilisateurs d'exploiter la bibliothèque d'algorithmes NetworkX’s afin de tirer parti de fonctionnalités qui ne sont pas présentes dansDAGCircuitet/ou rustworkx. Cependant, depuis lors, tantDAGCircuitet rustworkx ont mûri et offrent davantage de fonctionnalités, et la méthodeDAGCircuitest étroitement lié à rustworkx pour son fonctionnement et ces méthodes de conversion n'offraient qu'une fonctionnalité limitée et ont donc été supprimées. -
tweedleduma été supprimée en tant qu'exigence fondamentale de Qiskit Terra. La fonctionnalité fournie (qiskit.circuit.classicalfunction) est toujours disponible sitweedledumest installé manuellement, par exemple par :pip install tweedledumCe changement a été effectué parce que le développement de
tweedleduma ralenti au point de ne plus suivre les nouvelles versions de Python et du système d'exploitation, ce qui empêchait certains utilisateurs de Qiskit d'installer Qiskit. -
Les vérificateurs optionnels paresseux
HAS_MATPLOTLIB,HAS_PIL,HAS_PYLATEXetHAS_PDFTOCAIROne sont plus exposés à partir deqiskit.visualizationayant été dépréciés dans Qiskit Terra 0.21. L'emplacement canonique de ces vérificateurs (et de nombreux autres vérificateurs paresseux) est le suivantqiskit.utils.optionalset les quatre objets peuvent y être trouvés. -
L'argument
gatedu constructeur de la passe de transposition, précédemment déprécié, ainsi que l'attribut correspondant ont été supprimésDecomposeainsi que l'attribut correspondantDecompose.gateont été supprimés. L'argument et l'attribut ont été dépréciés dans le cadre de la version de Qiskit Terra 0.19.0 (décembre 2021). Au lieu de cela, il convient d'utiliser l'argumentgates_to_decomposepour le constructeur ainsi que l'attributDecompose.gates_to_decompose. L'argument et l'attributgates_to_decomposedevraient fonctionner de la même manière, mais ils portent un nom plus explicite et permettent également de spécifier des listes de portes au lieu de ne prendre en charge qu'une seule porte. -
L'argument
label, précédemment obsolète, pour le constructeur de l'élémentMCMTetMCMTVChaina été supprimé. Il a été supprimé à partir de la version de Qiskit Terra 0.19.0 (décembre 2021). L'utilisation de l'argumentlabelsur ces classes était un comportement non défini car elles sont des sous-classes deQuantumCircuitau lieu deInstruction. Dans ce cas, l'étiquette attribuée est généralement ignorée. Si vous devez attribuer une adresselabelà une instance deMCMTouMCMTVChainvous devez les convertir en une instance deGateavecto_gate()puis attribuer l'étiquette souhaitée à l'attributlabelattribut. Par exemple :from qiskit.circuit.library import MCMT, XGate mcmt_circuit = MCMT(XGate(), 3, 2) mcmt_gate = mcmt_circuit.to_gate() mcmt_gate.label = "Custom MCMT X" -
La dépendance
retworkxpour Qiskit a été supprimée et remplacée par la bibliothèquerustworkx. Il s'agit des mêmes paquets, maisrustworkxest le nouveau nom deretworkxqui a été renommé dans le cadre de la publication combinée de 0.12.0. Si vous utilisiez précédemment retworkx 0.12.0 avec Qiskit, alors vous avez déjà installé rustworkx (retworkx 0.12.0 était juste un shim de redirection pour la compatibilité ascendante). Ce changement a été effectué pour migrer vers le nouveau nom du paquet qui sera le seul paquet pris en charge à l'avenir. -
Le comportement par défaut de la passe du compilateur
SabreLayouta changé. La passe n'est plus unAnalysisPasset, par défaut, calculera la disposition initiale, l'appliquera au circuit, et exécutera également la commandeSabreSwapen interne et appliquera le mappage de permutation et définira le jeu de propriétésfinal_layoutavec la permutation causée par les insertions de permutation. Cela signifie que pour les utilisateurs qui utilisentSabreLayoutdans le cadre d'unPassManagerdevront ajuster le gestionnaire de passe pour en tenir compte (à moins qu'ils n'aient défini l'argumentrouting_passpourSabreLayout). Ce changement a été effectué dans le but d'améliorer la qualité des résultats, la qualité de l'agencement et du routage étant fortement liée et la qualité de l'agencement et du routage étant fortement liéeSabreLayoutpour calculer quelle semence fournit les meilleurs résultats, il faut effectuer à la fois l'agencement et le routage. Vous pouvez ajuster l'utilisation de votre gestionnaire de laissez-passer personnalisé de trois manières différentes. La première consiste à éviter d'utiliser l'intégration dans votre gestionnaire de presets. Si vous utilisiez auparavant quelque chose comme :from qiskit.transpiler import PassManager from qiskit.transpiler.preset_passmanagers import common from qiskit.transpiler.passes.SabreLayout pm = PassManager() pm.append(SabreLayout(coupling_map) pm += common.generate_embed_passmanager(coupling_map)pour calculer la disposition et l'appliquer (ce qui était généralement suivi par le routage), vous pouvez ajuster l'utilisation pour qu'elle soit tout simplement :
from qiskit.transpiler import PassManager from qiskit.transpiler.preset_passmanagers import common from qiskit.transpiler.passes.SabreLayout pm = PassManager() pm.append(SabreLayout(coupling_map)comme
SabreLayoutappliquera la mise en page et vous n'aurez plus besoin de l'étape d'intégration. Vous pouvez également spécifier l'argumentrouting_pass, qui ramènera le système à son comportement précédentSabreLayoutà son comportement précédent. Par exemple, si vous voulez exécuterSabreLayouttel qu'il était exécuté dans les versions précédentes, vous pouvez faire quelque chose comme :from qiskit.transpiler.passes import SabreSwap, SabreLayout routing_pass = SabreSwap( coupling_map, "decay", seed=seed, fake_run=True ) layout_pass = SabreLayout(coupling_map, routing_pass=routing_pass, seed=seed)qui aura
SabreLayouts'exécutera comme une passe d'analyse et définira simplement l'ensemble de propriétéslayout. La dernière approche consiste à utiliser l'argumentskip_routingsurSabreLayout, lorsque cet argument est défini surTrue, il n'est pas nécessaire d'appliquer la disposition trouvée et d'insérer les portes de permutation du routage. Cependant, cela entraîne une pénalité en termes de temps d'exécution, carSabreLayoutcalcule toujours le routage et n'utilise pas ces données. Les deux premières approches décrites n'entraînent pas de frais généraux supplémentaires. -
Les tracés calculés par la passe
SabreLayout(lorsqu'il est exécuté sans l'argumentrouting_pass) avec une valeur de départ fixe peuvent changer par rapport aux versions précédentes. Cela est dû à l'utilisation d'un nouveau générateur de nombres aléatoires dans le cadre de la réécriture de la passeSabreLayouten Rust, ce qui a considérablement amélioré les performances. Si vous avez besoin d'une sortie cohérente, vous pouvez exécuter la passe dans une version antérieure de Qiskit et utiliser l'outilqiskit.qpypour sauvegarder le circuit et le charger ensuite avec la version actuelle. Vous pouvez également définir explicitement l'argumentrouting_passcomme une instance deSabreSwappour refléter le comportement précédent deSabreLayout:from qiskit.transpiler.passes import SabreSwap, SabreLayout routing_pass = SabreSwap( coupling_map, "decay", seed=seed, fake_run=True ) layout_pass = SabreLayout(coupling_map, routing_pass=routing_pass, seed=seed)qui reflètera le comportement de la passe dans la version précédente. Notez que si vous utilisiez l'argument
swap_trialssurSabreLayoutdans les versions précédentes lors de l'adaptation de l'utilisation à cette forme, vous devrez définir l'argumenttrialssur le constructeurSabreSwapsi vous souhaitez conserver la sortie précédente avec une graine fixe. -
Le circuit exact renvoyé par
qiskit.circuit.random.random_circuitpour une graine donnée a changé. Ceci est dû à l'amélioration de l'efficacité de la génération interne de nombres aléatoires pour la fonction. -
La version requise pour le paquet de fonctionnalités optionnelles
qiskit-toqm, installable viapip install qiskit-terra[toqm], a été mise à jour de la version0.0.4à0.1.0. Pour utiliser la méthode de routagetoqmavectranspile()vous devez maintenant utiliser qiskit-toqm version0.1.0ou plus récente. Les versions antérieures ne peuvent plus être découvertes par le transpondeur. -
La sortie
QuasiDistributionde la méthodeSampler.runa été mise à jour pour filtrer tous les états dont la probabilité est nulle. Si un état valide est absent de la sortie du dictionnaire, on peut supposer qu'il a une probabilité de 0. Auparavant, tous les résultats possibles pour un nombre donné de bits (par exemple, pour un résultat de 3 bits000,001,010,011,100,101,110, et111) même si la probabilité d'un état donné était de 0. Cette modification a été apportée pour réduire la taille de la sortie, car pour un grand nombre de bits, la taille de la sortie pouvait être très importante. En outre, le filtrage des résultats à probabilité nulle rend la sortie cohérente avec d'autres implémentations deBaseSampler. -
Le comportement du constructeur d'impulsions lorsqu'un
Schedulea été amélioré. Les calendriers appelés sont convertis en interne enScheduleBlocket le mécanisme de référence est toujours appliqué au lieu d'ajouter les programmes enveloppés par l'instructionCall. Il convient de noter que le bloc converti ne récupère pas nécessairement le contexte d'alignement d'origine. Il s'agit simplement d'une séquence d'instructions d'impulsions alignées ASAP avec des intervalles de temps absolus. Il s'agit d'une mise à jour de la représentation interne des programmes d'impulsion appelés, et donc d'aucune modification de l'API. Toutefois, lesCallinstruction etSchedulene figurent plus dans le programme d'impulsion du constructeur. Cette modification garantit que les blocs de programmation générés sont toujours compatibles avec le QPY. Si vous filtrez les instructions du calendrier de sortie parCallvous pouvez accéder à l'élémentScheduleBlock.referencespour récupérer le programme appelé. -
RZXCalibrationBuilderetRZXCalibrationBuilderNoEchoont été mis à jour pour générer des fichiersScheduleBlock. Cette modification garantit que les circuits transposés sont toujours compatibles avec le QPY. Si vous utilisez directement la méthoderescale_cr_inst()à partir d'un autre programme ou d'une sous-classe de passe pour réévaluer l'impulsion de résonance croisée de l'appareil, cette méthode est maintenant transformée en macro de construction d'impulsion, et vous devez utiliser cette méthode dans le contexte de la construction d'impulsion pour adopter la nouvelle version. L'appel de méthode injecte une instruction de lecture dans le programme d'impulsion contextuel, au lieu de renvoyer une instruction de lecture avec l'impulsion étiréePlayavec l'impulsion étirée.
Remarques concernant la dépréciation
-
Le support pour l'exécution de Qiskit avec Python 3.7 a été déprécié et sera supprimé dans la version qiskit-terra 0.25.0. Cela signifie qu'à partir de la version 0.25.0, vous devrez mettre à jour la version Python que vous utilisez vers Python 3.8 ou une version supérieure.
-
La classe
LinearFunctionsSynthesisest désormais obsolète et sera supprimée dans une prochaine version. Elle a été remplacée par la classe plus généraleHighLevelSynthesisplus générale, qu'il convient d'utiliser à la place. Par exemple, vous pouvez créer une instance deHighLevelSynthesisqui se comportera de la même manière queLinearFunctionSynthesiswith :from qiskit.transpiler.passes import HighLevelSynthesis from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig HighLevelSynthesis( HLSConfig( linear_function=[("default", {})], use_default_on_unspecified=False, ) ) -
La prise en charge du passage de listes de valeurs d'arguments à la fonction
transpile()est obsolète et sera supprimée dans la version 0.25.0. Cela permet de réduire considérablement les frais généraux liés à l'exécution parallèle pour la transposition de plusieurs circuits à la fois. Si vous utilisez cette fonctionnalité actuellement, vous pouvez appelertranspile()plusieurs fois. Par exemple, si vous faisiez auparavant quelque chose comme.. :from qiskit.transpiler import CouplingMap from qiskit import QuantumCircuit from qiskit import transpile qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) qc.measure_all() cmaps = [CouplingMap.from_heavy_hex(d) for d in range(3, 15, 2)] results = transpile([qc] * 6, coupling_map=cmaps)au lieu de cela, vous devriez exécuter quelque chose comme :
from itertools import cycle from qiskit.transpiler import CouplingMap from qiskit import QuantumCircuit from qiskit import transpile qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) qc.measure_all() cmaps = [CouplingMap.from_heavy_hex(d) for d in range(3, 15, 2)] results = [] for qc, cmap in zip(cycle([qc]), cmaps): results.append(transpile(qc, coupling_map=cmap))Vous pouvez également utiliser
parallel_map()oumultiprocessingde la bibliothèque standard Python si vous souhaitez exécuter cette opération en parallèle. -
L'ancienne version du tiroir à impulsions présente sur le site
qiskit.visualization.pulseest obsolète et sera supprimée dans une prochaine version. Il s'agit notamment des classesScheduleDraweret :class`WaveformDrawer`. Ce module a été remplacé par le tiroirqiskit.visualization.pulse_v2et l'API utilisateur typiquepulse_drawer()etPulseBlock.draw()ont déjà été mis à jour en interne pour utiliserqiskit.visualization.pulse_v2. -
La méthode
pulse.Instruction.draw()est obsolète et sera supprimée dans une prochaine version. La nécessité de cette méthode a été remplacée par le tiroirqiskit.visualization.pulse_v2qui n'exige pas que les objetsInstrucionaient leur propre méthode de dessin. Si vous avez besoin de dessiner une instruction d'impulsion, vous devriez plutôt utiliser la fonctionpulse_drawer()à la place. -
L'importation
qiskit.circuit.qpy_serializationest obsolète, car QPY a été promu au niveau supérieur. Vous devez importer les mêmes objets à partir deqiskit.qpyau lieu de cela. L'ancien chemin sera supprimé dans un futur Qiskit Terra. -
L'objet
qiskit.IBMQest obsolète. Cet objet alias redirige paresseusement l'accès aux attributs versqiskit.providers.ibmq.IBMQ. Comme le paquetqiskit-ibmq-providera été remplacé par le paquetqiskit-ibm-providerqui a son propre espace de noms, le maintien de cet alias n'est plus pertinent avec le nouveau paquet. Si vous utilisiez l'aliasqiskit.IBMQ, vous devez mettre à jour votre utilisation pour utiliser directementqiskit.providers.ibmq.IBMQ(et envisager de migrer versqiskit-ibm-provider, voir le guide de migration pour plus de détails). -
Plusieurs méthodes publiques des convertisseurs pulse Qobj ont été dépréciées et ne pourront plus être appelées directement dans une prochaine version. La liste des méthodes est la suivante :
Sur
InstructionToQobjConverter,convert_acquire()convert_bundled_acquires()convert_set_frequency()convert_shift_frequency()convert_set_phase()convert_shift_phase()convert_delay()convert_play()convert_snapshot()
Sur
QobjToInstructionConverter,convert_acquire()convert_set_phase()convert_shift_phase()convert_set_frequency()convert_shift_frequency()convert_delay()bind_pulse()convert_parametric()convert_snapshot()
Au lieu d'appeler directement l'une de ces méthodes, elles seront implicitement sélectionnées lorsqu'une instance de convertisseur est appelée directement. Par exemple :
converter = QobjToInstructionConverter() converter(pulse_qobj) -
Les fonctions
qiskit.visualization.state_visualization.num_to_latex_ket()etqiskit.visualization.state_visualization.num_to_latex_terms()sont obsolètes et seront supprimées dans une prochaine version. Ces fonctions étaient principalement utilisées en interne par la sortie LaTeX deStatevector.draw()etDensityMatrix.draw()qui n'utilise plus ces fonctions et s'appuie sur sympy à la place. Si vous utilisiez ces fonctions, vous devriez plutôt utiliser les fonctions nsimplify() latex() de Sympy. -
La méthode
Register.qasm()est obsolète et sera supprimée dans une prochaine version. Cette méthode se retrouve dans les sous-classesQuantumRegisteretClassicalRegister. La dépréciation est due au fait que la méthodeqasm()promeut une vision erronée de la partie responsable de la conversion sûre vers OpenQASM 2; un objet seul n'a pas le contexte nécessaire pour fournir une conversion sûre, par exemple si son nom est incompatible après l'avoir échappé pour produire un identificateur valide. -
L'expression régulière classe-variable
Register.name_formatest obsolète et sera supprimée dans une prochaine version. Les noms des registres peuvent désormais être n'importe quelle chaîne valide Python, de sorte que l'expression régulière n'a plus d'utilité. -
Les fonctions
qiskit.quantum_info.synthesis.decompose_clifford()etqiskit.quantum_info.synthesis.decompose_cnot_dihedral()sont obsolètes et seront supprimées dans une prochaine version. Elles sont remplacées par les deux fonctionsqiskit.synthesis.synth_clifford_full()etqiskit.synthesis.synth_cnotdihedral_full()respectivement.
Corrections des erreurs
-
Correction d'un problème dans la méthode
PauliOp.adjoint()qui renvoyait la bonne valeur pour les Paulis à coefficients complexes, par exemple :PauliOp(Pauli("iX")). Correction #9433. -
Correction d'un problème avec les algorithmes d'estimation d'amplitude dans le module
qiskit.algorithms.amplitude_estimators(voiramplitude_estimators) pour l'utilisation de primitives construites à partir de la primitive abstraiteBaseSampler(telles queSampleretBackendSampler). Auparavant, les résultats des mesures étaient étendus à plus de bits que ceux réellement mesurés, ce qui, pour les oracles comportant plus d'un qubit, entraînait des erreurs potentielles dans la détection des "bons" états quantiques des oracles. -
Correction d'un problème où les méthodes
QuantumCircuit.add_calibrations()etDAGCircuit.add_calibrations()avaient un comportement différent dans la logique de formatage des paramètres. Auparavant,DAGCircuit.add_calibrations()essayait d'intégrer chaque paramètre dansfloat,QuantumCircuit.add_calibrations()utilisait les paramètres donnés tels quels. Cela pourrait provoquer une erreur lors de l'exécution du programmetranspile()sur unQuantumCircuitavec des portes à impulsion, car les paramètres des calibrations pourraient être conservés en tant qu'objetsParameterExpresion. -
Correction d'un problème de désérialisation dans les fichiers (
qiskit.qpy)load()de QPY où les circuits contenant des portes de classeMCXGate,MCXGrayCode,MCXRecursive,, etMCXVChainne parviendraient pas à se désérialiser. Correction #9390. -
Correction d'un problème dans
TensoredOp.to_matrix()où le coefficient global de l'opérateur était multiplié à la matrice finale plus d'une fois. Désormais, le coefficient global est correctement appliqué, indépendamment du nombre d'opérateurs ou d'états tensoriés. Correction #9398. -
Le résultat de la méthode
run()de la classeBackendSamplerdéfinit maintenant les attributsshotsetstddev_upper_boundde l'objet retournéQuasiDistribution. Auparavant, ces attributs étaient absents, ce qui empêchait tout post-traitement des résultats. Corrigé #9311 -
La méthode de l'exportateur OpenQASM 2
QuantumCircuit.qasm()émettra désormais par défaut des nombres en virgule flottante de plus haute précision pour les paramètres de la porte. En outre, une limite plus stricte ( au lieu de ) est utilisée pour vérifier si un paramètre donné est proche d'une fraction/puissance de . Correction #7166. -
Correction de la prise en charge dans le module
primitivespour l'exécution d'objetsQuantumCircuitavec des instructions de flux de contrôle (par ex.IfElseOp). Auparavant, les classes de baseBaseSampleretBaseEstimatorne pouvaient pas normaliser correctement de tels circuits. Toutefois, l'exécution de ces circuits dépend de la mise en œuvre particulière des instructions primitives de flux de contrôle. Il s'agit simplement d'un support fixe permettant à une implémentation particulière deBaseSamplerouBaseEstimatord'utiliser des instructions de flux de contrôle. -
Correction d'un problème avec la méthode
PauliOp.matmul()qui renvoyait des résultats incorrects aveciI. Correction #8680. -
Correction d'un problème avec la classe Approximate Quantum Compiler (
AQC) qui lui faisait renvoyer un circuit incorrect lorsque l'unité d'entrée avait un déterminant de -1. Corrigé #9327 -
Correction d'un problème avec la méthode
QuantumCircuit.compose()qui rejetait incorrectement les spécificateurs qubit ou clbit valides. Cette erreur a été corrigée de sorte que la méthode accepte désormais le même ensemble de spécificateurs qubit et clbit que d'autres méthodes telles queQuantumCircuittelles queappend(). Correction #8691. -
Correction d'un problème avec la méthode
QuantumCircuit.compose()qui faisait correspondre de manière incorrecte les registres dans les conditions du circuit donné avec les registres complets de la base. Auparavant, le mappage était très imprécis; les bits utilisés dans chaque condition n'étaient pas soumis au mappage, et une tentative imprécise était faite pour trouver un registre correspondant. Cela pourrait également entraîner l'extension d'une condition sur un registre plus petit à un registre plus grand, ce qui n'est pas une transformation valide. Désormais, une condition portant sur un seul bit ou un registre sera composée de manière à porter précisément sur les bits définis par l'argumentclbits. Un nouveau registre d'aliasing sera ajouté au circuit de base pour faciliter cette opération, si nécessaire. Correction #6583. -
Correction d'un problème avec la fonction
transpile()lorsqu'elle est exécutée avecoptimization_levelayant pour valeur1,2, ou3et qu'aucun argumentbackend,basis_gates, outargetn'est spécifié. Si le circuit d'entrée comportait des séries de portes à qubit unique pouvant être simplifiées, le circuit de sortie ne serait pas aussi optimisé que possible, car ces séries de portes à qubit unique n'auraient pas été supprimées. Cela aurait pu être corrigé précédemment en spécifiant les argumentsbackend,basis_gates, outargetlors de l'appel de la fonctiontranspile()mais maintenant la sortie sera aussi simplifiée qu'elle peut l'être sans connaître les portes cibles autorisées. Corrigé #9217 -
Correction d'un problème avec la fonction
transpile()lorsqu'elle est exécutée avecoptimization_level=3et qu'aucun argumentbackend,basis_gatesoutargetn'est spécifié. Si le circuit d'entrée contenait des blocs de 2 qubits équivalents à une matrice d'identité, le circuit de sortie ne serait pas aussi optimisé que possible et contiendrait toujours ce bloc d'identité. Cela aurait pu être corrigé précédemment en spécifiant les argumentsbackend,basis_gates, outargetlors de l'appel de la fonctiontranspile()mais maintenant la sortie sera aussi simplifiée qu'elle peut l'être sans connaître les portes cibles autorisées. Corrigé #9217 -
Correction d'un problème avec
LinCombSamplerGradientqui pouvait soulever une erreur lorsqu'il était exécuté avec la classeSamplerdeqiskit-aer. -
Correction d'un problème avec
NumPyEigensolveret par extensionNumPyMinimumEigensolveroù la résolution des sous-classes deBaseOperatorautres queOperatorprovoquait une erreur. -
Correction d'un problème dans la sortie des métadonnées de
primitivesoù la liste faisait des copies par référence et où tous les éléments étaient mis à jour avec la même valeur à chaque itération. -
Correction d'un problème avec
QobjToInstructionConverterlorsque plusieurs backends sont appelés et qu'ils ont accidentellement le même nom de pulse dans la bibliothèque de pulse. Il s'agissait d'un cas particulier qui ne pouvait se produire que lorsqu'une instance de convertisseur était réutilisée par plusieurs backends (ce qui n'était pas un schéma d'utilisation typique). -
Correction d'un problème avec la classe
PVQDoù la fonction de perte élevait de manière incorrecte la fidélité au carré. Cette erreur a été corrigée afin que la fonction de perte corresponde à la définition de l'algorithme original. -
Correction d'un bogue dans QPY (
qiskit.qpy) où les circuits contenant des registres dont les bits se trouvaient dans le circuit après les bits libres ne parvenaient pas à se désérialiser. Voir #9094. -
La classe
TwoQubitWeylDecompositionest désormais compatible avec le protocolepickle. Auparavant, la désérialisation échouait et soulevait un problèmeTypeError. Voir #7312. -
Correction d'un problème avec la méthode
LocalReadoutMitigator.quasi_probabilities()où l'argumentshotsn'était pas utilisé. Il est maintenant utilisé pour définir le nombre de tirs dans l'objet de renvoi. -
Correction d'une régression dans la construction d'objets
Cliffordobjets à partir deQuantumCircuitsqui contiennent d'autresCliffordobjets. -
Correction d'un problème avec la classe
TwoQubitWeylDecomposition(et ses sous-classes) pour permettre à la bibliothèque standard Pythonpicklede sérialiser ces classes. Ceci corrige partiellement #7312 -
QuantumCircuit.qasm()échappe désormais correctement les noms de portes et de registres qui entrent en conflit avec les mots-clés réservés de OpenQASM 2. Corrige #5043. -
Correction d'un problème dans le
RZXCalibrationBuilderoù la séquence d'impulsions ECR était mal alignée. Correction #9013. -
Correction d'un problème avec la fonction
pulse_drawer()où, dans certains cas, la visualisation de sortie omettait certains canaux d'une programmation. Correction #8981.
Aer 0.11.2
Pas de modification
IBM 0.19.2 du fournisseur Q
Pas de modification