RelabelModes
class RelabelModes(permutation=None, *, solver=None, **kwargs)
Bases : GenericPass[DAGCircuit, DAGCircuit]
Une passe de transpilation visant à renommer les modes fermioniques.
Cette passe réorganise les modes fermioniques d'un circuit. Le réordonnancement est décrit par une liste permutation , qui correspond à une correspondance entre l'index du mode d'origine et celui du nouveau mode : le mode d'origine i est placé à la nouvelle position dans permutation[i] le circuit réétiqueté. Par exemple, il place permutation = [0, 2, 4, 1, 3, 5] le mode d’origine 1 à un nouvel index 2, le mode d’origine 2 à un nouvel index 4, et ainsi de suite. S'agissant d'une permutation, chaque indice doit apparaître exactement une fois.
Post-traitement
Ce réétiquetage réorganise les modes fermioniques, ce qui influe à son tour sur la correspondance entre fermions et qubits choisie lors d'une étape de synthèse ultérieure (et donc sur la profondeur de circuit pouvant être atteinte). Étant donné que l'ordre des modes change, toute chaîne de bits échantillonnée à partir du circuit final est exprimée selon ce nouvel ordre et doit être reconvertie dans l'ordre d'origine avant de pouvoir être interprétée. Le changement d'étiquette qui a effectivement été appliqué est consigné dans un champ permutation des FermionicDAGCircuitéléments renvoyés metadata.
Lisez toujours les nouvelles étiquettes à partir des métadonnées du circuit plutôt que à partir de permutation. Lorsque l'optimisation automatique est utilisée (c'est-à-dire permutation (c'est-à-dire que None) la permutation appliquée n'est disponible qu'à partir des métadonnées; et même lorsque celle-ci a permutation été fournie explicitement, les métadonnées reflètent à coup sûr ce qu'a fait le passage.
Notez que le champ de métadonnées permutation n'apparaît que lorsque le passage a effectivement réétiqueté le circuit. Lorsque cette étape n'a aucun effet – par exemple, lorsque l'optimisation automatique ne peut pas s'exécuter en raison de solver l'absence d'une pyomo dépendance optionnelle ou d'un – le circuit renvoyé reste inchangé et ne contient aucune métadonnée permutation ; il convient donc de l'utiliser avec prudence (par exemple, qcirc.metadata.get("permutation")).
D'un point de vue conceptuel, l'annulation du réétiquetage attribue à chaque mode d'origine la m valeur qui avait été mesurée pour le nouveau mode permutation[m]. Dans la pratique, cela est compliqué par le fait que les FermionicRegister modes et les bits classiques de Qiskit sont organisés dans un ordre inverse (little-endian); ainsi, l'opération de regroupement dans l'espace des modes se transforme en une inversion d'indice (~idx) suivie d'une inversion finale ([::-1]) sur les chaînes de bits de comptage.
L'exemple ci-dessous consiste à réétiqueter un système à six modes, en passant d'un ordre de spin bloqué ([u0, u1, u2, d0, d1, d2]) à un ordre entrelacé ([u0, d0, u1, d1, u2, d2]), une astuce courante pour réduire la profondeur de mise en œuvre, puis à annuler ce réétiquetage sur les comptes échantillonnés :
>>> from qiskit.passmanager import MultiStagePassManager
>>> from qiskit.providers.basic_provider import BasicSimulator
>>> from qiskit_fermions.circuit import FermionicCircuit
>>> from qiskit_fermions.circuit.library import InitializeModes
>>> from qiskit_fermions.transpiler import FermionicCircuitToDAG, QuantumDAGToCircuit
>>> from qiskit_fermions.transpiler.passes import (
... F2QSynthesis, F2QSynthesisPluginManager, RelabelModes, TrivialF2QLayout,
... )
>>>
>>> # blocked occupation: spin-up orbitals 0 and 1 and spin-down orbital 0 are occupied
>>> circ = FermionicCircuit(6)
>>> circ.append(InitializeModes([1, 1, 0, 1, 0, 0]), circ.modes)
>>>
>>> synth_plugins = F2QSynthesisPluginManager()
>>> synth = F2QSynthesis()
>>> synth.methods["InitializeModes"] = synth_plugins.method("InitializeModes", "TrivialOccupation")()
>>>
>>> # map blocked mode order onto the interleaved one
>>> relabel = RelabelModes(permutation=[0, 2, 4, 1, 3, 5])
>>>
>>> pm = MultiStagePassManager(
... init=FermionicCircuitToDAG(),
... optimization=relabel,
... layout=TrivialF2QLayout(),
... synthesis=synth,
... output=QuantumDAGToCircuit(),
... )
>>>
>>> qcirc = pm.run(circ)
>>> qcirc.measure_all()
>>>
>>> bit_permutation = qcirc.metadata.get("permutation")
>>> print(bit_permutation)
[0, 2, 4, 1, 3, 5]
>>>
>>> res = BasicSimulator().run(qcirc, shots=1).result()
>>> counts = res.get_counts()
>>> print(counts) # measured in the interleaved ordering
{'000111': 1}
>>>
>>> # undo the relabeling to recover the counts in the original blocked ordering
>>> post_processed = {
... "".join(bitstring[~idx] for idx in bit_permutation)[::-1]: count
... for bitstring, count in counts.items()
... }
>>> print(post_processed) # recovered in the original blocked ordering
{'001011': 1}
L'initialisation de ce passage du transpileur peut s'effectuer à l'aide des arguments indiqués ci-dessous.
Paramètres
- permutation (list[int] | None) – la permutation d'indices utilisée pour renommer les indices des modes fermioniques. Lorsque ce sera le cas
None, une permutation sera déterminée automatiquement en fonction debuild_excitation_span_minimization_model(). Voir égalementpermutationpour plus de détails. - solver (pyomo.opt.SolverFactory | None) – l'instance du solveur de problèmes d'optimisation utilisée pour résoudre le problème
build_excitation_span_minimization_model(). Dans ce casNone, aucune valeur ne peutpermutationêtre déterminée automatiquement. Voir égalementsolverpour plus de détails. - kwargs – tout argument de mot-clé supplémentaire sera transmis à
build_excitation_span_minimization_model().
Attributs
permutation
La permutation d'indices utilisée pour renommer les indices des modes fermioniques.
Il peut s'agir soit d'une fonction list[int]qui mappe l'index du mode d'origine i vers le nouvel index de mode permutation[i] (voir la chaîne de documentation de la classe pour plus de détails). Sa longueur doit correspondre au nombre de modes fermioniques du circuit faisant l'objet de la transpilation, et chaque indice doit apparaître exactement une fois. Ce scénario nécessite donc que la passe de transcompilation soit adaptée de manière très spécifique au circuit de l'utilisateur.
Ou bien il se peut que None, dans ce cas, la fonction build_excitation_span_minimization_model() soit utilisée pour définir un problème d'optimisation visant à minimiser l'enveloppe de toutes les excitations fermioniques présentes. Dans ce cas, la permutation appliquée n'est accessible qu'à partir des métadonnées du circuit transpilé (voir la chaîne de documentation de la classe).
L'utilisation de ce modèle d'optimisation n'est mise en œuvre que pour les portes d'évolution temporelle contenant une instance FermionOperator de.
solver
L'instance du solveur de problèmes d'optimisation permettant de trouver automatiquement permutation.
Lorsque vaut permutation None, le problème d'optimisation défini par build_excitation_span_minimization_model() est utilisé pour trouver automatiquement une bonne permutation des indices de mode. Dans ce cas, l'utilisateur doit fournir un optimiseur pour résoudre ce modèle.
Méthodes
find_permutation
find_permutation(dag)
Recherche un index de mode permutation lorsqu'il n'est pas spécifié par l'utilisateur.
Cette fonction n'est appelée que lorsque n'est permutation pas spécifié par l'utilisateur (c'est-à-dire lorsqu'il s'agit de None). Dans ce cas, il procède comme suit :
- Assurez-vous que la dépendance facultative « pyomo » est installée. Sinon, aucune optimisation ne peut être effectuée et ce passage du transcompilateur n'a aucun effet.
- Assurez-vous qu’un est
solverspécifié. Sinon, aucune optimisation ne peut être effectuée et ce passage du transcompilateur n'a aucun effet. - rassembler toutes les excitations fermioniques provenant de toutes les portes
Evolutioncontenant une instanceFermionOperator. - construire le problème d'optimisation à l'aide de
build_excitation_span_minimization_model(), en transmettant tous les arguments clés supplémentaires (kwargs) provenant de la construction de ce passage du transcompilateur. - résoudre le problème d'optimisation à l'aide de
solveret extraire la permutation finale.
Paramètres
dag (FermionicDAGCircuit) – le circuit à transpilé.
Retours
La permutation à utiliser. Dans ce cas None, cette étape du transcompilateur n'aura aucun effet.
Augmentations
NotImplementedError – lorsqu’on rencontre une porte Evolution contenant un opérateur qui n’est pas une instance FermionOperator de.
Type de retour
tuple [ list [ int ] | None, pyomo.opt.results.results_.SolverResults | None]
run
run(dag)
Exécute cette passe de transpilation.
Paramètres
dag (DAGCircuit) – le circuit d'entrée avec des instructions basées sur les fermions. Seules les instances FermionicGate telles que DAGOpNode celles-ci op sont prises en charge.
Retours
Le circuit de sortie, qui agit toujours sur un registre fermionique.
Augmentations
NotImplementedError – lorsque le circuit d'entrée fourni comporte plus d'un registre.
Type de retour
Méthodes héritées
execute
execute(passmanager_ir, state, callback=None)
Exécuter la tâche d'optimisation pour le fichier IR Qiskit fourni.
Paramètres
- passmanager_ir (IR) – IR de Qiskit à optimiser.
- state (PassManagerState) – État lié à l'exécution du flux de travail par le gestionnaire de passes lui-même.
- callback (Callable[[Task, IR_OUT, PropertySet, float, int], None] | None) – Une fonction de rappel qui est appelée à chaque exécution d'une tâche d'optimisation.
Retours
Optimisation de l'IR de Qiskit et état d'avancement du workflow.
Type de retour
tuple [ IR_OUT, PassManagerState ]
name
update_status
update_status(state, run_state)
Mettre à jour le statut du workflow.
Paramètres
- state (PassManagerState) – Transmettre l'état du gestionnaire pour la mise à jour.
- run_state (RunState) – État d'avancement de la tâche en cours.
Retours
Mise à jour de l'état du gestionnaire de pass.
Type de retour