Note
Cette page a été générée à partir de `tutorials/circuits_advanced/05_pulse_gates.ipynb`__.
Exécuter en mode interactif dans le IBM Quantum lab.
Portes d’impulsions¶
Most quantum algorithms can be described with circuit operations alone. When we need more control over the low-level implementation of our program, we can use pulse gates. Pulse gates remove the constraint of executing circuits with basis gates only, and also allow you to override the default implementation of any basis gate.
Les portes d’impulsions vous permettent de faire correspondre une porte quantique (par exemple, X
) à un programme Qiskit Pulse, appelé Schedule
. Cette correspondance est appelée une calibration. Une calibration de haute fidélité est une calibration qui implémente fidèlement l’opération voulue (par exemple, la fidélité avec laquelle une porte X
fait passer l’état de \(|0\rangle\) à \(|1\rangle\), etc.).
Un schedule (planning) spécifie la dynamique temporelle exacte des signaux d’entrée sur tous les canaux channels allant vers le système. Il existe généralement plusieurs canaux par qubit, tels que le canal d’entrée et le canal de mesure. Cette interface est plus puissante et nécessite une compréhension plus approfondie de la physique des dispositifs sous-jacents.
Il est important de noter que les programmes Pulse fonctionnent sur des qubits physiques. Une impulsion d’entraînement sur le qubit \(a\) ne va pas mettre en oeuvre la même opération logique sur l’état d’un autre qubit \(b\)-en d’autres termes, les étalonnages d’un porte ne sont pas interchan geables d’un qubit à un autre. Ceci contrairement au niveau circuit, où une porte X
est définie indépendamment du qubit sur lequel elle opère.
Cette page vous montre comment ajouter une calibration à votre circuit.
Note: Pour exécuter un programme avec des portes d’impulsion, le backend doit être activé avec OpenPulse. Vous pouvez vérifier cela en utilisant backend.configuration().open_pulse
, qui est True
quand OpenPulse est activé. S’il est activé et que la fonction des portes d’impulsion n’est pas activée, vous pouvez `construire<07_pulse_scheduler.ipynb>`__ votre circuit d’entrée.
Construire votre circuit¶
Commençons par un exemple très simple, un circuit produisant l’état de Bell.
[1]:
from qiskit import QuantumCircuit
circ = QuantumCircuit(2, 2)
circ.h(0)
circ.cx(0, 1)
circ.measure(0, 0)
circ.measure(1, 1)
circ.draw('mpl')
[1]:

Construire vos calibrations¶
Maintenant que nous avons notre circuit, définissons une calibration pour la porte Hadamard sur le qubit 0.
Dans la pratique, la forme de l’impulsion et ses paramètres devraient être optimisés à travers une série d’expériences de Rabi (voir le Qiskit Textbook pour une preemière approche). Pour cette démonstration, notre Hadamard sera une impulsion gaussienne. Nous allons jouer notre impulsion sur le canal d’entrée du qubit 0.
Ne vous inquiétez pas trop des détails de la construction de l’étalonnage lui-même ; vous pouvez en apprendre plus sur ce sujet à la page suivante: `construction des ordonnancements d’impulsions<06_building_pulse_schedules.ipynb> `__.
[2]:
from qiskit import pulse
from qiskit.pulse.library import Gaussian
from qiskit.test.mock import FakeValencia
backend = FakeValencia()
with pulse.build(backend, name='hadamard') as h_q0:
pulse.play(Gaussian(duration=128, amp=0.1, sigma=16), pulse.drive_channel(0))
Dessinons le nouveau programme d’impulsions pour voir ce que nous avons construit.
[3]:
h_q0.draw()
[3]:

Connectez votre calibration à votre circuit¶
Il ne reste plus qu’à compléter l’enregistrement. La méthode de circuit add_calibration
a besoin d’informations sur la porte et d’une référence à la planification pour terminer la correspondance:
QuantumCircuit.add_calibration(gate, qubits, schedule, parameters)
La gate``(porte) peut être soit un objet de type ``circuit.Gate
soit le nom d’une porte. Habituellement, vous aurez besoin d’un planning différent pour chaque ensemble unique de qubits
et de parameters
. Puisque la porte Hadamard n’a aucun paramètre, nous n’avons pas à en fournir un.
[4]:
circ.add_calibration('h', [0], h_q0)
Enfin, notez que le transpilleur respectera vos calibrations. Utilisez-le comme vous le feriez normalement (ici, notre exemple est trop simple pour que le transpilleur puisse optimiser, donc la sortie est la même).
[5]:
from qiskit import transpile
from qiskit.test.mock import FakeAlmaden
backend = FakeAlmaden()
circ = transpile(circ, backend)
print(backend.configuration().basis_gates)
circ.draw('mpl', idle_wires=False)
['id', 'u1', 'u2', 'u3', 'cx']
[5]:

Notez que h
n’est pas une porte de base pour le backend simulé FakeAlmaden
. Puisque nous avons ajouté une calibration pour elle, le transpilleur traitera notre porte comme une porte de base; mais seulement sur les qubits pour lesquels elle a été définie. Une porte de Hadamard appliquée à un autre qubit aurait été transformée en une suite de portes de base.
C’est tout !
Portes personnalisées¶
Nous montrerons brièvement le même processus pour les portes non standard, complètement personnalisées. Cette démonstration comprend une porte avec des paramètres.
[6]:
from qiskit import QuantumCircuit
from qiskit.circuit import Gate
circ = QuantumCircuit(1, 1)
custom_gate = Gate('my_custom_gate', 1, [3.14, 1])
# 3.14 is an arbitrary parameter for demonstration
circ.append(custom_gate, [0])
circ.measure(0, 0)
circ.draw('mpl')
[6]:

[7]:
with pulse.build(backend, name='custom') as my_schedule:
pulse.play(Gaussian(duration=64, amp=0.2, sigma=8), pulse.drive_channel(0))
circ.add_calibration('my_custom_gate', [0], my_schedule, [3.14, 1])
# Alternatively: circ.add_calibration(custom_gate, [0], my_schedule)
Si nous utilisons la variable custom_gate
de l’instance Gate
pour ajouter l’étalonnage, les paramètres sont dérivés de cette instance. N’oubliez pas que l’ordre des paramètres est significatif.
[8]:
circ = transpile(circ, backend)
circ.draw('mpl', idle_wires=False)
[8]:

Normalement, si nous essayions de transpile notre circuit circ
, nous aurions une erreur. Aucune définition fonctionnelle n’ayant été fournie pour "my_custom_gate"
, de sorte que le transpileur ne peut pas le faire correspondre à des portes de l’ensemble dese portes de base de l’appareil cible. Nous pouvons le montrer en essayant d’ajouter "my_custom_gate"
à un autre qubit qui lui n’a pas été calibré.
[9]:
circ = QuantumCircuit(2, 2)
circ.append(custom_gate, [1])
from qiskit import QiskitError
try:
circ = transpile(circ, backend)
except QiskitError as e:
print(e)
"Cannot unroll the circuit to the given basis, ['id', 'u1', 'u2', 'u3', 'cx']. Instruction my_custom_gate not found in equivalence library and no rule found to expand."
[10]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
/Users/thomas/opt/anaconda3/envs/qiskit-3.8/lib/python3.8/site-packages/qiskit/aqua/operators/operator_globals.py:48: DeprecationWarning: `from_label` is deprecated and will be removed no earlier than 3 months after the release date. Use Pauli(label) instead.
X = make_immutable(PrimitiveOp(Pauli.from_label('X')))
Version Information
Qiskit Software | Version |
---|---|
Qiskit | 0.23.6 |
Terra | 0.17.0 |
Aer | 0.7.5 |
Ignis | 0.5.2 |
Aqua | 0.8.2 |
IBM Q Provider | 0.11.1 |
System information | |
Python | 3.8.5 (default, Aug 5 2020, 03:39:04) [Clang 10.0.0 ] |
OS | Darwin |
CPUs | 8 |
Memory (Gb) | 32.0 |
Sat Feb 27 11:07:23 2021 AST |
This code is a part of Qiskit
© Copyright IBM 2017, 2021.
This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.