Skip to content

Commit

Permalink
rename aadd to evbdd
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastiaanbrand committed Aug 27, 2024
1 parent 8a11e2f commit abf6904
Show file tree
Hide file tree
Showing 38 changed files with 3,416 additions and 3,416 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![CI testing](https://github.com/sebastiaanbrand/q-sylvan/actions/workflows/cmake.yml/badge.svg)](https://github.com/sebastiaanbrand/q-sylvan/actions/workflows/cmake.yml)

Q-Sylvan extends the parallel decision diagram library [Sylvan](https://github.com/trolando/sylvan) (v1.8.0) with QMDDs (i.e. multiplicative AADDs), as well as functionality to simulate quantum circuits. This is currently still a beta version.
Q-Sylvan extends the parallel decision diagram library [Sylvan](https://github.com/trolando/sylvan) (v1.8.0) with QMDDs (i.e. factored EVBDDs with complex edge weights), as well as functionality to simulate quantum circuits. This is currently still a beta version.


## Installation
Expand Down
12 changes: 6 additions & 6 deletions docs/documentation/c_interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ NOTE: In the code we are refering to the QMDDs as QMDDs, but our QMDDs are reall
* `qmdd_cgate2(QMDD qmdd, gate_id_t gateid, int c1, int c2, int t)` : As above but with two controls (c1 < c2 < t).
* `qmdd_cgate3(QMDD qmdd, gate_id_t gateid, int c1, int c2, int c3, int t)` : As above but with three controls (c1 < c2 < c3 < t).
* `qmdd_cgate_range(QMDD qmdd, gate_id_t gateid , int c_first, int c_last, int t)` : Applies controlled-`gateid` to (t)arget, with all qubits between (and including) c_first and c_last as controls (c_first < c_last < t).
* `aadd_matvec_mult(QMDD mat, QMDD vec, int n)` : Computes mat|vec> for an 2^n vector and a 2^n x 2^n matrix.
* `aadd_matmat_mult(QMDD a, QMDD b, int)` : Computes a*b for two 2^n x 2^n matrices.
* `aadd_vec_tensor_prod(QMDD a, QMDD b, int nqubits_a)` : Computes a \tensor b for two vector QMDDs.
* `aadd_mat_tensor_prod(QMDD a, QMDD b, QMDD nqubits_a)` : Computes a \tensor b for two matrix QMDDs.
* `evbdd_matvec_mult(QMDD mat, QMDD vec, int n)` : Computes mat|vec> for an 2^n vector and a 2^n x 2^n matrix.
* `evbdd_matmat_mult(QMDD a, QMDD b, int)` : Computes a*b for two 2^n x 2^n matrices.
* `evbdd_vec_tensor_prod(QMDD a, QMDD b, int nqubits_a)` : Computes a \tensor b for two vector QMDDs.
* `evbdd_mat_tensor_prod(QMDD a, QMDD b, QMDD nqubits_a)` : Computes a \tensor b for two matrix QMDDs.

## Measurements and related
Note: For measurements, the post-measurement state is the return value of the measurement function, while the input qmdd is unaffected.
Expand Down Expand Up @@ -52,5 +52,5 @@ Note: For measurements, the post-measurement state is the return value of the me


## Other
* `aadd_countnodes(QMDD qmdd)` Counts the number of nodes in the given QMDD.
* `aadd_fprintdot(FILE *out, QMDD qmdd, bool draw_zeroes)` Writes a .dot representation of the given QMDD to the given file.
* `evbdd_countnodes(QMDD qmdd)` Counts the number of nodes in the given QMDD.
* `evbdd_fprintdot(FILE *out, QMDD qmdd, bool draw_zeroes)` Writes a .dot representation of the given QMDD to the given file.
6 changes: 3 additions & 3 deletions examples/alg_run.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ run_grover()

// Sanity checks on final state
// 1. Check flag probability (marginalize ancilla qubit out)
flag[qubits] = 0; AADD_WGT amp0 = aadd_getvalue(stats.final_qmdd, flag);
flag[qubits] = 1; AADD_WGT amp1 = aadd_getvalue(stats.final_qmdd, flag);
flag[qubits] = 0; EVBDD_WGT amp0 = evbdd_getvalue(stats.final_qmdd, flag);
flag[qubits] = 1; EVBDD_WGT amp1 = evbdd_getvalue(stats.final_qmdd, flag);
double flag_prob = qmdd_amp_to_prob(amp0) + qmdd_amp_to_prob(amp1);
INFO("Measure Grover flag with prob %lf\n", flag_prob);

Expand Down Expand Up @@ -306,7 +306,7 @@ int main(int argc, char **argv)
/* Some stats */
stats.final_magnitude = qmdd_get_magnitude(stats.final_qmdd, stats.nqubits);
INFO("Magnitude of final state: %.05lf\n", stats.final_magnitude);
stats.final_nodecount = aadd_countnodes(stats.final_qmdd);
stats.final_nodecount = evbdd_countnodes(stats.final_qmdd);
INFO("Final Nodecount: %" PRIu64 "\n", stats.final_nodecount);
if (csv_outputfile != NULL) {
INFO("Writing csv output to %s\n", csv_outputfile);
Expand Down
22 changes: 11 additions & 11 deletions examples/circuit_equivalence.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,18 @@ QMDD get_gate_matrix(quantum_op_t* gate, BDDVAR nqubits, bool dag) {
QMDD compute_UPUdag(quantum_circuit_t *circuit, gate_id_t P, BDDVAR k) {
BDDVAR nqubits = circuit->qreg_size;
QMDD circ_matrix = qmdd_create_single_qubit_gate(nqubits, k, P);
QMDD tmp = AADD_ZERO;
aadd_protect(&circ_matrix);
aadd_protect(&tmp);
QMDD tmp = EVBDD_ZERO;
evbdd_protect(&circ_matrix);
evbdd_protect(&tmp);

quantum_op_t *op = circuit->operations;
while (op != NULL) {
switch (op->type) {
case op_gate:
tmp = get_gate_matrix(op, nqubits, false);
circ_matrix = aadd_matmat_mult(tmp, circ_matrix, nqubits);
circ_matrix = evbdd_matmat_mult(tmp, circ_matrix, nqubits);
tmp = get_gate_matrix(op, nqubits, true);
circ_matrix = aadd_matmat_mult(circ_matrix, tmp, nqubits);
circ_matrix = evbdd_matmat_mult(circ_matrix, tmp, nqubits);
break;
case op_measurement:
fprintf(stderr, "ERROR: Measurments not supported\n");
Expand All @@ -212,8 +212,8 @@ QMDD compute_UPUdag(quantum_circuit_t *circuit, gate_id_t P, BDDVAR k) {
op = op->next;
}

aadd_unprotect(&circ_matrix);
aadd_unprotect(&tmp);
evbdd_unprotect(&circ_matrix);
evbdd_unprotect(&tmp);

return circ_matrix;
}
Expand All @@ -236,13 +236,13 @@ QMDD compute_UPUdag(quantum_circuit_t *circuit, gate_id_t P, BDDVAR k) {
for (BDDVAR k = 0; k < nqubits; k++) {
for (int i = 0; i < 2; i++) {
QMDD qmdd_U = compute_UPUdag(U, XZ[i], k);
aadd_protect(&qmdd_U);
evbdd_protect(&qmdd_U);
QMDD qmdd_V = compute_UPUdag(V, XZ[i], k);
aadd_unprotect(&qmdd_U);
evbdd_unprotect(&qmdd_U);

if (count_nodes) {
size_t nodes_U = aadd_countnodes(qmdd_U);
size_t nodes_V = aadd_countnodes(qmdd_V);
size_t nodes_U = evbdd_countnodes(qmdd_U);
size_t nodes_V = evbdd_countnodes(qmdd_V);
stats.max_nodes_total = max(stats.max_nodes_total,nodes_U+nodes_V);
stats.max_nodes_U = max(stats.max_nodes_U, nodes_U);
stats.max_nodes_V = max(stats.max_nodes_V, nodes_V);
Expand Down
52 changes: 26 additions & 26 deletions examples/grover.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,75 +115,75 @@ QMDD qmdd_grover_matrix_multi_its(BDDVAR n, bool *flag, int t, QMDD *matrix)

// H on all qubits
all_H = qmdd_create_single_qubit_gates_same(nqubits, GATEID_H);
aadd_protect(&all_H);
evbdd_protect(&all_H);

// H on first n qubits (all qubits except ancilla)
for (BDDVAR k = 0; k < n; k++) gate_list[k] = GATEID_H;
gate_list[n] = GATEID_I;
first_n_H = qmdd_create_single_qubit_gates(nqubits, gate_list);
aadd_protect(&first_n_H);
evbdd_protect(&first_n_H);

// oracle
for (BDDVAR k = 0; k < n; k++) cgate_options[k] = flag[k];
cgate_options[n] = 2; // ancilla qubit is target qubit of this multi-cgate
oracle = qmdd_create_multi_cgate(nqubits, cgate_options, GATEID_X);
aadd_protect(&oracle);
evbdd_protect(&oracle);

// X on first n qubits (all qubits except ancilla)
for (BDDVAR k = 0; k < n; k++) gate_list[k] = GATEID_X;
gate_list[n] = GATEID_I;
first_n_X = qmdd_create_single_qubit_gates(nqubits, gate_list);
aadd_protect(&first_n_X);
evbdd_protect(&first_n_X);

// CZ gate on all qubits except ancilla
for (BDDVAR k = 0; k < n-1; k++) cgate_options[k] = 1; // controls"
cgate_options[n-1] = 2; // target last qubit before ancilla
cgate_options[n] = -1; // do nothing to ancilla
first_n_CZ = qmdd_create_multi_cgate(nqubits, cgate_options, GATEID_Z);
aadd_protect(&first_n_CZ);
evbdd_protect(&first_n_CZ);

// Grover iteration = oracle + mean inversion
grov_it = oracle;
aadd_protect(&grov_it);
grov_it = aadd_matmat_mult(first_n_H, grov_it, nqubits);
grov_it = aadd_matmat_mult(first_n_X, grov_it, nqubits);
grov_it = aadd_matmat_mult(first_n_CZ, grov_it, nqubits);
grov_it = aadd_matmat_mult(first_n_X, grov_it, nqubits);
grov_it = aadd_matmat_mult(first_n_H, grov_it, nqubits);
evbdd_protect(&grov_it);
grov_it = evbdd_matmat_mult(first_n_H, grov_it, nqubits);
grov_it = evbdd_matmat_mult(first_n_X, grov_it, nqubits);
grov_it = evbdd_matmat_mult(first_n_CZ, grov_it, nqubits);
grov_it = evbdd_matmat_mult(first_n_X, grov_it, nqubits);
grov_it = evbdd_matmat_mult(first_n_H, grov_it, nqubits);

// Compute grov_it^t (by squaring if t is a power of 2)
grov_its = grov_it;
aadd_protect(&grov_its);
evbdd_protect(&grov_its);
if (EXP_BY_SQUARING && ((t & (t - 1)) == 0)) {
for (int i = 0; i < log2l(t); i++) {
grov_its = aadd_matmat_mult(grov_its, grov_its, nqubits);
grov_its = evbdd_matmat_mult(grov_its, grov_its, nqubits);
}
}
else {
for (int i = 1; i < t; i++) {
grov_its = aadd_matmat_mult(grov_its, grov_it, nqubits);
grov_its = evbdd_matmat_mult(grov_its, grov_it, nqubits);
}
}
R = R / t;
*matrix = grov_its; // return for nodecount in bench

aadd_unprotect(&first_n_H);
aadd_unprotect(&first_n_X);
aadd_unprotect(&first_n_CZ);
aadd_unprotect(&oracle);
aadd_unprotect(&grov_it);
evbdd_unprotect(&first_n_H);
evbdd_unprotect(&first_n_X);
evbdd_unprotect(&first_n_CZ);
evbdd_unprotect(&oracle);
evbdd_unprotect(&grov_it);

// Now, actually apply the circuit:
// 1. Start with all zero state + ancilla: |000...0>|1>
bool *init = malloc( sizeof(bool)*(nqubits) );
for (BDDVAR k = 0; k < n; k++) init[k] = 0;
init[n] = 1;
state = qmdd_create_basis_state(nqubits, init);
aadd_protect(&state);
evbdd_protect(&state);

// 2. H on all qubits
state = aadd_matvec_mult(all_H, state, nqubits);
aadd_unprotect(&all_H);
state = evbdd_matvec_mult(all_H, state, nqubits);
evbdd_unprotect(&all_H);

// 3. Grover iterations
if (VERBOSE) {
Expand All @@ -198,19 +198,19 @@ QMDD qmdd_grover_matrix_multi_its(BDDVAR n, bool *flag, int t, QMDD *matrix)
}

// gc edge wegith table
aadd_gc_wgt_table();
evbdd_gc_wgt_table();

// gc node table
sylvan_gc();
}
state = aadd_matvec_mult(grov_its, state, nqubits);
state = evbdd_matvec_mult(grov_its, state, nqubits);
}
if (VERBOSE) {
printf("\rGrover progress %lf%%\n", 100.);
}

aadd_unprotect(&grov_its);
aadd_unprotect(&state);
evbdd_unprotect(&grov_its);
evbdd_unprotect(&state);

free(init);
free(gate_list);
Expand Down
6 changes: 3 additions & 3 deletions examples/shor.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ qmdd_phi_add_mod(QMDD qmdd, BDDVAR c1, BDDVAR c2, uint64_t a, uint64_t N)
// are not parameterized on a)
sylvan_clear_cache();
shor_set_globals(a, N); // set bitvalues of a/N (N says the same though)
BDDVAR nc = AADD_INVALID_VAR; // no control
BDDVAR nc = EVBDD_INVALID_VAR; // no control

// 1. controlled(c1,c2) phi_add(a)
qmdd = qmdd_phi_add(qmdd, shor_wires.targ_first, shor_wires.targ_last, c1, c2, shor_bits_a);
Expand Down Expand Up @@ -141,7 +141,7 @@ qmdd_phi_add_mod_inv(QMDD qmdd, BDDVAR c1, BDDVAR c2, uint64_t a, uint64_t N)
// are not parameterized on a)
sylvan_clear_cache();
shor_set_globals(a, N); // set bitvalues of a/N (N says the same though)
BDDVAR nc = AADD_INVALID_VAR; // no control
BDDVAR nc = EVBDD_INVALID_VAR; // no control

// 13. controlled(c1,c2) phi_add_inv(a)
qmdd = qmdd_phi_add_inv(qmdd, shor_wires.targ_first, shor_wires.targ_last, c1, c2, shor_bits_a);
Expand Down Expand Up @@ -187,7 +187,7 @@ qmdd_cmult(QMDD qmdd, uint64_t a, uint64_t N)

// 2. loop over k = {0, n-1}
uint64_t t = a;
//BDDVAR cs[] = {shor_wires.top, AADD_INVALID_VAR, AADD_INVALID_VAR};
//BDDVAR cs[] = {shor_wires.top, EVBDD_INVALID_VAR, EVBDD_INVALID_VAR};
for (BDDVAR c2 = shor_wires.ctrl_last; c2 >= shor_wires.ctrl_first; c2--) {
// 2a. double controlled phi_add_mod(a* 2^k)
qmdd = qmdd_phi_add_mod(qmdd, shor_wires.top, c2, t, N);
Expand Down
Loading

0 comments on commit abf6904

Please sign in to comment.