spin lock sequence - #1540
Conversation
for more information, see https://pre-commit.ci
…cation. This is still however unable to run for long pulse durations in the spin lock pulse.
for more information, see https://pre-commit.ci
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1540 +/- ##
==========================================
- Coverage 94.36% 93.40% -0.97%
==========================================
Files 136 137 +1
Lines 10634 10809 +175
==========================================
+ Hits 10035 10096 +61
- Misses 599 713 +114
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Im kind of stuck trying to make the protocol run for long durations of the spin lock pulse. I see that the driver supports batching , would this be a good way to allow longer sequences. |
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
Just for the sake of future reference: batching is quite the opposite. It is a way to accelerate the execution of short sequences, but quite ineffective on long ones. For very long sequences, we just need to identify the limiting factor (instruction memory, waveform memory, acquisition memory) and check whether there is a specific implementation lifting the bottleneck. In this case, the sequence is in a sense small, since it is made by few operations. The reason it is failing is because of waveform memory limitations, which can only be lifted by not realizing the spin-locking pulse as a single arbitrary waveform. Which can be realized by either decomposing it in parts (e.g. repeating many back-to-back identical rectangular units) or with a compressed pulse implementation (which is possible for the flux pulse). |
Use LongPulse instead of rectangular pulses
lballerio
left a comment
There was a problem hiding this comment.
Overall I think is good, just small suggestions.
Btw @jevillegasd can you also paste on this PR some data plot you generated while running this experiment?
| duration_min: int | ||
| """Minimum spin-lock pulse duration [ns].""" | ||
| duration_max: int | ||
| """Maximum spin-lock pulse duration [ns].""" | ||
| duration_step: int | ||
| """Step spin-lock pulse duration [ns].""" |
There was a problem hiding this comment.
we decided to move into ranges as input, i.e. tuples of the form (init_value, final_value, step).
| duration_min: int | |
| """Minimum spin-lock pulse duration [ns].""" | |
| duration_max: int | |
| """Maximum spin-lock pulse duration [ns].""" | |
| duration_step: int | |
| """Step spin-lock pulse duration [ns].""" | |
| duration_range: tuple[float, float, float] | |
| """Spin-lock pulse duration range [ns].""" |
Also in theory we can admit times to be float for sub-ns sampling rate; then drivers will convert it accordingly.
| @property | ||
| def duration_range(self) -> tuple[int, int, int]: | ||
| """Return a tuple with the spin-lock pulse duration range.""" | ||
| return self.duration_min, self.duration_max, self.duration_step |
There was a problem hiding this comment.
noy necessary anymore since we are taking range as input.
| @property | |
| def duration_range(self) -> tuple[int, int, int]: | |
| """Return a tuple with the spin-lock pulse duration range.""" | |
| return self.duration_min, self.duration_max, self.duration_step |
| amplitude_min: float | ||
| """Minimum spin-lock pulse amplitude [a.u.].""" | ||
| amplitude_max: float | ||
| """Maximum spin-lock pulse amplitude [a.u.].""" | ||
| n_amplitudes: int | ||
| """Number of amplitude points, log-spaced between amplitude_min and amplitude_max.""" |
There was a problem hiding this comment.
Honestly here I don't know whether is better to ask for a tuple or not. However I will write amplitude_values as a @property of the SpinLockParameters class.
| gamma: dict[QubitId, list[float]] = field(default_factory=dict) | ||
| """Relaxation rate :math:`\\Gamma_{1\\rho} = S(\\nu_R)` for each amplitude [Hz].""" | ||
| gamma_error: dict[QubitId, list[float]] = field(default_factory=dict) | ||
| """Error on :math:`\\Gamma_{1\\rho}` [Hz].""" |
There was a problem hiding this comment.
Maybe better to save them together?
Something like:
| gamma: dict[QubitId, list[float]] = field(default_factory=dict) | |
| """Relaxation rate :math:`\\Gamma_{1\\rho} = S(\\nu_R)` for each amplitude [Hz].""" | |
| gamma_error: dict[QubitId, list[float]] = field(default_factory=dict) | |
| """Error on :math:`\\Gamma_{1\\rho}` [Hz].""" | |
| gamma: dict[QubitId, list[float, float]] = field(default_factory=dict) | |
| """Relaxation rate :math:`\\Gamma_{1\\rho} = S(\\nu_R)` and its error for each amplitude [Hz].""" |
| ) -> SpinLockData: | ||
| """Data acquisition for the spin-lock (T1rho) experiment.""" | ||
|
|
||
| duration_range = np.arange(*params.duration_range) |
There was a problem hiding this comment.
I would call in a different way since it is not a range and then might be confused with params.duration_range.
| qd_channel = platform.qubits[q].drive | ||
| ro_channel, ro_pulse = natives.MZ()[0] | ||
| rx_pulse = natives.RX()[0][1] |
There was a problem hiding this comment.
Is there a reason why not:
ro_channel, ro_pulse = natives.MZ()[0]
rx_pulse, qd_channel = natives.RX()[0][1]that I cannot see?
| nshots=params.nshots, | ||
| relaxation_time=params.relaxation_time, | ||
| acquisition_type=AcquisitionType.DISCRIMINATION, | ||
| averaging_mode=AveragingMode.SINGLESHOT, |
There was a problem hiding this comment.
Is there a reason why you set SINGLESHOT as acquisition mode and not CYCLIC?
| ) | ||
|
|
||
| for q in targets: | ||
| prob = probability(results[ro_pulses[q].id], state=1) |
There was a problem hiding this comment.
if you use CYCLIC:
| prob = probability(results[ro_pulses[q].id], state=1) | |
| prob = results[ro_pulses[q].id] |
| gamma = {} | ||
| gamma_error = {} |
There was a problem hiding this comment.
as before, maybe error and measurement can be incorporated
| return SpinLockResults(t1rho, gamma, gamma_error, rabi_frequency, fitted_parameters) | ||
|
|
||
|
|
||
| def _plot(data: SpinLockData, target: QubitId, fit: SpinLockResults = None): |
There was a problem hiding this comment.
| def _plot(data: SpinLockData, target: QubitId, fit: SpinLockResults = None): | |
| def _plot(data: SpinLockData, target: QubitId, fit: SpinLockResults | None = None): |
|
Btw also rebase (in this case is straightforward) and try to solve the failing tests |
This is a first trial to address #1525
The experiment runs, but I run out of memory surprisingly fast, even though I use sweepers for both amplitude and time iterators. Maybe this works better if I use of of the iterations to be a for loop outside (at the cost of the experiment being longer than necessary).