diff options
| author | hachem <im@hachem.wtf> | 2026-09-14 12:20:52 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-14 12:20:52 +0200 |
| commit | ee14ad272e68d9363202d7f668e0b20302827209 (patch) | |
| tree | 88dd1012ad7f9d6ac7abeb7562dac2194794b823 /tester/main.c | |
| parent | ae07aab1442a45bbddb79e066f15eaf252a4254a (diff) | |
feat: simd + testing + formatting
Diffstat (limited to 'tester/main.c')
| -rw-r--r-- | tester/main.c | 265 |
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(®, hadamard, t0, 1); - psi_apply_gate(®, 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(®); - - 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(®2, 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(®2); - - 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(); } - |
