Appendix B: Answers¶
3. Analog Input Calibration¶
- Consider an uncalibrate time of flight (24 ns) and remove the wait() command, How would the recorded raw ADC trace would look like?
- The recording window will show the tail end of the previous pulse. In the displayed figure, the oscillating signal appears to fill the entire time axis, even though the time of flight hasn't been calibrated.
- What is the problem if the recorded raw ADC amplitude is below 1 milivolt?
- Refer to the hardware specifications, and you'll see that the ADCs offer a 12-bit resolution for a range of +/- 0.5 Volts. This means the smallest detectable change (digitization granularity) is approximately 0.25 mV. If your input signal is near or below 1 mV, it could introduce noise and inaccuracies to the signal you capture. Therefore, it's recommended to amplify the signal!
- If you set the analog input offset to 0.25 V, and send a signal of 0.4 V amplitude from the analog outputs to the inputs, how would the raw ADC trace look like?
- Analog input offsets are applied after the signal has been digitized. This leads to two key points:
- Tweaking the analog input offset won't recover the dynamic range at the input if there's an undesired DC offset.
- If you record a 0.4 V signal and then introduce a DC offset, the signal will be capped at 0.5 V. You can test this out!
- Analog input offsets are applied after the signal has been digitized. This leads to two key points:
- Calculate the data size in megabytes transferred to your computer when you execute measure() and the length of the pulse is 5 microseconds and take 1000 shots, as mentioned on line 26 of raw_adc_traces.py.
- In the QM platform, each data point is represented by 32 bits. If you record an ADC trace for 5 microseconds, it will be 5x32 bits in size. Taking 1,000 shots will still result in an average signal size of 5x32 bits. However, collecting all 1,000 of these traces will result in a total size of 5x32x1,000 bits. Consequently, when transferring data from the OPX to your computer, you might be sending a total of approximately 0.0191 megabytes.
4. Spectroscopy¶
-
Without using update_frequency(), create a spectroscopy sweep for the following frequencies [2, 3, 6, 8, 12] MHz. Verify that you succesfully created the five different pulses either using simulated_samples or an oscilloscope.
-
To conduct spectroscopy without the
update_frequency()function in QUA:- Create five distinct operations named
readout_2MHzthroughreadout_12MHz. - Ensure the
intermediate_frequencyof theresonatorelement is set to zero. - For each of the aforementioned operations, associate dedicated pulses with specific
waveforms. These waveforms should define the frequencies point by point, such as 2, 3, 6, 8, and 12 MHz, rather than just being envelopes multiplied by the oscillator in the PPU. - It's important to note that the
waveformlist processes at 1 GSa/s.
- Create five distinct operations named
Using the OPX like an AWG is quite labor-intensive compared to using it as a dedicated quantum experiment processor.
-
-
Modify the real-time dual demodulation process to exclusively utilize demod.full() and still achieve identical result as I and Q.
- Note that
dual_demoddoescosxout1 + sinxout2 = I, so to usedemod.fullyou will need to write four statements,demod.full('cos', II, 'out1')demod.full('sin', IQ, 'out2')demod.full('minus_sin', QQ, 'out1')demod.full('cos', QI, 'out2')
You can either retrive them seprately into dedicated streams or perform the arithmetic in QUA and retrieve the data as in the form of dual demodulation,
IandQ. - Note that
-
Adjust the QUA program to generate the qubit and the resonator pulse to coincide in time as well as to have the same duration.
-
The compiler assigns separate threads to both
qubitandresonator, allowing them to operate concurrently. We ensured sequential execution usingalign(). To modify this:- First, remove the
align()function. - Then, adjust the durations of
saturationandreadoutinconfiguration.pyto ensure they are of equal length.
- First, remove the
-
-
Why is it beneficial to place the pause() function in the outer loop?
- Everytime the
pause()function is called we active instructions in your computer to make changes to instruments and also to callresume()which is an operation that transfer information via the LAN to resume the PPU's work. If we place it in the outer loop we minimize the time we communicate between the computer and the OPX, thus creating minimal communication overhead.
- Everytime the
-
How much additional time would the QUA program require if the pause() function were moved from the outer loop to the inner most loop?
- Assume that each
pause()andresume()cycle takes 1 second. Quantify the number of iterations and calculate the time it takes in the outer loop and in the inner-most loop.
- Assume that each
-
Considering that the qubit and resonator operate in separate threads having the possibility of generatingn paralellism, and needing align() to make them sequential. How come at each for-loop iteration the qubit pulse always happens after the resonator pulse.
- Well it turns out that
with qua.for_()has an implicitalign()not displayed and is under the QUA, we implemented it because at the beginning of QUA many users forgot toalign()the threads and would have pulses from different iterations being combined thus producing menaingless results.
- Well it turns out that
5. Power-Time Rabi¶
-
Reconfigure the Rabi sequence from lines 32 to 35, place the amplitude sweep as the outer loop, the duration as the middle, and the shots as the innermost loop; then, how should the SPU pipelines be set up to retrieve averaged 2D arrays?
- The stream processing would look like this
-
Modify the for-loop to:
with qua.for_(a, 0, a < a_max, a):(line 34); note that we disabled the update condition. To implement the iterations once again, which QUA code line would you add to the indented instructions? Implement it.- After line 34, insert the code
assign(a, a + da). You can obtain the delta value from line 20. Before entering the amplitude for-loop that follows line 33, reset the value ofawith the codeassign(a, 0.0).
- After line 34, insert the code
-
Generate a simplified program to test the following. Instead of using
assign(a, a + da), use the Python commanda += da, and then fetch the results usingsave(a, a_st)to your computer.- To fetch the results you need to create
a_st = qua.declare_stream(), and also add another line of code to the SPU,a_st.save_all("a_values"), and then fetch bya_values = job.result_handles.get("a_values").fetch_all()['value'].
- To fetch the results you need to create
-
Instead of using a QUA for-loop for generating
100k shotsin the outer averaging loop (line 30), use a Python loop ->for n in range(100_000).- Because of the Python for loop, you will exhaust the program memory if you write 100,000 lines of QUA code, since each line typically consumes 1 instruction unit of memory.
-
What occurs if you have
a=7.8and doassign(a, a+1)? Similarly, what happens witha=-7.8when you applyassign(a, a-1)?- Fixed QUA variables value between [-8, 8> and if you go beyond this boundaries you overflow.
-
What occurs if you have
n=2_147_473_648and doassign(n, n+10_000)? Similarly, what happens withn=-2_147_473_648when you doassign(n, n-10_000)?- Integer QUA variables range between [-2^31, 2^31-1> and if you go beyond this boundaries your overflow.
-
Consider using flat-top Gaussian pulse instead of a standard Gaussian pulse. In a time-Rabi sequence, if you wish to scan only the flat-top section while maintaining a constant rise and fall, how would you use
durationto achieve it?- You will need to create three operations
gaussian_rise,gaussian_flatop, andgaussian_falland place them in theelementsdictionary as part ofqubit. Then you need to do the following codeblock,
- You will need to create three operations
-
If the Gaussian pulse's amplitude is to
0.17 Vin the configuration dictionary, and during a power-Rabi you sweep theaparameter up to1.5, what is the highest voltage measured at the analog outputs?- It will be
0.17x1.5 = 0.255 V.
- It will be
-
What would occur if you set the Gaussian pulse amplitude to
0.4 V, and sweep theaparameter up to1.5?- The signal will clip at the DACs output at
0.5 V.
- The signal will clip at the DACs output at
-
Why do you need to multiply
amplitudes * x180_ampand4 * durationswhen plotting your results in line 109 of the QUA program?- It is because
amplitudesis only the scaling prefactor anddurationsused in the QUA program needs to be in clock cycles. To visualize the results in Volts and nanoseconds, you need the mentioned multiplications.
- It is because
6. Chevron-Ramsey¶
-
The function
frame_rotation_2pi(Cast.mul_fixed_by_int(Cast.to_fixed(f * 1e-9), 4 * delay),"qubit")has three inner operations:f * 1e-9,4 * delay, andCast.mul_fixed_by_int(). Perform each operation individually, and save the results into QUA variables and pass them to a data stream. Retrieve the results onto your computer and verify that the PPU executed contrasting them with Python calculations.-
Use the following code block,
-
-
Implement the frame_rotation_2pi() function using the amplitude matrix and employ real-time mathematical operations to calculate both cosine and sine.
- Use
play('x90'*amp(a_11, a_12, a_21, a_22), 'qubit'), andassign(a_11, Math.cos(angle)),assign(a_12, Math.sin(-angle)),assign(a_21, Math.sin(angle)), andassign(a_22, Math.cos(angle)).
- Use
-
How can you utilize real-time mathematics together with frame_rotation() to replicate the functionality of frame_rotation_2pi()?
- If a phase value might surpass the set precision limits, you should develop a method to handle numbers greater than these limits. This involves using
intand binary operations. Additionally, you'll need to implement themodulooperation since it isn't natively supported in QUA.
- If a phase value might surpass the set precision limits, you should develop a method to handle numbers greater than these limits. This involves using
-
How would include delay = 0 into the QUA program to create play('x90', 'qubit') - wait(0) - play('x90', 'qubit')? Do not use QUA if-statement.
- Generate an outside loop of the following form, and adjust the stream processing to take one extra sample,
with progam() as prog: with qua.for_(n, 0, n < n_avg, n + 1): with qua.for_(*from_array(f, freq_array)): play("x90", "qubit") play("x90", "qubit") qua.align("qubit", "resonator") measure( "readout", "resonator", None, qua.dual_demod.full("cos", "sin", I), qua.dual_demod.full("minus_sin", "cos", Q), ) qua.wait(thermalization_time // 4, "resonator") save(I, I_st) save(Q, Q_st) with qua.for_(*from_array(delay, taus)): ... with qua.stream_processing(): I_st.buffer(len(taus)+1).buffer(len(freq_array)).average().save("I") Q_st.buffer(len(taus)+1).buffer(len(freq_array)).average().save("Q") n_st.save("iteration") -
What would the result be if you were to remove reset_frame() in line 60 of the QUA program?
- The phase continuously accumulates, and when averaged over time in the SPU, any irregularities in the data's coherent oscillations might be masked or smoothed out.
7. Active Reset¶
-
Quantify the Real-Time Feedback latency for the two cases of using
if-statementsandconditional-play.- if-statement latency: 245 ns, and conditional play latency: 200 ns. You will need have a recording window that can capture the pulse that readout pulse and the conditional played pulse at the analog inputs. Thus, you can create a third element that has a longer readout length to capture a longer raw ADC trace.
-
Modify the original QUA code to implement Repeat Until Success for Active Reset.
- Use
with while_(),
with qua.program() as prog: with while_(I > ge_threshold): # repeat until success measure( "readout", "resonator", None, dual_demod.full("rotated_cos", "out1", "rotated_sin", "out2", I), dual_demod.full("rotated_minus_sin", "out1", "rotated_cos", "out2", Q), ) with if_(I > ge_threshold): play("x180", "qubit") measure( "readout", "resonator", None, dual_demod.full("rotated_cos", "out1", "rotated_sin", "out2", I), dual_demod.full("rotated_minus_sin", "out1", "rotated_cos", "out2", Q), ) - Use
-
Given the distribution of the two states provided below, formulate various Active Reset methods,
- To maximize the ground state preparation fidelity implement repeat-until-success and make the condition to exit
with while_()for theIvalue to be a few standar deviations deep into the ground state distribution. - To make a compromise between the preparation fidelity and run-time, define the exit condition in
with while_()to be the mean value of the ground state distribution, and conditionallyplay()in the threshold between the excited and ground state.
Start to think about how to implement Bayesian estimation to dynamically estimate the threshold for better preparation fidelity.
- To maximize the ground state preparation fidelity implement repeat-until-success and make the condition to exit
8 .Randomized Benchmarking¶
-
For a depth of 3, and the random number in each iteration to be 7.
- depth = 1, circuit =
-x90-y90, inv_gate =y90x90 - depth = 2, circuit =
-x90-y90-x90-y90, inv_gate =-x90-y90 - depth = 3, circuit =
-x90-y90-x90-y90-x90-y90, inv_gate =I
- depth = 1, circuit =
-
For a depth of 13, and the random number list for the sequential iterations to be [3, 17, 22, 8, 0, 14, 19, 6, 21, 11, 15, 5, 20]
- depth = 1, circuit =
3, inv_gate =3(switch/case values) - depth = 2, circuit =
3-16, inv_gate =17 - depth = 3, circuit =
3-16-1, inv_gate =1 - depth = 4, circuit =
3-16-1-11, inv_gate =4 - depth = 5, circuit =
3-16-1-11-11, inv_gate =4 - depth = 6, circuit =
3-16-1-11-11-16, inv_gate =17 - depth = 7, circuit =
3-16-1-11-11-16-9, inv_gate =5 - depth = 8, circuit =
3-16-1-11-11-16-9-1, inv_gate =1 - depth = 9, circuit =
3-16-1-11-11-16-9-1-20, inv_gate =20 - depth = 10, circuit =
3-16-1-11-11-16-9-1-20-23, inv_gate =23 - depth = 11, circuit =
3-16-1-11-11-16-9-1-20-23-9, inv_gate =5 - depth = 12, circuit =
3-16-1-11-11-16-9-1-20-23-9-0, inv_gate =0 - depth = 13, circuit =
3-16-1-11-11-16-9-1-20-23-9-0-20, inv_gate =20
- depth = 1, circuit =
-
Given that we declared the
switch/caseto beunsafe=True, What would occur if you removewith case_(5)statement in theplay_sequence()macro?- Read more about the unsafe
switch/casein the documentation.
- Read more about the unsafe