Skip to main content
IBM Quantum Platform

Notes de publication de Qiskit 0.37


0.37.2

Terra 0.21.2

Prélude

Qiskit Terra 0.21.2 est principalement une version de correction de bogues, et vient également avec plusieurs pages de documentation améliorées.

Corrections des erreurs

  • aer_simulator_statevector_gpu sera désormais reconnue correctement comme une méthode statevector dans certaines fonctions lors de l'utilisation des simulateurs GPU de Qiskit Aer dans QuantumInstance et d'autres algorithmes.

  • Correction de la méthode UCGate.inverse() qui, auparavant, n'inversait pas la phase globale.

  • QuantumCircuit.compose() fonctionne désormais correctement lorsqu'il est utilisé avec l'argument inplace=True dans des contextes de construction de flux de contrôle. Auparavant, les instructions étaient ajoutées en dehors du flux de contrôle. Correction #8433.

  • Correction d'un bogue où une expression liée ParameterExpression n'était pas identifiée comme réelle si symengine était installé et que l'expression liée n'était pas une simple 1j. Par exemple :

    from qiskit.circuit import Parameter
    
    x = Parameter("x")
    expr = 1j * x
    bound = expr.bind({x: 2})
    print(bound.is_real())  # used to be True, but is now False
  • Correction de la sérialisation et de la désérialisation QPY de ControlledGate avec des contrôles ouverts (c'est-à-dire ceux dont ctrl_state n'est pas tout un). Correction #8549.

  • Tous les faux backends de qiskit.providers.fake_provider.backends ont été mis à jour pour renvoyer les objets de canal d'impulsion correspondants avec l'appel de méthode de drive_channel(), measure_channel(), acquire_channel(), control_channel().

  • Correction de la prise en charge de l'exécution de Z2Symmetries.taper() sur des problèmes plus importants. Auparavant, la méthode nécessitait une grande quantité de mémoire, ce qui entraînait généralement des échecs pour les problèmes plus importants. Cette correction a eu pour effet secondaire d'améliorer considérablement les performances.

Aer 0.10.4

Pas de modification

IBM 0.19.2 du fournisseur Q

Pas de modification


0.37.1

Terra 0.21.1

Corrections des erreurs

  • Correction d'un problème dans la méthode QuantumCircuit.decompose() lors du passage d'une liste de classes Gate pour l'argument gates_to_decompose . Si l'une des portes du circuit avait une étiquette définie, cet argument ne serait pas traité correctement et la décomposition de sortie sauterait incorrectement les portes figurant explicitement dans la liste gates_to_decompose .

  • Fixe to_instruction() qui tentait auparavant de créer un UnitaryGate sans exponentialiser l'opérateur à faire évoluer. Comme cet opérateur n'est généralement pas unitaire, une erreur s'est produite (et si l'opérateur avait été unitaire par hasard, cela n'aurait pas été le résultat escompté).

    L'appel de to_instruction() produit correctement une porte qui met en œuvre l'évolution temporelle de l'opérateur qu'elle détient :

    >>> from qiskit.opflow import EvolvedOp, X
    >>> op = EvolvedOp(0.5 * X)
    >>> op.to_instruction()
    Instruction(
        name='unitary', num_qubits=1, num_clbits=0,
        params=[array([[0.87758256+0.j, 0.-0.47942554j], [0.-0.47942554j, 0.87758256+0.j]])]
    )
  • Correction d'un problème avec la fonction marginal_distribution() : lorsqu'un tableau numpy était passé en argument indices , la fonction soulevait une erreur. Corrigé #8283

  • Auparavant, il n'était pas possible d'adjoindre un CircuitStateFn construit à partir d'un VectorStateFn. C'est parce que le vecteur d'état a été converti en circuit avec l'instruction Initialize , qui n'est pas unitaire. Ce problème est désormais résolu par l'utilisation de l'instruction StatePreparation qui peut être utilisée puisque l'état est supposé commencer dans l'état 0.

    Par exemple, nous pouvons maintenant faire :

    from qiskit import QuantumCircuit
    from qiskit.opflow import StateFn
    
    left = StateFn([0, 1])
    left_circuit = left.to_circuit_op().primitive
    
    right_circuit = QuantumCircuit(1)
    right_circuit.x(0)
    
    overlap = left_circuit.inverse().compose(right_circuit)  # this line raised an error before!
  • Correction d'un bogue dans les classes Optimizer où la reconstruction d'une nouvelle instance d'optimiseur à partir d'une instance existante précédemment réinitialisait les paramètres du nouvel optimiseur et de l'ancien à leurs valeurs par défaut settings réinitialisait les paramètres par défaut du nouvel optimiseur et de l'ancien. Cela a notamment conduit à un bogue si des objets Optimizer étaient envoyés en entrée des programmes Qiskit Runtime.

    Les objets de l'optimiseur sont désormais correctement reconstruits :

    >>> from qiskit.algorithms.optimizers import COBYLA
    >>> original = COBYLA(maxiter=1)
    >>> reconstructed = COBYLA(**original.settings)
    >>> reconstructed._options["maxiter"]
    1  # used to be 1000!
  • Correction d'un problème où l'argument limit_amplitude sur un individu SymbolicPulse ou Waveform n'était pas correctement pris en compte par la validation des paramètres. En outre, le calendrier QPY dump() a été corrigé pour stocker correctement la valeur limit_amplitude liée à l'instance, au lieu de sauvegarder la variable de classe globale.

  • Fixer la structure d'enchevêtrement par paire pour les NLocal circuits. Cela a conduit à un bogue dans l'application ZZFeatureMapoù l'utilisation de entanglement="pairwise" provoquait une erreur. Il produit maintenant correctement la carte de caractéristiques souhaitée :

    from qiskit.circuit.library import ZZFeatureMap
    encoding = ZZFeatureMap(4, entanglement="pairwise", reps=1)
    print(encoding.decompose().draw())

    Les impressions ci-dessus :

         ┌───┐┌─────────────┐
    q_0: ┤ H ├┤ P(2.0*x[0]) ├──■────────────────────────────────────■────────────────────────────────────────────
         ├───┤├─────────────┤┌─┴─┐┌──────────────────────────────┐┌─┴─┐
    q_1: ┤ H ├┤ P(2.0*x[1]) ├┤ X ├┤ P(2.0*- x[0])*- x[1])) ├┤ X ├──■────────────────────────────────────■──
         ├───┤├─────────────┤└───┘└──────────────────────────────┘└───┘┌─┴─┐┌──────────────────────────────┐┌─┴─┐
    q_2: ┤ H ├┤ P(2.0*x[2]) ├──■────────────────────────────────────■──┤ X ├┤ P(2.0*- x[1])*- x[2])) ├┤ X ├
         ├───┤├─────────────┤┌─┴─┐┌──────────────────────────────┐┌─┴─┐└───┘└──────────────────────────────┘└───┘
    q_3: ┤ H ├┤ P(2.0*x[3]) ├┤ X ├┤ P(2.0*- x[2])*- x[3])) ├┤ X ├──────────────────────────────────────────
         └───┘└─────────────┘└───┘└──────────────────────────────┘└───┘
  • Correction d'un problème dans la gestion de la phase globale de la classe UCGate classe.

Aer 0.10.4

Pas de modification

IBM 0.19.2 du fournisseur Q

Pas de modification


0.37.0

Cette version marque officiellement la fin du support du projet Qiskit Ignis par Qiskit. Il était à l'origine déprécié dans la version 0.33.0 et, comme cela a été documenté dans cette version, le paquet qiskit-ignis a été retiré du métapaquet Qiskit, ce qui signifie que dans cette future version pip install qiskit n'inclura plus qiskit-ignis. Cependant, en raison des limitations de l'emballage de Python, nous ne pouvons pas supprimer automatiquement une installation préexistante de qiskit-ignis. Si vous mettez à jour une version précédente, il est recommandé de désinstaller manuellement Qiskit Ignis avec pip uninstall qiskit-ignis ou d'installer le métapackage dans un nouvel environnement Python.

Qiskit Ignis a été supplanté par le projet Qiskit Experiments. Vous pouvez vous référer au guide de migration pour plus de détails sur la façon de passer de Qiskit Ignis à Qiskit Experiments.

Terra 0.21.0

Prélude

Les points forts de la version de Qiskit 0.21.0 sont les suivants :

  • Prise en charge de la sérialisation d'une impulsion ScheduleBlock via qiskit.qpy. Le format QPY a été mis à jour à la version 5 qui comprend une définition pour l'inclusion des horaires d'impulsions. Pour ce faire, une nouvelle classe SymbolicPulse a été introduite pour permettre de définir des formes d'impulsion paramétriques au moyen d'expressions symboliques.
  • Amélioration de l'utilisation des gestionnaires de laissez-passer prédéfinis. Une nouvelle fonction generate_preset_pass_manager() permet de générer facilement un gestionnaire de passe équivalent à celui que transpile() utilisera en interne. En outre, les gestionnaires de passes prédéfinies sont désormais des instances de StagedPassManager ce qui facilite la modification des sections.
  • Une refonte de la structure de données interne de l'attribut QuantumCircuit.data attribut. Il s'agissait auparavant d'une liste de tuples sous la forme (instruction, qubits, clbits) et il s'agit maintenant d'une liste d'objets CircuitInstruction objets. Les objets CircuitInstruction est rétrocompatible avec l'accès précédent basé sur les n-uplets, mais avec des frais généraux d'exécution.

En outre, le transpondeur a été amélioré pour permettre des sorties de meilleure qualité. Il s'agit notamment de l'introduction de nouveaux laissez-passer tels que VF2PostLayout et ToqmSwap.

Nouvelles fonctions

  • Ajout d'une nouvelle classe, qiskit.transpiler.StagedPassManagerqui est une sous-classe de PassManager qui possède un pipeline avec des phases définies pour effectuer la compilation des circuits. Chaque phase est un objet PassManager qui sera exécuté dans un ordre déterminé. Par exemple :

    from qiskit.transpiler.passes import *
    from qiskit.transpiler import PassManager, StagedPassManager
    
    basis_gates = ['rx', 'ry', 'rxx']
    init = PassManager([UnitarySynthesis(basis_gates, min_qubits=3), Unroll3qOrMore()])
    translate = PassManager([Collect2qBlocks(),
                             ConsolidateBlocks(basis_gates=basis_gates),
                             UnitarySynthesis(basis_gates)])
    
    staged_pm = StagedPassManager(stages=['init', 'translation'], init=init, translation=translate)
  • Ajout des méthodes PauliList.group_commuting() et SparsePauliOp.group_commuting()qui partitionnent ces opérateurs en sous-listes dont chaque élément commute avec tous les autres. Par exemple :

    from qiskit.quantum_info import PauliList, SparsePauliOp
    
    groups = PauliList(["XX", "YY", "IZ", "ZZ"]).group_commuting()
    # 'groups' is [PauliList(['IZ', 'ZZ']), PauliList(['XX', 'YY'])]
    
    op = SparsePauliOp.from_list([("XX", 2), ("YY", 1), ("IZ", 2j), ("ZZ", 1j)])
    groups = op.group_commuting()
    # 'groups' is [
    #     SparsePauliOp(['IZ', 'ZZ'], coeffs=[0.+2.j, 0.+1.j]),
    #     SparsePauliOp(['XX', 'YY'], coeffs=[2.+0.j, 1.+0.j]),
    # ]
  • Ajout d'une nouvelle fonction, marginal_distribution()qui est utilisée pour marginaliser un dictionnaire de chaînes de bits vers un entier (tel que Counts). Cette fonction est similaire à la fonction existante, à trois différences près marginal_counts() existante, à trois différences près. La première est que marginal_counts() fonctionne avec un dictionnaire de comptes ou un objet Results , alors que marginal_distribution() ne fonctionne qu'avec un dictionnaire. La seconde est que marginal_counts() ne respecte pas l'ordre des indices dans son argument indices alors que marginal_distribution() le fait et permute les bits de sortie en fonction de l'ordre indices . La troisième différence est que marginal_distribution() devrait être plus rapide car son implémentation est écrite en Rust et rationalisée pour marginaliser une entrée de dictionnaire.

  • Ajout de l'opérateur binaire @ (__matmul__) aux sous-classes de BaseOperator dans le module qiskit.quantum_info module. Il s'agit d'un raccourci pour appeler la méthode dot de la classe (A @ B == A.dot(B)).

  • Ajout d'un nouvel argument facultatif, reps, à QuantumCircuit.decompose()qui permet la décomposition répétée du circuit. Par exemple :

    from qiskit import QuantumCircuit
    
    circuit = QuantumCircuit(1)
    circuit.ry(0.5, 0)
    
    # Equivalent to circuit.decompose().decompose()
    circuit.decompose(reps=2)
    
    # decompose 2 times, but only RY gate 2 times and R gate 1 times
    circuit.decompose(gates_to_decompose=['ry','r'], reps=2)
  • Ajout d'une nouvelle classe de base d'impulsion SymbolicPulse. Il s'agit d'un remplacement de la méthode conventionnelle ParametricPulsequi sera obsolète. Dans la nouvelle classe de base, les fonctions d'enveloppe d'impulsion et de validation des paramètres sont représentées par des objets d'expression symbolique. La nouvelle classe fournit des données d'impulsion autonomes et portables puisque ces équations symboliques peuvent être facilement sérialisées par le biais de bibliothèques de calcul symbolique.

  • Ajout de la prise en charge des opérateurs non hermitiens en AerPauliExpectation. Cela permet d'utiliser les calculs rapides de l'espérance instantanée d'Aer dans des algorithmes tels que QEOM.

  • Ajout d'un nouveau style de dessin de circuit, textbook, qui utilise le schéma de couleurs du manuel Qiskit.

  • Un nouvel attribut QuantumCircuit.op_start_times est rempli lorsque l'une des passes d'analyse d'ordonnancement est exécutée sur le circuit. Il peut être utilisé pour obtenir une instruction de circuit avec le temps d'instruction, par exemple :

    from qiskit import QuantumCircuit, transpile
    from qiskit.providers.fake_provider import FakeMontreal
    
    backend = FakeMontreal()
    
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    
    qct = transpile(
        qc, backend, initial_layout=[0, 1], coupling_map=[[0, 1]], scheduling_method="alap"
    )
    scheduled_insts = list(zip(qct.op_start_times, qct.data))
  • Ajout d'une nouvelle méthode QuantumCircuit.clear() qui est utilisée pour supprimer toutes les instructions d'un fichier QuantumCircuit.

  • Ajout d'une nouvelle méthode QuantumCircuit.copy_empty_like() qui permet d'obtenir une copie effacée d'une instance de QuantumCircuit instance. Cette méthode est logiquement équivalente à qc.copy().clear(), mais elle est nettement plus rapide et plus efficace en termes de mémoire. Cela est utile lorsque l'on a besoin d'un nouveau circuit vide avec toutes les mêmes ressources (qubits, bits classiques, métadonnées, etc.) déjà ajoutées.

  • La méthode Target.instruction_supported() prend désormais en charge deux nouveaux arguments de type mot-clé, operation_class et parameters. En utilisant ces arguments, la méthode instruction_supported() peut maintenant être utilisée pour vérifier qu'une opération spécifique avec des valeurs de paramètres est supportée par un objet Target objet. Par exemple, si vous voulez vérifier si un site Web nommé Target nommé target supporte l'exécution d'un RXGate avec θ=π2\theta = \frac{\pi}{2}, vous feriez quelque chose comme :

    from math import pi
    from qiskit.circuit.library import RXGate
    
    target.instruction_supported(operation_class=RXGate, parameters=[pi/2])

    qui renverra True si target est compatible avec l'exécution de RXGate avec θ=π2\theta = \frac{\pi}{2} et False si ce n'est pas le cas.

  • Ajout d'un algorithme d'évolution quantique en temps réel basé sur la trotterisation qiskit.algorithms.TrotterQRTE. Il est conforme au nouveau cadre d'évolution temporelle quantique et fait appel à la méthode des ProductFormula et PauliEvolutionGate et les implémentations.

    from qiskit.algorithms import EvolutionProblem
    from qiskit.algorithms.evolvers.trotterization import TrotterQRTE
    from qiskit.opflow import X, Z, StateFn, SummedOp
    
    operator = SummedOp([X, Z])
    initial_state = StateFn([1, 0])
    time = 1
    evolution_problem = EvolutionProblem(operator, time, initial_state)
    
    trotter_qrte = TrotterQRTE()
    evolution_result = trotter_qrte.evolve(evolution_problem)
    evolved_state_circuit = evolution_result.evolved_state
  • Ajout d'une nouvelle fonction generate_preset_pass_manager() qui peut être utilisée pour générer rapidement un objet prédéfini PassManager qui reflète l'objet PassManager utilisé en interne par la fonction transpile() fonction. Par exemple :

    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    from qiskit.providers.fake_provider import FakeWashingtonV2
    
    # Generate an optimization level 3 pass manager targeting FakeWashingtonV2
    pass_manager = generate_preset_pass_manager(3, FakeWashingtonV2())
  • Ajout d'une nouvelle fonction marginal_memory() qui est utilisée pour marginaliser les tableaux de mémoire de tir. Si l'on fournit le tableau de mémoire des prises de vue et les indices d'intérêt, la fonction renvoie un tableau de mémoire des prises de vue maginisé. Cette fonction diffère de la prise en charge de la mémoire dans la méthode marginal_counts() qui ne fonctionne que sur le champ memory d'un objet Results .

  • L'interface des primitives a été étendue pour accepter des objets en plus des indices comme arguments de la méthode __call__ . L'argument parameter_values peut désormais être facultatif.

  • L'exportateur OpenQASM 3 (qiskit.qasm3) supporte maintenant l'exportation de circuits avec des retards explicites, comme ceux de QuantumCircuit.delay().

  • Ajout d'une nouvelle méthode d'agencement et de routage à transpile() basée sur l'article "Time-optimal qubit mapping". Pour l'utiliser, le paquetage optionnel Qiskit TOQM doit être installé. Le kwarg routing_method de transpile() prend en charge une valeur supplémentaire, 'toqm' , qui est utilisée pour permettre la mise en page et le routage via TOQM.

    Pour installer qiskit-toqm en même temps que Terra, exécutez :

    pip install qiskit-terra[toqm]
  • Ajout d'un nouveau module qiskit.quantum_info.synthesis.qsd pour appliquer la décomposition quantique de Shannon à des unitaires arbitraires. Cette fonctionnalité remplace l'ancienne approche basée sur l'isométrie dans la passe du transpondeur de synthèse unitaire par défaut ainsi que lors de l'ajout d'éléments unitaires à un circuit à l'aide d'un fichier UnitaryGate.

    La décomposition quantique de Shannon utilise environ la moitié des portes cnot que l'implémentation isométrique lors de la décomposition de matrices unitaires de plus de deux qubits.

  • Les classes du module quantum_info qui supportent la multiplication scalaire peuvent maintenant être multipliées par un scalaire à partir de la gauche ou de la droite. Auparavant, ils n'acceptaient que les multiplicateurs scalaires de gauche.

  • Le passeur de transpondeurs LookaheadSwap (utilisé par transpile() lorsque routing_method="lookahead") a vu ses performances améliorées et sera désormais environ trois fois plus rapide. Il s'agit d'une simple amélioration de l'efficacité des calculs, qui ne modifie pas la complexité de l'algorithme. Dans la plupart des cas, un algorithme de routage plus moderne comme SabreSwap (routing_method="sabre") sera beaucoup plus performant.

  • De nouveaux laissez-passer pour les transpondeurs ont été ajoutés. La passe de transposition Commuting2qGateRouter utilise des stratégies d'échange pour acheminer un bloc de portes de commutation vers la carte de couplage. En effet, le routage est un problème difficile, mais il est nettement plus facile lorsque les portes se croisent, comme dans les réseaux CZ. Les blocs de portes de migration alternante sont également typiques de l'AQAO. Ces cas peuvent être traités à l'aide de stratégies d'échange qui appliquent un ensemble prédéfini de couches de portes SWAP. En outre, la nouvelle passe de transpilation FindCommutingPauliEvolutions identifie les blocs d'évolutions de Pauli constitués de termes à deux qubits commutés. Ici, une stratégie d'échange est spécifiée par la classe SwapStrategy. Les stratégies d'échange doivent être adaptées à la carte de couplage et, idéalement, au circuit pour obtenir les meilleurs résultats.

  • Introduction d'un nouvel optimiseur dans la bibliothèque Qiskit, qui permet d'optimiser les paramètres des algorithmes quantiques variationnels. Il s'agit de l'algorithme de distribution marginale univariée (UMDA), qui est un type spécifique d'algorithme d'estimation de distribution. Par exemple :

    from qiskit.opflow import X, Z, I
    from qiskit import Aer
    from qiskit.algorithms.optimizers import UMDA
    from qiskit.algorithms import QAOA
    from qiskit.utils import QuantumInstance
    
    H2_op = (-1.052373245772859 * I ^ I) + \
            (0.39793742484318045 * I ^ Z) + \
            (-0.39793742484318045 * Z ^ I) + \
            (-0.01128010425623538 * Z ^ Z) + \
            (0.18093119978423156 * X ^ X)
    
    p = 2  # Toy example: 2 layers with 2 parameters in each layer: 4 variables
    
    opt = UMDA(maxiter=100, size_gen=20)
    backend = Aer.get_backend('statevector_simulator')
    vqe = QAOA(opt,
               quantum_instance=QuantumInstance(backend=backend),
               reps=p)
    
    result = vqe.compute_minimum_eigenvalue(operator=H2_op)
  • Le constructeur de la passe Unroll3qOrMore a deux nouveaux arguments optionnels, target et basis_gates. Ces options vous permettent de spécifier les portes de base Target ou les portes de base prises en charge, respectivement, pour décrire le backend cible. Si l'une des opérations du circuit se trouve sur target ou basis_gates , elle ne sera pas déroulée par la passe car l'appareil cible dispose d'un support natif pour l'opération.

  • La sérialisation QPY a été mise à jour pour prendre en charge les fichiers ScheduleBlock. Vous pouvez maintenant sauvegarder le programme d'impulsion en binaire et le charger ultérieurement :

    from qiskit import pulse, qpy
    
    with pulse.build() as schedule:
        pulse.play(pulse.Gaussian(160, 0.1, 40), pulse.DriveChannel(0))
    
    with open('schedule.qpy', 'wb') as fd:
        qpy.dump(schedule, fd)
    
    with open('schedule.qpy', 'rb') as fd:
        new_schedule = qpy.load(fd)[0]

    Il utilise l'interface QPY commune à QuantumCircuit. Voir SCHEDULE_BLOCK pour plus de détails sur la structure des données.

  • Ajout d'une nouvelle passe de transpilateur, VF2PostLayout. Cette passe est d'un nouveau type pour réaliser une nouvelle phase/fonction dans le pipeline de compilation, après la mise en page ou la sélection des qubits après l'optimisation. L'idée derrière ce passage est qu'après avoir terminé la boucle d'optimisation dans le transpiler, nous connaissons le nombre final de portes sur chaque qubit du circuit, ce qui nous permet de trouver un sous-ensemble de qubits plus performant sur un backend pour exécuter le circuit. La passe recherchera un sous-graphe isomorphe dans le graphe de connectivité du backend cible et examinera le taux d'erreur total du circuit complet sur tout sous-graphe trouvé et renverra la disposition trouvée avec le taux d'erreur le plus bas pour le circuit.

    Cette passe est similaire à la passe VF2Layout et les deux utilisent en interne la même implémentation VF2 de retworkx. Cependant, VF2PostLayout est conçu pour s'exécuter après la mise en page initiale, le routage, la translation de base et toutes les passes d'optimisation. Il ne fonctionnera que si une mise en page a déjà été appliquée, si le circuit a été routé et si toutes les portes se trouvent dans la base cible. Ceci est nécessaire pour que, lorsqu'une nouvelle disposition est appliquée, le circuit puisse toujours être exécuté sur l'appareil cible. VF2Layout quant à lui, est conçu pour trouver une disposition initiale parfaite et peut fonctionner avec n'importe quel circuit.

  • La passe ApplyLayout transpiler prend désormais en charge la mise à jour d'une mise en page sur un circuit après qu'une mise en page a été appliquée une première fois. Si le champ post_layout est présent (en plus du champ obligatoire layout ), le property_set lors de l'exécution du laissez-passer mettra à jour la présentation pour appliquer la nouvelle présentation ApplyLayout le pass mettra à jour la mise en page pour appliquer la nouvelle mise en page. Cela renverra un DAGCircuit avec les qubits dans le nouvel ordre physique et l'ensemble de propriétés layout sera mis à jour afin de faire correspondre les qubits virtuels de la disposition originale aux qubits physiques dans le nouveau champ post_layout .

  • Les gestionnaires de passes prédéfinies générées par level_1_pass_manager(), level_2_pass_manager(), et level_3_pass_manager() qui correspondent respectivement aux adresses optimization_level 1, 2 et 3 de la fonction transpile() exécutent maintenant la passe VF2PostLayout après avoir exécuté la passe de routage. Cela permet au transpileur de trouver potentiellement un ensemble différent de qubits physiques sur le backend cible pour exécuter le circuit sur lequel les taux d'erreur sont plus faibles. La passe VF2PostLayout ne sera pas exécutée si vous spécifiez manuellement les arguments layout_method, routing_method, ou initial_layout à la commande transpile(). Si le pass peut trouver un sous-ensemble de qubits plus performant sur le backend pour faire fonctionner le circuit physique, il ajustera la disposition du circuit pour utiliser les qubits alternatifs à la place.

  • L'algorithme calcule itérativement chaque état propre en commençant par l'état fondamental (qui est calculé comme dans VQE) et en optimisant ensuite une fonction de coût modifiée qui tente de calculer les états propres qui sont orthogonaux aux états calculés dans les itérations précédentes et qui ont l'énergie la plus faible lorsqu'ils sont calculés sur l'ansatz. L'interface mise en œuvre est très similaire à celle de VQE et se présente sous la forme suivante :

    from qiskit.algorithms import VQD
    from qiskit.utils import QuantumInstance
    from qiskit.circuit.library import TwoLocal
    from qiskit.algorithms.optimizers import COBYLA
    from qiskit import BasicAer
    from qiskit.opflow import I,Z,X
    
    h2_op = (
        -1.052373245772859 * (I ^ I)
        + 0.39793742484318045 * (I ^ Z)
        - 0.39793742484318045 * (Z ^ I)
        - 0.01128010425623538 * (Z ^ Z)
        + 0.18093119978423156 * (X ^ X)
    )
    
    vqd = VQD(k =2, ansatz = TwoLocal(rotation_blocks="ry", entanglement_blocks="cz"),optimizer = COBYLA(maxiter = 0), quantum_instance = QuantumInstance(
                BasicAer.get_backend("qasm_simulator"), shots = 2048)
            )
    vqd_res = vqd.compute_eigenvalues(op)

    Cet extrait de code particulier génère 2 valeurs propres (état fondamental et premier état excité). Des tests ont également été mis en œuvre.

Mise à niveau

  • Les classes de pouls dans qiskit.pulse.library sont maintenant des sous-classes de SymbolicPulse et non plus de ParametricPulse. Les classes disponibles restent inchangées Gaussian, GaussianSquare, Drag, et Constant. SymbolicPulse offre une compatibilité ascendante totale, et il ne devrait pas y avoir de perte de fonctionnalité.

  • Le type de données de chaque élément de QuantumCircuit.data a changé. Auparavant, il s'agissait d'un simple triplet composé d'un Instructiond'une liste de Qubitet d'une liste de Clbits, alors qu'il s'agit maintenant d'une instance de CircuitInstruction.

    Les attributs de cette nouvelle classe sont les suivants operation, qubits et clbitscorrespondant aux éléments du tuple précédent. Cependant, qubits et clbits sont maintenant des instances tuple et non list.

    Cette nouvelle classe se comportera exactement comme l'ancien 3-tuple si l'on tente d'accéder à son index, à ses éléments ou de les parcourir. Il s'agit notamment de lancer les qubits et clbits en listes. Cela permet d'assurer la compatibilité ascendante. À partir de Qiskit Terra 0.21, ce n'est plus la manière préférée d'accéder à ces éléments. Au lieu de cela, vous devez utiliser la forme d'accès aux attributs décrite ci-dessus.

    Cela a été fait pour permettre des développements ultérieurs de la structure de données dans Terra, sans rompre constamment la compatibilité ascendante QuantumCircuit dans Terra, sans rompre constamment la compatibilité ascendante. Les développements prévus comprennent des circuits dynamiques paramétrés et une réduction globale de l'utilisation de la mémoire des circuits profonds.

  • La dépendance python-constraint , qui est utilisée uniquement par la passe de transposition CSPLayout n'est plus dans la liste des exigences du paquet Qiskit Terra. Cela s'explique par le fait que le CSPLayout n'est plus utilisée par défaut dans aucun des gestionnaires de passe prédéfinis pour transpile(). Bien que le pass soit toujours disponible, si vous l'utilisez, vous devrez installer manuellement python-contraint ou, lorsque vous installez qiskit-terra , vous pouvez utiliser l'extra csp-layout , par exemple :

    pip install "qiskit-terra[csp-layout]"
  • La version du format QPY émise par qpy.dump() est passé à la version 5. Cette nouvelle version du format est incompatible avec les versions précédentes et provoquera une erreur si l'on tente de la charger avec un désérialiseur qui n'est pas en mesure de gérer la version 5 de QPY. Cette modification était nécessaire pour permettre de représenter correctement les portes contrôlées et les états de contrôle autres que ceux par défaut.

  • Les extensions Rust compilées de Qiskit Terra ont maintenant une version Rust minimale supportée (MSRV) de 1.56.1. Cela signifie que lorsque Qiskit Terra est construit à partir des sources, la version la plus ancienne du compilateur Rust prise en charge est 1.56.1. Si vous utilisez une ancienne version du compilateur Rust, vous devrez la mettre à jour pour continuer à construire Qiskit à partir des sources. Ce changement était nécessaire car un certain nombre de dépendances en amont ont également mis à jour leurs versions minimales supportées.

  • La planification des circuits s'exécute désormais en parallèle lorsque plus d'un circuit est prévu pour schedule(). Pour plus de détails, voir le numéro 2695.

  • Les classes BaseBackend, BaseJob et BaseProvider , précédemment obsolètes, ont toutes été supprimées. Ils étaient à l'origine dépréciés dans la version 0.18.0. Au lieu de ces classes, vous devriez utiliser les classes d'interface des fournisseurs versionnées, les plus récentes étant BackendV2, JobV1, et ProviderV1.

  • L'argument backend pour le constructeur de la passe de RZXCalibrationBuilder a été supprimé. Il était à l'origine obsolète dans la version 0.19.0. Au lieu de cela, vous devez interroger l'objet Backend pour obtenir les adresses instruction_schedule_map et qubit_channel_mapping et les transmettre directement au constructeur. Par exemple, avec un BackendV1 backend :

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.providers.fake_provider import FakeMumbai
    
    backend = FakeMumbai()
    inst_map = backend.defaults().instruction_schedule_map
    channel_map = backend.configuration().qubit_channel_mapping
    cal_pass = RZXCalibrationBuilder(
        instruction_schedule_map=inst_map,
        qubit_channel_mapping=channel_map,
    )

    ou avec un BackendV2 backend :

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.providers.fake_provider import FakeMumbaiV2
    
    backend = FakeMumbaiV2()
    inst_map = backend.instruction_schedule_map
    channel_map = {bit: backend.drive_channel(bit) for bit in range(backend.num_qubits)}
    cal_pass = RZXCalibrationBuilder(
        instruction_schedule_map=inst_map,
        qubit_channel_mapping=channel_map,
    )
  • La limite des tirs de mesure pour le backend BasicAer a été supprimée.

  • Pour le DAGNode, les kwargs et attributs précédemment dépréciés type, op, qargs, cargs, et wire ont été supprimés. Ils ont été supprimés à l'origine dans la version 0.19.0. Les kwargs et attributs op, qargs et cargs ne sont accessibles qu'aux instances de DAGOpNode, et le kwarg et l'attribut wire ne sont accessibles qu'aux instances de DAGInNode ou DAGOutNode.

  • La fonction obsolète pauli_group() a été supprimée. Il était à l'origine obsolète dans Qiskit Terra 0.17.

  • Plusieurs méthodes obsolètes sur Pauli ont été supprimées, alors qu'elles étaient à l'origine obsolètes dans Qiskit Terra 0.17. Il s'agit de


    sgn_prod

    Utiliser Pauli.compose() ou Pauli.dot() à la place.


    to_spmatrix

    Utiliser Pauli.to_matrix() avec l'argument sparse=True .


    kron

    Utiliser Pauli.expand()mais attention, cela renvoie un nouvel objet, au lieu de muter l'objet existant.


    update_z et update_x

    Définir directement les attributs z et x de l'objet.


    insert_paulis

    Utiliser Pauli.insert().


    append_paulis

    Utiliser Pauli.expand().


    delete_qubits

    Utiliser Pauli.delete().


    pauli_single

    Construire l'étiquette manuellement et la passer directement à l'initialisateur, comme par exemple :

    Pauli("I" * index + pauli_label + "I" * (num_qubits - index - len(pauli_label)))

    random

    Utiliser quantum_info.random_pauli() à la place.

  • Suppression de la méthode optimize des classes Optimizer qui est remplacée par la méthode minimize() en remplacement direct. La seule exception est SPSAoù l'avertissement de dépréciation n'a pas été déclenché et où la méthode est donc conservée.

  • Result a été modifié de manière à ce qu'il contienne toujours les attributs date, status et header ( None s'il n'est pas spécifié).

  • Pour Python 3.7 shared-memory38 est désormais une dépendance. Il a été ajouté en tant que dépendance pour Python 3.7 afin de permettre l'exploitation des constructions de mémoire partagée dans la bibliothèque standard des versions plus récentes de Python. Si vous utilisez Python >= 3.8, aucune dépendance supplémentaire n'est nécessaire.

  • Instruction les étiquettes sont désormais vérifiées lors de la création de l'instruction.

  • La sérialisation de QPY a été mise à jour pour sérialiser QuantumCircuit avec QuantumCircuit.calibrations. Depuis la version 5 de QPY, seules les entrées d'étalonnage de type ScheduleBlock peuvent être sérialisées.

  • La définition de XXPlusYYGate a été modifiée. Voir #7969 pour plus de détails.

  • Les gestionnaires de passes prédéfinies générées par level_1_pass_manager(), level_2_pass_manager(), et level_3_pass_manager() et utilisés par l'argument de la fonction transpile() l'argument optimization_level de la fonction, respectivement à 1, 2 et 3, ne fixent plus de limite temporelle stricte à la passe du transpondeur VF2Layout transpiler. Cela signifie que la passe n'arrêtera plus d'essayer de trouver une meilleure disposition parfaite alternative jusqu'à une limite de temps fixe ( 100ms pour le niveau 1, 10 sec pour le niveau 2, et 60 sec pour le niveau 3) car cela limitait la reproductibilité de la compilation lorsqu'une disposition parfaite était disponible. Cela signifie que le résultat de l'utilisation de la passe peut être différent du résultat précédent, bien que dans tous les cas il ne change que si un ensemble de qubits moins bruyants peut être trouvé par rapport au résultat précédent. Si vous souhaitez conserver le comportement précédent, vous pouvez créer un fichier personnalisé PassManager qui définit l'argument time_limit dans le constructeur pour la passe VF2Layout .

Remarques concernant la dépréciation

  • L'appel timeline_drawer() avec un circuit non programmé a été supprimé. Tous les circuits, même ceux composés uniquement d'instructions de retard, doivent être transposés avec le mot-clé scheduling_method argument de transpile() set, afin de générer les informations de programmation stockées dans QuantumCircuit.op_start_times.

  • Les fonctions NetworkX pour DAGCircuit.to_networkx() et from_networkx(), ainsi que la méthode DAGDependency.to_networkx() sont obsolètes et seront supprimées dans une prochaine version. Qiskit utilise retworkx comme bibliothèque de graphes depuis la version qiskit-terra 0.12.0, et depuis lors, les fonctions de conversion de networkx sont avec pertes. Ils ont été ajoutés à l'origine pour permettre aux utilisateurs d'exploiter des fonctionnalités de la bibliothèque d'algorithmes NetworkX’s qui ne sont pas présentes dans retworkx. Depuis lors, retworkx a évolué et offre davantage de fonctionnalités, et l'outil de gestion de l'information est étroitement lié à retworkx pour son fonctionnement DAGCircuit est étroitement lié à retworkx pour son fonctionnement. Ces méthodes de conversion ne présentent qu'un intérêt limité pour l'avenir et seront donc supprimées dans une prochaine version.

  • L'accès à plusieurs anciennes bascules (HAS_MATPLOTLIB, HAS_PDFTOCAIRO, HAS_PYLATEX et HAS_PIL) à partir du module qiskit.visualization est désormais obsolète, et ces chemins d'importation seront supprimés dans une prochaine version de Qiskit Terra. Les mêmes objets doivent être accédés par l'intermédiaire de qiskit.utils.optionalsqui contient des testeurs pour presque toutes les dépendances optionnelles de Terra.

  • Le module qiskit.test.mock est désormais obsolète. Les classes de faux backend et de faux fournisseurs qui étaient auparavant disponibles dans qiskit.test.mock sont accessibles dans qiskit.providers.fake_provider depuis Terra 0.20.0. Ce changement représente un véritable engagement à supporter les fausses classes de backend dans le cadre de Qiskit, alors qu'auparavant elles faisaient simplement partie de la suite de tests internes, et étaient exposées aux utilisateurs en tant qu'effet secondaire.

  • Les noms des arguments lors de l'appel d'un Estimator ou Sampler en tant que fonction sont renommés de circuit_indices et observable_indices à circuits et observables.

  • Les arguments qobj_id et qobj_header de la fonction execute() sont obsolètes et seront supprimés dans une prochaine version. Depuis la suppression de la classe BaseBackend , ces arguments n'ont plus d'effet car aucun backend ne prend en charge l'exécution avec un objet Qobj directement et ne travaille qu'avec les objets QuantumCircuit directement.

  • Les arguments x, z et label de l'initialisateur de Pauli ont été documentés comme dépréciés dans Qiskit Terra 0.17, mais un bogue a empêché l'affichage de l'avertissement attendu au moment de l'exécution. L'avertissement s'affichera correctement, et les arguments seront supprimés dans Qiskit Terra 0.23 ou plus tard. Une paire de x et z doit être transmise positionnellement comme un seul tuple (Pauli((z, x))). Une chaîne de caractères label doit être transmise en position dans le premier argument (Pauli("XYZ")).

  • La méthode SPSA.optimize() est dépréciée au profit de la méthode SPSA.minimize()qui peut être utilisée en remplacement direct. Notez que cette méthode renvoie un objet de résultat complet contenant plus d'informations qu'auparavant.

  • L'argument circuits de qpy.dump() a été déprécié et remplacé par programs , car QPY prend désormais en charge plusieurs types de données autres que les circuits.

  • AlignmentKind.to_dict() est obsolète et sera supprimée.

Corrections des erreurs

  • Une validation supplémentaire a été ajoutée à DiagonalGate pour vérifier que l'argument a un module de un.

  • Les indices de qubits dupliqués donnés à SparsePauliOp.from_sparse_list() soulèvera désormais correctement une erreur, au lieu d'écraser silencieusement les valeurs précédentes. Il est possible d'accéder à l'ancien comportement en passant l'argument du nouveau mot-clé do_checks=False.

  • La visualisation timeline_drawer() ne désaligne plus les emplacements de registres classiques.

  • La validation des paramètres pour GaussianSquare est désormais cohérente avant et après la construction. Pour plus de détails, voir le numéro 7882.

  • Les BackendV2-basé sur les faux backends du module qiskit.providers.fake_provider tels que FakeMontrealV2supportent maintenant l'opération Delay dans leurs attributs target attributs. Auparavant, les objets contenant des retards ne pouvaient pas être compilés dans ces backends, QuantumCircuit qui contenaient des retards ne pouvaient pas être compilés dans ces backends.

  • Correction d'un bogue dans TridiagonalToeplitz.eigs_bounds(), qui entraînait le retour de bornes de valeurs propres incorrectes dans certains cas de valeurs propres négatives. Pour plus de détails, voir le numéro 7939.

  • Correction d'un bogue dans lequel le tiroir du vecteur d'état LaTeX ignorait le paramètre max_size .

  • Correction de la prise en charge dans la méthode PassManagerConfig.from_backend() pour construire un objet PassManagerConfig à partir d'une BackendV2 d'une instance. Auparavant, cela n'était pas géré correctement et échouait lors de l'exécution avec un BackendV2 objet.

  • Correction de la prise en charge de la sérialisation (qpy.dump()) et la désérialisation (qpy.load()) d'un objet QuantumCircuit contenant des objets ControlledGate personnalisés. Auparavant, une exception était levée par qpy.load() lorsqu'il essayait de reconstruire le fichier personnalisé ControlledGate. Correction #7999.

  • Correction de la prise en charge de la sérialisation (qpy.dump()) et la désérialisation (qpy.load()) d'un objet QuantumCircuit contenant des objets MCPhaseGate personnalisés. Auparavant, une exception était levée par qpy.load() lorsqu'il essayait de reconstruire le MCPhaseGate.

  • Correction de la prise en charge de la sérialisation (qpy.dump()) et la désérialisation (qpy.load()) d'un objet QuantumCircuit contenant des portes contrôlées avec un état de contrôle ouvert. Auparavant, l'état de contrôle ouvert était perdu par le processus de sérialisation et le circuit reconstruit.

  • Fixe QuantumCircuit.reverse_bits() avec des circuits contenant des Qubit et Clbit. Par exemple, le texte suivant fonctionnera désormais :

    from qiskit.circuit import QuantumCircuit, Qubit, Clbit
    
    qc = QuantumCircuit([Qubit(), Clbit()])
    qc.h(0).c_if(qc.clbits[0], 0)
    qc.reverse_bits()
  • Correction de l'attribut ConfigurableFakeBackend.t2 , qui était auparavant incorrectement défini en fonction de la valeur fournie pour t1 .

  • Correction d'un problème avec BackendV2-basé sur de fausses classes de backend du module qiskit.providers.fake_provider telles que FakeMontrealV2 où la valeur de l'attribut dt (et de l'attribut Target.dt ) n'étaient pas correctement converties en secondes. Cela poserait des problèmes lors de l'utilisation de ces faux backends dans le cadre de la programmation.

  • Correction d'un bogue dans plot_histogram() lorsque l'argument number_to_keep était plus petit que le nombre de clés. Le code suivant ne produira plus d'erreurs et sera correctement aligné :

    from qiskit.visualization import plot_histogram
    data = {'00': 3, '01': 5, '11': 8, '10': 11}
    plot_histogram(data, number_to_keep=2)
  • Amélioration des performances lors de la construction et de l'utilisation d'instances paramétrées avec de nombreuses portes qui partagent un nombre relativement faible de paramètres QuantumCircuit paramétrées avec de nombreuses portes qui partagent un nombre relativement faible de paramètres.

  • L'exportateur OpenQASM 3 (qiskit.qasm3) n'essaiera plus de produire des définitions pour les portes non standard dans l'option basis_gates .

  • Correction du getter de OptimizerResult.nitqui renvoyait auparavant le nombre d'évaluations du jacobien au lieu du nombre d'itérations.

  • Correction d'un bogue dans la représentation des chaînes de caractères des objets Result qui entraînait une mauvaise spécification des attributs.

  • Correction d'un problème avec transpile() où, dans certains cas, la fourniture d'une liste de chaînes de portes de base avec le mot-clé argument basis_gates ou implicitement via une entrée Target via l'argument mot-clé target n'était pas interprété correctement et entraînait l'utilisation d'un sous-ensemble des portes listées pour chaque circuit.

  • Correction d'un problème dans la passe UnitarySynthesis qui entraînait une erreur lorsqu'un objet Target qui n'avait pas de restrictions de qubits sur les opérations (par exemple dans le cas d'une cible de simulateur idéal) était spécifié avec l'argument du mot-clé target pour le constructeur.

  • La méthode qiskit.result.marginal_counts()lorsqu'on lui transmet un Result à partir d'un backend d'impulsion, échouerait, car elle contient un tableau d'objets ExperimentResult , chacun d'entre eux ayant un objet QobjExperimentHeader, et ces ExperimentHeaders n'ont pas de variables d'instance creg_sizes. Si le site Result provenait d'un backend de simulateur (par exemple Aer), cette variable d'instance y figurerait. Nous corrigeons marginal_counts pour qu'il ignore la logique qui nécessite creg_sizes si le champ n'est pas présent ou n'est pas None.

  • 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.

  • Correction d'un problème de reproductibilité de la fonction transpile() lors de l'utilisation de optimization_level 1, 2 et 3. Auparavant, dans certaines conditions, lorsqu'il existait plusieurs schémas parfaits (un schéma qui ne nécessite pas de portes SWAP), le schéma et le circuit de sortie sélectionnés pouvaient varier, que l'argument seed_transpiler ait été défini ou non.

Aer 0.10.4

Pas de modification

IBM 0.19.2 du fournisseur Q

Corrections des erreurs

  • Dans la prochaine version de Terra, une version candidate sera étiquetée avant la version finale. Cependant, le changement de la chaîne de version pour le paquet est bloqué sur le qiskit-ibmq-provider en ce moment parce qu'il essaie d'analyser la version et suppose qu'il n'y aura pas de suffixe prelease sur la chaîne de version (voir #8200 pour les détails). PR #1135 corrige cette analyse de version pour utiliser le regex du projet pypa/packaging qui gère toutes les versions des paquets PEP440 en incluant les suffixes de pré-version. Cela permettra à terra de publier une étiquette 0.21.0rc1 sans casser le fournisseur qiskit-ibmq.
  • threading.currentThread et notifyAll ont été supprimés dans Python 3.10 (octobre 2021) et seront supprimés dans Python 3.12 (octobre 2023). Le PR #1133 les remplace par threading.current_thread, notify_all ajouté à Python 2.6 (octobre 2008).
Cette page a-t-elle été utile ?
Signaler un bogue, une coquille ou proposer du contenu sur GitHub.