Skip to main content
IBM Quantum Platform

Notes de publication de Qiskit 0.39


0.39.5

Terra 0.22.4

Prélude

Qiskit Terra 0.22.4 est une version mineure qui corrige quelques bugs identifiés dans la série 0.22.

Corrections des erreurs

  • Correction d'un bug dans BackendSampler qui provoquait une erreur si sa méthode run() était appelée deux fois séquentiellement.

  • Correction de deux bogues dans le ComposedOp où la méthode ComposedOp.to_matrix() ne fournissait pas les résultats corrects pour les compositions avec StateFn et pour les compositions avec un coefficient global. Correction #9283.

  • Correction du problème dans lequel les primitives, Sampler et Estimatorne fonctionnaient pas lorsqu'on leur passait un circuit avec numpy.ndarray comme paramètre.

  • Correction d'un bogue dans SamplingVQE où l'argument aggregation n'avait pas d'effet. La fonction d'agrégation et, avec elle, la valeur d'espérance CVaR peuvent maintenant être correctement spécifiées.

  • Correction d'un bug de performance où SamplingVQE évaluait les énergies des états propres de manière lente.

  • Correction de l'auto-évaluation des paramètres bêta en VQDa ajouté la prise en charge des entrées SparsePauliOp et a corrigé la fonction d'évaluation de l'énergie pour tirer parti de l'exécution asynchrone des primitives, en ne récupérant les résultats du travail qu'une fois que les deux travaux ont été soumis.

  • Correction d'un problème avec les Statevector.probabilities_dict() et DensityMatrix.probabilities_dict() qui renvoyaient des résultats incorrects pour les systèmes non quantiques lorsque l'argument qargs était spécifié. Corrigé #9210

  • Correction de la gestion de certains classmethodpar wrap_method() dans Python 3.11. Auparavant, dans Python 3.11, wrap_method enveloppait la fonction non liée associée à classmethod et échouait lorsqu'elle était invoquée parce que l'objet de classe habituellement lié à classmethod n'était pas transmis à la fonction. À partir de Python 3.11.1, ce problème a affecté QiskitTestCase, l'empêchant d'être importé par d'autres codes de test. Correction #9291.

Aer 0.11.2

Pas de modification

IBM 0.19.2 du fournisseur Q

Pas de modification


0.39.4

Terra 0.22.3

Pas de modification

Aer 0.11.2

Nouvelles fonctions

  • Ajout du support pour l'exécution de Qiskit Aer avec le support de Python 3.11.

Problèmes connus

  • Correction de deux bogues dans AerStatevector. AerStatevector utilise les instructions mc*, qui ne sont pas activées dans la méthode matrix_product_state. Ce commit modifie AerStatevector pour ne pas utiliser MC* et utiliser H, X, Y, Z, U et CX. AerStatevector échoue également si une instruction est décomposée en QuantumCircuit. Cet engagement permet une telle instruction.

Corrections des erreurs

  • Correction de la prise en charge, dans la méthode AerSimulator.from_backend() , de l'instanciation d'une instance AerSimulator à partir d'un objet a BackendV2 à partir d'un objet a. Auparavant, une tentative d'utilisation de AerSimulator.from_backend() avec un objet BackendV2 aurait généré un message AerError indiquant que ce n'était pas pris en charge.

  • Correction d'un bogue où NoiseModel.from_backend() avec un objet BackendV2 peut générer un modèle de bruit avec un nombre excessif de QuantumError s sur des instructions non-Gate alors que, par exemple, seul ReadoutError s devrait être suffisant pour les mesures. Ce commit met à jour NoiseModel.from_backend() avec un objet BackendV2 afin qu'il renvoie le même modèle de bruit que celui appelé avec l'objet BackendV1 correspondant. En d'autres termes, le modèle de bruit résultant ne contient pas de QuantumError s sur les mesures et il peut contenir uniquement des erreurs de relaxation thermique sur d'autres instructions non liées aux portes, telles que les réinitialisations. Notez qu'il contient toujours ReadoutError s sur les mesures.

  • Correction d'un bogue dans NoiseModel.from_backend() où l'utilisation de temperature kwarg avec une valeur autre que celle par défaut calculait incorrectement la population de l'état excité pour la température spécifiée. Auparavant, il y avait un facteur supplémentaire de 2 dans le calcul de la distribution de Boltzman, ce qui entraînait une valeur inférieure incorrecte pour la population de l'état excité.

  • Correction d'une logique incorrecte dans le compilateur de flux de contrôle qui pouvait permettre à des instructions non liées d'apparaître "à l'intérieur" des corps de flux de contrôle pendant l'exécution, ce qui entraînait des résultats incorrects. Par exemple, précédemment :

    from qiskit import QuantumCircuit
    from qiskit_aer import AerSimulator
    
    backend = AerSimulator(method="statevector")
    
    circuit = QuantumCircuit(3, 3)
    circuit.measure(0, 0)
    circuit.measure(1, 1)
    
    with circuit.if_test((0, True)):
        with circuit.if_test((1, False)):
            circuit.x(2)
    
    with circuit.if_test((0, False)):
        with circuit.if_test((1, True)):
            circuit.x(2)
    
    circuit.measure(range(3), range(3))
    print(backend.run(circuit, method=method, shots=100).result())

    s'imprimerait à l'adresse {'010': 100} , car les opérations de flux de contrôle imbriquées sauteraient accidentellement la première porte X du qubit 2, qui aurait dû être exécutée.

  • Correction d'un bogue à cause duquel NoiseModel.from_backend() affiche des avertissements verbeux lorsqu'il fournit un backend qui rapporte des paramètres de dispositif non physiques tels que T2 > 2 * T1 en raison d'erreurs statistiques dans leur estimation. Ce commit supprime ces avertissements car ils ne sont pas exploitables par les utilisateurs dans le sens où il n'y a pas d'autres moyens que de les tronquer aux limites théoriques comme cela est fait dans le module noise.device . Voir le numéro 1631 pour plus de détails sur le bogue corrigé.

  • Il s'agit d'une correction pour le simulateur de vecteur d'état du GPU. La distribution de chunk a essayé d'allouer toute la mémoire libre sur le GPU, mais cela provoque une erreur d'allocation de mémoire. Ce correctif alloue donc 80 % de la mémoire libre. Cela fixe également la taille de la mémoire tampon de la matrice lorsque l'échantillonnage du bruit est appliqué.

  • Il s'agit d'un correctif de AerState fonctionnant avec le blocage du cache. AerState un transpileur d'Aer mal configuré pour le blocage du cache, et son algorithme d'échange de qubits a alors mal fonctionné. Ce correctif corrige AerState pour qu'il utilise ce transpileur. Plus précisément, après la transpilation, une carte de qubits échangés est ramenée à la carte d'origine en utilisant AerState. Cette correction est nécessaire pour que AerStatevector puisse utiliser plusieurs GPU.

  • Il s'agit d'un correctif pour AerStatevector. Il n'a pas été possible de créer une instance AerStatevector directement à partir du vecteur d'État de Terra. Ce correctif permet d'utiliser un vecteur d'état en tant qu'entrée AerStatevector’s.

  • SamplerResult.quasi_dists contiennent les données relatives au nombre de qubits. QuasiDistribution.binary_probabilities() renvoie des chaînes de bits de longueur correcte.

  • Auparavant, la graine n'est pas initialisée dans AerStatevector et les résultats échantillonnés sont toujours les mêmes. Avec cet engagement, une graine est initialisée pour chaque échantillonnage et les résultats de l'échantillonnage peuvent être variés.

IBM 0.19.2 du fournisseur Q

Pas de modification


0.39.3

Terra 0.22.3

Prélude

Qiskit Terra 0.22.3 est une version mineure qui corrige quelques bugs dans la série 0.22.

Corrections des erreurs

  • AdaptVQE indique désormais correctement qu'il prend en charge les opérateurs auxiliaires.

  • Les tiroirs du circuit (QuantumCircuit.draw() et circuit_drawer()) n'émettront plus d'avertissement concernant le paramètre cregbundle lors de l'utilisation des arguments par défaut, si le contenu du circuit exige que tous les bits soient dessinés individuellement. Ce problème était le plus susceptible d'apparaître lorsque l'on essayait de dessiner des circuits avec des opérations de flux de contrôle de type nouveau.

  • Correction d'un bogue provoquant l'échec de QNSPSA échouait lorsque max_evals_grouped avait une valeur supérieure à 1.

  • Correction d'un problème avec la passe SabreSwap qui faisait que la sortie de plusieurs exécutions de la passe sans l'argument seed spécifié réutilisait la même graine de générateur de nombres aléatoires entre les exécutions au lieu d'utiliser des graines différentes. Auparavant, des résultats identiques étaient renvoyés d'une exécution à l'autre, même lorsqu'aucune adresse seed n'était spécifiée.

  • Correction d'un problème avec les classes primitives, BackendSampler et BackendEstimatoroù les instances ne pouvaient pas être sérialisées avec pickle. En général, il n'est pas garanti que ces classes soient sérialisables en tant que BackendV2 et les instances BackendV1 ne sont pas tenues d'être sérialisables (et ne le sont souvent pas), mais les définitions de classe de BackendSampler et BackendEstimator n'empêchent plus l'utilisation de pickle.

  • La méthode pulse.Instruction.draw() aboutira maintenant, comme précédemment. Cette méthode est obsolète et aucun remplacement n'est prévu, mais elle devrait encore fonctionner pendant la période d'obsolescence.

Aer 0.11.1

Pas de modification

IBM 0.19.2 du fournisseur Q

Pas de modification


0.39.2

Terra 0.22.2

Prélude

Qiskit Terra 0.22.2 est une version mineure de correction de bogues, et marque la première prise en charge officielle de Python 3.11.

Corrections des erreurs

  • Correction d'un problème avec les classes primitives du backend BackendSampler et BackendEstimator qui empêchait l'exécution avec une instance BackendV1 qui n'a pas de champ max_experiments défini dans son fichier BackendConfiguration.

  • Correction d'un bug dans la passe VF2PostLayout lors de la transpilation pour les backends avec une définition de Targetdéfini, où le graphe d'interaction était construit de manière incorrecte. Cela pourrait entraîner des durées d'exécution excessives, le graphe étant beaucoup plus complexe que nécessaire.

  • L'analyseur d'expressions Pulse ne devrait plus se bloquer périodiquement lorsqu'il est appelé depuis les notebooks Jupyter. Il s'agit d'éviter une deepycopy interne d'un objet récursif qui semble être particulièrement difficile à évaluer pour la mémorisation.

Aer 0.11.1

Pas de modification

IBM 0.19.2 du fournisseur Q

Pas de modification


0.39.1

Terra 0.22.1

Prélude

Qiskit Terra 0.22.1 est une version de correction de bugs, adressant quelques problèmes mineurs identifiés depuis la version 0.22.0.

Remarques concernant la dépréciation

  • Le kwarg pauli_list de pauli_basis() a été déprécié car pauli_basis() renvoie toujours un PauliList. Cet argument a été supprimé prématurément de Qiskit Terra 0.22.0, ce qui a entraîné une rupture de compatibilité pour les utilisateurs qui exploitaient le site pauli_list``argument. Now, the argument has been restored but will emit a ``DeprecationWarning lorsqu'il était utilisé. Si elle est utilisée, elle n'a aucun effet car depuis Qiskit Terra 0.22.0 a PauliList est toujours retourné.

Corrections des erreurs

  • Correction du BarrierBeforeFinalMeasurements transpiler lorsqu'il y a des conditions sur les loose Clbitimmédiatement avant la couche de mesure finale. Auparavant, l'opération échouait au motif que le bit n'était pas présent dans un circuit temporaire interne. Corrigé #8923

  • Les vérificateurs d'égalité pour QuantumCircuit et DAGCircuit (avec des objets du même type) gèrent désormais correctement les conditions sur des bits uniques. Auparavant, ces contrôles produisaient des faux négatifs pour l'égalité, car les bits utilisaient des contrôles d'égalité "exacts" au lieu des contrôles "sémantiques" dont bénéficient le reste des propriétés des instructions de circuit.

  • Traitement fixe des bits classiques dans StochasticSwap avec le flux de contrôle. Auparavant, les opérations de flux de contrôle étaient étendues pour contenir tous les bits classiques du circuit extérieur et n'étaient plus contractées, ce qui entraînait un décalage entre le nombre de bits de contrôle dont l'instruction déclarait avoir besoin et le nombre réel qui lui était fourni. Corrigé #8903

  • Correction de la gestion des instructions définies globalement pour la classe Target classe. Auparavant, deux méthodes, operations_for_qargs() et operation_names_for_qargs() ignoraient ou traitaient de manière incorrecte les opérations idéales définies globalement et présentes dans la cible. Par exemple :

    from qiskit.transpiler import Target
    from qiskit.circuit.library import CXGate
    
    target = Target(num_qubits=5)
    target.add_instruction(CXGate())
    names = target.operation_names_for_qargs((1, 2))
    ops = target.operations_for_qargs((1, 2))

    renverra désormais {"cx"} pour names et [CXGate()] pour ops au lieu de renvoyer KeyError ou un message vide.

  • Correction d'un problème dans la méthode Target.add_instruction() qui acceptait un argument avec un nombre invalide de qubits dans l'argument properties . Par exemple :

    from qiskit.transpiler import Target
    from qiskit.circuit.library import CXGate
    
    target = Target()
    target.add_instruction(CXGate(), {(0, 1, 2): None})

    Cette opération génère désormais correctement un message TranspilerError au lieu de provoquer des problèmes d'exécution lors de l'interaction avec la cible. Corrigé #8914

  • Correction d'un problème avec la fonction de visualisation plot_state_hinton() qui entraînait un axe mal placé et décalé par rapport au tracé réel. Corrigé #8446 <https://github.com/Qiskit/qiskit/issues/8446>

  • Correction de la sortie de la fonction plot_state_hinton() afin que les étiquettes d'état soient ordonnées correctement et que l'image corresponde à l'ordre naturel de la matrice. Corrigé #8324

  • Correction d'un problème avec les classes primitives, BackendSampler et BackendEstimator lors de l'exécution sur des backends qui ont un nombre limité de circuits dans chaque travail. Tous les backends ne prennent pas en charge une taille de lot illimitée (la plupart des backends matériels ne le font pas) et, auparavant, les classes primitives du backend auraient potentiellement envoyé de manière incorrecte plus de circuits que le backend n'en prenait en charge. Ceci a été corrigé de manière à ce que BackendSampler et BackendEstimator répartissent les circuits en plusieurs travaux si le backend dispose d'un nombre limité de circuits par travail.

  • Correction d'un problème avec la classe BackendEstimator où le fait de définir une option d'exécution nommée monitor avec une valeur évaluée comme True aurait incorrectement déclenché un moniteur de travail qui ne fonctionnait que sur les backends du paquetage qiskit-ibmq-provider . Cette option a été supprimée afin que vous puissiez utiliser l'option d'exécution monitor si nécessaire, sans que cela ne pose de problème.

  • Correction d'un problème avec la méthode Target.build_coupling_map() qui renvoyait incorrectement None pour un objet Target avec un mélange d'instructions idéales globalement disponibles et d'instructions ayant des contraintes de qubits. Dans ce cas, la fonction Target.build_coupling_map() renverra une carte de couplage pour l'instruction contrainte (sauf s'il s'agit d'une opération à 2 qubits qui renverra None parce que globalement il n'y a pas de contrainte de connectivité). Corrigé #8971

  • Correction d'un problème avec l'attribut Target.qargs qui renvoyait incorrectement None pour un objet Target contenant une instruction idéale disponible dans le monde entier.

  • Correction de la suppression prématurée de l'argument du mot-clé pauli_list de la fonction pauli_basis() qui a cassé le code existant utilisant le chemin de compatibilité future pauli_list=True lors de la mise à jour vers Qiskit Terra 0.22.0. Ce mot-clé a été réintroduit dans la fonction. Il est désormais obsolète et sera supprimé dans une prochaine version.

  • Correction d'un problème dans la sérialisation QPY (dump()) lorsqu'une sous-classe ControlledGate qui surchargeait la méthode _define() pour fournir une définition personnalisée de l'opération. Auparavant, ce type d'opération n'était pas sérialisé correctement parce qu'il n'était pas tenu compte de l'utilisation de la méthode potentiellement _define() pour fournir une définition. Corrige #8794

  • La désérialisation QPY n'ajoutera plus d'instances supplémentaires au circuit Clbit au circuit s'il y a à la fois des Clbitdans le circuit et qu'il y a plus de Qubitque de Clbits.

  • La désérialisation QPY n'ajoutera plus les registres nommés q et c si le circuit d'entrée ne contient que des bits libres.

  • Correction de la méthode SparsePauliOp.dot() lorsqu'elle est exécutée sur deux opérateurs à coefficients réels. Pour remédier à ce problème, le dtype que SparsePauliOp peut prendre est limité à np.complex128 et object. Corrigé #8992

  • Correction d'un problème dans la fonction circuit_drawer() et la méthode QuantumCircuit.draw() où le seul style intégré utilisable pour la sortie mpl était default. Si un autre style intégré, tel que iqx, était utilisé, un avertissement concernant l'introuvabilité du style serait émis et le tiroir reviendrait à l'utilisation du style default . Corrigé #8991

  • Correction d'un problème avec la fonction transpile() qui échouait auparavant avec un TypeError si un objet personnalisé Target était transmis via l'argument target et qu'une liste de circuits multiples était spécifiée pour l'argument circuits .

  • Correction d'un problème avec transpile() lors du ciblage d'un Target (soit directement via l'argument target , soit via une instance de BackendV2 à partir de l'argument backend ) qui contenait une instruction idéale Measure idéale (qui n'a pas de propriétés définies). Auparavant, une exception était levée lors de l'analyse de la cible. Corrigé #8969

  • Correction d'un problème avec le VF2Layout qui provoquait une erreur lorsqu'il était exécuté avec un Target dont les instructions ne comportaient pas de taux d'erreur. Cette erreur a été corrigée de sorte que, dans de tels cas, l'absence de taux d'erreur sera considérée comme une mise en œuvre idéale et, si aucun taux d'erreur n'est présent, la première mise en page correspondante sera sélectionnée. Corrigé #8970

  • Correction d'un problème avec le VF2PostLayout qui provoquait une erreur lorsqu'il était exécuté avec un Target dont les instructions étaient manquantes. Dans ce cas, l'absence de taux d'erreur sera considérée comme une mise en œuvre idéale de l'opération.

  • Correction d'un problème avec la classe VQD si plus de k=2 valeurs propres ont été calculées. Auparavant, cette opération échouait en raison d'une incompatibilité de type interne, mais elle s'exécute désormais comme prévu. Corrigé #8982

  • Correction d'un bug de performance où les nouveaux algorithmes variationnels basés sur les primitives minimum_eigensolvers.VQE, eigensolvers.VQD et SamplingVQE ne mettaient pas en lot les évaluations énergétiques par défaut, ce qui entraînait un ralentissement significatif si un backend matériel était utilisé.

  • Les portes et instructions à opérande nul fonctionneront désormais avec circuit_to_gate(), QuantumCircuit.to_gate(), Gate.control()et la construction d'un Operator à partir d'un QuantumCircuit contenant des instructions à opérande nul. Ce cas limite est parfois utile pour créer des portes à phase globale dans le cadre d'instructions composées plus importantes, mais pour de nombreuses utilisations, QuantumCircuit.global_phase peut s'avérer plus approprié.

  • Corrige le problème où Statevector.evolve() et DensityMatrix.evolve() soulevait une exception en cas d'évolution de sous-systèmes imbriqués pour des sous-systèmes non quantiques. Corrige le problème #8897

  • Correction d'un bogue dans Statevector.evolve() où l'évolution du sous-système renvoie une valeur incorrecte dans certains cas où il y a au moins deux sous-systèmes non évolués avec des dimensions de sous-système différentes. Corrige le problème #8899

Aer 0.11.1

Corrections des erreurs

  • Correction d'une erreur de construction potentielle lors de l'utilisation de CMake 3.18 ou plus récent et de la construction de qiskit-aer avec le support GPU activé. Depuis CMake 3.18 ou une version ultérieure, lorsque l'on construit avec CUDA, il est nécessaire de définir CMAKE_CUDA_ARCHITECTURES avec la valeur de l'architecture pour le GPU cible. Cette erreur a été corrigée de manière à ce que le paramètre AER_CUDA_ARCH soit utilisé s'il n'a pas été défini.

  • Correction d'un bogue dans la gestion des instructions avec clbits dans LocalNoisePass. Auparavant, il effaçait accidentellement des clbits d'instructions (par exemple des mesures) auxquels le bruit est appliqué dans le cas de method="append".

  • Correction de la surcharge de performance de la classe Sampler lorsqu'elle fonctionne avec des circuits identiques sur plusieurs exécutions. Pour ce faire, la transpilation de ces circuits identiques a été ignorée ou mise en cache lors des exécutions suivantes.

  • Correction de la compatibilité des classes primitives Sampler et Estimator avec la version de qiskit-terra 0.22.0. Dans qiskit-terra 0.22.0, des changements révolutionnaires de l'API ont été apportés à l'interface abstraite, ce qui a rompu la compatibilité avec ces classes Sampler et Estimator peuvent maintenant être utilisés avec qiskit-terra >= 0.22.0.

IBM 0.19.2 du fournisseur Q

Pas de modification


0.39.0

Cette version met officiellement fin au projet Qiskit Aer, qui fait partie du métapackage Qiskit. Cela signifie que dans une prochaine version, pip install qiskit n'inclura plus qiskit-aer. Si vous installez ou listez actuellement qiskit comme dépendance pour obtenir Aer, vous devriez mettre à jour ceci pour lister explicitement qiskit-aer également.

Le projet qiskit-aer est toujours actif et maintenu, mais pour le métapackage Qiskit (c'est-à-dire ce qui est installé via pip install qiskit), le projet s'oriente vers un modèle où le paquet Qiskit ne contient que la fonctionnalité de base commune pour la construction et la compilation de circuits, de programmes et d'applications quantiques et où les paquets qui s'appuient sur lui ou qui relient Qiskit au matériel ou aux simulateurs sont des paquets distincts.

Terra 0.22.0

Prélude

La version de Qiskit Terra 0.22.0 est une version majeure qui inclut une myriade de nouvelles fonctionnalités et de corrections de bugs. Les points forts de cette version sont les suivants :

  • Ajout d'un support initial au transpileur pour transpiler QuantumCircuit qui contiennent des instructions de flux de contrôle telles que ForLoopOp et WhileLoopOp.
  • Mise à l'échelle et performances grandement améliorées pour la fonction transpile() avec un grand nombre de qubits, en particulier lorsque optimization_level=3 est utilisé.
  • Interface de plugin externe pour transpile() qui permet à des paquets externes de mettre en œuvre des étapes pour les gestionnaires de passe par défaut. Plus d'informations à ce sujet sont disponibles à l'adresse suivante qiskit.transpiler.preset_passmanagers.plugin. En outre, BackendV2 peuvent désormais définir de manière optionnelle des plugins personnalisés par défaut à utiliser pour les étapes de planification et de traduction.
  • Mise à jour des implémentations d'algorithmes en qiskit.algorithms qui s'appuient sur les classes primitives qui implémentent les classes BaseSampler et BaseEstimator.

Nouvelles fonctions

  • Ajouter un support pour représenter une opération qui a une largeur variable à la classe Target classe. Auparavant, un objet Target devait avoir une instance de Operation définie pour chaque opération prise en charge par la cible. Elle a été utilisée pour la validation des arguments et des paramètres de l'opération. Toutefois, pour les opérations de largeur variable, cela n'était pas possible car chaque instance d'une classe Operation ne peut avoir qu'un nombre fixe de qubits. Lorsqu'un backend prend en charge des opérations de largeur variable, l'instruction peut être ajoutée avec la classe de l'opération au lieu d'une instance. Dans ce cas, l'opération sera considérée comme globalement supportée par tous les qubits. Par exemple, si l'on construit un objectif comme :

    from qiskit.circuit import Parameter, Measure, IfElseOp, ForLoopOp, WhileLoopOp
    from qiskit.circuit.library import IGate, RZGate, SXGate, XGate, CXGate
    from qiskit.transpiler import Target, InstructionProperties
    
    theta = Parameter("theta")
    
    ibm_target = Target()
    i_props = {
        (0,): InstructionProperties(duration=35.5e-9, error=0.000413),
        (1,): InstructionProperties(duration=35.5e-9, error=0.000502),
        (2,): InstructionProperties(duration=35.5e-9, error=0.0004003),
        (3,): InstructionProperties(duration=35.5e-9, error=0.000614),
        (4,): InstructionProperties(duration=35.5e-9, error=0.006149),
    }
    ibm_target.add_instruction(IGate(), i_props)
    rz_props = {
        (0,): InstructionProperties(duration=0, error=0),
        (1,): InstructionProperties(duration=0, error=0),
        (2,): InstructionProperties(duration=0, error=0),
        (3,): InstructionProperties(duration=0, error=0),
        (4,): InstructionProperties(duration=0, error=0),
    }
    ibm_target.add_instruction(RZGate(theta), rz_props)
    sx_props = {
        (0,): InstructionProperties(duration=35.5e-9, error=0.000413),
        (1,): InstructionProperties(duration=35.5e-9, error=0.000502),
        (2,): InstructionProperties(duration=35.5e-9, error=0.0004003),
        (3,): InstructionProperties(duration=35.5e-9, error=0.000614),
        (4,): InstructionProperties(duration=35.5e-9, error=0.006149),
    }
    ibm_target.add_instruction(SXGate(), sx_props)
    x_props = {
        (0,): InstructionProperties(duration=35.5e-9, error=0.000413),
        (1,): InstructionProperties(duration=35.5e-9, error=0.000502),
        (2,): InstructionProperties(duration=35.5e-9, error=0.0004003),
        (3,): InstructionProperties(duration=35.5e-9, error=0.000614),
        (4,): InstructionProperties(duration=35.5e-9, error=0.006149),
    }
    ibm_target.add_instruction(XGate(), x_props)
    cx_props = {
        (3, 4): InstructionProperties(duration=270.22e-9, error=0.00713),
        (4, 3): InstructionProperties(duration=305.77e-9, error=0.00713),
        (3, 1): InstructionProperties(duration=462.22e-9, error=0.00929),
        (1, 3): InstructionProperties(duration=497.77e-9, error=0.00929),
        (1, 2): InstructionProperties(duration=227.55e-9, error=0.00659),
        (2, 1): InstructionProperties(duration=263.11e-9, error=0.00659),
        (0, 1): InstructionProperties(duration=519.11e-9, error=0.01201),
        (1, 0): InstructionProperties(duration=554.66e-9, error=0.01201),
    }
    ibm_target.add_instruction(CXGate(), cx_props)
    measure_props = {
        (0,): InstructionProperties(duration=5.813e-6, error=0.0751),
        (1,): InstructionProperties(duration=5.813e-6, error=0.0225),
        (2,): InstructionProperties(duration=5.813e-6, error=0.0146),
        (3,): InstructionProperties(duration=5.813e-6, error=0.0215),
        (4,): InstructionProperties(duration=5.813e-6, error=0.0333),
    }
    ibm_target.add_instruction(Measure(), measure_props)
    ibm_target.add_instruction(IfElseOp, name="if_else")
    ibm_target.add_instruction(ForLoopOp, name="for_loop")
    ibm_target.add_instruction(WhileLoopOp, name="while_loop")

    Les IfElseOp, ForLoopOp, et WhileLoopOp sont prises en charge globalement pour n'importe quel nombre de qubits. Ceci est ensuite reflété par d'autres appels dans l Target Tels que instruction_supported():

    ibm_target.instruction_supported(operation_class=WhileLoopOp, qargs=(0, 2, 3, 4))
    ibm_target.instruction_supported('if_else', qargs=(0, 1))

    tous deux renvoient True.

  • Ajout de nouvelles implémentations primitives, BackendSampler et BackendEstimatorles nouvelles primitives ont été ajoutées à l'ensemble des primitives de l'Union européenne qiskit.primitives. La mise en œuvre de ces nouvelles classes primitives permet d'envelopper un BackendV1 ou BackendV2 en tant qu'instance BaseSampler ou BaseEstimator respectivement. Le cas d'utilisation prévu pour ces implémentations primitives est de combler le fossé entre les fournisseurs qui n'ont pas d'implémentations primitives natives et d'utiliser le backend de ce fournisseur avec des API qui fonctionnent avec des primitives. Par exemple, la classe SamplingVQE a besoin d'une instance BaseSampler pour fonctionner. Si vous souhaitez exécuter cette classe avec un backend provenant d'un fournisseur sans implémentation primitive native, vous pouvez construire un fichier BackendSampler pour ce faire :

    from qiskit.algorithms.minimum_eigensolvers import SamplingVQE
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.circuit.library import TwoLocal
    from qiskit.primitives import BackendSampler
    from qiskit.providers.fake_provider import FakeHanoi
    from qiskit.opflow import PauliSumOp
    from qiskit.quantum_info import SparsePauliOp
    
    backend = FakeHanoi()
    sampler = BackendSampler(backend=backend)
    
    operator = PauliSumOp(SparsePauliOp(["ZZ", "IZ", "II"], coeffs=[1, -0.5, 0.12]))
    ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    optimizer = SLSQP()
    sampling_vqe = SamplingVQE(sampler, ansatz, optimizer)
    result = sampling_vqe.compute_minimum_eigenvalue(operator)
    eigenvalue = result.eigenvalue

    Si vous utilisez un fournisseur qui a des implémentations primitives natives (telles que qiskit-ibm-runtime ou qiskit-aer), il est toujours préférable d'utiliser cette implémentation primitive native au lieu de BackendEstimator ou BackendSampler car les implémentations natives seront beaucoup plus efficaces et/ou effectueront des pré- et post-traitements supplémentaires. BackendEstimator et BackendSampler sont conçus pour être génériques et peuvent fonctionner avec n'importe quel backend qui renvoie Counts dans leur Results , ce qui exclut toute optimisation supplémentaire.

  • Ajout d'une nouvelle classe d'algorithme, AdaptVQE à qiskit.algorithms Cet algorithme utilise un qiskit.algorithms.minimum_eigensolvers.VQE en combinaison avec une réserve d'opérateurs à partir de laquelle on peut construire un système de gestion de l'information qiskit.circuit.library.EvolvedOperatorAnsatz de manière adaptative. Par exemple :

    from qiskit.algorithms.minimum_eigensolvers import AdaptVQE, VQE
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.primitives import Estimator
    from qiskit.circuit.library import EvolvedOperatorAnsatz
    
    # get your Hamiltonian
    hamiltonian = ...
    
    # construct your ansatz
    ansatz = EvolvedOperatorAnsatz(...)
    
    vqe = VQE(Estimator(), ansatz, SLSQP())
    
    adapt_vqe = AdaptVQE(vqe)
    
    result = adapt_vqe.compute_minimum_eigenvalue(hamiltonian)
  • La classe BackendV2 prend désormais en charge deux nouveaux points d'accroche facultatifs permettant aux backends d'injecter des étapes de compilation personnalisées dans le cadre de l'exécution des tâches de transpile() et generate_preset_pass_manager(). Si une implémentation BackendV2 inclut les méthodes get_scheduling_stage_plugin() ou get_translation_stage_plugin() , le transpondeur utilisera la chaîne renvoyée comme valeur par défaut pour les arguments scheduling_method et translation_method . Cela permet aux backends d'exécuter des passes de transpilation personnalisées supplémentaires lorsqu'ils ciblent ce backend en tirant parti de l'interface transpiler stage plugin de l'interface. Pour plus de détails sur l'utilisation de cette fonction, voir : Passes de transpondeur personnalisées.

  • Ajout d'un nouveau mot-clé, ignore_backend_supplied_default_methods, à la fonction transpile() qui peut être utilisé pour désactiver la sélection personnalisée d'une méthode par défaut par un backend si le backend cible a défini get_scheduling_stage_plugin() ou get_translation_stage_plugin() .

  • Ajout d'un paramètre label au constructeur de la classe Barrier et à la méthode barrier() qui permet à l'utilisateur d'attribuer une étiquette à une instance de la directive Barrier à une instance de la directive. Pour les visualisations générées avec circuit_drawer() ou QuantumCircuit.draw() cette étiquette sera imprimée en haut de la page barrier.

    from qiskit import QuantumCircuit
    
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.h(1)
    circuit.barrier(label="After H")
    circuit.draw('mpl')
  • Ajouter de nouvelles portes CCZGate, CSGate, et CSdgGate aux portes standard de la bibliothèque de circuits (qiskit.circuit.library).

  • Ajout d'un paquet qiskit.algorithms.eigensolvers afin d'inclure des interfaces pour les algorithmes basés sur les primitives. Ce nouveau module remplacera à terme le précédent qiskit.algorithms.eigen_solvers. Ce nouveau module contient une implémentation alternative du module VQD qui, au lieu de prendre un backend ou QuantumInstance prend une instance de BaseEstimatory compris Estimator, BackendEstimatorou toute implémentation de fournisseur telle que celles présentes dans qiskit-ibm-runtime et qiskit-aer.

    Par exemple, pour utiliser la nouvelle implémentation avec une instance de Estimator classe :

    from qiskit.algorithms.eigensolvers import VQD
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.circuit.library import TwoLocal
    from qiskit.primitives import Sampler, Estimator
    from qiskit.algorithms.state_fidelities import ComputeUncompute
    from qiskit.opflow import PauliSumOp
    from qiskit.quantum_info import SparsePauliOp
    
    h2_op = PauliSumOp(SparsePauliOp(
        ["II", "IZ", "ZI", "ZZ", "XX"],
        coeffs=[
            -1.052373245772859,
            0.39793742484318045,
            -0.39793742484318045,
            -0.01128010425623538,
            0.18093119978423156,
        ],
    ))
    
    estimator = Estimator()
    ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    optimizer = SLSQP()
    fidelity = ComputeUncompute(Sampler())
    
    vqd = VQD(estimator, fidelity, ansatz, optimizer, k=2)
    result = vqd.compute_eigenvalues(h2_op)
    eigenvalues = result.eigenvalues

    Notez que les opérateurs auxiliaires évalués sont maintenant obtenus via le champ aux_operators_evaluated sur les résultats. Il s'agit d'une liste ou d'un dict de tuples contenant les valeurs attendues pour ces opérateurs, ainsi que les métadonnées de l'exécution primitive. aux_operator_eigenvalues n'est plus un champ valide.

  • Ajout de nouveaux algorithmes pour calculer les fidélités/chevauchements d'états pour des paires de circuits quantiques (qui peuvent être paramétrés). Outre la classe de base (BaseStateFidelity) qui définit l'interface, il existe une implémentation de la méthode de calcul-décompilation qui s'appuie sur les instances de la primitive BaseSampler primitive : qiskit.algorithms.state_fidelities.ComputeUncompute.

    Par exemple :

    import numpy as np
    from qiskit.primitives import Sampler
    from qiskit.algorithms.state_fidelities import ComputeUncompute
    from qiskit.circuit.library import RealAmplitudes
    
    sampler = Sampler(...)
    fidelity = ComputeUncompute(sampler)
    circuit = RealAmplitudes(2)
    values = np.random.random(circuit.num_parameters)
    shift = np.ones_like(values) * 0.01
    
    job = fidelity.run([circuit], [circuit], [values], [values+shift])
    fidelities = job.result().fidelities
  • Ajout d'un nouveau module qiskit.algorithms.gradients qui contient des classes utilisées pour calculer des gradients en utilisant les interfaces primitives définies dans la norme qiskit.primitives. Il existe 4 types de classes de gradient : Différence finie, Décalage des paramètres, Combinaison linéaire de l'unité et SPSA avec des implémentations qui utilisent une instance de l'interface BaseEstimator de l'interface :

    ou une instance de l'interface BaseSampler l'interface :

    Les gradients basés sur l'estimateur calculent le gradient des valeurs attendues, tandis que les gradients basés sur l'échantillonneur renvoient les gradients des résultats des mesures (également appelés "gradients de probabilité").

    Par exemple :

    estimator = Estimator(...)
    gradient = ParamShiftEstimatorGradient(estimator)
    job = gradient.run(circuits, observables, parameters)
    gradients = job.result().gradients
  • La classe Grover possède un nouveau mot-clé, sampler , qui est utilisé pour exécuter l'algorithme en utilisant une instance de l'interface BaseSampler pour calculer les résultats. Ce nouvel argument remplace l'argument quantum_instance et, par conséquent, quantum_instance est en attente de dépréciation et sera déprécié puis supprimé dans les prochaines versions.

    Exemple :

    from qiskit import QuantumCircuit
    from qiskit.primitives import Sampler
    from qiskit.algorithms import Grover, AmplificationProblem
    
    sampler = Sampler()
    oracle = QuantumCircuit(2)
    oracle.cz(0, 1)
    problem = AmplificationProblem(oracle, is_good_state=["11"])
    grover = Grover(sampler=sampler)
    result = grover.amplify(problem)
  • Une nouvelle option, "formatter.control.fill_waveform" , a été ajoutée aux feuilles de style du tiroir à impulsions (pulse_v2.draw() et Schedule.draw()). Cette option peut être utilisée pour supprimer la couleur de la face des impulsions dans la visualisation de sortie, ce qui permet de dessiner les impulsions uniquement avec des lignes.

    Par exemple :

    from qiskit.visualization.pulse_v2 import IQXStandard
    
    my_style = IQXStandard(
        **{"formatter.control.fill_waveform": False, "formatter.line_width.fill_waveform": 2}
    )
    
    my_sched.draw(style=my_style)
  • Ajout d'une nouvelle passe de transpilation, ResetAfterMeasureSimplificationqui est utilisée pour remplacer une opération Reset après un Measure par une opération conditionnelle XGate. Cette passe peut être utilisée sur les backends où une opération est réalisée en effectuant une mesure et ensuite une porte X conditionnelle afin de supprimer les doublons implicites Reset est réalisée en effectuant une mesure, puis une porte X conditionnelle, ce qui permet de supprimer le doublon implicite Measure de l'opération Reset opération. Par exemple :

    from qiskit import QuantumCircuit
    from qiskit.transpiler.passes import ResetAfterMeasureSimplification
    
    qc = QuantumCircuit(1)
    qc.measure_all()
    qc.reset(0)
    qc.draw('mpl')
    result = ResetAfterMeasureSimplification()(qc)
    result.draw('mpl')
  • Ajout d'une nouvelle valeur prise en charge, "reverse_linear" , pour l'argument du mot-clé entanglement dans le constructeur de la classe NLocal circuit. Pour les TwoLocal (qui sont des sous-classes de NLocal), si entanglement_blocks="cx" , l'utilisation de entanglement="reverse_linear" fournit un circuit n-qubit équivalent à entanglement="full" , mais avec seulement n1n-1 CXGate au lieu de n(n1)2\frac{n(n-1)}{2}.

  • ScheduleBlock a été mis à jour afin qu'il puisse gérer les sous-programmes non assignés, en d'autres termes, pour permettre l'appel paresseux d'autres programmes. Par exemple, cela permet le flux de travail suivant :

    from qiskit import pulse
    
    with pulse.build() as prog:
      pulse.reference("x", "q0")
    
    with pulse.build() as xq0:
      pulse.play(Gaussian(160, 0.1, 40), pulse.DriveChannel(0))
    
    prog.assign_references({("x", "q0"): xq0})

    Désormais, un utilisateur peut créer prog sans connaître la mise en œuvre effective de la référence ("x", "q0"), et l'affecter ultérieurement à l'exécution. Cela améliore la modularité des programmes d'impulsions, et l'on peut ainsi facilement écrire un programme d'impulsions modèle reposant sur d'autres étalonnages.

    Pour réaliser cette fonctionnalité, la nouvelle instruction pulse (directive du compilateur) Reference a été ajoutée. Cette instruction est injectée dans le champ d'application du constructeur en cours lorsque la commande reference() est utilisée. Toutes les références définies dans le programme d'impulsion actuel peuvent être répertoriées à l'aide de la propriété references .

    En outre, chaque référence est gérée avec un champ d'application afin de faciliter la gestion des paramètres. scoped_parameters() et search_parameters() ont été ajoutés à ScheduleBlock. Voir la documentation de l'API pour plus de détails.

  • Ajout d'une nouvelle méthode SparsePauliOp.argsort()qui renvoie la composition des permutations dans l'ordre du tri par coefficient et du tri par Pauli. En utilisant le mot-clé weight pour la méthode, la sortie peut également être triée en fonction du nombre de termes non identiques dans le Pauli, où l'ensemble de tous les Paulis d'un poids donné est toujours ordonné lexicographiquement.

  • Ajout d'une nouvelle méthode SparsePauliOp.sort()qui triera d'abord les coefficients à l'aide de numpy's argsort() et ensuite par Pauli, où le tri par Pauli est prioritaire. Si le tri de Pauli est le même, il sera alors trié par coefficient. En utilisant l'argument du mot-clé weight , la sortie peut également être triée en fonction du nombre de termes non identiques dans le Pauli, où l'ensemble de tous les Paulis d'un poids donné est toujours ordonné lexicographiquement.

  • Ajout d'un nouveau mot-clé, wire_order, à la fonction circuit_drawer() fonction et QuantumCircuit.draw() qui permet de réordonner arbitrairement les bits quantiques et classiques dans la visualisation de sortie. Par exemple :

    from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
    
    qr = QuantumRegister(4, "q")
    cr = ClassicalRegister(4, "c")
    cr2 = ClassicalRegister(2, "ca")
    circuit = QuantumCircuit(qr, cr, cr2)
    circuit.h(0)
    circuit.h(3)
    circuit.x(1)
    circuit.x(3).c_if(cr, 10)
    circuit.draw('mpl', cregbundle=False, wire_order=[2, 1, 3, 0, 6, 8, 9, 5, 4, 7])
  • Ajout de la prise en charge de l'élément CSGate, CSdgGate et CCZGate au constructeur de la classe d'opérateur CNOTDihedral. Les circuits d'entrée lors de la création d'un CNOTDihedral prendront désormais en charge les circuits utilisant ces portes. Par exemple :

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import CNOTDihedral
    
    qc = QuantumCircuit(2)
    qc.t(0)
    qc.cs(0, 1)
    qc.tdg(0)
    operator = CNOTDihedral(qc)
  • Les classes d'algorithmes d'estimation d'amplitude :

    Ont maintenant un nouveau mot-clé argument, sampler sur leur constructeur qui prend une instance d'un objet qui implémente l'interface BaseSampler y compris l'interface BackendSampler, Sampler, ou toute implémentation de fournisseur comme celles présentes dans qiskit-ibm-runtime et qiskit-aer. Il s'agit d'une alternative à l'utilisation de l'argument quantum_instance pour définir la cible Backend ou QuantumInstance pour exécuter l'algorithme. L'utilisation d'un QuantumInstance est en attente de dépréciation et sera dépréciée dans une prochaine version.

  • Ajout d'une nouvelle classe, BackendV2Converterqui est utilisée pour envelopper une instance de BackendV1 dans une interface BackendV2 d'une interface. Il vous permet d'avoir une BackendV2 de n'importe quel BackendV1. Cela permet de normaliser les schémas d'accès sur l'interface la plus récente BackendV2 même si vous supportez toujours BackendV1.

  • Ajout d'une nouvelle fonction convert_to_target() qui est utilisée pour prendre un BackendConfigurationet éventuellement a BackendProperties et PulseDefaults et créer un objet Target équivalent au contenu de ces objets.

  • qiskit.quantum_info.BaseOperator (telles que ScalarOp, SparsePauliOp et PauliList) peuvent désormais être utilisées avec la fonction intégrée Python sum() .

  • Un nouveau transpileur pass, ConvertConditionsToIfOps a été ajoutée, qui peut être utilisée pour convertir les instructions conditionnées de l'ancien style en instructions conditionnées de l'ancien style Instruction.c_if()-en objets IfElseOp objets. Il s'agit de faciliter la transition entre l'ancien et le nouveau type de backend. Pour la plupart des utilisateurs, il n'est pas nécessaire de l'ajouter à vos gestionnaires de laissez-passer, et il n'est pas inclus dans les gestionnaires de laissez-passer prédéfinis.

  • Analyse de commutativité de porte refaite en une classe CommutationChecker. Cette classe permet de vérifier (sur la base d'une multiplication matricielle) si deux portes commutent ou ne commutent pas, et de mettre en cache les résultats (de sorte qu'une vérification similaire à l'avenir ne nécessitera plus de multiplication matricielle).

    Par exemple, nous pouvons maintenant faire :

    from qiskit.circuit import QuantumRegister, CommutationChecker
    
    comm_checker = CommutationChecker()
    qr = QuantumRegister(4)
    
    res = comm_checker.commute(CXGate(), [qr[1], qr[0]], [], CXGate(), [qr[1], qr[2]], [])

    Comme les deux portes CX commutent (la première porte CX est sur les qubits qr[1] et qr[0], et la seconde porte CX est sur les qubits qr[1] et qr[2]), nous aurons que res est True.

    Cette vérification de la commutativité est trop conservatrice pour les portes conditionnelles et paramétrées, et peut renvoyer False même lorsque ces portes sont commutatives.

  • Ajout d'une nouvelle passe de transposition CommutativeInverseCancellation qui annule les paires de portes inverses en exploitant les relations de commutation entre les portes. Cette passe est une généralisation de la passe transpiler InverseCancellation car elle détecte un plus grand nombre de portes inverses, et prend en compte la commutativité. Cette passe permet également d'éviter certains problèmes liés à la passe transpiler CommutativeCancellation.

    Par exemple :

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import CommutativeInverseCancellation
    
    circuit = QuantumCircuit(2)
    circuit.z(0)
    circuit.x(1)
    circuit.cx(0, 1)
    circuit.z(0)
    circuit.x(1)
    
    passmanager = PassManager(CommutativeInverseCancellation())
    new_circuit = passmanager.run(circuit)

    annule la paire de portes Z auto-inversées et la paire de portes X auto-inversées (puisque les portes concernées commutent avec la porte CX), produisant un circuit composé d'une seule porte CX.

    La vérification inverse est trop prudente pour les portes conditionnelles et paramétrées, et peut ne pas annuler certaines de ces portes.

  • QuantumCircuit.compose() acceptera désormais un opérande avec des bits classiques si le circuit de base n'en a pas lui-même. Le modèle de composition d'un circuit avec des mesures sur un circuit uniquement quantique est maintenant valide. Par exemple :

    from qiskit import QuantumCircuit
    
    base = QuantumCircuit(3)
    terminus = QuantumCircuit(3, 3)
    terminus.measure_all()
    
    # This will now succeed, though it was previously a CircuitError.
    base.compose(terminus)
  • Les DAGCircuit méthodes depth() et size() disposent d'un nouveau mot-clé recurse à utiliser avec les circuits qui contiennent des opérations de flux de contrôle (tels que IfElseOp, WhileLoopOp, et ForLoopOp). Par défaut, il s'agit de False , ce qui provoque une erreur si des opérations de flux de contrôle sont présentes, afin d'éviter des résultats mal définis. Si elle est fixée à True, une valeur de remplacement qui tente de pondérer équitablement chaque bloc de flux de contrôle par rapport à son état est renvoyée, même si la profondeur ou la taille d'une coulée de béton est généralement inconnue. Voir la documentation de chaque méthode pour savoir comment chaque opération de flux de contrôle affecte la sortie.

  • DAGCircuit.count_ops() a gagné un argument de mot-clé recurse pour la récursivité dans les blocs de flux de contrôle. Par défaut, il s'agit de True, et toutes les opérations de tous les blocs seront renvoyées, ainsi que les opérations de flux de contrôle elles-mêmes.

  • Ajout d'un argument create_preds_and_succs aux fonctions circuit_to_dagdependency() et dag_to_dagdependency() qui convertissent de QuantumCircuit et DAGCircuitrespectivement, en DAGDependency. Lorsque la valeur de create_preds_and_succs est False, les prédécesseurs et successeurs transitifs des nœuds de DAGDependency ne sont pas construits, ce qui rend les conversions plus rapides et beaucoup moins gourmandes en mémoire. Les prédécesseurs et successeurs directs des nœuds de DAGDependency sont construits comme d'habitude.

    Par exemple :

    from qiskit.converters import circuit_to_dagdependency
    from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
    
    circuit_in = QuantumCircuit(2)
    circuit_in.h(qr[0])
    circuit_in.h(qr[1])
    
    dag_dependency = circuit_to_dagdependency(circuit_in, create_preds_and_succs=False)
  • Ajout de nouveaux attributs Clifford.symplectic_matrix, Clifford.tableau, Clifford.z, Clifford.x, Clifford.phase, Clifford.stab, Clifford.stab_z, Clifford.stab_x, Clifford.stab_phase, Clifford.destab, Clifford.destab_z, Clifford.destab_x, Clifford.destab_phase à la Clifford classe. Ils peuvent être utilisés à la place de Clifford.table, qui sera obsolète à l'avenir. StabilizerTable et PauliTable sont en attente de dépréciation et seront dépréciés dans la prochaine version, puis supprimés.

  • Le constructeur Commuting2qGateRouter le constructeur a maintenant un nouveau mot-clé en argument, edge_coloring. Cet argument est utilisé pour fournir une coloration des bords de la carte de couplage afin de déterminer l'ordre dans lequel les portes de commutation sont appliquées.

  • Ajout d'une nouvelle interface d'algorithmes pour la création d'algorithmes d'évolution temporelle utilisant les primitives BaseSampler et BaseEstimator. Cette nouvelle interface comprend

    Cette nouvelle interface est une alternative à l'interface existante pour les algorithmes d'évolution temporelle, définie par EvolutionProblem, EvolutionResult, RealEvolver, et ImaginaryEvolver qui fonctionnait avec un objet QuantumInstance au lieu de primitives. Cette nouvelle interface remplace l'interface précédente qui, à terme, sera obsolète et donc supprimée dans les prochaines versions.

  • Ajout de nouvelles classes de backend à qiskit.providers.fake_provider:

    Ces nouvelles classes mettent en œuvre l'interface BackendV2 et sont créées à l'aide d'instantanés stockés des informations de base des systèmes IBM Quantum, ibm_auckland, ibm_oslo, ibm_geneva et ibm_perth respectivement.

  • La classe Z2Symmetries possède deux nouvelles méthodes, convert_clifford() et taper_clifford(). Ces deux méthodes sont les deux opérations nécessaires pour réduire un opérateur sur la base des symétries Z2 de l'objet et étaient auparavant effectuées en interne via la méthode taper() méthode. Toutefois, ces méthodes sont désormais des méthodes publiques de la classe qui peuvent être appelées individuellement si nécessaire.

  • La performance d'exécution pour la conjugaison d'un objet long PauliList par un Clifford à l'aide de l'outil PauliList.evolve() s'est considérablement améliorée. Il fonctionnera désormais beaucoup plus rapidement qu'auparavant.

  • Ajout d'une nouvelle classe abstraite ClassicalIOChannel au module qiskit.pulse.channels module. Cette classe est utilisée pour représenter les canaux d'E/S classiques et les différencier des autres sous-classes de la classe Channel. Cette nouvelle classe est la classe de base de la classe MemorySlot, RegisterSlot, et SnapshotChannel . En conséquence, la transformée d'impulsion de pad() transformée d'impulsion de canonisation en qiskit.pulse.transforms n'introduira pas de retard dans les instances de ClassicalIOChannel

  • La passe SabreSwap dispose d'un nouveau mot-clé dans son constructeur, trials. L'argument trials est utilisé pour spécifier le nombre d'essais de semences aléatoires à tenter. Le résultat de l' algorithme SABRE peut varier considérablement en fonction de la graine utilisée pour le nombre aléatoire. SabreSwap va maintenant exécuter l'algorithme avec trials nombre de graines aléatoires et choisir la meilleure (avec le moins d'échanges insérés). Si trials n'est pas spécifié, la passe utilisera par défaut le nombre de CPU physiques sur le système local.

  • La passe SabreLayout dispose d'un nouveau mot-clé dans son constructeur, swap_trials. L'argument swap_trials est utilisé pour spécifier le nombre d'essais de semences aléatoires à effectuer sur la passe en interne SabreSwap en interne. Il correspond à l'article trials sur le SabreSwap passe. Lorsqu'elle est définie, chaque itération de SabreSwap sera exécutée en interne swap_trials fois. Si swap_trials n'est pas spécifié, le système utilisera par défaut le nombre de CPU physiques du système local.

  • Ajout d'une nouvelle fonction, estimate_observables() qui utilise une implémentation de l'interface BaseEstimator (par exemple Estimator, BackendEstimatorou toute implémentation de fournisseur telle que celles présentes dans qiskit-ibm-runtime et qiskit-aer) pour calculer les valeurs d'espérance, leurs moyennes et leurs écarts types à partir d'une liste ou d'un dictionnaire d'observables. Cette fonction est similaire à la fonction préexistante eval_observables() qui effectuait le calcul à l'aide d'un objet QuantumInstance et a été remplacée (et sera dépréciée puis supprimée dans les versions futures) par cette nouvelle fonction.

  • Ajout d'une nouvelle classe de base Operation qui fournit une interface abstraite légère pour les objets qui peuvent être placés sur les serveurs QuantumCircuit. Cela permet de stocker des objets de "niveau supérieur" directement sur un circuit (par exemple, des objets de "niveau supérieur"), de combiner directement ces objets (par exemple, de composer plusieurs objets consécutifs), Clifford objets), de combiner directement de tels objets (par exemple, de composer plusieurs objets Clifford objets consécutifs sur les mêmes qubits) et de synthétiser ces objets au moment de l'exécution (par exemple, de synthétiser d'une manière qui optimise la profondeur et/ou exploite la connectivité du dispositif) Clifford d'une manière qui optimise la profondeur et/ou exploite la connectivité du dispositif). Auparavant, seules les sous-classes de qiskit.circuit.Instruction pouvaient être placées sur QuantumCircuitmais cette interface est devenue lourde et comprend trop de méthodes et d'attributs pour des objets d'usage général.

    La nouvelle interface Operation inclut name, num_qubits et num_clbits (à l'avenir, elle pourra être légèrement modifiée), mais surtout n'inclut pas definition (et ne lie donc pas la synthèse à l'objet), n'inclut pas condition (cela devrait faire partie d'un flux de contrôle classique distinct), et n'inclut pas duration et unit (car il s'agit de propriétés de la sortie du transpileur).

    Dès à présent, Operation comprend Gate, Reset, Barrier, Measureet des objets de "niveau supérieur" tels que Clifford. Cette liste d'objets de "niveau supérieur" s'allongera à l'avenir.

  • A Clifford est maintenant ajouté à un circuit quantique en tant que Operationsans avoir à synthétiser au préalable un sous-circuit implémentant ce Clifford. La synthèse proprement dite est reportée à un passage de transpilation ultérieur HighLevelSynthesis transpilation ultérieure.

    Par exemple, le code suivant :

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import random_clifford
    
    qc = QuantumCircuit(3)
    cliff = random_clifford(2)
    qc.append(cliff, [0, 1])

    ne convertit plus cliff en qiskit.circuit.Instructionqui comprend la synthèse du clifford en un circuit, lorsqu'il est annexé à qc.

  • Ajout d'une nouvelle passe de transposition OptimizeCliffords qui collecte des blocs d'objets Clifford consécutifs dans un circuit, et remplace chaque bloc par un seul objet Clifford.

    Par exemple, le code suivant :

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import random_clifford
    from qiskit.transpiler.passes import OptimizeCliffords
    from qiskit.transpiler import PassManager
    
    qc = QuantumCircuit(3)
    cliff1 = random_clifford(2)
    cliff2 = random_clifford(2)
    qc.append(cliff1, [2, 1])
    qc.append(cliff2, [2, 1])
    qc_optimized = PassManager(OptimizeCliffords()).run(qc)

    stocke d'abord les deux Cliffords cliff1 et cliff2 sur qc en tant qu'objets de "niveau supérieur", puis la passe de transpilation optimise le circuit en composant ces deux Cliffords en un seul Clifford OptimizeCliffords optimise le circuit en composant ces deux Clifford en un seul Clifford. Notez que le Clifford résultant est toujours stocké sur qc en tant qu'objet de niveau supérieur. Ce laissez-passer n'est pas encore inclus dans les gestionnaires de laissez-passer prédéfinis.

  • Ajout d'une nouvelle passe de transposition HighLevelSynthesis qui synthétise des objets de plus haut niveau (par exemple, Clifford objets).

    Par exemple, le code suivant :

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import random_clifford
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import HighLevelSynthesis
    
    qc = QuantumCircuit(3)
    qc.h(0)
    cliff = random_clifford(2)
    qc.append(cliff, [0, 1])
    
    qc_synthesized = PassManager(HighLevelSynthesis()).run(qc)

    synthétisera le Clifford de niveau supérieur stocké dans qc en utilisant la fonction par défaut de decompose_clifford() .

    Ce nouveau passeur de transpondeurs HighLevelSynthesis est intégré dans les gestionnaires de passe prédéfinis, fonctionnant juste après la passe UnitarySynthesis passe. Ainsi, transpile() synthétisera tous les Cliffords de niveau supérieur présents dans le circuit.

    Il est important de noter que le travail effectué pour stocker les objets Clifford en tant qu'objets de "niveau supérieur" et pour transposer ces objets à l'aide de HighLevelSynthesis devraient être totalement transparents, et qu'aucune modification du code n'est nécessaire.

  • SparsePauliOppeuvent désormais être construits avec des tableaux de coefficients qui sont des objets généraux Python. Cette méthode est destinée à être utilisée avec les objets ParameterExpression d'autres objets peuvent fonctionner, mais ne bénéficient pas d'un support de première classe. Certaines méthodes SparsePauliOp (telles que la conversion vers d'autres représentations de classes) peuvent ne pas fonctionner lors de l'utilisation de tableaux object , si la cible souhaitée ne peut pas représenter ces tableaux généraux.

    Par exemple, un ParameterExpression SparsePauliOp pourrait être construit par :

    import numpy as np
    from qiskit.circuit import Parameter
    from qiskit.quantum_info import SparsePauliOp
    
    print(SparsePauliOp(["II", "XZ"], np.array([Parameter("a"), Parameter("b")])))

    ce qui donne

    SparsePauliOp(['II', 'XZ'],
          coeffs=[ParameterExpression(1.0*a), ParameterExpression(1.0*b)])
  • Ajout d'une nouvelle fonction plot_distribution() pour tracer les distributions sur les quasi-probabilités. Il convient pour Counts, QuasiDistribution et ProbDistribution. La dictée brute peut également être transmise. Par exemple :

    from qiskit.visualization import plot_distribution
    
    quasi_dist = {'0': .98, '1': -.01}
    plot_distribution(quasi_dist)
  • Introduction d'une nouvelle interface de plugin de synthèse de haut niveau qui permet d'utiliser des techniques de synthèse alternatives incluses dans des paquets externes de manière transparente avec la passe de HighLevelSynthesis transpiler pass. Ces techniques de synthèse alternatives peuvent être spécifiées pour tout objet de "niveau supérieur" de type Operationcomme par exemple pour Clifford et LinearFunction les objets. L'interface de ce plugin est similaire à celle de la synthèse unitaire. Dans ce dernier cas, les détails sur l'écriture d'un nouveau plugin figurent dans la qiskit.transpiler.passes.synthesis.plugin dans la documentation du module.

  • Introduction d'une nouvelle classe HLSConfig qui peut être utilisée pour spécifier des algorithmes de synthèse alternatifs pour des objets de "niveau supérieur" de type Operation. Pour chaque objet d'intérêt de niveau supérieur, un objet HLSConfig spécifie une liste de méthodes de synthèse et leurs arguments. Cet objet peut être transmis à HighLevelSynthesis transpiler pass ou spécifié comme paramètre hls_config dans transpile().

    À titre d'exemple, supposons que op_a et op_b sont les noms de deux objets de niveau supérieur, que les objets op_a ont deux méthodes de synthèse default qui ne nécessite aucun paramètre supplémentaire et other avec deux paramètres entiers facultatifs option_1 et option_2, que les objets op_b ont une seule méthode de synthèse default, et que qc est un circuit quantique contenant les objets op_a et op_b . L'extrait de code suivant :

    hls_config = HLSConfig(op_b=[("other", {"option_1": 7, "option_2": 4})])
    pm = PassManager([HighLevelSynthesis(hls_config=hls_config)])
    transpiled_qc = pm.run(qc)

    montre comment exécuter la méthode de synthèse alternative other pour les objets op_b, tout en utilisant les méthodes default pour tous les autres objets de haut niveau, y compris les objets op_a.

  • Ajout de nouvelles méthodes pour l'exécution des primitives : BaseSampler.run() et BaseEstimator.run(). Ces méthodes s'exécutent de manière asynchrone et renvoient des objets JobV1 qui fournissent une poignée pour les exécutions. Ces nouvelles méthodes d'exécution peuvent être transmises QuantumCircuit (et les observables pour les BaseEstimator) qui ne sont pas enregistrés dans le constructeur. Par exemple :

    estimator = Estimator()
    result = estimator.run(circuits, observables, parameter_values).result()

    Il s'agit d'une alternative au modèle d'exécution précédent (qui est désormais obsolète) pour le modèle BaseSampler et BaseEstimator qui prenaient toutes les entrées via le constructeur et appelaient l'objet primitif avec la combinaison de ces paramètres d'entrée à utiliser dans l'exécution.

  • Ajout de l'option shots pour les implémentations de référence des primitives. Les nombres aléatoires peuvent être fixés en donnant seed_primitive. Par exemple :

    from qiskit.primitives import Sampler
    from qiskit import QuantumCircuit
    
    bell = QuantumCircuit(2)
    bell.h(0)
    bell.cx(0, 1)
    bell.measure_all()
    
    with Sampler(circuits=[bell]) as sampler:
        result = sampler(circuits=[0], shots=1024, seed_primitive=15)
        print([q.binary_probabilities() for q in result.quasi_dists])
  • Les constructeurs pour les BaseSampler et BaseEstimator disposent d'un nouveau mot-clé optionnel, options , qui permet de définir les valeurs par défaut des options exposées via l'attribut options .

  • Ajout de la classe PVQD au cadre de l'évolution temporelle dans qiskit.algorithms. Cette classe met en œuvre l'algorithme de dynamique quantique variationnelle projetée (p-VQD) de Barison et al.

    À chaque étape, cet algorithme calcule l'état suivant à l'aide d'une formule de Trotter et le projette sur une forme variationnelle. La projection est déterminée en maximisant la fidélité de l'état évolué par Trotter et de l'ansatz, à l'aide d'une routine d'optimisation classique.

    import numpy as np
    
    from qiskit.algorithms.state_fidelities import ComputeUncompute
    from qiskit.algorithms.evolvers import EvolutionProblem
    from qiskit.algorithms.time_evolvers.pvqd import PVQD
    from qiskit.primitives import Estimator, Sampler
    from qiskit import BasicAer
    from qiskit.circuit.library import EfficientSU2
    from qiskit.quantum_info import Pauli, SparsePauliOp
    from qiskit.algorithms.optimizers import L_BFGS_B
    
    sampler = Sampler()
    fidelity = ComputeUncompute(sampler)
    estimator = Estimator()
    hamiltonian = 0.1 * SparsePauliOp([Pauli("ZZ"), Pauli("IX"), Pauli("XI")])
    observable = Pauli("ZZ")
    ansatz = EfficientSU2(2, reps=1)
    initial_parameters = np.zeros(ansatz.num_parameters)
    
    time = 1
    optimizer = L_BFGS_B()
    
    # setup the algorithm
    pvqd = PVQD(
        fidelity,
        ansatz,
        initial_parameters,
        estimator,
        num_timesteps=100,
        optimizer=optimizer,
    )
    
    # specify the evolution problem
    problem = EvolutionProblem(
        hamiltonian, time, aux_operators=[hamiltonian, observable]
    )
    
    # and evolve!
    result = pvqd.evolve(problem)
  • La méthode QNSPSA.get_fidelity() supporte maintenant un argument optionnel sampler qui est utilisé pour fournir une implémentation de l'interface BaseSampler (comme Sampler, BackendSamplerou toute implémentation de fournisseur telle que celles présentes dans qiskit-ibm-runtime et qiskit-aer) pour calculer la fidélité d'un QuantumCircuit. Par exemple :

    from qiskit.primitives import Sampler
    from qiskit.algorithms.optimizers import QNSPSA
    
    fidelity = QNSPSA.get_fidelity(my_circuit, Sampler())
  • Ajout d'un nouveau mot-clé sampler aux constructeurs des classes d'estimation de phase :

    Cet argument est utilisé pour fournir une implémentation de l'interface BaseSampler telle que Sampler, BackendSamplerou toute implémentation de fournisseur telle que celles présentes dans qiskit-ibm-runtime et qiskit-aer.

    Par exemple :

    from qiskit.primitives import Sampler
    from qiskit.algorithms.phase_estimators import HamiltonianPhaseEstimation
    from qiskit.synthesis import MatrixExponential
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.opflow import PauliSumOp
    
    
    sampler = Sampler()
    num_evaluation_qubits = 6
    phase_est = HamiltonianPhaseEstimation(
        num_evaluation_qubits=num_evaluation_qubits, sampler=sampler
    )
    
    hamiltonian = PauliSumOp(SparsePauliOp.from_list([("X", 0.5), ("Y", 0.6), ("I", 0.7)]))
    result = phase_est.estimate(
        hamiltonian=hamiltonian,
        state_preparation=None,
        evolution=MatrixExponential(),
        bound=1.05,
    )
  • La passe de SabreSwap a considérablement amélioré les performances d'exécution grâce à une réécriture de l'algorithme en Rust.

  • Sous-classes d'impulsions symboliques Gaussian, GaussianSquare, Drag et Constant ont été mises à jour pour instancier SymbolicPulse plutôt que la sous-classe elle-même. Tous les objets d'impulsion paramétriques dans les programmes d'impulsion doivent être des instances d'impulsion symboliques, car la sous-classification n'est plus nécessaire. Notez que SymbolicPulse peut identifier de manière unique une enveloppe particulière avec l'objet d'expression symbolique défini dans SymbolicPulse.envelope.

  • Ajout d'une nouvelle fonction, sampled_expectation_value()qui permet de calculer les valeurs de l'espérance des opérateurs diagonaux à partir de distributions telles que Counts et QuasiDistribution. Les opérateurs valables pour cette fonction sont str, Pauli, PauliOp, PauliSumOp, et SparsePauliOp.

  • A SamplingVQE est introduite, qui est optimisée pour les hamiltoniens diagonaux et tire parti d'une primitive sampler . A QAOA une classe est également ajoutée, qui sous-classe SamplingVQE.

    Pour utiliser le nouveau SamplingVQE avec une primitive de référence, on peut faire, par exemple :

    from qiskit.algorithms.minimum_eigensolvers import SamplingVQE
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.circuit.library import TwoLocal
    from qiskit.primitives import Sampler
    from qiskit.opflow import PauliSumOp
    from qiskit.quantum_info import SparsePauliOp
    
    operator = PauliSumOp(SparsePauliOp(["ZZ", "IZ", "II"], coeffs=[1, -0.5, 0.12]))
    
    sampler = Sampler()
    ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    optimizer = SLSQP()
    
    sampling_vqe = SamplingVQE(sampler, ansatz, optimizer)
    result = sampling_vqe.compute_minimum_eigenvalue(operator)
    eigenvalue = result.eigenvalue

    Notez que les opérateurs auxiliaires évalués sont maintenant obtenus via le champ aux_operators_evaluated sur les résultats. Il s'agit d'une liste ou d'un dict de tuples contenant les valeurs attendues pour ces opérateurs, ainsi que les métadonnées de l'exécution primitive. aux_operator_eigenvalues n'est plus un champ valide.

  • Ajout d'un nouvel argument atol à la méthode SparsePauliOp.equiv() pour ajuster la tolérance du contrôle d'équivalence,

  • Introduction d'une nouvelle interface de plugin pour les étapes de transposition, qui est utilisée pour permettre aux objets alternatifs d'un paquetage externe dans une étape particulière, dans le cadre d'un projet de transposition PassManager d'autres objets provenant d'un paquetage externe dans une étape particulière dans le cadre d'un projet de transposition transpile() ou de la StagedPassManager sortie de generate_preset_pass_manager(), level_0_pass_manager(), level_1_pass_manager(), level_2_pass_manager(), et level_3_pass_manager(). Les utilisateurs peuvent sélectionner un plugin à utiliser pour une étape de transposition avec les arguments de mots-clés init_method, layout_method, routing_method, translation_method, optimization_method, et scheduling_method sur transpile() et generate_preset_pass_manager(). Une liste complète des noms des plugins actuellement installés peut être consultée à l'aide de la fonction list_stage_plugins() fonction. Pour la création de plugins, se référer à la documentation du module qiskit.transpiler.preset_passmanagers.plugin qui comprend un guide pour l'écriture de plugins de scène.

  • L'option transpile() possède deux nouveaux mots-clés, init_method et optimization_method , qui sont utilisés pour spécifier les plugins alternatifs à utiliser pour les étapes init et optimization respectivement.

  • La classe PassManagerConfig possède deux nouveaux attributs, init_method et optimization_method , ainsi que des arguments de mots-clés correspondants dans les méthodes de construction. Ils représentent les plugins init et optimization spécifiés par l'utilisateur à utiliser pour la compilation.

  • La classe SteppableOptimizer est ajoutée. Il permet d'effectuer des optimisations classiques étape par étape à l'aide de la méthode step() méthode. Ces optimiseurs mettent en œuvre l'interface "ask and tell" qui permet (en option) de calculer manuellement les évaluations de la fonction ou du gradient requis et de les réintégrer dans l'optimiseur. Pour plus d'informations sur cette interface, voir : ask and tell interface. Un cas d'utilisation très simple où l'utilisateur peut vouloir faire l'optimisation pas à pas est la lecture :

    import random
    import numpy as np
    from qiskit.algorithms.optimizers import GradientDescent
    
    def objective(x):
          return (np.linalg.norm(x) - 1) ** 2
    
    def grad(x):
          return 2 * (np.linalg.norm(x) - 1) * x / np.linalg.norm(x)
    
    
    initial_point = np.random.normal(0, 1, size=(100,))
    
    optimizer = GradientDescent(maxiter=20)
    optimizer.start(x0=initial_point, fun=objective, jac=grad)
    
    for _ in range(maxiter):
        state = optimizer.state
        # Here you can manually read out anything from the optimizer state.
        optimizer.step()
    
    result = optimizer.create_result()

    Un cas plus complexe serait la gestion des erreurs. Imaginez que la fonction que vous évaluez ait une chance aléatoire d'échouer. Dans ce cas, vous pouvez détecter l'erreur et réexécuter la fonction jusqu'à ce qu'elle produise le résultat souhaité avant de poursuivre le processus d'optimisation. Dans ce cas, il convient d'utiliser l'interface "ask and tell".

    import random
    import numpy as np
    from qiskit.algorithms.optimizers import GradientDescent
    
    def objective(x):
        if random.choice([True, False]):
            return None
        else:
            return (np.linalg.norm(x) - 1) ** 2
    
    def grad(x):
        if random.choice([True, False]):
            return None
        else:
            return 2 * (np.linalg.norm(x) - 1) * x / np.linalg.norm(x)
    
    
    initial_point = np.random.normal(0, 1, size=(100,))
    
    optimizer = GradientDescent(maxiter=20)
    optimizer.start(x0=initial_point, fun=objective, jac=grad)
    
    while optimizer.continue_condition():
        ask_data = optimizer.ask()
        evaluated_gradient = None
    
        while evaluated_gradient is None:
            evaluated_gradient = grad(ask_data.x_center)
            optimizer.state.njev += 1
    
        optmizer.state.nit += 1
    
        cf  = TellData(eval_jac=evaluated_gradient)
        optimizer.tell(ask_data=ask_data, tell_data=tell_data)
    
    result = optimizer.create_result()

    Transformation de GradientDescent en sous-classe de SteppableOptimizer.

  • La méthode subset_fitter est ajoutée à la classe TensoredMeasFitter classe. La mise en œuvre est limitée aux modèles d'atténuation dans lesquels chaque qubit est atténué individuellement, par exemple [[0], [1], [2]]. C'est cependant le cas le plus répandu. Il permet d'utiliser le TensoredMeasFitter dans les cas où l'ordre numérique des qubits physiques ne correspond pas à l'index du bit classique.

  • Les opérations de flux de contrôle sont désormais prises en charge par le transpileur aux niveaux d'optimisation 0 et 1 (par exemple, l'appel à transpile() ou generate_preset_pass_manager() avec le mot-clé optimization_level=1). On peut maintenant construire un circuit tel que

    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(2, 1)
    qc.h(0)
    qc.measure(0, 0)
    with qc.if_test((0, True)) as else_:
      qc.x(1)
    with else_:
      qc.y(1)

    et de le transposer avec succès, comme par exemple par :

    from qiskit import transpile
    from qiskit_aer import AerSimulator
    
    backend = AerSimulator(method="statevector")
    transpiled = transpile(qc, backend)

    Les valeurs disponibles pour le mot-clé layout_method sont "trivial" et "dense". Pour routing_method, les options "stochastique" et "aucun" sont disponibles. La traduction (translation_method) peut être effectuée à l'aide de "translator" ou "unroller". Les niveaux d'optimisation 2 et 3 ne sont pas encore pris en charge par le flux de contrôle, ni l'ordonnancement des circuits (c'est-à-dire la fourniture d'une valeur à scheduling_method), bien que nous ayons l'intention d'étendre la prise en charge de ces méthodes et des autres méthodes d'agencement, de routage et de traduction dans les versions ultérieures de Qiskit Terra.

    Pour que la transpilation avec des opérations de flux de contrôle réussisse avec un backend, ce dernier doit avoir les opérations de flux de contrôle requises dans sa base déclarée. C'est ce que fait, par exemple, Qiskit Aer. Si vous souhaitez simplement essayer de telles transpositions, envisagez de remplacer l'argument basis_gates par transpile().

  • Les passes de transpilation suivantes ont toutes été formées pour comprendre les constructions de flux de contrôle sous la forme d'instructions dans un circuit ControlFlowOp instructions dans un circuit :


    Lié à la mise en page


    Lié au routage


    Lié à la traduction


    Lié à l'optimisation

    Ces passes sont le plus souvent utilisées via les gestionnaires de passes prédéfinis (ceux utilisés en interne par transpile() et generate_preset_pass_manager()), mais ils sont également disponibles pour d'autres usages. Ces passages seront ensuite réinvestis dans des opérations de flux de contrôle, le cas échéant, en mettant à jour ou en analysant les blocs internes.

  • Ajout d'une nouvelle classe TrotterQRTE qui implémente l'interface RealTimeEvolver qui utilise un qiskit.primitives.BaseEstimator pour effectuer le calcul. Cette nouvelle classe remplace la classe qiskit.algorithms.TrotterQRTE (qui sera dépréciée et supprimée dans les versions ultérieures) qui utilisait un fichier Backend ou QuantumInstance pour effectuer le calcul.

  • DAGCircuit.substitute_node_with_dag() prend désormais propagate_condition comme argument de mot-clé. La valeur par défaut est True, ce qui était le comportement précédent, et copie toute condition sur le nœud à remplacer sur chaque nœud d'opération dans le remplacement. Si la valeur est False, la condition ne sera pas copiée, ce qui permet de remplacer un nœud conditionnel par un sous-DAG qui implémente déjà fidèlement la condition.

  • DAGCircuit.substitute_node_with_dag() peut désormais prendre un mapping pour son paramètre wires ainsi qu'une séquence. Le mappage doit mettre en correspondance les bits du DAG de remplacement avec les bits du DAG dans lequel il est inséré. Cela permet un style de construction plus facile pour les appelants lorsque le nœud d'entrée possède à la fois des bits classiques et une condition, et que le DAG de remplacement peut les utiliser dans le désordre.

  • Ajout du paquet qiskit.algorithms.minimum_eigensolvers afin d'inclure des interfaces pour les algorithmes basés sur les primitives. VQE a été remanié dans cette implémentation afin de tirer parti des primitives.

    Pour utiliser la nouvelle implémentation avec une primitive de référence, on peut faire, par exemple :

    from qiskit.algorithms.minimum_eigensolvers import VQE
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.circuit.library import TwoLocal
    from qiskit.primitives import Estimator
    from qiskit.quantum_info import SparsePauliOp
    
    h2_op = SparsePauliOp(
        ["II", "IZ", "ZI", "ZZ", "XX"],
        coeffs=[
            -1.052373245772859,
            0.39793742484318045,
            -0.39793742484318045,
            -0.01128010425623538,
            0.18093119978423156,
        ],
    )
    
    estimator = Estimator()
    ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    optimizer = SLSQP()
    
    vqe = VQE(estimator, ansatz, optimizer)
    result = vqe.compute_minimum_eigenvalue(h2_op)
    eigenvalue = result.eigenvalue

    Notez que les opérateurs auxiliaires évalués sont maintenant obtenus via le champ aux_operators_evaluated sur les résultats. Il s'agit d'une liste ou d'un dict de tuples contenant les valeurs attendues pour ces opérateurs, ainsi que les métadonnées de l'exécution primitive. aux_operator_eigenvalues n'est plus un champ valide.

Mise à niveau

  • Pour les Target qui ne contiennent que des opérations de 2 qubits définies globalement sans aucune contrainte de connectivité, le retour de la méthode Target.build_coupling_map() renverra désormais None au lieu d'un objet CouplingMap qui contient num_qubits nœuds et aucune arête. Ce changement a été effectué pour mieux refléter les contraintes de connectivité réelles de la base de données Target car dans ce cas, il n'y a pas de contraintes de connectivité sur le backend modélisé par l'élément Targetil ne s'agit donc pas d'un manque de connectivité. Si vous souhaitez obtenir le comportement précédent pour une raison quelconque, vous pouvez le reproduire en vérifiant la présence d'un retour None et en construisant manuellement une carte de couplage, par exemple :

    from qiskit.transpiler import Target, CouplingMap
    from qiskit.circuit.library import CXGate
    
    target = Target(num_qubits=3)
    target.add_instruction(CXGate())
    cmap = target.build_coupling_map()
    if cmap is None:
        cmap = CouplingMap()
        for i in range(target.num_qubits):
            cmap.add_physical_qubit(i)
  • La valeur par défaut de l'argument du mot-clé entanglement dans le constructeur de l'élément RealAmplitudes et EfficientSU2 est passée de "full" à "reverse_linear". Ce changement a été effectué parce que le circuit de sortie est équivalent mais utilise seulement n1n-1 au lieu de n(n1)2\frac{n(n-1)}{2} CXGate les portes. Si vous souhaitez conserver l'ancienne valeur par défaut, vous pouvez explicitement définir entanglement="full" lors de l'appel à l'un des deux constructeurs.

  • Ajout d'un contrôle de validation à BaseSampler.run(). Il soulève une erreur s'il n'y a pas de bit classique.

  • Le comportement de la fonction call() a été amélioré. Lorsqu'une instance ScheduleBlock est appelée par cette méthode, elle crée en interne une référence à l'instance Reference dans le contexte actuel, et assigne immédiatement le programme appelé à la référence. Ainsi, l'instruction Call n'est plus générée. Parallèlement à cette modification, il est interdit d'appeler différents blocs avec le même argument name . Une telle opération entraînera une erreur.

  • Pour la plupart des architectures, à partir de la prochaine version de Qiskit Terra, 0.23, le paquet tweedledum deviendra une dépendance optionnelle, au lieu d'une exigence. C'est ce qu'utilisent actuellement certaines fonctions classiques d'oracle de phase. Si votre application ou votre bibliothèque a besoin de cette fonctionnalité, vous pouvez vous préparer en ajoutant immédiatement tweedledum aux dépendances de votre paquetage.

    tweedledum n'est plus obligatoire sur macOS arm64 ( M1 ) avec effet immédiat sur Qiskit Terra 0.22. En effet, les roues fournies pour cette plateforme sont cassées, et la construction à partir de la sdist n'est pas fiable pour la plupart des gens. Si vous installez manuellement une version fonctionnelle de tweedledum, toutes les fonctionnalités dépendantes continueront à fonctionner.

  • L'attribut ._layout de l'objet QuantumCircuit est passé du stockage d'un objet Layout pour stocker une classe de données avec 2 attributs, initial_layout qui contient un objet Layout pour la disposition initiale définie lors de la compilation et input_qubit_mapping qui contient un dictionnaire associant les qubits aux indices de position dans le circuit d'origine. Cette modification était nécessaire pour fournir toutes les informations permettant à un circuit post-transpilé d'inverser complètement la permutation causée par la disposition initiale dans toutes les situations. Bien que cet attribut soit privé et ne doive pas être utilisé à l'extérieur, c'est le seul moyen de suivre la mise en page initiale par l'intermédiaire de transpile() c'est pourquoi le changement est documenté au cas où vous vous en seriez servi. Si vous avez un cas d'utilisation de l'attribut _layout qui n'est pas pris en compte par l'API Qiskit, veuillez ouvrir un dossier afin que nous puissions combler cette lacune.

  • Les constructeurs de SetPhase, ShiftPhase, SetFrequency, et ShiftFrequency lèveront désormais un PulseError si la valeur transmise via l'argument channel n'est pas une instance de PulseChannel. Cette modification a été apportée pour s'assurer que les entrées des constructeurs sont valides, car les instructions ne sont valables que pour les canaux à impulsions et non pour d'autres types de canaux.

  • La fonction plot_histogram() a été modifiée pour renvoyer un véritable histogramme de valeurs discrètes binées. Le comportement précédent de la fonction était, malgré son nom, de générer une visualisation de la distribution de l'entrée. En raison de cette disparité entre le nom de la fonction et son comportement, le comportement de la fonction a été modifié de sorte qu'elle génère désormais un histogramme correct de données discrètes. Si vous souhaitez conserver le comportement précédent consistant à tracer une distribution de probabilité des données de comptage, vous pouvez utiliser la fonction plot_distribution() pour générer un graphique équivalent. Par exemple, le comportement précédent de plot_histogram({'00': 512, '11': 500}) peut être recréé avec :

    from qiskit.visualization import plot_distribution
    import matplotlib.pyplot as plt
    
    ax = plt.subplot()
    plot_distribution({'00': 512, '11': 500}, ax=ax)
    ax.set_ylabel('Probabilities')
  • Les contextes qiskit.pulse.builder , inline et pad ont été supprimés. Ils ont été supprimés pour la première fois dans Terra 0.18.0 (juillet 2021). Il n'y a pas de remplacement pour inline; on peut simplement écrire les impulsions dans l'oscilloscope contenant. Le gestionnaire de contexte pad n'a plus d'effet depuis qu'il a été déprécié.

  • La sortie de la passe SabreSwap (y compris lorsque optimization_level=3 ou routing_method ou layout_method sont remplacés par 'sabre' lors de l'appel à transpile()) avec une valeur de semence fixe peut 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 passe SabreSwap en 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 le levier qiskit.qpy pour sauvegarder le circuit et le charger ensuite avec la version actuelle.

  • Le comportement Layout.add() lorsque l'on ne spécifie pas de physical_bit a changé par rapport aux versions précédentes. Dans les versions précédentes, un nouveau bit physique était ajouté en fonction de la longueur de l'objet Layout de l'objet. Par exemple, si vous avez un Layout avec les bits physiques 1 et 3, les appels successifs à add() ajouteraient les bits physiques 2, 4, 5, 6, etc. Si les bits physiques étaient 2 et 3, les appels successifs ajouteraient 4, 5, 6, 7, etc. Ceci a été modifié de telle sorte qu'au lieu de cela Layout.add() ajoutera d'abord tous les bits physiques manquants entre 0 et le bit physique maximum contenu dans le fichier Layout. Ainsi, pour l'exemple 1 et 3, il ajoute maintenant 0, 2, 4, 5 et pour l'exemple 2 et 3, il ajoute 0, 1, 4, 5 au Layout. Cette modification a été apportée à la fois pour améliorer la prévisibilité du résultat et pour corriger une catégorie de bogues provoqués par le comportement inattendu. Comme les bits physiques d'un backend sont toujours des séquences contiguës de 0 à nn, l'ajout de nouveaux bits alors qu'il reste des bits physiques inutilisés pourrait amener la disposition à utiliser plus de bits que ceux disponibles sur le backend. Si vous souhaitez le comportement précédent, vous pouvez spécifier manuellement le bit physique désiré lorsque vous appelez Layout.add().

  • L'attribut SparsePauliOp.table , méthode obsolète, a été supprimé. Il était à l'origine obsolète dans Qiskit Terra 0.19. La méthode paulis() doit être utilisée à la place.

  • La possibilité de renvoyer une adresse PauliTable à partir de la fonction pauli_basis() a été supprimée. De même, l'argument pauli_list de la fonction pauli_basis() qui était utilisé pour passer à un PauliList (qui est désormais le seul type de retour) a été supprimé. Cette fonctionnalité a été supprimée dans la version de Qiskit Terra 0.19.

  • Les faux objets du backend FakeJohannesburg, FakeJohannesburgV2, FakeAlmaden, FakeAlmadenV2, FakeSingaporeet FakeSingaporeV2 ne contiennent plus les charges utiles d'impulsion par défaut. Cela signifie que pour les classes basées sur BackendV1 la méthode BackendV1.defaults() et la simulation d'impulsions par l'intermédiaire de la méthode BackendV1.run() ne sont plus disponibles. Pour les classes basées sur BackendV2 la propriété calibration pour les instructions de la classe Target n'est plus renseignée. Ce changement a été effectué parce que ces systèmes avaient des charges utiles de défauts d'impulsion excessivement importantes (au total ~50MB ) en raison de l'utilisation de formes d'ondes échantillonnées au lieu de définitions d'impulsions paramétriques. Ces trois fichiers utiles occupent plus de 50 % de l'espace disque nécessaire à l'installation de qiskit-terra. Si l'on compare la taille du fichier à la valeur potentielle de la possibilité de compiler avec la connaissance de l'impulsion ou de simuler l'impulsion de ces dispositifs retirés, le coût n'en vaut pas la peine. Si vous avez besoin d'exploiter ces propriétés, vous pouvez utiliser une ancienne version de Qiskit et utiliser qpy pour transférer les circuits des anciennes versions de Qiskit dans la version actuelle.

  • isinstance vérifier avec les classes de pouls Gaussian, GaussianSquare, Drag et Constant sera invalidé car ces sous-classes de pouls ne sont plus instanciées. Ils fonctionneront toujours dans Terra 0.22, mais vous devriez commencer la transition immédiatement. Au lieu d'utiliser des informations sur les types, il convient d'utiliser SymbolicPulse.pulse_type . On suppose qu'il s'agit d'un identificateur de chaîne unique pour les enveloppes d'impulsion, et nous pouvons utiliser l'égalité des chaînes pour étudier les types d'impulsion. Exemple :

    from qiskit.pulse.library import Gaussian
    
    pulse = Gaussian(160, 0.1, 40)
    
    if isinstance(pulse, Gaussian):
      print("This is Gaussian pulse.")

    Ce code devrait être mis à jour pour devenir

    from qiskit.pulse.library import Gaussian
    
    pulse = Gaussian(160, 0.1, 40)
    
    if pulse.pulse_type == "Gaussian":
      print("This is Gaussian pulse.")

    Pour la même raison, il ne faut pas accéder aux attributs de classe tels que pulse.__class__.__name__ pour obtenir des informations sur le type d'impulsion.

  • L'exception qiskit.exceptions.QiskitIndexError a été supprimée et n'existe plus selon la notice de dépréciation de qiskit-terra 0.18.0 (publiée le 12 juillet 2021).

  • Les arguments dépréciés epsilon et factr pour le constructeur de la classe L_BFGS_B ont été supprimés. Ces arguments étaient à l'origine dépréciés dans le cadre de la version 0.18.0 (publiée le 12 juillet 2021). A la place, l'argument ftol doit être utilisé, vous pouvez vous référer à la documentation scipy sur l'optimiseur pour plus de détails sur la relation entre ces arguments.

  • Les gestionnaires de passage prédéfinis pour les niveaux 1 et 2, qui seront utilisés lorsque optimization_level=1 ou optimization_level=2 avec transpile() ou generate_preset_pass_manager() et la sortie de level_1_pass_manager() et level_2_pass_manager()utiliseront désormais SabreLayout et SabreSwap par défaut au lieu des valeurs par défaut précédentes DenseLayout et StochasticSwap. Ce changement a été effectué pour améliorer la qualité de sortie du transpileur, la combinaison de SabreLayout et SabreSwap permet généralement de réduire le nombre d'objets insérés dans le circuit de sortie SwapGate d'objets insérés dans le circuit de sortie. Si vous souhaitez utiliser les anciennes passes par défaut, vous pouvez définir layout_method='dense' et routing_method='stochastic' sur transpile() ou generate_preset_pass_manager() pour tirer parti de DenseLayout et StochasticSwap respectivement.

  • L'utilisation implicite de approximation_degree!=1.0 par défaut dans la fonction transpile() lorsque optimization_level=3 est défini a été désactivée. Le transpileur doit, par défaut, préserver l'unitarité de l'entrée jusqu'aux transformations connues telles que les permutations unilatérales et les transformations de similarité. L'utilisation antérieure de approximation_degree=None a entraîné des résultats incorrects dans des cas tels que l'évolution trottérienne avec de nombreux pas de temps, où les unités étaient trop approximées, ce qui entraînait des résultats erronés. Il a été décidé que les transformations qui rompent l'équivalence unitaire devraient être explicitement activées par l'utilisateur. Si vous souhaitez le comportement par défaut précédent, où les instructions synthétisées UnitaryGate sont approximées jusqu'aux taux d'erreur des instructions natives du backend cible, vous pouvez explicitement définir approximation_degree=None lorsque vous appelez transpile() avec optimization_level=3, par exemple :

    transpile(circuit, backend, approximation_degree=None, optimization_level=3)
  • Modifier la valeur par défaut du nombre maximal d'évaluations de fonctions autorisées (maxfun) dans L_BFGS_B de 1000 à 15000 pour correspondre à la valeur par défaut de SciPy. Ce nombre correspond également au nombre d'itérations par défaut (maxiter).

  • Mise à jour ProbDistribution et QuasiDistribution pour stocker l'information sur le nombre de bits si des chaînes de bits sans préfixe “0b” sont données. ProbDistribution.binary_probabilities() et QuasiDistribution.binary_probabilities() utiliser le nombre de bits enregistré comme valeur par défaut du nombre de bits.

  • RZXCalibrationBuilder et RZXCalibrationBuilderNoEcho ont été améliorés pour sauter les portes CX d'étirement mises en œuvre par une séquence de résonance croisée sans écho (ECR) afin d'éviter que la passe ne se termine par des erreurs inattendues. Ces passes prennent un nouvel argument verbose qui contrôle si les passes avertissent lorsque cela se produit. Si verbose=True est activé, pass émet un avertissement à l'utilisateur lorsqu'il rencontre une séquence non ECR.

  • Le module de visualisation qiskit.visualization a fait l'objet d'une réorganisation interne. Cela ne devrait pas avoir d'incidence sur l'interface publique, mais si vous accédiez à des éléments internes des tiroirs de circuits, il se peut qu'ils se trouvent maintenant à des endroits différents. Les seules parties du module de visualisation qui sont considérées comme publiques sont les composants décrits dans cette documentation en ligne.

Remarques concernant la dépréciation

  • L'importation des noms Int1, Int2, classical_function et BooleanExpression directement à partir de qiskit.circuit est obsolète. Cela fait partie de la démarche visant à faire de tweedledum une dépendance optionnelle plutôt qu'une exigence complète. Au lieu de cela, vous devez importer ces noms à partir de qiskit.circuit.classicalfunction.

  • Les modules qiskit.algorithms.factorizers et qiskit.algorithms.linear_solvers sont obsolètes et seront supprimés dans une prochaine version. Ils sont remplacés par des tutoriels dans le manuel Qiskit : Shor HHL

  • Le site random_stabilizer_table() est obsolète et sera supprimé dans une prochaine version. Au lieu de cela, il faut utiliser la fonction random_pauli_list() doit être utilisée.

  • La fonction du module d'impulsion qiskit.pulse.utils.deprecated_functionality est obsolète et sera supprimée dans une prochaine version. Il s'agissait d'une fonction essentiellement interne. La même fonctionnalité est fournie par qiskit.utils.deprecate_function, qui doit être utilisé à la place.

  • La méthode d'exécution des primitives a été modifiée. Les méthodes BaseSampler.__call__() et BaseEstimator.__call__() sont obsolètes. Par exemple :

    estimator = Estimator(...)
    result = estimator(circuits, observables, parameters)
    
    sampler = Sampler(...)
    result = sampler(circuits, observables, parameters)

    doit être réécrite comme suit

    estimator = Estimator()
    result = estimator.run(circuits, observables, parameter_values).result()
    
    sampler = Sampler()
    result = sampler.run(circuits, parameter_values).result()

    L'utilisation de primitives comme gestionnaires de contexte est déconseillée. Toutes les primitives ne disposent pas d'un gestionnaire de contexte. Lorsqu'il est disponible (par exemple sur qiskit-ibm-runtime), le gestionnaire de contexte de la session fournit une fonctionnalité équivalente.

    circuits, observables, et parameters dans le constructeur a été déprécié. circuits et observables peuvent être transmises par les méthodes run . run ne prennent pas en charge parameters. Les utilisateurs doivent recourir eux-mêmes aux valeurs des paramètres.

  • L'argument inutilisé qubit_channel_mapping dans les RZXCalibrationBuilder et RZXCalibrationBuilderNoEcho ont été dépréciés et seront supprimés dans une prochaine version. Cet argument n'est plus utilisé et n'a aucun effet sur le fonctionnement des passes.

Corrections des erreurs

  • Correction d'un problème où Pauli.evolve() et PauliList.evolve() soulevait une erreur de type lors de l'évolution de certaines portes de Clifford qui modifiaient la phase de Pauli. Corrigé #8438

  • Correction d'un bug dans QuantumCircuit.initialize() et QuantumCircuit.prepare_state() qui faisait qu'ils n'acceptaient pas un seul Qubit comme argument pour l'initialisation.

  • La méthode QuantumCircuit.while_loop() résoudra maintenant les références de bits classiques dans sa condition de la même manière que QuantumCircuit.if_test() et InstructionSet.c_if() le font.

  • Les DAGCircuit méthodes depth(), size() et DAGCircuit.count_ops() renvoyaient auparavant silencieusement des résultats qui n'avaient que peu ou pas de signification si un flux de contrôle était présent dans le circuit. Les depth() et size() lèveront correctement une erreur dans ces cas, mais disposeront d'un nouvel argument recurse pour permettre le calcul d'une valeur proxy, tandis que les méthodes count_ops() se réintéressera par défaut aux blocs et comptera les opérations qui s'y trouvent.

  • Correction d'un problème dans la passe de DenseLayout transpiler où tous les objets Qubit (c.-à-d. ne faisant pas partie d'un objet QuantumRegister) qui faisaient partie d'un QuantumCircuit n'étaient pas inclus dans la sortie Layout générée par la passe.

  • La méthode du Operator.from_circuit() a été mise à jour afin qu'elle puisse gérer la sortie de l'agencement à partir de transpile() et inverser correctement la permutation des qubits causée par la disposition dans tous les cas. Auparavant, si votre circuit transpilé utilisait des objets en vrac, de multiples Qubit objets, plusieurs QuantumRegister ou un seul objet QuantumRegister avec un nom autre que "q" , le constructeur ne parvenait pas à créer un objet du circuit Operator à partir du circuit. Correction #8800.

  • Correction d'un bug où la décomposition d'une instruction avec un qubit et un bit classique contenant une seule porte quantique échouait. La décomposition suivante se fait maintenant comme prévu :

    block = QuantumCircuit(1, 1)
    block.h(0)
    
    circuit = QuantumCircuit(1, 1)
    circuit.append(block, [0], [0])
    
    decomposed = circuit.decompose()
  • Initialisation fixe de la matrice symplectique vide dans from_symplectic() dans la classe PauliList par exemple :

    from qiskit.quantum_info.operators import PauliList
    
    x = np.array([], dtype=bool).reshape((1,0))
    z = np.array([], dtype=bool).reshape((1,0))
    pauli_list = PauliList.from_symplectic(x, z)
  • Correction d'un problème dans la passe de GateDirection pour la passe de transpilation de l'élément CZGate. La porte CZ est symétrique, de sorte que l'inversion des arguments des qubits est autorisée pour correspondre à la carte de couplage dirigé.

  • Correction de problèmes avec la méthode DerivativeBase.gradient_wrapper() lors de la réutilisation d'un échantillonneur de circuit entre les appels et la liaison de paramètres imbriqués.

  • Correction d'un problème dans les tiroirs des circuits mpl et latex , lorsque le réglage de l'option idle_wires sur False alors qu'il y avait un barrier dans le circuit entraînait l'échec des tiroirs, a été corrigé. Corrigé #8313

  • Correction d'un problème dans circuit_drawer() et QuantumCircuit.draw() avec la méthode latex qui provoquait l'apparition de OSError sur les systèmes dont les répertoires temporaires (par exemple /tmp) se trouvent sur un système de fichiers différent de celui du répertoire de travail. Corrige #8542

  • Emboîtement d'un FlowController à l'intérieur d'un autre dans un PassManager pouvait auparavant faire en sorte que certaines passes de transpilation soient "oubliées" pendant la transpilation, si les passes renvoyaient un nouveau DAGCircuit au lieu de modifier leur entrée. Les FlowControllerimbriqués affecteront désormais correctement la transpilation.

  • Comparaison entre QuantumCircuit et DAGCircuitpour l'égalité était auparavant non déterministe si les circuits contenaient plus d'un registre du même type (par exemple, deux ou plusieurs QuantumRegister), renvoyant parfois False même si les registres étaient identiques. Il compare désormais correctement les circuits à registres multiples.

  • L'exportateur OpenQASM 2 (QuantumCircuit.qasm()) définira désormais correctement les paramètres des qubits pour les opérations de UnitaryGate qui n'affectent pas tous les qubits sur lesquels ils sont définis. Correction #8224.

  • Deux bogues dans le tiroir du circuit text ont été corrigés. Ceux-ci sont apparus lorsque vertical_compression a été remplacé par medium, qui est la valeur par défaut. La première cause parfois l'écrasement d'autres textes ou d'autres portes, et la seconde provoque parfois la rupture des connexions entre une porte et ses commandes. Voir #8588.

  • Correction d'un problème avec le UnitarySynthesis où un circuit avec des portes à 1 qubit et une entrée Target échouait parfois au lieu de traiter le circuit comme prévu.

  • La passe du transpondeur GateDirection respecte désormais les valeurs disponibles pour les paramètres des portes lorsqu'il manipule des portes paramétrées avec un paramètre Target.

  • Correction d'un problème dans la classe SNOBFIT lorsqu'une erreur interne était levée lors de l'exécution de la méthode minimize() si aucune borne d'entrée n'était spécifiée. Ce point est désormais vérifié au moment de l'appel afin d'envoyer rapidement un message à ValueError si les bornes requises ne sont pas présentes dans l'appel minimize() appel. Corrige #8580

  • Correction d'un problème dans l'appel de sortie de la méthode get_energy_evaluation() de la classe VQD appelle désormais correctement l'adresse callback spécifiée lorsqu'elle est exécutée. Auparavant, le rappel n'était pas utilisé dans ce cas. Corrigé #8575

  • Correction d'un problème lorsque circuit_drawer() était utilisé avec reverse_bits=True sur un circuit sans bits classiques, ce qui entraînait l'émission d'un avertissement potentiellement déroutant à propos de cregbundle . Corrigé #8690

  • L'exportateur OpenQASM 3 (qiskit.qasm3) traitera maintenant correctement les composants OpenQASM (tels que reset et measure) qui ont une condition classique appliquée par c_if(). Auparavant, cette condition aurait été ignorée.

  • Correction d'un problème avec la classe SPSA qui essayait de regrouper les travaux en lots de taille égale, ce qui soulevait une exception si la création de lots de taille égale n'était pas possible. Ce problème a été corrigé de manière à ce que les travaux soient toujours mis en lots avec succès, même s'ils ne sont pas de taille égale.

  • Correction du comportement de Layout.add() qui pouvait entraîner l'invalidité de la sortie de transpile() était invalide et contenait plus de Qubits que ce qui était disponible sur le backend cible. Fixe : #8667

  • Correction d'un problème avec la fonction state_to_latex() : le passage d'une chaîne latex à l'argument optionnel prefix de la fonction entraînait une erreur. Corrigé #8460

  • La fonction state_to_latex() a produit une version non valide de LaTeX en présence de valeurs proches de zéro, ce qui entraîne des erreurs lors de l'appel de state_drawer() . Correction #8169.

  • GradientDescent comptera désormais correctement le nombre d'itérations, d'évaluations de fonctions et d'évaluations de gradient. De plus, la documentation indique maintenant correctement que le gradient est approximé par une méthode de différence finie.

  • Correction des avertissements de dépréciation dans NaturalGradientqui utilise désormais StandardScaler pour mettre à l'échelle les données avant d'ajuster le modèle si le paramètre normalize est réglé sur True.

Aer 0.11.0

Pas de modification

IBM 0.19.2 du fournisseur Q

Pas de modification

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