-
Notifications
You must be signed in to change notification settings - Fork 11
Description
With #20 merged to main we can now declare return types in defcal statements. However there isn't a convenient way to return values from defcal statements (as far as I can tell, please correct me if I'm wrong). This capability is demonstrated in the capture instructions of the OpenPulse Grammar specification. I suggest implementing a new method of the opqy.Program class that adds a ReturnStatement ast node to the program
def returns(self, return_var:AstConvertible):
self._add_statement(ast.ReturnStatement(return_var.to_ast(self)))
return self
This method just wraps the current workaround I've found to return a value from a defcal statement which requires using the 'private' _add_statement function of opqy.Program, see e.g. the following example
from openpulse import ast
import oqpy
prog = oqpy.Program() # create a new oqpy program
m0 = oqpy.PortVar("m0")
cap0 = oqpy.PortVar("cap0")
stimulus_frame = oqpy.FrameVar(m0, 5e9, 0, name="stimulus_frame")
caputure_frame = oqpy.FrameVar(cap0, 5e9, 0, name="capture_frame")
dummy_wfm = oqpy.WaveformVar([-1.0, 0.5, 0.25, -0.75], "dummy_wfm")
capture_v2 = oqpy.declare_extern("capture_v2", [("output", ast.FrameType()), ("duration", oqpy.duration)], oqpy.bit)
qubit = oqpy.PhysicalQubits[0]
with oqpy.defcal(prog, qubit, "measure", return_type=oqpy.bit):
prog.play(stimulus_frame, dummy_wfm)
prog._add_statement(
ast.ReturnStatement(capture_v2(caputure_frame, 16000e-9).to_ast(prog))
) # Suggestion: replace with prog.returns(result)
prog.measure(qubit, oqpy.BitVar(name="measured_bit"))
print(prog.to_qasm(encal_declarations=True))
Which generates the following OpenQASM code
OPENQASM 3.0;
defcalgrammar "openpulse";
cal {
extern capture_v2(frame, duration) -> bit;
port m0;
port cap0;
frame stimulus_frame = newframe(m0, 5000000000.0, 0);
waveform dummy_wfm = {-1.0, 0.5, 0.25, -0.75};
frame capture_frame = newframe(cap0, 5000000000.0, 0);
}
bit measured_bit;
defcal measure $0 -> bit {
play(stimulus_frame, dummy_wfm);
return capture_v2(capture_frame, 16000.0ns);
}
measured_bit = measure $0;
I'm willing to take the lead on implementing this method and any tests that may be required.