Skip to content

Commit

Permalink
Add OpenQASM support (XAMPPRocky#1041)
Browse files Browse the repository at this point in the history
  • Loading branch information
mtreinish authored and ErikSchierboom committed Jun 7, 2024
1 parent 52df651 commit d076c9d
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ ObjectiveC
ObjectiveCpp
OCaml
Odin
OpenQASM
Org
Oz
Pascal
Expand Down
6 changes: 6 additions & 0 deletions languages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,12 @@
"quotes": [["\\\"","\\\""], ["`", "`"]],
"extensions": ["rego"]
},
"OpenQasm": {
"name": "OpenQASM",
"line_comment": ["//"],
"multi_line_comments": [["/*", "*/"]],
"extensions": ["qasm"]
},
"OpenType": {
"name": "OpenType Feature File",
"line_comment": ["#"],
Expand Down
89 changes: 89 additions & 0 deletions tests/data/vqe.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// 89 lines 58 code 21 comments 10 blanks
/*
* Variational eigensolver example
*
* Goal is to estimate the energy for a fixed set of parameters.
* The parameters are updated outside of this program and a new
* OpenQASM circuit is generated for the next iteration.
*/
include "stdgates.inc";

const int[32] n = 10; // number of qubits
const int[32] layers = 3; // number of entangler layers
const int[32] prec = 16; // precision of all types
const int[32] shots = 1000; // number of shots per Pauli observable

// Parameters could be written to local variables for this
// iteration, but we will request them using extern functions
extern get_parameter(uint[prec], uint[prec]) -> angle[prec];
extern get_npaulis() -> uint[prec];
extern get_pauli(int[prec]) -> bit[2 * n];

// The energy calculation uses floating point division,
// so we do that calculation in an extern function
extern update_energy(int[prec], uint[prec], float[prec]) -> float[prec];

gate entangler q { for uint i in [0:n-2] { cx q[i], q[i+1]; } }
def xmeasure(qubit q) -> bit { h q; return measure q; }
def ymeasure(qubit q) -> bit { s q; h q; return measure q; }

/* Pauli measurement circuit.
* The first n-bits of spec are the X component.
* The second n-bits of spec are the Z component.
*/
def pauli_measurement(bit[2*n] spec, qubit[n] q) -> bit {
bit b = 0;
for uint[prec] i in [0: n - 1] {
bit temp;
if(spec[i]==1 && spec[n+i]==0) { temp = xmeasure(q[i]); }
if(spec[i]==0 && spec[n+i]==1) { temp = measure q[i]; }
if(spec[i]==1 && spec[n+i]==1) { temp = ymeasure(q[i]); }
b ^= temp;
}
return b;
}

// Circuit to prepare trial wave function
def trial_circuit(qubit[n] q) {
for int[prec] l in [0: layers - 1] {
for uint[prec] i in [0: n - 1] {
angle[prec] theta;
theta = get_parameter(l * layers + i);
ry(theta) q[i];
}
if(l != layers - 1) entangler q;
}
}

/* Apply VQE ansatz circuit and measure a Pauli operator
* given by spec. Return the number of 1 outcomes.
*/
def counts_for_term(bit[2*n] spec, qubit[n] q) -> uint[prec] {
uint[prec] counts;
for uint i in [1: shots] {
bit b;
reset q;
trial_circuit q;
b = pauli_measurement(spec, q);
counts += int[1](b);
}
return counts;
}

// Estimate the expected energy
def estimate_energy(qubit[n] q) -> float[prec] {
float[prec] energy;
uint[prec] npaulis = get_npaulis();
for int[prec] t in [0:npaulis-1] {
bit[2*n] spec = get_pauli(t);
uint[prec] counts;
counts = counts_for_term(spec, q);
energy = update_energy(t, counts, energy);
}
return energy;
}

qubit[n] q;
float[prec] energy;

energy = estimate_energy(q);

0 comments on commit d076c9d

Please sign in to comment.