Skip to content

Commit

Permalink
Fix bug where lo units were not being properly converted (#3597)
Browse files Browse the repository at this point in the history
* Fix backend config where lo ranges were not adjusted to Hz.

* Fix bug where assemble/execute accepted parameters in GHz rather than Hz.

* linting

* Documentation fixes for Hz.

* Add channel bandwidth.

* bug fix with kwarg pop.

* Missing None in kwargs pop.

* linting.

* Fix range in list comprehension for lo ranges in backend configuration.

* Update qiskit/compiler/assemble.py

Co-Authored-By: Lauren Capelluto <laurencapelluto@gmail.com>

* Update qiskit/compiler/assemble.py

Co-Authored-By: Lauren Capelluto <laurencapelluto@gmail.com>

* lo to LO in docstrings.

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
Co-authored-by: Lauren Capelluto <laurencapelluto@gmail.com>
  • Loading branch information
3 people authored and mergify[bot] committed Jan 6, 2020
1 parent 85d0d03 commit a187d83
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 41 deletions.
12 changes: 8 additions & 4 deletions qiskit/assembler/assemble_schedules.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ def assemble_schedules(schedules, qobj_id, qobj_header, run_config):
if meas_lo_freq is None:
raise QiskitError('meas_lo_freq must be supplied.')

qubit_lo_range = qobj_config.pop('qubit_lo_range', None)
meas_lo_range = qobj_config.pop('meas_lo_range', None)
meas_map = qobj_config.pop('meas_map', None)

# convert enums to serialized values
Expand All @@ -66,6 +64,8 @@ def assemble_schedules(schedules, qobj_id, qobj_header, run_config):

instruction_converter = instruction_converter(PulseQobjInstruction, **qobj_config)

qubit_lo_range = qobj_config.pop('qubit_lo_range', None)
meas_lo_range = qobj_config.pop('meas_lo_range', None)
lo_converter = LoConfigConverter(PulseQobjExperimentConfig,
qubit_lo_range=qubit_lo_range,
meas_lo_range=meas_lo_range,
Expand Down Expand Up @@ -132,6 +132,10 @@ def assemble_schedules(schedules, qobj_id, qobj_header, run_config):
qobj_config['pulse_library'] = [PulseLibraryItem(name=pulse.name, samples=pulse.samples)
for pulse in user_pulselib.values()]

# convert lo frequencies to GHz
qobj_config['qubit_lo_freq'] = [freq/1e9 for freq in qubit_lo_freq]
qobj_config['meas_lo_freq'] = [freq/1e9 for freq in meas_lo_freq]

# create qobj experiment field
experiments = []
schedule_los = qobj_config.pop('schedule_los', [])
Expand All @@ -141,10 +145,10 @@ def assemble_schedules(schedules, qobj_id, qobj_header, run_config):
# update global config
q_los = lo_converter.get_qubit_los(lo_dict)
if q_los:
qobj_config['qubit_lo_freq'] = q_los
qobj_config['qubit_lo_freq'] = [freq/1e9 for freq in q_los]
m_los = lo_converter.get_meas_los(lo_dict)
if m_los:
qobj_config['meas_lo_freq'] = m_los
qobj_config['meas_lo_freq'] = [freq/1e9 for freq in m_los]

if schedule_los:
# multiple frequency setups
Expand Down
22 changes: 11 additions & 11 deletions qiskit/compiler/assemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,24 @@ def assemble(experiments,
Random seed to control sampling, for when backend is a simulator
qubit_lo_freq (list):
List of default qubit LO frequencies. Will be overridden by
List of default qubit LO frequencies in Hz. Will be overridden by
`schedule_los` if set.
meas_lo_freq (list):
List of default meas LO frequencies. Will be overridden by
`schedule_los` if set.
List of default measurement LO frequencies in Hz. Will be overridden
by `schedule_los` if set.
qubit_lo_range (list):
List of drive LO ranges used to validate that the supplied qubit LOs
are valid.
List of drive LO ranges each of form `[range_min, range_max]` in Hz.
Used to validate the supplied qubit frequencies.
meas_lo_range (list):
List of meas LO ranges used to validate that the supplied measurement LOs
are valid.
List of measurement LO ranges each of form `[range_min, range_max]` in Hz.
Used to validate the supplied qubit frequencies.
schedule_los (None or list[Union[Dict[PulseChannel, float], LoConfig]] or \
Union[Dict[PulseChannel, float], LoConfig]):
Experiment LO configurations
Experiment LO configurations, frequencies are given in Hz.
meas_level (int or MeasLevel):
Set the appropriate level of the measurement output for pulse experiments.
Expand Down Expand Up @@ -254,14 +254,14 @@ def _parse_pulse_args(backend, qubit_lo_freq, meas_lo_freq, qubit_lo_range,
if isinstance(schedule_los, (LoConfig, dict)):
schedule_los = [schedule_los]

# Convert to LoConfig if lo configuration supplied as dictionary
# Convert to LoConfig if LO configuration supplied as dictionary
schedule_los = [lo_config if isinstance(lo_config, LoConfig) else LoConfig(lo_config)
for lo_config in schedule_los]

if not qubit_lo_freq and hasattr(backend_default, 'qubit_freq_est'):
qubit_lo_freq = [freq / 1e9 for freq in backend_default.qubit_freq_est]
qubit_lo_freq = backend_default.qubit_freq_est
if not meas_lo_freq and hasattr(backend_default, 'meas_freq_est'):
meas_lo_freq = [freq / 1e9 for freq in backend_default.meas_freq_est]
meas_lo_freq = backend_default.meas_freq_est

qubit_lo_range = qubit_lo_range or getattr(backend_config, 'qubit_lo_range', None)
meas_lo_range = meas_lo_range or getattr(backend_config, 'meas_lo_range', None)
Expand Down
4 changes: 2 additions & 2 deletions qiskit/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,10 @@ def execute(experiments, backend,
Random seed to control sampling, for when backend is a simulator
default_qubit_los (list):
List of default qubit LO frequencies
List of default qubit LO frequencies in Hz
default_meas_los (list):
List of default meas LO frequencies
List of default meas LO frequencies in Hz
schedule_los (None or list[Union[Dict[PulseChannel, float], LoConfig]] or \
Union[Dict[PulseChannel, float], LoConfig]):
Expand Down
22 changes: 13 additions & 9 deletions qiskit/providers/models/backendconfiguration.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,24 +325,28 @@ def __init__(self,
self.n_uchannels = n_uchannels
self.u_channel_lo = u_channel_lo
self.meas_levels = meas_levels
self.qubit_lo_range = qubit_lo_range
self.meas_lo_range = meas_lo_range
self.qubit_lo_range = [[min_range * 1e9, max_range * 1e9] for
(min_range, max_range) in qubit_lo_range]
self.meas_lo_range = [[min_range * 1e9, max_range * 1e9] for
(min_range, max_range) in meas_lo_range]
self.rep_times = rep_times
self.meas_kernels = meas_kernels
self.discriminators = discriminators
self.hamiltonian = hamiltonian
self._dt = dt*1e-9
self._dtm = dtm*1e-9

self._dt = dt * 1e-9
self._dtm = dtm * 1e-9

channel_bandwidth = kwargs.pop('channel_bandwidth', None)
if channel_bandwidth:
self.channel_bandwidth = [[min_range * 1e9, max_range * 1e9] for
(min_range, max_range) in channel_bandwidth]

super().__init__(backend_name=backend_name, backend_version=backend_version,
n_qubits=n_qubits, basis_gates=basis_gates, gates=gates,
local=local, simulator=simulator, conditional=conditional,
open_pulse=open_pulse, memory=memory, max_shots=max_shots,
n_uchannels=n_uchannels, u_channel_lo=u_channel_lo,
meas_levels=meas_levels, qubit_lo_range=qubit_lo_range,
meas_lo_range=meas_lo_range,
rep_times=rep_times, meas_kernels=meas_kernels,
discriminators=discriminators, **kwargs)
**kwargs)

@property
def dt(self) -> float: # pylint: disable=invalid-name
Expand Down
14 changes: 8 additions & 6 deletions qiskit/qobj/converters/lo_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ def __init__(self, qobj_model, qubit_lo_freq, meas_lo_freq,
Args:
qobj_model (PulseQobjExperimentConfig): qobj model for experiment config.
qubit_lo_freq (list): List of default qubit lo frequencies.
meas_lo_freq (list): List of default meas lo frequencies.
qubit_lo_range (list): List of qubit lo ranges.
meas_lo_range (list): List of measurement lo ranges.
qubit_lo_freq (list): List of default qubit lo frequencies in Hz.
meas_lo_freq (list): List of default meas lo frequencies in Hz.
qubit_lo_range (list): List of qubit lo ranges,
each of form `[range_min, range_max]` in Hz.
meas_lo_range (list): List of measurement lo ranges,
each of form `[range_min, range_max]` in Hz.
run_config (dict): experimental configuration.
"""
self.qobj_model = qobj_model
Expand Down Expand Up @@ -64,11 +66,11 @@ def __call__(self, user_lo_config):

q_los = self.get_qubit_los(user_lo_config)
if q_los:
lo_config['qubit_lo_freq'] = q_los
lo_config['qubit_lo_freq'] = [freq/1e9 for freq in q_los]

m_los = self.get_meas_los(user_lo_config)
if m_los:
lo_config['meas_lo_freq'] = m_los
lo_config['meas_lo_freq'] = [freq/1e9 for freq in m_los]

return self.qobj_model(**lo_config)

Expand Down
10 changes: 5 additions & 5 deletions test/python/compiler/test_assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,11 +328,11 @@ def setUp(self):
[self.backend_config.acquire(i) for i in range(self.backend_config.n_qubits)],
[MemorySlot(i) for i in range(self.backend_config.n_qubits)]))

self.user_lo_config_dict = {self.backend_config.drive(0): 4.91}
self.user_lo_config_dict = {self.backend_config.drive(0): 4.91e9}
self.user_lo_config = pulse.LoConfig(self.user_lo_config_dict)

self.default_qubit_lo_freq = [4.9, 5.0]
self.default_meas_lo_freq = [6.5, 6.6]
self.default_qubit_lo_freq = [4.9e9, 5.0e9]
self.default_meas_lo_freq = [6.5e9, 6.6e9]

self.config = {
'meas_level': 1,
Expand Down Expand Up @@ -582,8 +582,8 @@ def setUp(self):
self.backend = FakeOpenPulse2Q()
self.config = self.backend.configuration()
self.defaults = self.backend.defaults()
self.qubit_lo_freq = [freq / 1e9 for freq in self.defaults.qubit_freq_est]
self.meas_lo_freq = [freq / 1e9 for freq in self.defaults.meas_freq_est]
self.qubit_lo_freq = [freq for freq in self.defaults.qubit_freq_est]
self.meas_lo_freq = [freq for freq in self.defaults.meas_freq_est]
self.qubit_lo_range = self.config.qubit_lo_range
self.meas_lo_range = self.config.meas_lo_range
self.schedule_los = {pulse.DriveChannel(0): self.qubit_lo_freq[0],
Expand Down
8 changes: 4 additions & 4 deletions test/python/qobj/test_pulse_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,19 +233,19 @@ class TestLoConverter(QiskitTestCase):

def test_qubit_los(self):
"""Test qubit channel configuration."""
user_lo_config = LoConfig({DriveChannel(0): 1.3})
user_lo_config = LoConfig({DriveChannel(0): 1.3e9})
converter = LoConfigConverter(PulseQobjExperimentConfig,
[1.2], [3.4], [(0., 5.)], [(0., 5.)])
[1.2e9], [3.4e9], [(0., 5e9)], [(0., 5e9)])

valid_qobj = PulseQobjExperimentConfig(qubit_lo_freq=[1.3])

self.assertEqual(converter(user_lo_config), valid_qobj)

def test_meas_los(self):
"""Test measurement channel configuration."""
user_lo_config = LoConfig({MeasureChannel(0): 3.5})
user_lo_config = LoConfig({MeasureChannel(0): 3.5e9})
converter = LoConfigConverter(PulseQobjExperimentConfig,
[1.2], [3.4], [(0., 5.)], [(0., 5.)])
[1.2e9], [3.4e9], [(0., 5e9)], [(0., 5e9)])

valid_qobj = PulseQobjExperimentConfig(meas_lo_freq=[3.5])

Expand Down

0 comments on commit a187d83

Please sign in to comment.