Skip to main content

Block-encoding primitives and semantic execution for classical simulation.

Project description

QuBlock

QuBlock is a lightweight Python library for block-encoding primitives, semantic simulation on statevectors, and OpenQASM export. The pip package name is qublock, and the import namespace is blockflow.

Highlights

  • Explicit block-encoding invariants with normalization, error tolerance, and success tracking.
  • Fast semantic execution for algorithm validation without circuits.
  • Recipe-based circuits with declared wire requirements.
  • OpenQASM 2 or 3 export with a minimal gate set.
  • Small dependency footprint (NumPy only at runtime).

Requirements

  • Python 3.9+
  • NumPy >= 1.22

Installation

python -m pip install -e .

Dev tools:

python -m pip install -e .[dev]

Quickstart

Semantic execution

import numpy as np

from blockflow import (
    ApplyBlockEncodingStep,
    BlockEncoding,
    NumpyMatrixOperator,
    Program,
    ResourceEstimate,
    SemanticExecutor,
    StateVector,
)

mat = np.array([[0, 1], [1, 0]], dtype=complex)
op = NumpyMatrixOperator(mat)
be = BlockEncoding(op=op, alpha=1.0, resources=ResourceEstimate())

program = Program([ApplyBlockEncodingStep(be)])
state = StateVector(np.array([1.0, 0.0], dtype=complex))
final_state, report = SemanticExecutor().run(program, state, renormalize_each_step=True)

Attach a circuit recipe and export QASM

from blockflow import (
    Capabilities,
    Circuit,
    StaticCircuitRecipe,
    WireSpec,
)

circ = Circuit(num_qubits=1)
circ.add("h", [0])
recipe = StaticCircuitRecipe(WireSpec(system_qubits=1), circ)

be_with_recipe = BlockEncoding(
    op=op,
    alpha=1.0,
    resources=ResourceEstimate(),
    recipe=recipe,
    capabilities=Capabilities(supports_circuit_recipe=True),
)
qasm = be_with_recipe.export_openqasm(flavor="qasm3")

Core concepts

  • Linear operators: implement the LinearOperator protocol (shape, apply, apply_adjoint).
  • Block encodings: BlockEncoding wraps an operator with alpha, epsilon, resources, and recipes.
  • Vector encodings: VectorEncoding represents normalized state-prep with optional recipes.
  • Capabilities and success: Capabilities and SuccessModel capture supported operations and postselection success rates.
  • Resources: ResourceEstimate tracks ancillas, depth, and gate counts.
  • Recipes and circuits: CircuitRecipe produces backend-agnostic Circuit objects with a WireSpec.
  • QASM export: to_openqasm emits a minimal gate set to QASM2/QASM3.

Semantic execution

SemanticExecutor applies each program step directly to the system statevector. This is useful for validating algorithmic structure before committing to a specific circuit implementation.

program = Program([ApplyBlockEncodingStep(be)])
state = StateVector(np.array([1.0, 0.0], dtype=complex))
final_state, report = SemanticExecutor().run(program, state)

The RunReport accumulates uses, success probabilities, and ancilla peaks.

Circuits, recipes, and OpenQASM

Recipes declare required wires and return a backend-agnostic circuit. The block encoding verifies that the recipe matches its resource claims.

from blockflow import Capabilities, Circuit, StaticCircuitRecipe, WireSpec

circ = Circuit(num_qubits=2)
circ.add("h", [0])
circ.add("cx", [0, 1])

recipe = StaticCircuitRecipe(WireSpec(system_qubits=2), circ)
be = BlockEncoding(
    op=op,
    alpha=1.0,
    resources=ResourceEstimate(),
    recipe=recipe,
    capabilities=Capabilities(supports_circuit_recipe=True),
)

qasm3 = be.export_openqasm(flavor="qasm3")
qasm2 = be.export_openqasm(flavor="qasm2", optimize=False)

Export currently supports a minimal gate set (h, x, y, z, s, t, cx, cz, swap, rx, ry, rz, and measure) plus controlled variants in QASM3.

Matrix to block-encoding synthesis (n-qubit)

If you have a 2^n x 2^n matrix, QuBlock can synthesize a block-encoding circuit without attaching a recipe. There are two paths:

  • If A / alpha is unitary (2x2 only), it synthesizes a 1-qubit circuit that implements it.
  • Otherwise, it builds an LCU block encoding using the Pauli expansion of A (requires alpha == sum(|Pauli coeffs|)).

For LCU synthesis you can choose a strategy:

  • prep_select uses ceil(log2(m)) ancillas (plus one phase ancilla if needed) and multi-controlled select gates, where m is the number of nonzero Pauli terms.
  • sparse uses one ancilla per term and single-controlled select gates.

Both LCU strategies export only to QASM3 because they use controlled rotations.

mat = np.array([[0, 1], [1, 0]], dtype=complex)
be = BlockEncoding(
    op=NumpyMatrixOperator(mat),
    alpha=1.0,
    resources=ResourceEstimate(),
    capabilities=Capabilities(supports_circuit_recipe=True),
    synthesis_strategy="prep_select",  # or "sparse"
)
qasm = be.export_openqasm()

Optimization

Use optimize_circuit to apply simple peephole optimizations, or disable it when you need a 1:1 recipe export.

optimized = be.build_circuit(optimize=True)
raw = be.build_circuit(optimize=False)

Examples and notebooks

  • notebooks/lcu_demo.ipynb walks through LCU synthesis and QASM export.

Development

Tests run with coverage enforcement:

pytest

Ruff is configured for linting and import sorting:

ruff check .

Optional Qiskit cross-check

tests/test_qiskit_integration.py compares QASM output against Qiskit statevector simulation. Install Qiskit to enable those tests.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qublock-0.1.0.tar.gz (27.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qublock-0.1.0-py3-none-any.whl (23.6 kB view details)

Uploaded Python 3

File details

Details for the file qublock-0.1.0.tar.gz.

File metadata

  • Download URL: qublock-0.1.0.tar.gz
  • Upload date:
  • Size: 27.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for qublock-0.1.0.tar.gz
Algorithm Hash digest
SHA256 82170c2d1666af1c441d46451fcf7c23292e66911eb85d8146fff168102e4b03
MD5 4a42daa0e34e0b1cbc5fea8d23217883
BLAKE2b-256 22cbaf2768f7006812dd9c2d5804ca3393f437b9654ddca0a0e0727f9bfe8f7b

See more details on using hashes here.

Provenance

The following attestation bundles were made for qublock-0.1.0.tar.gz:

Publisher: python-publish.yml on EthanFeld/QuBlock

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qublock-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: qublock-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for qublock-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cf0501e0edbad4fb0198b439d30d74a72ffffa8fc642bd22421651f1d0399763
MD5 32895ca38bee131ffb25ae40d4a97096
BLAKE2b-256 29f585598d41af3ef4651f8c6d785e474e2b7b7343485cf4d4337845df76f657

See more details on using hashes here.

Provenance

The following attestation bundles were made for qublock-0.1.0-py3-none-any.whl:

Publisher: python-publish.yml on EthanFeld/QuBlock

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page