Nota
Esta página foi gerada de tutorials/circuits_advanced/05_pulse_gates.ipynb.
Portas de pulso¶
A maioria dos algoritmos quânticos podem ser descritos, simplesmente, com operações de circuito. Quando precisamos de mais controle sobre a implementação de baixo nível do nosso programa, podemos usar portas de pulso. Portas de pulso removem a restrição de executar circuitos, apenas com portões de base, e, também permitem que você substitua a implementação padrão de qualquer portão de base.
Portas de pulso permitem mapear uma porta de circuito lógico (por exemplo, X
) para um programa Qiskit Pulse chamado de Schedule
. Este mapeamento é referido como uma calibração. Uma calibração de alta fidelidade é uma que implementa fielmente a operação lógica da qual é mapeada (por exemplo, se a calibração do X
direciona \(|0\rangle\) to \(|1\rangle\), etc.).
Uma programação especifica a dinâmica de tempo exata dos sinais de entrada em todas as entradas canais para o dispositivo. Geralmente, há vários canais por qubit, como direção e medida. Essa interface é mais poderosa e requer uma compreensão mais profunda da física do dispositivo subjacente.
It’s important to note that Pulse programs operate on physical qubits. A drive pulse on qubit \(a\) will not enact the same logical operation on the state of qubit \(b\) – in other words, gate calibrations are not interchangeable across qubits. This is in contrast to the circuit level, where an X
gate is defined independent of its qubit operand.
Esta página mostra como adicionar uma calibração ao seu circuito.
Nota: Para executar um programa com portas de pulso, o backend deve ser habilitado com o OpenPulse. Você pode verificar, via backend.configuration().open_pulse
, que é True
, quando o OpenPulse está habilitado. Se estiver habilitado e as portas de pulso não estiverem ativados, você pode, no seu circuito de entrada agendar.
Construindo o circuito¶
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]:

Fazendo as suas calibrações¶
Now that we have our circuit, let’s define a calibration for the Hadamard gate on qubit 0.
Na prática a forma do pulso e seus parâmetros serão otimizados através de uma série de experimentos Rabi (veja o Qiskit Textbook para uma explicação). Para esta demonstração, nosso Hadamard será um pulso gaussiano. Vamos jogar nosso pulso no canal direção do 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.providers.fake_provider 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]:

Vincule sua calibração ao seu circuito¶
Resta, apenas, completar o registro. O método de circuito add_calibration
precisa de informações sobre a porta e a referência ao cronograma para completar o mapeamento:
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)
Por último, note que o transpilador respeitará suas calibrações. Use-o como você normalmente usaria (nosso exemplo é muito simples para que o transpilador o otimize, então a saída é a mesma).
[5]:
from qiskit import transpile
from qiskit.providers.fake_provider import FakeHanoi
backend = FakeHanoi()
circ = transpile(circ, backend)
print(backend.configuration().basis_gates)
circ.draw('mpl', idle_wires=False)
['id', 'rz', 'sx', 'x', 'cx', 'reset']
[5]:

Notice that h
is not a basis gate for the mock backend FakeHanoi
. 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!
Portas personalizadas¶
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)
Se usarmos a variável de instância Gate
custom_gate
para adicionar a calibração, os parâmetros são derivados dessa instância. Lembre-se de que a ordem dos parâmetros é significativa.
[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', 'rz', 'sx', 'x', 'cx', 'reset']. 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
Version Information
Qiskit Software | Version |
---|---|
qiskit-terra | 0.21.2 |
qiskit-aer | 0.10.4 |
qiskit-ibmq-provider | 0.19.2 |
qiskit | 0.37.2 |
System information | |
Python version | 3.10.7 |
Python compiler | GCC 12.2.0 |
Python build | main, Sep 6 2022 21:22:27 |
OS | Linux |
CPUs | 32 |
Memory (Gb) | 125.64828109741211 |
Mon Sep 12 15:28:25 2022 EDT |
This code is a part of Qiskit
© Copyright IBM 2017, 2022.
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.