Overview
SansqritPy is a Python package and DSL runtime for quantum programming. The language focuses on concise scientific syntax while the runtime provides sparse simulation, sharded sparse maps, hierarchical tensor shards, MPS bridge mode, stabilizer simulation, density/noise workflows, QEC helpers, hardware export adapters, diagnostics, and embedded AI training datasets.
What users should understand first
SansqritPy is not only a syntax wrapper. It is a planning layer that decides how a quantum program should be represented: exact sparse state, dense local block, sharded sparse partition, stabilizer tableau, tensor/MPS bridge, density/noise model, hardware export, or distributed task. The same DSL code can therefore be taught to beginners while still exposing the simulation limits that scientists care about.
The most important rule is honesty about scale. A 120-qubit program is allowed as a logical program, but the runtime should never expand it into a full dense vector unless the problem is tiny. Instead, Sansqrit keeps structure visible and selects a backend that matches the circuit.
Animated React Architecture Diagrams
How the Execution Flow Works
Execution flow explained in plain language
When a user runs a .sq file, Sansqrit first reads the program like a compiler: it identifies registers, gate calls, shard declarations, bridge operations, measurements, and export commands. After parsing, the planner builds a qubit interaction graph. This graph is the key to backend choice because it shows whether the circuit is local, sparse, Clifford-only, low-entanglement, noisy, or suitable only for hardware export.
For students, this means the package can show why a small Bell circuit is simple but an arbitrary 120-qubit dense state is impossible. For researchers, it means the page documents where exactness is preserved, where tensor-network structure is assumed, and where an external provider or optional dependency is needed.
The core flow is: .sq source → lexer/parser → AST → runtime environment → auto planner → backend router → lookup/cache layer → sparse/sharded/MPS/stabilizer/density/GPU/distributed engine → measurement/export/logging. The planner checks qubit count, gate classes, non-Clifford use, expected amplitude growth, entanglement graph, block separability, lookup eligibility, optional GPU availability, distributed workers, and QEC/noise requirements.
Sansqrit source
→ parse / translate
→ analyze gates and qubit graph
→ engine("auto") chooses backend
→ lookup files loaded from sansqrit/data
→ execute sparse, sharded, MPS, stabilizer, density, GPU, or distributed
→ measure / export / profile / verify120-Qubit Dense-to-Multi-Split Design
How to read the 120-qubit diagram
The diagram below shows all missing data-flow links: source code enters the auto planner, the planner routes local gates into twelve independent 10-qubit shards, and a cross-shard operation such as CNOT(q[9], q[10]) is promoted into an MPS/tensor/sparse-global bridge. The bridge is the important scientific detail because it prevents the incorrect assumption that two entangled shards are still independent.
This model is beginner-friendly because each shard is small enough to explain as a 1024-amplitude local vector. It is also scientist-friendly because it clearly separates local exact dense kernels from cross-boundary correlation handling.
Sansqrit can represent a 120-qubit program as twelve 10-qubit blocks when the blocks are independent. Local gates inside a block can use dense 1024-amplitude vectors and embedded lookup transitions. When a cross-block gate appears, the runtime must preserve entanglement. Sansqrit therefore promotes bridge operations to MPS or sparse global updates instead of pretending the blocks remain independent.
Beginner view
Think of 120 qubits as twelve small notebooks. If you only write inside one notebook, it stays simple. When you draw a line from one notebook to another, Sansqrit records that relationship instead of flattening every page into one impossible giant notebook.
Scientist view
The backend preserves tensor separability for local sub-registers and introduces a bridge representation only when entangling gates cross block boundaries. This keeps local dynamics exact while making the entanglement boundary explicit.
Runtime view
Dense block kernels handle small 10-qubit vectors. Bridge gates request an MPS/tensor update or sparse-global fallback depending on circuit structure, cutoff, and backend plan.
simulate(120, engine="hierarchical", block_size=10, cutoff=0.0) {
q = quantum_register(120)
shard block_0 [0..9]
shard block_1 [10..19]
apply H on block_0
apply X on block_1
apply CNOT on q[9], q[10] bridge_mode=sparse
print(hierarchical_report())
}Dense 120-Qubit Reality
Precomputed Lookup Values
What lookup tables do and do not do
Lookup tables speed up repeated fixed gate operations by loading known matrices or embedded transitions from package data. They are useful for 1-qubit and 2-qubit gates, small independent blocks, examples, teaching material, and deterministic benchmarks.
They do not contain every possible circuit and they do not remove exponential scaling. Parameterized rotations, custom gates, large entangling circuits, or unsupported compositions safely fall back to runtime math or a different backend. This distinction is important for credibility.
The package ships lookup data files inside the wheel: static one-qubit matrices, static two-qubit matrices, and compressed embedded single-qubit transitions for all register sizes from 1 to 10 qubits. Runtime lookup selection uses the fastest safe option: full embedded transitions for independent blocks up to 10 qubits, matrix lookup for larger sparse states, generated block cache for repeated static sequences, and arithmetic fallback for parameterized gates.
from importlib.resources import files
for item in files("sansqrit").joinpath("data").iterdir():
print(item.name)Distributed Computing
Distributed execution in practical terms
The distributed layer is best understood as a coordinator-plus-workers model. The coordinator decides which shard owns which sparse entries, sends worker-local gate batches, collects measurement or diagnostic results, and coordinates shard exchange when a bridge gate crosses worker boundaries.
Distributed execution helps when the state is sparse or partitionable. It still cannot make an arbitrary dense 120-qubit vector easy, because dense growth increases communication and memory faster than workers can compensate.
The distributed layer supports capability detection, worker-local state commands, batched operations, compressed JSON payloads, checkpoint/restore hooks, and Ray/Dask/MPI planning. Correct sparse partitioning is preferred over mathematically unsafe splitting. Cross-worker gates require shard exchange or coordinator-mediated merge/apply/split depending on backend configuration.
GPU Backend Planning
The GPU layer exposes planning hooks for dense state-vector, tensor-network, and density-matrix acceleration. Optional CuPy/cuQuantum paths are detected by sansqrit gpu. For large 120-qubit dense states, GPU does not remove exponential scaling; for moderate dense blocks or tensor contractions, GPU planning can be valuable.
Quantum Error Correction
QEC explanation for new users
Quantum error correction protects logical information by encoding one logical qubit across multiple physical qubits. Sansqrit exposes this as logical-qubit helpers, code metadata, syndrome circuits, error injection, decoder hooks, and correction workflows. Students can see the encode → noise → syndrome → decode pattern, while advanced users can export or compare syndrome-oriented workflows.
The framework should be treated as an educational and research-oriented layer unless connected to calibrated hardware, realistic noise models, and validated decoders.
Sansqrit includes bit-flip, phase-flip, repetition code helpers, Shor 9-qubit, Steane 7-qubit, five-qubit code metadata, surface-code lattice helpers, syndrome extraction circuits, logical qubit abstraction, logical gates, decoder interface, Stim-style text export, and PyMatching-style adapter hooks.
simulate(9, engine="stabilizer") {
logical = qec_logical(code="shor9", base=0, name="satellite_link")
qec_encode(logical)
qec_inject_error(logical, "X", 3)
syndrome = qec_syndrome(logical)
qec_correct(logical, syndrome)
print(qec_syndrome_circuit(logical))
}Hardware Export
Export versus real hardware execution
Hardware export means Sansqrit can translate a circuit into a format understood by other ecosystems, such as OpenQASM, Qiskit, Cirq, Braket, Azure-style payloads, PennyLane, Stim, or CUDA-Q planning metadata. This is different from guaranteeing execution on a provider.
Actual cloud execution depends on provider credentials, installed SDKs, device availability, supported gate sets, qubit connectivity, transpilation constraints, queue time, pricing, and noise. The website now makes that distinction explicit so users do not confuse export adapters with a complete hardware compiler.
Circuits can be exported to OpenQASM 2, OpenQASM 3, Qiskit/IBM, Cirq, Amazon Braket, Azure-style OpenQASM 3 payloads, PennyLane, CUDA-Q planning metadata, Stim text, and PyMatching syndrome workflows. The exported hardware code remains a representation of the circuit; cloud execution requires provider credentials and SDK installation.
AI Training Dataset
Why the dataset is included
The package includes training and evaluation records so assistants or local models can learn the Sansqrit DSL, common backend choices, safety limitations, example patterns, and troubleshooting language. This is useful for building code-generation helpers, documentation search, tutorials, and automated examples.
Dataset records should still be validated before model training. Good practice includes schema checks, duplicate removal, execution checks for code examples, backend-label verification, and clear separation between teaching examples and production claims.
The wheel embeds supervised fine-tuning records, evaluation records, preference pairs, and 500 real-world scenario question-answer-code records. These are designed to teach AI models Sansqrit syntax, backend selection, dense-state safety, QEC workflows, hardware export patterns, and troubleshooting.
sansqrit dataset info
sansqrit dataset sample --split sft_train -n 5
sansqrit scenarios sample -n 5 --domain smart_grid
sansqrit dataset export --output ./sansqrit-training-exportDSL Syntax Summary
| Category | Syntax | Purpose |
|---|---|---|
| Simulation | simulate(n, engine="auto") { ... } | Create execution context |
| Register | q = quantum_register(120) | Allocate logical qubits |
| Gate | H(q[0]), CNOT(q[0], q[1]) | Apply quantum operations |
| Shard | shard block_A [0..9] | Name a 10-qubit local block |
| Block apply | apply H on block_A | Apply gate to a shard |
| Bridge | apply CNOT on q[9], q[10] bridge_mode=sparse | Cross-block entanglement safely |
| QEC | qec_logical(code="steane7") | Logical qubit abstraction |
| Export | export_hardware("braket") | Build provider payload |
| Diagnostics | lookup_profile() | Inspect lookup hits/fallbacks |
Python API Function and Class Index
| Symbol | Kind | Description |
|---|---|---|
sansqrit.algorithms.GroverResult | class | |
sansqrit.algorithms.OptimizationResult | class | |
sansqrit.algorithms.VQEResult | class | |
sansqrit.algorithms.QPEResult | class | |
sansqrit.algorithms.HHLResult | class | |
sansqrit.algorithms.qft(engine, qubits) | function | |
sansqrit.algorithms.iqft(engine, qubits) | function | |
sansqrit.algorithms.grover_search(n_qubits, target) | function | |
sansqrit.algorithms.grover_search_multi(n_qubits, targets) | function | |
sansqrit.algorithms.deutsch_jozsa(n_bits, oracle_type) | function | Return 'constant' or 'balanced' for reference oracle families. |
sansqrit.algorithms.bernstein_vazirani(secret) | function | |
sansqrit.algorithms.simon_algorithm(secret) | function | Educational placeholder returning the hidden XOR mask for a supplied oracle. |
sansqrit.algorithms.quantum_phase_estimation(phase, n_counting_qubits) | function | |
sansqrit.algorithms.qaoa_maxcut(n_nodes, edges) | function | |
sansqrit.algorithms.maxcut_value(bitstring, edges) | function | |
sansqrit.algorithms.vqe_h2(bond_length) | function | Tiny H2-like VQE toy model with a two-parameter ansatz. |
sansqrit.algorithms.amplitude_estimation(probability, n_eval_bits) | function | |
sansqrit.algorithms.quantum_counting(n_search_bits, n_solutions, n_counting_bits) | function | |
sansqrit.algorithms.swap_test(engine1, engine2) | function | |
sansqrit.algorithms.teleport(bit) | function | |
sansqrit.algorithms.superdense_coding(bit0, bit1) | function | |
sansqrit.algorithms.bb84_qkd(key_length) | function | |
sansqrit.algorithms.hhl_solve(a, b) | function | |
sansqrit.algorithms.shor_factor(n) | function | Small educational Shor-style factor fallback using classical order search. |
sansqrit.algorithms.variational_classifier(features, params) | function | |
sansqrit.architecture.MemoryEstimate | class | |
sansqrit.architecture.human_bytes(n) | function | |
sansqrit.architecture.dense_memory_estimate(qubits) | function | |
sansqrit.architecture.execution_flow_mermaid() | function | |
sansqrit.architecture.architecture_layers() | function | |
sansqrit.architecture.scenario_table() | function | |
sansqrit.architecture.explain_120_qubits_dense() | function | |
sansqrit.architecture.lookup_architecture() | function | |
sansqrit.architecture.package_positioning() | function | |
sansqrit.circuit.Circuit | class | A lightweight circuit that can be simulated or exported to QASM. |
sansqrit.cli.cmd_run(args) | function | |
sansqrit.cli.cmd_translate(args) | function | |
sansqrit.cli.cmd_qasm(args) | function | |
sansqrit.cli.cmd_examples(args) | function | |
sansqrit.cli.cmd_worker(args) | function | |
sansqrit.cli.cmd_verify(args) | function | |
sansqrit.cli.cmd_doctor(args) | function | |
sansqrit.cli.cmd_backends(args) | function | |
sansqrit.cli.cmd_estimate(args) | function | |
sansqrit.cli.cmd_architecture(args) | function | |
sansqrit.cli.cmd_troubleshoot(args) | function | |
sansqrit.cli.cmd_hardware(args) | function | |
sansqrit.cli.cmd_dataset(args) | function | |
sansqrit.cli.cmd_scenarios(args) | function | |
sansqrit.cli.cmd_plan(args) | function | |
sansqrit.cli.cmd_gpu(args) | function | |
sansqrit.cli.cmd_distributed_info(args) | function | |
sansqrit.cli.cmd_qec_plan(args) | function | |
sansqrit.cli.build_parser() | function | |
sansqrit.cli.main(argv) | function | |
sansqrit.cluster.encode_state(state) | function | |
sansqrit.cluster.decode_state(payload) | function | |
sansqrit.cluster.encode_compressed_payload(payload) | function | |
sansqrit.cluster.decode_compressed_payload(envelope) | function | |
sansqrit.cluster.serve_worker(host, port) | function | |
sansqrit.cluster.start_worker_in_thread(host, port) | function | |
sansqrit.cluster.WorkerClient | class | |
sansqrit.cluster.worker_capabilities(client) | function | |
sansqrit.cluster.distributed_capabilities() | function | |
sansqrit.cluster.DistributedSparseEngine | class | Multi-worker sparse engine with compressed transfers and batching. |
sansqrit.dataset.TrainingRecord | class | |
sansqrit.dataset.dataset_path(split) | function | Return the importlib resource path-like string for a packaged split. |
sansqrit.dataset.dataset_info() | function | Return the packaged dataset manifest. |
sansqrit.dataset.available_splits() | function | Return available packaged dataset split names. |
sansqrit.dataset.load_training_records(split) | function | Yield records from a packaged compressed JSONL split. |
sansqrit.dataset.export_dataset(output_dir) | function | Export packaged records to plain JSONL files. |
sansqrit.dataset.sample_records(split, n) | function | Return the first ``n`` records from a split. |
sansqrit.dataset.builtin_training_records() | function | Small in-memory seed records kept for backwards compatibility. |
sansqrit.dataset.generate_jsonl(path, records) | function | Write seed records or custom records to a plain JSONL file. |
sansqrit.dataset.examples_to_training_records(examples_dir) | function | |
sansqrit.density.DensityMatrixEngine | class | Sparse density matrix backend for small noisy simulations. |
sansqrit.diagnostics.BackendAvailability | class | |
sansqrit.diagnostics.optional_available(module) | function | |
sansqrit.diagnostics.backends() | function | |
sansqrit.diagnostics.doctor() | function | |
sansqrit.diagnostics.doctor_text() | function | |
sansqrit.diagnostics.configure_logging(level, path) | function | |
sansqrit.diagnostics.log_event(event) | function | |
sansqrit.diagnostics.troubleshoot(topic) | function | |
sansqrit.diagnostics.estimate(qubits) | function | |
sansqrit.dsl.translate(source) | function | Translate Sansqrit DSL source to Python source. |
sansqrit.dsl.run_code(source) | function | |
sansqrit.dsl.run_file(path) | function | |
sansqrit.engine.EngineConfig | class | |
sansqrit.engine.QuantumEngine | class | Sparse, sharded and optionally threaded state-vector simulator. |
sansqrit.engine.bell_state() | function | |
sansqrit.engine.ghz_state(n_qubits) | function | |
sansqrit.errors.SansqritError | class | Base exception for Sansqrit. |
sansqrit.errors.SansqritSyntaxError | class | Raised when Sansqrit source cannot be translated. |
sansqrit.errors.SansqritRuntimeError | class | Raised for DSL/runtime errors. |
sansqrit.errors.QuantumError | class | Raised for invalid quantum operations. |
sansqrit.gates.GateOp | class | An operation in a circuit or engine history. |
sansqrit.gates.canonical_gate_name(name) | function | |
sansqrit.gates.cis(theta) | function | |
sansqrit.gates.matrix_2x2(name, params) | function | Return a single-qubit unitary as (m00, m01, m10, m11). |
sansqrit.gates.controlled_matrix(single) | function | Controlled-U matrix with qubit order |control,target>. |
sansqrit.gates.matrix_4x4(name, params) | function | Return a two-qubit unitary in basis |q0 q1> = 00,01,10,11. |
sansqrit.gates.validate_gate_arity(name, qubits, params) | function | |
sansqrit.gates.gate_to_qasm2(name, qubits, params) | function | Export one operation to OpenQASM 2-ish qelib1 syntax. |
sansqrit.gates.flatten_qubits(args) | function | |
sansqrit.gpu.CuPyStateVectorEngine | class | Dense CuPy state-vector backend. |
sansqrit.gpu.gpu_capabilities() | function | Return optional GPU/cuQuantum capabilities without importing heavy SDKs eagerly. |
sansqrit.gpu.estimate_gpu_statevector_memory(n_qubits, bytes_per_amplitude, overhead) | function | |
sansqrit.gpu.CuQuantumAdapter | class | Lazy adapter for production cuQuantum integrations. |
sansqrit.hardware.HardwareTarget | class | |
sansqrit.hardware.hardware_targets() | function | |
sansqrit.hardware.export_for_hardware(circuit_or_engine, provider) | function | |
sansqrit.hardware.hardware_payload_summary(circuit_or_engine) | function | |
sansqrit.hierarchical.TensorShard | class | A fixed logical block in a hierarchical tensor simulation. |
sansqrit.hierarchical.HierarchicalReport | class | |
sansqrit.hierarchical.HierarchicalTensorEngine | class | Block-dense + MPS-bridge backend. |
sansqrit.hybrid.HybridRunReport | class | |
sansqrit.hybrid.HybridEngine | class | Factory-style hybrid backend. |
sansqrit.interop.to_qiskit(circuit) | function | Convert a Sansqrit Circuit to qiskit.QuantumCircuit if qiskit is installed. |
sansqrit.interop.to_cirq(circuit) | function | Convert a Sansqrit Circuit to cirq.Circuit if Cirq is installed. |
sansqrit.interop.to_braket(circuit) | function | Convert a Sansqrit Circuit to braket.circuits.Circuit if the Braket SDK is installed. |
sansqrit.interop.apply_to_pennylane(circuit) | function | Return a callable quantum function that applies a Sansqrit Circuit in PennyLane. |
sansqrit.lookup.packaged_metadata() | function | Return metadata for the lookup files bundled in the installed package. |
sansqrit.lookup.LookupTable | class | Lookup table facade used by engines. |
sansqrit.lookup.clear_lookup_caches() | function | |
sansqrit.mps.MPSEngine | class | Tensor-network/MPS simulator with SVD truncation. |
sansqrit.optimizer.OptimizationReport | class | |
sansqrit.optimizer.optimize_operations(operations) | function | Optimize a list of operations. |
sansqrit.optimizer.is_clifford_operation(op) | function | Return True for operations supported by the stabilizer backend. |
sansqrit.optimizer.is_clifford_circuit(operations) | function | |
sansqrit.planner.CircuitFeatures | class | |
sansqrit.planner.BackendPlan | class | |
sansqrit.planner.estimate_depth(n_qubits, operations) | function | |
sansqrit.planner.dense_memory_bytes(n_qubits, bytes_per_amplitude) | function | |
sansqrit.planner.density_memory_bytes(n_qubits, bytes_per_entry) | function | |
sansqrit.planner.analyze_features(n_qubits, operations) | function | |
sansqrit.planner.analyze_operations(n_qubits, operations) | function | |
sansqrit.planner.explain_backend_plan(n_qubits, operations) | function | |
sansqrit.planner.enforce_backend_selection(plan) | function | |
sansqrit.planner.estimate_dense_memory(n_qubits, bytes_per_amplitude) | function | |
sansqrit.planner.plan_from_gate_tuples(n_qubits, gates) | function | |
sansqrit.profiler.LookupProfile | class | |
sansqrit.qasm.export_qasm2(ops, n_qubits) | function | |
sansqrit.qasm.export_qasm3(ops, n_qubits) | function | |
sansqrit.qasm.Qasm3Builder | class | Small OpenQASM 3 builder for classical control, delays, barriers and pragmas. |
sansqrit.qasm.export_qasm3_advanced(ops, n_qubits) | function | |
sansqrit.qasm.qasm3_mid_circuit_template(n_qubits) | function | |
sansqrit.qec.StabilizerCode | class | Declarative stabilizer-code description. |
sansqrit.qec.LogicalQubit | class | Logical qubit mapped onto physical qubits for a selected QEC code. |
sansqrit.qec.Decoder | class | Interface for QEC decoders. |
sansqrit.qec.LookupDecoder | class | Table-driven decoder for small stabilizer codes. |
sansqrit.qec.RepetitionDecoder | class | Majority-style decoder for bit-flip, phase-flip and repetition codes. |
sansqrit.qec.SurfaceCodeLattice | class | Rotated planar surface-code helper lattice. |
sansqrit.qec.SurfaceCodeDecoder | class | Greedy surface-code decoder interface. |
sansqrit.qec.repetition_code(distance) | function | |
sansqrit.qec.surface_code(distance) | function | |
sansqrit.qec.get_code(name) | function | |
sansqrit.qec.list_codes() | function | |
sansqrit.qec.logical_qubit(code) | function | |
sansqrit.qec.apply_pauli_string(engine, term) | function | |
sansqrit.qec.encode(engine, logical) | function | Encode a logical |0> into the selected code when a simple encoder is known. |
sansqrit.qec.decode(engine, logical) | function | Inverse of the simple encoder when available. |
sansqrit.qec.syndrome_circuit(logical) | function | Return a syndrome-extraction circuit as operations. |
sansqrit.qec.measure_syndrome(engine, logical) | function | |
sansqrit.qec.default_decoder(code) | function | |
sansqrit.qec.single_error_lookup_table(code) | function | Generate a simple single-error syndrome lookup table. |
sansqrit.qec.correct(engine, logical, syndrome, decoder) | function | |
sansqrit.qec.logical_x(engine, logical) | function | |
sansqrit.qec.logical_z(engine, logical) | function | |
sansqrit.qec.logical_h(engine, logical) | function | |
sansqrit.qec.logical_s(engine, logical) | function | |
sansqrit.qec.logical_cnot(engine, control, target) | function | |
sansqrit.qec.inject_error(engine, logical, pauli, physical_offset) | function | |
sansqrit.qec.CorrectionResult | class | |
sansqrit.qec.syndrome_and_correct(engine, logical) | function | |
sansqrit.qec.PyMatchingSurfaceDecoder | class | Optional PyMatching-style decoder adapter. |
sansqrit.qec.qec_optional_features() | function | Return availability of optional QEC acceleration libraries. |
sansqrit.qec.syndrome_circuit_as_stim_text(logical) | function | Return a best-effort Stim-like text circuit for the syndrome extraction. |
sansqrit.qec.stim_surface_code_task(distance, rounds, after_clifford_depolarization) | function | Return a Stim surface-code memory experiment circuit when Stim is present. |
sansqrit.qec.DecodingReport | class | |
sansqrit.qec.pymatching_decode_surface(code, syndrome) | function | Decode a surface-code syndrome using PyMatching when possible. |
sansqrit.qec.qec_threshold_sweep_template(distances, physical_error_rates) | function | Return a JSON-safe threshold-sweep plan for external Stim/PyMatching runs. |
sansqrit.qec.logical_resource_estimate(algorithmic_logical_qubits, logical_depth) | function | Small resource-estimation helper inspired by cloud resource estimators. |
sansqrit.research.ResearchGap | class | |
sansqrit.research.research_gaps() | function | |
sansqrit.runtime.Pipeable | class | |
sansqrit.runtime.map(fn, seq) | function | |
sansqrit.runtime.filter(fn, seq) | function | |
sansqrit.runtime.reduce(fn, seq, initial) | function | |
sansqrit.runtime.sort(seq, reverse) | function | |
sansqrit.runtime.enumerate(seq) | function | |
sansqrit.runtime.zip(a, b) | function | |
sansqrit.runtime.sum(seq) | function | |
sansqrit.runtime.mean(seq) | function | |
sansqrit.runtime.range_step(start, stop, step) | function | |
sansqrit.runtime.read_file(path) | function | |
sansqrit.runtime.write_file(path, text) | function | |
sansqrit.runtime.read_json(path) | function | |
sansqrit.runtime.write_json(path, obj) | function | |
sansqrit.runtime.read_csv(path) | function | |
sansqrit.runtime.write_csv(path, rows) | function | |
sansqrit.runtime.simulate | class | |
sansqrit.runtime.current_engine() | function | |
sansqrit.runtime.quantum_register(n_qubits) | function | |
sansqrit.runtime.last_engine() | function | |
sansqrit.runtime.I(q) | function | |
sansqrit.runtime.X(q) | function | |
sansqrit.runtime.Y(q) | function | |
sansqrit.runtime.Z(q) | function | |
sansqrit.runtime.H(q) | function | |
sansqrit.runtime.S(q) | function | |
sansqrit.runtime.Sdg(q) | function | |
sansqrit.runtime.T(q) | function | |
sansqrit.runtime.Tdg(q) | function | |
sansqrit.runtime.SX(q) | function | |
sansqrit.runtime.SXdg(q) | function | |
sansqrit.runtime.Rx(q, theta) | function | |
sansqrit.runtime.Ry(q, theta) | function | |
sansqrit.runtime.Rz(q, theta) | function | |
sansqrit.runtime.Phase(q, theta) | function | |
sansqrit.runtime.U1(q, theta) | function | |
sansqrit.runtime.U2(q, phi, lam) | function | |
sansqrit.runtime.U3(q, theta, phi, lam) | function | |
sansqrit.runtime.CNOT(c, t) | function | |
sansqrit.runtime.CX(c, t) | function | |
sansqrit.runtime.CZ(c, t) | function | |
sansqrit.runtime.CY(c, t) | function | |
sansqrit.runtime.CH(c, t) | function | |
sansqrit.runtime.CSX(c, t) | function | |
sansqrit.runtime.SWAP(a, b) | function | |
sansqrit.runtime.iSWAP(a, b) | function | |
sansqrit.runtime.SqrtSWAP(a, b) | function | |
sansqrit.runtime.fSWAP(a, b) | function | |
sansqrit.runtime.DCX(a, b) | function | |
sansqrit.runtime.CRx(c, t, theta) | function | |
sansqrit.runtime.CRy(c, t, theta) | function | |
sansqrit.runtime.CRz(c, t, theta) | function | |
sansqrit.runtime.CP(c, t, theta) | function | |
sansqrit.runtime.CU(c, t, theta, phi, lam) | function | |
sansqrit.runtime.RXX(a, b, theta) | function | |
sansqrit.runtime.RYY(a, b, theta) | function | |
sansqrit.runtime.RZZ(a, b, theta) | function | |
sansqrit.runtime.RZX(a, b, theta) | function | |
sansqrit.runtime.ECR(a, b) | function | |
sansqrit.runtime.MS(a, b) | function | |
sansqrit.runtime.Toffoli(a, b, c) | function | |
sansqrit.runtime.CCX(a, b, c) | function | |
sansqrit.runtime.Fredkin(c, a, b) | function | |
sansqrit.runtime.CSWAP(c, a, b) | function | |
sansqrit.runtime.CCZ(a, b, c) | function | |
sansqrit.runtime.MCX() | function | |
sansqrit.runtime.MCZ() | function | |
sansqrit.runtime.C3X(a, b, c, t) | function | |
sansqrit.runtime.C4X(a, b, c, d, t) | function | |
sansqrit.runtime.H_all(qubits) | function | |
sansqrit.runtime.Rx_all(theta, qubits) | function | |
sansqrit.runtime.Ry_all(theta, qubits) | function | |
sansqrit.runtime.Rz_all(theta, qubits) | function | |
sansqrit.runtime.qft(q) | function | |
sansqrit.runtime.iqft(q) | function | |
sansqrit.runtime.measure(q) | function | |
sansqrit.runtime.measure_all(q, shots) | function | |
sansqrit.runtime.probabilities(q) | function | |
sansqrit.runtime.expectation_z(q) | function | |
sansqrit.runtime.expectation_zz(a, b) | function | |
sansqrit.runtime.engine_nnz() | function | |
sansqrit.runtime.export_qasm2(path) | function | |
sansqrit.runtime.export_qasm3(path) | function | |
sansqrit.runtime.shards() | function | |
sansqrit.runtime.ShardMapping | class | |
sansqrit.runtime.shard(name, start, end) | function | |
sansqrit.runtime.apply_block(gate, block) | function | |
sansqrit.runtime.hierarchical_report() | function | |
sansqrit.runtime.noise_depolarize(q, p) | function | |
sansqrit.runtime.noise_bit_flip(q, p) | function | |
sansqrit.runtime.noise_phase_flip(q, p) | function | |
sansqrit.runtime.noise_amplitude_damping(q, gamma) | function | |
sansqrit.runtime.optimize_circuit(circuit) | function | |
sansqrit.runtime.verify_circuit(circuit) | function | |
sansqrit.runtime.to_qiskit(circuit) | function | |
sansqrit.runtime.to_cirq(circuit) | function | |
sansqrit.runtime.to_braket(circuit) | function | |
sansqrit.runtime.to_pennylane(circuit) | function | |
sansqrit.runtime.make_globals() | function | |
sansqrit.runtime.qec_code(name, distance) | function | |
sansqrit.runtime.qec_codes() | function | |
sansqrit.runtime.qec_logical(code, base, name, distance) | function | |
sansqrit.runtime.qec_encode(logical) | function | |
sansqrit.runtime.qec_decode(logical) | function | |
sansqrit.runtime.qec_syndrome(logical, ancilla_base) | function | |
sansqrit.runtime.qec_correct(logical, syndrome) | function | |
sansqrit.runtime.qec_syndrome_and_correct(logical, ancilla_base) | function | |
sansqrit.runtime.qec_inject_error(logical, pauli, physical_offset) | function | |
sansqrit.runtime.logical_x(logical) | function | |
sansqrit.runtime.logical_z(logical) | function | |
sansqrit.runtime.logical_h(logical) | function | |
sansqrit.runtime.logical_s(logical) | function | |
sansqrit.runtime.logical_cx(control, target) | function | |
sansqrit.runtime.qec_surface_lattice(distance) | function | |
sansqrit.runtime.qec_syndrome_circuit(logical, ancilla_base) | function | |
sansqrit.runtime.lookup_profile() | function | |
sansqrit.runtime.plan_backend(circuit_or_n_qubits, operations) | function | |
sansqrit.runtime.sansqrit_doctor() | function | |
sansqrit.runtime.sansqrit_backends() | function | |
sansqrit.runtime.estimate_qubits(n_qubits) | function | |
sansqrit.runtime.execution_flow() | function | |
sansqrit.runtime.architecture_layers() | function | |
sansqrit.runtime.lookup_architecture() | function | |
sansqrit.runtime.explain_120_qubits_dense() | function | |
sansqrit.runtime.hardware_targets() | function | |
sansqrit.runtime.export_hardware(provider) | function | |
sansqrit.runtime.hardware_payload_summary() | function | |
sansqrit.runtime.troubleshooting(topic) | function | |
sansqrit.runtime.research_gaps() | function | |
sansqrit.runtime.write_training_jsonl(path) | function | |
sansqrit.runtime.training_dataset_info() | function | |
sansqrit.runtime.training_dataset_sample(split, n) | function | |
sansqrit.runtime.export_training_dataset(output_dir, split, limit) | function | |
sansqrit.runtime.enable_logging(level, path) | function | |
sansqrit.runtime.log_sansqrit_event(event, fields) | function | |
sansqrit.runtime.qec_optional_features() | function | |
sansqrit.runtime.qec_stim_syndrome_text(logical, ancilla_base) | function | |
sansqrit.runtime.real_world_scenarios_info() | function | |
sansqrit.runtime.real_world_scenario_sample(n, domain) | function | |
sansqrit.runtime.export_real_world_scenarios(path, limit, domain) | function | |
sansqrit.runtime.explain_backend(n_qubits, operations) | function | |
sansqrit.runtime.planner_features(n_qubits, operations) | function | |
sansqrit.runtime.distributed_capabilities() | function | |
sansqrit.runtime.gpu_capabilities() | function | |
sansqrit.runtime.gpu_memory_estimate(n_qubits) | function | |
sansqrit.runtime.cuquantum_recommendation(n_qubits, circuit_type) | function | |
sansqrit.runtime.qasm3_mid_circuit_template(n_qubits) | function | |
sansqrit.runtime.qasm3_advanced(path) | function | |
sansqrit.runtime.qec_stim_surface_task(distance, rounds, p) | function | |
sansqrit.runtime.qec_threshold_sweep(distances, physical_error_rates) | function | |
sansqrit.runtime.qec_logical_resource_estimate(logical_qubits, logical_depth, distance, factories) | function | |
sansqrit.runtime.conformance_report() | function | |
sansqrit.scenarios.scenario_info() | function | |
sansqrit.scenarios.load_scenarios() | function | |
sansqrit.scenarios.sample_scenarios(n) | function | |
sansqrit.scenarios.export_scenarios(output_path) | function | |
sansqrit.sharding.ShardInfo | class | |
sansqrit.sharding.ShardedState | class | |
sansqrit.sparse.bit_of(state, qubit) | function | |
sansqrit.sparse.flip_bit(state, qubit) | function | |
sansqrit.sparse.bitstring(state, n_qubits) | function | |
sansqrit.sparse.conventional_bitstring(state, n_qubits) | function | |
sansqrit.sparse.SparseState | class | Sparse quantum state vector. |
sansqrit.stabilizer.StabilizerEngine | class | Clifford-only simulator backed by a stabilizer tableau. |
sansqrit.types.QubitRef | class | A reference to a qubit index inside a quantum register. |
sansqrit.types.QuantumRegister | class | A simple addressable quantum register. |
sansqrit.types.qubit_index(q) | function | Return an integer qubit index from either an int or QubitRef. |
sansqrit.verification.VerificationResult | class | |
sansqrit.verification.compare_probabilities(a, b) | function | |
sansqrit.verification.verify_with_qiskit(circuit) | function | |
sansqrit.verification.verify_with_cirq(circuit) | function | |
sansqrit.verification.verify_all_available(circuit) | function | |
sansqrit.verification.verify_with_braket(circuit) | function | Verify Braket exportability and optionally local-simulator probabilities. |
sansqrit.verification.verify_with_stim(circuit) | function | Verify Clifford circuits with Stim when installed. |
sansqrit.verification.conformance_report(circuit) | function | Run all available cross-framework checks and return a JSON-safe report. |
sansqrit.verification.verify_all_available(circuit) | function |
Complete Package Documentation Imported from the Wheel
The sections below are rendered from the package documentation shipped inside sansqrit-0.3.6. Similar subjects have been merged into one navigable documentation flow, with the original detailed material preserved inside the relevant chapter. This avoids the earlier repeated explanations while still keeping the full content available for students, physicists, scientists, backend developers, and search engines.
Merged documentation map
Use this map when you want a complete understanding of the package rather than a short marketing summary. Each card links to the chapter where similar content has been consolidated.
How to read this section
Start with the architecture chapter if you are new, then move to DSL syntax, backend selection, 120-qubit limitations, QEC, hardware export, and troubleshooting. Each chapter is written as practical documentation rather than a short marketing summary.
For novice students
Focus on what each command means, what problem it solves, and why dense 120-qubit simulation is not realistic. The page explains when Sansqrit uses sparse, sharded, hierarchical, MPS, stabilizer, GPU, and distributed modes.
For physicists and scientists
Use the backend and architecture notes to map circuit structure to simulation method: separable local blocks, Clifford circuits, tensor-network bridges, noisy density workflows, QEC helper circuits, and provider export formats.
Direct hyperlinks to every Markdown document in the package
These links are kept so nothing from the wheel is hidden. The main page merges the most important repeated explanations, while the original Markdown files remain available for direct reading, sharing, and search indexing.
COMPLETE_ARCHITECTURE_AND_DSL_REFERENCE.md
What this chapter covers
This is the main design reference for the package. It explains the DSL surface, the Python runtime modules, planner decisions, memory reality for large qubit counts, safe execution modes, hardware export, diagnostics, and correct claims for public documentation.
Why it matters
Quantum programs are easy to write but difficult to simulate honestly. This chapter separates educational examples from physically realistic execution modes so users understand when a result is exact, approximate, sparse, tensor-network based, or only an export target for real hardware.
Recommended path
Read the quick-start first, then the architecture flow, then the 120-qubit dense simulation reality section. After that, choose the backend chapter that matches your circuit: sparse, sharded, hierarchical, MPS, stabilizer, density/noise, GPU, or distributed.
Sansqrit Quantum DSL
Author / maintainer: Karthik V Version: 0.3.3 Package: sansqrit Purpose: a simplified quantum-computing DSL and Python runtime for scientists, AI/ML training datasets, educational quantum-programming examples, sparse/sharded simulation, lookup-accelerated execution, hierarchical tensor shards, QEC, and hardware export workflows.
Sansqrit is designed to make quantum circuits readable:
simulate(120, engine="hierarchical", block_size=10) {
q = quantum_register(120)
shard node_0 [0..9]
shard node_1 [10..19]
apply H on node_0
X(q[119])
apply CNOT on q[9], q[10] bridge_mode=sparse
print(hierarchical_report())
print(lookup_profile())
}
It is not a claim that arbitrary dense 120-qubit state-vector simulation is possible on local hardware. Sansqrit supports 120+ logical qubit programs when the circuit remains sparse, Clifford-structured, low-entanglement, or decomposable into independent tensor blocks.
---
Table of contents
- Installation
- Quick start
- Execution architecture
- 120-qubit dense simulation reality
- Sparse, sharded, hierarchical and MPS modes
- Precomputed lookup files
- Distributed computing model
- GPU backend
- Stabilizer backend
- Density/noise backend
- Quantum error correction framework
- Hardware export: Qiskit, Cirq, Braket, Azure, PennyLane, QASM
- Complete DSL syntax
- Gate/function reference
- Algorithms and high-level helpers
- Logging, diagnostics and troubleshooting
- AI/ML training usage
- Real-world 120+ qubit examples
- PyPI upload/release notes
- Limitations and safe claims
---
1. Installation
pip install sansqrit
Optional integrations:
pip install "sansqrit[qiskit]"
pip install "sansqrit[cirq]"
pip install "sansqrit[braket]"
pip install "sansqrit[pennylane]"
pip install "sansqrit[gpu]"
pip install "sansqrit[all]"
Development install:
git clone <your-repo-url>
cd sansqrit
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[all,dev]"
---
2. Quick start
Create bell.sq:
simulate(2, engine="sparse") {
q = quantum_register(2)
H(q[0])
CNOT(q[0], q[1])
print(probabilities())
print(measure_all(shots=10))
}
Run:
sansqrit run bell.sq
Export QASM:
sansqrit qasm bell.sq --version 3 -o bell.qasm
Inspect environment:
sansqrit doctor
sansqrit backends
sansqrit estimate 120
sansqrit architecture
sansqrit troubleshoot lookup
sansqrit hardware
---
3. Execution architecture
Sansqrit uses a layered runtime:
flowchart TD
A[Sansqrit .sq DSL] --> B[Translator / Parser]
B --> C[Circuit History + Runtime Engine]
C --> D[Optimizer Passes]
D --> E[Adaptive Planner]
E -->|Sparse / few amplitudes| F[Sparse State Map]
E -->|Large sparse| G[Sharded Sparse State]
E -->|Independent <=10q blocks| H[Hierarchical Tensor Shards]
E -->|Cross-block low entanglement| I[MPS Bridge]
E -->|Clifford circuit| J[Stabilizer Tableau]
E -->|Noisy small circuit| K[Density Matrix]
E -->|GPU available and dense small| L[CuPy / GPU Statevector]
E -->|Cluster configured| M[TCP Distributed Sparse Workers]
F --> N[Lookup Matrices + Sparse Updates]
G --> N
H --> O[Packaged 1..10q Embedded Lookups]
I --> P[Tensor SVD / Bond Update]
J --> Q[Tableau Update]
K --> R[Kraus / Noise Channels]
L --> S[GPU Vector Operations]
M --> T[Shard Exchange / Coordinator]
N --> U[Measurement / QASM / Hardware Export]
O --> U
P --> U
Q --> U
R --> U
S --> U
T --> U
Layers
| Layer | What it does |
|---|---|
| DSL | Human-friendly .sq syntax. |
| Translator | Converts Sansqrit into Python runtime calls. |
| Circuit history | Records operations for export, optimization, verification and profiling. |
| Optimizer | Cancels inverse gates, merges rotations, removes zero rotations. |
| Planner | Recommends sparse, sharded, hierarchical, MPS, stabilizer, density, GPU or distributed mode. |
| Lookup layer | Loads packaged precomputed gates and embedded <=10-qubit transitions. |
| Sparse map | Stores only nonzero amplitudes as {basis_index: amplitude}. |
| Sharded sparse map | Partitions sparse amplitudes into shards for locality and workers. |
| Hierarchical tensor shards | Keeps independent 10-qubit blocks dense and promotes bridge entanglement to MPS. |
| QEC layer | Logical qubits, stabilizer codes, syndrome extraction, decoders and correction. |
| Hardware export | OpenQASM 2/3, Qiskit, Cirq, Braket, Azure payloads and PennyLane callable exports. |
---
4. 120-qubit dense simulation reality
A dense n-qubit state vector contains 2^n amplitudes. A 120-qubit dense vector has:
2^120 ≈ 1.329e36 amplitudes
At complex128 precision, even one full vector is astronomically too large for ordinary hardware. Precomputed lookup, sharding and distributed execution reduce overhead and organize data, but they do not remove exponential dense-state growth.
Sansqrit therefore uses this decision strategy:
| Circuit structure | Recommended backend |
|---|---|
| Few active basis states | sparse, sharded, threaded |
| Independent <=10-qubit blocks | hierarchical |
| Low-entanglement chain/grid | mps, hierarchical bridge mode |
| Clifford-only circuit | stabilizer |
| Small noisy circuit | density |
| Small/medium dense circuit with CUDA | gpu |
| Multi-node sparse workloads | distributed |
| Arbitrary dense 120-qubit state | Not feasible on normal hardware |
---
5. Sparse, sharded, hierarchical and MPS modes
Sparse mode
simulate(120, engine="sparse") {
q = quantum_register(120)
X(q[119])
H(q[0])
CNOT(q[0], q[1])
print(engine_nnz())
}
Sparse mode stores only active amplitudes. It is efficient when the number of nonzero amplitudes stays small.
Sharded sparse mode
simulate(120, engine="sharded", n_shards=16, workers=8) {
q = quantum_register(120)
X(q[5])
X(q[87])
H(q[0])
CNOT(q[0], q[1])
print(shards())
}
Sharding partitions active basis keys. It helps memory locality and distributed layout. It does not blindly split entangled systems into independent sub-simulators.
Hierarchical tensor shards
simulate(120, engine="hierarchical", block_size=10) {
q = quantum_register(120)
shard block_0 [0..9]
shard block_1 [10..19]
apply H on block_0
apply X on block_1
print(hierarchical_report())
}
A 120-qubit register becomes 12 local blocks of 10 qubits. Each local block can be represented by 1024 amplitudes, and precomputed embedded lookup tables can accelerate local static gates.
Bridge entanglement
simulate(120, engine="hierarchical", block_size=10, cutoff=0.0, max_bond_dim=null) {
q = quantum_register(120)
H(q[9])
apply CNOT on q[9], q[10] bridge_mode=sparse
print(hierarchical_report())
}
A cross-block gate such as CNOT(q[9], q[10]) is not mathematically local to a single 10-qubit block. Sansqrit promotes the model to an MPS bridge so correlations are represented accurately when cutoff=0.0 and max_bond_dim=null.
---
6. Precomputed lookup files
The package includes real lookup data files:
sansqrit/data/lookup_static_gates.json
sansqrit/data/lookup_two_qubit_static_gates.json
sansqrit/data/lookup_embedded_single_upto_10.json.gz
sansqrit/data/lookup_metadata.json
Runtime lookup policy:
- If
n <= 10and the gate is a static single-qubit gate, use embedded full-register transition tables. - Else if the gate is a static single-qubit gate, use the packaged 2x2 matrix.
- Else if the gate is a static two-qubit gate, use the packaged 4x4 matrix.
- Else compute at runtime and optionally rely on higher-level block/cache optimizations.
Check usage:
simulate(10, engine="sparse", use_lookup=true) {
q = quantum_register(10)
H(q[0])
SX(q[3])
CNOT(q[0], q[1])
print(lookup_profile())
}
---
7. Distributed computing model
Start workers:
sansqrit worker --host 0.0.0.0 --port 8765
sansqrit worker --host 0.0.0.0 --port 8766
Use from Python:
from sansqrit import QuantumEngine
engine = QuantumEngine.create(120, backend="distributed", addresses=[("10.0.0.1", 8765), ("10.0.0.2", 8766)])
The built-in distributed backend is correctness-first. It is useful for sparse shard orchestration and testing. For production HPC, a future backend should add MPI/Ray/Dask, compressed amplitude transfer, worker-local gate kernels and topology-aware shard exchange.
---
8. GPU backend
pip install "sansqrit[gpu]"
simulate(24, engine="gpu") {
q = quantum_register(24)
H(q[0])
CNOT(q[0], q[1])
print(measure_all(shots=100))
}
GPU acceleration helps small/medium dense state vectors. It does not make arbitrary dense 120-qubit simulation feasible.
---
9. Stabilizer backend
simulate(1000, engine="stabilizer") {
q = quantum_register(1000)
for i in range(0, 999) {
H(q[i])
CNOT(q[i], q[i + 1])
}
print(measure_all(shots=5))
}
The stabilizer backend is for Clifford circuits using gates such as H, S, X, Y, Z, CNOT, CZ, and SWAP. It does not support arbitrary non-Clifford rotations as exact tableau operations.
---
10. Density and noise backend
simulate(3, engine="density") {
q = quantum_register(3)
H(q[0])
CNOT(q[0], q[1])
noise_bit_flip(q[1], 0.01)
noise_phase_flip(q[0], 0.01)
print(probabilities())
}
Noise helpers:
noise_bit_flip(q, p)
noise_phase_flip(q, p)
noise_depolarize(q, p)
noise_amplitude_damping(q, gamma)
Density matrices scale as 4^n, so use this backend for small noisy circuits.
---
11. Quantum error correction framework
Sansqrit includes a dedicated QEC module.
Supported codes:
bit_flip
phase_flip
repetition3
repetition distance-d
shor9
steane7
five_qubit
surface3
surface distance-d helpers
Core DSL functions:
qec_codes()
qec_code(name, distance=null)
qec_logical(code="bit_flip", base=0, name="logical", distance=null)
qec_encode(logical)
qec_decode(logical)
qec_syndrome(logical, ancilla_base=null)
qec_correct(logical, syndrome)
qec_syndrome_and_correct(logical, ancilla_base=null)
qec_inject_error(logical, pauli, physical_offset)
logical_x(logical)
logical_z(logical)
logical_h(logical)
logical_s(logical)
logical_cx(control, target)
qec_surface_lattice(distance=3)
qec_syndrome_circuit(logical, ancilla_base=null)
qec_optional_features()
qec_stim_syndrome_text(logical, ancilla_base=null)
Bit-flip example:
simulate(6, engine="sparse") {
q = quantum_register(6)
logical = qec_logical("bit_flip", base=0)
qec_encode(logical)
qec_inject_error(logical, "X", 1)
result = qec_syndrome_and_correct(logical, ancilla_base=3)
print(result)
}
Surface-code helper:
simulate(20, engine="sparse") {
q = quantum_register(20)
logical = qec_logical("surface", base=0, distance=3)
print(logical.stabilizers())
print(qec_surface_lattice(3).stabilizers())
print(qec_optional_features())
}
The built-in surface-code decoder is educational/greedy. If pymatching is installed, Sansqrit exposes an integration point for MWPM-style decoding. If stim is installed, the package can emit syndrome-extraction text that can be adapted into Stim workflows.
---
12. Hardware export
OpenQASM 3
simulate(3, engine="sparse") {
q = quantum_register(3)
H(q[0])
CNOT(q[0], q[1])
print(export_qasm3())
}
Hardware target summary
simulate(4, engine="sparse") {
q = quantum_register(4)
H(q[0])
CNOT(q[0], q[1])
print(hardware_targets())
print(hardware_payload_summary())
print(export_hardware("azure"))
}
Supported export modes:
| Target | Export |
|---|---|
| Qiskit / IBM | qiskit.QuantumCircuit or OpenQASM fallback |
| Cirq | cirq.Circuit or OpenQASM fallback |
| Amazon Braket | braket.circuits.Circuit or OpenQASM fallback |
| Azure Quantum | OpenQASM 3 / Qiskit / Cirq payload style |
| PennyLane | Callable quantum function for QNode construction |
| OpenQASM 2/3 | Text export |
Sansqrit does not store cloud credentials. Submission to cloud hardware remains controlled by the provider SDK and user account.
---
13. Complete DSL syntax
Variables
x = 10
y = 3.14
name = "sansqrit"
flag = true
nothing = null
Lists, dictionaries and math
values = [1, 2, 3, 4]
config = {"backend": "sparse", "shots": 1000}
print(sum(values))
print(mean(values))
Functions
fn square(x) {
return x * x
}
print(square(7))
Lambdas and pipelines
values = [1, 2, 3, 4]
result = values |> map(fn(x) => x * x) |> filter(fn(x) => x > 4)
print(result)
Loops and conditionals
for i in range(0, 10) {
if i % 2 == 0 {
print(i)
} else {
print("odd")
}
}
Simulation blocks
simulate(5, engine="sparse") {
q = quantum_register(5)
H(q[0])
}
Arguments:
simulate(n_qubits, engine="sparse", n_shards=1, workers=1, seed=null, use_lookup=true, max_bond_dim=null, cutoff=0.0, addresses=null, block_size=10)
Shard declarations
shard block_A [0..9]
apply H on block_A
Bridge gate syntax
apply CNOT on q[9], q[10] bridge_mode=sparse
The translator routes this to the engine while retaining the bridge-mode intention for hierarchical backends.
---
14. Gate/function reference
Single-qubit gates
I(q)
X(q)
Y(q)
Z(q)
H(q)
S(q)
Sdg(q)
T(q)
Tdg(q)
SX(q)
SXdg(q)
Rx(q, theta)
Ry(q, theta)
Rz(q, theta)
Phase(q, theta)
U1(q, theta)
U2(q, phi, lambda)
U3(q, theta, phi, lambda)
Two-qubit gates
CNOT(c, t)
CX(c, t)
CZ(c, t)
CY(c, t)
CH(c, t)
CSX(c, t)
SWAP(a, b)
iSWAP(a, b)
SqrtSWAP(a, b)
fSWAP(a, b)
DCX(a, b)
CRx(c, t, theta)
CRy(c, t, theta)
CRz(c, t, theta)
CP(c, t, theta)
CU(c, t, theta, phi, lambda)
RXX(a, b, theta)
RYY(a, b, theta)
RZZ(a, b, theta)
RZX(a, b, theta)
ECR(a, b)
MS(a, b)
Three/multi-qubit gates
Toffoli(a, b, c)
CCX(a, b, c)
Fredkin(c, a, b)
CSWAP(c, a, b)
CCZ(a, b, c)
MCX(q0, q1, ..., target)
MCZ(q0, q1, ...)
C3X(a, b, c, target)
C4X(a, b, c, d, target)
Whole-register helpers
H_all(qubits=null)
Rx_all(theta, qubits=null)
Ry_all(theta, qubits=null)
Rz_all(theta, qubits=null)
qft(q=null)
iqft(q=null)
measure(q)
measure_all(q=null, shots=1)
probabilities(q=null)
expectation_z(q)
expectation_zz(a, b)
engine_nnz()
shards()
lookup_profile()
hierarchical_report()
File/data helpers
read_file(path)
write_file(path, text)
read_json(path)
write_json(path, obj)
read_csv(path)
write_csv(path, rows)
Diagnostics and architecture helpers
sansqrit_doctor()
sansqrit_backends()
estimate_qubits(n_qubits)
execution_flow()
architecture_layers()
lookup_architecture()
explain_120_qubits_dense()
troubleshooting(topic=null)
research_gaps()
enable_logging(level="INFO", path=null)
log_sansqrit_event(event, fields={})
---
15. Algorithms and high-level helpers
grover_search
grover_search_multi
shor_factor
vqe_h2
qaoa_maxcut
quantum_phase_estimation
hhl_solve
bernstein_vazirani
simon_algorithm
deutsch_jozsa
quantum_counting
swap_test
teleport
superdense_coding
bb84_qkd
amplitude_estimation
variational_classifier
---
16. Logging, diagnostics and troubleshooting
enable_logging("INFO", "sansqrit.log")
log_sansqrit_event("start", {"program": "sparse_120"})
print(sansqrit_doctor())
print(sansqrit_backends())
print(troubleshooting("lookup"))
CLI:
sansqrit doctor
sansqrit backends
sansqrit estimate 120
sansqrit troubleshoot distributed
sansqrit architecture
sansqrit hardware
---
17. AI/ML training usage
Sansqrit ships examples and docs inside the wheel so AI tools can inspect them after installation.
from sansqrit.dataset import builtin_training_records, generate_jsonl
records = builtin_training_records()
generate_jsonl("sansqrit_training.jsonl", records)
Training task types:
| Task | Input | Output |
|---|---|---|
| DSL generation | Natural language algorithm request | .sq program |
| DSL correction | Buggy .sq | Corrected .sq |
| DSL-to-QASM | .sq program | OpenQASM 2/3 |
| Backend planning | Circuit description | Recommended backend + explanation |
| QEC explanation | Error model + code | Syndrome/correction flow |
| Hardware export | Sansqrit circuit | Provider payload/QASM |
---
18. Real-world 120+ qubit example themes
The package includes 300+ examples. New high-qubit examples cover:
- Climate sensor anomaly encoding
- Supply-chain route optimization
- Finance portfolio risk flags
- Cybersecurity graph threat propagation
- Telecom network routing
- Drug-discovery feature maps
- QEC satellite link protection
- Smart-grid sparse fault localization
- Port logistics
- Aerospace sensor fusion
- 1000-qubit Clifford/stabilizer workflows
Run:
sansqrit run examples/278_climate_128q_sparse_sensors.sq
sansqrit run examples/283_hierarchical_120q_bridge_iot.sq
sansqrit run examples/300_city_1000q_stabilizer_graph.sq
---
19. PyPI release notes
Build:
python -m pip install --upgrade build twine
rm -rf build dist *.egg-info src/*.egg-info
python -m build --sdist --wheel
python -m twine check dist/*
python -m twine upload dist/*
If version 0.3.3 is already uploaded to PyPI, PyPI will reject another upload with the same version. In that case, bump to 0.3.6 or later.
---
20. Limitations and safe claims
Safe claim:
> Sansqrit supports 120+ logical qubit programs using sparse, sharded, lookup-accelerated, stabilizer, MPS, hierarchical tensor, density-matrix, GPU and distributed backends when the circuit has exploitable structure.
Unsafe claim:
> Sansqrit can simulate any arbitrary dense 120-qubit quantum state on local hardware.
That is not physically realistic.
---
License
MIT.
DSL_REFERENCE.md
Sansqrit DSL Reference
Sansqrit source files use the .sq extension. The Python implementation translates Sansqrit into Python and runs it with Sansqrit quantum builtins. It is intended for trusted local programs.
Program shape
simulate(2) {
let q = quantum_register(2)
H(q[0])
CNOT(q[0], q[1])
print(measure_all(q, shots=1000))
}
Engine selection
simulate(8, engine="sparse") { }
simulate(8, engine="sharded", n_shards=4, workers=2) { }
simulate(8, engine="threaded", workers=4) { }
Variables
let x = 1
const EPS = 1e-9
x += 1
x -= 1
x *= 2
x /= 2
Literals
true
false
None
1
1.5
"text"
[1, 2, 3]
{"key": "value"}
(1, 2)
Functions
fn square(x) {
return x * x
}
let cube = fn(x) => x * x * x
Pipelines
let xs = [1, 2, 3, 4]
let ys = xs |> map(fn(x) => x * x)
let zs = ys |> filter(fn(x) => x > 4)
let total = zs |> sum
let folded = xs |> reduce(fn(a, b) => a + b)
Control flow
if x > 0 {
print("positive")
} else if x == 0 {
print("zero")
} else {
print("negative")
}
for i in range(10) {
print(i)
}
while error > 1e-6 {
error = error / 2
}
Quantum register
let q = quantum_register(5)
q[0]
q[4]
Qubits are little-endian internally: q[0] is the least-significant bit. Displayed bitstrings are conventional most-significant-bit first.
Gates
Single-qubit
I(q[0]); X(q[0]); Y(q[0]); Z(q[0]); H(q[0])
S(q[0]); Sdg(q[0]); T(q[0]); Tdg(q[0])
SX(q[0]); SXdg(q[0])
Rx(q[0], PI / 2); Ry(q[0], PI / 2); Rz(q[0], PI / 2)
Phase(q[0], PI / 4); U1(q[0], PI / 4)
U2(q[0], 0.1, 0.2); U3(q[0], 0.1, 0.2, 0.3)
Two-qubit
CNOT(q[0], q[1]); CX(q[0], q[1])
CZ(q[0], q[1]); CY(q[0], q[1]); CH(q[0], q[1])
CSX(q[0], q[1]); SWAP(q[0], q[1]); iSWAP(q[0], q[1])
SqrtSWAP(q[0], q[1]); fSWAP(q[0], q[1]); DCX(q[0], q[1])
CRx(q[0], q[1], PI/3); CRy(q[0], q[1], PI/3); CRz(q[0], q[1], PI/3)
CP(q[0], q[1], PI/3); CU(q[0], q[1], 0.1, 0.2, 0.3)
RXX(q[0], q[1], PI/4); RYY(q[0], q[1], PI/4); RZZ(q[0], q[1], PI/4)
RZX(q[0], q[1], PI/4); ECR(q[0], q[1]); MS(q[0], q[1])
Three and multi-qubit
Toffoli(q[0], q[1], q[2]); CCX(q[0], q[1], q[2])
Fredkin(q[0], q[1], q[2]); CSWAP(q[0], q[1], q[2])
CCZ(q[0], q[1], q[2])
MCX(q[0], q[1], q[2], q[3])
MCZ(q[0], q[1], q[2])
C3X(q[0], q[1], q[2], q[3])
C4X(q[0], q[1], q[2], q[3], q[4])
Circuit helpers
H_all()
Rx_all(PI / 4)
Ry_all(PI / 4)
Rz_all(PI / 4)
qft(q)
iqft(q)
Measurement
measure(q[0])
measure_all(q, shots=1000)
probabilities(q)
expectation_z(q[0])
expectation_zz(q[0], q[1])
engine_nnz()
shards()
Algorithms
grover_search(3, 5, shots=512)
grover_search_multi(4, [3, 12], shots=512)
shor_factor(15)
vqe_h2(0.735, max_iter=32)
qaoa_maxcut(4, [(0,1), (1,2), (2,3), (3,0)], p=1, shots=256)
quantum_phase_estimation(0.3125, 5, shots=256)
hhl_solve([[2, 0], [0, 4]], [2, 8])
bernstein_vazirani("101101")
simon_algorithm("101")
deutsch_jozsa(4, "balanced")
quantum_counting(6, 7, 5)
teleport(1)
superdense_coding(1, 0)
bb84_qkd(24, eavesdropper=false)
amplitude_estimation(0.37, 5)
variational_classifier([0.1, 0.5, 1.2], layers=3)
I/O
write_file("out.txt", "hello")
let text = read_file("out.txt")
write_json("data.json", {"shots": 1000})
let obj = read_json("data.json")
write_csv("data.csv", [{"gate": "H", "q": 0}])
let rows = read_csv("data.csv")
Advanced backend syntax
simulate(1000, engine="stabilizer") { H(0); CNOT(0, 999) }
simulate(64, engine="mps", max_bond_dim=128, cutoff=1e-12) { H(0) }
simulate(3, engine="density") { H(0); noise_depolarize(0, 0.01) }
simulate(20, engine="gpu") { H(0); CNOT(0, 1) }
Additional functions:
noise_depolarize(q, p)noise_bit_flip(q, p)noise_phase_flip(q, p)noise_amplitude_damping(q, gamma)engine_nnz()for sparse nonzero count; stabilizer/MPS may return-1because they do not store computational-basis sparse amplitudes.
Use Python API for hybrid and cluster orchestration:
Circuit(150).H(0).CNOT(0, 149).run(backend="hybrid")
DistributedSparseEngine.from_addresses(150, ["host1:8765", "host2:8765"])
API_REFERENCE.md
Python API Reference
QuantumEngine
from sansqrit import QuantumEngine
engine = QuantumEngine.create(n_qubits=5, backend="sparse")
Options:
backend:"sparse","sharded", or"threaded".n_shards: local partition count for sharded mode.workers: worker thread count for large single-qubit transforms.use_lookup: use precomputed static-gate matrices.seed: deterministic sampling seed.
Core methods:
engine.H(0)
engine.CNOT(0, 1)
engine.RZZ(1, 2, 0.5)
engine.H_all()
engine.qft([0, 1, 2])
engine.measure(0)
engine.measure_all(1000)
engine.probabilities()
engine.expectation_z(0)
engine.expectation_zz(0, 1)
engine.export_qasm2()
engine.export_qasm3()
engine.shard_info()
Circuit
from sansqrit import Circuit
c = Circuit(2).H(0).CNOT(0, 1)
engine = c.run()
counts = c.run(shots=1000)
print(c.qasm3())
DSL runner
from sansqrit import run_code, run_file, translate
run_file("program.sq")
print(translate(open("program.sq").read()))
Algorithms module
from sansqrit.algorithms import grover_search, qaoa_maxcut, vqe_h2
The algorithms module contains readable reference implementations and toy hybrid algorithms for examples, education and model training.
Advanced Python APIs
from sansqrit import Circuit, QuantumEngine, StabilizerEngine, DensityMatrixEngine
from sansqrit.mps import MPSEngine
from sansqrit.hybrid import HybridEngine
from sansqrit.cluster import DistributedSparseEngine
from sansqrit.optimizer import optimize_operations
from sansqrit.interop import to_qiskit, to_cirq, to_braket, apply_to_pennylane
from sansqrit.verification import verify_all_available
Backends
QuantumEngine.create(n, backend="sparse")QuantumEngine.create(n, backend="sharded", n_shards=8)QuantumEngine.create(n, backend="threaded", workers=8)QuantumEngine.create(n, backend="stabilizer")QuantumEngine.create(n, backend="mps", max_bond_dim=128)QuantumEngine.create(n, backend="density")QuantumEngine.create(n, backend="gpu")QuantumEngine.create(n, backend="distributed", addresses=["host:8765"])
Optimizer
optimized_ops, report = optimize_operations(circuit.operations)
The report includes before, after, removed, and the set of passes used.
Verification
verify_all_available(circuit) attempts Qiskit and Cirq comparisons if installed.
ADVANCED_BACKENDS.md
Sansqrit Advanced Backends
Sansqrit 0.2 adds advanced backends for large and specialized simulations. These backends are not magic: a fully dense, highly entangled 150-qubit state is still infeasible on local hardware. The goal is to avoid expanding the state whenever the circuit structure allows it.
Backend selection summary
| Backend | DSL syntax | Best for | Scaling idea | Important limit |
|---|---|---|---|---|
| Sparse | simulate(n, engine="sparse") | few nonzero amplitudes, oracle circuits, large-index demos | stores only nonzero basis amplitudes | dense superpositions still explode |
| Sharded | simulate(n, engine="sharded", n_shards=8) | larger sparse states on one machine | partitions sparse dictionary | not multi-node |
| Threaded | simulate(n, engine="threaded", workers=8) | large sparse single-qubit transforms | thread pool over sparse chunks | Python GIL limits CPU speedups for some operations |
| Stabilizer | simulate(n, engine="stabilizer") | Clifford circuits with hundreds/thousands of qubits | binary tableau | rejects non-Clifford gates such as T/Rx/RZZ |
| MPS / tensor network | simulate(n, engine="mps", max_bond_dim=128) | low-entanglement 1D-ish circuits | matrix product state with SVD truncation | high entanglement increases bond dimension |
| Hybrid | Python API: Circuit(...).run(backend="hybrid") | automatic whole-circuit routing | chooses stabilizer/MPS/sparse | dynamic DSL routing is intentionally conservative |
| Density / noisy | simulate(n, engine="density") | small noisy circuits | sparse density matrix and Kraus channels | density matrices scale as 4^n in the worst case |
| GPU / CuPy | simulate(n, engine="gpu") | moderate dense state vectors on CUDA GPUs | dense vector on GPU | not for 150 dense qubits |
| Distributed cluster | Python API: DistributedSparseEngine.from_addresses(...) | correctness-first multi-node sparse shards | TCP workers store shards | gathers state per gate; not MPI-performance yet |
Stabilizer backend
Use it for Clifford circuits:
simulate(1000, engine="stabilizer", seed=7) {
H(0)
for i in range(0, 999) {
CNOT(i, i + 1)
}
print(measure_all(shots=8))
}
Supported stabilizer gates: I, X, Y, Z, H, S, Sdg, CNOT/CX, CZ, SWAP.
The backend raises an error for non-Clifford gates. This is intentional: silently switching to dense simulation would defeat the purpose.
MPS / tensor-network backend
Use it when the circuit has limited entanglement:
simulate(64, engine="mps", max_bond_dim=64, cutoff=1e-10) {
for i in range(0, 64) { Ry(i, 0.05) }
for i in range(0, 63) { CNOT(i, i + 1) }
print(measure_all(shots=32))
}
Install dependencies:
pip install sansqrit[tensor]
Noise and density matrices
simulate(2, engine="density", seed=1) {
H(0)
CNOT(0, 1)
noise_depolarize(0, 0.01)
noise_amplitude_damping(1, 0.05)
print(probabilities())
}
Noise functions:
noise_depolarize(q, p)noise_bit_flip(q, p)noise_phase_flip(q, p)noise_amplitude_damping(q, gamma)
GPU backend
pip install sansqrit[gpu]
simulate(20, engine="gpu") {
H(0)
CNOT(0, 1)
print(measure_all(shots=100))
}
The GPU backend is dense. It accelerates moderate state vectors but cannot store arbitrary 150-qubit dense states.
Distributed cluster backend
Start workers on machines reachable by TCP:
sansqrit worker --host 0.0.0.0 --port 8765
sansqrit worker --host 0.0.0.0 --port 8766
Use from Python:
from sansqrit.cluster import DistributedSparseEngine
engine = DistributedSparseEngine.from_addresses(150, ["worker-a:8765", "worker-b:8766"])
engine.apply("H", 0)
engine.apply("CNOT", 0, 149)
print(engine.measure_all(100))
This mode is a real multi-node protocol, but it prioritizes correctness. It gathers/repartitions state around each operation, so it is not yet a high-performance MPI simulator.
Interop
Install extras as needed:
pip install sansqrit[qiskit]
pip install sansqrit[cirq]
pip install sansqrit[braket]
pip install sansqrit[pennylane]
Python API:
from sansqrit import Circuit
from sansqrit.interop import to_qiskit, to_cirq, to_braket, apply_to_pennylane
circuit = Circuit(2).H(0).CNOT(0, 1)
qc = to_qiskit(circuit)
cc = to_cirq(circuit)
braket_circuit = to_braket(circuit)
qml_function = apply_to_pennylane(circuit)
Formal verification helpers
from sansqrit import Circuit
from sansqrit.verification import verify_all_available
circuit = Circuit(2).H(0).CNOT(0, 1)
for result in verify_all_available(circuit):
print(result)
The helpers compare Sansqrit probabilities against installed SDK simulators. They are regression checks, not mathematical proof certificates.
HIERARCHICAL_TENSOR_SHARDS.md
Sansqrit Hierarchical Tensor Shards
Version 0.3.3 adds a safe implementation of the common idea: simulate a large logical register as many small dense blocks, then promote to a tensor network when blocks become entangled.
Why this exists
A 120-qubit dense state vector has 2^120 amplitudes, which is not physically practical on local hardware. However, many useful programs do not immediately create global dense entanglement. They contain local dynamics, independent blocks, sparse activity, or low-entanglement bridge operations.
The hierarchical backend exploits that structure.
120 logical qubits
↓
12 local dense blocks of 10 qubits each
↓
local gates use dense 1024-amplitude vectors and packaged lookup matrices
↓
first cross-block entangling bridge promotes to MPS
↓
MPS tracks correlations with bond dimensions instead of one 2^120 vector
Important correctness rule
Sansqrit does not blindly treat twelve 10-qubit blocks as independent after a cross-block gate. That would be wrong.
For example:
cx q[9], q[10]
creates a bridge between block 0 and block 1. After this, the backend promotes into MPS mode so the correlation is represented accurately.
Memory example
For block_size=10, one local block has:
2^10 = 1024 complex amplitudes
1024 × 16 bytes ≈ 16 KiB with complex128
A 120-qubit separable block state has 12 blocks:
12 × 16 KiB ≈ 192 KiB for raw block vectors
This is only valid while the global state factors across those blocks.
DSL usage
simulate(120, engine="hierarchical", block_size=10, max_bond_dim=null, cutoff=0.0) {
q = quantum_register(120)
shard block_A [0..9]
shard block_B [10..19]
apply H on block_A
apply X on block_B
# Cross-block bridge. This promotes the backend to MPS safely.
apply CNOT on q[9], q[10] bridge_mode=sparse
info = hierarchical_report()
print(info)
}
Equivalent Python:
from sansqrit import QuantumEngine
engine = QuantumEngine.create(120, backend="hierarchical", block_size=10, max_bond_dim=None, cutoff=0.0)
q = engine.quantum_register()
for i in range(10):
engine.H(q[i])
for i in range(10, 20):
engine.X(q[i])
engine.CNOT(q[9], q[10])
print(engine.hierarchical_report())
Runtime modes
mode="blocks" means the state is still a product of dense local blocks.
mode="mps" means a bridge gate has created cross-block entanglement and the state was promoted to the MPS backend.
Accuracy
Block mode is exact.
MPS bridge mode is exact if:
max_bond_dim = None
cutoff = 0.0
If you set a finite bond dimension or nonzero cutoff, Sansqrit may truncate small singular values to save memory/time. That can be useful for approximation but is no longer exact.
Lookup usage
Inside each 10-qubit block, static primitive gates use packaged lookup matrices:
H, X, Y, Z, S, Sdg, T, Tdg, SX, SXdg
CNOT, CZ, CY, CH, CSX, SWAP, iSWAP, SqrtSWAP, fSWAP, DCX, ECR, MS
The backend reports lookup counters via:
lookup_profile()
hierarchical_report()
Recommended use cases
Good fits:
- 120+ qubit programs with local block dynamics.
- Independent 10-qubit components.
- Low-entanglement bridges between neighboring blocks.
- Real-time sparse/logical applications that should not materialize a global dense vector.
- Workloads where the programmer wants explicit block mapping.
Poor fits:
- Random all-to-all dense circuits.
h_allfollowed by many nonlocal entanglers.- Circuits with rapidly growing MPS bond dimension.
Use engine="stabilizer" for large Clifford-only circuits and engine="sparse" or engine="sharded" for oracle-style sparse state maps.
PRECOMPUTED_LOOKUPS.md
Sansqrit Precomputed Lookup Tables
Sansqrit v0.4.0 ships precomputed lookup files inside the Python wheel under sansqrit/data/.
Included files:
lookup_metadata.json— table schema, version, and limits.lookup_static_gates.json— precomputed 2x2 matrices for all static single-qubit gates.lookup_two_qubit_static_gates.json— precomputed 4x4 matrices for all static two-qubit gates that do not need parameters.lookup_embedded_single_upto_10.json.gz— embedded basis-transition tables for every register size from 1 to 10 qubits, every target qubit position, and every static single-qubit gate.
Why not every possible circuit product?
A phrase like "all possible matrix multiplications up to 10 qubits" can mean an infinite or combinatorially explosive set. Parametric gates such as Rx(theta) have continuous parameters, and even a finite static gate alphabet has an astronomical number of possible circuit products as sequence length grows.
Sansqrit therefore packages the practical exhaustive tables:
- Every static primitive matrix.
- Every static primitive embedded single-qubit transition for n=1..10.
- Static two-qubit primitive matrices.
Runtime then performs sequence fusion/caching and arithmetic fallback where the state space or parameters make prepackaging impractical.
Runtime lookup path
For QuantumEngine.create(n, use_lookup=True):
- if
n <= 10and the gate is static single-qubit, Sansqrit uses the packaged - if the gate is static two-qubit, Sansqrit uses the packaged 4x4 matrix;
- otherwise it computes the needed matrix at runtime.
full-register transition table;
For n > 10, Sansqrit still uses packaged primitive matrices but not full embedded transition tables, because embedded full-register tables scale as 2^n.
Inspect installed lookup data
python - <<'PY'
from importlib.resources import files
import sansqrit
root = files('sansqrit').joinpath('data')
for path in root.iterdir():
print(path.name)
PY
python - <<'PY'
from sansqrit.lookup import packaged_metadata, DEFAULT_LOOKUP
print(packaged_metadata())
print(DEFAULT_LOOKUP.has_embedded_single(10, 7, 'H'))
PY
QEC_FRAMEWORK.md
Sansqrit Quantum Error Correction Framework
Sansqrit v0.3.6 adds a dedicated QEC layer for teaching, prototyping, AI training corpora, and small simulator validation. It includes code definitions, logical qubit objects, syndrome extraction circuits, decoder interfaces, logical gate helpers, and noise/correction examples.
Included codes
| Code | Identifier | Physical qubits | Distance | Purpose |
|---|---|---|---|---|
| 3-qubit bit-flip | bit_flip | 3 | 3 | Correct one X error |
| 3-qubit phase-flip | phase_flip | 3 | 3 | Correct one Z error |
| Repetition code | repetition, repetition3, repetition5, ... | odd d | d | Scalable repetition helper |
| Shor code | shor9 | 9 | 3 | Classic bit+phase protection |
| Steane code | steane7 | 7 | 3 | CSS stabilizer code |
| Five-qubit code | five_qubit | 5 | 3 | Perfect [[5,1,3]] code helper |
| Surface code | surface, surface3, ... | d² | d | Rotated planar layout helper |
Python API
from sansqrit import QuantumEngine
from sansqrit.qec import logical_qubit, encode, inject_error, syndrome_and_correct, decode
engine = QuantumEngine.create(5, backend="sparse")
logical = logical_qubit("bit_flip", base=0)
encode(engine, logical)
inject_error(engine, logical, "X", 1)
result = syndrome_and_correct(engine, logical, ancilla_base=3)
decode(engine, logical)
print(result.syndrome, result.corrections)
Sansqrit DSL syntax
simulate(5) {
let q = quantum_register(5)
let l = qec_logical("bit_flip", base=0)
qec_encode(l)
qec_inject_error(l, "X", 1)
let result = qec_syndrome_and_correct(l, ancilla_base=3)
qec_decode(l)
let counts = measure_all(q)
}
QEC functions exposed to the DSL
qec_codes()
qec_code(name, distance=null)
qec_logical(code="bit_flip", base=0, name="logical", distance=null)
qec_encode(logical)
qec_decode(logical)
qec_syndrome(logical, ancilla_base=null)
qec_correct(logical, syndrome)
qec_syndrome_and_correct(logical, ancilla_base=null)
qec_inject_error(logical, pauli, physical_offset)
logical_x(logical)
logical_z(logical)
logical_h(logical)
logical_s(logical)
logical_cx(control_logical, target_logical)
qec_surface_lattice(distance=3)
qec_syndrome_circuit(logical, ancilla_base=null)
Decoder interface
A decoder implements:
class Decoder:
def decode(self, code, syndrome):
return [("X", 1), ("Z", 4)]
Sansqrit includes:
RepetitionDecoderLookupDecoderSurfaceCodeDecoder
The included surface-code decoder is a greedy educational decoder. It is intentionally replaceable; production surface-code threshold research should plug in a specialized MWPM or union-find decoder through the same interface.
Stabilizer syndrome extraction
syndrome_circuit(logical) returns gate tuples that extract each stabilizer onto an ancilla. Z checks use data-to-ancilla CNOTs. X checks use ancilla preparation/measurement in the X basis. This lets AI tools inspect how stabilizer checks are converted into circuits.
Logical gate helpers
Sansqrit exposes logical Pauli and transversal helper gates:
logical_x, logical_z, logical_h, logical_s, logical_cx
Where transversal gates are not universally valid for all codes, these helpers are educational primitives; code-specific fault-tolerant compilation should be added as later specialized passes.
HARDWARE_EXPORTS_AND_CLOUD.md
Hardware exports and cloud-provider workflows
Sansqrit can export circuit payloads but does not manage cloud credentials.
Built-in export paths
export_qasm2()export_qasm3()export_hardware("qiskit")export_hardware("ibm")export_hardware("cirq")export_hardware("braket")export_hardware("azure")export_hardware("pennylane")hardware_targets()hardware_payload_summary()
Qiskit / IBM
Install:
pip install "sansqrit[qiskit]"
Use export_hardware("qiskit") for a QuantumCircuit when Qiskit is installed. Otherwise Sansqrit returns an OpenQASM 3 fallback payload.
Amazon Braket
Install:
pip install "sansqrit[braket]"
Use export_hardware("braket") for a Braket Circuit when the SDK is installed.
Azure Quantum
Sansqrit emits an OpenQASM 3/Azure-style payload. Submit it using your QDK, Qiskit or Cirq Azure workflow.
PennyLane
Install:
pip install "sansqrit[pennylane]"
Use export_hardware("pennylane") to get a callable quantum function that can be wrapped by a PennyLane QNode.
INDUSTRY_PARITY_V036.md
Sansqrit v0.3.6 Industry-Parity Upgrade Notes
Author/Maintainer: Karthik V
This release adds a stronger adaptive execution planner, production-oriented distributed sparse execution APIs, optional Stim/PyMatching QEC bridges, GPU/cuQuantum capability adapters, richer OpenQASM 3 builders, and expanded conformance verification hooks.
Why these features were added
Modern quantum platforms do not use one simulator for every circuit. They choose among dense state vectors, density matrices, stabilizer/tableau methods, matrix-product-state/tensor-network methods, GPU acceleration, hardware exports, and resource-estimation workflows. Sansqrit now exposes a comparable planning layer while keeping its simple DSL.
Adaptive planner
Use:
sansqrit plan program.sq --json
or in DSL:
print(plan_backend(120, [("H", [0], []), ("CNOT", [0, 1], [])]))
print(explain_backend(120, [("H", [0], []), ("CNOT", [0, 1], [])]))
The planner extracts:
- qubit count
- gate count
- Clifford/non-Clifford count
- estimated depth
- connected-component sizes
- cross-block bridge edges
- dense memory estimate
- density-matrix memory estimate
- sparse-amplitude estimate
- safe backend recommendation
Backend choices include:
sparseshardedsparse_shardedhierarchicalmpsstabilizerextended_stabilizerdensitygpudistributed
Distributed execution
Built-in TCP sparse workers support:
- compressed payloads
- batched gate application
- checkpoint/restore
- capability discovery
- optional Ray/Dask/MPI metadata hooks
Start workers:
sansqrit worker --host 0.0.0.0 --port 8765
Use from Python:
from sansqrit.cluster import DistributedSparseEngine
eng = DistributedSparseEngine.from_addresses(120, [("worker1", 8765), ("worker2", 8765)])
eng.apply_batch([
("H", (0,), ()),
("CNOT", (0, 1), ()),
])
eng.checkpoint("./checkpoint")
This remains mathematically correct by keeping an authoritative sparse state. Large production clusters should add worker-local kernels and pairwise shard exchange for gate families whose partner amplitudes are colocated.
GPU and cuQuantum layer
Use:
sansqrit gpu --qubits 28 --type dense
DSL:
print(gpu_capabilities())
print(cuquantum_recommendation(28, "dense"))
The package does not hard-depend on CUDA. It detects:
- CuPy
- cuQuantum
- cuStateVec target
- cuTensorNet target
- cuDensityMat target
OpenQASM 3 advanced support
Sansqrit now includes a text builder for:
- mid-circuit measurements
- classical bit control
- delays/timing
- barriers
- pragmas
- extern declarations
- calibration blocks
DSL:
print(qasm3_mid_circuit_template(2))
Python:
from sansqrit.qasm import Qasm3Builder
print(Qasm3Builder(2).gate("h", [0]).measure(0, 0).if_bit(0, 1, "x q[1];").text())
QEC production bridges
Sansqrit adds optional integrations and planning utilities:
print(qec_stim_surface_task(3, 3, 0.001))
print(qec_threshold_sweep())
print(qec_logical_resource_estimate(100, 1000, 5, 10))
It supports built-in educational codes and external production pathways:
- bit-flip
- phase-flip
- repetition codes
- Shor 9-qubit
- Steane 7-qubit
- 5-qubit perfect code
- surface-code lattice helpers
- Stim generated surface-code memory experiments when Stim is installed
- PyMatching-compatible MWPM adapter when a matching graph is supplied
Formal verification
The verification layer now attempts:
- Qiskit probability comparison
- Cirq probability comparison
- Braket local simulator/export check
- Stim Clifford parse check
CLI:
sansqrit verify program.sq
DSL:
simulate(2) {
q = quantum_register(2)
H(q[0])
CNOT(q[0], q[1])
print(conformance_report())
}
Large 120+ qubit design rule
For 120+ qubits, Sansqrit avoids false dense claims. It chooses:
- stabilizer for Clifford-only circuits
- extended-stabilizer for mostly Clifford circuits
- hierarchical tensor shards when components are <=10 qubits
- MPS when cross-block entanglement is limited
- sparse/sharded/distributed when active amplitudes stay sparse
- hardware export when classical simulation is not appropriate
Dense 120-qubit state-vector simulation remains physically infeasible because it requires 2^120 amplitudes.
TROUBLESHOOTING_AND_LOGGING.md
Troubleshooting and logging
CLI
sansqrit doctor
sansqrit backends
sansqrit estimate 120
sansqrit troubleshoot lookup
sansqrit hardware
DSL logging
enable_logging("INFO", "sansqrit.log")
log_sansqrit_event("program_start", {"name": "sparse_150"})
Common issues
- Slow 120-qubit run: use
estimate_qubits,plan_backend,stabilizer,mps, orhierarchical. - Missing lookup files: verify
sansqrit/data/exists in the installed package. - Cloud export fails: install the provider extra or use OpenQASM fallback.
- Density backend memory issue: density matrices scale as
4^n. - GPU missing: install CuPy matching your CUDA runtime.
DESIGN_AND_BUG_AUDIT.md
Sansqrit v0.3.6/v0.3.6 Design and Bug Audit
Author/maintainer metadata: Karthik V
Audit date: 2026-04-26
Executive summary
I tested the latest Sansqrit package and found that the overall architecture is directionally good: sparse + sharded + lookup + hierarchical tensor shards + MPS + stabilizer + QEC + hardware export is the right high-level design for a large-logical-qubit DSL.
However, the v0.3.6 package should not be treated as production-complete. I found three concrete correctness/release issues and fixed them in the rebuilt v0.3.6 package:
- MPS non-adjacent two-qubit gates were wrong when the first qubit index was greater than the second, e.g.
CNOT(3, 0). export_hardware("pennylane")raised an exception when PennyLane was not installed, while other providers returned a QASM fallback.- Distributed TCP worker request threads could keep waiting for more input, making some subprocess-style tests hang after use.
I also updated metadata/dependency policy in v0.3.6:
- version bumped to
0.3.6; - author/maintainer kept as
Karthik V; - core dependency changed to include
numpy>=1.26, because MPS/hierarchical functionality is advertised as a primary feature; - placeholder
example.comproject URLs replaced with PyPI links; - wheel metadata retains optional extras for Qiskit, Cirq, Braket, PennyLane, GPU, Stim, and PyMatching.
Test results
v0.3.6 baseline tests
- Included test suite: 23 tests passed, 0 failed.
- Python source compilation: passed.
- Example translation/compilation: 800 examples compiled, 0 failed.
- Example execution: 797 examples passed, 3 failed.
The 3 failing examples were:
745_scenario_hardware_calibration_05.sq751_scenario_hardware_calibration_11.sq757_scenario_hardware_calibration_17.sq
Cause: each example called export_hardware("pennylane"); without PennyLane installed, the package raised QuantumError instead of returning a fallback payload.
Extra audit tests beyond bundled tests
I added targeted checks not covered by the original test suite:
- Sparse vs sharded equivalence on a mixed 6-qubit circuit.
- MPS vs sparse equivalence for non-adjacent
CNOT(3, 0). - MPS vs sparse equivalence on a mixed circuit with non-adjacent CNOT, SWAP, RZZ, Ry.
- Hierarchical bridge promotion sanity.
- 150-qubit sparse/sharded state sanity.
- Wheel content inspection.
- Training/scenario dataset manifest and count checks.
v0.3.6 fixed package validation
- Included test suite: 23 tests passed, 0 failed.
- Example translation/compilation: 800 examples compiled, 0 failed.
- Former PennyLane-failing examples: all passed with fallback payloads.
- MPS reversed non-adjacent CNOT test: passed.
- Mixed MPS vs sparse test: passed.
- Wheel contains:
- 34 Python modules
- 800 packaged
.sqexamples - 19 packaged markdown docs
- 10 packaged data/training/lookup files
- no
__pycache__or.pycfiles
twine check was not run because twine is not installed in this container.
Bugs fixed in v0.3.6
1. MPS non-adjacent reversed two-qubit gates
Problem:
q = quantum_register(4)
H(q[3])
CNOT(q[3], q[0])
The MPS backend produced the wrong target correlation when q0 > q1 and the two sites were non-adjacent.
Fix:
- transform the 4x4 matrix into swapped site order with
SWAP @ U @ SWAP; - then reuse the left-to-right MPS two-site path.
2. PennyLane export fallback
Problem:
print(export_hardware("pennylane"))
raised an exception when PennyLane was missing.
Fix:
- PennyLane now matches Qiskit/Cirq/Braket behavior:
- use native adapter when installed;
- otherwise return an OpenQASM 3 fallback payload plus install hint.
3. Distributed worker subprocess hang risk
Problem:
The TCP worker request handler could continue waiting for additional input on the same request connection.
Fix:
- worker server now has
daemon_threads = True; - client calls
sock.shutdown(socket.SHUT_WR)after sending one JSON request.
Design analysis
What is strong
Sparse + sharded is the right foundation
Sansqrit correctly avoids claiming arbitrary dense 120-qubit simulation. Sparse state maps plus sharding are appropriate for large logical registers when the active amplitude count remains small.
Hierarchical 10-qubit blocks are valid with a bridge rule
The hierarchical tensor-shard strategy is mathematically valid when:
- local operations stay inside independent 10-qubit blocks; and
- cross-block gates promote the representation to MPS/tensor-network form instead of pretending the blocks remain independent.
The package follows this direction.
Lookup files are useful but should be treated as a middle-layer accelerator
The packaged lookup files are appropriate for:
- static single-qubit matrices;
- static two-qubit matrices;
- embedded <=10-qubit transition tables;
- small block accelerators.
They cannot make arbitrary dense 120-qubit simulation feasible.
QEC module is useful for education and AI training
The QEC module includes logical qubits, code registries, syndrome extraction helpers, and decoder interfaces. This is useful, but the built-in surface-code decoder should remain labelled educational unless a full MWPM graph is implemented.
What is still missing for industry-grade parity
1. True adaptive backend planner
Current planning is useful but should become mandatory for engine("auto").
Add:
- estimated active amplitudes;
- Clifford/non-Clifford count;
- T-count/magic-state cost;
- entanglement graph;
- MPS bond-dimension estimate;
- memory estimate;
- backend decision explanation;
- safe refusal for impossible dense runs.
2. Real distributed execution plan
Current distributed mode is correctness-first and coordinator-driven. For real cluster performance, add:
- worker-local single-qubit gate execution;
- pairwise shard exchange for cross-shard two-qubit gates;
- batched gate execution;
- compressed amplitude transfer;
- checkpoint/restart;
- optional Ray/Dask/MPI transport.
3. Production QEC decoder
Add real surface-code decoding:
- construct detector graph from syndrome circuits;
- integrate PyMatching MWPM directly;
- support repeated syndrome rounds;
- support circuit-level noise;
- support logical error-rate estimation;
- export Stim detector-error models.
4. Formal cross-simulator verification
Add optional validation suites:
- compare small circuits against Qiskit Aer;
- compare Clifford/QEC circuits against Stim;
- compare MPS low-entanglement circuits against dense sparse/statevector for <=20 qubits;
- compare QASM export/import round trips.
5. Stronger OpenQASM 3 support
The exporter should eventually support:
- mid-circuit measurement;
- classical control;
- timing/delay/duration;
- calibration blocks;
- extern declarations;
- hardware-native gate set decomposition.
6. Benchmark suite
Add repeatable benchmarks:
- sparse 150q oracle;
- 1000q stabilizer Clifford graph;
- MPS 500q chain;
- QEC surface-code d=3/d=5;
- 20–30q dense statevector;
- lookup-hit benchmark;
- distributed sparse benchmark.
7. Lookup block compiler
The next improvement for lookup speed is not packaging every possible circuit. It is:
- detect static <=10-qubit blocks;
- fuse gates;
- hash the block;
- generate/cache the fused unitary or transition map;
- reuse across runs.
8. Data-quality tooling for AI training
The synthetic dataset should add quality gates:
- JSON schema validation;
- duplicates/near-duplicates report;
- code execution result attached to records;
- backend label verification;
- rejected-output taxonomy;
- eval set with hidden answers;
- citation/license metadata.
Recommendation before PyPI upload
Upload the fixed package as 0.3.6, not 0.3.6, if 0.3.6 has already been uploaded.
Run locally before upload:
python -m pip install --upgrade build twine
python -m twine check dist/*
python -m twine upload dist/*
Then verify:
python -m venv /tmp/sansqrit-check
source /tmp/sansqrit-check/bin/activate
pip install sansqrit==0.3.6
sansqrit doctor
sansqrit dataset info
sansqrit scenarios info
python - <<'PY'
from sansqrit import QuantumEngine
e = QuantumEngine.create(2)
e.H(0)
e.CNOT(0, 1)
print(e.probabilities())
PY
Final status
The v0.3.6 package is safer to upload than the v0.3.6 package because it fixes the concrete MPS, hardware-export, and distributed-worker issues found during the audit.
The design is promising, but for claims like "on par with Qiskit/Azure/AWS," the package should be described as an alpha/research DSL with multiple execution strategies, not yet a production cloud runtime or calibrated hardware compiler.
Disclaimer and Current Limitations
This bottom section collects the practical limitations that users, students, scientists, and evaluators should understand before making technical claims, publishing benchmark statements, or integrating the package into a larger workflow. The goal is transparency: the package can be useful and ambitious while still being honest about what is currently approximate, optional, experimental, or environment-dependent.
Simulation scale
Arbitrary dense 120-qubit state-vector simulation is not feasible on a local Python package. Large logical circuits require sparse, sharded, stabilizer, MPS, hierarchical, or distributed assumptions.
Backend dependence
Actual behavior depends on circuit structure. Some workflows are exact for the selected representation, while others are approximate or only valid when separability, sparsity, low entanglement, or Clifford structure is present.
Hardware export
Export adapters generate representations for other ecosystems, but successful execution on IBM, AWS, Azure, PennyLane, CUDA-Q, or other providers still depends on credentials, SDKs, gate support, topology, and provider availability.
Optional modules
GPU, cloud, interoperability, and some advanced tooling paths require optional dependencies. Without them, the package may fall back to slower local logic or disable certain features entirely.
QEC and noise
Quantum error-correction helpers and noise workflows are primarily educational/research utilities unless backed by validated decoders, calibrated device assumptions, and external benchmarking.
AI datasets
The packaged datasets are useful for assistants, tutorials, and local model training, but examples and labels should still be validated before use in automated pipelines or scientific claims.
- Performance numbers vary by hardware, Python version, optional libraries, and circuit structure.
- Lookup tables accelerate selected operations, but they do not remove exponential scaling for general quantum simulation.
- Approximate tensor-network or hierarchical modes can require cutoff, truncation, and structure-aware interpretation.
- Exported circuits may need additional transpilation, routing, calibration awareness, or provider-specific adaptation.
- Examples on this website are teaching artifacts; they are not a replacement for independent verification, profiling, and experiment design.
- APIs, packaged data layout, and experimental features can evolve across releases.