-
Notifications
You must be signed in to change notification settings - Fork 15
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
Remove platform start and stop #739
Conversation
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.
Actually, are you sure do we need to retain setup()
? To the best of my knowledge:
- only the LO are using it
- most of the others are calling it empty in the docstring (Qblox, Zurich & RFSoC)
- some are even calling it deprecated (QM & RFSoC)
if self.flux is not None and self.sweetspot != 0: | ||
self.flux.offset = self.sweetspot | ||
|
||
@property | ||
def flux(self): | ||
return self._flux | ||
|
||
@flux.setter | ||
def flux(self, channel): | ||
if self.sweetspot != 0: | ||
channel.offset = self.sweetspot |
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.
Can't you just set it in any case, even when self.sweetspot == 0
?
Would it be wrong for some reason?
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.
My main doubt on the PR is just leaving the setup()
.
The rest is pretty much good to go, but here there is a further doubt that is related to a change quite unrelated to start()
, stop()
, and setup()
in the first place.
@property | ||
def flux(self): | ||
return self._flux | ||
|
||
@flux.setter | ||
def flux(self, channel): | ||
if self.sweetspot != 0: | ||
channel.offset = self.sweetspot | ||
self._flux = channel |
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.
Do you believe this is actually required?
Here we are duplicating the information, in channel and qubit, and then we have to increase the code complexity to keep them in sync.
In general, it is good to have a single source of truth, and always read from there (currently, if the .sweetspot
is updated afterward, ._flux
get out of sync, unless properly corrected).
The problem is that the qubit depends on the channel, and not the opposite.
However, the qubit is the parameters' container, and the channel (and especially the port) is the one acting to send pulses.
So, eventually you need to play a pulse on a qubit, and this information goes down to the instruments (the .play()
or .sweep()
methods of the controllers, that we may eventually unify
qibolab/src/qibolab/instruments/qm/driver.py
Lines 111 to 112 in d881d1f
def play(self, qubits, couplers, sequence, options): | |
return self.sweep(qubits, couplers, sequence, options) |
However, the instrument has no access to the channels, that's why is provided through
Qubit
. But in principle, we could even invert, and play the pulse on a Channel
and a QubitId
(even a Port
is not unique, in case of multiplexing).
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'm not sure that inverting the dependency is simple and the most effective strategy (esp. in the short term).
But I just see the duplication, and that you're trying to cope for it with syncing. And I know this is hard to maintain, in general.
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 also don't fully like this. In terms of this PR I did it to keep the behavior the same after the removal of platform.setup()
.
In general channel.offset
can be different than qubit.sweetspot
, for example if channel
is not a flux channel or if we don't want to operate a qubit at its sweetspot. So it is not double source of truth, we are just assuming that we are operating all qubits at their sweetspots and we are setting the flux offset accordingly.
Other potential solutions I can think of are:
- Drop
offset
from channels and modify drivers to usequbit.sweetspot
as the offset of flux. This has many downsides asoffset
may be useful for non-flux channels and it will not be possible to operate qubits not at their sweetspot. - Drop
qubit.sweetspot
and just put the value on theoffset
directly as an instrument setting. Main downside of this is "political", people doing calibration may find it weird and the format of the runcards will change a bit so it should be communicated. Other than that that's not necessarily bad solution. - Keep both but the user has to set both manually. More flexible but will lead to repetition in the runcards, as the same value will be set twice in most cases. This is similar to the qubit frequency which is set as
qubit.drive_frequency
and also as the frequency of the native RX pulse.
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.
In general
channel.offset
can be different thanqubit.sweetspot
, for example ifchannel
is not a flux channel or if we don't want to operate a qubit at its sweetspot. So it is not double source of truth, we are just assuming that we are operating all qubits at their sweetspots and we are setting the flux offset accordingly.
Even @hay-k mentioned this to me, and he mentioned that also @aorgazf asked for this feature (that in practice consists in doing something less).
But I agree that for this PR might be better to keep the same behavior (just because the PR is about something else).
Solution 1. I don't like, because as you pointed out they could be two different objects, and because we don't want to repeat over and over some decision in all the drivers.
Every entity should be represented, and we should make proper use of them. If we want to change the offset, let's do it at higher level.
As you said yourself, solution 2. is better software-wise. But if we calibrate the sweetspot, it has to be recorded somewhere.
Solution 3. is close to what we have, and it's the one I'd keep. I'd simply drop the automated sync at this point.
We can have a mechanism (a method? a parameter in other method?) to do that (set the channel.offset
out of the qubit.sweetspot
) if it's a convenient shortcut for reading from the one side and setting to the other. Or otherwise do it manually. But the decision should always be explicit (unless we have an offset setting stage, and we just keep sweetspot as the default - but this stage should be easily accessible by the user).
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.
But I agree that for this PR might be better to keep the same behavior (just because the PR is about something else).
Indeed, I opened an issue (#741) from this discussion. Let's come back to it in the next (or next next) milestone.
Actually also the Qblox modules are using the |
And also in QM it is used as of #733, not in the The thing is that we need a way to deserialize the It does not appear in Zurich because it is still following the old approach of hard-coding instrument settings in the qibolab/tests/dummy_qrc/zurich.py Line 131 in cc8a1b4
and maybe RFSoC does not need any instrument settings (that could be calibrated). |
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #739 +/- ##
==========================================
+ Coverage 62.00% 62.68% +0.67%
==========================================
Files 48 47 -1
Lines 6095 5930 -165
==========================================
- Hits 3779 3717 -62
+ Misses 2316 2213 -103
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
These could be |
Then I will rename Settings are indeed uploaded during module_name:
port_ name:
setting_name: setting_value so Loading in |
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.
Ok, I only had concerns related to .setup()
and .flux
property, and they have been discussed.
We could keep discussing .setup()
, and decide whether or not we want to get rid of it, but I feel like it does not belong any longer to this PR (it became different in kind from .start()
and .stop()
).
It's good to go.
I was imagining (and them proposing)
The idea was just to pass the corresponding runcard section, and deserializing the |
Qblox and Zurich qpu tests are now passing on this branch. As soon as the CI passes, I will merge this. |
Fixes #673. In the end I kept
platform.connect()
andplatform.disconnect()
and the same for instruments.I also kept
instrument.setup
because it is used for loading the settings from the runcard (in serialize.py), however I removedplatform.setup()
as the loading of settings happens in the platform creation.Since we are breaking the interface anyway, I also removed some
set_*
/get_*
methods from the platform as they are not used much in qibocal anymore (with a very small exception) and the SPI driver as we have not used it for very long time and the driver may be outdated anyway (if we need it we can go back to the latest tag).Some small updates in qibocal and qibolab_platforms_qrc are needed after merging this PR!
Checklist: