aboutsummaryrefslogtreecommitdiff
path: root/tester/main.c
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-14 12:20:52 +0200
committerhachem <im@hachem.wtf>2026-09-14 12:20:52 +0200
commitee14ad272e68d9363202d7f668e0b20302827209 (patch)
tree88dd1012ad7f9d6ac7abeb7562dac2194794b823 /tester/main.c
parentae07aab1442a45bbddb79e066f15eaf252a4254a (diff)
feat: simd + testing + formatting
Diffstat (limited to 'tester/main.c')
-rw-r--r--tester/main.c265
1 files changed, 28 insertions, 237 deletions
diff --git a/tester/main.c b/tester/main.c
index 10d0b7d..c516568 100644
--- a/tester/main.c
+++ b/tester/main.c
@@ -1,250 +1,41 @@
#include <stdio.h>
-#include <stdlib.h>
+#include <string.h>
-#include "psi.h"
+#include "tests.h"
-int main(void)
+static bool has_arg(int argc, char** argv, const char* name)
{
- printf("psi %s\n", psi_version());
+ for (int i = 1; i < argc; i++)
+ if (strcmp(argv[i], name) == 0)
+ return true;
- struct PsiComplex a = psi_new_complex(1.0, 2.0);
- struct PsiComplex b = psi_new_complex(3.0, -1.0);
-
- struct PsiComplex sum = psi_add_complex(a, b);
- struct PsiComplex product = psi_mul_complex(a, b);
-
- printf("a = %g + %gi\n", a.real, a.imaginary);
- printf("b = %g + %gi\n", b.real, b.imaginary);
- printf("a + b = %g + %gi\n", sum.real, sum.imaginary);
- printf("a * b = %g + %gi\n", product.real, product.imaginary);
- printf("|a| = %g\n", psi_abs_complex(a));
-
- struct PsiVector u = psi_column_vector(
- psi_new_complex(1.0, 0.0),
- psi_new_complex(2.0, 0.0),
- psi_new_complex(3.0, 0.0));
- struct PsiVector v = psi_column_vector(
- psi_new_complex(4.0, 0.0),
- psi_new_complex(5.0, 0.0),
- psi_new_complex(6.0, 0.0));
-
- struct PsiComplex dot = psi_dot_vector(u, v);
- struct PsiComplex norm = psi_norm_vector(u);
-
- printf("u . v = %g + %gi\n", dot.real, dot.imaginary);
- printf("|u| = %g + %gi\n", norm.real, norm.imaginary);
-
- psi_free_vector(&u);
- psi_free_vector(&v);
-
- struct PsiMatrix m = psi_matrix(2, 2,
- psi_new_complex(1.0, 0.0), psi_new_complex(2.0, 0.0),
- psi_new_complex(3.0, 0.0), psi_new_complex(4.0, 0.0));
- struct PsiMatrix mm = psi_dot_matrix(m, m);
-
- printf("m*m = [%g %g; %g %g]\n",
- psi_get_matrix(mm, 0, 0).real, psi_get_matrix(mm, 0, 1).real,
- psi_get_matrix(mm, 1, 0).real, psi_get_matrix(mm, 1, 1).real);
-
- struct PsiVector x = psi_column_vector(
- psi_new_complex(1.0, 0.0),
- psi_new_complex(1.0, 0.0));
- struct PsiVector mx = psi_mul_vector_matrix(x, m);
-
- printf("m*x = [%g, %g]\n", mx.data[0].real, mx.data[1].real);
-
- psi_free_vector(&x);
- psi_free_vector(&mx);
- psi_free_matrix(&m);
- psi_free_matrix(&mm);
-
- double inv_sqrt2 = 0.7071067811865475;
- struct PsiMatrix h = psi_matrix(2, 2,
- psi_new_complex(inv_sqrt2, 0.0), psi_new_complex(inv_sqrt2, 0.0),
- psi_new_complex(inv_sqrt2, 0.0), psi_new_complex(-inv_sqrt2, 0.0));
- struct PsiQuantumGate gate = psi_new_quantum_gate_from_matrix("H", h);
-
- struct PsiVector s0 = psi_new_state_0();
- struct PsiVector hs0 = psi_mul_vector_matrix(s0, gate.matrix);
-
- printf("gate = %s (%zu qubit)\n", gate.name, gate.num_qubits);
- printf("H|0> = [%g, %g]\n", hs0.data[0].real, hs0.data[1].real);
-
- psi_free_vector(&s0);
- psi_free_vector(&hs0);
- psi_free_quantum_gate(&gate);
-
- const char *names[] = { "q0", "q1" };
- struct PsiQuantumRegister reg = psi_new_quantum_register("bell", names, 2);
-
- struct PsiQuantumGate hadamard = psi_hadamard_gate();
- struct PsiQuantumGate cnot = psi_cnot_gate();
-
- size_t t0[] = { 0 };
- size_t t01[] = { 0, 1 };
- psi_apply_gate(&reg, hadamard, t0, 1);
- psi_apply_gate(&reg, cnot, t01, 2);
-
- printf("bell = [%g, %g, %g, %g]\n",
- reg.state_vector.data[0].real, reg.state_vector.data[1].real,
- reg.state_vector.data[2].real, reg.state_vector.data[3].real);
-
- psi_free_quantum_gate(&hadamard);
- psi_free_quantum_gate(&cnot);
- psi_free_quantum_register(&reg);
-
- struct PsiCompositeGateOp bell_ops[] = {
- { PSI_OP_H, { 0 }, 1 },
- { PSI_OP_CNOT, { 0, 1 }, 2 },
- };
- struct PsiCustomGate bell = psi_new_custom_gate_from_composite("BELL", 2, bell_ops, 2);
- struct PsiQuantumGate bell_gate = psi_to_quantum_gate(bell);
-
- struct PsiQuantumRegister reg2 = psi_new_quantum_register("bell2", names, 2);
- size_t t01b[] = { 0, 1 };
- psi_apply_gate(&reg2, bell_gate, t01b, 2);
-
- printf("custom = %s -> [%g, %g, %g, %g]\n", bell_gate.name,
- reg2.state_vector.data[0].real, reg2.state_vector.data[1].real,
- reg2.state_vector.data[2].real, reg2.state_vector.data[3].real);
-
- psi_free_custom_gate(&bell);
- psi_free_quantum_gate(&bell_gate);
- psi_free_quantum_register(&reg2);
-
- const char *cnames[] = { "c0", "c1" };
- struct PsiClassicalRegister creg = psi_new_classical_register("c", cnames, 2);
- creg.bits[1].state = true;
-
- printf("creg = %s=%d %s=%d\n",
- creg.bits[0].name, creg.bits[0].state,
- creg.bits[1].name, creg.bits[1].state);
-
- psi_free_classical_register(&creg);
-
- struct PsiQuantumCircuit circuit = psi_new_quantum_circuit(3);
- psi_apply_h(&circuit, 0);
- psi_apply_cnot(&circuit, 0, 1);
- psi_apply_rx(&circuit, 2, 1.5707963267948966);
- psi_apply_ccnot(&circuit, 0, 1, 2);
-
- struct PsiCompositeGateOp cops[] = { { PSI_OP_X, { 0 }, 1 } };
- struct PsiCustomGate xg = psi_new_custom_gate_from_composite("MYX", 1, cops, 1);
- size_t ct[] = { 2 };
- psi_apply_custom(&circuit, xg, ct, 1);
-
- psi_measure_all(&circuit);
+ return false;
+}
- printf("circuit = %zu qubits, %zu classical, %zu ops\n",
- circuit.num_qubits, circuit.num_classical, circuit.operation_count);
- for (size_t i = 0; i < circuit.operation_count; i++)
+int main(int argc, char** argv)
+{
+ if (has_arg(argc, argv, "help") || has_arg(argc, argv, "--help") || has_arg(argc, argv, "-h"))
{
- size_t tc;
- const size_t *targets = psi_gate_op_quantum_targets(&circuit.operations[i], &tc);
- printf(" %zu: %s on", i, psi_gate_op_name(circuit.operations[i]));
- for (size_t j = 0; j < tc; j++)
- printf(" q%zu", targets[j]);
- printf("\n");
+ printf("Usage: tester [clifford|non-clifford|custom|kernels|simd|noise|all]\n");
+ return 0;
}
- psi_free_quantum_circuit(&circuit);
-
- size_t kt[] = { 0 };
- struct PsiKernelBatch batch = psi_new_kernel_batch(1);
- struct PsiQuantumGate hg = psi_hadamard_gate();
- psi_add_kernel(&batch, psi_new_kernel("H", psi_clone_matrix(hg.matrix), kt, 1));
- psi_add_kernel(&batch, psi_new_kernel("H", psi_clone_matrix(hg.matrix), kt, 1));
- psi_free_quantum_gate(&hg);
-
- size_t before = batch.count;
- psi_optimize_kernel_batch(&batch);
-
- struct PsiVector state = psi_new_state_0();
- psi_execute_kernel_batch(batch, &state);
-
- printf("kernels = %zu -> %zu (fused), HH|0> = [%g, %g]\n",
- before, batch.count, state.data[0].real, state.data[1].real);
-
- psi_free_vector(&state);
- psi_free_kernel_batch(&batch);
-
- struct PsiStructureAwareBatch sa = psi_new_structure_aware_batch(2);
- struct PsiQuantumGate hg2 = psi_hadamard_gate();
- struct PsiQuantumGate xg2 = psi_pauli_x_gate();
- size_t q0[] = { 0 };
- size_t q1[] = { 1 };
- psi_add_structure_aware_kernel(&sa, psi_new_kernel("H", psi_clone_matrix(hg2.matrix), q0, 1));
- psi_add_structure_aware_kernel(&sa, psi_new_kernel("X", psi_clone_matrix(xg2.matrix), q1, 1));
- psi_add_structure_aware_kernel(&sa, psi_new_kernel("H", psi_clone_matrix(hg2.matrix), q0, 1));
- psi_free_quantum_gate(&hg2);
- psi_free_quantum_gate(&xg2);
-
- psi_optimize_structure_aware_batch(&sa);
- struct PsiKernelStats stats = psi_structure_aware_batch_stats(sa);
-
- struct PsiQuantumRegister r = psi_new_quantum_register("r", names, 2);
- struct PsiVector sast = psi_clone_vector(r.state_vector);
- psi_free_quantum_register(&r);
- psi_execute_structure_aware_batch_layered(sa, &sast);
+ bool all = argc < 2 || has_arg(argc, argv, "all");
- printf("sa = %zu kernels, %zu layers -> [%g, %g, %g, %g]\n",
- stats.total_kernels, stats.execution_layers,
- sast.data[0].real, sast.data[1].real, sast.data[2].real, sast.data[3].real);
+ printf("psi %s test suite\n", psi_version());
- psi_free_vector(&sast);
- psi_free_structure_aware_batch(&sa);
+ if (all || has_arg(argc, argv, "clifford"))
+ run_clifford_tests();
+ if (all || has_arg(argc, argv, "non-clifford"))
+ run_non_clifford_tests();
+ if (all || has_arg(argc, argv, "custom"))
+ run_custom_tests();
+ if (all || has_arg(argc, argv, "kernels"))
+ run_kernel_tests();
+ if (all || has_arg(argc, argv, "simd"))
+ run_simd_tests();
+ if (all || has_arg(argc, argv, "noise"))
+ run_noise_tests();
- struct PsiQuantumCircuit ghz = psi_new_quantum_circuit(3);
- psi_apply_h(&ghz, 0);
- psi_apply_cnot(&ghz, 0, 1);
- psi_apply_cnot(&ghz, 1, 2);
-
- const struct PsiVector *ghz_state = psi_compute_circuit_with(&ghz, PSI_RUNTIME_STRUCTURE_AWARE);
- printf("ghz =");
- for (size_t i = 0; i < ghz_state->size; i++)
- printf(" %g", ghz_state->data[i].real);
- printf("\n");
-
- double probs[8];
- psi_circuit_probabilities(&ghz, probs);
- printf("p(000) = %g, p(111) = %g\n", probs[0], probs[7]);
-
- char abuf[64];
- char pbuf[64];
- printf("amp = |000> %s, p|111> %s\n",
- psi_format_amplitude(ghz_state->data[0], abuf, sizeof abuf),
- psi_format_probability(probs[7], pbuf, sizeof pbuf));
-
- psi_free_quantum_circuit(&ghz);
-
- struct PsiDensityMatrix dm = psi_new_density_matrix(1);
- printf("dm = purity %g (pure? %d)\n", psi_purity_density_matrix(dm), psi_is_pure_density_matrix(dm, 1e-10));
-
- struct PsiNoiseChannel bf = psi_bit_flip_channel(0.25);
- psi_apply_noise_channel(&dm, bf, 0);
-
- double dprobs[2];
- psi_density_matrix_probabilities(dm, dprobs);
- printf("noisy = p [%g, %g], purity %g\n", dprobs[0], dprobs[1], psi_purity_density_matrix(dm));
-
- psi_free_noise_channel(&bf);
- psi_free_density_matrix(&dm);
-
- struct PsiQuantumCircuit viz = psi_new_quantum_circuit(3);
- psi_apply_h(&viz, 0);
- psi_apply_cnot(&viz, 0, 1);
- psi_apply_rx(&viz, 2, 1.5707963267948966);
- psi_apply_ccnot(&viz, 0, 1, 2);
- psi_measure(&viz, 0, 0);
-
- char *diagram = psi_render_circuit_vertical(&viz);
- printf("\n%s\n", diagram);
- free(diagram);
-
- char *hdiagram = psi_render_circuit_horizontal(&viz);
- printf("%s\n", hdiagram);
- free(hdiagram);
-
- psi_free_quantum_circuit(&viz);
+ return psi_test_summary();
}
-