Skip to main content
IBM Quantum Platform

Notes de publication de Qiskit 0.33


0.33.1

Terra 0.19.1

Prélude

Qiskit Terra 0.19.1 est une version de correction de bogues, résolvant certains problèmes dans 0.19.0 concernant les circuits construits par l'interface de construction de flux de contrôle, les portes conditionnelles et la sérialisation QPY des nouveaux objets Terra.

Remarques concernant la dépréciation

  • Les fonctions libres qiskit.circuit.measure.measure() et qiskit.circuit.reset.reset() sont obsolètes et seront supprimées dans une prochaine version. Au lieu de cela, vous devez y accéder en tant que méthodes sur QuantumCircuit:

    from qiskit import QuantumCircuit
    circuit = QuantumCircuit(1, 1)
    
    # Replace this deprecated form ...
    from qiskit.circuit.measure import measure
    measure(circuit, 0, 0)
    
    # ... with either of the next two lines:
    circuit.measure(0, 0)
    QuantumCircuit.measure(circuit, 0, 0)

Corrections des erreurs

  • Correction d'une erreur dans les fonctions de conversion des circuits circuit_to_gate() et circuit_to_instruction() (et leurs méthodes de circuit associées QuantumCircuit.to_gate() et QuantumCircuit.to_instruction()) lorsqu'elles agissent sur un circuit avec des bits sans registre ou des bits dans plus d'un registre. Auparavant, le nombre de bits nécessaires pour la porte ou l'instruction créée était calculé de manière incorrecte, ce qui provoquait souvent une exception lors de la conversion.

  • Correction d'un problème où l'appel à QuantumCircuit.copy() sur les circuits "body" d'une opération de flux de contrôle créée avec l'interface du constructeur provoquait une erreur. Par exemple, le message suivant, qui était auparavant une erreur, sera désormais renvoyé avec succès :

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    
    qreg = QuantumRegister(4)
    creg = ClassicalRegister(1)
    circ = QuantumCircuit(qreg, creg)
    
    with circ.if_test((creg, 0)):
        circ.h(0)
    
    if_else_instruction, _, _ = circ.data[0]
    true_body = if_else_instruction.params[0]
    true_body.copy()
  • L'interface du constructeur de flux de contrôle prend désormais en charge l'utilisation de ClassicalRegistercomme conditions dans des portées de flux de contrôle imbriquées. Auparavant, cette opération n'entraînait pas d'erreur immédiate, mais les blocs de circuits internes ne disposaient pas des registres corrects, ce qui entraînait l'échec de la logique ultérieure fonctionnant avec les blocs internes.

    Par exemple, auparavant, les dessinateurs échouaient lorsqu'ils essayaient de dessiner un bloc intérieur conditionné par un registre classique, alors qu'aujourd'hui ils y parviennent, comme dans cet exemple :

    from qiskit import QuantumCircuit
    from qiskit.circuit import QuantumRegister, ClassicalRegister
    
    qreg = QuantumRegister(4)
    creg = ClassicalRegister(1)
    circ = QuantumCircuit(qreg, creg)
    
    with circ.for_loop(range(10)) as a:
        circ.ry(a, 0)
        with circ.if_test((creg, 1)):
            circ.break_loop()
    
    print(circ.draw(cregbundle=False))
    print(circ.data[0][0].blocks[0].draw(cregbundle=False))
  • Correction de qpy_serialization pour la prise en charge de la sérialisation QuantumCircuit qui utilisent ParameterVector ou ParameterVectorElement comme paramètres. Auparavant, un paramètre ParameterVectorElement était simplement traité comme un Parameter pour la sérialisation QPY, ce qui signifiait que le contexte ParameterVector était perdu dans QPY et l'ordre de sortie de parameters pouvait être incorrect.

    Pour résoudre ce problème, une nouvelle version du format QPY, la version 3, a été nécessaire. Cette nouvelle version du format inclut une représentation de la classe ParameterVectorElement qui est décrite dans la documentation qpy_serialization à l'adresse PARAMETER_VECTOR_ELEMENT.

  • Correction de la prise en charge par qpy_serialization de la sérialisation d'un PauliEvolutionGate objet. Auparavant, l'élément PauliEvolutionGate était traitée comme une porte personnalisée pour la sérialisation et était désérialisée sous la forme d'un objet Gate qui avait la même définition et le même nom que l'objet PauliEvolutionGate. Toutefois, cela entraînerait la perte de l'état initial de l'élément PauliEvolutionGate. Cela a été corrigé de sorte qu'à partir de cette version, un PauliEvolutionGate dans le circuit sera préservée 1:1 à travers la sérialisation QPY. La seule limitation de cette méthode est qu'elle ne prend pas en charge les classes personnalisées EvolutionSynthesis personnalisées. Seules les classes disponibles à partir de qiskit.synthesis peuvent être utilisées avec un PauliEvolutionGate pour la sérialisation qpy.

    Pour résoudre ce problème, une nouvelle version du format QPY, la version 3, a été nécessaire. Cette nouvelle version du format inclut une représentation de la classe PauliEvolutionGate qui est décrite dans la documentation qpy_serialization à l'adresse PAULI_EVOLUTION.

  • Deux fonctions libres qiskit.circuit.measure.measure() et qiskit.circuit.reset.reset() ont été accidentellement supprimées sans période de dépréciation. Elles ont été rétablies, mais sont considérées comme obsolètes en faveur des méthodes QuantumCircuit.measure() et QuantumCircuit.reset()et seront supprimées dans une prochaine version.

Autres remarques

  • La nouvelle interface de construction du flux de contrôle utilise divers gestionnaires de contexte et objets d'aide pour effectuer son travail. Elles ne doivent pas être considérées comme faisant partie de l'API publique et sont susceptibles d'être modifiées et supprimées sans préavis. L' utilisation de l'interface du constructeur présente des garanties de stabilité, en ce sens que le comportement décrit par QuantumCircuit.for_loop(), while_loop() et if_test() pour l'interface du constructeur sont soumis aux politiques de dépréciation standard, mais les objets réels utilisés à cet effet ne le sont pas. Vous ne devez pas compter sur le fait que les objets (tels que IfContext ou ControlFlowBuilderBlock) existent à leur emplacement actuel, ni sur le fait que des méthodes ou des attributs leur soient attachés.

    Cela n'était pas clair dans la version 0.19.0. Tous ces objets sont désormais accompagnés d'un avertissement explicite dans leurs chaînes de documentation. Il est probable qu'à l'avenir, leurs emplacements et leurs applications de soutien deviendront très différents.

Aer 0.9.1

Pas de modification

Ignis 0.7.0

Pas de modification

IBM 0.18.2 du fournisseur Q

Corrections des erreurs

  • Correction apportée dans #1065 pour le problème où le travail continuait à se bloquer quand Parameter était passé dans les métadonnées du circuit.
  • Correction fournie dans #1094 pour le problème où qiskit.providers.ibmq.runtime.RuntimeEncoder fait une decompose() supplémentaire si le circuit sérialisé est un BlueprintCircuit.

0.33.0

Cette version marque officiellement la fin du soutien au projet Qiskit Aqua dans Qiskit. Il était à l'origine déprécié dans la version 0.25.0 et comme cela a été documenté dans cette version, le paquet qiskit-aqua a été supprimé du métapaquet Qiskit, ce qui signifie que pip install qiskit n'inclura plus qiskit-aqua. Cependant, en raison des limitations de l'emballage python, nous ne pouvons pas supprimer automatiquement une installation préexistante de qiskit-aqua lors de la mise à niveau d'une version précédente de Qiskit vers cette version (ou une version future) avec pip install -U qiskit. Si vous mettez à jour une version précédente, il est recommandé de désinstaller manuellement Qiskit Aqua avec pip uninstall qiskit-aqua ou de l'installer dans un nouvel environnement Python.

Les modules d'application fournis par qiskit-aqua ont été divisés en plusieurs nouveaux paquets : qiskit-optimization, qiskit-nature, qiskit-machine-learning, et qiskit-finance. Ces paquets peuvent être installés seuls (via la commande pip install standard, par exemple pip install qiskit-nature) ou avec le reste du métapackage Qiskit en tant qu'éléments optionnels (par ex. pip install 'qiskit[finance,optimization]' ou pip install 'qiskit[all]'). Les algorithmes de base et le flux d'opérateurs sont désormais disponibles dans le cadre de Qiskit Terra à l'adresse qiskit.algorithms et qiskit.opflow. En fonction de votre utilisation actuelle d'Aqua, vous devriez utiliser soit les paquets d'application, soit les nouveaux modules de Qiskit Terra. Pour plus de détails sur la façon de migrer depuis Qiskit Aqua, vous pouvez vous référer au Guide de Migration Aqua.

Cette version met officiellement fin au projet Qiskit Ignis. En conséquence, dans une prochaine version, le paquet qiskit-ignis sera retiré du métapaquet Qiskit, ce qui signifie que dans cette future version, pip install qiskit n'inclura plus qiskit-ignis. Qiskit Ignis a été supplanté par le projet Qiskit Experiments et le développement actif a cessé. Bien qu'il s'agisse d'une version obsolète, des corrections de bogues critiques et des corrections de compatibilité continueront d'être apportées afin de donner aux utilisateurs une opportunité suffisante de migrer hors d'Ignis. Après la période de dépréciation (qui ne sera pas inférieure à 3 mois à partir de cette version), le projet sera retiré et archivé. 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.19.0

Prélude

Les points forts de la version Qiskit Terra 0.19 sont les suivants :

  • Une nouvelle version de l'interface abstraite Qiskit/hardware, sous la forme de BackendV2qui s'accompagne d'une nouvelle structure de données Target pour permettre aux backends de mieux modéliser leurs contraintes pour le transpilateur.
  • Une interface de plugin extensible pour la passe de transpilation UnitarySynthesis permettant aux utilisateurs ou à d'autres paquets d'étendre les routines de synthèse de Qiskit Terra avec de nouvelles méthodes.
  • Instructions de flux de contrôle, pour représenter les boucles for et while et les déclarations if/else en QuantumCircuit. Les simulateurs de Qiskit Aer seront bientôt capables de travailler avec ces nouvelles instructions, ce qui vous permettra d'écrire des programmes quantiques plus dynamiques.
  • Prise en charge préliminaire de la spécification évolutive OpenQASM 3. Vous pouvez utiliser le nouveau module qiskit.qasm3 pour sérialiser vos QuantumCircuitdans OpenQASM 3, y compris les nouvelles constructions de flux de contrôle.

Cette version marque la fin de la prise en charge de Python 3.6 dans Qiskit. Cette version de Qiskit Terra, et toutes les versions ultérieures de correction de bogues dans la série 0.19.x, sera la dernière à fonctionner avec Python 3.6. À partir de la prochaine version mineure ( 0.20.0 ) de Qiskit Terra, la version minimale requise de Python sera 3.7.

Comme toujours, cette version comporte de nombreuses autres fonctionnalités et corrections, que vous pouvez découvrir ci-dessous.

Nouvelles fonctions

  • QuantumCircuit.decompose() et sa passe de transposition correspondante Decompose acceptent désormais, de manière optionnelle, un paramètre contenant une collection de noms de portes. Si ce paramètre est indiqué, seules les portes dont les noms correspondent seront décomposées. Cela permet d'utiliser des caractères génériques de type Unix-shell. Par exemple :

    qc.decompose(["h", "r[xz]"])

    décomposera toutes les portes h, rx ou rz , mais laissera (par exemple) les portes x intactes.

  • Ajout de l'argument termination_checker à l'optimiseur SPSA optimiseur. Cela permet à l'utilisateur de mettre en œuvre un critère de terminaison personnalisé.

    import numpy as np
    from qiskit.algorithms.optimizers import SPSA
    
    def objective(x):
        return np.linalg.norm(x) + .04*np.random.rand(1)
    
    class TerminationChecker:
    
        def __init__(self, N : int):
            """
            Callback to terminate optimization when the average decrease over
            the last N data points is smaller than the specified tolerance.
            """
            self.N = N
            self.values = []
    
        def __call__(self, nfev, parameters, value, stepsize, accepted) -> bool:
            """
            Returns:
                True if the optimization loop should be terminated.
            """
            self.values.append(value)
    
            if len(self.values) > self.N:
                last_values = self.values[-self.N:]
                pp = np.polyfit(range(self.N), last_values, 1)
                slope = pp[0] / self.N
    
                if slope > 0:
                    return True
            return False
    
    maxiter = 400
    spsa = SPSA(maxiter=maxiter, termination_checker=TerminationChecker(10))
    parameters, value, niter = spsa.optimize(2, objective, initial_point=np.array([0.5, 0.5]))
  • Ajout d'une nouvelle version de l'interface Backend de l'interface, BackendV2. Cette nouvelle version représente un changement important par rapport à la version précédente, BackendV1 et modifie à la fois le modèle d'accès de l'utilisateur aux propriétés du backend (comme le nombre de qubits, etc.) et la façon dont le backend représente ses contraintes au transpileur. L'exécution des circuits (via la méthode run() reste inchangée. Avec un BackendV2 au lieu d'avoir un backend configuration(), properties()et defaults() des méthodes qui construisent BackendConfiguration, BackendPropertieset PulseDefaults respectivement, comme dans l'interface BackendV1 les attributs contenus dans ces objets de sortie sont directement accessibles en tant qu'attributs de l'objet BackendV2 de l'objet. Par exemple, pour obtenir le nombre de qubits pour un backend avec BackendV1 vous feriez :

    num_qubits = backend.configuration().n_qubits

    tandis qu'avec BackendV2 c'est le cas :

    num_qubits = backend.num_qubits

    L'autre changement est que le nombre d'attributs exposés dans la classe abstraite BackendV2 est conçu pour être un ensemble de champs obligatoires ou optionnels, agnostique au niveau du matériel et des fournisseurs, que le reste de Qiskit peut utiliser aujourd'hui avec n'importe quel backend. Les sous-classes de la classe abstraite BackendV2 peuvent ajouter la prise en charge d'attributs et de méthodes supplémentaires au-delà de ceux définis dans BackendV2mais ceux-ci ne seront pas supportés universellement dans Qiskit.

    L'autre changement critique qui est principalement important pour les auteurs de fournisseurs est la façon dont un BackendV2 expose les propriétés d'un backend particulier au transpileur. Avec l'aide de BackendV2 cela se fait par l'intermédiaire d'un objet Target objet. Le Targetqui est exposée via l'attribut target est utilisé pour représenter l'ensemble des contraintes liées à l'exécution des circuits sur un backend particulier. Il contient le sous-ensemble d'informations précédemment exposées par le BackendConfiguration, BackendProperties, et PulseDefaults que le transpondeur peut utiliser activement. Lors de la migration d'un fournisseur vers l'utilisation de BackendV2 (ou lors de la création d'un nouveau paquetage de fournisseur), la construction d'objets de backend consistera principalement à créer un objet Target pour le backend.

  • Ajout d'une nouvelle classe Target au module transpiler module. La classe Target est conçue pour représenter les contraintes du backend au compilateur. La classe Target est destinée à être utilisée avec un backend BackendV2 et c'est ainsi que les backends modéliseront leurs contraintes pour le transpilateur à l'avenir. Il combine les champs précédemment distincts utilisés pour contrôler l'appareil cible (par exemple,,, etc.) en une seule structure de données transpile() (par exemple basis_gates, coupling_map, instruction_durations, etc) en une seule structure de données. Il ajoute également des fonctionnalités supplémentaires à celles qui étaient disponibles auparavant, telles que la représentation d'ensembles de portes hétérogènes, la connectivité de portes à plusieurs qubits et des variantes accordées des mêmes portes. Actuellement, le transpondeur ne tient pas compte de toutes ces contraintes, mais au fil du temps, il se développera pour tirer parti de cette fonctionnalité supplémentaire.

  • La classe Options dispose désormais d'un support optionnel pour la spécification de validateurs. Cela permet aux auteurs Backend aux auteurs de spécifier facultativement une validation de base des valeurs fournies par l'utilisateur pour les champs de l'objet Options de l'objet. Par exemple, si vous avez un objet Options défini avec :

    from qiskit.providers.Options
    options = Options(shots=1024)

    vous pouvez définir un validateur sur les tirs pour qu'il soit compris entre 1 et 4096 avec :

    options.set_validator('shots', (1, 4096))

    Lorsque le validateur est activé, tout appel à la méthode update_options() vérifiera que si shots est mis à jour, la nouvelle valeur proposée se situe dans la plage de validité.

  • Ajout d'une nouvelle passe d'analyse du transpileur, ContainsInstructionau module qiskit.transpiler.passes module. Cette passe est utilisée pour déterminer si un circuit contient une instruction spécifique. Elle prend un seul paramètre à l'initialisation, le nom de l'instruction à vérifier, et définit un booléen dans l'ensemble des propriétés si le circuit contient cette instruction ou non. Par exemple :

    from qiskit.transpiler.passes import ContainsInstruction
    from qiskit.circuit import QuantumCircuit
    
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.measure_all()
    
    property_set = {}
    # Contains Hadamard
    contains_h = ContainsInstruction("h")
    contains_h(circuit, property_set)
    assert property_set["contains_h"] == True
    # Not contains SX
    contains_sx = ContainsInstruction("sx")
    contains_sx(circuit, property_set)
    assert property_set["contains_sx"] == False
  • Ajout d'une fonction d'utilité qiskit.utils.detach_prefix() qui est une contrepartie de apply_prefix(). La nouvelle fonction renvoie un tuple de la valeur mise à l'échelle et du préfixe à partir d'une valeur flottante donnée. Par exemple, la valeur 1.3e8 sera convertie en (130, "M") qui peut être utilisé pour afficher une valeur dans un format convivial, tel que 130 MHz.

  • Les valeurs "gate_error" et "balanced" sont désormais disponibles pour l'option objective dans la construction de l'objet BIPMapping , et "balanced" est désormais la valeur par défaut.

    L'objectif "gate_error" nécessite le passage d'une instance dans kwarg, qui contient les erreurs de porte utilisées dans le calcul des objectifs BackendProperties dans le kwarg backend_prop , qui contient les erreurs de porte 2q-gate utilisées dans le calcul des objectifs. L'objectif "balanced" utilisera l'instance BackendProperties s'il est donné, mais sinon il supposera un taux d'erreur CX tel qu'indiqué dans le nouveau paramètre default_cx_error_rate. Les poids relatifs des composantes "erreur de porte" et "profondeur" de l'objectif équilibré peuvent être contrôlés à l'aide du nouveau paramètre depth_obj_weight .

  • Chaque attribut de la classe VQE qui est défini lors de l'initialisation est maintenant accessible avec des getters et des setters. En outre, les valeurs par défaut des attributs VQE ansatz et optimizer peuvent être réinitialisées en leur attribuant None :

    vqe = VQE(my_ansatz, my_optimizer)
    vqe.ansatz = None   # reset to default: RealAmplitudes ansatz
    vqe.optimizer = None  # reset to default: SLSQP optimizer
  • Ajout d'une nouvelle méthode PauliList.group_qubit_wise_commuting() qui partitionne a PauliList en ensembles d'opérateurs commuant mutuellement dans le sens du qubit Pauli mutuellement qubit-wise. Par exemple :

    from qiskit.quantum_info import PauliList, Pauli
    pauli_list = PauliList([Pauli("IY"), Pauli("XX"), Pauli("YY"), Pauli("YX")])
    pauli_list.group_qubit_wise_commuting()
  • Ajout d'une nouvelle méthode de construction de carte de couplage CouplingMap.from_hexagonal_lattice() pour construire une carte de couplage de réseau hexagonal. Par exemple, pour construire une carte de couplage de réseau hexagonal 2x2 :

    from qiskit.transpiler import CouplingMap
    cmap = CouplingMap.from_hexagonal_lattice(2, 2)
    cmap.draw()
  • De nouvelles classes de faux backend sont disponibles à l'adresse qiskit.test.mock. Il s'agit notamment de versions simulées de ibmq_brooklyn, ibmq_manila, ibmq_jakarta, et ibmq_lagos. Comme pour les autres faux backends, ceux-ci comprennent des instantanés de données d'étalonnage (c'est-à-dire backend.defaults()) et les données d'erreur (c'est-à-dire backend.properties()) prises dans le système réel, et peuvent être utilisées pour les tests locaux, la compilation et la simulation.

  • Ajout de la méthode OperatorBase.is_hermitian() pour vérifier si l'opérateur est hermitien ou non. NumPyEigensolver et NumPyMinimumEigensolver utiliser eigh ou eigsh pour résoudre le problème des valeurs propres lorsque l'opérateur est hermitien.

  • Ajout d'une nouvelle méthode de construction PassManagerConfig.from_backend(). Il construit un objet PassManagerConfig avec les options de l'utilisateur et la configuration d'un backend. Grâce à cette fonction, il est plus facile de créer un gestionnaire de laissez-passer prédéfini. Par exemple :

    from qiskit.transpiler.passmanager_config import PassManagerConfig
    from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
    from qiskit.test.mock import FakeMelbourne
    
    pass_manager = level_1_pass_manager(
      PassManagerConfig.from_backend(FakeMelbourne(), seed_transpiler=42)
    )
  • Une nouvelle passe de transpilation, PulseGatesa été ajoutée, qui extrait automatiquement les calibrations fournies par l'utilisateur de la carte des instructions et attache la grille au circuit quantique donné (transposé) en tant que porte d'impulsion.

    La passe de PulseGates est appliquée à tous les niveaux d'optimisation de 0 à 3. Aucune implémentation de porte n'est mise à jour à moins que l'utilisateur final ne remplace explicitement le site backend.defaults().instruction_schedule_map. Ce laissez-passer évite aux utilisateurs d'appeler individuellement QuantumCircuit.add_calibration() pour chaque circuit exécuté sur le matériel.

    Pour compléter ce nouveau laissez-passer, un calendrier a été ajouté à InstructionScheduleMap et est implicitement mis à jour avec un champ de métadonnées "publisher". Les programmes de portes calibrés par le backend ont un type d'éditeur spécial pour éviter d'écraser les circuits avec des calibrages de programmes déjà connus. En général, les utilisateurs finaux n'ont pas besoin de s'occuper de ces métadonnées car elles sont appliquées automatiquement. Vous pouvez appeler InstructionScheduleMap.has_custom_gate() pour vérifier si la carte dispose d'un calibrage personnalisé des portes.

    Voir l'exemple de code ci-dessous pour apprendre comment appliquer l'implémentation de portes personnalisées pour tous les circuits en cours d'exécution.

    from qiskit.test.mock import FakeGuadalupe
    from qiskit import pulse, circuit, transpile
    
    backend = FakeGuadalupe()
    
    with pulse.build(backend, name="x") as x_q0:
        pulse.play(pulse.Constant(160, 0.1), pulse.drive_channel(0))
    
    backend.defaults().instruction_schedule_map.add("x", (0,), x_q0)
    
    circs = []
    for _ in range(100):
        circ = circuit.QuantumCircuit(1)
        circ.sx(0)
        circ.rz(1.57, 0)
        circ.x(0)
        circ.measure_active()
        circs.append(circ)
    
    circs = transpile(circs, backend)
    circs[0].calibrations  # This returns calibration only for x gate

    Notez que la carte de planification des instructions est un objet mutable. Si vous remplacez l'une des entrées et que vous utilisez ce backend pour d'autres expériences, vous risquez de mettre à jour accidentellement la définition de la porte.

    backend = FakeGuadalupe()
    
    instmap = backend.defaults().instruction_schedule_map
    instmap.add("x", (0, ), my_x_gate_schedule)
    
    qc = QuantumCircuit(1, 1)
    qc.x(0)
    qc.measure(0, 0)
    
    qc = transpile(qc, backend)  # This backend uses custom X gate

    Si vous souhaitez mettre à jour les définitions des portes d'une expérience spécifique, vous devez d'abord copier en profondeur la carte du programme d'instructions et la transmettre directement au transpileur.

  • Introduction d'une nouvelle option qubit_subset dans le constructeur de BIPMapping. Cette option nous permet de spécifier les qubits physiques à utiliser (dans coupling_map du dispositif) pendant le mappage en une seule ligne :

    mapped_circ = BIPMapping(
        coupling_map=CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]),
        qubit_subset=[1, 3, 4]
    )(circ)

    Auparavant, pour faire la même chose, nous devions fournir une version réduite de coupling_map qui ne contenait que les qubits à utiliser, intégrer le circuit résultant dans la version originale de coupling_map et mettre à jour QuantumCircuit._layout en conséquence :

    reduced_coupling = coupling_map.reduce(qubit_to_use)
    mapped = BIPMapping(reduced_coupling)(circ)
    # skip the definition of fill_with_ancilla()
    # recover circuit on original coupling map
    layout = Layout({q: qubit_to_use[i] for i, q in enumerate(mapped.qubits)})
    for reg in mapped.qregs:
        layout.add_register(reg)
    property_set = {"layout": fill_with_ancilla(layout)}
    recovered = ApplyLayout()(mapped, property_set)
    # recover layout
    overall_layout = Layout({v: qubit_to_use[q] for v, q in mapped._layout.get_virtual_bits().items()})
    for reg in mapped.qregs:
        overall_layout.add_register(reg)
    recovered._layout = fill_with_ancilla(overall_layout)
  • Ajout des arguments ignore_pauli_phase et copy au constructeur de SparsePauliOp. ignore_pauli_phase empêche la lecture de l'attribut phase d'une entrée PauliList d'être lu, ce qui est plus performant si l'on sait déjà que toutes les phases de l'entrée sont à zéro dans la convention interne de ZX PauliList est déjà connu pour avoir toutes les phases à zéro dans la convention interne ZX. copy permet aux utilisateurs d'éviter la copie des données d'entrée lorsqu'ils définissent explicitement copy=False.

  • Amélioration de la performance des opérations suivantes SparsePauliOp opérations :

  • Ajout de la méthode SparsePauliOp.sum() pour additionner plusieurs SparsePauliOps. Cette méthode est nettement plus performante que l'addition des instances dans une boucle. Par exemple, la façon précédente d'additionner plusieurs SparsePauliOpensemble serait de faire :

    from qiskit.quantum_info import SparsePauliOp, random_pauli_list
    sparse_ops = [SparsePauliOp(random_pauli_list(10, 10)) for _ in [None]*1000]
    
    total = sparse_ops[0]
    for op in sparse_ops[1:]:
        total += op

    Cette opération peut désormais être réalisée de manière beaucoup plus efficace (en termes de rapidité et de frappe!) comme :

    SparsePauliOp.sum(sparse_ops)
  • Ajout d'un argument limit_amplitude au constructeur de ParametricPulse, qui est la classe de base de Gaussian, GaussianSquare, Drag et Constantpour permettre la désactivation de la limite d'amplitude de 1 sur une base d'impulsion par impulsion. Avec limit_amplitude=False, des impulsions individuelles peuvent avoir une amplitude supérieure à l'unité sans soulever de problème PulseError. Voir #6544 pour plus de détails.

  • L'utilisation de QuantumCircuit.draw() ou circuit_drawer() avec le tiroir latex génère désormais un fichier dans un format d'image déduit de l'extension du nom de fichier, par exemple :

    import qiskit
    
    circuit = qiskit.QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.draw('latex', filename='./file.jpg')

    Cette opération permet d'enregistrer le dessin du circuit au format JPEG. Auparavant, l'image était toujours au format PNG. Pour plus de détails, voir le numéro 6448.

    Maintenant, s'il rencontre une extension de nom de fichier qui n'est pas prise en charge, par exemple :

    circuit.draw('latex', filename='./file.spooky')

    il lancera ValueError pour changer l'extension du nom de fichier en un format d'image pris en charge.

  • Le paramètre filename a été ajouté à plot_gate_map() et plot_coupling_map()qui permet d'enregistrer les images résultantes dans un fichier.

  • Présentation d'un compilateur quantique approximatif et d'un plugin de synthèse unitaire correspondant. La classe AQC principale est AQC pour une version autonome qui compile une matrice unitaire en un circuit approximatif. Le plugin peut être invoqué par transpile() lorsque l'argument unitary_synthesis_method est défini à 'aqc'. Voir qiskit.transpiler.synthesis.aqc pour plus de détails.

  • Ajout d'un argument filter_function à QuantumCircuit.depth() et QuantumCircuit.size() afin d'analyser les opérations sur les circuits en fonction de certains critères.

    Par exemple, pour obtenir le nombre de portes à deux qubits, vous pouvez faire :

    circuit.size(lambda x: x[0].num_qubits == 2)

    Ou pour obtenir la profondeur des portes T agissant sur le qubit zeroth :

    circuit.depth(lambda x: x[0].name == 't' and circuit.qubits[0] in x[1])
  • Ajout d'une nouvelle passe de transpilation, CollectMultiQBlocksau module qiskit.transpiler.passes module. Cette passe est utilisée pour collecter des séquences de portes ininterrompues agissant sur des groupes de qubits. Elle offre une fonction similaire à la passe Collect2qBlocks existante, mais alors que cette passe est conçue et optimisée pour trouver des blocs de 2 qubits, cette nouvelle passe fonctionnera pour trouver des blocs de n'importe quelle taille.

  • Il existe une interface de construction pour les nouvelles opérations de flux de contrôle sur QuantumCircuittelles que les nouvelles opérations de flux de contrôle sur ForLoopOp, IfElseOp, et WhileLoopOp. L'interface utilise les mêmes méthodes de circuit, à savoir QuantumCircuit.for_loop(), QuantumCircuit.if_test() et QuantumCircuit.while_loop()qui sont surchargés de sorte que si le paramètre body n'est pas fourni, ils renvoient un gestionnaire de contexte. L'entrée dans l'un de ces gestionnaires de contexte fait entrer un champ d'application dans le circuit et capture tous les appels de porte (et d'autres champs d'application) ainsi que les ressources qu'ils utilisent, et construit l'opération correspondante à la fin. Par exemple, vous pouvez maintenant faire :

    qc = QuantumCircuit(2, 2)
    with qc.for_loop(range(5)) as i:
        qc.rx(i * math.pi / 4, 0)

    Cela produira un ForLoopOp sur qc, qui sait que le qubit 0 est la seule ressource utilisée dans le corps de la boucle. Ces gestionnaires de contexte peuvent être imbriqués et détermineront correctement leur largeur. Vous pouvez utiliser QuantumCircuit.break_loop() et QuantumCircuit.continue_loop() dans un contexte, et il s'étendra à la largeur correcte de la boucle qu'il contient, même s'il est imbriqué dans d'autres blocs QuantumCircuit.if_test() supplémentaires.

    Le gestionnaire de contexte if_test() fournit un gestionnaire enchaîné qui, si on le souhaite, peut être utilisé pour créer un bloc else , comme par exemple :

    qreg = QuantumRegister(2)
    creg = ClassicalRegister(2)
    qc = QuantumCircuit(qreg, creg)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure(0, 0)
    with qc.if_test((creg, 0)) as else_:
        qc.x(1)
    with else_:
        qc.z(1)

    Le gestionnaire veillera à ce que les corps if et else soient définis sur le même ensemble de ressources.

  • Introduction d'une nouvelle passe de transposition InverseCancellation qui généralise la passe CXCancellation pour annuler toutes les portes auto-inversées ou les paires porte-inverse. Il peut être utilisé en initialisant InverseCancellation et en passant une porte à annuler, par exemple :

    from qiskit.transpiler.passes import InverseCancellation
    from qiskit import QuantumCircuit
    from qiskit.circuit.library import HGate
    from qiskit.transpiler import PassManager
    
    qc = QuantumCircuit(2, 2)
    qc.h(0)
    qc.h(0)
    pass_ = InverseCancellation([HGate()])
    pm = PassManager(pass_)
    new_circ = pm.run(qc)
  • Le constructeur de RZXCalibrationBuilder possède deux nouveaux kwargs instruction_schedule_map et qubit_channel_mapping qui prennent respectivement un InstructionScheduleMap et une liste de noms de canaux pour chaque qubit respectivement. Ces nouveaux arguments sont utilisés pour spécifier directement les informations requises d'une cible backend. Ils doivent être utilisés au lieu de passer un BaseBackend ou un objet directement au pass avec l'argument BackendV1 directement à la passe avec l'argument backend .

  • Les Statevectordes états composés uniquement de qubits peuvent maintenant être dessinés sur LaTeX en notation ket. Dans la notation ket, les entrées du vecteur d'état sont traitées de manière à ce que les facteurs exacts tels que les fractions ou les racines carrées de deux soient dessinés en tant que tels. La convention particulière peut être choisie en passant l'argument du mot-clé convention comme "ket" ou "vector" , selon le cas :

    import math
    from qiskit.quantum_info import Statevector
    
    sv = Statevector([math.sqrt(0.5), 0, 0, -math.sqrt(0.5)])
    sv.draw("latex", convention="ket")
    sv.draw("latex", convention="vector")
  • Ajout d'une nouvelle passe de transposition EchoRZXWeylDecomposition qui permet aux utilisateurs de décomposer une porte arbitraire à deux qubits en termes de portes RZX échangées en s'appuyant sur la décomposition de Cartan. En combinaison avec d'autres passes de transpilation, cela peut être utilisé pour transpiler des circuits arbitraires en circuits basés sur les portes RZX et efficaces en termes d'impulsions qui mettent en œuvre le même unitaire.

  • Les SPSA et QNSPSA sont désormais capables de regrouper autant d'évaluations de circuits que possible, tant pour les itérations que pour les calibrages initiaux. Ceci peut être exploité en définissant le kwarg max_evals_grouped sur le constructeur de VQE lors de l'utilisation de SPSA ou QNSPSA comme paramètre optimizer . Par exemple :

    from qiskit.circuit.library import TwoLocal
    from qiskit.algorithms import VQE
    from qiskit.algorithms.optimizers import QNSPSA
    from qiskit.test.mock import FakeMontreal
    
    backend = FakeMontreal()
    ansatz = TwoLocal(2, rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    qnspsa = QNSPSA(fidelity, maxiter=5)
    vqe = VQE(
        ansatz=ansatz,
        optimizer=qnspsa,
        max_evals_grouped=100,
        quantum_instance=backend,
    )
  • Cette version introduit une méthode de décomposition pour les portes à deux qubits qui cible des ensembles de portes RZX définis par l'utilisateur. Les utilisateurs de Transpiler peuvent activer la décomposition pour {RZX(pi/2), RZX(pi/4), and RZX(pi/6)} spécifiquement en incluant 'rzx' dans leur liste basis_gates lors de l'appel à transpile(). Les utilisateurs du paquet d'informations Quantum peuvent trouver la méthode elle-même sous la classe XXDecomposer classe.

  • Ajout d'un transpiler pass Optimize1qGatesSimpleCommutationqui optimise un circuit selon une stratégie de commutation de portes à un seul qubit afin de découvrir des opportunités de resynthèse.

  • Ajout d'un paramètre max_job_tries à QuantumInstancepour limiter le nombre de tentatives d'exécution d'un job sur un backend. Auparavant, la soumission et la récupération des résultats étaient tentées à l'infini, même si le travail était annulé ou s'il y avait eu une erreur au niveau du backend. La valeur par défaut est maintenant de 50, et le comportement précédent peut être obtenu en réglant max_job_tries=-1. Corrige #6872 et #6821.

  • La méthode de sortie latex pour la fonction circuit_drawer() et la méthode QuantumCircuit.draw() peut maintenant dessiner des circuits qui contiennent des portes avec une condition de bit unique. Cela a été ajouté pour assurer la compatibilité du tiroir Latex avec la nouvelle fonctionnalité de prise en charge du conditionnement classique des portes sur des bits classiques uniques.

  • La méthode de sortie "mpl" pour la fonction circuit_drawer() et la méthode QuantumCircuit.draw() peut maintenant dessiner des circuits qui contiennent des portes avec une condition de bit unique. Cela a été ajouté pour assurer la compatibilité du tiroir "mpl" avec la nouvelle fonction de prise en charge du conditionnement classique des portes sur des bits classiques uniques.

  • La méthode de sortie text pour la fonction circuit_drawer() et la méthode QuantumCircuit.draw() peut maintenant dessiner des circuits qui contiennent des portes avec une condition de bit unique. Cela a été ajouté pour assurer la compatibilité du tiroir de texte avec la nouvelle fonction de prise en charge du conditionnement classique des portes sur des bits classiques uniques.

  • Un nouveau passeur d'analyse, GatesInBasisa été ajouté à qiskit.transpiler.passes. Cette passe est utilisée pour vérifier si le DAGCircuit en cours de transposition possède toutes les portes de l'ensemble de base configuré ou non. Il définira l'attribut "all_gates_in_basis" dans l'ensemble de propriétés à True si toutes les portes de l'ensemble de propriétés sont dans l'ensemble de base configuré ou à si elles ne le sont pas DAGCircuit sont dans l'ensemble de base configuré ou False si ce n'est pas le cas. Par exemple :

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler.passes import GatesInBasis
    
    # Instatiate Pass
    basis_gates = ["cx", "h"]
    basis_check_pass = GatesInBasis(basis_gates)
    # Build circuit
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.measure_all()
    # Run pass on circuit
    property_set = {}
    basis_check_pass(circuit, property_set=property_set)
    assert property_set["all_gates_in_basis"]
  • Ajout de deux nouvelles méthodes de construction, from_heavy_hex() et from_heavy_square()à la classe CouplingMap classe. Ces méthodes de construction sont utilisées pour créer un CouplingMap qui sont des graphes hexagonaux ou carrés lourds tels que décrits dans Chamberland et al..., 2020.

    Par exemple :

    from qiskit.transpiler import CouplingMap
    
    cmap = CouplingMap.from_heavy_hex(5)
    cmap.draw()
    from qiskit.transpiler import CouplingMap
    
    cmap = CouplingMap.from_heavy_square(5)
    cmap.draw()
  • L'algorithme HHL peut désormais trouver des solutions lorsque sa matrice a des valeurs propres négatives. Pour ce faire, l'algorithme ajoute désormais un qubit supplémentaire pour représenter le signe de la valeur, et l'algorithme d'aide ExactReciprocal a été mis à jour pour traiter cette nouvelle information. Voir #6971 pour plus de détails.

  • Ajout de deux nouvelles classes, CompleteMeasFitter et TensoredMeasFitter au module qiskit.utils.mitigation module. Ces classes ne peuvent être utilisées que comme valeurs pour le kwarg measurement_error_mitigation_cls de la classe QuantumInstance de la classe. L'instanciation et l'utilisation de ces classes (ou de tout autre élément de qiskit.utils.mitigation) en dehors du kwarg measurement_error_mitigation_cls doivent être considérées comme une API privée interne et ne doivent pas être utilisées.

  • La ListOp dans qiskit.opflow possède maintenant un attribut coeffs qui renvoie une liste des coefficients de la liste d'opérateurs, avec le coefficient global (ListOp.coeff) réparti de manière multiplicative dans la liste. Il est à noter que les ListOp peuvent être imbriqués (contenus dans oplist d'un objet ListOp ) et, dans ce cas, une exception est levée si la méthode coeffs est appelée. La méthode ListOp.coeffs permet de comparer les types de canards à la méthode de propriété coeffs de la classe non imbriquée PauliSumOp non imbriquée.

  • La classe Statevector est désormais inscriptible. L'utilisateur peut maintenant récupérer le nième coefficient d'un Statevector par index comme statevec[n].

  • Ajout de la méthode Statevector.inner pour calculer les produits intérieurs des instances Statevector instances. Par exemple :

    statevec_inner_other = statevec.inner(other)

    renverra le produit intérieur de statevec avec other. Alors que statevec doit être un Statevectorother peut être tout ce qui peut être construit comme un Statevectorcomme un tableau Numpy.

  • Un nouveau paramètre, add_bits, a été ajouté à QuantumCircuit.measure_all(). Par défaut, il est fixé à True afin de conserver le comportement précédent, à savoir l'ajout d'un nouveau qubit de la même taille que le nombre de qubits pour stocker les mesures ClassicalRegister de la même taille que le nombre de qubits pour stocker les mesures. S'il est réglé sur False, les mesures seront stockées dans les bits classiques existants. Par exemple, si vous créez un circuit avec des bits classiques existants comme :

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    
    qr = QuantumRegister(2)
    cr = ClassicalRegister(2, "meas")
    circuit = QuantumCircuit(qr, cr)

    l'appel à circuit.measure_all(add_bits=False) utilisera le registre classique existant cr comme cible de sortie des objets Measurement ajoutés au circuit.

  • ParameterExpression délègue désormais ses conversions numériques à la bibliothèque symbolique sous-jacente, même s'il existe des paramètres potentiellement non liés. Cela permet de convertir des expressions telles que :

    >>> from qiskit.circuit import Parameter
    >>> x = Parameter('x')
    >>> float(x - x + 2.3)
    2.3

    où l'expression sous-jacente a une valeur fixe, mais où le paramètre x n'est pas encore lié.

  • Ajout d'une méthode Optimizer.minimize() à tous les optimiseurs : Optimizer et aux classes dérivées. Cette méthode imite la signature de la fonction SciPy’s minimize() et renvoie un fichier OptimizerResult.

    Par exemple

    import numpy as np
    from qiskit.algorithms.optimizers import COBYLA
    
    def loss(x):
        return -(x[0] - 1) ** 2 - (x[1] + 1) ** 3
    
    initial_point = np.array([0, 0])
    optimizer = COBYLA()
    result = optimizer.minimize(loss, initial_point)
    
    optimal_parameters = result.x
    minimum_value = result.fun
    num_function_evals = result.nfev
  • Ajout d'un PauliEvolutionGate à la bibliothèque de circuits (qiskit.circuit.library) qui définit une porte réalisant l'évolution temporelle de (sommes ou sommes de sommes de) Paulis. La synthèse de cette porte est réalisée par EvolutionSynthesis et est découplée de la porte elle-même. Les méthodes de synthèse actuellement disponibles sont les suivantes :

    Par exemple :

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.synthesis import SuzukiTrotter
    
    operator = SparsePauliOp.from_list([
        ("XIZ", 0.5), ("ZZX", 0.5), ("IYY", -1)
    ])
    time = 0.12  # evolution time
    synth = SuzukiTrotter(order=4, reps=2)
    
    evo = PauliEvolutionGate(operator, time=time, synthesis=synth)
    
    circuit = QuantumCircuit(3)
    circuit.append(evo, range(3))
  • Une nouvelle fonction plot_coupling_map() a été introduite, qui étend la fonctionnalité de la fonction existante plot_gate_map()en acceptant trois paramètres : num_qubit, qubit_coordinates, et coupling_map (au lieu de backend), pour permettre de tracer une carte de couplage de qubits arbitraire.

  • Qiskit Terra a maintenant un support initial pour la sérialisation QuantumCircuitvers OpenQASM 3 :

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    from qiskit import qasm3
    
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    
    print(qasm3.dumps(qc))

    Cette version initiale ne prend en charge que les registres nommés, les instructions intégrées de base (telles que mesure, barrière et réinitialisation), les portes définies par l'utilisateur, les instructions définies par l'utilisateur (en tant que sous-programmes) et les nouvelles constructions de flux de contrôle également introduites dans cette version :

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    from qiskit import qasm3
    import math
    
    composite_circ_qreg = QuantumRegister(2)
    composite_circ = QuantumCircuit(composite_circ_qreg, name="composite_circ")
    composite_circ.h(0)
    composite_circ.x(1)
    composite_circ.cx(0, 1)
    composite_circ_gate = composite_circ.to_gate()
    
    qr = QuantumRegister(2, "qr")
    cr = ClassicalRegister(2, "cr")
    qc = QuantumCircuit(qr, cr)
    with qc.for_loop(range(4)) as i:
        qc.rx(i * math.pi / 4, 0)
        qc.cx(0, 1)
    qc.barrier()
    qc.append(composite_circ_gate, [0, 1])
    qc.measure([0, 1], [0, 1])
    
    print(qasm3.dumps(qc))
  • La classe QDrift a été reformulée comme une méthode de synthèse pour PauliEvolutionGatedérivant de TrotterizationBase.

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.synthesis import QDrift
    from qiskit.opflow import X, Y, Z
    
    qdrift = QDrift(reps=2)
    operator = (X ^ 3) + (Y ^ 3) + (Z ^ 3)
    time = 2.345  # evolution time
    
    evolution_gate = PauliEvolutionGate(operator, time, synthesis=qdrift)
    
    circuit = QuantumCircuit(3)
    circuit.append(evolution_gate, range(3))
  • La sérialisation QPY est désormais capable de représenter global_phase attributs d'un objet QuantumCircuit qui sont des objets int, Parameter objet, ou ParameterExpression objet. Les versions précédentes de QPY n'acceptaient qu'un global_phase qui était un float.

    Cela nécessite le format QPY version 2 qui a été introduit dans cette version pour représenter les types supplémentaires.

  • Une nouvelle méthode find_bit() a été ajoutée à la classe QuantumCircuit qui permet de consulter l'index et les registres d'un élément fourni sur le circuit donné Bit sur le circuit donné. La méthode renvoie un namedtuple à deux éléments contenant 0) l'indice du Bit dans l'un ou l'autre des cas suivants qubits (pour un Qubit) ou clbits (pour un Clbit) et 1) une liste de tuples length-2 contenant chaque circuit Register qui contient le Bit, et l'indice dans ce Register auquel le Bit peut être trouvé.

    Par exemple :

    from qiskit.circuit import QuantumCircuit, QuantumRegister, Qubit
    
    reg1 = QuantumRegister(3, 'foo')
    qubit = Qubit()
    reg2 = QuantumRegister(2, 'bar')
    
    qc = QuantumCircuit(reg1, [qubit], reg2)
    
    print(qc.find_bit(reg1[2]))
    print(qc.find_bit(qubit))

    générerait :

    BitLocations(index=2, registers=[(QuantumRegister(3, 'foo'), 2)])
    BitLocations(index=3, registers=[])
  • Trois nouvelles sous-classes Instruction ont été ajoutées pour prendre en charge les opérations de flux de contrôle dans les circuits dynamiques : WhileLoopOp, ForLoopOp, et IfElseOp. En outre, deux sous-classes, BreakLoopOpet ContinueLoopOpont été ajoutées pour prendre en charge la rupture et la poursuite de l'itération suivante d'un contexte de boucle, respectivement.

    Ils peuvent être créés comme des Instructionou ajoutés à une instance QuantumCircuit par le biais de leurs méthodes respectives, QuantumCircuit.while_loop(), for_loop(), if_test(), if_else(), break_loop()et continue_loop().

  • Ajout de la classe de base abstraite BaseReadoutMitigator classe de base abstraite pour la mise en œuvre de dispositifs classiques d'atténuation des erreurs de mesure. Ces objets sont destinés à atténuer les erreurs de mesure dans les objets suivants Counts les objets renvoyés à la suite de l'exécution de circuits sur des backends présentant des erreurs de mesure.

    Les classes d'atténuateurs de lecture ont deux méthodes principales :

    Notez qu'actuellement le module qiskit.algorithms et la classe QuantumInstance utilisent encore les atténuateurs hérités de Qiskit Ignis en qiskit.utils.mitigation. Il est prévu de mettre à jour le module afin d'utiliser les nouvelles classes d'atténuation et de supprimer l'ancien code d'atténuation dans une prochaine version.

  • Ajout de la classe LocalReadoutMitigator pour l'atténuation des erreurs locales de mesure lors de la lecture des mesures. Les erreurs de mesure locales sont celles qui sont décrites par un produit tensoriel d'erreurs de mesure d'un qubit unique.

    Cette classe peut être initialisée avec une liste de matrices d'affectation d'erreur de mesure NN ou à partir d'un backend en utilisant les informations d'erreur de lecture dans les propriétés du backend.

    L'atténuation est mise en œuvre à l'aide de l'inversion de la matrice d'affectation locale, dont la complexité est de O(2N)O(2^N) pour l'atténuation de NN -qubit de QuasiDistribution et des valeurs d'espérance.

  • Ajout de la classe CorrelatedReadoutMitigator pour l'atténuation des erreurs de lecture des mesures corrélées. Cette classe peut être initialisée avec une seule matrice d'affectation des erreurs de mesure 2N×2N2^N \times 2^N qui décrit les probabilités d'erreur. L'atténuation est mise en œuvre via l'inversion de la matrice d'affectation, qui a une complexité d'atténuation de O(4N)O(4^N) de QuasiDistribution et des valeurs d'espérance.

  • Ajout d'un attribut QuasiDistribution.stddev_upper_bound et un kwarg au constructeur de la classe QuasiDistribution qui est utilisée pour stocker les erreurs standard dans les estimations de quasi-probabilité. Il est utilisé par les classes BaseReadoutMitigator pour stocker l'erreur standard dans les quasi probabilités atténuées.

  • Ajout d'une méthode shots() à qiskit.result.Counts pour renvoyer la somme de tous les résultats dans les décomptes.

  • Lors de l'exécution de la classe d'algorithme Grover si la puissance optimale est connue et qu'un seul circuit est exécuté, il n'est plus nécessaire d'activer la fonction de rappel et la recherche de Grover renverra la chaîne de bits la plus probable AmplificationProblem.is_good_state n'a plus besoin d'être activée et la recherche de Grover renverra la chaîne de bits la plus probable. En général, si la puissance optimale de l'opérateur de Grover n'est pas connue, l'algorithme vérifie différentes puissances (c'est-à-dire des itérations) et applique la puissance optimale Grover vérifie différentes puissances (c'est-à-dire des itérations) et applique la fonction is_good_state pour vérifier si une bonne chaîne de bits a été mesurée. Par exemple, vous pouvez maintenant exécuter quelque chose comme :

    from qiskit.algorithms import Grover, AmplificationProblem
    from qiskit.providers.aer import AerSimulator
    from qiskit.quantum_info import Statevector
    
    # Fixed Grover power: 2.
    grover = Grover(iterations=2, quantum_instance=AerSimulator())
    
    # The ``is_good_state`` argument not required here since Grover search
    # will be run only once, with a power of 2.
    problem = AmplificationProblem(Statevector.from_label("111"))
    
    # Run Grover search and print the best measurement
    result = grover.amplify(problem)
    print(result.top_measurement)  # should print 111
  • Ajout d'une méthode remove_cregs() à la classe DAGCircuit pour prendre en charge la suppression du registre classique.

  • Ajout d'une méthode remove_clbits() à la classe DAGCircuit pour permettre la suppression des bits classiques inutilisés. Tout registre classique faisant référence à un bit supprimé est également supprimé.

  • Ajout d'une nouvelle méthode, replace_block_with_op()à la classe DAGCircuit classe. Cette méthode est utilisée pour remplacer un bloc de nœuds dans le DAG en une seule opération. L'exemple canonique est celui de la passe ConsolidateBlocks qui remplace les blocs de nœuds par des nœuds équivalents UnitaryGate .

  • Ajout d'un nouveau passeur d'analyse, Collect1qRunsau module qiskit.transpiler.passes module. Cette passe est utilisée pour trouver des séquences de portes ininterrompues agissant sur un seul qubit. Il est similaire aux Collect2qBlocks et CollectMultiQBlocks mais il est optimisé pour des exécutions d'un seul qubit au lieu de blocs de plusieurs qubits.

  • Diverses fonctions internes de transpilation utilisent désormais les nouvelles caractéristiques de retworkx 0.10 lorsqu'elles opèrent sur la représentation du circuit interne. Cela permet souvent d'accélérer les appels à transpile de l'ordre de 10 à 40 %, avec des effets plus importants à des niveaux d'optimisation plus élevés. Voir #6302 pour plus de détails.

  • Le UnitarySynthesis transpiler pass in qiskit.transpiler.passes a un nouveau kwarg dans le constructeur, min_qubits. Lorsqu'elle est spécifiée, cette valeur peut être fixée à int , ce qui correspond à la taille minimale de l'objet UnitaryGate sur lequel la synthèse unitaire doit être exécutée. Si un UnitaryGate dans un QuantumCircuit utilise moins de qubits, elle sera ignorée par cette instance de la passe.

  • Les interfaces Eigensolver et MinimumEigensolver prennent désormais en charge le type Dict[str, Optional[OperatorBase]] pour le paramètre aux_operators dans leurs méthodes respectives compute_eigenvalues() et compute_minimum_eigenvalue() . Dans ce cas, les valeurs propres auxiliaires sont également stockées dans un dictionnaire sous les mêmes clés que celles fournies par le dictionnaire aux_operators . Les clés correspondant à un opérateur qui ne commute pas avec l'opérateur principal sont abandonnées.

  • Les BasisTranslator, GateDirection, et CheckGateDirection ont un nouveau kwarg target dans leurs constructeurs, qui peut être utilisé pour définir un objet Target comme cible de la passe. S'il est défini, il sera utilisé à la place des adresses target_basis (dans le cas du BasisTranslator ) ou coupling_map (dans le cas de la passe GateDirection et CheckGateDirection ).

  • Autoriser deux étapes de transpilation dans le QuantumInstanceun pour les circuits paramétrés et un second pour les circuits liés (c'est-à-dire sans paramètres libres) uniquement. Si une instance quantique avec des passes pour des circuits non liés et liés est introduite dans une instance quantique CircuitSamplerl'échantillonneur tentera d'appliquer la passe non liée une fois sur le circuit paramétré, de la mettre en cache et de n'appliquer la passe liée que pour toutes les évaluations ultérieures.

    Cela permet aux algorithmes variationnels comme le VQE d'exécuter une fois un gestionnaire de passes personnalisé pour les circuits paramétrés et, en outre, d'exécuter à nouveau le transpileur avec un gestionnaire de passes personnalisé différent sur les circuits liés à chaque itération. Il est important de pouvoir utiliser différents gestionnaires de passes, car toutes les passes ne prennent pas en charge les circuits paramétrés (par exemple Optimize1qGatesDecomposition ne fonctionne qu'avec des paramètres de circuit liés).

    Par exemple, cette caractéristique permet d'utiliser la décomposition CX efficace en termes d'impulsions dans l'EQV, comme suit

    from qiskit.algorithms import VQE
    from qiskit.opflow import Z
    from qiskit.circuit.library.standard_gates.equivalence_library import StandardEquivalenceLibrary as std_eqlib
    from qiskit.transpiler import PassManager, PassManagerConfig, CouplingMap
    from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
    from qiskit.transpiler.passes import (
        Collect2qBlocks, ConsolidateBlocks, Optimize1qGatesDecomposition,
        RZXCalibrationBuilderNoEcho, UnrollCustomDefinitions, BasisTranslator
    )
    from qiskit.transpiler.passes.optimization.echo_rzx_weyl_decomposition import EchoRZXWeylDecomposition
    from qiskit.test.mock import FakeBelem
    from qiskit.utils import QuantumInstance
    
    # Replace by a real backend! If not ensure qiskit-aer is installed to simulate the backend
    backend = FakeBelem()
    
    # Build the pass manager for the parameterized circuit
    rzx_basis = ['rzx', 'rz', 'x', 'sx']
    coupling_map = CouplingMap(backend.configuration().coupling_map)
    config = PassManagerConfig(basis_gates=rzx_basis, coupling_map=coupling_map)
    pre = level_1_pass_manager(config)
    
    # Build a pass manager for the CX decomposition (works only on bound circuits)
    post = PassManager([
        # Consolidate consecutive two-qubit operations.
        Collect2qBlocks(),
        ConsolidateBlocks(basis_gates=['rz', 'sx', 'x', 'rxx']),
    
        # Rewrite circuit in terms of Weyl-decomposed echoed RZX gates.
        EchoRZXWeylDecomposition(backend),
    
        # Attach scaled CR pulse schedules to the RZX gates.
        RZXCalibrationBuilderNoEcho(backend),
    
        # Simplify single-qubit gates.
        UnrollCustomDefinitions(std_eqlib, rzx_basis),
        BasisTranslator(std_eqlib, rzx_basis),
        Optimize1qGatesDecomposition(rzx_basis),
    ])
    
    quantum_instance = QuantumInstance(backend, pass_manager=pre, bound_pass_manager=post)
    
    vqe = VQE(quantum_instance=quantum_instance)
    result = vqe.compute_minimum_eigenvalue(Z ^ Z)
  • Introduction d'une nouvelle interface de synthèse unitaire qui permet d'utiliser des techniques de synthèse alternatives incluses dans des paquets externes de manière transparente avec la passe de UnitarySynthesis transpiler. Les utilisateurs peuvent sélectionner un plugin à utiliser lors de l'appel de transpile() en attribuant au kwarg unitary_synthesis_method le nom du plugin. La liste complète des plugins installés peut être consultée à l'aide de la fonction qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names() pour obtenir la liste complète des plugins installés. Par exemple, si vous avez installé un paquet qui inclut un plugin de synthèse nommé special_synth , vous pouvez l'utiliser avec :

    from qiskit import transpile
    
    transpile(qc, unitary_synthesis_method='special_synth', optimization_level=3)

    Cela remplacera toutes les utilisations de la méthode UnitarySynthesis par la méthode incluse dans le paquet externe qui exporte le plugin special_synth .

    L'interface du plugin est construite autour de points d'entrée setuptools qui permettent aux paquets externes à Qiskit d'annoncer qu'ils incluent un plugin de synthèse. Pour plus de détails sur l'écriture d'un nouveau plugin, reportez-vous à la documentation du module qiskit.transpiler.passes.synthesis.plugin la documentation du module.

  • Ajout d'une nouvelle passe de transpilateur, VF2Layout. Cette passe modélise le problème d'allocation d'agencement comme un problème d'isomorphisme de sous-graphes et utilise l'implémentation de l' algorithme VF2 dans rustworkx pour trouver un agencement parfait (un agencement qui ne nécessiterait pas de routage supplémentaire) s'il en existe un. La fonctionnalité exposée par ce nouveau laissez-passer est très similaire à celle des laissez-passer existants CSPLayout mais VF2Layout est nettement plus rapide.

Problèmes connus

  • La convention "ket" dans le tiroir "latex" de Statevector.draw() n'est valable que pour les états composés uniquement de qubits. Si vous utilisez des états avec des espaces de dimension supérieure à deux, vous devez soit passer convention="vector", soit utiliser un autre tiroir.

  • Les capacités d'exportation de OpenQASM 3 sont en phase bêta et certaines fonctionnalités de Qiskit Terra ne sont pas encore prises en charge QuantumCircuit ne sont pas encore prises en charge. En particulier, vous risquez de rencontrer des erreurs si vous essayez d'exporter des sous-programmes personnalisés avec des paramètres classiques, et il n'est pas encore possible d'exporter des opérations calibrées en fonction du pouls dans le format OpenPulse.

  • Lors de l'exécution du programme BasisTranslator de manière isolée avec l'argument target défini sur un objet Target où certaines portes à qubit unique ne peuvent s'appliquer qu'à des ensembles de qubits qui ne se chevauchent pas, le circuit de sortie peut incorrectement inclure des opérations sur un qubit qui ne sont pas autorisées par l'objet Target. Par exemple, si vous avez couru :

    from qiskit.circuit import QuantumCircuit, Parameter
    from qiskit.circuit.library import UGate, RZGate, XGate, SXGate, CXGate
    from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
    
    from qiskit.transpiler import PassManager, Target, InstructionProperties
    from qiskit.transpiler.passes import BasisTranslator
    
    gmap = Target()
    
    # U gate in qubit 0.
    theta = Parameter('theta')
    phi = Parameter('phi')
    lam = Parameter('lambda')
    u_props = {
        (0,): InstructionProperties(duration=5.23e-8, error=0.00038115),
    }
    gmap.add_instruction(UGate(theta, phi, lam), u_props)
    
    # Rz gate in qubit 1.
    phi = Parameter("phi")
    rz_props = {
        (1,): InstructionProperties(duration=0.0, error=0),
    }
    gmap.add_instruction(RZGate(phi), rz_props)
    
    # X gate in qubit 1.
    x_props = {
        (1,): InstructionProperties(
            duration=3.5555555555555554e-08, error=0.00020056469709026198
        ),
    }
    gmap.add_instruction(XGate(), x_props)
    
    # SX gate in qubit 1.
    sx_props = {
        (1,): InstructionProperties(
            duration=3.5555555555555554e-08, error=0.00020056469709026198
        ),
    }
    gmap.add_instruction(SXGate(), sx_props)
    
    cx_props = {
        (0, 1): InstructionProperties(duration=5.23e-7, error=0.00098115),
        (1, 0): InstructionProperties(duration=4.52e-7, error=0.00132115),
    }
    gmap.add_instruction(CXGate(), cx_props)
    
    bt_pass = BasisTranslator(sel, target_basis=None, target=gmap)
    
    qc = QuantumCircuit(2)
    qc.iswap(0, 1)
    output = bt_pass(qc)

    output aura RZGate et SXGate sur le qubit 0, même si cela est interdit. Pour corriger ce problème, vous pouvez normalement exécuter le traducteur de base une deuxième fois (c'est-à-dire output = bt_pass(output) dans l'exemple ci-dessus) pour corriger cela. Cela ne devrait pas affecter le résultat de l'exécution de la fonction transpile() et n'est un problème que si vous exécutez la passe seule.

Mise à niveau

  • À partir de cette version, from qiskit import * n'importera pas de sous-modules, mais seulement une liste d'objets sélectionnés. Cela risque d'interrompre le code existant qui utilise from qiskit import * et fait référence à des objets qui ne font pas partie de l'espace de noms actuel. Pour rappel, import * est considéré comme une mauvaise pratique et ne doit pas être utilisé dans le code de production. Qiskit met en place __all__ sur qiskit/__init__.py afin d'atténuer les effets de ces mauvaises pratiques. Si votre code renvoie name '<something>' is not defined, ajoutez from qiskit import <something> et réessayez.

  • Les gestionnaires de passage prédéfinis pour les niveaux d'optimisation 0, 1, 2 et 3 qui sont générés par level_0_pass_manager(), level_1_pass_manager(), level_2_pass_manager(), et level_3_pass_manager() respectivement, n'exécuteront plus inconditionnellement la fonction TimeUnitConversion. Auparavant, les gestionnaires de passes prédéfinies exécutaient toujours cette passe, quelles que soient les entrées du transpondeur et du circuit. Cette passe ne sera exécutée que si un paramètre scheduling_method est défini ou si le circuit contient une instruction et que le paramètre est défini Delay et que le paramètre instruction_durations est défini. Ce changement a été effectué dans l'intérêt des performances d'exécution, car dans certains cas, l'exécution sur des circuits comportant un grand nombre de portes et aucun retard ou ordonnancement n'est utilisé transpile() sur des circuits comportant un grand nombre de portes et n'utilisant pas de retards, de temporisation ou d'ordonnancement, la transposition pourrait être le goulot d'étranglement le plus important de la transpilation TimeUnitConversion pourrait être le goulot d'étranglement le plus important dans la transpilation.

  • La méthode par défaut pour BIPMapping est désormais balanced au lieu de depth. Ce nouvel objectif permet généralement d'obtenir un meilleur résultat, car il tient compte à la fois de la profondeur du circuit et de l'erreur de la porte.

  • Le site sort_parameters_by_name de la classe VQE a été supprimée, suite à sa dépréciation dans Qiskit Terra 0.18. Il n'y a pas d'alternative, car le nouvel ordre des paramètres est l'ordre de tri le plus naturel.

  • Les tiroirs du circuit QuantumCircuit.draw() et circuit_drawer() avec l'option latex enregistreront désormais leurs images dans un format déterminé par l'extension du fichier (si un nom de fichier est fourni). Auparavant, ils étaient toujours enregistrés au format PNG. Ils affichent désormais ValueError si le format de l'image n'est pas connu. Cela a été fait pour faciliter l'enregistrement de l'image dans différents formats.

  • La dépendance principale retworkx a vu sa version requise passer de 0.9 à 0.10.1. Cela permet d'améliorer les performances lors des différents passages de transpilation.

  • Le kwarg condition , qui avait été supprimé lors de la publication de 0.15.0, a été supprimé de DAGCircuit.apply_operation_back() et DAGCircuit.apply_operation_front(). Au lieu de cela, définissez l'attribut condition sur les instances Instruction ajoutées à l'instance DAGCircuit en utilisant Instruction.c_if().

  • La méthode DAGCircuit.extend_back() a été supprimée. Il était à l'origine obsolète dans la version 0.13.0. À la place, vous pouvez utiliser la méthode DAGCircuit.compose() qui est plus générale et offre la même fonctionnalité.

  • La méthode DAGCircuit.compose_back() a été supprimée. Il était à l'origine obsolète dans la version 0.13.0. À la place, vous pouvez utiliser la méthode DAGCircuit.compose() qui est plus générale et offre la même fonctionnalité.

  • Le kwarg edge_map de la DAGCircuit méthode compose() a été supprimé. Il était à l'origine obsolète dans la version 0.14.0. La méthode utilise qubits et clbits kwargs pour spécifier l'ordre positionnel des bits à composer au lieu d'utiliser un dictionnaire de correspondance fourni précédemment par edge_map .

  • La méthode DAGCircuit.twoQ_gates() a été supprimée. Il était à l'origine obsolète dans la version 0.13.0. Au lieu de cela, DAGCircuit.two_qubit_ops() doit être utilisé.

  • La méthode DAGCircuit.threeQ_or_more_gates() a été supprimée. Il était à l'origine obsolète dans la version 0.13.0. Au lieu de cela, il convient d'utiliser la méthode, DAGCircuit.multi_qubit_ops() doit être utilisée.

  • L'accès nommé pour le premier argument positionnel du constructeur de la classe SingleQubitUnitary avec u a été supprimé. Il était à l'origine obsolète dans la version 0.14.0. Au lieu de cela, le premier argument positionnel peut être défini à l'aide du nom unitary_matrix (ou simplement positionné au lieu d'être défini par son nom).

  • Accès nommé pour le premier argument positionnel de la QuantumCircuit méthode squ avec u a été supprimé. Il était à l'origine obsolète dans la version 0.14.0. Au lieu de cela, le premier argument positionnel peut être défini à l'aide du nom unitary_matrix (ou simplement positionné au lieu d'être défini par son nom).

  • Les kwargs inutilisés proc et nested_scope pour la méthode qasm() des classes de nœuds QASM dans le module qiskit.qasm.node ont été supprimés. Ils étaient à l'origine dépréciés dans la version 0.15.0.

  • Les kwargs inutilisés proc et nested_scope pour la méthode latex() des classes de nœuds QASM dans le module qiskit.qasm.node ont été supprimés. Ils étaient à l'origine dépréciés dans la version 0.15.0.

  • Les kwargs inutilisés proc et nested_scope pour la méthode real() des classes de nœuds QASM dans le module qiskit.qasm.node ont été supprimés. Ils étaient à l'origine dépréciés dans la version 0.15.0.

  • La sortie de Statevector.draw() lors de l'utilisation de la sortie "latex" est maintenant la nouvelle convention "ket" si l'on trace un état composé uniquement de qubits. Ceci a été modifié pour rendre la lecture de la sortie plus claire, en particulier dans des contextes éducatifs, parce qu'elle montre les étiquettes de ket, et n'affiche que les éléments non nuls.

  • Lorsque l'on court execute() avec un backend BackendV1 les valeurs par défaut des kwargs shots, max_credits, meas_level, meas_return et memory_slot_size seront désormais celles définies par défaut dans l'attribut options du backend cible. Auparavant, ces valeurs par défaut étaient définies de manière à correspondre aux valeurs par défaut lors d'un appel à execute() avec un ancien backend BaseBackend . Par exemple :

    from qiskit.test.mock import FakeMumbai
    from qiskit import QuantumCircuit, execute
    
    circuit = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    backend = FakeMumbai()
    backend.set_options(shots=4096)
    execute(qc, backend)

    fonctionnera désormais avec 4096 shots. Alors que dans les versions précédentes, il fonctionnait avec 1024.

  • La version minimale supportée par Matplotlib est passée de 2.1.0 à 3.3.0. Vous devez maintenant installer Matplotlib 3.3.0 si vous utilisez des fonctions de visualisation basées sur Matplotlib, telles que le backend 'mpl' pour la fonction circuit_drawer() ou la fonction plot_bloch_vector() fonction. Ceci a été fait pour deux raisons, la première étant que les versions récentes de Matplotlib ont déprécié l'utilisation des API autour des visualisations de 3D qui étaient compatibles avec les versions antérieures et la seconde étant que l'installation des versions antérieures de Matplotlib devenait de plus en plus difficile car les dépendances en amont de matplotlib ont causé des incompatibilités qui ont rendu les tests plus difficiles à réaliser.

  • L'utilisation interne du générateur de nombres aléatoires dans random_circuit() a été ajustée, ce qui modifiera le résultat par rapport aux versions précédentes, même avec une graine fixe. Cela a été fait pour améliorer considérablement la durée d'exécution en fonction du nombre de qubits utilisés. Si vous dépendiez d'une sortie identique d'une version précédente, il est recommandé d'utiliser qpy_serialization.dump() pour sauvegarder le circuit aléatoire généré avec une version précédente, au lieu de le générer à nouveau avec la nouvelle version, et d'utiliser qpy_serialization.load() pour charger ce circuit sauvegardé.

  • L'utilisation de * (__mul__) pour la méthode dot() et de @ (__matmul__) pour la méthode compose() de BaseOperator (qui est le parent de toutes les classes d'opérateurs en qiskit.quantum_info y compris des classes comme Operator et Pauli) n'est plus supportée. L'utilisation de ces opérateurs a été supprimée dans la version 0.17.0. Au lieu de cela, vous devez utiliser les boutons dot() et compose() directement, ou utiliser l'opérateur & (__and__) pour les méthodes compose(). Par exemple, si vous utilisiez auparavant l'opérateur comme :

    from qiskit.quantum_info import random_hermitian
    
    op_a = random_hermitian(4)
    op_b = random_hermitian(4)
    
    new_op = op_a @ op_b

    il convient de modifier ce point comme suit :

    from qiskit.quantum_info import random_hermitian
    
    op_a = random_hermitian(4)
    op_b = random_hermitian(4)
    new_op = op_a.compose(op_b)

    ou :

    new_op = op_a & op_b
  • Diverses méthodes d'assignation de paramètres aux opérandes des instructions du programme d'impulsion ont été supprimées, car elles étaient obsolètes dans Qiskit Terra 0.17. Exemples :

    • la méthode assign() de pulse.Instruction.
    • la méthode assign() de Channel, qui est à la base de AcquireChannel, SnapshotChannel, MemorySlot et RegisterSlot.
    • les méthodes assign() et assign_parameters() de ParametricPulse, qui est la base de pulse.Gaussian, pulse.GaussianSquare, pulse.Drag et pulse.Constant.

    Ces paramètres doivent être attribués à partir du programme d'impulsion (pulse.Schedule et pulse.ScheduleBlock) plutôt que des opérandes de l'instruction du programme d'impulsion.

  • La méthode flatten() de pulse.Instruction et qiskit.pulse.Schedule a été supprimée et n'existe plus selon l'avis de dépréciation de Qiskit Terra 0.17. Cette transformation est définie comme une fonction autonome dans qiskit.pulse.transforms.canonicalization.flatten().

  • qiskit.pulse.interfaces.ScheduleComponent a été supprimé et n'existe plus selon l'avis de dépréciation de Qiskit Terra 0.15. Aucune classe alternative ne sera proposée.

  • Les anciens arguments des tiroirs à impulsion ont été supprimés de pulse.Waveform.draw(), Schedule.draw() et ScheduleBlock.draw() et n'existent plus conformément à l'avis de dépréciation de Qiskit Terra 0.16. Désormais, ces méthodes de dessin ne prennent en charge que les arguments de V2 pulse drawer. Voir la documentation sur les méthodes pour plus de détails.

  • Le module qiskit.pulse.reschedule a été supprimé et ce chemin d'importation n'existe plus, conformément à l'avis de dépréciation de Qiskit Terra 0.14. Utiliser qiskit.pulse.transforms à la place.

  • Une méthode protégée Schedule._children() a été supprimée et remplacée par une variable d'instance protégée, conformément à l'avis de dépréciation de Qiskit Terra 0.17. Il s'agit désormais d'un attribut public Schedule.children.

  • Les méthodes et propriétés relatives aux créneaux horaires ont été supprimées et n'existent plus dans ScheduleBlock conformément à l'avis de dépréciation de Qiskit Terra 0.17. Comme cette représentation n'a pas de notion de temps d'instruction t0, l'information sur le créneau horaire sera disponible après avoir été transformée en a Schedule. Des attributs correspondants ont été fournis après cette conversion, mais ils ne sont plus pris en charge. Les attributs suivants sont supprimés :

    • timeslots
    • start_time
    • stop_time
    • ch_start_time
    • ch_stop_time
    • shift
    • insert
  • Les transformateurs de calendrier d'alignement des impulsions ont été supprimés et n'existent plus, conformément à l'avis de dépréciation de Qiskit Terra 0.17. Ces transformations sont intégrées et mises en œuvre dans le contexte AlignmentKind du bloc horaire. Les fonctions de transformation explicites suivantes sont supprimées :

    • qiskit.pulse.transforms.align_equispaced
    • qiskit.pulse.transforms.align_func
    • qiskit.pulse.transforms.align_left
    • qiskit.pulse.transforms.align_right
    • qiskit.pulse.transforms.align_sequential
  • Les commandes redondantes de construction d'impulsions ont été supprimées et n'existent plus conformément à l'avis de dépréciation de Qiskit Terra 0.17. pulse.builder.call_schedule et pulse.builder.call_circuit ont été intégrés dans pulse.builder.call().

  • Un filtre interne qui provoquait l'affichage de tous les avertissements de dépréciation de Qiskit a été supprimé. Cela signifie que le comportement va maintenant revenir au comportement standard Python pour les dépréciations; vous ne devriez voir un DeprecationWarning que s'il a été déclenché par du code dans le fichier de script principal, la session d'interpréteur ou le carnet Jupyter. L'utilisateur ne recevra plus d'avertissement si des fonctions internes de Qiskit font appel à des comportements dépréciés. Si vous écrivez des bibliothèques, vous devriez occasionnellement les exécuter avec les filtres d'avertissement par défaut désactivés, ou avoir des tests qui s'exécutent toujours avec ces filtres désactivés. Voir la documentation de Python sur les avertissements, et en particulier la section sur les tests de dépréciation pour plus d'informations sur la façon de procéder.

  • Certains avertissements n'étaient auparavant émis qu'une seule fois, même s'ils étaient déclenchés à partir de plusieurs endroits. Ce comportement a été supprimé, il est donc possible que si vous appelez des fonctions dépréciées, vous receviez plus d'avertissements qu'auparavant. Vous devriez changer tous les appels de fonction dépréciés par les versions suggérées, car les formes dépréciées seront supprimées dans les prochaines versions de Qiskit.

  • Le module qiskit.schemas et le module qiskit.validation , qui construisent le validateur jsonschema à partir des schémas, ont été supprimés. Cette fonction a été supprimée dans la version 0.17.0 et a été remplacée par un dépôt dédié aux schémas de charge utile de l'API Quantum IBM.

    Si vous vous appuyiez sur les fichiers de schémas précédemment empaquetés dans qiskit.schemas ou sur les validateurs construits sur ces fichiers, vous devez utiliser ce référentiel et créer des validateurs à partir des fichiers de schémas qu'il contient.

  • Les fonctions qiskit.qobj.validate_qobj_against_schema et qiskit.qobj.common.validator ainsi que le kwarg validate des méthodes QasmQobj.to_dict(), PulseQobj.to_dict()et Qobj.to_dict() ont été supprimées. Ils ont été supprimés dans la version 0.17.0. Si vous utilisiez ces fonctions, vous devrez créer manuellement des fonctions de validation jsonschema pour les objets Qobj en utilisant les fichiers jsonschema du référentiel dédié aux schémas de charge utile de l'API IBM Quantum.

  • Les paquets fastjsonschema et jsonschema ne sont plus dans la liste des exigences pour qiskit-terra. L'utilisation interne de jsonschema a été supprimée et il n'est plus nécessaire d'utiliser qiskit-terra.

  • L'exception soulevée par la fonction assemble() lorsque des paramètres non valides sont transmis pour la construction d'un fichier de données PulseQobj sont passés de SchemaValidationError à QiskitError. Cela était nécessaire car la classe SchemaValidationError a été supprimée en même temps que le reste des classes dépréciées qiskit.schemas et qiskit.validation. Cela permet également d'être plus cohérent avec les autres conditions d'erreur de assemble() qui soulevaient déjà un QiskitError.

  • La passe de routage et la passe de mise en page par défaut pour l'optimisation de niveau 3 du transpilateur ont été modifiées pour utiliser SabreSwap et SabreLayout respectivement. Cela a été fait pour améliorer la qualité du résultat, car l'utilisation des passes de sabre donne de meilleurs résultats que l'utilisation de StochasticSwap et DenseLayoutqui étaient utilisés par défaut dans les versions précédentes. Cette modification améliorera la qualité des résultats lors de l'exécution de transpile() ou execute() avec le kwarg optimization_level fixé à 3. Bien qu'il s'agisse généralement d'une amélioration, si vous devez conserver le comportement précédent pour une raison quelconque, vous pouvez le faire en définissant explicitement les paramètres routing_method="stochastic" et layout_method="dense" lorsque vous appelez transpile() avec optimization_level=3.

  • Le type de retour de pauli_basis() passera de PauliTable à PauliList dans une prochaine version de Qiskit Terra. Pour passer immédiatement au nouveau comportement, passez l'argument du mot-clé pauli_list=True.

  • L'attribut name de la classe SingleQubitUnitary a été modifié de unitary à squ. Cela était nécessaire pour éviter un conflit avec le nom de la classe UnitaryGate qui était également unitary puisque les deux portes ne sont pas les mêmes et n'ont pas la même implémentation (et ne peuvent pas être utilisées de manière interchangeable).

  • La version minimale de Symengine requise pour l'installation a été augmentée à 0.8.0. Cette modification était nécessaire pour résoudre certains problèmes liés à la gestion des valeurs numpy.float16 et numpy.float32 lors de l'exécution de la commande bind() pour lier des paramètres dans un ParameterExpression.

  • Une nouvelle dépendance, celle de manutentionnaire, a été ajoutée à la liste des besoins. Ceci est requis par qiskit-terra car il est utilisé pour construire l'interface du plugin de synthèse unitaire.

Remarques concernant la dépréciation

  • L'attribut gate et le paramètre d'initialisation de qiskit.transpiler.passes.Decompose sont obsolètes et seront supprimés dans une prochaine version. Au lieu de cette porte unique, vous devez transmettre une liste de noms de portes au nouveau paramètre gates_to_decompose. En effet, le nouveau formulaire permet de sélectionner plus d'une porte comme cible de décomposition, ce qui est plus souple, et il n'est pas nécessaire de réexécuter la passe plusieurs fois pour décomposer un ensemble de portes.

  • Il y a eu une réorganisation importante du passage des transpileurs en ce qui concerne les étalonnages. Les chemins d'importation :

    from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilder
    from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilderNoEcho

    sont obsolètes et seront supprimées dans une prochaine version. Le chemin d'importation :

    from qiskit.transpiler.passes.scheduling.rzx_templates import rzx_templates

    est également obsolète et sera supprimée dans une prochaine version. Vous devez utiliser les nouveaux chemins d'importation :

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.transpiler.passes import RZXCalibrationBuilderNoEcho
    from qiskit.transpiler.passes.calibration.rzx_templates import rzx_templates
  • La classe DAGNode est dépréciée en tant que classe autonome et ne sera plus utilisée à l'avenir que comme classe parente de DAGOpNode, DAGInNode, et DAGOutNode. Dans le cadre de cette dépréciation, les kwargs suivants et les attributs associés dans DAGNode sont également dépréciés : type, op, et wire.

  • Pour le constructeur de l'élément RZXCalibrationBuilder le fait de passer un backend comme premier argument positionnel ou avec le kwarg nommé backend est déprécié et ne fonctionnera plus dans une prochaine version. Au lieu de cela, un InstructionScheduleMap devrait être transmis directement au kwarg instruction_schedule_map et une liste de noms de canaux pour chaque qubit devrait être transmise directement à qubit_channel_mapping. Par exemple, si vous appelez la passe comme suit :

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.test.mock import FakeMumbai
    
    backend = FakeMumbai()
    cal_pass = RZXCalibrationBuilder(backend)

    au lieu de cela, vous devriez l'appeler comme :

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

    Ce changement est nécessaire parce qu'en règle générale, les objets du backend ne sont pas sérialisables par Pickle et qu'ils seraient cassés s'ils étaient utilisés avec plusieurs processus à l'intérieur de transpile() lors de la compilation de plusieurs circuits à la fois.

  • La propriété label de la classe MCMT et de la sous-classe MCMTVChain est obsolète et sera supprimée dans une prochaine version. Par conséquent, le kwarg label du constructeur de ces deux classes est également déprécié, de même que le kwarg label de la méthode MCMT.control(). Actuellement, la propriété label est utilisée pour nommer la cible contrôlée lorsqu'elle est composée de plus d'un qubit cible. Cependant, cette propriété n'a jamais été conçue pour être spécifiée par l'utilisateur et peut entraîner une porte MCMT incorrecte si le nom d'une opération bien connue est utilisé. Après la dépréciation, la propriété label ne pourra plus être spécifiée par l'utilisateur. Cependant, vous pouvez obtenir le nom généré de la cible contrôlée via

    MCMT.data[0][0].base_gate.name
  • La méthode subgraph() de la classe CouplingMap est obsolète et sera supprimée dans une prochaine version. A la place, il faut utiliser la méthode reduce() qui fait la même chose, sauf qu'elle préserve l'ordre de la liste des nœuds pour la sortie CouplingMap (alors que subgraph() ne préservait pas l'ordre des listes).

  • La création d'une instance de InstructionSet avec le mot-clé circuit_cregs comme argument est obsolète. En général, ces classes n'ont jamais besoin d'être construites par les utilisateurs (mais sont utilisées en interne), mais si vous devez le faire, vous devez passer un appelable comme argument du mot-clé resource_requester . Par exemple :

    from qiskit.circuit import Clbit, ClassicalRegister, InstructionSet
    from qiskit.circuit.exceptions import CircuitError
    
    def my_requester(bits, registers):
        bits_set = set(bits)
        bits_flat = tuple(bits)
        registers_set = set(registers)
    
        def requester(specifier):
            if isinstance(specifer, Clbit) and specifier in bits_set:
                return specifier
            if isinstance(specifer, ClassicalRegster) and specifier in register_set:
                return specifier
            if isinstance(specifier, int) and 0 <= specifier < len(bits_flat):
                return bits_flat[specifier]
            raise CircuitError(f"Unknown resource: {specifier}")
    
        return requester
    
    my_bits = [Clbit() for _ in [None]*5]
    my_registers = [ClassicalRegister(n) for n in range(3)]
    
    InstructionSet(resource_requester=my_requester(my_bits, my_registers))
  • L'utilisation des classes d'atténuation des mesures qiskit.ignis.mitigation.CompleteMeasFitter et qiskit.ignis.mitigation.TensoredMeasFitter de qiskit-ignis comme valeurs pour le kwarg measurement_error_mitigation_cls du constructeur de la classe QuantumInstance est obsolète et sera supprimée dans une prochaine version. Au lieu de cela, les classes équivalentes de qiskit.utils.mitigation, CompleteMeasFitter et TensoredMeasFitter doivent être utilisées. Cela était nécessaire car le projet qiskit-ignis est désormais obsolète et ne sera plus pris en charge dans un avenir proche. Il convient de noter que, contrairement aux classes équivalentes de qiskit-ignis , les versions de qiskit.utils.mitigation ne sont supportées que dans leur utilisation avec QuantumInstance (c'est-à-dire en tant que classe et non en tant qu'instance avec le kwarg measurement_error_mitigation_cls ) et ne sont pas destinées à une utilisation autonome.

  • La méthode Optimizer.optimize() pour tous les optimiseurs (Optimizer et classes dérivées) est désormais obsolète et sera supprimée dans une prochaine version. Au lieu de cela, il convient d'utiliser la méthode Optimizer.minimize() qui imite la signature de la fonction SciPy’s minimize() .

    Pour remplacer l'appel à l'optimisation par l'appel à la minimisation, vous pouvez remplacer l'appel à l'optimisation par l'appel à la minimisation

    xopt, fopt, nfev = optimizer.optimize(
        num_vars,
        objective_function,
        gradient_function,
        variable_bounds,
        initial_point,
    )

    par

    result = optimizer.minimize(
        fun=objective_function,
        x0=initial_point,
        jac=gradient_function,
        bounds=variable_bounds,
    )
    xopt, fopt, nfev = result.x, result.fun, result.nfev
  • L'importation du module qiskit.util émettra désormais un message DeprecationWarning. Les utilisateurs devraient plutôt importer toutes les mêmes fonctionnalités à partir de qiskit.utils. Le module util est obsolète depuis Terra 0.17, mais n'émettait pas d'avertissement auparavant. Il sera supprimé sur le site Terra 0.20.

  • La propriété table est obsolète et sera supprimée dans une prochaine version. Ceci est dû au fait que SparsePauliOp a été mis à jour pour utiliser en interne PauliList au lieu de PauliTable. Ceci afin d'améliorer de manière significative les performances. Vous devez maintenant accéder aux PauliList en utilisant l'attribut SparsePauliOp.paulis pour accéder aux données.

Corrections des erreurs

  • Correction d'un bug où de nombreuses méthodes d'agencement ignoraient les portes à 3 qubits ou plus, ce qui entraînait des décisions d'allocation d'agencement inattendues. La passe de transpondeur Unroll3qOrMore est désormais exécutée avant la passe de mise en page dans tous les gestionnaires de passes prédéfinis lorsque l'option transpile() est appelé. Correction #7156.

  • Les circuits désassemblés héritent désormais des étalonnages des circuits assemblés et des expériences QasmQobj et des expériences. Corrige #5348.

  • Correction de la définition des attributs ansatz ou optimizer d'une instance de VQE à None , ce qui entraînait un bogue. Voir #7093 pour plus de détails.

  • Correction de l'ajout de PauliLists avec qargs. La méthode utilisée pour soulever une erreur d'exécution si les opérandes ont des nombres différents de qubits.

  • Correction d'un problème provoquant une erreur lors de la tentative de calcul d'un gradient avec la classe CircuitGradient pour une porte qui n'était pas une porte supportée. Ce correctif transpose une porte donnée dans l'ensemble des portes prises en charge pour une méthode de gradient donnée. Corrige #6918.

  • Suppression des résultats d'étalonnage lors de l'utilisation de l'atténuation des erreurs avec la execute() méthode de QuantumInstance. Corrige #7129.

  • Correction d'un avertissement de dépréciation émis lors de l'exécution de QuantumCircuit.draw() ou circuit_drawer() avec Sympy 1.9 installé, en mentionnant la fonction Sympy expr_free_symbols(). Les dessinateurs de circuits ont déjà utilisé cette méthode pour trouver des instances de constantes symboliques.

  • Correction d'un problème où le kwarg ax et l'option figwidth dans le kwarg style pour le tiroir de circuit mpl n'étaient pas mis à l'échelle correctement. Les utilisateurs peuvent désormais faire passer un ax d'un sous-graphe Matplotlib au tiroir de circuit mpl et le circuit sera dessiné à l'intérieur des limites de ce sous-graphe. L'utilisateur peut également définir l'adresse figwidth en pouces dans style dict kwarg et le dessin sera mis à l'échelle de la largeur en pouces définie. Correction #6367.

  • Correction d'un problème avec la fonction circuit_drawer() et la méthode draw() de la méthode QuantumCircuit. Lors de l'affichage d'une instruction measure ciblée sur un bit classique au lieu d'un registre, en utilisant l'option de tiroir latex , le tiroir échouait.

  • Correction d'un problème avec la fonction circuit_drawer() et la méthode draw() de la méthode QuantumCircuit. Avec l'une des trois options de tiroir, mpl, latex, ou text, si une porte avec une condition classique était rencontrée et conditionnée sur un bit classique sans registre, le tiroir échouerait.

  • Correction d'un problème avec la fonction circuit_drawer() et la méthode draw() de la méthode QuantumCircuit. Avec l'une des trois options de tiroir, mpl, latex, ou text, si une porte avec une condition classique était conditionnée sur le même bit classique qu'une measure et que le bit visé par la mesure n'avait pas de registre, le tiroir échouerait.

  • C3SXGate a maintenant une décomposition et une représentation matricielle correctes. Auparavant, il équivalait à SdgXGate().control(3), au lieu de SXGate().control(3).

  • Le membre name de qiskit.test.mock.utils.ConfigurableFakeBackend a été changé en backend_name. Ceci a été fait pour éviter un conflit avec la méthode name() héritée de la classe abstraite parente BackendV1 mère. Cela rend ConfigurableFakeBackend compatible avec tout ce qui attend un BackendV1 objet. Toutefois, si vous utilisiez l'attribut name directement auparavant, vous devrez l'appeler en tant que méthode ou accéder à l'attribut backend_name à la place.

  • Correction d'un problème où l'appel à QuantumCircuit.decompose() sur un circuit contenant un Instruction dont l'attribut definition était vide laissait l'instruction en place, au lieu de la décomposer en zéro opération. Par exemple, avec un circuit :

    from qiskit.circuit import QuantumCircuit
    empty = QuantumCircuit(1, name="decompose me!")
    circuit = QuantumCircuit(1)
    circuit.append(empty.to_gate(), [0])

    Auparavant, le fait d'appeler circuit.decompose() ne modifiait pas le circuit. Maintenant, la décomposition va correctement décomposer empty en zéro instruction. Voir #6997 pour plus d'informations.

  • Correction d'un problème avec la fonction circuit_drawer() et la méthode draw() de la méthode QuantumCircuit. Lors de l'affichage d'une instruction measure contenant une instruction classique condition à l'aide des options mpl ou latex , les informations condition écrasaient parfois l'affichage measure .

  • Correction d'un problème avec la fonction circuit_drawer() et la méthode draw() de la méthode QuantumCircuit. Le tiroir mpl utilise la notation hexagonale pour afficher la valeur condition , tandis que les tiroirs text et latex utilisent la notation décimale. Les trois tiroirs utilisent maintenant la notation hexagonale.

  • Correction d'un bogue dans la passe de transpilation de l'optimiseur Hoare, qui pouvait tenter de supprimer une porte deux fois si elle pouvait être combinée séparément avec son prédécesseur et son successeur pour former l'identité. Pour plus de détails, voir le numéro 7271.

  • Rendre une instruction conditionnelle avec la méthode standard InstructionSet.c_if() avec des indices entiers est maintenant cohérent avec le schéma de numérotation utilisé par le système de gestion des instructions QuantumCircuit dont les instructions font partie. Auparavant, si deux ClassicalRegisterse chevauchant, la numérotation était incorrecte Clbitse chevauchent, la numérotation était incorrecte. Voir #7246 pour plus de détails.

  • Rendre une instruction conditionnelle avec la méthode standard InstructionSet.c_if() réussira désormais, même s'il n'y a pas de ClassicalRegisterdans le circuit. Voir #7250 pour plus de détails.

  • Rendre une instruction conditionnelle avec la méthode standard InstructionSet.c_if() lors de l'utilisation d'un Clbit contenu dans un registre ClassicalRegister de taille 1 créera désormais correctement une condition sur le bit, et non sur le registre. Voir #7255 pour plus de détails.

  • Essayer de rendre une instruction conditionnelle avec la méthode standard InstructionSet.c_if() soulèvera désormais correctement une erreur si la ressource classique n'est pas présente dans le circuit. Voir #7255 pour plus de détails.

  • Correction d'un problème de compatibilité avec Matplotlib 3.5, où le rendu de la sphère de Bloch échouait s'il y avait des vecteurs attachés, comme en utilisant plot_bloch_vector. Voir #7272 pour plus de détails.

  • Correction d'un problème avec la méthode NLocal.add_layer() ajoutait incorrectement des couches si l'objet NLocal avait déjà été construit.

  • Correction d'un problème avec le décapage de l'objet InstructionScheduleMap lors de l'utilisation de Python 3.6. Voir #6944 pour plus de détails.

  • L'affectation de paramètres d'impulsion à valeur complexe avec le symengine a été corrigée. Exemple :

    from qiskit import circuit, pulse
    import numpy as np
    
    amp = circuit.Parameter("amp")
    phase = circuit.Parameter("phase")
    
    with pulse.build() as sched:
        pulse.play(pulse.Gaussian(160, amp * np.exp(1j * phase), 40), pulse.DriveChannel(0))
    sched.assign_parameters({amp: 0.1, phase: 1.57}, inplace=True)

    L'amplitude attribuée a été indiquée sous la forme ParameterExpression(0.1*exp(1.57*I)) après que l'utilisation de symengine a été introduite dans la version 0.18.0. L'évaluation est maintenant correcte et se traduit par 7.96327e-05 + 0.0999999683j.

  • Correction d'un problème où QAOA.construct_circuit() avec différents opérateurs avec le même nombre de qubits générait le même circuit à chaque fois. Voir #7223 pour plus de détails.

  • Correction d'un problème où QAOAAnsatz avait un nombre incorrect de paramètres si les identités de PauliSumOp étaient données, par exemple PauliSumOp.from_list([("III", 1)]). Voir #7225 pour plus de détails.

  • Correction d'un problème où la méthode QuantumCircuit.qasm() pouvait renvoyer des instructions OpenQASM 2 avec des identifiants non valides. Le même bogue a été corrigé pour UnitaryGate.

  • Correction d'un problème où le fait d'essayer d'afficher des bits sans registre entraînait une défaillance des tiroirs de circuits mpl et latex . Un _ a été supprimé de l'affichage des numéros des bits sans registre dans le tiroir text . Correction #6732.

  • Pour les registres d'un bit, tous les tiroirs de circuits n'affichent plus que le nom du registre et non plus l'indice 0 . Correction #5784.

  • Correction des collisions de noms des registres implicites dans QuantumCircuit.qasm lorsqu'il s'agit de qubits et de clbits sans registre. Auparavant, les qubits et les clbits sans registre étaient placés dans les sites correspondants qreg et creg , tous deux appelés regless, malgré la collision. Ils auront désormais des noms distincts, générés de manière déterministe, qui n'entreront pas en conflit avec les noms de registres définis par l'utilisateur dans le circuit.

  • Correction d'un problème dans l'ordonnancement des circuits avec des opérations clbits, par exemple des mesures, des portes conditionnelles, des mises à jour, etc ASAPSchedule, ALAPSchedule, et AlignMeasures. Les ordonnanceurs mis à jour supposent que toutes les opérations d'E/S des clbits ne prennent pas de temps, que measure écrit la valeur mesurée dans un clbit à la fin et que c_if lit la valeur conditionnelle dans le(s) clbit(s) au début. Correction #7006.

  • L'appel de transpile sur une liste vide renverra désormais correctement une liste vide sans émettre d'avertissement. Correction #7287.

  • Correction d'un problème dans PiecewiseChebyshev lorsque la fonction à approximer était constante. Dans ces cas, vous devez désormais transmettre la constante directement en tant qu'argument f_x , plutôt que d'utiliser une fonction, comme par exemple :

    from qiskit.circuit.library.arithmetic import PiecewiseChebyshev
    
    PiecewiseChebyshev(1.0, degree=3)

    Voir #6707 pour plus de détails.

  • Si une instance de l'algorithme HHL a été construite sans l'élément QuantumInstance (par défaut), les tentatives d'utilisation des propriétés getter et setter pour lire ou définir une instance ultérieurement échoueraient. Les getters et setters fonctionnent désormais comme prévu.

  • La méthode QuantumCircuit.qasm() édite maintenant les noms des copies des instructions présentes dans le circuit, et non les instructions originales qui se trouvent dans circuit.data. Pour plus de détails, voir le numéro 6952.

  • Correction d'un bug dans PauliSumOp.permute() provoquant l'erreur :

    QiskitError: 'Pauli string label "" is not valid.'

    si la permutation avait le même nombre de termes de Pauli. L'appel de permute([2, 1, 0]) sur X ^ Y ^ Z ne soulève plus d'erreur et renvoie désormais Z ^ Y ^ X.

  • Correction d'un bogue où les limites des paramètres du mélangeur dans la section QAOAAnsatz n'étaient pas définies.

  • Détermination fixe des opérations finales (barrières et mesures) en passe RemoveFinalMeasurements et en méthode remove_final_measurements() de la classe QuantumCircuit qui, auparavant, ne prenaient en compte que les nœuds précédant immédiatement un nœud de sortie.

  • Détermination fixe des opérations finales dans la passe RemoveFinalMeasurements et dans la méthode remove_final_measurements() de la classe QuantumCircuit qui pouvaient considérer à tort une barrière comme finale, même si d'autres opérations du circuit la suivaient.

  • Correction de la suppression du registre classique multi-bits dans la passe RemoveFinalMeasurements et dans la méthode remove_final_measurements() de la classe QuantumCircuit où les registres classiques n'étaient pas supprimés même si d'autres bits étaient inactifs, à moins qu'une mesure finale n'ait été effectuée sur chaque bit. Désormais, les registres classiques qui deviennent inactifs à la suite de la suppression des mesures finales et des barrières sont toujours supprimés. Les bits classiques sont supprimés s'ils sont référencés uniquement par des registres supprimés ou s'ils ne sont pas référencés du tout et sont devenus inactifs en raison de la suppression. Cette correction permet également de gérer correctement les registres dont les bits sous-jacents sont partagés.

  • Correction d'un problème avec RemoveFinalMeasurements qui pouvait entraîner l'invalidité du résultat DAGCircuit de devenir invalide. Voir #7196 pour plus de détails.

  • Correction d'un problème avec la méthode remove_final_measurements() de la classe QuantumCircuit qui faisait que la méthode QuantumCircuit.clbits était incorrect après l'invocation. Se référer au n° 7089 pour plus de détails.

  • Lors de l'effilage d'un opérateur zéro vide dans qiskit.opflowle code, en détectant qu'il s'agissait d'un zéro, enregistre un avertissement et renvoie l'opérateur d'origine. De tels opérateurs sont souvent présents dans les opérateurs auxiliaires, lors de l'utilisation de Qiskit Nature, et le comportement ci-dessus a conduit VQE à lancer une exception car les opérateurs non nuls tapés étaient un nombre de qubits différent des opérateurs nuls tapés (puisque taper a retourné l'opérateur d'entrée inchangé). Le code va maintenant correctement réduire un opérateur zéro de sorte que le nombre de qubits est réduit comme prévu et correspond aux opérateurs non nuls réduits, par exemple `0*"IIII"` lorsque nous réduisons de 3 qubits deviendra 0*"I".

  • Correction d'un problème avec la méthode draw() et la fonction circuit_drawer() où un style personnalisé défini via le fichier de configuration de l'utilisateur (c'est-à-dire settings.conf) ignorerait la valeur définie du champ circuit_mpl_style si le kwarg style de la fonction/méthode n'était pas défini.

Autres remarques

  • La chaîne de caractères utilisée pour qiskit.circuit.ParameterExpression n'a plus de précision totale. Cela supprime le 0s de fin lors de l'impression des paramètres liés à des flottants. Cela a des conséquences pour la sérialisation des QASM et le tiroir de texte du circuit :

    >>> from qiskit.circuit import Parameter
    >>> x = Parameter('x')
    >>> str(x.bind({x:0.5}))
    '0.5'   # instead of '0.500000000000000'
  • Le QAOAAnsatz a été mis à jour pour utiliser le symbole de paramètre γ pour l'opérateur de coût et β pour l'opérateur de mélange, comme c'est le cas dans la littérature de l'AQAO.

Aer 0.9.1

Pas de modification

Ignis 0.7.0

Prélude

Cette version déprécie le projet Qiskit Ignis, qui a été supplanté par le projet Qiskit Experiments et dont le développement actif a cessé. Bien qu'il s'agisse d'une version obsolète, des corrections de bogues critiques et des corrections de compatibilité continueront d'être apportées afin de donner aux utilisateurs une opportunité suffisante de migrer hors d'Ignis. Après la période de dépréciation (qui ne sera pas inférieure à 3 mois à partir de cette version), le projet sera retiré et archivé.

Nouvelles fonctions

  • Mise à jour du protocole d'accréditation afin d'utiliser la routine d'ajustement de https://arxiv.org/abs/2103.06603. AccreditationFitter possède désormais les méthodes FullAccreditation (protocole précédent) et MeanAccreditation (nouveau protocole). En outre, la saisie des données a été modifiée pour utiliser soit l'objet résultat AppendResult soit une liste de chaînes de caractères AppendStrings. qiskit.ignis.verification.QOTPCorrectString() a également été ajouté.

  • Ajout d'une option pour la génération analytique rapide de graphiques de syndromes. Le site RepetitionCode dispose désormais d'un nouvel argument bool brute, qui permet de continuer à utiliser la méthode de la force brute. La classe d'aide RepetitionCodeSyndromeGenerator a été ajoutée pour faciliter cette opération.

  • Le site RepetitionCode a maintenant des arguments de type mot-clé : resets et delay. Le premier détermine si des portes de réinitialisation sont insérées après la mesure. Ce dernier permet de spécifier un temps (en dt) pour un délai après chaque mesure (et réinitialisation, le cas échéant).

    La méthode syndrome_measurement() de RepetitionCode a maintenant des arguments de mots-clés final et delay. Le premier détermine s'il convient d'ajouter des portes de réinitialisation conformément au site global resets ou de le remplacer par un comportement approprié pour la dernière série de mesures du syndrome. Ce dernier permet de spécifier un temps (en dt) pour un délai après chaque mesure (et réinitialisation, le cas échéant).

  • La classe RepetitionCode prend désormais en charge l'encodage avec x états de base. Cela peut être utilisé en définissant l'argument du mot-clé xbasis lors de la construction d'un objet RepetitionCode .

Mise à niveau

  • Le mot-clé reset a été supprimé de la méthode syndrome_measurement() de RepetitionCode. Il est remplacé par le mot-clé global resets pour la classe ainsi que par le mot-clé final pour syndrome_measurement. Dans les cas où l'on ajoutait auparavant le dernier tour de mesure à l'aide de reset=False pour éviter les portes de réinitialisation finales, il convient désormais d'utiliser final=True.

  • Retirer ParametrizedSchedule de update_u_gates().

    ParametrizedSchedule a été supprimé dans le cadre de Qiskit-terra 0.17.0 et sera supprimé dans la prochaine version. La fonction met désormais à jour les portes u avec les programmes Schedule impliquant des objets Parameter non assignés.

Remarques concernant la dépréciation

  • Méthodes dépréciées dans AccreditationFitter , à savoir bound_variation_distance et single_protocol_run

  • Le projet Qiskit Ignis dans son ensemble a été déprécié et le projet sera retiré et archivé à l'avenir. Bien qu'il soit déprécié, seules les corrections de compatibilité et les corrections de bogues critiques seront apportées au projet. Au lieu d'utiliser Qiskit Ignis, vous devriez migrer vers Qiskit Experiments. Vous pouvez vous référer au guide de migration :

    https://github.com/qiskit-community/qiskit-ignis#migration-guide

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