Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update configurations to perform serialization/deserialization scalings before initializing class #4728

Merged
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 50 additions & 3 deletions qiskit/providers/models/backendconfiguration.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ def from_dict(cls, data):
data (dict): A dictionary representing the GateConfig to create.
It will be in the same format as output by
:func:`to_dict`.

Returns:
GateConfig: The GateConfig from the input dictionary.
"""
Expand Down Expand Up @@ -352,7 +351,30 @@ def to_dict(self):
'tags']:
if hasattr(self, kwarg):
out_dict[kwarg] = getattr(self, kwarg)

out_dict.update(self._data)

if 'dt' in out_dict:
out_dict['dt'] *= 1e-9
if 'dtm' in out_dict:
out_dict['dtm'] *= 1e-9

if 'qubit_lo_range' in out_dict:
out_dict['qubit_lo_range'] = [
[min_range * 1e9, max_range * 1e9] for
(min_range, max_range) in out_dict['qubit_lo_range']
]

if 'meas_lo_range' in out_dict:
out_dict['meas_lo_range'] = [
[min_range * 1e9, max_range * 1e9] for
(min_range, max_range) in out_dict['meas_lo_range']
]

# convert rep_times from μs to sec
if 'rep_times' in out_dict:
out_dict['rep_times'] = [_rt * 1e-6 for _rt in out_dict['rep_times']]

return out_dict

@property
Expand Down Expand Up @@ -541,8 +563,7 @@ def from_dict(cls, data):

Args:
data (dict): A dictionary representing the GateConfig to create.
It will be in the same format as output by
:func:`to_dict`.
It will be in the same format as output by :func:`to_dict`.

Returns:
GateConfig: The GateConfig from the input dictionary.
Expand Down Expand Up @@ -599,6 +620,31 @@ def to_dict(self):
out_dict.pop('_qubit_channel_map')
out_dict.pop('_channel_qubit_map')
out_dict.pop('_control_channels')

if self.qubit_lo_range:
out_dict['qubit_lo_range'] = [
[min_range * 1e-9, max_range * 1e-9] for
(min_range, max_range) in self.qubit_lo_range]

if self.meas_lo_range:
out_dict['meas_lo_range'] = [
[min_range * 1e-9, max_range * 1e-9] for
(min_range, max_range) in self.meas_lo_range]

if self.rep_times:
out_dict['rep_times'] = [_rt * 1e6 for _rt in self.rep_times]
Comment on lines +624 to +635
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this interact with the equivalent lines in QasmBackendConfiguration? I assume we just end up running this conversion twice and overwriting what's in out_dict with this from super().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are fields are only for pulse backends. They aren't in the QasmBackendConfiguration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore my previous comment. Apparently they are in the QASM backend. However, they should interact as you said so it shouldn't be an issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the follow on question here then is whether we need this duplicated, but it doesn't hurt anything and we can always clean it up in a follow up PR later.


if self.rep_delays:
out_dict['rep_delays'] = [_rd * 1e6 for _rd in self.rep_delays]

out_dict['dt'] = out_dict['dt'] * 1e9 # pylint: disable=invalid-name
out_dict['dtm'] = out_dict['dtm'] * 1e9

if hasattr(self, 'channel_bandwidth'):
out_dict['channel_bandwidth'] = [
[min_range * 1e-9, max_range * 1e-9] for
(min_range, max_range) in self.channel_bandwidth]

return out_dict

def __eq__(self, other):
Expand All @@ -618,6 +664,7 @@ def drive(self, qubit: int) -> DriveChannel:

Raises:
BackendConfigurationError: If the qubit is not a part of the system.

Returns:
Qubit drive channel.
"""
Expand Down
6 changes: 3 additions & 3 deletions qiskit/providers/models/pulsedefaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ def __init__(self,
**kwargs: Dict[str, Any]):
"""
Validate and reformat transport layer inputs to initialize.

Args:
qubit_freq_est: Estimated qubit frequencies in GHz.
meas_freq_est: Estimated measurement cavity frequencies in GHz.
Expand Down Expand Up @@ -223,7 +222,6 @@ def __getattr__(self, name):

def to_dict(self):
"""Return a dictionary format representation of the PulseDefaults.

Returns:
dict: The dictionary form of the PulseDefaults.
"""
Expand All @@ -245,6 +243,9 @@ def to_dict(self):
'instruction_schedule_map']:
out_dict[key] = value
out_dict.update(self._data)

out_dict['qubit_freq_est'] = [freq * 1e-9 for freq in self.qubit_freq_est]
out_dict['meas_freq_est'] = [freq * 1e-9 for freq in self.meas_freq_est]
return out_dict

@classmethod
Expand All @@ -255,7 +256,6 @@ def from_dict(cls, data):
data (dict): A dictionary representing the PulseDefaults
to create. It will be in the same format as output by
:meth:`to_dict`.

Returns:
PulseDefaults: The PulseDefaults from the input dictionary.
"""
Expand Down
21 changes: 21 additions & 0 deletions qiskit/qobj/pulse_qobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import copy
import json
import pprint
from typing import Union, List

import numpy

Expand Down Expand Up @@ -220,6 +221,9 @@ def from_dict(cls, data):
discriminators_obj = [
QobjMeasurementOption.from_dict(x) for x in discriminators]
data['discriminators'] = discriminators_obj
if 'parameters' in data and 'amp' in data['parameters']:
data['parameters']['amp'] = _to_complex(data['parameters']['amp'])

return cls(name, t0, **data)

def __eq__(self, other):
Expand All @@ -229,6 +233,23 @@ def __eq__(self, other):
return False


def _to_complex(value: Union[List[float], complex]) -> complex:
"""Convert the input value to type ``complex``.
Args:
value: Value to be converted.
Returns:
Input value in ``complex``.
Raises:
TypeError: If the input value is not in the expected format.
"""
if isinstance(value, list) and len(value) == 2:
return complex(value[0], value[1])
elif isinstance(value, complex):
return value

raise TypeError("{} is not in a valid complex number format.".format(value))


class PulseQobjConfig(QobjDictField):
"""A configuration for a Pulse Qobj."""

Expand Down
2 changes: 1 addition & 1 deletion qiskit/test/mock/backends/almaden/conf_almaden.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion qiskit/test/mock/backends/almaden/defs_almaden.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion qiskit/test/mock/backends/almaden/props_almaden.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion qiskit/test/mock/backends/armonk/conf_armonk.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"n_uchannels": 0, "u_channel_lo": [], "meas_levels": [1, 2], "qubit_lo_range": [[4.474467513126881, 5.474467513126881]], "meas_lo_range": [[6.493427855, 7.493427855]], "meas_kernels": ["boxcar"], "discriminators": ["linear_discriminator", "quadratic_discriminator"], "hamiltonian": {"description": "Qubits are modelled as a two level system. Qubits are coupled through resonator buses. The provided Hamiltonian has been projected into the zero excitation subspace of the resonator buses leading to an effective qubit-qubit flip-flop interaction. The qubit resonance frequencies in the Hamiltonian are the cavity dressed frequencies and not exactly what is returned by the backend defaults, which also includes the dressing due to the qubit-qubit interactions.\nWarning: Currently not all system Hamiltonian information is available to the public, missing values have been replaced with 0.\n", "h_latex": "\\begin{align} \\mathcal{H}/\\hbar = & \\sum_{i=0}^{0}\\left(\\frac{\\omega_{q,i}}{2} (\\mathbb{1}_i-\\sigma_i^{z})+ \\Omega_{d,i}D_i(t)\\sigma_i^{X}\\right) \\\\ \\end{align}", "h_str": ["_SUM[i,0,0,wq{i}/2*(I{i}-Z{i})]", "_SUM[i,0,0,omegad{i}*X{i}||D{i}]"], "osc": {}, "qub": {"0": 2}, "vars": {"omegad0": 0, "wq0": 31.255501189521}}, "rep_times": [1000.0000000000001], "dt": 0.2222222222222222, "dtm": 0.2222222222222222, "channels": {"acquire0": {"operates": {"qubits": [0]}, "purpose": "acquire", "type": "acquire"}, "d0": {"operates": {"qubits": [0]}, "purpose": "drive", "type": "drive"}, "m0": {"operates": {"qubits": [0]}, "purpose": "measure", "type": "measure"}}, "acquisition_latency": [], "conditional_latency": [], "meas_map": [[0]], "backend_name": "ibmq_armonk", "backend_version": "1.1.0", "n_qubits": 1, "basis_gates": ["id", "u1", "u2", "u3"], "gates": [{"name": "id", "parameters": [], "qasm_def": "gate id q { U(0,0,0) q; }", "coupling_map": [[0]]}, {"name": "u1", "parameters": ["lambda"], "qasm_def": "gate u1(lambda) q { U(0,0,lambda) q; }", "coupling_map": [[0]]}, {"name": "u2", "parameters": ["phi", "lambda"], "qasm_def": "gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; }", "coupling_map": [[0]]}, {"name": "u3", "parameters": ["theta", "phi", "lambda"], "qasm_def": "gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; }", "coupling_map": [[0]]}], "local": false, "simulator": false, "conditional": false, "open_pulse": true, "memory": true, "max_shots": 8192, "coupling_map": null, "max_experiments": 75, "sample_name": "SPARROW", "n_registers": 1, "credits_required": true, "online_date": "2019-10-16T04:00:00+00:00", "description": "1 qubit device", "allow_q_object": true, "parametric_pulses": [], "quantum_volume": null, "qubit_channel_mapping": [["m0", "d0"]], "uchannels_enabled": true, "url": "None", "allow_object_storage": true}
{"n_uchannels": 0, "u_channel_lo": [], "meas_levels": [1, 2], "qubit_lo_range": [[4474445584.380117, 5474445584.380117]], "meas_lo_range": [[6493427855.0, 7493427855.0]], "meas_kernels": ["boxcar"], "discriminators": ["quadratic_discriminator", "linear_discriminator"], "hamiltonian": {"description": "Qubits are modeled as Duffing oscillators. In this case, the system includes higher energy states, i.e. not just |0> and |1>. The Pauli operators are generalized via the following set of transformations:\n\n$(\\mathbb{I}-\\sigma_{i}^z)/2 \\rightarrow O_i \\equiv b^\\dagger_{i} b_{i}$,\n\n$\\sigma_{+} \\rightarrow b^\\dagger$,\n\n$\\sigma_{-} \\rightarrow b$,\n\n$\\sigma_{i}^X \\rightarrow b^\\dagger_{i} + b_{i}$.\n\nQubits are coupled through resonator buses. The provided Hamiltonian has been projected into the zero excitation subspace of the resonator buses leading to an effective qubit-qubit flip-flop interaction. The qubit resonance frequencies in the Hamiltonian are the cavity dressed frequencies and not exactly what is returned by the backend defaults, which also includes the dressing due to the qubit-qubit interactions.\n\nQuantities are returned in angular frequencies, with units 2*pi*GHz.\n\nWARNING: Currently not all system Hamiltonian information is available to the public, missing values have been replaced with 0.\n", "h_latex": "\\begin{align} \\mathcal{H}/\\hbar = & \\sum_{i=0}^{0}\\left(\\frac{\\omega_{q,i}}{2}(\\mathbb{I}-\\sigma_i^{z})+\\frac{\\Delta_{i}}{2}(O_i^2-O_i)+\\Omega_{d,i}D_i(t)\\sigma_i^{X}\\right) \\\\ \\end{align}", "h_str": ["_SUM[i,0,0,wq{i}/2*(I{i}-Z{i})]", "_SUM[i,0,0,delta{i}/2*O{i}*O{i}]", "_SUM[i,0,0,-delta{i}/2*O{i}]", "_SUM[i,0,0,omegad{i}*X{i}||D{i}]"], "osc": {}, "qub": {"0": 3}, "vars": {"delta0": 0, "omegad0": 64964031.66196872, "wq0": 31.255363407141527}}, "dynamic_reprate_enabled": true, "rep_times": [0.001], "rep_delays": [1e-06], "dt": 2.2222222222222221e-10, "dtm": 2.2222222222222221e-10, "channels": {"acquire0": {"operates": {"qubits": [0]}, "purpose": "acquire", "type": "acquire"}, "d0": {"operates": {"qubits": [0]}, "purpose": "drive", "type": "drive"}, "m0": {"operates": {"qubits": [0]}, "purpose": "measure", "type": "measure"}}, "acquisition_latency": [], "conditional_latency": [], "meas_map": [[0]], "backend_name": "alt_armonk", "backend_version": "1.1.0", "n_qubits": 1, "basis_gates": ["id", "u1", "u2", "u3"], "gates": [{"name": "id", "parameters": [], "qasm_def": "gate id q { U(0,0,0) q; }", "coupling_map": [[0]]}, {"name": "u1", "parameters": ["lambda"], "qasm_def": "gate u1(lambda) q { U(0,0,lambda) q; }", "coupling_map": [[0]]}, {"name": "u2", "parameters": ["phi", "lambda"], "qasm_def": "gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; }", "coupling_map": [[0]]}, {"name": "u3", "parameters": ["theta", "phi", "lambda"], "qasm_def": "gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; }", "coupling_map": [[0]]}], "local": false, "simulator": false, "conditional": false, "open_pulse": true, "memory": true, "max_shots": 100000, "coupling_map": null, "max_experiments": 10000, "sample_name": "SPARROW", "n_registers": 1, "credits_required": true, "online_date": "2019-10-16T04:00:00+00:00", "description": "1 qubit device Armonk alternate", "allow_q_object": true, "parametric_pulses": [], "quantum_volume": null, "qubit_channel_mapping": [["d0", "m0"]], "uchannels_enabled": true, "url": "None", "allow_object_storage": true}
2 changes: 1 addition & 1 deletion qiskit/test/mock/backends/armonk/defs_armonk.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion qiskit/test/mock/backends/armonk/props_armonk.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"backend_name": "ibmq_armonk", "backend_version": "1.1.0", "last_update_date": "2020-06-10T21:20:30+00:00", "qubits": [[{"date": "2020-06-09T21:03:58+00:00", "name": "T1", "unit": "\u00b5s", "value": 194.51644400301424}, {"date": "2020-06-10T21:15:38+00:00", "name": "T2", "unit": "\u00b5s", "value": 147.75709460786982}, {"date": "2020-06-10T21:20:30+00:00", "name": "frequency", "unit": "GHz", "value": 4.974467513126882}, {"date": "2020-06-10T21:12:29+00:00", "name": "readout_error", "unit": "", "value": 0.039000000000000035}, {"date": "2020-06-10T21:12:29+00:00", "name": "prob_meas0_prep1", "unit": "", "value": 0.048}, {"date": "2020-06-10T21:12:29+00:00", "name": "prob_meas1_prep0", "unit": "", "value": 0.030000000000000027}]], "gates": [{"qubits": [0], "gate": "id", "parameters": [{"date": "2020-06-10T21:17:55+00:00", "name": "gate_error", "unit": "", "value": 0.0005308549630003499}, {"date": "2020-06-10T21:20:30+00:00", "name": "gate_length", "unit": "ns", "value": 142.22222222222223}]}, {"qubits": [0], "gate": "u1", "parameters": [{"date": "2020-06-10T21:17:55+00:00", "name": "gate_error", "unit": "", "value": 0}, {"date": "2020-06-10T21:20:30+00:00", "name": "gate_length", "unit": "ns", "value": 0}]}, {"qubits": [0], "gate": "u2", "parameters": [{"date": "2020-06-10T21:17:55+00:00", "name": "gate_error", "unit": "", "value": 0.0005308549630003499}, {"date": "2020-06-10T21:20:30+00:00", "name": "gate_length", "unit": "ns", "value": 142.22222222222223}]}, {"qubits": [0], "gate": "u3", "parameters": [{"date": "2020-06-10T21:17:55+00:00", "name": "gate_error", "unit": "", "value": 0.0010614281190088892}, {"date": "2020-06-10T21:20:30+00:00", "name": "gate_length", "unit": "ns", "value": 284.44444444444446}]}], "general": []}
{"backend_name": "alt_armonk", "backend_version": "1.1.0", "last_update_date": "2020-07-16T20:12:05+00:00", "qubits": [[{"date": "2020-07-16T12:03:50+00:00", "name": "T1", "unit": "\u00b5s", "value": 173.56037544043704}, {"date": "2020-07-16T20:09:14+00:00", "name": "T2", "unit": "\u00b5s", "value": 137.39745920906893}, {"date": "2020-07-16T20:12:05+00:00", "name": "frequency", "unit": "GHz", "value": 4.974445584380118}, {"date": "2020-07-16T20:07:43+00:00", "name": "readout_error", "unit": "", "value": 0.052000000000000046}, {"date": "2020-07-16T20:07:43+00:00", "name": "prob_meas0_prep1", "unit": "", "value": 0.056}, {"date": "2020-07-16T20:07:43+00:00", "name": "prob_meas1_prep0", "unit": "", "value": 0.04800000000000004}]], "gates": [{"qubits": [0], "gate": "id", "parameters": [{"date": "2020-07-16T20:10:30+00:00", "name": "gate_error", "unit": "", "value": 0.0005108302042606528}, {"date": "2020-07-16T20:12:05+00:00", "name": "gate_length", "unit": "ns", "value": 142.22222222222223}]}, {"qubits": [0], "gate": "u1", "parameters": [{"date": "2020-07-16T20:10:30+00:00", "name": "gate_error", "unit": "", "value": 0}, {"date": "2020-07-16T20:12:05+00:00", "name": "gate_length", "unit": "ns", "value": 0}]}, {"qubits": [0], "gate": "u2", "parameters": [{"date": "2020-07-16T20:10:30+00:00", "name": "gate_error", "unit": "", "value": 0.0005108302042606528}, {"date": "2020-07-16T20:12:05+00:00", "name": "gate_length", "unit": "ns", "value": 142.22222222222223}]}, {"qubits": [0], "gate": "u3", "parameters": [{"date": "2020-07-16T20:10:30+00:00", "name": "gate_error", "unit": "", "value": 0.0010213994610237531}, {"date": "2020-07-16T20:12:05+00:00", "name": "gate_length", "unit": "ns", "value": 284.44444444444446}]}], "general": []}
Loading