Portuguese
Idiomas
English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

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]:
../../_images/tutorials_circuits_advanced_05_pulse_gates_2_0.png

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]:
../../_images/tutorials_circuits_advanced_05_pulse_gates_6_0.png

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]:
../../_images/tutorials_circuits_advanced_05_pulse_gates_10_1.png

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]:
../../_images/tutorials_circuits_advanced_05_pulse_gates_12_0.png
[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]:
../../_images/tutorials_circuits_advanced_05_pulse_gates_15_0.png

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 SoftwareVersion
qiskit-terra0.21.2
qiskit-aer0.10.4
qiskit-ibmq-provider0.19.2
qiskit0.37.2
System information
Python version3.10.7
Python compilerGCC 12.2.0
Python buildmain, Sep 6 2022 21:22:27
OSLinux
CPUs32
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.