diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c831196a..d165a472 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,17 +16,15 @@ jobs: env: CI: 1 steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + - uses: actions/checkout@v7 + - name: Set up uv + uses: astral-sh/setup-uv@v5 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - sudo apt install -y pandoc - python -m pip install --upgrade pip - pip install . --group test - pip freeze + - name: Install pandoc + run: sudo apt install -y pandoc + - name: Install + run: make install - name: Run test run: make test @@ -41,18 +39,13 @@ jobs: CI: 1 FUNSOR_BACKEND: torch steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + - uses: actions/checkout@v7 + - name: Set up uv + uses: astral-sh/setup-uv@v5 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - # TODO: remove once pyro-ppl releases the Uniform arg_constraints fix - # (https://github.com/pyro-ppl/pyro/pull/3453). - pip install .[torch] --group test "torch<=2.6" - pip freeze + - name: Install + run: make install - name: Run test run: make test @@ -67,17 +60,12 @@ jobs: CI: 1 FUNSOR_BACKEND: jax steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + - uses: actions/checkout@v7 + - name: Set up uv + uses: astral-sh/setup-uv@v5 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - # TODO: remove once a NumPyro release fully supports jax>=0.10 - # (temporary pin from https://github.com/pyro-ppl/funsor/pull/611). - pip install .[jax] --group test "jax<0.10" - pip freeze + - name: Install + run: make install - name: Run test run: make test diff --git a/.gitignore b/.gitignore index 096b0504..6171d485 100644 --- a/.gitignore +++ b/.gitignore @@ -124,6 +124,9 @@ celerybeat-schedule venv/ ENV/ +# uv lockfile is intentionally untracked for this library +uv.lock + # IDE settings .spyderproject .idea diff --git a/Makefile b/Makefile index 44c0ba24..845adb24 100644 --- a/Makefile +++ b/Makefile @@ -3,62 +3,67 @@ all: docs test install: - pip install -e . --group dev + uv sync docs: FORCE + uv sync --group docs --no-default-groups --inexact mkdir -p docs/source/_static - $(MAKE) -C docs html + $(MAKE) -C docs html SPHINXBUILD="uv run --no-sync sphinx-build" lint: FORCE - ruff check --fix . - python scripts/update_headers.py --check - python test/test_import.py + uv run ruff check --fix . license: FORCE - python scripts/update_headers.py + uv run python scripts/update_headers.py format: license FORCE - ruff format . + uv run ruff format . -test: lint FORCE +test: FORCE + uv run ruff check . + uv run ruff format --check . + uv run python scripts/update_headers.py --check + uv run python test/test_import.py ifeq (${FUNSOR_BACKEND}, torch) - pytest -v -n auto test/ - FUNSOR_DEBUG=1 pytest -v test/test_gaussian.py - FUNSOR_PROFILE=99 pytest -v test/test_einsum.py - FUNSOR_USE_TCO=1 pytest -v test/test_terms.py - FUNSOR_USE_TCO=1 pytest -v test/test_einsum.py - python examples/adam.py -n 2 - python examples/discrete_hmm.py -n 2 - python examples/discrete_hmm.py -n 2 -t 50 --lazy - FUNSOR_USE_TCO=1 python examples/discrete_hmm.py -n 1 -t 50 --lazy - FUNSOR_USE_TCO=1 python examples/discrete_hmm.py -n 1 -t 500 --lazy - python examples/forward_backward.py -t 3 - python examples/kalman_filter.py -n 2 - python examples/kalman_filter.py -n 2 -t 50 --lazy - FUNSOR_USE_TCO=1 python examples/kalman_filter.py -n 1 -t 50 --lazy - FUNSOR_USE_TCO=1 python examples/kalman_filter.py -n 1 -t 500 --lazy - python examples/minipyro.py - python examples/minipyro.py --jit - python examples/slds.py -n 2 -t 50 - python examples/pcfg.py --size 3 - python examples/talbot.py -n 2 - python examples/vae.py --smoke-test - python examples/eeg_slds.py --num-steps 2 --fon --test - python examples/mixed_hmm/experiment.py -d seal -i discrete -g discrete -zi --smoke - python examples/mixed_hmm/experiment.py -d seal -i discrete -g discrete -zi --parallel --smoke - python examples/sensor.py --seed=0 --num-frames=2 -n 1 - python examples/adam.py --num-steps=21 + uv sync --extra torch --inexact + uv run pytest -v -n auto test/ + FUNSOR_DEBUG=1 uv run pytest -v test/test_gaussian.py + FUNSOR_PROFILE=99 uv run pytest -v test/test_einsum.py + FUNSOR_USE_TCO=1 uv run pytest -v test/test_terms.py + FUNSOR_USE_TCO=1 uv run pytest -v test/test_einsum.py + uv run python examples/adam.py -n 2 + uv run python examples/discrete_hmm.py -n 2 + uv run python examples/discrete_hmm.py -n 2 -t 50 --lazy + FUNSOR_USE_TCO=1 uv run python examples/discrete_hmm.py -n 1 -t 50 --lazy + FUNSOR_USE_TCO=1 uv run python examples/discrete_hmm.py -n 1 -t 500 --lazy + uv run python examples/forward_backward.py -t 3 + uv run python examples/kalman_filter.py -n 2 + uv run python examples/kalman_filter.py -n 2 -t 50 --lazy + FUNSOR_USE_TCO=1 uv run python examples/kalman_filter.py -n 1 -t 50 --lazy + FUNSOR_USE_TCO=1 uv run python examples/kalman_filter.py -n 1 -t 500 --lazy + uv run python examples/minipyro.py + uv run python examples/minipyro.py --jit + uv run python examples/slds.py -n 2 -t 50 + uv run python examples/pcfg.py --size 3 + uv run python examples/talbot.py -n 2 + uv run python examples/vae.py --smoke-test + uv run python examples/eeg_slds.py --num-steps 2 --fon --test + uv run python examples/mixed_hmm/experiment.py -d seal -i discrete -g discrete -zi --smoke + uv run python examples/mixed_hmm/experiment.py -d seal -i discrete -g discrete -zi --parallel --smoke + uv run python examples/sensor.py --seed=0 --num-frames=2 -n 1 + uv run python examples/adam.py --num-steps=21 @echo PASS else ifeq (${FUNSOR_BACKEND}, jax) - pytest -v -n auto --ignore=test/examples --ignore=test/pyro --ignore=test/pyroapi \ + uv sync --extra jax --inexact + uv run pytest -v -n auto --ignore=test/examples --ignore=test/pyro --ignore=test/pyroapi \ --ignore=test/test_distribution.py --ignore=test/test_distribution_generic.py \ --ignore=test/torch - pytest -v -n auto test/test_distribution.py - pytest -v -n auto test/test_distribution_generic.py + uv run pytest -v -n auto test/test_distribution.py + uv run pytest -v -n auto test/test_distribution_generic.py @echo PASS else - # default backend - pytest -v -n auto --ignore=test/examples --ignore=test/pyro \ + # default backend; requires prior `make install` (or equivalent uv sync) + uv run pytest -v -n auto --ignore=test/examples --ignore=test/pyro \ --ignore=test/pyroapi --ignore=test/torch @echo PASS endif diff --git a/README.md b/README.md index 30d33a7a..fdd4197e 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,30 @@ git checkout master pip install . ``` +**Install using uv:** + +From PyPI: + +```sh +uv add funsor +``` + +From source (installs the project and the default `dev` dependency group): + +```sh +git clone git@github.com:pyro-ppl/funsor.git +cd funsor +git checkout master +make install # or: uv sync +``` + +Optional backends: + +```sh +uv sync --extra torch --inexact +uv sync --extra jax --inexact +``` + ## Using funsor Funsor can be used through a number of interfaces: diff --git a/pyproject.toml b/pyproject.toml index 104d3801..e453fa30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ jax = [ ] [dependency-groups] -test = [ +dev = [ "pandas", "pyro-api>=0.1.2", "pytest>=7", @@ -63,10 +63,6 @@ docs = [ "sphinx-gallery", "sphinx_rtd_theme", ] -dev = [ - { include-group = "test" }, - { include-group = "docs" }, -] [project.urls] Homepage = "https://github.com/pyro-ppl/funsor" @@ -106,6 +102,17 @@ known-first-party = ["funsor", "test"] [tool.ruff.lint.pycodestyle] max-line-length = 120 +[tool.uv] +# Temporary CI/local sync constraints (not published package metadata). +constraint-dependencies = [ + # TODO: remove once pyro-ppl releases the Uniform arg_constraints fix + # (https://github.com/pyro-ppl/pyro/pull/3453). + "torch<=2.6", + # TODO: remove once a NumPyro release fully supports jax>=0.10 + # (temporary pin from https://github.com/pyro-ppl/funsor/pull/611). + "jax<0.10", +] + [tool.pytest.ini_options] filterwarnings = [ "error",