-
Notifications
You must be signed in to change notification settings - Fork 127
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
Calibrations Definition #26
Calibrations Definition #26
Conversation
* refactor CalibrationsDefinition to allow non-unique parameter names in different schedules.
* Fixed lint.
* Added pandas to requireements.
* Added tests.
* Fixed issue with date_time.
* Added argument control_index to deal with multiple control channels per qubit pair.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. It is nice to break it out from #20. The biggest questions I have right now are:
- Should we allow different schedules with the same name for different qubits? I made an inline comment about this question.
- Will working with
qiskit.circuit.Parameter
s like this work okay? It seems like it will be okay, but it also seems like there is some potential for user error because the links between parameters in different schedules is somewhat hidden (compared to the previous global parameter name method where a user would very explicitly use aamp_xp
in both places) and I could see someone accidentally using a newamp
variable inxm
instead of reusing the one used inxp
. I think that might just be something one gets used to though. - How does serializing and deserializing the calibrated parameters work? I think storing values indexed as
(schedule name, parameter name, qubits): value
and then usingadd_parameter_value
to load them back should work. Partly I wonder about this becauseCalibrations
stores the values internally keyed off ofParameter
instances which don't live outside of one Python process, butadd_parameter_value
looks up theParameter
instances so it should be fine.
"formatted following index1.index2..." | ||
) | ||
|
||
self._schedules[schedule.name] = schedule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we allow for different qubits to use different schedules for the same schedule name? It would be nice to retain the default behavior of not specifying qubits and having the schedule apply to all qubits that have not had specific schedules set for them, but sometimes you might want to vary the schedule for different qubits. This would require tweaking the way parameters are stored in the class right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good point. It sounds like users need to manage schedule name though there is almost no flexibility for the schedule name, i.e I guess the name is used to map the gate to schedule, or basis_gate name. Perhaps you need another dict that maps (Gate, qubits) to schedule.
self._schedules[schedule.name] = schedule | ||
|
||
for param in schedule.parameters: | ||
self._parameter_map[ParameterKey(schedule.name, param.name)] = param |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering about the case where the user adds a schedule name that was already added previously. I suppose it is the user's responsibility to reuse the same Parameter
as the previous schedule to avoid losing the history of values stored under the old Parameter
that now won't be pointed to by (schedule.name, param.name)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we can make this easier by adding a flag which makes the decision a conscious one? E.g. change the signature of the method to:
def add_schedules(self, schedules: Union[Schedule, List[Schedule]], override_existing: bool = False):
Then if the schedule name is already present and override_existing
is False
we raise an error. We could also check the hash of the parameters for existing schedule to avoid history loss. How does that sound?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on the work flow, it might be sufficient to forbid a schedule to be added twice. If it is easy to save to and reload from the database, the answer might be that one should create a new CalibrationsDefinition
instance and reload if one wants to redefine schedules. On the other hand, maybe it is something that a user would expect to be able to do, so it should be allowed.
I don't think it needs by default to be an error for a user to redefine a schedule. It is when a user replaces a Parameter
that I was concerned about. The storage of parameters is (schedule.name, parameter.name): Parameter
in _parameter_map
and Parameter: {qubits: [ParameterValue, ...]}
in _params
. So if (schedule.name, parameter.name)
is updated to point to a new Parameter
in _parameter_map
, that (schedule.name, parameter.name)
loses the history stored in the old Parameter
entry in _params
. I think this is how it worked when I made the comment above. Now with the way you wrote register_parameter
, a CalibrationError
will be raised for the second schedule if it reuses any of the parameter names of the first. register_parameter(p, s)
probably should not raise an exception if p == _parameter_map[(s.name, p.name)]
(re-adding a schedule with the same parameter instances).
What did you mean by "check the hash?" Do you mean that if (schedule.name, parameter.name)
is already in _parameter_map
that _params[_parameter_map[(schedule.name, parameter.name)]]
would be copied to _params[parameter]
if parameter != _parameter_map[(schedule.name, parameter.name)]
? That seems like a natural thing to do. It allows for messy situations though where (xp, amp)
and (yp, amp)
point to the same Parameter
in _params
but then calling add_schedules(xp)
a second time with a new amp
Parameter results in xp
and yp
pointing to separate entries in _params
.
I think this is somewhat of an edge case concern, but it is a question of how much flexibility to give the user vs keeping the implementation simple and giving the user less chance to get confused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of this is addressed in 72ce1c0. We still have the issue of tracking the history of the links between parameters and schedules when schedule are re-added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New implementation looks nice. Perhaps we need to reconsider what defines the scope of parameter.
"formatted following index1.index2..." | ||
) | ||
|
||
self._schedules[schedule.name] = schedule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good point. It sounds like users need to manage schedule name though there is almost no flexibility for the schedule name, i.e I guess the name is used to map the gate to schedule, or basis_gate name. Perhaps you need another dict that maps (Gate, qubits) to schedule.
Co-authored-by: Will Shanks <wshaos@posteo.net>
* Added unittest for channel names.
Co-authored-by: Will Shanks <wshaos@posteo.net>
Co-authored-by: Will Shanks <wshaos@posteo.net>
…xperiments into calibrations_definition
Co-authored-by: Will Shanks <wshaos@posteo.net>
… duplicate names.
* get_template can now handle default schedules.
Update to assign_params
Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
* Reworded error message.
* * Added initial draft of cal def. * * Added exception and PArameterValue. * refactor CalibrationsDefinition to allow non-unique parameter names in different schedules. * * Black and fstrings. * * Removed unnecessary hashing. * * Added init. * Fixed lint. * * Renamed CalibrationsDefinition to Calibrations. * Added pandas to requireements. * * Fixed issue with parameters in the Schedule. * Added tests. * * Removed pnadas. * * Cleaned up _get_Channel_index. * * Removed pandas import. * * Added description to get_circuit. * * Added type to backend in __init__. * * Added raise error to get_parameter_value. * Fixed issue with date_time. * * Added __init__ in tests for lint. * Added argument control_index to deal with multiple control channels per qubit pair. * * Removed erronous comment. * Update qiskit_experiments/calibration/calibrations.py Co-authored-by: Will Shanks <wshaos@posteo.net> * * implified CalibrationError. * Added unittest for channel names. * Update qiskit_experiments/calibration/calibrations.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/calibrations.py Co-authored-by: Will Shanks <wshaos@posteo.net> * * Simplified parameter assignment in the Calibrations. * * Removed pandas from the docstrings. * Update qiskit_experiments/calibration/calibrations.py Co-authored-by: Will Shanks <wshaos@posteo.net> * * Fixed the keys in parameters_table. * * Made parameter registration more transparent and added an error for duplicate names. * * Improved docstring. * * Added check to ensure that all parameter names in a schedule are unique. * Removed the erroneous check in register_parameter. * * Removed properties from Calibrations. * * Made self._params a defaultdict. * * Fixed order of raise in add_parameter_value. * * Removed the deepcopy of schedule. * * Added qubits to keys in self._schedules and self._parameter_map, and self._params. * * Added test where default schedule is overridden. * * Updated parameter management to - parameter_map as (schedule.name, parameter.name, qubits): Parameter - _params as (schedule.name, parameter.name, qubits): [ParameterValue, ...] * * Improved docstrings. * * Improved methodology to get the values of parameters. * * Fixed lint. * * Removed the backend object and added a config for the controls. * * Extended the functionality of the channel naming convention. * Start a cross-resonance pulse schedule test. * * Added methodology to deal with Call schedule and cross-resonance schedules. Note that frames are not supported here yet. * * Added first stab of the method to export the calibrations to a csv. * Calibrations.parameters now returns self._parameter_map_r. * * Added the class BackendCalibrations to manage configurations in the context of a backend. * Lint and Black. * * Renamed file and added BackendCalibrations to __init__ * * Added test for BackendCalibrations. * * Added a check when adding parameter values to ensure that the schedule exists. * * Fixed small issue with _get_frequencies. * * Made register_parameter private. * * Made add_parameter_value accept Union[int, float, complex, ParameterValue]. * * channel pattern is now a class variable. * * Made _get_circuit private. * * Added method calibration_parameter. * Improved docstrings. * * Added the hash to Calibrations.parameters * * Imprved the docstrings. * * black * * Black * * Lint * * Renamed qubit_ref_est -> qubit_lo_freq. * * _get_frequencies only returns valid frequencies. * * Fixed regex. * * Docstring fix. * * Added ScheduleKey. * * Fixed String trimming. * * Fixed channel checking length issue. * * Added the max function for efficiency. * * Added error message in get_parameter_keys. * * Simplified get_parameter_keys. * Added an extra test. * * Changed method schedules. * * Improved to_csv docstring. * * Added method to clean the mapping which is need when overwritting schedule. * * Added an instance to make parameter hashes nice and counting up from 0. * * Do not register parameters in a call but recursively register the subroutine of the call. * * Removed regex from docstring and improved it. * * Added code example in class docstring. * Removed unused variable. * * Raise error if a channel has more than one parameter. * * Amended class docstring. * * Added remove_schedule method. * Update qiskit_experiments/calibration/calibrations.py Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * * Added the cutoff_date to schedule. * * Made get_parameter_keys private. * * Added missing type hint. * * removed get circuit. * * Fixed inconsistency with in parameters_table. * * Switched to assigned_subroutine. * * Cahnged to BackendV1. * * Removed unused import. * * Fixed lint * Allowed duplicate parameters. * * Aligned docstring. * * Made schedules in test more concis. * * Improved the CR test. This passes but requires terra bug fix #6322. * * Improved docstrings. * pylint and Black. * * Renamed files. * * Lint * Update qiskit_experiments/calibration/backend_calibrations.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/backend_calibrations.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/backend_calibrations.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/backend_calibrations.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/calibrations_manager.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/calibrations_manager.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/calibrations_manager.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/calibrations_manager.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/calibrations_manager.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update qiskit_experiments/calibration/calibrations_manager.py Co-authored-by: Will Shanks <wshaos@posteo.net> * * Reverted name to Calibrations. * * Improved docstring. * * Added functions get_qubit_frequencies and get_meas_frequencies. * * Added ScheduleBlock. * * Removed candidate_default_keys. * * Improved the error message. * * Improved docstring. * * Added measurement schedule tests. * * Added double call test. * * Added recursive assign to handle multiple Calls of the same schedule on different channels. * * Added support for parametric durations: - This required handling Schedule and ScheduleBlock seprately in _assign. - Called instructions are now registered separately too. * * Added tests on the parameter filtering. * * Black. * * Added test to check that a template is preserved after getting a schedule. * * Moved docstring to module level. * * Removed if isinstance on Call in add_schedule. * * Moved the Schedule and ScheduleBlock test to add_schedule. * * Added reverse look-up to deal with pure control channel cases. * * Added a pure Schedule test. * * Fixed test_backend_calibrations. * * Refactored order of ParameterKey. * Allowed free_params to be a list of strings or tuples. * * Amended docstring for free_params in get_schedule. * * Improved consistency of argument ordering. * * Added a check on the number of free parameters and the assigned schedule. * Added corresponding unit test. * * Black * Update qiskit_experiments/calibration/__init__.py Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * Update qiskit_experiments/calibration/__init__.py Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * Update qiskit_experiments/calibration/__init__.py Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * Update qiskit_experiments/calibration/__init__.py Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * Update qiskit_experiments/calibration/__init__.py Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * * made docstring example consistent. * * Made error message clearer * * Added more robustnes to user qubit input: - Add _to_tuple - Default to all qubits if qubit tuple is empty instead of None. * * Amended docstring. * * Added a test for an acquire channel. * * Renamed _hash_map to _hash_to_counter_map. * * Removed Schedule from Calibrations. * * Added saving and loading to csv. * Added tests for saving and loading. * Made functions to ensure ParameterValue types are obeyed. * * Improved docstring in __init__ * Changed a test to cover the case when qubit in add_parameter_value is an int. * * Added warning in save. * * Added development warning to the __init__ * * Added check for unregistered subroutines and correspoinding test. * * Added method get_template and corresponding tests. * * Errors are now raised if a schedule is called. * * Simplified _assign. * * Refactored free_params methodology to assign_params. * Added main of terra to tox.ini * * Improved error message. * * Improved docstrings. * * Added utf-8 encoding. * * Added a missing utf-8 in loading. * * Improved docstrings. * * Added example of parameter assignment. * * refined the parameter management for coupled parameters. * * Removed break coupling. * * Corrected docstring. * Scope assign_params by qubits and calibration_parameter * * Added a test and changed test_assign_coupled_implicitly. * * Changed order of tests for readability. * no error for default and specific qubit assign_params * Clean up conditional * Multiple assign_params keys for one param okay if assinging same value * Clarify assign_params comment * Test assign parameter in call * Test assigning to same param name in two levels of subroutines * * Made use of self.calibration_parameter. * * Docstring update. * * Added check on parameter consistency across subroutines. * get_template can now handle default schedules. * * Renamed a Test. * * ParameterValueType refactor. * Test nested assignment to Parameter edge case * Remvoe unused import * Fix test names * * Black and lint. * * Added check for subroutine inconsistencies and corresponding tests. * * Removed the check on parameters in _assign as the schedule check covers that. * Update qiskit_experiments/calibration/calibrations.py Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * * Added an Enum type for the frequency elements. * Reworded error message. Co-authored-by: Will Shanks <wshaos@posteo.net> Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> Co-authored-by: Will Shanks <willshanks@us.ibm.com>
Summary
The
CalibrationsDefinition
class is intended to let users manage parameters and schedules.Details and comments
At the heart of the calibrations definition is a dict of template schedules and a dict of parameters with values. The template schedules are fully parametric schedules (i.e. pulse durations, pulse parameters, channel indices, etc... are all parameters). The dict of parameters stores the values of the each parameter for different qubits and schedules as the parameter evolves through the calibration.