aboutsummaryrefslogtreecommitdiff
path: root/src/core/runtime.c
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-10 20:20:14 +0200
committerhachem <im@hachem.wtf>2026-09-10 20:20:14 +0200
commit7e093e9726d7017943f5b9c45470a2acd9024d70 (patch)
treea4278203a826aba8ee1d3874e87dd84f7f36340c /src/core/runtime.c
parente75de99a233f446d7ee1d80d5b2af24e9edf822e (diff)
feat: rt execution engine and circuit compute
Diffstat (limited to 'src/core/runtime.c')
-rw-r--r--src/core/runtime.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/core/runtime.c b/src/core/runtime.c
new file mode 100644
index 0000000..0e5cf9d
--- /dev/null
+++ b/src/core/runtime.c
@@ -0,0 +1,201 @@
+#include "core/runtime.h"
+
+#include "core/custom_gate.h"
+#include "core/gates.h"
+#include "core/kernel.h"
+#include "maths/complex.h"
+
+struct PsiRuntimeConfig psi_new_runtime_config(void)
+{
+ struct PsiRuntimeConfig config;
+ config.parallel = false;
+ config.simd = false;
+ config.batched = false;
+ config.structure_aware = false;
+ config.parallel_threshold = PSI_PARALLEL_THRESHOLD;
+
+ return config;
+}
+
+struct PsiRuntimeConfig psi_optimal_runtime_config(void)
+{
+ struct PsiRuntimeConfig config = psi_new_runtime_config();
+ config.structure_aware = true;
+ config.simd = true;
+ config.parallel = true;
+
+ return config;
+}
+
+struct PsiRuntimeConfig psi_runtime_to_config(enum PsiRuntime runtime)
+{
+ struct PsiRuntimeConfig config = psi_new_runtime_config();
+
+ switch (runtime)
+ {
+ case PSI_RUNTIME_BASIC:
+ break;
+ case PSI_RUNTIME_BASIC_MT:
+ config.parallel = true;
+ break;
+ case PSI_RUNTIME_BATCHED:
+ config.batched = true;
+ break;
+ case PSI_RUNTIME_BATCHED_MT:
+ config.batched = true;
+ config.parallel = true;
+ break;
+ case PSI_RUNTIME_SIMD:
+ config.batched = true;
+ config.simd = true;
+ break;
+ case PSI_RUNTIME_SIMD_MT:
+ config.batched = true;
+ config.simd = true;
+ config.parallel = true;
+ break;
+ case PSI_RUNTIME_STRUCTURE_AWARE:
+ config.structure_aware = true;
+ config.simd = true;
+ break;
+ case PSI_RUNTIME_STRUCTURE_AWARE_MT:
+ config.structure_aware = true;
+ config.simd = true;
+ config.parallel = true;
+ break;
+ }
+
+ return config;
+}
+
+static bool op_to_kernel(struct PsiGateOp op, struct PsiKernel *out)
+{
+ struct PsiMatrix matrix;
+ const char *name;
+
+ switch (op.kind)
+ {
+ case PSI_GATE_H: matrix = psi_hadamard_gate().matrix; name = "H"; break;
+ case PSI_GATE_X: matrix = psi_pauli_x_gate().matrix; name = "X"; break;
+ case PSI_GATE_Y: matrix = psi_pauli_y_gate().matrix; name = "Y"; break;
+ case PSI_GATE_Z: matrix = psi_pauli_z_gate().matrix; name = "Z"; break;
+ case PSI_GATE_S: matrix = psi_s_gate().matrix; name = "S"; break;
+ case PSI_GATE_T: matrix = psi_t_gate().matrix; name = "T"; break;
+ case PSI_GATE_SDG: matrix = psi_sdg_gate().matrix; name = "Sdg"; break;
+ case PSI_GATE_TDG: matrix = psi_tdg_gate().matrix; name = "Tdg"; break;
+ case PSI_GATE_SX: matrix = psi_sx_gate().matrix; name = "Sx"; break;
+ case PSI_GATE_SXDG: matrix = psi_sxdg_gate().matrix; name = "Sxdg"; break;
+ case PSI_GATE_RX: matrix = psi_rx_matrix(op.params[0]); name = "Rx"; break;
+ case PSI_GATE_RY: matrix = psi_ry_matrix(op.params[0]); name = "Ry"; break;
+ case PSI_GATE_RZ: matrix = psi_rz_matrix(op.params[0]); name = "Rz"; break;
+ case PSI_GATE_P: matrix = psi_p_matrix(op.params[0]); name = "P"; break;
+ case PSI_GATE_U1: matrix = psi_u1_matrix(op.params[0]); name = "U1"; break;
+ case PSI_GATE_U2: matrix = psi_u2_matrix(op.params[0], op.params[1]); name = "U2"; break;
+ case PSI_GATE_U3: matrix = psi_u3_matrix(op.params[0], op.params[1], op.params[2]); name = "U3"; break;
+ case PSI_GATE_CNOT: matrix = psi_cnot_gate().matrix; name = "CNOT"; break;
+ case PSI_GATE_CZ: matrix = psi_cz_gate().matrix; name = "CZ"; break;
+ case PSI_GATE_SWAP: matrix = psi_swap_gate().matrix; name = "SWAP"; break;
+ case PSI_GATE_CRX: matrix = psi_crx_matrix(op.params[0]); name = "CRx"; break;
+ case PSI_GATE_CRY: matrix = psi_cry_matrix(op.params[0]); name = "CRy"; break;
+ case PSI_GATE_CRZ: matrix = psi_crz_matrix(op.params[0]); name = "CRz"; break;
+ case PSI_GATE_CP: matrix = psi_cp_matrix(op.params[0]); name = "CP"; break;
+ case PSI_GATE_CCNOT: matrix = psi_toffoli_gate().matrix; name = "CCNOT"; break;
+ case PSI_GATE_CSWAP: matrix = psi_fredkin_gate().matrix; name = "CSWAP"; break;
+ case PSI_GATE_MEASURE: return false;
+ case PSI_GATE_CUSTOM: matrix = psi_to_quantum_gate(*op.custom).matrix; name = "Custom"; break;
+ }
+
+ size_t target_count;
+ const size_t *targets = psi_gate_op_quantum_targets(&op, &target_count);
+ *out = psi_new_kernel(name, matrix, targets, target_count);
+
+ return true;
+}
+
+static struct PsiVector new_zero_state(size_t num_qubits)
+{
+ size_t dim = (size_t)1 << num_qubits;
+ struct PsiVector state = psi_new_vector(dim, PSI_COLUMN_VECTOR);
+ state.data[0] = psi_new_complex(1.0, 0.0);
+
+ return state;
+}
+
+struct PsiVector psi_compute_runtime_config(struct PsiRuntimeConfig config, size_t num_qubits, const struct PsiGateOp *operations, size_t op_count)
+{
+ struct PsiVector state = new_zero_state(num_qubits);
+
+ if (config.structure_aware)
+ {
+ struct PsiStructureAwareBatch batch = psi_new_structure_aware_batch(num_qubits);
+ for (size_t i = 0; i < op_count; i++)
+ {
+ struct PsiKernel kernel;
+ if (op_to_kernel(operations[i], &kernel))
+ psi_add_structure_aware_kernel(&batch, kernel);
+ }
+
+ psi_optimize_structure_aware_batch(&batch);
+ psi_execute_structure_aware_batch(batch, &state);
+ psi_free_structure_aware_batch(&batch);
+
+ return state;
+ }
+
+ struct PsiKernelBatch batch = psi_new_kernel_batch(num_qubits);
+ for (size_t i = 0; i < op_count; i++)
+ {
+ struct PsiKernel kernel;
+ if (op_to_kernel(operations[i], &kernel))
+ psi_add_kernel(&batch, kernel);
+ }
+
+ if (config.batched)
+ psi_optimize_kernel_batch(&batch);
+
+ psi_execute_kernel_batch(batch, &state);
+ psi_free_kernel_batch(&batch);
+
+ return state;
+}
+
+struct PsiVector psi_compute_runtime(enum PsiRuntime runtime, size_t num_qubits, const struct PsiGateOp *operations, size_t op_count)
+{
+ return psi_compute_runtime_config(psi_runtime_to_config(runtime), num_qubits, operations, op_count);
+}
+
+const struct PsiVector *psi_compute_circuit_with_config(struct PsiQuantumCircuit *circuit, struct PsiRuntimeConfig config)
+{
+ if (!circuit->is_computed)
+ {
+ psi_free_vector(&circuit->computed_state);
+ circuit->computed_state = psi_compute_runtime_config(config, circuit->num_qubits, circuit->operations, circuit->operation_count);
+ circuit->is_computed = true;
+ }
+
+ return &circuit->computed_state;
+}
+
+const struct PsiVector *psi_compute_circuit_with(struct PsiQuantumCircuit *circuit, enum PsiRuntime runtime)
+{
+ return psi_compute_circuit_with_config(circuit, psi_runtime_to_config(runtime));
+}
+
+const struct PsiVector *psi_compute_circuit(struct PsiQuantumCircuit *circuit)
+{
+ return psi_compute_circuit_with(circuit, PSI_RUNTIME_BASIC);
+}
+
+double psi_circuit_probability(struct PsiQuantumCircuit *circuit, size_t state_index)
+{
+ const struct PsiVector *state = psi_compute_circuit(circuit);
+ return psi_norm2_complex(state->data[state_index]);
+}
+
+void psi_circuit_probabilities(struct PsiQuantumCircuit *circuit, double *out)
+{
+ const struct PsiVector *state = psi_compute_circuit(circuit);
+ size_t dim = (size_t)1 << circuit->num_qubits;
+ for (size_t i = 0; i < dim; i++)
+ out[i] = psi_norm2_complex(state->data[i]);
+}