0
$\begingroup$

Right now I'm trying to delve into qiskit pulses and its usage with quantum hardware. First of all I decided to run spectroscopy experiment with FakeManila backend:

import numpy as np
from qiskit.providers.fake_provider import FakeManila

backend = FakeManila()
# 1.1. retrieve the configuration for the backend
config = backend.configuration()

# 1.2. retrieve the default values for the backend
defaults = backend.defaults()

### 2. Qubit SPECTROSCOPY ###
QUBIT = 1

# unit conversion factors (All backend properties are in SI units)
GHz = 1.0e9  # Gigahertz
MHz = 1.0e6  # Megahertz
us = 1.0e-6  # Microseconds
ns = 1.0e-9  # Nanoseconds'

# experiment options
from collections import namedtuple

drive_sigma_sec = 0.015 * us  # width of the gaussian pulse
drive_duration_sec = drive_sigma_sec * 8  # truncating the gaussian to 8 sigma

Experiment_options = namedtuple("Experiment_options", "amp, sigma, width, duration")
experiment_options = Experiment_options(
    amp=0.05,  # The amplitude of the spectroscopy pulse
    duration=drive_duration_sec,  # The duration of the spectroscopy pulse in seconds
    sigma=drive_sigma_sec,  # The standard deviation of the spectroscopy pulse in seconds
    width=0,  # The width of the flat-top of the GaussianSquare pulse in samples
)

# Retrieve the estimated qubit frequency
center_frequency = defaults.qubit_freq_est[QUBIT]  # in Hz
print(f"Qubit {QUBIT} has an estimated frequency of {center_frequency/GHz} GHz")

# Create a range to sweep
frequency_span = 40 * MHz  # in Hz
frequency_step = 1 * MHz  # in Hz
frequency_min = center_frequency - frequency_span / 2
frequency_max = center_frequency + frequency_span / 2
frequency_list = np.arange(frequency_min, frequency_max, frequency_step)

# set timing options for experiment
from qiskit_experiments.framework import BackendTiming

timing = BackendTiming(backend)

duration = timing.round_pulse(
    time=experiment_options.duration
)  # the duration regarding to timing constraints
sigma = experiment_options.sigma / timing.dt
width = experiment_options.width / timing.dt  

### 2. Create a spectroscopy schedule  
from qiskit import pulse
from qiskit.circuit import Parameter  # This is Prameter class for variable parameters
from qiskit.circuit import Gate, QuantumCircuit

# 2.1 create variable parameter
# https://qiskit.org/documentation/stubs/qiskit.circuit.Parameter.html
freq_param = Parameter("frequency")

# 2.2 create a default pulse schedule
# https://qiskit.org/documentation/tutorials/circuits_advanced/06_building_pulse_schedules.html
with pulse.build(backend=backend, name="spectroscopy") as spec_sched:
    # 2.2.1 choose drive channel
    drive_chan = pulse.drive_channel(QUBIT)

    # 2.2.2 change frequency on selected channel
    pulse.shift_frequency(freq_param, drive_chan)

    # 2.2.3 Play pulse
    pulse.play(
        pulse=pulse.GaussianSquare(
            duration=duration,
            sigma=sigma,
            width=width,
            amp=experiment_options.amp,
        ),
        channel=drive_chan,
    )

    # 2.2.4 shift frequency back to original value
    pulse.shift_frequency(-freq_param, drive_chan)  

# 2.3 Create the Spectroscopy gate
spec_gate_name = "Spec_gate"
spec_gate = Gate(name=spec_gate_name, num_qubits=1, params=[freq_param])

# 2.4 Create a qusntum circuit for spectroscopy
qc_spec = QuantumCircuit(1)
qc_spec.append(spec_gate, (0,))  # apply the spectroscopy gate to qubit register 0

# Adds measurement to all non-idle qubits.
qc_spec.measure_active()  # Creates a new ClassicalRegister with a size equal to the number of non-idle qubits being measured

# 2.5 add circuit calibration
# https://docs.quantum-computing.ibm.com/build/pulse
qc_spec.add_calibration(
    spec_gate_name,
    qubits=[
        QUBIT,
    ],
    schedule=spec_sched,
    params=[freq_param],
)

# 2.6 apply parameters
freq_sweep_circs = [
    qc_spec.assign_parameters({freq_param: round(f, 3)}, inplace=False)
    for f in frequency_list
]  

### Get Results ###  
num_shots_per_frequency = 1024

job = backend.run(
    freq_sweep_circs, meas_level=1, meas_return="avg", shots=num_shots_per_frequency
)  

frequency_sweep_results = job.result()

last line returns AerError: 'unknown instruction: Spec_gate'
But I'm pretty sure that I defined this gate previously... So what am I missing out here?

$\endgroup$

2 Answers 2

1
$\begingroup$

can you share a full working example in which you get the error "Operation 'Spec_gate' on qubit(s) [0] not supported by the backend command definition. Did you remember to transpile your input circuit for the same backend?"? I was going to reply that you need to make sure the gate has a pulse defined (either in backend.target or attached to the gate itself), but it looks like you've done that.

$\endgroup$
9
  • $\begingroup$ Hi @DanPuzzuoli! Your answer is not answering the question but rather asks for more information on the problem. This kind of contributions are better in the "comment" section below the question. You need a reputation above 50 to comment, so I understand why you did not, but remember this for the next time please. $\endgroup$ Aug 30, 2023 at 7:27
  • $\begingroup$ @DanPuzzuoli, yes, sure, here is my script: gist.github.com/ikaryss/7d1cf31d6f25a067ca86bf589ab37163 $\endgroup$
    – Ikaryssik
    Aug 30, 2023 at 10:18
  • 1
    $\begingroup$ @Ikaryssik there appears to be some kind of labelling issue. Even though you add the calibration to the circuit and specify qubits=(0,), if you do qc_spec.calibrations, it appears that the calibration has been added for qubit 1. I'm not an expert in transpilation so I'm not sure what the relation is between the physical indexing and the circuit indexing and how the transpiler is supposed to deal with that. $\endgroup$ Aug 30, 2023 at 13:55
  • 1
    $\begingroup$ @Ikaryssik even though it's not necessarily what you want to do, I was able to get it to run with # Create quantum circuit for spectroscopy qc_spec = QuantumCircuit(2) qc_spec.append(spec_gate, (1,)) # apply the spectroscopy gate to qubit register 0 so that the physical and circuit indexing both point to qubit 1. You'll probably want to do something else, but at least this verifies the issue. $\endgroup$ Aug 30, 2023 at 13:57
  • 1
    $\begingroup$ @Ikaryssik Once running, this simulation however is very slow - I'd recommend either switching it to be done with JAX and/or limiting the model to the qubit(s) you want to simulate using the subsystem_list optional argument in DynamicsBackend.from_backend. There is guidance on how to use JAX in the tutorials/user guide, and the subsystem_list argument is documented in the API docs. $\endgroup$ Aug 30, 2023 at 13:58
0
$\begingroup$

The fake backends don't support pulse gates.

$\endgroup$
3
  • $\begingroup$ May be there are some other methods to run such experiments? Please, can you give me some hints about it? I want to go through all calibrations steps, but it is pretty painful to wait for around 6 hours for each step on real hardware :( $\endgroup$
    – Ikaryssik
    Aug 28, 2023 at 13:14
  • $\begingroup$ Try this: qiskit.org/ecosystem/dynamics/tutorials/index.html $\endgroup$ Aug 28, 2023 at 17:44
  • $\begingroup$ Thank you! I've read Simulating backends at the pulse-level with DynamicsBackend tutorial. As I understand, I can simply apply DynamicsBackend.from_backend(real_manila_backend) and get full representation of this specific real manila backend. But I am still getting the QiskitError: "Operation 'Spec_gate' on qubit(s) [0] not supported by the backend command definition. Did you remember to transpile your input circuit for the same backend?" While using the same code (except for changing the backend to dynamics one) $\endgroup$
    – Ikaryssik
    Aug 29, 2023 at 11:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.