59 programs, each with what the reader must do with it: the language specification's 21 example programs, unchanged (those that run held to their results, the rest to the code that names the first construct the reader cannot hold exactly, or the example's own error), and a program for each construct with a reference written without it. stdgates.qasm applies every standard gate once, and its reference writes each in U and CX alone. Expectations: refused (a code), warns (every warning's code), deterministic (every shot's outcome), distribution (exact outcome probabilities), expectations (exact Pauli values), equivalent (a reference's unitary up to a global phase), exact (the bit-exact circuit takes it or refuses it with a code), outputs, timing and calibrations. bundle.json holds the cases with their text inline for builds that read no files; a test holds it equal to the files. CI: wai-quantum-lang.yml runs the reader's tests, the corpus natively, the reader built without the lowerings, and the corpus under wasm32-wasip2 by wasmtime; wai-web's wasm32 tests read every case through the page's engine (the wasm32 count goes from 8 to 9). Co-Authored-By: Claude Opus 5.5 <[email protected]>
525 lines
43 KiB
JSON
525 lines
43 KiB
JSON
{
|
|
"format": "wai.qasm3-conformance-bundle/1",
|
|
"about": "manifest.json's cases with each program's text inline, for builds that read no files (the browser, the edge); a test holds it equal to the files",
|
|
"cases": [
|
|
{
|
|
"file": "spec/adder.qasm",
|
|
"qasm": "/*\n * quantum ripple-carry adder\n * Cuccaro et al, quant-ph/0410184\n */\ninclude \"stdgates.inc\";\n\ngate majority a, b, c {\n cx c, b;\n cx c, a;\n ccx a, b, c;\n}\n\ngate unmaj a, b, c {\n ccx a, b, c;\n cx c, a;\n cx a, b;\n}\n\nqubit[1] cin;\nqubit[4] a;\nqubit[4] b;\nqubit[1] cout;\nbit[5] ans;\nuint[4] a_in = 1; // a = 0001\nuint[4] b_in = 15; // b = 1111\n// initialize qubits\nreset cin;\nreset a;\nreset b;\nreset cout;\n\n// set input states\nfor uint i in [0: 3] {\n if(bool(a_in[i])) x a[i];\n if(bool(b_in[i])) x b[i];\n}\n// add a to b, storing result in b\nmajority cin[0], b[0], a[0];\nfor uint i in [0: 2] { majority a[i], b[i + 1], a[i + 1]; }\ncx a[3], cout[0];\nfor uint i in [2: -1: 0] { unmaj a[i],b[i+1],a[i+1]; }\nunmaj cin[0], b[0], a[0];\nmeasure b[0:3] -> ans[0:3];\nmeasure cout[0] -> ans[4];\n",
|
|
"expect": {
|
|
"deterministic": "10000"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/alignment.qasm",
|
|
"qasm": "/* CPMG XY4 decoupling\n * This example demonstrates the use of stretch to\n * specify design intent on gate alignment, without\n * being tied to physical qubits and gates.\n*/\ninclude \"stdgates.inc\";\n\nstretch g;\n\nqubit[3] q;\nbarrier q;\ncx q[0], q[1];\ndelay[g] q[2];\nU(pi/4, 0, pi/2) q[2];\ndelay[2*g] q[2];\nbarrier q;\n",
|
|
"expect": {
|
|
"warns": [
|
|
"Q403"
|
|
],
|
|
"timing": true,
|
|
"distribution": {
|
|
"000": 0.8535533905932737,
|
|
"100": 0.14644660940672624
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/arrays.qasm",
|
|
"qasm": "OPENQASM 3.0; // Version statement is optional\n\n// ==================\n// Array declarations\n// ==================\n\n// Declare 'my_ints' to be a 1D array of 8-bit signed integers, where the index\n// runs from 0 to 15.\narray[int[8], 16] my_ints;\n\n// Declare 'my_doubles' to be a 2D array of double-precision floating-point\n// values, where the first index runs from 0 to 7 and the second from 0 to 3.\narray[float[64], 8, 4] my_doubles;\n\n// Initialise a 1D array with fixed values.\narray[uint[32], 4] my_defined_uints = {5, 6, 7, 8};\n\n// Initialise a 2D array with fixed values.\narray[float[32], 4, 2] my_defined_floats = {\n {0.5, 0.5},\n {1.0, 2.0},\n {-0.4, 0.7},\n {1.3, -2.1e-2}\n};\n\n// Initialise an array using a row of another array. Note that this copies the\n// data; changes to the values in `my_defined_float_row` will not affect\n// `my_defined_floats`.\narray[float[32], 2] my_defined_float_row = my_defined_floats[0];\n\n// Arrays can be defined in terms of compile-time constant dimension sizes, and\n// can use expressions in the slots of their initialisers.\nconst uint[8] DIM_SIZE = 2;\narray[int[8], DIM_SIZE, DIM_SIZE] all_ones = {{2+3, 4-1}, {3+8, 12-4}};\n\n\n// =============================\n// Array indexing and operations\n// =============================\n\n// Use `[]` notation to access array elements. The dimensions are\n// comma-separated.\nuint[8] a = my_defined_uints[0];\nfloat[32] b = my_defined_floats[2, 1];\n\n// The same notation is used in simple assignments.\nmy_defined_uints[1] = 5;\nmy_defined_floats[3, 0] = -0.45;\n\n// In both, the indices can be (non-constant) expressions.\nmy_defined_uints[a - 1] = a + 1;\n\n// Assignments can also be done using an array, or array slice, on the left-hand\n// side, provided the right-hand side evaluates to an array of exactly the same\n// shape. The assignment is done by copy, so subsequent changes to either of\n// the two parts will not affect the other.\nmy_defined_floats[2] = my_defined_float_row;\n\n// You can also use the slice notation to set elements. Beware that it is\n// generally a logical error to read and write from overlapping slices at the\n// same time, and that OpenQASM 3 makes no guarantees about which order the data\n// will be read from and written to. You might clobber data if you overlap.\nmy_defined_floats[0:1] = my_defined_floats[2:3];\n\n// The ``sizeof`` operator returns the size of an array's dimension.\nconst uint[32] dimension = sizeof(my_defined_uints); // assigns 4.\n\n// The ``sizeof`` operator can also be used in two-argument form, where the\n// second argument is the index of the dimension, counting from 0.\nconst uint[32] first_dimension = sizeof(my_doubles, 0); // returns 8\nconst uint[32] second_dimension = sizeof(my_doubles, 1); // returns 4\n\n// If the second argument is omitted from ``sizeof`` and the given array is\n// multi-dimensional, it defaults to returning the first dimension, so\n// ``sizeof(my_array) == sizeof(my_array, 0)`` in all circumstances.\nconst uint[32] first_dimension = sizeof(my_doubles); // still 8.\n\n\n// =====================\n// Arrays in subroutines\n// =====================\n\n// Array arguments have a mandatory ``readonly`` or ``mutable`` specifier when\n// defined in a subroutine argument list. This is because arrays are passed to\n// subroutines by reference, not by value, so modifications will propagate back\n// to the original data. Such modifications are only allowed for ``mutable``\n// references, not ``readonly``.\ndef copy_3_bytes(readonly array[uint[8], 3] in_array, mutable array[uint[8], 3] out_array) {\n // Within this block, ``in_array`` can be read from, but not written to,\n // whereas ``out_array`` can be both read from and written to.\n}\n\n// When specifying array subroutine parameters, there is a second format where\n// the sizes of the dimensions are not given explicitly, only the number of\n// dimensions. This is where the ``sizeof`` operator is most useful. In these\n// cases, `sizeof` is _not_ a compile-time constant.\ndef multi_dimensional_input(readonly array[int[32], #dim=3] my_array) {\n uint[32] dimension_0 = sizeof(my_array, 0);\n uint[32] dimension_1 = sizeof(my_array, 1);\n uint[32] dimension_2 = sizeof(my_array, 2);\n}\n",
|
|
"expect": {
|
|
"refused": "Q107"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/cphase.qasm",
|
|
"qasm": "gate cphase(θ) a, b\n{\n U(0, 0, θ / 2) a;\n CX a, b;\n U(0, 0, -θ / 2) b;\n CX a, b;\n U(0, 0, θ / 2) b;\n}\ncphase(π / 2) q[0], q[1];\n",
|
|
"expect": {
|
|
"refused": "Q102"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/dd.qasm",
|
|
"qasm": "/* CPMG XY4 decoupling w/ boxing\n * This example demonstrates the use of referential delays\n * and time alignment.\n*/\ninclude \"stdgates.inc\";\n\nstretch a;\nduration start_stretch = -0.5 * durationof({x $0;}) + a;\nduration middle_stretch = -0.5 * durationof({x $0;}) - 5 * durationof({y $0;}) + a;\nduration end_stretch = -0.5 * durationof({y $0;}) + a;\n\nbox {\n delay[start_stretch] $0;\n x $0;\n delay[middle_stretch] $0;\n y $0;\n delay[middle_stretch] $0;\n x $0;\n delay[middle_stretch] $0;\n y $0;\n delay[end_stretch] $0;\n\n cx $2, $3;\n cx $1, $2;\n u $3;\n}\n",
|
|
"expect": {
|
|
"refused": "Q405"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/defcal.qasm",
|
|
"qasm": "defcalgrammar \"openpulse\";\n\ndefcal x $0 {\n play drive($0), gaussian(...);\n}\n\ndefcal x $1 {\n play drive($1), gaussian(...);\n}\n\ndefcal rz(angle[20] theta) q {\n shift_phase drive(q), -theta;\n}\n\ndefcal measure $0 -> bit {\n complex[int[24]] iq;\n bit state;\n complex[int[12]] k0[1024] = [i0 + q0*j, i1 + q1*j, i2 + q2*j, ...];\n play measure($0), flat_top_gaussian(...);\n iq = capture acquire($0), 2048, extern(k0);\n return threshold(iq, 1234);\n}\n\ndefcal zx90_ix $0, $1 {\n play drive($0, \"cr1\"), flat_top_gaussian(...); // uses a non-default\n // frame labeled \"cr1\"\n}\n\ndefcal cx $0, $1 {\n zx90_ix $0, $1;\n x $0;\n shift_phase drive($0, \"cr1\");\n zx90_ix $0, $1;\n x $0;\n x $1;\n}\n",
|
|
"expect": {
|
|
"refused": "Q100"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/gateteleport.qasm",
|
|
"qasm": "// Repetition code gate teleportation\ninclude \"stdgates.inc\";\n\n// declarations\nconst int[32] n = 3;\nextern vote(bit[n]) -> bit;\n\ndef logical_meas(qubit[3] d) -> bit {\n bit[3] c;\n bit r;\n measure d -> c;\n r = vote(c);\n return r;\n}\n\nqubit[3] q;\nqubit[3] a;\nbit r;\n\n// prep magic state\nrz(pi/4) a;\n\n// entangle two logical registers\ncx q, a;\n\n// measure out the ancilla\nr = logical_meas(a);\n\n// if we get a logical |1> then we need to apply a logical Z correction\nif (r == 1) z q;\n",
|
|
"expect": {
|
|
"refused": "Q125"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/inverseqft1.qasm",
|
|
"qasm": "// QFT and measure, version 1\ninclude \"stdgates.inc\";\n\nqubit[4] q;\nbit[4] c;\nreset q;\nh q;\nbarrier q;\nh q[0];\nc[0] = measure q[0];\nif(int[4](c) == 1) { rz(pi / 2) q[1]; }\nh q[1];\nc[1] = measure q[1];\nif(int[4](c) == 1){ rz(pi / 4) q[2]; }\nif(int[4](c) == 2){ rz(pi / 2) q[2]; }\nif(int[4](c) == 3){ rz(pi / 2 + pi / 4) q[2]; }\nh q[2];\nc[2] = measure q[2];\nif(int[4](c) == 1) rz(pi / 8) q[3];\nif(int[4](c) == 2) rz(pi / 4) q[3];\nif(int[4](c) == 3) rz(pi/4+pi/8) q[3];\nif(int[4](c) == 4) rz(pi / 2) q[3];\nif(int[4](c) == 5) rz(pi / 2 + pi / 8) q[3];\nif(int[4](c) == 6) rz(pi / 2+ pi / 4) q[3];\nif(int[4](c) == 7) rz(pi / 2 + pi / 4 + pi / 8) q[3];\nh q[3];\nc[3] = measure q[3];\n",
|
|
"expect": {
|
|
"deterministic": "0000"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/inverseqft2.qasm",
|
|
"qasm": "// QFT and measure, version 2\ninclude \"stdgates.inc\";\n\nqubit[4] q;\nbit c0;\nbit c1;\nbit c2;\nbit c3;\n\nreset q;\nh q;\nbarrier q;\nh q[0];\nmeasure q[0] -> c0;\nif(c0 == 1) { rz(pi / 2) q[1]; }\nh q[1];\nmeasure q[1] -> c1;\nif(c0==1) { rz(pi / 4) q[2]; }\nif(c1==1) { rz(pi / 2) q[2]; }\nh q[2];\nmeasure q[2] -> c2;\nif(c0 == 1) { rz(pi / 8) q[3]; }\nif(c1 == 1) { rz(pi / 4) q[3]; }\nif(c2 == 1) { rz(pi / 2) q[3]; }\nh q[3];\nmeasure q[3] -> c3;\n",
|
|
"expect": {
|
|
"deterministic": "0000"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/ipe.qasm",
|
|
"qasm": "/*\n * Iterative phase estimation\n */\ninclude \"stdgates.inc\";\n\nconst int[32] n = 10; // number of iterations\nconst float[32] theta = 3 * pi / 8; // phase angle on target qubit\n\nqubit q; // phase estimation qubit\nqubit r; // target qubit for the controlled-unitary gate\nangle[n] c; // phase estimation bits\n\n// initialize\nreset q;\nreset r;\n\n// prepare uniform superposition of eigenvectors of phase\nh r;\n\n// iterative phase estimation loop\nuint[n] power = 1;\nfor uint i in [0: n - 1] { // implicitly cast val to int\n reset q;\n h q;\n ctrl @ pow(power) @ phase(theta) q, r;\n inv @ phase(c) q;\n h q;\n measure q -> c[0];\n // newest measurement outcome is associated to a pi/2 phase shift\n // in the next iteration, so shift all bits of c left\n c <<= 1;\n power <<= 1;\n}\n\n// Now c contains the n-bit estimate of phi in the\n// eigenvalue e^{i*phi} and qreg r is projected to an\n// approximate eigenstate of the phase gate.\n",
|
|
"expect": {
|
|
"refused": "Q128"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/msd.qasm",
|
|
"qasm": "/*\n * Magic state distillation and computation\n */\ninclude \"stdgates.inc\";\n\nconst int[32] buffer_size = 6; // size of magic state buffer\n\n// Y-basis measurement\ndef ymeasure(qubit q) -> bit {\n s q;\n h q;\n return measure q;\n}\n\n/*\n * Distillation subroutine takes 10 |H> magic states\n * and 3 scratch qubits that will be reinitialized.\n * The first two input magic states are the outputs.\n * The subroutine returns a success bit that is true\n * on success and false otherwise (see arXiv:1811.00566).\n */\ndef distill(qubit[10] magic, qubit[3] scratch) -> bool {\n bit temp;\n bit[3] checks;\n // Encode two magic states in the [[4,2,2]] code\n reset scratch[0: 1];\n h scratch[1];\n cx scratch[1], magic[0];\n cx magic[1], scratch[0];\n cx magic[0], scratch[0];\n cx scratch[1], magic[1];\n // Body of distillation circuit\n cy magic[2], scratch[0];\n h magic[1];\n temp = ymeasure(magic[2]);\n if(temp == 1) { ry(-pi / 2) scratch[0]; }\n reset scratch[2];\n h scratch[2];\n cz scratch[2], scratch[0];\n cy magic[3], scratch[0];\n temp = ymeasure(magic[3]);\n if(temp==0) { ry(pi / 2) scratch[0]; }\n h scratch[0];\n s scratch[0];\n cy magic[4], scratch[1];\n temp = ymeasure(magic[4]);\n if(temp==1) { ry(-pi / 2) scratch[1]; }\n cz scratch[3], scratch[2];\n cy magic[5], scratch[1];\n temp = ymeasure(magic[5]);\n if(temp==0) { ry(pi / 2) scratch[1]; }\n cy scratch[0], magic[1];\n inv @ s scratch[1];\n cz scratch[0], scratch[1];\n h scratch[0];\n cy scratch[1], magic[1];\n cy magic[6], scratch[0];\n temp = ymeasure(magic[6]);\n if(temp == 1) { ry(-pi / 2) scratch[0]; }\n cz scratch[2], scratch[1];\n cz scratch[2], scratch[0];\n cy magic[7], scratch[0];\n temp = ymeasure(magic[7]);\n if(temp == 0) ry(pi / 2) scratch[0];\n cy magic[8], scratch[1];\n temp = ymeasure(magic[8]);\n if(temp==1) { ry(-pi / 2) scratch[1]; }\n cz scratch[2], scratch[1];\n cy magic[9], scratch[1];\n temp = ymeasure(magic[9]);\n if(temp == 0) { ry(pi / 2) scratch[1]; }\n h scratch[2];\n // Decode [[4,2,2]] code\n cx magic[0], scratch[0];\n cx scratch[1], magic[1];\n cx magic[1], scratch[0];\n cx scratch[1], magic[0];\n h scratch[1];\n checks = measure scratch;\n success = ~(bool(checks[0]) | bool(checks[1]) | bool(checks[2]));\n return success;\n}\n\n// Repeat level-0 distillation until success\ndef rus_level_0(qubit[10] magic, qubit[3] scratch) {\n bool success;\n while(~success) {\n reset magic;\n ry(pi / 4) magic;\n success = distill(magic, scratch);\n }\n}\n\n/*\n * Run two levels of 10:2 magic state distillation.\n * Both levels have two distillations running in parallel.\n * The output pairs from the first level are separated and\n * input to different second levels distillation circuits\n * because a failure in a first level circuit can lead to\n * errors on both outputs.\n * Put the requested even number of copies into the buffer.\n */\ndef distill_and_buffer(int[32] num, qubit[33] work, qubit[buffer_size] buffer) {\n int[32] index;\n bit success_0;\n bit success_1;\n let magic_lvl0 = work[0: 9];\n let magic_lvl1_0 = work[10: 19];\n let magic_lvl1_1 = work[20: 29];\n let scratch = work[30: 32];\n\n // Run first-level circuits until 10 successes,\n // storing the outputs for use in the second level\n for uint i in [0: 9] {\n rus_level_0 magic_lvl0, scratch;\n swap magic_lvl0[0], magic_lvl1_0[i];\n swap magic_lvl0[1], magic_lvl1_1[i];\n }\n\n // Run two second level circuits simultaneously\n success_0 = distill(magic_lvl1_0, scratch);\n success_1 = distill(magic_lvl1_1, scratch);\n\n // Move usable magic states into the buffer register\n if(success_0 && index < buffer_size) {\n swap magic_lvl1_0[0: 1], buffer[index: index + 1];\n index += 2;\n }\n if(success_1 && index < buffer_size) {\n swap magic_lvl1_1[0: 1], buffer[index: index + 1];\n index += 2;\n }\n}\n\n// Apply Ry(pi/4) to a qubit by consuming a magic state\n// from the magic state buffer at address \"addr\"\ndef Ty(int[32] addr, qubit q, qubit[buffer_size] buffer) {\n bit outcome;\n cy buffer[addr], q;\n outcome = ymeasure(buffer[addr]);\n if(outcome == 1) ry(pi / 2) q;\n}\n\nqubit[33] workspace;\nqubit[buffer_size] buffer;\n\nqubit[5] q;\nbit[5] c;\nint[32] address;\n\n// initialize\nreset workspace;\nreset buffer;\nreset q;\n\ndistill_and_buffer(buffer_size) workspace, buffer;\n\n// Consume magic states to apply some gates ...\nh q[0];\ncx q[0], q[1];\nTy(address) q[0], buffer;\naddress += 1;\ncx q[0], q[1];\nTy(address) q[1], buffer;\naddress += 1;\n\n// In principle each Ty gate can execute as soon as the magic\n// state is available at the address in the buffer register.\n\n// We can continue alternating state distillation and computation\n// to refill and empty a circular buffer.\n",
|
|
"expect": {
|
|
"refused": "Q107"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/qec.qasm",
|
|
"qasm": "// Repetition code syndrome measurement\ninclude \"stdgates.inc\";\n\nqubit[3] q;\nqubit[2] a;\nbit[3] c;\nbit[2] syn;\n\ndef syndrome(qubit[3] d, qubit[2] a) -> bit[2] {\n bit[2] b;\n cx d[0], a[0];\n cx d[1], a[0];\n cx d[1], a[1];\n cx d[2], a[1];\n measure a -> b;\n return b;\n}\nreset q;\nreset a;\nx q[0]; // insert an error\nbarrier q;\nsyn = syndrome(q, a);\nif(int[2](syn)==1) x q[0];\nif(int[2](syn)==2) x q[2];\nif(int[2](syn)==3) x q[1];\nc = measure q;\n",
|
|
"expect": {
|
|
"deterministic": "01000"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/qft.qasm",
|
|
"qasm": "// quantum Fourier transform\ninclude \"stdgates.inc\";\nqubit[4] q;\nbit[4] c;\nreset q;\nx q[0];\nx q[2];\nbarrier q;\nh q[0];\ncphase(pi / 2) q[1], q[0];\nh q[1];\ncphase(pi / 4) q[2], q[0];\ncphase(pi / 2) q[2], q[1];\nh q[2];\ncphase(pi / 8) q[3], q[0];\ncphase(pi / 4) q[3], q[1];\ncphase(pi / 2) q[3], q[2];\nh q[3];\nc = measure q;\n",
|
|
"expect": {
|
|
"distribution": {
|
|
"0000": 0.0625,
|
|
"0001": 0.0625,
|
|
"0010": 0.0625,
|
|
"0011": 0.0625,
|
|
"0100": 0.0625,
|
|
"0101": 0.0625,
|
|
"0110": 0.0625,
|
|
"0111": 0.0625,
|
|
"1000": 0.0625,
|
|
"1001": 0.0625,
|
|
"1010": 0.0625,
|
|
"1011": 0.0625,
|
|
"1100": 0.0625,
|
|
"1101": 0.0625,
|
|
"1110": 0.0625,
|
|
"1111": 0.0625
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/qpt.qasm",
|
|
"qasm": "include \"stdgates.inc\";\n\ngate pre q { } // pre-rotation\ngate post q { } // post-rotation\n\nqubit q;\nbit c;\nreset q;\npre q;\nbarrier q;\nh q;\nbarrier q;\npost q;\nc = measure q;\n",
|
|
"expect": {
|
|
"distribution": {
|
|
"0": 0.5,
|
|
"1": 0.5
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/rb.qasm",
|
|
"qasm": "// One randomized benchmarking sequence\ninclude \"stdgates.inc\";\n\nqubit[2] q;\nbit[2] c;\n\nreset q;\nh q[0];\nbarrier q;\ncz q[0], q[1];\nbarrier q;\ns q[0];\ncz q[0], q[1];\nbarrier q;\ns q[0];\nz q[0];\nh q[0];\nbarrier q;\nmeasure q -> c;\n",
|
|
"expect": {
|
|
"deterministic": "00"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/rus.qasm",
|
|
"qasm": "/*\n * Repeat-until-success circuit for Rz(theta),\n * cos(theta-pi)=3/5, from Nielsen and Chuang, Chapter 4.\n */\ninclude \"stdgates.inc\";\n\n/*\n * Applies identity if out is 01, 10, or 11 and a Z-rotation by\n * theta + pi where cos(theta)=3/5 if out is 00.\n * The 00 outcome occurs with probability 5/8.\n */\ndef segment(qubit[2] anc, qubit psi) -> bit[2] {\n bit[2] b;\n reset anc;\n h anc;\n ccx anc[0], anc[1], psi;\n s psi;\n ccx anc[0], anc[1], psi;\n z psi;\n h anc;\n measure anc -> b;\n return b;\n}\n\nqubit input_qubit;\nqubit[2] ancilla;\nbit[2] flags = \"11\";\nbit output_qubit;\n\nreset input_qubit;\nh input_qubit;\n\n// braces are optional in this case\nwhile(int[2](flags) != 0) {\n flags = segment(ancilla, input_qubit);\n}\nrz(pi - arccos(3 / 5)) input_qubit;\nh input_qubit;\noutput_qubit = measure input_qubit; // should get zero\n",
|
|
"expect": {
|
|
"refused": "Q310"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/scqec.qasm",
|
|
"qasm": "/*\n * Surface code quantum memory.\n *\n * Estimate the failure probability as a function\n * of parameters at the top of the file.\n */\ninclude \"stdgates.inc\";\n\nconst int[32] d = 3; // code distance\nconst int[32] m = 10; // number of syndrome measurement cycles\nconst int[32] shots = 1000; // number of samples\nconst int[32] n = d**2; // number of code qubits\n\nuint[32] failures; // number of observed failures\n\nextern zfirst(creg[n - 1], int[32], int[32]);\nextern send(creg[n -1 ], int[32], int[32], int[32]);\nextern zlast(creg[n], int[32], int[32]) -> bit;\n\nqubit[n] data; // code qubits\nqubit[n-1] ancilla; // syndrome qubits\n/*\n * Ancilla are addressed in a (d-1) by (d-1) square array\n * followed by 4 length (d-1)/2 arrays for the top,\n * bottom, left, and right boundaries.\n */\n\nbit[n-1] layer; // syndrome outcomes in a cycle\nbit[n] data_outcomes; // data outcomes at the end\nbit outcome; // logical outcome\n\n/* Declare a sub-circuit for Hadamard gates on ancillas\n */\ndef hadamard_layer(qubit[n-1] ancilla) {\n // Hadamards in the bulk\n for uint[32] row in [0: d-2] {\n for uint[32] col in [0: d-2] {\n bit[32] sum = bit[32](row + col);\n if(sum[0] == 1)\n h ancilla[row * (d - 1) + col];\n }\n }\n // Hadamards on the left and right boundaries\n for uint[32] i in [0: d - 2] {\n h ancilla[(d - 1)**2 + (d - 1) + i];\n }\n}\n\n/* Declare a sub-circuit for a syndrome cycle.\n */\ndef cycle(qubit[n] data, qubit[n-1] ancilla) -> bit[n-1] {\n reset ancilla;\n hadamard_layer ancilla;\n\n // First round of CNOTs in the bulk\n for uint[32] row in [0: d - 2] {\n for uint[32] col in [0:d - 2] {\n bit[32] sum = bit[32](row + col);\n if(sum[0] == 0)\n cx data[row * d + col], ancilla[row * (d - 1) + col];\n if(sum[0] == 1) {\n cx ancilla[row * (d - 1) + col], data[row * d + col];\n }\n }\n }\n // First round of CNOTs on the bottom boundary\n for uint[32] i in [0: (d - 3) / 2] {\n cx data[d * (d - 1) + 2 * i], ancilla[(d - 1) ** 2 + ( d- 1) / 2 + i];\n }\n // First round of CNOTs on the right boundary\n for uint[32] i in [0: (d - 3) / 2] {\n cx ancilla[(d - 1) ** 2 + 3 * (d - 1) / 2 + i], data[2 * d - 1 + 2 * d * i];\n }\n // Remaining rounds of CNOTs, go here ...\n\n hadamard_layer ancilla;\n return measure ancilla;\n}\n\n// Loop over shots\nfor uint[32] shot in [1: shots] {\n\n // Initialize\n reset data;\n layer = cycle(data, ancilla);\n zfirst(layer, shot, d);\n\n // m cycles of syndrome measurement\n for int[32] i in [1: m] {\n layer = cycle(data, ancilla);\n send(layer, shot, i, d);\n }\n\n // Measure\n data_outcomes = measure data;\n\n outcome = zlast(data_outcomes, shot, d);\n failures += int[1](outcome);\n}\n\n/* The ratio of \"failures\" to \"shots\" is our result.\n * The data can be logged by the external functions too.\n */\n",
|
|
"expect": {
|
|
"refused": "Q125"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/t1.qasm",
|
|
"qasm": "/* Measuring the relaxation time of a qubit\n * This example demonstrates the repeated use of fixed delays.\n*/\ninclude \"stdgates.inc\";\n\nduration stride = 1us; // time resolution of points taken\nconst int[32] points = 50; // number of points taken\nconst int[32] shots = 1000; // how many shots per point\n\nint[32] counts0;\nint[32] counts1 = 0; // surviving |1> populations of qubits\n\nextern tabulate(int[32], int[32], int[32]);\n\nbit c0;\nbit c1;\n\ndefcalgrammar \"openpulse\";\n\n// define a gate calibration for an X gate on any qubit\ndefcal x q {\n play drive(q), gaussian(100, 30, 5);\n}\n\nfor int[32] p in [0 : points-1] {\n for uint i in [1 : shots] {\n // start of a basic block\n reset $0;\n reset $1;\n // excite qubits\n x $0;\n x $1;\n // wait for a fixed time indicated by loop counter\n delay[p * stride] $0;\n // wait for a fixed time indicated by loop counters\n delay[p * durationof({x $1;})];\n // read out qubit states\n c0 = measure $0;\n c1 = measure $1;\n // increment counts memories, if a 1 is seen\n counts0 += int[1](c0);\n counts1 += int[1](c1);\n }\n // log survival probability curve\n tabulate(counts0, shots, p);\n tabulate(counts1, shots, p);\n}\n",
|
|
"expect": {
|
|
"refused": "Q405"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/teleport.qasm",
|
|
"qasm": "// quantum teleportation example\nOPENQASM 3; // Version statement is optional\ninclude \"stdgates.inc\";\nqubit[3] q;\nbit c0;\nbit c1;\nbit c2;\n// optional post-rotation for state tomography\n// empty gate body => identity gate\ngate post q { }\nreset q;\nU(0.3, 0.2, 0.1) q[0];\nh q[1];\ncx q[1], q[2];\nbarrier q;\ncx q[0], q[1];\nh q[0];\nc0 = measure q[0];\nc1 = measure q[1];\nif(c0==1) z q[2];\nif(c1==1) { x q[2]; } // braces optional in this case\npost q[2];\nc2 = measure q[2];\n",
|
|
"expect": {
|
|
"expectations": {
|
|
"Z2": 0.955336489125606
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/varteleport.qasm",
|
|
"qasm": "/*\n * Prepare a parameterized number of Bell pairs\n * and teleport a qubit using them.\n */\ninclude \"stdgates.inc\";\n\nconst int[32] n_pairs = 10; // number of teleportations to do\n\ndef bellprep(qubit[2] q) {\n reset q;\n h q[0];\n cx q[0], q[1];\n}\n\ndef xprepare(qubit q) {\n reset q;\n h q;\n}\n\nqubit input_qubit;\nbit output_qubit;\nqubit[2*n_pairs] q;\n\nxprepare(input_qubit);\nrz(pi / 4) input_qubit;\n\nlet io = input_qubit;\nfor uint i in [0: n_pairs - 1] {\n let bp = q[{2*i, 2*i + 1}];\n bit[2] pf;\n bellprep bp;\n cx io, bp[0];\n h io;\n pf[0] = measure io;\n pf[1] = measure bp[0];\n if (pf[0]==1) z bp[1];\n if (pf[1]==1) x bp[1];\n let io = bp[1];\n}\n\nh io;\noutput_qubit = measure io; // should get zero\n",
|
|
"expect": {
|
|
"refused": "Q101"
|
|
}
|
|
},
|
|
{
|
|
"file": "spec/vqe.qasm",
|
|
"qasm": "/*\n * Variational eigensolver example\n *\n * Goal is to estimate the energy for a fixed set of parameters.\n * The parameters are updated outside of this program and a new\n * OpenQASM circuit is generated for the next iteration.\n */\ninclude \"stdgates.inc\";\n\nconst int[32] n = 10; // number of qubits\nconst int[32] layers = 3; // number of entangler layers\nconst int[32] prec = 16; // precision of all types\nconst int[32] shots = 1000; // number of shots per Pauli observable\n\n// Parameters could be written to local variables for this\n// iteration, but we will request them using extern functions\nextern get_parameter(uint[prec]) -> angle[prec];\nextern get_npaulis() -> uint[prec];\nextern get_pauli(int[prec]) -> bit[2 * n];\n\n// The energy calculation uses floating point division,\n// so we do that calculation in an extern function\nextern update_energy(int[prec], uint[prec], float[prec]) -> float[prec];\n\ngate entangler q { for uint i in [0:n-2] { cx q[i], q[i+1]; } }\ndef xmeasure(qubit q) -> bit { h q; return measure q; }\ndef ymeasure(qubit q) -> bit { s q; h q; return measure q; }\n\n/* Pauli measurement circuit.\n * The first n-bits of spec are the X component.\n * The second n-bits of spec are the Z component.\n */\ndef pauli_measurement(bit[2*n] spec, qubit[n] q) -> bit {\n bit b = 0;\n for uint[prec] i in [0: n - 1] {\n bit temp;\n if(spec[i]==1 && spec[n+i]==0) { temp = xmeasure(q[i]); }\n if(spec[i]==0 && spec[n+i]==1) { temp = measure q[i]; }\n if(spec[i]==1 && spec[n+i]==1) { temp = ymeasure(q[i]); }\n b ^= temp;\n }\n return b;\n}\n\n// Circuit to prepare trial wave function\ndef trial_circuit(qubit[n] q) {\n for int[prec] l in [0: layers - 1] {\n for uint[prec] i in [0: n - 1] {\n angle[prec] theta;\n theta = get_parameter(l * layers + i);\n ry(theta) q[i];\n }\n if(l != layers - 1) entangler q;\n }\n}\n\n/* Apply VQE ansatz circuit and measure a Pauli operator\n * given by spec. Return the number of 1 outcomes.\n */\ndef counts_for_term(bit[2*n] spec, qubit[n] q) -> uint[prec] {\n uint[prec] counts;\n for uint i in [1: shots] {\n bit b;\n reset q;\n trial_circuit q;\n b = pauli_measurement(spec, q);\n counts += int[1](b);\n }\n return counts;\n}\n\n// Estimate the expected energy\ndef estimate_energy(qubit[n] q) -> float[prec] {\n float[prec] energy;\n uint[prec] npaulis = get_npaulis();\n for int[prec] t in [0:npaulis-1] {\n bit[2*n] spec = get_pauli(t);\n uint[prec] counts;\n counts = counts_for_term(spec, q);\n energy = update_energy(t, counts, energy);\n }\n return energy;\n}\n\nqubit[n] q;\nfloat[prec] energy;\n\nenergy = estimate_energy(q);\n",
|
|
"expect": {
|
|
"refused": "Q125"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/def.qasm",
|
|
"qasm": "OPENQASM 3.1;\ninclude \"stdgates.inc\";\n// Subroutines inlined: qubits by reference, classical arguments by value,\n// values returned.\nqubit[3] q;\ndef layer(qubit a, qubit b, float[64] t) { h a; cx a, b; rz(t) b; }\ndef half(float[64] x) -> float[64] { return x / 2; }\ndef twice(int[32] k) -> int[32] { return 2 * k; }\nlayer(q[0], q[1], half(pi / 2));\nlayer(q[1], q[2], pi / twice(4));\n",
|
|
"expect": {
|
|
"equivalent": "lang/def.ref.qasm",
|
|
"exact": "ok"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[3] q;\nh q[0];\ncx q[0], q[1];\nrz(pi / 4) q[1];\nh q[1];\ncx q[1], q[2];\nrz(pi / 8) q[2];\n"
|
|
},
|
|
{
|
|
"file": "lang/def_measure.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// Teleportation as a subroutine with bits of its own, fed forward, and a\n// subroutine whose returned measurement lands in the caller's bit.\nqubit[3] q;\nbit[1] r;\ndef teleport(qubit src, qubit mid, qubit dst) {\n bit a;\n bit b;\n h mid;\n cx mid, dst;\n cx src, mid;\n h src;\n a = measure src;\n b = measure mid;\n if (b) x dst;\n if (a) z dst;\n}\ndef read_out(qubit s) -> bit { return measure s; }\nx q[0];\nteleport(q[0], q[1], q[2]);\nr[0] = read_out(q[2]);\n",
|
|
"expect": {
|
|
"deterministic": "1"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/inv.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[2] q;\ngate g(a) x, y { h x; cx x, y; rz(a) y; s x; }\nh q[0];\nt q[1];\ninv @ g(0.3) q[0], q[1];\ninv @ sx q[1];\ninv @ U(0.1, 0.2, 0.3) q[0];\ninv @ iswap q[0], q[1];\n",
|
|
"expect": {
|
|
"equivalent": "lang/inv.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[2] q;\nh q[0];\nt q[1];\n// g's gates inverted, in reverse order\nsdg q[0];\nrz(-0.3) q[1];\ncx q[0], q[1];\nh q[0];\n// sx = h s h\nh q[1];\nsdg q[1];\nh q[1];\n// U(θ, φ, λ) is rz(φ) ry(θ) rz(λ) up to a phase\nrz(-0.2) q[0];\nry(-0.1) q[0];\nrz(-0.3) q[0];\n// iswap = s, s, h, cx, cx, h\nh q[1];\ncx q[1], q[0];\ncx q[0], q[1];\nh q[0];\nsdg q[1];\nsdg q[0];\n"
|
|
},
|
|
{
|
|
"file": "lang/pow.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[2] q;\ngate g a, b { h a; cx a, b; t b; }\npow(3) @ g q[0], q[1];\npow(-2) @ rx(0.4) q[0];\npow(4) @ t q[1];\npow(0) @ h q[0];\n",
|
|
"expect": {
|
|
"equivalent": "lang/pow.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[2] q;\nh q[0]; cx q[0], q[1]; t q[1];\nh q[0]; cx q[0], q[1]; t q[1];\nh q[0]; cx q[0], q[1]; t q[1];\nrx(-0.8) q[0];\nz q[1];\n"
|
|
},
|
|
{
|
|
"file": "lang/root.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[2] q;\nh q[0];\nh q[1];\npow(0.5) @ x q[0];\npow(0.5) @ z q[1];\npow(0.5) @ s q[0];\npow(0.25) @ rz(1.2) q[1];\npow(-0.5) @ x q[1];\npow(0.5) @ cz q[0], q[1];\n",
|
|
"expect": {
|
|
"equivalent": "lang/root.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[2] q;\nh q[0];\nh q[1];\nsx q[0];\ns q[1];\nt q[0];\nrz(0.3) q[1];\nsxdg q[1];\ncp(pi / 2) q[0], q[1];\n"
|
|
},
|
|
{
|
|
"file": "lang/ctrl_any.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// Controls on any gate: a rotation under two controls, and a negative control.\nqubit[3] q;\nx q[0];\nx q[1];\nctrl(2) @ ry(pi / 3) q[0], q[1], q[2];\nnegctrl @ x q[2], q[0];\n",
|
|
"expect": {
|
|
"distribution": {
|
|
"010": 0.75,
|
|
"111": 0.25
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/ctrl_user.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[2] q;\ngate g a { h a; t a; }\nh q[0];\nctrl @ g q[0], q[1];\nctrl @ rz(0.7) q[1], q[0];\nctrl @ U(0.1, 0.2, 0.3) q[0], q[1];\n",
|
|
"expect": {
|
|
"equivalent": "lang/ctrl_user.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[2] q;\nh q[0];\nch q[0], q[1];\ncp(pi / 4) q[0], q[1];\ncrz(0.7) q[1], q[0];\ncu(0.1, 0.2, 0.3, 0) q[0], q[1];\n"
|
|
},
|
|
{
|
|
"file": "lang/types.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// Classical types, arithmetic, casts and built-in functions, folded on reading.\nqubit q;\nconst float[64] half = 0.5;\nangle[3] quarter = pi / 2;\ncomplex[float[64]] z = 1.0 + 2.0im;\nuint[8] u = 250;\nu += 3;\nint[8] k = int[8](-3.7);\nconst bit[4] mask = \"1010\";\narray[int[32], 3] a = {1, 2, 3};\nrx(half * pi) q;\nrz(quarter) q;\nry(real(z * z)) q;\nrz(float(u) / 1000) q;\nrx(k) q;\nry(popcount(mask) + a[2]) q;\nrz(sqrt(4.0) + arctan(1.0) * 4 - pi) q;\n",
|
|
"expect": {
|
|
"equivalent": "lang/types.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit q;\nrx(pi / 2) q;\nrz(pi / 2) q;\nry(-3.0) q;\nrz(0.253) q;\nrx(-3.0) q;\nry(5.0) q;\nrz(2.0) q;\n"
|
|
},
|
|
{
|
|
"file": "lang/angle_round.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// An angle[4] holds 4 bits of a turn: pi/3 is held as 3/16 of a turn.\nqubit q;\nangle[4] t = pi / 3;\nh q;\nrz(t) q;\n",
|
|
"expect": {
|
|
"warns": [
|
|
"Q121"
|
|
],
|
|
"equivalent": "lang/angle_round.ref.qasm",
|
|
"exact": "ok"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit q;\nh q;\nrz(3 * pi / 8) q;\n"
|
|
},
|
|
{
|
|
"file": "lang/while_static.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[4] q;\nint i = 0;\nwhile (i < 4) {\n h q[i];\n i += 1;\n}\nint j = 3;\nwhile (true) {\n if (j < 1) break;\n x q[j];\n j -= 2;\n}\n",
|
|
"expect": {
|
|
"equivalent": "lang/while_static.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[4] q;\nh q[0];\nh q[1];\nh q[2];\nh q[3];\nx q[3];\nx q[1];\n"
|
|
},
|
|
{
|
|
"file": "lang/while_rus.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// Repeat until success on measured bits, under a declared bound.\nqubit q;\nbit c;\nc = measure q;\[email protected]_iterations 3\nwhile (c == 0) {\n x q;\n c = measure q;\n}\n",
|
|
"expect": {
|
|
"warns": [
|
|
"Q311"
|
|
],
|
|
"deterministic": "1"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/while_unbounded.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit q;\nbit c;\nc = measure q;\nwhile (c == 0) {\n x q;\n c = measure q;\n}\n",
|
|
"expect": {
|
|
"refused": "Q310"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/switch.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[3] q;\nbit[3] c;\nconst int mode = 2;\nswitch (mode) {\n case 1 { x q[0]; }\n case 2, 3 { x q[1]; }\n default { h q[0]; }\n}\nc[0] = measure q[1];\nc[1] = measure q[0];\nswitch (c[0:1]) {\n case 0 { }\n case 1 { x q[2]; }\n case 2 { h q[2]; }\n default { }\n}\nc[2] = measure q[2];\n",
|
|
"expect": {
|
|
"deterministic": "101"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/break_continue.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[8] q;\nfor int i in [0:7] {\n if (i == 2) continue;\n if (i == 5) break;\n x q[i];\n}\n",
|
|
"expect": {
|
|
"equivalent": "lang/break_continue.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[8] q;\nx q[0];\nx q[1];\nx q[3];\nx q[4];\n"
|
|
},
|
|
{
|
|
"file": "lang/runtime_break.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// `break` on a measured bit: a jump forward past the rest of the loop.\nqubit q;\nqubit[3] t;\nbit c;\nbit[3] r;\nfor int i in [0:2] {\n c = measure q;\n if (c) break;\n x t[i];\n x q;\n}\nr = measure t;\n",
|
|
"expect": {
|
|
"deterministic": "0011"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/conditions.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// Comparisons, &&, || and ! on measured bits.\nqubit[3] p;\nqubit[3] t;\nbit[3] c;\nbit[3] r;\nx p[1];\nx p[2];\nc = measure p;\nif (c >= 6 && !c[0]) x t[0];\nif (c < 6 || c == 7) x t[1];\nif (c > 4 && c <= 6) x t[2];\nr = measure t;\n",
|
|
"expect": {
|
|
"deterministic": "101110"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/output.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[2] q;\noutput bit[2] c;\noutput int[32] n = 3;\noutput float[64] t = pi / 4;\nx q[1];\nc = measure q;\n",
|
|
"expect": {
|
|
"deterministic": "10",
|
|
"outputs": [
|
|
{
|
|
"name": "c",
|
|
"type": "bit[2]",
|
|
"bits": [
|
|
0,
|
|
1
|
|
]
|
|
},
|
|
{
|
|
"name": "n",
|
|
"type": "int[32]",
|
|
"value": 3
|
|
},
|
|
{
|
|
"name": "t",
|
|
"type": "float[64]",
|
|
"value": 0.7853981633974483
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/timing.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// Durations carried, and labelled as not applied by the method.\nqubit[2] q;\nstretch s;\nduration d = 100ns;\nh q[0];\ndelay[2 * d] q[0];\nbox [1us] {\n cx q[0], q[1];\n}\ndelay[s] q[1];\nbarrier q;\nx[20ns] q[1];\n",
|
|
"expect": {
|
|
"warns": [
|
|
"Q403"
|
|
],
|
|
"timing": true,
|
|
"distribution": {
|
|
"01": 0.5,
|
|
"10": 0.5
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/calibration.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// Calibrations kept verbatim for export, never run.\ndefcalgrammar \"openpulse\";\ncal {\n extern port d0;\n}\ndefcal x $0 {\n play(d0, gaussian(1.0, 160dt, 40dt));\n}\nqubit q;\nh q;\n",
|
|
"expect": {
|
|
"warns": [
|
|
"Q450",
|
|
"Q451",
|
|
"Q452"
|
|
],
|
|
"calibrations": 3,
|
|
"distribution": {
|
|
"0": 0.5,
|
|
"1": 0.5
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/stdgates.qasm",
|
|
"qasm": "OPENQASM 3.1;\ninclude \"stdgates.inc\";\n// Every standard gate, once, after a layer that leaves no symmetry.\nqubit[3] q;\nU(0.31, 0.72, -0.4) q[0];\nU(1.13, -0.25, 0.9) q[1];\nU(2.07, 0.5, 0.33) q[2];\nCX q[0], q[1];\nCX q[1], q[2];\nU(0.6, 1.1, -0.7) q[0];\nid q[0];\nx q[0];\ny q[1];\nz q[2];\nh q[0];\ns q[1];\nsdg q[2];\nt q[0];\ntdg q[1];\nsx q[2];\nsxdg q[0];\nrx(0.41) q[1];\nry(-1.3) q[2];\nrz(0.77) q[0];\np(1.9) q[1];\nphase(0.2) q[2];\nu1(-0.6) q[0];\nu2(0.3, -1.2) q[1];\nu3(0.8, 0.1, 2.2) q[2];\nU(1.4, -0.9, 0.35) q[0];\ncx q[0], q[1];\nCX q[2], q[0];\ncy q[1], q[2];\ncz q[2], q[0];\nch q[0], q[2];\ncp(0.9) q[1], q[0];\ncphase(-1.1) q[2], q[1];\ncrx(0.6) q[0], q[1];\ncry(-0.8) q[1], q[2];\ncrz(1.7) q[2], q[0];\ncu(0.5, 0.25, -0.75, 0.4) q[0], q[2];\nswap q[1], q[2];\niswap q[0], q[1];\nrxx(0.45) q[1], q[2];\nryy(-0.65) q[0], q[2];\nrzz(1.25) q[0], q[1];\nccx q[0], q[1], q[2];\nccz q[2], q[0], q[1];\ncswap q[1], q[2], q[0];\n",
|
|
"expect": {
|
|
"equivalent": "lang/stdgates.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\n// The same gates, each written in U and CX alone.\ngate d_x a { U(pi, 0, pi) a; }\ngate d_y a { U(pi, pi / 2, pi / 2) a; }\ngate d_z a { U(0, 0, pi) a; }\ngate d_h a { U(pi / 2, 0, pi) a; }\ngate d_s a { U(0, 0, pi / 2) a; }\ngate d_sdg a { U(0, 0, -pi / 2) a; }\ngate d_t a { U(0, 0, pi / 4) a; }\ngate d_tdg a { U(0, 0, -pi / 4) a; }\ngate d_p(l) a { U(0, 0, l) a; }\ngate d_rx(t) a { U(t, -pi / 2, pi / 2) a; }\ngate d_ry(t) a { U(t, 0, 0) a; }\ngate d_rz(t) a { U(0, 0, t) a; }\ngate d_sx a { d_h a; d_s a; d_h a; }\ngate d_sxdg a { d_h a; d_sdg a; d_h a; }\ngate d_cz a, b { d_h b; CX a, b; d_h b; }\ngate d_cy a, b { d_sdg b; CX a, b; d_s b; }\ngate d_ch a, b { d_h b; d_sdg b; CX a, b; d_h b; d_t b; CX a, b; d_t b; d_h b; d_s b; d_x b; d_s a; }\ngate d_cp(l) a, b { d_p(l / 2) a; CX a, b; d_p(-l / 2) b; CX a, b; d_p(l / 2) b; }\ngate d_crz(l) a, b { d_rz(l / 2) b; CX a, b; d_rz(-l / 2) b; CX a, b; }\ngate d_crx(l) a, b { d_p(pi / 2) b; CX a, b; U(-l / 2, 0, 0) b; CX a, b; U(l / 2, -pi / 2, 0) b; }\ngate d_cry(l) a, b { d_ry(l / 2) b; CX a, b; d_ry(-l / 2) b; CX a, b; }\ngate d_cu(t, f, l, g) a, b { d_p(g) a; d_p((l + f) / 2) a; d_p((l - f) / 2) b; CX a, b; U(-t / 2, 0, -(f + l) / 2) b; CX a, b; U(t / 2, f, 0) b; }\ngate d_swap a, b { CX a, b; CX b, a; CX a, b; }\ngate d_iswap a, b { d_s a; d_s b; d_h a; CX a, b; CX b, a; d_h b; }\ngate d_rzz(t) a, b { CX a, b; d_rz(t) b; CX a, b; }\ngate d_rxx(t) a, b { d_h a; d_h b; d_rzz(t) a, b; d_h a; d_h b; }\ngate d_ryy(t) a, b { d_rx(pi / 2) a; d_rx(pi / 2) b; d_rzz(t) a, b; d_rx(-pi / 2) a; d_rx(-pi / 2) b; }\ngate d_ccx a, b, c { d_h c; CX b, c; d_tdg c; CX a, c; d_t c; CX b, c; d_tdg c; CX a, c; d_t b; d_t c; d_h c; CX a, b; d_t a; d_tdg b; CX a, b; }\ngate d_ccz a, b, c { d_h c; d_ccx a, b, c; d_h c; }\ngate d_cswap a, b, c { CX c, b; d_ccx a, b, c; CX c, b; }\nqubit[3] q;\nU(0.31, 0.72, -0.4) q[0];\nU(1.13, -0.25, 0.9) q[1];\nU(2.07, 0.5, 0.33) q[2];\nCX q[0], q[1];\nCX q[1], q[2];\nU(0.6, 1.1, -0.7) q[0];\nd_x q[0];\nd_y q[1];\nd_z q[2];\nd_h q[0];\nd_s q[1];\nd_sdg q[2];\nd_t q[0];\nd_tdg q[1];\nd_sx q[2];\nd_sxdg q[0];\nd_rx(0.41) q[1];\nd_ry(-1.3) q[2];\nd_rz(0.77) q[0];\nd_p(1.9) q[1];\nd_p(0.2) q[2];\nd_p(-0.6) q[0];\nU(pi / 2, 0.3, -1.2) q[1];\nU(0.8, 0.1, 2.2) q[2];\nU(1.4, -0.9, 0.35) q[0];\nCX q[0], q[1];\nCX q[2], q[0];\nd_cy q[1], q[2];\nd_cz q[2], q[0];\nd_ch q[0], q[2];\nd_cp(0.9) q[1], q[0];\nd_cp(-1.1) q[2], q[1];\nd_crx(0.6) q[0], q[1];\nd_cry(-0.8) q[1], q[2];\nd_crz(1.7) q[2], q[0];\nd_cu(0.5, 0.25, -0.75, 0.4) q[0], q[2];\nd_swap q[1], q[2];\nd_iswap q[0], q[1];\nd_rxx(0.45) q[1], q[2];\nd_ryy(-0.65) q[0], q[2];\nd_rzz(1.25) q[0], q[1];\nd_ccx q[0], q[1], q[2];\nd_ccz q[2], q[0], q[1];\nd_cswap q[1], q[2], q[0];\n"
|
|
},
|
|
{
|
|
"file": "lang/aliases.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[6] q;\nqubit r;\nlet evens = q[0:2:5];\nlet tail = q[-2:] ++ r;\nh evens;\nx tail;\ncx q[{1, 3}], q[{2, 4}];\n",
|
|
"expect": {
|
|
"equivalent": "lang/aliases.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[6] q;\nqubit r;\nh q[0];\nh q[2];\nh q[4];\nx q[4];\nx q[5];\nx r;\ncx q[1], q[2];\ncx q[3], q[4];\n"
|
|
},
|
|
{
|
|
"file": "lang/physical.qasm",
|
|
"qasm": "OPENQASM 3.1;\nh $0;\ncx $0, $1;\nrz(0.2) $2;\n",
|
|
"expect": {
|
|
"equivalent": "lang/physical.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[3] q;\nh q[0];\ncx q[0], q[1];\nrz(0.2) q[2];\n"
|
|
},
|
|
{
|
|
"file": "lang/gphase.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[2] q;\nh q;\ngphase(0.3);\nctrl @ gphase(0.7) q[0];\nnegctrl @ gphase(0.2) q[1];\n",
|
|
"expect": {
|
|
"equivalent": "lang/gphase.ref.qasm"
|
|
},
|
|
"reference_qasm": "OPENQASM 3.1;\nqubit[2] q;\nh q;\np(0.7) q[0];\nx q[1];\np(0.2) q[1];\nx q[1];\n"
|
|
},
|
|
{
|
|
"file": "lang/bits_known.qasm",
|
|
"qasm": "OPENQASM 3.1;\n// A bit register set by a constant is known until a measurement writes it.\nqubit[2] q;\nbit[2] b = \"10\";\nif (b == 2) x q[0];\nif (b[0]) x q[1];\nb = measure q;\n",
|
|
"expect": {
|
|
"deterministic": "01"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/generator.qasm",
|
|
"qasm": "OPENQASM 3.1;\ninput uint n;\nqubit[n] q;\nh q[0];\nfor uint i in [0:n-2] {\n cx q[i], q[i + 1];\n}\n",
|
|
"expect": {
|
|
"inputs": {
|
|
"n": 4
|
|
},
|
|
"distribution": {
|
|
"0000": 0.5,
|
|
"1111": 0.5
|
|
},
|
|
"exact": "ok"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/qasm2.qasm",
|
|
"qasm": "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[2];\ncreg c[2];\nu3(pi, 0, pi) q[0];\nu2(0, pi) q[1];\nu1(pi/2) q[1];\nCX q[0], q[1];\nmeasure q -> c;\n",
|
|
"expect": {
|
|
"distribution": {
|
|
"01": 0.5,
|
|
"11": 0.5
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/qasm2_if.qasm",
|
|
"qasm": "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[2];\ncreg c[2];\nx q[0];\nmeasure q -> c;\nif(c==1) x q[1];\nmeasure q[1] -> c[1];\n",
|
|
"expect": {
|
|
"deterministic": "11"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/exported.qasm",
|
|
"qasm": "OPENQASM 3.0;\ninclude \"stdgates.inc\";\ngate rzx(_gate_p_0) _gate_q_0, _gate_q_1 {\n h _gate_q_1;\n cx _gate_q_0, _gate_q_1;\n rz(_gate_p_0) _gate_q_1;\n cx _gate_q_0, _gate_q_1;\n h _gate_q_1;\n}\nbit[3] c;\nqubit[3] q;\nh q[0];\ncx q[0], q[1];\nrzx(1.5707963267948966) q[1], q[2];\nrzx(-1.5707963267948966) q[1], q[2];\ncx q[1], q[2];\nc[0] = measure q[0];\nc[1] = measure q[1];\nc[2] = measure q[2];\n",
|
|
"expect": {
|
|
"distribution": {
|
|
"000": 0.5,
|
|
"111": 0.5
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/refuse_root.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit q;\npow(0.5) @ U(0.1, 0.2, 0.3) q;\n",
|
|
"expect": {
|
|
"refused": "Q205"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/refuse_extern.qasm",
|
|
"qasm": "OPENQASM 3.1;\nextern f(int) -> int;\nqubit q;\nrz(f(1)) q;\n",
|
|
"expect": {
|
|
"refused": "Q125"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/refuse_runtime.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit q;\nbit c;\nc = measure q;\nint k = c;\n",
|
|
"expect": {
|
|
"refused": "Q306"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/refuse_durationof.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit q;\nduration d = durationof({ x q; });\n",
|
|
"expect": {
|
|
"refused": "Q405"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/refuse_opaque.qasm",
|
|
"qasm": "OPENQASM 2.0;\nqreg q[1];\nopaque g a;\ng q[0];\n",
|
|
"expect": {
|
|
"refused": "Q126"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/refuse_truncating.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit q;\nrz(1/2) q;\n",
|
|
"expect": {
|
|
"refused": "Q118"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/refuse_caret.qasm",
|
|
"qasm": "qubit q;\nrz(2 ^ 3) q;\n",
|
|
"expect": {
|
|
"refused": "Q119"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/refuse_unknown_gate.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit q;\nfoo q;\n",
|
|
"expect": {
|
|
"refused": "Q103"
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/exact_not_dyadic.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit q;\nh q;\nrz(pi / 3) q;\n",
|
|
"expect": {
|
|
"exact": "Q500",
|
|
"distribution": {
|
|
"0": 0.5,
|
|
"1": 0.5
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"file": "lang/exact_dynamic.qasm",
|
|
"qasm": "OPENQASM 3.1;\nqubit[2] q;\nbit c;\nh q[0];\nc = measure q[0];\nif (c) x q[1];\n",
|
|
"expect": {
|
|
"exact": "Q502"
|
|
}
|
|
}
|
|
]
|
|
}
|