Quantum-circuit to quantum-device layer compilation backend
Explanation of changes
This merge request creates a new more general compilation backend for the quantum-circuit to quantum-device compilation.
- it replaces the
add_pulse_information_transmonthat has been marked as deprecated the old code is still functional for backwards compatibility (closes #64 (closed)). - it creates a new structure for the configuration files based on the pydantic datastructure introduced in !341 (merged) ( closing #67 (closed)).
- support for the new configuration files has been added to the QuantumDevice and TransmonElement. A future version will need to redesign the Transmon Element to make the structure of the parameters match the structure of the configuration files and result in a better UX.
This new configuration allows users to easily use custom (user-defined) pulses or gates, without needing to program a new compiler backend. This is a priority as this functionality is required for several projects.
This MR has tests and an example configuration and all data structures have appropriate docstrings.
Immediate further work would
-
modify the user-guide to explain how to use this (in combination with the QuantumDevice and TransmonElement) - expand the user-guide to explain how to use this with custom operations (and custom device objects) (separate MR/issue?).
- provide an example "edge" that can be added to the QuantumDevice (separate MR/issue).
Merge checklist
See also merge request guidelines
-
Merge request has been reviewed and approved by a project maintainer. -
Merge request contains a clear description of the proposed changes and the issue it addresses. -
Merge request made onto appropriate branch (develop for most MRs). -
New code is fully tested. -
New code is documented and docstrings use numpydoc format. -
CHANGELOG.rstandAUTHORS.rsthave been updated (when applicable). -
CI pipelines pass -
pre-commit run --all-files --hook-stage commitpasses (gitlab-ci), - test suite passes (gitlab-ci),
- no degradation in code-coverage (codacy),
- no (serious) new pylint code quality issues introduced (codacy),
- documentation builds successfully (CI and readthedocs),
-
windows tests pass (manually triggered by maintainers before merging).
-
THIS IS OLD TEXT
Although I have added tests and an example configuration, this MR cannot be merged yet.
Before this can be merged, the following needs to happen
-
a tutorial, explaining how a user can create a custom configuration and how to use this. -
make the existing transmon element generate a config in the new style to allow depreciation without breaking existing code. (still requires some bugfixes found in test). -
add pydanticbased validators (allow schema validation without breaking backwards compatibility). -
documentation for the configuration format, potentially including a python object to validate configurations (traitlets, pydantic, json-schema, not sure what's best yet). -
documentation on what a valid generator function is and how this helps with composite and/or parameterized operations.
An important consideration for keeping the new configs as simple dictionaries is that that is something I can easily explain to a user. More complex objects could also work, but I'm a bit hesitant to start making a custom data structure (although we might create such a thing from a dictionary representation).
Structure of config files
sched = Schedule("Test schedule")
# define the resources
# q0, q1 = Qubits(n=2) # assumes all to all connectivity
q0, q1 = ("q0", "q1")
sched.add(Reset(q0, q1))
sched.add(Rxy(90, 0, qubit=q0))
sched.add(Rxy(180, 0, qubit=q1), ref_pt='start')
sched.add(CZ(qC=q0, qT=q1))
sched.add(Rxy(theta=90, phi=0, qubit=q0))
sched.add(Measure(q0, q1), label="M0")
# pulse information is added
dev_sched = add_pulse_information_transmon(
deepcopy(sched), device_cfg=DEVICE_CONFIG_OLD
)
new_dev_sched = compile_circuit_to_device(sched, device_cfg=example_transmon_cfg)
new_dev_sched = determine_absolute_timing(schedule=new_dev_sched, time_unit="physical")
example_transmon_cfg = {
"backend": "quantify_scheduler.backends.circuit_to_device"
+ ".compile_circuit_to_device",
"clocks": {
"q0.01": 6020000000.0,
"q0.ro": 7040000000.0,
"q1.01": 5020000000.0,
"q1.ro": 6900000000.0,
},
"elements": {
"q0": {
"reset": {
"factory_func": "quantify_scheduler.operations.pulse_library.IdlePulse",
"factory_kwargs": {"duration": 0.0002},
},
"Rxy": {
"factory_func": "quantify_scheduler.operations."
+ "pulse_factories.rxy_drag_pulse",
"gate_info_factory_kwargs": ["theta", "phi"],
"factory_kwargs": {
"amp180": 0.32,
"motzoi": 0.45,
"port": "q0:mw",
"clock": "q0.01",
"duration": 2e-08,
},
},
"Z": {
"factory_func": "quantify_scheduler.operations."
+ "pulse_library.SoftSquarePulse",
"factory_kwargs": {
"amp": 0.23,
"duration": 4e-09,
"port": "q0:fl",
"clock": "cl0.baseband",
},
},
"measure": {
"factory_func": "quantify_scheduler.operations."
+ "measurement_factories.dispersive_measurement",
"gate_info_factory_kwargs": ["acq_index", "bin_mode"],
"factory_kwargs": {
"port": "q0:res",
"clock": "q0.ro",
"pulse_type": "SquarePulse",
"pulse_amp": 0.25,
"pulse_duration": 1.6e-07,
"acq_delay": 1.2e-07,
"acq_duration": 3e-07,
"acq_protocol": "SSBIntegrationComplex",
"acq_channel": 0,
},
},
},
"q1": {
"reset": {
"factory_func": "quantify_scheduler.operations.pulse_library.IdlePulse",
"factory_kwargs": {"duration": 0.0002},
},
"Rxy": {
"factory_func": "quantify_scheduler.operations."
+ "pulse_factories.rxy_drag_pulse",
"gate_info_factory_kwargs": ["theta", "phi"],
"factory_kwargs": {
"amp180": 0.4,
"motzoi": 0.25,
"port": "q1:mw",
"clock": "q1.01",
"duration": 2e-08,
},
},
"measure": {
"factory_func": "quantify_scheduler.operations."
+ "measurement_factories.dispersive_measurement",
"gate_info_factory_kwargs": ["acq_index", "bin_mode"],
"factory_kwargs": {
"port": "q1:res",
"clock": "q1.ro",
"pulse_type": "SquarePulse",
"pulse_amp": 0.21,
"pulse_duration": 1.6e-07,
"acq_delay": 1.2e-07,
"acq_duration": 3e-07,
"acq_protocol": "SSBIntegrationComplex",
"acq_channel": 1,
},
},
},
},
"edges": {
"q0-q1": {
"CZ": {
"factory_func": "quantify_scheduler.operations."
+ "pulse_library.SuddenNetZeroPulse",
"factory_kwargs": {
"port": "q0:fl",
"clock": "cl0.baseband",
"amp_A": 0.5,
"amp_B": 0.4,
"net_zero_A_scale": 0.95,
"t_pulse": 2e-08,
"t_phi": 2e-09,
"t_integral_correction": 1e-08,
},
}
}
},
}

