펄스 게이트들¶
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.
펄스 게이트를 사용하면 논리 회로 게이트(예: X
)를 스케쥴
이라고 하는 키스킷 펄스 프로그램에 사상할 수 있다. 이 사상 작업을 교정 이라고 한다. 높은 정확도의 교정은 사상 된 논리 연산(예: X
게이트 교정은 \(|0\rangle\) 을 \(|1\rangle\) 로 바꾼다, 등등)을 충실히 구현하는 교정이다.
스케줄은 장치에 대한 모든 입력 채널들 에 걸쳐 입력 신호의 정확한 시간 역학을 지정한다. 일반적으로 큐비트 마다드라이브 및 측정과 같은 여러 채널이 있다. 이 인터페이스는 더 강력하며 기본적인 장치의 물리학적 원리를 더 깊이 이해해야 한다.
펄스 프로그램은 물리적인 큐비트에 작용하는 것임을 기억하는 것이 중요합니다. 큐빗의 드라이브 펄스 \(a\) 는 큐빗의 상태 :math:`b`에 같은 논리적 연산을 하지 않습니다 - 바꾸어 말하면 게이트 보정은 큐비트들 사이에 상호 교환이 가능하지 않습니다. 이것은 ``X`게이트가 대상 큐비트에 독립적으로 정의되는 회로 레벨과는 대조적입니다.
이 페이지는 여러분의 회로에 보정을 추가하는 법을 설명합니다.
주: 펄스 게이트가 있는 프로그램을 실행하기 위해서는 OpenPulse를 지원하는 벡엔드를 사용해야 한다. ``backend.configuration().open_pulse``의 옵션이 ``True``인 것으로 OpenPulse를 사용할 수 있는지 확인할 수 있다. 오픈펄스가 활성화 되어 있고 펄스 게이트 기능이 사용하지 않은 경우 입력 회로에 `스케쥴 <07_pulse_scheduler.ipynb>`__을 사용할 수 있다.
Build your circuit¶
Let’s start with a very simple example, a Bell state circuit.
[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]:

Build your calibrations¶
Now that we have our circuit, let’s define a calibration for the Hadamard gate on qubit 0.
In practice, the pulse shape and its parameters would be optimized through a series of Rabi experiments (see the Qiskit Textbook for a walk through). For this demonstration, our Hadamard will be a Gaussian pulse. We will play our pulse on the drive channel of qubit 0.
Don’t worry too much about the details of building the calibration itself; you can learn all about this on the following page: building pulse schedules.
[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))
Let’s draw the new schedule to see what we’ve built.
[3]:
h_q0.draw()
[3]:

Link your calibration to your circuit¶
All that remains is to complete the registration. The circuit method add_calibration
needs information about the gate and a reference to the schedule to complete the mapping:
QuantumCircuit.add_calibration(gate, qubits, schedule, parameters)
The gate
can either be a circuit.Gate
object or the name of the gate. Usually, you’ll need a different schedule for each unique set of qubits
and parameters
. Since the Hadamard gate doesn’t have any parameters, we don’t have to supply any.
[4]:
circ.add_calibration('h', [0], h_q0)
Lastly, note that the transpiler will respect your calibrations. Use it as you normally would (our example is too simple for the transpiler to optimize, so the output is the same).
[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]:

Notice that h
is not a basis gate for the mock backend FakeAlmaden
. Since we have added a calibration for it, the transpiler will treat our gate as a basis gate; but only on the qubits for which it was defined. A Hadamard applied to a different qubit would be unrolled to the basis gates.
That’s it!
Custom gates¶
We’ll briefly show the same process for nonstandard, completely custom gates. This demonstration includes a gate with parameters.
[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)
If we use the Gate
instance variable custom_gate
to add the calibration, the parameters are derived from that instance. Remember that the order of parameters is meaningful.
[8]:
circ = transpile(circ, backend)
circ.draw('mpl', idle_wires=False)
[8]:

Normally, if we tried to transpile our circ
, we would get an error. There was no functional definition provided for "my_custom_gate"
, so the transpiler can’t unroll it to the basis gate set of the target device. We can show this by trying to add "my_custom_gate"
to another qubit which hasn’t been calibrated.
[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.