Spanish
Idiomas
English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

Nota

Esta página fue generada a partir de tutorials/circuits_advanced/05_pulse_gates.ipynb.

Compuertas de pulso

La mayoría de los algoritmos cuánticos se pueden describir solo con operaciones de circuito. Cuando necesitamos más control sobre la implementación de bajo nivel de nuestro programa, podemos usar compuertas de pulso. Las compuertas de pulso eliminan la restricción de ejecutar circuitos solamente con compuertas base y también te permiten anular la implementación predeterminada de cualquier compuerta base.

Las compuertas de pulso te permiten mapear una compuerta de circuito lógico (por ejemplo, X) a un programa de Qiskit Pulse, llamado Schedule. Este mapeo se conoce como calibración. Una calibración de alta fidelidad es aquella que implementa fielmente la operación lógica desde la que está mapeada (por ejemplo, si la calibración de la compuerta X impulsa \(|0\rangle\) a \(|1\rangle\), etc.).

Un planificador (schedule) especifica la dinámica de tiempo exacta de las señales de entrada a través de todos los canales de entrada al dispositivo. Por lo general, hay varios canales por qubit, como dirección (drive) y medición (measure). Esta interfaz es más poderosa y requiere una comprensión más profunda de la física subyacente del dispositivo.

Es importante señalar que los programas de Pulso operan sobre qubits físicos. Un pulso tipo “drive” en el qubit \(a\) no ejecutará la misma operación lógica en el estado del qubit \(b\); en otras palabras, las calibraciones de las compuertas no son intercambiables entre qubits. Esto contrasta con el nivel del circuito, donde una compuerta X se define independientemente del qubit que sea su operando.

Esta página te muestra cómo agregar una calibración a tu circuito.

Note: Not all providers support pulse gates.

Construye tu circuito

Empecemos con un ejemplo muy simple, un circuito de estado 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]:
../../_images/tutorials_circuits_advanced_05_pulse_gates_2_0.png

Construye tus calibraciones

Ahora que tenemos nuestro circuito, definamos una calibración para la compuerta Hadamard en el qubit 0.

En la práctica, la forma del pulso y sus parámetros se optimizarían a través de una serie de experimentos Rabi (consulta el Libro de Texto de Qiskit para profundizar). Para esta demostración, nuestra compuerta Hadamard será un pulso Gaussiano. Reproduciremos nuestro pulso en el canal de dirección (drive) del qubit 0.

No te preocupes demasiado por los detalles de la construcción de la calibración en sí; puedes aprender todo sobre esto en la siguiente página: construyendo planificadores de pulso.

[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))

Dibujemos el nuevo planificador para ver lo que hemos construido.

[3]:
h_q0.draw()
[3]:
../../_images/tutorials_circuits_advanced_05_pulse_gates_6_0.png

Vincula tu calibración a tu circuito

Todo lo que queda es completar el registro. El método de circuito add_calibration necesita información sobre la compuerta y una referencia al planificador para completar el mapeo:

QuantumCircuit.add_calibration(gate, qubits, schedule, parameters)

La gate puede ser un objeto circuit.Gate o el nombre de la compuerta. Generalmente, necesitarás un planificador diferente para cada conjunto único de qubits y parameters. Puesto que la compuerta de Hadamard no tiene parámetros, no tenemos que suministrar ninguno.

[4]:
circ.add_calibration('h', [0], h_q0)

Por último, ten en cuenta que el transpilador respetará tus calibraciones. Utilízalo como lo harías normalmente (nuestro ejemplo es demasiado simple para que el transpilador lo optimice, por lo que la salida es la misma).

[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

Ten en cuenta que h no es una compuerta base para el backend emulado FakeHanoi. Ya que le hemos agregado una calibración, el transpilador tratará a nuestra compuerta como una compuerta base; pero solo en los qubits para los que se definió. Una Hadamard aplicada a un qubit diferente se desplegaría en las compuertas base.

¡Eso es todo!

Compuertas personalizadas

Mostraremos brevemente el mismo proceso para compuertas no estándar y completamente personalizadas. Esta demostración incluye una compuerta con parámetros.

[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)

Si usamos la variable de instancia custom_gate de Gate para agregar la calibración, los parámetros se derivan de esa instancia. Recuerda que el orden de los parámetros es significativo.

[8]:
circ = transpile(circ, backend)
circ.draw('mpl', idle_wires=False)
[8]:
../../_images/tutorials_circuits_advanced_05_pulse_gates_15_0.png

Normalmente, si intentáramos transpilar nuestro circ, obtendríamos un error. No se proporcionó una definición funcional para "my_custom_gate", por lo que el transpilador no puede desenrollarlo en el conjunto de compuertas base del dispositivo objetivo. Podemos mostrar esto intentando agregar "my_custom_gate" a otro qubit que no haya sido calibrado.

[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.