diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0aa6667 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,21 @@ +# VCS +.git/ +.gitignore + +# Python build artifacts +*.egg-info/ +__pycache__/ +*.py[cod] +*.so +build/ +dist/ +.eggs/ + +# Packaging outputs (avoid re-bundling previous build products) +debian-packages/ +rpm-packages/ + +# Editor / OS +.vscode/ +.idea/ +.DS_Store diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml new file mode 100644 index 0000000..2ed930d --- /dev/null +++ b/.github/workflows/build-deb.yml @@ -0,0 +1,36 @@ +name: Build Debian Packages + +on: + push: + tags: + - 'v*' + pull_request: + branches: [main] + paths: + - 'packaging/debian/**' + - 'flagquantum/**' + - 'pyproject.toml' + - '.github/workflows/build-deb.yml' + workflow_dispatch: + +jobs: + build-deb: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build .deb + run: bash packaging/debian/build-helpers/build-flagquantum.sh + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: flagquantum-amd64-packages + path: debian-packages/*.deb + retention-days: 7 diff --git a/.github/workflows/build-rpm.yml b/.github/workflows/build-rpm.yml new file mode 100644 index 0000000..c05a2b1 --- /dev/null +++ b/.github/workflows/build-rpm.yml @@ -0,0 +1,36 @@ +name: Build RPM Packages + +on: + push: + tags: + - 'v*' + pull_request: + branches: [main] + paths: + - 'packaging/rpm/**' + - 'flagquantum/**' + - 'pyproject.toml' + - '.github/workflows/build-rpm.yml' + workflow_dispatch: + +jobs: + build-rpm: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build .rpm + run: bash packaging/rpm/build-flagquantum-rpm.sh + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: flagquantum-amd64-rpm-packages + path: rpm-packages/*.rpm + retention-days: 7 diff --git a/packaging/INSTALL.md b/packaging/INSTALL.md new file mode 100644 index 0000000..8bd92fe --- /dev/null +++ b/packaging/INSTALL.md @@ -0,0 +1,25 @@ +# Installing python3-flagquantum + +After `apt install python3-flagquantum` (Debian/Ubuntu) or `dnf install python3-flagquantum` (Fedora), +install the ML runtime separately — it is intentionally **not** declared as a +hard Depends/Requires because the distro versions are CPU-only (torch) or +too old (triton) for GPU workloads. + +FlagQuantum needs PyTorch (GPU build) at runtime: + +```bash +pip install --index-url https://download.pytorch.org/whl/cu128 torch==2.9.0+cu128 +``` + +A `venv` is recommended to isolate pip-installed packages from the system +Python: + +```bash +python3 -m venv ~/.venv/flagos +source ~/.venv/flagos/bin/activate +# then the pip install lines above +``` + +Note: the distro `python3-torch` package (CPU-only build) is intentionally +not pulled in — FlagOS workloads need a GPU build, which PyTorch upstream +distributes via PyPI (per-CUDA-version wheels), not as a `.deb` / `.rpm`. diff --git a/packaging/debian/build-helpers/Dockerfile.deb b/packaging/debian/build-helpers/Dockerfile.deb new file mode 100644 index 0000000..406e255 --- /dev/null +++ b/packaging/debian/build-helpers/Dockerfile.deb @@ -0,0 +1,32 @@ +ARG BASE_IMAGE_VERSION=24.04 +FROM ubuntu:${BASE_IMAGE_VERSION} +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential debhelper devscripts dpkg-dev fakeroot \ + dh-python pybuild-plugin-pyproject \ + python3-all python3-pip python3-setuptools python3-wheel \ + git ca-certificates \ + lintian \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + + +COPY . /workspace/FlagQuantum +WORKDIR /workspace/FlagQuantum + +RUN cp -r packaging/debian debian + +RUN dpkg-buildpackage -us -uc -b || \ + { echo "=== build failed ===" >&2; \ + find /workspace -name "*.log" -exec echo "=== {} ===" \; -exec cat {} \; 2>/dev/null || true; \ + exit 1; } + +# Run lintian against the produced .deb — surface packaging warnings +# (unused-license-paragraph, no-manual-page, missing-build-dependency, etc.) +# in the build log without failing the build. +RUN lintian --info --display-info /workspace/python3-flagquantum_*.deb || true + +RUN mkdir -p /output && \ + find /workspace -maxdepth 1 -name "*.deb" -exec cp {} /output/ \; && \ + find /workspace -maxdepth 1 -name "*.changes" -exec cp {} /output/ \; && \ + ls -lh /output/ diff --git a/packaging/debian/build-helpers/build-flagquantum.sh b/packaging/debian/build-helpers/build-flagquantum.sh new file mode 100755 index 0000000..b3ee1e3 --- /dev/null +++ b/packaging/debian/build-helpers/build-flagquantum.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$(dirname "$(dirname "$SCRIPT_DIR")")")" +BASE_IMAGE_VERSION="${1:-24.04}" +IMAGE_TAG="flagquantum-deb:${BASE_IMAGE_VERSION}" +OUTPUT_DIR="${PROJECT_DIR}/debian-packages" + +docker build --network=host \ + -f "${SCRIPT_DIR}/Dockerfile.deb" \ + --build-arg BASE_IMAGE_VERSION="$BASE_IMAGE_VERSION" \ + -t "$IMAGE_TAG" "$PROJECT_DIR" + +mkdir -p "$OUTPUT_DIR" +CID=$(docker create "$IMAGE_TAG") +docker cp "$CID:/output/." "$OUTPUT_DIR/" +docker rm "$CID" > /dev/null + +echo ""; echo ">>> Output:"; ls -lh "$OUTPUT_DIR" diff --git a/packaging/debian/changelog b/packaging/debian/changelog new file mode 100644 index 0000000..00ab5a4 --- /dev/null +++ b/packaging/debian/changelog @@ -0,0 +1,5 @@ +flagquantum (0.1.0-1) unstable; urgency=medium + + * Initial Debian packaging. + + -- FlagOS Contributors Tue, 12 May 2026 12:00:00 +0000 diff --git a/packaging/debian/control b/packaging/debian/control new file mode 100644 index 0000000..99290da --- /dev/null +++ b/packaging/debian/control @@ -0,0 +1,23 @@ +Source: flagquantum +Section: python +Priority: optional +Maintainer: FlagOS Contributors +Build-Depends: debhelper-compat (= 13), + dh-python, + python3-all, + python3-setuptools, + python3-wheel, + pybuild-plugin-pyproject +Standards-Version: 4.6.2 +Homepage: https://github.com/flagos-ai/FlagQuantum +Vcs-Browser: https://github.com/flagos-ai/FlagQuantum +Vcs-Git: https://github.com/flagos-ai/FlagQuantum.git +Rules-Requires-Root: no + +Package: python3-flagquantum +Architecture: all +Depends: python3:any, ${misc:Depends}, python3-numpy +# python3-torch is intentionally NOT declared. The distro 'python3-torch' is +# CPU-only; users install matching CUDA torch via pip — see packaging/INSTALL.md. +Description: FlagQuantum — quantum state-vector simulator for FlagOS + High-performance distributed quantum statevector simulator built on the FlagOS unified multi-chip backend. diff --git a/packaging/debian/copyright b/packaging/debian/copyright new file mode 100644 index 0000000..95096f0 --- /dev/null +++ b/packaging/debian/copyright @@ -0,0 +1,23 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: FlagQuantum +Upstream-Contact: FlagOS Contributors +Source: https://github.com/flagos-ai/FlagQuantum + +Files: * +Copyright: 2024-2026 Beijing Academy of Artificial Intelligence (BAAI) + 2024-2026 FlagQuantum contributors +License: Apache-2.0 + +License: Apache-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + . + On Debian systems, the full text of the Apache 2.0 License is in + /usr/share/common-licenses/Apache-2.0. diff --git a/packaging/debian/rules b/packaging/debian/rules new file mode 100755 index 0000000..e862ef8 --- /dev/null +++ b/packaging/debian/rules @@ -0,0 +1,31 @@ +#!/usr/bin/make -f +export DH_VERBOSE = 1 +export PYBUILD_NAME = flagquantum + +%: + dh $@ --with python3 --buildsystem=pybuild + +# Smoke find_spec test (not actual import) — verifies the built +# module lands at the expected path. Doesn't import the module +# because module-level deps (torch, triton, cupy, ...) are install- +# time concerns not satisfied in the build container. Catches: +# wrong install path, missing __init__.py, dh_python install bugs. +override_dh_auto_test: + @echo "=== smoke find_spec test ===" + # Use found_dir + break (not `&& exit 0` inside the loop) so future + # multi-Python builds verify every interpreter rather than stopping + # at the first match. + @found_dir=""; \ + for d in .pybuild/cpython3_*/build; do \ + if [ -d "$$d/flagquantum" ]; then \ + found_dir="$$d"; \ + break; \ + fi; \ + done; \ + if [ -z "$$found_dir" ]; then \ + echo "ERROR: could not find a built flagquantum module"; \ + exit 1; \ + fi; \ + echo "Found build dir: $$found_dir"; \ + PYTHONDONTWRITEBYTECODE=1 PYTHONSAFEPATH=1 PYTHONPATH="$$found_dir" python3 -c \ + "import importlib.util; s = importlib.util.find_spec('flagquantum'); assert s and s.origin, 'flagquantum not findable'; print('OK: flagquantum at', s.origin)" diff --git a/packaging/debian/source/format b/packaging/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/packaging/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/packaging/rpm/build-flagquantum-rpm.sh b/packaging/rpm/build-flagquantum-rpm.sh new file mode 100755 index 0000000..ce0df45 --- /dev/null +++ b/packaging/rpm/build-flagquantum-rpm.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")" +BASE_IMAGE_VERSION="${1:-43}" +IMAGE_TAG="flagquantum-rpm:f${BASE_IMAGE_VERSION}" +OUTPUT_DIR="${PROJECT_DIR}/rpm-packages" + +docker build --network=host \ + -f "${SCRIPT_DIR}/dockerfiles/Dockerfile.rpm" \ + --build-arg BASE_IMAGE_VERSION="$BASE_IMAGE_VERSION" \ + -t "$IMAGE_TAG" "$PROJECT_DIR" + +mkdir -p "$OUTPUT_DIR" +CID=$(docker create "$IMAGE_TAG") +docker cp "$CID:/output/." "$OUTPUT_DIR/" +docker rm "$CID" > /dev/null + +echo ""; echo ">>> Output:"; ls -lh "$OUTPUT_DIR" diff --git a/packaging/rpm/dockerfiles/Dockerfile.rpm b/packaging/rpm/dockerfiles/Dockerfile.rpm new file mode 100644 index 0000000..380fc40 --- /dev/null +++ b/packaging/rpm/dockerfiles/Dockerfile.rpm @@ -0,0 +1,30 @@ +ARG BASE_IMAGE=fedora +ARG BASE_IMAGE_VERSION=43 + +FROM ${BASE_IMAGE}:${BASE_IMAGE_VERSION} + +RUN dnf install -y \ + rpm-build rpmdevtools pyproject-rpm-macros \ + python3-devel python3-setuptools python3-wheel python3-pip \ + && dnf clean all + +RUN rpmdev-setuptree + +COPY . /workspace/FlagQuantum + +RUN SPEC_VERSION=$(grep '^Version:' /workspace/FlagQuantum/packaging/rpm/specs/flagquantum.spec | awk '{print $2}') && \ + tar czf /root/rpmbuild/SOURCES/flagquantum-${SPEC_VERSION}.tar.gz \ + -C /workspace/FlagQuantum \ + --exclude='./.git' \ + --transform "s|^\./|flagquantum-${SPEC_VERSION}/|" \ + . + +RUN rpmbuild -ba /workspace/FlagQuantum/packaging/rpm/specs/flagquantum.spec 2>&1 || \ + { echo "=== build failed ==="; \ + find /root/rpmbuild -name "*.log" -exec echo "=== {} ===" \; -exec cat {} \; 2>/dev/null || true; \ + exit 1; } + +RUN mkdir -p /output && \ + find /root/rpmbuild/RPMS -name "*.rpm" -exec cp {} /output/ \; && \ + find /root/rpmbuild/SRPMS -name "*.rpm" -exec cp {} /output/ \; && \ + ls -lh /output/ diff --git a/packaging/rpm/specs/flagquantum.spec b/packaging/rpm/specs/flagquantum.spec new file mode 100644 index 0000000..b12c7d1 --- /dev/null +++ b/packaging/rpm/specs/flagquantum.spec @@ -0,0 +1,55 @@ +%global debug_package %{nil} + +# Filter the auto-generated Requires for: torch. +# Reason: distro torch is CPU-only; users install GPU torch via pip. +# See packaging/INSTALL.md (or future flagos-packaging install docs) for the +# user-side pip install incantation. +%global __requires_exclude ^python3(\.[0-9]+)?dist\((torch)\)$ +Name: python3-flagquantum +Version: 0.1.0 +Release: 1%{?dist} +Summary: FlagQuantum — quantum state-vector simulator for FlagOS + +License: Apache-2.0 +URL: https://github.com/flagos-ai/FlagQuantum +Source0: %{url}/archive/refs/tags/v%{version}.tar.gz#/flagquantum-%{version}.tar.gz +BuildArch: noarch +BuildRequires: python3-devel +BuildRequires: python3-setuptools >= 60 +BuildRequires: python3-wheel +BuildRequires: python3-pip +BuildRequires: pyproject-rpm-macros + +Requires: python3-numpy + +%description +High-performance distributed quantum statevector simulator built on the FlagOS unified multi-chip backend. + +%prep +%autosetup -n flagquantum-%{version} + +%build +%pyproject_wheel + +%install +%pyproject_install +%pyproject_save_files flagquantum + +%check +# Smoke find_spec test (no actual import) — verifies the built module +# lands at the expected sitelib path. Doesn't import the module so +# missing runtime deps (torch, triton, ...) don't trip the check; +# those are user-install-time concerns, not packaging concerns. +# PYTHONSAFEPATH=1 keeps the cwd (the unpacked source tree, which also +# contains flagquantum/) off sys.path, so find_spec resolves against the +# installed copy under PYTHONPATH, not the source tree. +PYTHONDONTWRITEBYTECODE=1 PYTHONSAFEPATH=1 \ + PYTHONPATH=%{buildroot}%{python3_sitelib} \ + python3 -c "import importlib.util; s = importlib.util.find_spec('flagquantum'); assert s and s.origin, 'flagquantum not findable'; print('OK: flagquantum at', s.origin)" + +%files -f %{pyproject_files} +%license LICENSE + +%changelog +* Wed May 13 2026 FlagOS Contributors - 0.1.0-1 +- Initial RPM packaging.