Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: pypi

on:
workflow_dispatch:
push:
tags:
- "v*"

jobs:
build-wheels:
name: Build wheels (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Build wheels
uses: pypa/cibuildwheel@v2.22.0
env:
CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-*"
CIBW_SKIP: "*-musllinux_* pp* *-win32 *_i686"
CIBW_ARCHS_MACOS: "x86_64 arm64"
CIBW_ENVIRONMENT: "CMAKE_BUILD_PARALLEL_LEVEL=2"

- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: wheelhouse/*.whl

build-sdist:
name: Build sdist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Build sdist
run: |
python -m pip install --upgrade pip build
python -m build --sdist

- uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz

publish:
name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags/v')
needs: [build-wheels, build-sdist]
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
pattern: wheels-*
path: dist
merge-multiple: true

- uses: actions/download-artifact@v4
with:
name: sdist
path: dist

- name: Publish
uses: pypa/gh-action-pypi-publish@release/v1

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ rules.ninja

# Binaries
lidmas
!python/lidmas/
!python/lidmas/__init__.py
!python/lidmas/__main__.py
*.exe
*.out
*.a
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ add_executable(lidmas_surface

target_include_directories(lidmas_surface PRIVATE include)

# Install CLI binary into the Python package layout used by scikit-build-core.
# This enables `pip install lidmas` to provide a bundled executable invoked by
# the Python console entrypoint.
install(TARGETS lidmas
RUNTIME DESTINATION lidmas/_bin
)

if(OpenMP_CXX_FOUND)
message(STATUS "OpenMP found via find_package")
target_link_libraries(lidmas PRIVATE OpenMP::OpenMP_CXX)
Expand Down
52 changes: 42 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ surface-code threshold experiments under discrete Pauli noise and hybrid
continuous-variable (CV)-discrete noise models as the primary workflow. It also
includes CSS and LDPC engine paths for comparative studies.

Install from PyPI:

```bash
python -m pip install --upgrade lidmas
```

Then run:

```bash
lidmas --help
```

Documentation:

- [GitHub Pages Documentation](https://denniswayo.github.io/lidmas_cpp/)
- Read the Docs mirror is currently unavailable.

## Statement of Need

Benchmarking decoder behavior and threshold trends requires reproducible, scriptable,
Expand All @@ -21,7 +38,7 @@ and inspectable simulation pipelines. LiDMaS+ provides:
- deterministic Monte Carlo runs with explicit seed control,
- multiple decoders under a common interface,
- confidence-interval-aware threshold outputs,
- publication-ready CSV and figure workflows in `examples/`.
- numerous reproducible workflows and scripts across `examples/`.

This makes it suitable for method development, reproducibility appendices, and
comparative decoder studies.
Expand Down Expand Up @@ -56,6 +73,13 @@ Primary executable:

- `build/lidmas`

## Packaging Notes

- Brand name remains **LiDMaS+**.
- PyPI package name is `lidmas`.
- CLI command is `lidmas`.
- Published wheels are CPU-oriented; CUDA builds are supported from source builds.

### Optional CUDA build (Pauli surface_threshold sampling)

```bash
Expand Down Expand Up @@ -202,7 +226,7 @@ For quick validation in local or CI environments:

## Hardware Integration

See [docs/hardware-integration.md](/Users/denniswayo/lidmas_cpp/docs/hardware-integration.md) for the decoder IO schema,
See [hardware-integration](https://denniswayo.github.io/lidmas_cpp/hardware-integration/) for the decoder IO schema,
recommended data transport, and adapter API.

## Project Layout
Expand All @@ -221,14 +245,22 @@ GitHub Releases.
## Citation

If you use LiDMaS+ in academic work, cite the software release used for your
experiments (tag + commit hash). If a JOSS/arXiv record is available for your
release, cite that record directly.

Suggested software citation format:

```text
Wayo, D. (Year). LiDMaS+ (Version X.Y.Z) [Computer software].
https://github.com/DennisWayo/lidmas_cpp
experiments (tag + commit hash).

Paper reference (`paper_01`):

![paper_01 graphic](docs/images/paper_01_graphic.png)

```bibtex
@misc{wayo2026decoder,
title={Decoder Performance in Hybrid CV-Discrete Surface-Code Threshold Estimation Using LiDMaS+},
author={Dennis Delali Kwesi Wayo and Chinonso Onah and Vladimir Milchakov and Leonardo Goliatt and Sven Groppe},
year={2026},
eprint={2603.06730},
archivePrefix={arXiv},
primaryClass={quant-ph},
url={https://arxiv.org/abs/2603.06730}
}
```

## License
Expand Down
Binary file added docs/images/paper_01_graphic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[build-system]
requires = ["scikit-build-core>=0.9"]
build-backend = "scikit_build_core.build"

[project]
name = "lidmas"
version = "1.1.0"
description = "LiDMaS+ (Logical Injection & Decoding Modeling System) quantum error-correction simulator"
readme = "README.md"
requires-python = ">=3.9"
license = { file = "LICENSE" }
authors = [
{ name = "Dennis Delali Kwesi Wayo" }
]
keywords = ["quantum", "qec", "surface-code", "decoder", "simulation"]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: C++",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Topic :: Scientific/Engineering :: Physics"
]

[project.urls]
Homepage = "https://github.com/DennisWayo/lidmas_cpp"
Repository = "https://github.com/DennisWayo/lidmas_cpp"

[project.scripts]
lidmas = "lidmas.__main__:main"

[tool.scikit-build]
cmake.version = ">=3.16"
cmake.build-type = "Release"
wheel.packages = ["python/lidmas"]

9 changes: 9 additions & 0 deletions python/lidmas/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""LiDMaS+ Python launcher package."""

from importlib.metadata import PackageNotFoundError, version

try:
__version__ = version("lidmas")
except PackageNotFoundError:
__version__ = "0+local"

40 changes: 40 additions & 0 deletions python/lidmas/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Console launcher for the bundled LiDMaS+ executable."""

from __future__ import annotations

import os
import subprocess
import sys
from importlib.resources import files
from pathlib import Path


def _binary_name() -> str:
return "lidmas.exe" if os.name == "nt" else "lidmas"


def _binary_path() -> Path:
return Path(files("lidmas")).joinpath("_bin", _binary_name())


def main() -> int:
exe = _binary_path()
if not exe.exists():
print(
f"LiDMaS executable not found at '{exe}'. "
"Reinstall the package or build from source.",
file=sys.stderr,
)
return 1

cmd = [str(exe), *sys.argv[1:]]
if os.name == "nt":
return subprocess.call(cmd)

os.execv(cmd[0], cmd)
return 0


if __name__ == "__main__":
raise SystemExit(main())