diff --git a/grammars/Quil.g4 b/grammars/Quil.g4 index 7b5918f..b2ebd22 100644 --- a/grammars/Quil.g4 +++ b/grammars/Quil.g4 @@ -7,11 +7,19 @@ grammar Quil; quil : allInstr? ( NEWLINE+ allInstr )* NEWLINE* EOF ; allInstr : defGate + | defGateAsPauli | defCircuit + | defFrame + | defWaveform + | defCalibration + | defMeasCalibration | instr ; -instr : gate +instr : fence + | fenceAll + | delay + | gate | measure | defLabel | halt @@ -28,7 +36,16 @@ instr : gate | nop | include | pragma - | memoryDescriptor + | pulse + | setFrequency + | shiftFrequency + | setPhase + | shiftPhase + | swapPhase + | setScale + | capture + | rawCapture + | memoryDescriptor // this is a little unusual, but it's in steven's example ; // C. Static and Parametric Gates @@ -41,19 +58,24 @@ qubit : INT ; param : expression ; modifier : CONTROLLED - | DAGGER ; + | DAGGER + | FORKED ; // D. Gate Definitions -defGate : DEFGATE name ( ( LPAREN variable ( COMMA variable )* RPAREN ) | ( AS gateType ) )? COLON NEWLINE matrix ; +defGate : DEFGATE name (( LPAREN variable ( COMMA variable )* RPAREN ) | ( AS gatetype ))? COLON NEWLINE matrix ; +defGateAsPauli : DEFGATE name ( LPAREN variable ( COMMA variable )* RPAREN )? qubitVariable+ AS PAULISUM COLON NEWLINE pauliTerms ; variable : PERCENTAGE IDENTIFIER ; - -gateType : MATRIX | PERMUTATION ; +gatetype : MATRIX + | PERMUTATION ; matrix : ( matrixRow NEWLINE )* matrixRow ; matrixRow : TAB expression ( COMMA expression )* ; +pauliTerms : ( pauliTerm NEWLINE )* pauliTerm; +pauliTerm : TAB IDENTIFIER LPAREN expression RPAREN qubitVariable+ ; + // E. Circuits defCircuit : DEFCIRCUIT name ( LPAREN variable ( COMMA variable )* RPAREN )? qubitVariable* COLON NEWLINE circuit ; @@ -115,8 +137,8 @@ include : INCLUDE STRING ; // M. Pragma Support -pragma : PRAGMA IDENTIFIER pragma_name* STRING? ; -pragma_name : IDENTIFIER | INT ; +pragma : PRAGMA ( IDENTIFIER | keyword ) pragma_name* STRING? ; +pragma_name : IDENTIFIER | keyword | INT ; // Expressions (in order of precedence) @@ -141,10 +163,54 @@ number : MINUS? ( realN | imaginaryN | I | PI ) ; imaginaryN : realN I ; realN : FLOAT | INT ; +// Analog control + +waveformName : name (DIVIDE name)? ; + +defFrame : DEFFRAME frame ( COLON frameSpec+ )? ; +frameSpec : NEWLINE TAB frameAttr COLON ( expression | STRING ) ; +frameAttr : SAMPLERATE | INITIALFREQUENCY | DIRECTION | HARDWAREOBJECT | CENTERFREQUENCY; + +defWaveform : DEFWAVEFORM waveformName ( LPAREN param (COMMA param)* RPAREN )? COLON NEWLINE matrix ; +defCalibration : DEFCAL name (LPAREN param ( COMMA param )* RPAREN)? qubitOrFormal+ COLON ( NEWLINE TAB instr )+ ; +defMeasCalibration : DEFCAL MEASURE qubitOrFormal ( name )? COLON ( NEWLINE TAB instr )* ; + +pulse : NONBLOCKING? PULSE frame waveform ; +capture : NONBLOCKING? CAPTURE frame waveform addr ; +rawCapture : NONBLOCKING? RAWCAPTURE frame expression addr ; + +setFrequency : SETFREQUENCY frame expression ; +shiftFrequency : SHIFTFREQUENCY frame expression ; +setPhase : SETPHASE frame expression ; +shiftPhase : SHIFTPHASE frame expression ; +swapPhase : SWAPPHASE frame frame ; +setScale : SETSCALE frame expression ; + +delay : DELAY qubitOrFormal+ STRING* expression ; +fenceAll : FENCE ; +fence : FENCE qubitOrFormal+ ; + +qubitOrFormal : qubit | qubitVariable ; +namedParam : IDENTIFIER COLON expression ; +waveform : waveformName (LPAREN namedParam ( COMMA namedParam )* RPAREN)? ; +frame : qubitOrFormal+ STRING ; + +// built-in waveform types include: "flat", "gaussian", "draggaussian", "erfsquare" + + //////////////////// // LEXER //////////////////// +keyword : DEFGATE | DEFCIRCUIT | MEASURE | LABEL | HALT | JUMP | JUMPWHEN | JUMPUNLESS + | RESET | WAIT | NOP | INCLUDE | PRAGMA | DECLARE | SHARING | OFFSET | AS | MATRIX + | PERMUTATION | NEG | NOT | TRUE | FALSE | AND | IOR | XOR | OR | ADD | SUB | MUL + | DIV | MOVE | EXCHANGE | CONVERT | EQ | GT | GE | LT | LE | LOAD | STORE | PI | I + | SIN | COS | SQRT | EXP | CIS | CAPTURE | DEFCAL | DEFFRAME | DEFWAVEFORM + | DELAY | DIRECTION | FENCE | INITIALFREQUENCY | CENTERFREQUENCY | NONBLOCKING | PULSE | SAMPLERATE + | SETFREQUENCY | SETPHASE | SETSCALE | SHIFTPHASE | SWAPPHASE | RAWCAPTURE + | CONTROLLED | DAGGER | FORKED ; + // Keywords DEFGATE : 'DEFGATE' ; @@ -167,6 +233,11 @@ DECLARE : 'DECLARE' ; SHARING : 'SHARING' ; OFFSET : 'OFFSET' ; +AS : 'AS' ; +MATRIX : 'MATRIX' ; +PERMUTATION : 'PERMUTATION' ; +PAULISUM : 'PAULI-SUM'; + NEG : 'NEG' ; NOT : 'NOT' ; TRUE : 'TRUE' ; // Deprecated @@ -204,9 +275,6 @@ SQRT : 'SQRT' ; EXP : 'EXP' ; CIS : 'CIS' ; -MATRIX : 'MATRIX' ; -PERMUTATION : 'PERMUTATION' ; - // Operators PLUS : '+' ; @@ -215,10 +283,34 @@ TIMES : '*' ; DIVIDE : '/' ; POWER : '^' ; +// analog keywords + +CAPTURE : 'CAPTURE' ; +DEFCAL : 'DEFCAL' ; +DEFFRAME : 'DEFFRAME' ; +DEFWAVEFORM : 'DEFWAVEFORM' ; +DELAY : 'DELAY' ; +DIRECTION : 'DIRECTION' ; +FENCE : 'FENCE' ; +HARDWAREOBJECT : 'HARDWARE-OBJECT' ; +INITIALFREQUENCY : 'INITIAL-FREQUENCY' ; +CENTERFREQUENCY : 'CENTER-FREQUENCY' ; +NONBLOCKING : 'NONBLOCKING' ; +PULSE : 'PULSE' ; +SAMPLERATE : 'SAMPLE-RATE' ; +SETFREQUENCY : 'SET-FREQUENCY' ; +SHIFTFREQUENCY : 'SHIFT-FREQUENCY' ; +SETPHASE : 'SET-PHASE' ; +SETSCALE : 'SET-SCALE' ; +SHIFTPHASE : 'SHIFT-PHASE' ; +SWAPPHASE : 'SWAP-PHASE' ; +RAWCAPTURE : 'RAW-CAPTURE' ; + // Modifiers CONTROLLED : 'CONTROLLED' ; DAGGER : 'DAGGER' ; +FORKED : 'FORKED' ; // Identifiers @@ -231,7 +323,7 @@ FLOAT : [0-9]+ ( '.' [0-9]+ )? ( ( 'e'|'E' ) ( '+' | '-' )? [0-9]+ // String -STRING : '"' ~( '\n' | '\r' )* '"'; +STRING : '"' ~( '\n' | '\r' | '"' )* '"'; // Punctuation diff --git a/rfcs/analog/proposal.md b/rfcs/analog/proposal.md index 9ccf552..21ab8e9 100644 --- a/rfcs/analog/proposal.md +++ b/rfcs/analog/proposal.md @@ -1,63 +1,56 @@ -# Analog Control RFC +# Quilt Overview and Proposal ## Introduction -Quil enables users to specify high-level, gate-based, timing-agnostic quantum -programs. Only a subset of experiments can be specified this way (albeit a -large subset), others require lower level control. +Quil enables users to specify high-level, gate-based, timing-agnostic quantum programs. Only a subset of experiments can be specified this way (albeit a large subset), others require lower level control. In particular there is a desire to: + - be able to define custom waveforms - have full control over pulse timing and length -- be able to introduce more sophisticated translation for ideas eg. dynamic -decoupling, crosstalk correction, gate decompositions, etc. -- define new gates (e.g. Toffoli and Fredkin) by composing pulses on frames -and/or that exploit levels beyond the two level qubit approximation -- remove channels where discrepancies between internal and external performance -can be introduced +- be able to introduce more sophisticated translation for ideas eg. dynamic decoupling, crosstalk correction, gate decompositions, etc. +- define new gates (e.g. Toffoli and Fredkin) by composing pulses on frames and/or that exploit levels beyond the two level qubit approximation +- remove channels where discrepancies between internal and external performance can be introduced -This RFC proposes adding analog control to Quil which will be accessible -through Quil language bindings and used by compilers and simulators. +This RFC proposes adding analog control to Quil which will be accessible through Quil language bindings and used by compilers and simulators. ## Language Proposal -See the diff on Quil.md for the syntax of the introduction of a number of new -Quil instruction types: -- DEFCAL -- DEFFRAME, DEFWAVEFORM -- DELAY -- FENCE -- PULSE -- CAPTURE, RAW-CAPTURE -- SET-SCALE -- SET-FREQUENCY, SHIFT-FREQUENCY -- SET-PHASE, SHIFT-PHASE, SWAP-PHASES +Quilt extends Quil with the following new instructions -### Frames and Waveforms +- `DEFCAL` +- `DEFFRAME`, `DEFWAVEFORM` +- `DELAY` +- `FENCE` +- `PULSE` +- `CAPTURE`, `RAW-CAPTURE` +- `SET-SCALE` +- `SET-FREQUENCY`, `SHIFT-FREQUENCY` +- `SET-PHASE`, `SHIFT-PHASE`, `SWAP-PHASES` -Each qubit can have multiple frames, denoted by string names such as "xy", "cz", -or "ro". A frame is an abstraction that captures the instantaneous frequency and -phase that will be mixed into the control signal. The frame frequencies are with -respect to the absolute "lab frame". +### Frames and Waveforms Quilt has two notions of _waveforms_. Custom waveforms are defined using -DEFWAVEFORM as a list of complex numbers which represent the desired waveform +`DEFWAVEFORM` as a list of complex numbers which represent the desired waveform envelope, along with a sample rate. Each complex number represents one sample of -the waveform. The exact time to play a waveform can be determined by dividing by -the _sample rate_, which is in units of samples per second. +the waveform. The exact duration (in seconds) of a waveform can be determined by dividing +the length of the waveform by the _sample rate_ of the frame, which is in units of samples +per second. -**NOTE**: Quilt frames also have an associated sample rate, which may be -specified in the corresponding `DEFFRAME` block, and are ultimately -determined/enforced at link time by the underlying control hardware which the -frame is associated to. If a custom waveform is applied (via `PULSE` or -`CAPTURE`) to a frame for which it has an incompatible sample rate, the behavior -is undefined. +As an example, a custom waveform representing a "linear ramp" might be defined as + +``` +DEFWAVEFORM linear_ramp: + 0.001, 0.002, 0.003, 0.004, ... +``` There are also some built-in waveform generators which take as a parameter the duration of the waveform in seconds, alleviating the need to know the sample rate to calculate duration. These are valid for use regardless of the frame's underlying sample rate. +#### Frame State + In order to materialize the precise waveforms to be played the waveform envelopes must be modulated by the frame's frequency, in addition to applying some scaling and phasing factors. Although in theory it would be mostly possible @@ -72,12 +65,11 @@ additional instructions for phase). Here's a table explaining the differences between these three values that are tracked through the program: -| Name | Initial Value | Valid Values | Can be parameterized? | -|-----------|---------------|-----------------------|-----------------------| -| Frequency | (not set) | Real numbers | No | -| Phase | 0.0 | Real numbers | Yes | -| Scale | 1.0 | Real numbers | No | - +| Name | Initial Value | Valid Values | Can be parameterized? | +|-----------|-----------------------------------|-----------------------|-----------------------| +| Frequency | INITIAL-FREQUENCY in DEFFRAME | Real numbers | Yes | +| Phase | 0.0 | Real numbers | Yes | +| Scale | 1.0 | Real numbers | Yes | ### Pulses @@ -107,7 +99,7 @@ as an integration kernel. The inner product of the integration kernel and the list of measured IQ values is evaluated to produce a single complex result. This complex number needs to be stored in Quil classical memory. Quil does not -currently support complex numbers, so a real array of length 2 is used instead: +currently support complex typed memory regions, so a real array of length 2 is used instead: ``` # Simple capture of an IQ point DECLARE iq REAL[2] @@ -129,7 +121,7 @@ Roughly speaking: 4. Pulses on distinct frames which involve a common resource may not overlap in time unless one is marked as `NONBLOCKING`. -A more precise specification of the timing semantics is provided in +A more precise specification of the timing semantics is proposed in [scheduling.md](./scheduling.md). #### Pulse Operations @@ -153,12 +145,12 @@ in ``` NONBLOCKING PULSE 0 "xy" flat(duration: 1.0, iq: 1.0) -PULSE 0 1 "ff" flat(duration: 1.0, iq: 1.0) +NONBLOCKING PULSE 0 1 "ff" flat(duration: 1.0, iq: 1.0) ``` the two pulses could be emitted simultaneously. Nonetheless, a `NONBLOCKING` pulse does still exclude the usage of the pulse frame, so e.g. `NONBLOCKING -PULSE 0 "xy" ... ; PULSE 0 "xy" ...` would require serial execution. +PULSE 0 "xy" ... ; NONBLOCKING PULSE 0 "xy" ...` would require serial execution. #### Delay @@ -198,9 +190,11 @@ Calibrations can be parameterized and include concrete values, which are resolved in "Haskell-style", with later definitions being prioritized over earlier ones. For example, given the following list of calibration definitions in this order: -1. `DEFCAL RX(%theta) %qubit:` -2. `DEFCAL RX(%theta) 0:` -3. `DEFCAL RX(pi/2) 0:` + +1. `DEFCAL RX(%theta) qubit: ...` +2. `DEFCAL RX(%theta) 0: ...` +3. `DEFCAL RX(pi/2) 0: ...` + The instruction `RX(pi/2) 0` would match (3), the instruction `RX(pi) 0` would match (2), and the instruction `RX(pi/2) 1` would match (1). @@ -304,9 +298,9 @@ DEFCAL RX(pi/2) 0: RZ: ``` -DEFCAL RZ(%theta) %qubit: +DEFCAL RZ(%theta) qubit: # RZ of +theta corresponds to a frame change of -theta - SHIFT-PHASE %qubit "xy" -%theta + SHIFT-PHASE qubit "xy" -%theta ``` Calibrations of CZ: @@ -318,23 +312,29 @@ DEFCAL CZ 0 1: # With no parallel 2Q gates DEFCAL CZ 0 1: - FENCE 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 + FENCE PULSE 0 1 "cz" erfsquare(duration: 340e-9, risetime: 20e-9, padleft: 8e-9, padright: 8e-9) SHIFT-PHASE 0 "xy" 0.00181362669 SHIFT-PHASE 1 "xy" 3.44695296672 - FENCE 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 + FENCE ``` Readout: ``` -DEFCAL MEASURE 0 %dest: - DECLARE iq REAL[2] - PULSE 0 "ro" flat(duration: 1.2e-6, iq: ???) - CAPTURE 0 "out" flat(duration: 1.2e-6, iq: ???) iq - LT %dest iq[0] ??? # thresholding +DEFCAL MEASURE 0 addr: + FENCE 0 + DECLARE q0_unclassified REAL[2] + NONBLOCKING PULSE 0 "ro_tx" flat(duration: 1.68e-06, iq: 1.0, scale: 0.04466835921509615, phase: 0.0, detuning: 0.0) + NONBLOCKING CAPTURE 0 "ro_rx" boxcar_kernel(duration: 1.68e-06, scale: 1.0, phase: 2.6571617075901393, detuning: 0.0) q0_unclassified[0] + PRAGMA FILTER-NODE q0_unclassified "{'module':'lodgepole.filters.io','filter_type':'DataBuffer','source':'q0_ro_rx/filter','publish':true,'params':{},'_type':'FilterNode'}" + PRAGMA LOAD-MEMORY q0_unclassified "q0_unclassified[0]" + PRAGMA FILTER-NODE q0_classified "{'module':'lodgepole.filters.classifiers','filter_type':'SingleQLinear','source':'q0_ro_rx/filter','publish':false,'params':{'a':[1.0,0.0],'threshold':0.000241237408735565},'_type':'FilterNode'}" + PRAGMA FILTER-NODE q0 "{'module':'lodgepole.filters.io','filter_type':'DataBuffer','source':'q0_classified','publish':true,'params':{},'_type':'FilterNode'}" + PRAGMA LOAD-MEMORY q0 "addr" + FENCE 0 ``` -Toffoli gate (from Colm): +Toffoli gate: ``` SET-FREQUENCY 12 13 "cz" 283.5e6 SET-FREQUENCY 13 14 "iswap" 181e6 @@ -356,19 +356,6 @@ DEFCAL CCNOT 12 13 14: FENCE 12 13 14 ``` -Active Reset Calibration: -``` -DEFCAL RESET %qubit: - DECLARE ro BIT - MEASURE %qubit ro[0] - JUMP-UNLESS ro @delay - RX(pi) %qubit - JUMP @end - LABEL delay - DELAY %qubit 60e-9 - LABEL end -``` - Single point of a parametric gate chevron: (parameterized in amplitude, frequency, and time) ``` @@ -379,6 +366,19 @@ SET-SCALE 0 "cz" 0.45 PULSE 0 1 "cz" erfsquare(duration: 100e-9, risetime: 20e-9, padleft: 0, padright: 0) ``` +Active Reset Calibration: +``` +DEFCAL RESET qubit: + DECLARE ro BIT + MEASURE qubit ro[0] + JUMP-UNLESS ro @delay + RX(pi) qubit + JUMP @end + LABEL delay + DELAY qubit 60e-9 + LABEL end +``` + ## FAQs **How would this interact with quilc and qvm?** diff --git a/rfcs/analog/spec_changes.md b/rfcs/analog/spec_changes.md index 399036b..a4c20a0 100644 --- a/rfcs/analog/spec_changes.md +++ b/rfcs/analog/spec_changes.md @@ -11,30 +11,29 @@ Frame :: Qubit+ FrameName A frame encapsulates any rotating frame relative to which control/readout waveforms may be defined. For the purposes of scheduling and execution on -possibly heterogenous hardware, frames are specified with respect to a specific +possibly heterogeneous hardware, frames are specified with respect to a specific list of qubits. Thus, `0 1 "cz"` is the "cz" frame on qubits 0 and 1. The order of the qubits matters. In particular, the above frame may differ from `1 0 "cz"`. #### DEFFRAME -Quilt itself has no built-in frames. Frames must be defined using the `DEFFRAME` +Frames are the basic resources manipulated by Quilt programs, and in +any implementation will involve a certain amount of coupling with the +underlying control hardware. As such, Quilt itself has no built-in +frames. Native or canonical frame definitions may be provided by a +hardware vendor, and are exposed to Quilt programs via the `DEFFRAME` directive. ``` DefFrame :: DEFFRAME Frame (: FrameSpec+ )? FrameSpec :: Indent FrameAttr : ( Expression | String ) -FrameAttr :: SAMPLE-RATE | INITIAL-FREQUENCY | DIRECTION | HARDWARE-OBJECT +FrameAttr :: Identifier ``` -All frames used in a program must have a corresponding top-level definition. - - -Before execution, a Quilt program is linked with a specific system of control -hardware, and frames are mapped to suitable hardware objects (cf. the -`HARDWARE-OBJECT` frame attribute below). Native or canonical frame definitions may be -provided by a hardware vendor. Some examples of Rigetti's canonical frames are -listed below, but this is subject to change. +All frames used in a program must have a corresponding top-level +definition. Some examples of Rigetti's canonical frames are listed +below, but this is subject to change. Examples (names only): ``` @@ -46,44 +45,87 @@ Examples (names only): "out" # eg. for the capture line ``` +Relevant characteristics of a particular frame are indicated in the +body of a `DEFFRAME` by way of frame attributes. Certain of these +attributes are standardized, whereas others are hardware or +implementation specific. The specific set of required and optional +frame attributes is implementation specific. -##### Frame Attributes +Here is an example of a full frame definition: -Frame attributes represent quantities associated with a given frame which need not be specified by the programmer, but which are ultimately required to fully link and execute a Quilt program on a physical device. +``` +DEFFRAME 0 1 "cz": + DIRECTION: "tx" + INITIAL-FREQUENCY: 220487409.16137844 + CENTER-FREQUENCY: 375000000.0 + HARDWARE-OBJECT: "q0_ff" + SAMPLE-RATE: 1000000000.0 +``` + + +##### Standard Frame Attributes + +All frames have an associated frequency and sample rate. Additionally, operations on frames must respect a certain sort of type safety: namely, certain frames can have `PULSE` applied, others can have `CAPTURE` applied, and the two are assumed to be exclusive. - `SAMPLE-RATE` is a floating point number indicating the rate (in Hz) of the digital-to-analog converter on the control hardware associated with this frame. - `INITIAL-FREQUENCY` is a floating point number indicating the initial frame frequency. -- `DIRECTION` is one of `"tx"` or `"rx"`. -- `HARDWARE-OBJECT` is a string indicating the (implementation-specific) hardware object that the frame is associated with. +- `DIRECTION` is one of `"tx"` or `"rx"`, and indicates whether the frame is available for pulse operations (`"tx"`) or capture operations (`"rx"`). + + +##### Rigetti Native Frame Attributes + +Frame attributes represent quantities associated with a given frame which need not be specified by the programmer, but which are ultimately required to fully link and execute a Quilt program on a physical device. + +- `HARDWARE-OBJECT` is a string indicating the (implementation-specific) hardware object that the frame is associated with, used for program linkage. +- `CENTER-FREQUENCY` is an optional attribute, consisting of a floating point value indicating the frame frequency which should be considered the "center" for the purposes of digital-to-analog or analog-to-digital conversion. -### Waveforms +### Waveform References ``` Waveform :: Name -Waveform :: flat ( duration: Expression, iq: Expression ) -Waveform :: gaussian ( duration: Expression, fwhm: Expression, t0: Expression ) -Waveform :: draggaussian ( duration: Expression, fwhm: Expression, t0: Expression, - anh: Expression, alpha: Expression ) -Waveform :: erfsquare ( duration: Expression, risetime: Expression, - padleft: Expression, padright: Expression ) +Waveform :: Name '(' NamedParam ( , NamedParam )* ')' +NamedParam :: Name : Expression ``` -Waveforms are referenced either by name or by a built-in waveform generator. +There are two sorts of waveform references present in Quilt. Custom +waveforms, defined with `DEFWAVEFORM`, are referenced directly by +name. Quilt implementations may also support a number of "template +waveforms", which are denoted using functional notation. For example +`foo(a: 1, b: 2)` denotes a template waveform named `foo` with +template parameter `a` set to `1` and `b` set to `2`. -The built-in waveform generators are: -- `flat(duration, iq)` creates a flat waveform where: +Although the values of template parameters may be expressions in +general, specific implementations of Quilt are free to restrict this +in a suitable fashion (e.g. to literal real or complex values). + +#### Rigetti's Template Waveforms + +Some examples of the template waveforms made available by Rigetti include: + +``` +Waveform :: flat '(' duration: Expression, iq: Expression ')' +Waveform :: gaussian '(' duration: Expression, fwhm: Expression, t0: Expression ')' +Waveform :: draggaussian '(' duration: Expression, fwhm: Expression, t0: Expression, + anh: Expression, alpha: Expression ')' +Waveform :: erfsquare '(' duration: Expression, risetime: Expression, + padleft: Expression, padright: Expression ')' +``` + +The meaning of these are as follows + +- `flat(duration, iq)` denotes a flat waveform where: - `duration` is a rational number representing the duration of the waveform in seconds - `iq` is a complex number representing the IQ value to play for the duration of the waveform -- `gaussian(duration, fwhm, t0)` creates a Gaussian waveform where: +- `gaussian(duration, fwhm, t0)` denotes a Gaussian waveform where: - `duration` is a rational number representing the duration of the waveform in seconds - `fwhm` is a rational number representing the full-width-half-max of the waveform in seconds - `t0` is a rational number representing the center time coordinate of the waveform in seconds -- `draggaussian(duration, fwhm, t0, anh, alpha)` creates a DRAG gaussian pulse where: +- `draggaussian(duration, fwhm, t0, anh, alpha)` denotes a DRAG gaussian pulse where: - `duration` is a rational number representing the duration of the waveform in seconds - `fwhm` is a rational number representing the full-width-half-max of @@ -93,8 +135,8 @@ The built-in waveform generators are: - `anh` is a rational number representing the anharmonicity of the qubit in Hertz - `alpha` is a rational number for the dimensionless drag parameter -- `erfsquare(duration, risetime, padleft, padright)` creates a pulse with a flat - top and edges that are error functions (erfs) where: +- `erfsquare(duration, risetime, padleft, padright)` denotes a pulse with a flat + top and edges that are error functions (erf) where: - `duration` is a rational number representing the duration of the waveform in seconds - `risetime` is a rational number representing the rise and fall sections of @@ -103,32 +145,30 @@ The built-in waveform generators are: padding to add to the left of the pulse - `padright` is a rational number representing the amount of zero-amplitude padding to add to the right of the pulse + +At present, all `Expression` values above must be statically determinable, as template resolution occurs prior to execution time. #### Defining new waveforms ``` SampleRate :: Float -WaveformDefinition :: DEFWAVEFORM Name ( Parameter+ ) SampleRate : MatrixRow +WaveformDefinition :: DEFWAVEFORM Name : MatrixRow MatrixRow :: Indent (Expression ,)+ ``` -New waveforms may be defined by specifying the sample rate (in Hertz) and listing out all -the IQ values as complex numbers, separated by commas. Waveform definitions may -also be parameterized, although note that Quil has no support for vector level -operations. +New waveforms may be defined by by listing out all the IQ values as +complex numbers, separated by commas. Example: ``` -DEFWAVEFORM my_custom_waveform 6.0: +DEFWAVEFORM my_custom_waveform: 1+2i, 3+4i, 5+6i - -DEFWAVEFORM my_custom_parameterized_waveform(%a) 6.0: - (1+2i)*%a, (3+4i)*%a, (5+6i)*%a ``` -The duration (in seconds) of a custom waveform may be computed by dividing the -number of samples by the sample rate. In the above example, both waveforms have -a duration of 0.5 seconds. +The duration (in seconds) of a custom waveform applied on a particular +frame may be computed by dividing the number of samples in the +waveform by the sample rate of the frame. In the above example, both +waveforms have a duration of 0.5 seconds. ### Pulses @@ -143,9 +183,6 @@ Examples: # Simple pulse with previously defined waveform PULSE 0 "xy" my_custom_waveform -# Pulse with previously defined parameterized waveform -PULSE 0 "xy" my_custom_parameterized_waveform(0.5) - # Pulse with built-in waveform generator PULSE 0 "xy" flat(duration: 1e-6, iq: 2+3i) @@ -159,16 +196,24 @@ corresponding frame's sample rate is undefined. ### Frame Mutations +The state of a frame may be updated by one of several "frame +mutations". In what follows, frame mutations may take as arguments +arbitrary real-valued expressions. However, conforming Quilt +implementations may restrict the arguments to literal reals, memory +references, or specific combinations thereof. + #### Frequency ``` -SetFrequency :: SET-FREQUENCY Frame Float -ShiftFrequency :: SHIFT-FREQUENCY Frame Float +SetFrequency :: SET-FREQUENCY Frame Expression +ShiftFrequency :: SHIFT-FREQUENCY Frame Expression ``` -Each frame has a frequency which is tracked throughout the program. Initial -frame frequencies are specified in the frame definition's `INITIAL-FREQUENCY` -attribute. Subsequent code may update this, either assigning an absolute value (`SET-FREQUENCY`) or a relative offset (`SHIFT-FREQUENCY`). +Each frame has a real frequency which is tracked throughout the +program. Initial frame frequencies are specified in the frame +definition's `INITIAL-FREQUENCY` attribute. Subsequent code may update +this, either assigning an absolute value (`SET-FREQUENCY`) or a +relative offset (`SHIFT-FREQUENCY`). ``` @@ -179,19 +224,15 @@ SHIFT-FREQUENCY 0 "ro" 6.1e9 #### Phase ``` -SetPhase :: SET-PHASE Frame Float +SetPhase :: SET-PHASE Frame Expression ShiftPhase :: SHIFT-PHASE Frame Expression SwapPhases :: SWAP-PHASES Frame Frame ``` -Each frame has a phase which is tracked throughout the program. Initially the +Each frame has a real phase which is tracked throughout the program. Initially the phase starts out as 0. It may be set or shifted up and down, as well as swapped with other frames. -The phase must be a rational real number. There is also support for -shifted the phase based on some expression, as long as that expression returns -a real number. - Example: ``` SET-PHASE 0 "xy" pi/2 @@ -205,10 +246,10 @@ SWAP-PHASE 0 "xy" 1 "xy" #### Scale ``` -SetScale :: SET-SCALE Frame Float +SetScale :: SET-SCALE Frame Expression ``` -Each frame has a scale which is tracked throughout the program. Initially the +Each frame has a real scale which is tracked throughout the program. Initially the scale starts out as 1. Example: @@ -237,23 +278,20 @@ Example: ``` # Simple capture of an IQ point DECLARE iq REAL[2] -CAPTURE 0 "out" flat(1e-6, 2+3i) iq +CAPTURE 0 "out" flat(duration: 1e-6, iq: 2+3i) iq # Raw capture -DECLARE iqs REAL[400] # length needs to be determined based on the sample rate -CAPTURE 0 "out" 200e-6 iqs +DECLARE iqs REAL[400] # length needs to be determined based on the sample rate of the `0 "out"` frame +RAW-CAPTURE 0 "out" 200e-6 iqs ``` -The behavior of a `CAPTURE` instruction with a custom waveform whose sample rate -does not match the corresponding frame's sample rate is undefined. - **Defining Calibrations** ### Defining Calibrations ``` GateModifier :: CONTROLLED | DAGGER | FORKED -CalibrationDefinition :: DEFCAL OpModifier* Name ( Parameter+ ) Qubit+ : Instruction+ +CalibrationDefinition :: DEFCAL GateModifier* Name ( Parameter+ ) Qubit+ : Instruction+ MeasureCalibrationDefinition :: DEFCAL Name Qubit? Parameter : Instruction+ ``` @@ -287,7 +325,8 @@ DEFCAL X 0: # Parameterized gate on qubit 0 DEFCAL RX(%theta) 0: - PULSE 0 "xy" flat(duration: 1e-6, iq: 2+3i)*%theta/(2*pi) + SET-SCALE 0 "xy" %theta/(2*pi) + PULSE 0 "xy" flat(duration: 1e-6, iq: 2+3i) # Applying RZ to any qubit DEFCAL RZ(%theta) %qubit: @@ -296,7 +335,7 @@ DEFCAL RZ(%theta) %qubit: # Measurement and classification DEFCAL MEASURE 0 %dest: DECLARE iq REAL[2] - CAPTURE 0 "out" flat(1e-6, 2+3i) iq + CAPTURE 0 "out" flat(duration: 1e-6, iq: 2+3i) iq LT %dest iq[0] 0.5 # thresholding ``` @@ -336,7 +375,7 @@ unaffected. Fence ensures that all operations involving the specified qubits that follow the fence statement happen after all operations involving the specified qubits that -preceed the fence statement. If no qubits are specified, the `FENCE` operation +precede the fence statement. If no qubits are specified, the `FENCE` operation implicitly applies to all qubits on the device. Examples: