From d1e081d3c3c9b8e1f9857d6a11f463c3dcb6c24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 13:24:37 +0200 Subject: [PATCH 01/24] nx version + update actions --- .github/workflows/build_doc.yml | 4 ++-- .github/workflows/build_tests.yml | 20 ++++++++++---------- CITATION.cff | 5 +++-- RELEASES.md | 4 ++-- ot/__init__.py | 2 +- requirements_all.txt | 2 +- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build_doc.yml b/.github/workflows/build_doc.yml index e1620683f..403a3eb7b 100644 --- a/.github/workflows/build_doc.yml +++ b/.github/workflows/build_doc.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: submodules: true # Standard drop-in approach that should work for most people. @@ -45,7 +45,7 @@ jobs: uses: rickstaa/sphinx-action@master with: docs-folder: "docs/" - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Documentation path: docs/build/html/ diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 2510004c1..d574da77a 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -27,7 +27,7 @@ jobs: - name: Checking Out Repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: submodules: true # Install Python & Packages @@ -44,12 +44,12 @@ jobs: build_from_source: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: submodules: true - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.14" - name: Build from source @@ -74,7 +74,7 @@ jobs: with: android: true dotnet: true - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: submodules: true @@ -105,12 +105,12 @@ jobs: runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'no ci')" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: submodules: true - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.14" cache: 'pip' @@ -160,11 +160,11 @@ jobs: python-version: ["3.13"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: submodules: true - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} cache: 'pip' @@ -190,11 +190,11 @@ jobs: python-version: ["3.13"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: submodules: true - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} cache: 'pip' diff --git a/CITATION.cff b/CITATION.cff index 2b0c64ac0..2c73bd3bd 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -84,11 +84,12 @@ authors: - given-names: Marco family-names: Corneli affiliation: Université Côte d'Azur - identifiers: - type: url value: 'https://github.com/PythonOT/POT' description: Code + - type: doi + value: 10.5281/zenodo.17161062 repository-code: 'https://github.com/PythonOT/POT' url: 'https://pythonot.github.io/' keywords: @@ -98,4 +99,4 @@ keywords: - wasserstein - gromov-wasserstein license: MIT -version: 0.9.5 +version: 0.9.7 diff --git a/RELEASES.md b/RELEASES.md index d74a11e82..938f65595 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,8 +1,8 @@ # Releases -## 0.9.7.dev0## 0.9.7.dev0 +## 0.9.7 -This new release adds support for sparse cost matrices and a new lazy EMD solver that computes distances on-the-fly from coordinates, reducing memory usage from O(n×m) to O(n+m). Both implementations are backend-agnostic and preserve gradient computation for automatic differentiation. +This new release adds support for sparse cost matrices and a new lazy exact OT solver that re-computes distances on-the-fly from coordinates, reducing memory usage from O(n×m) to O(n+m). Both implementations are backend-agnostic and preserve gradient computation for automatic differentiation. #### New features diff --git a/ot/__init__.py b/ot/__init__.py index deb3a087d..7455b8396 100644 --- a/ot/__init__.py +++ b/ot/__init__.py @@ -93,7 +93,7 @@ from .utils import dist, unif, tic, toc, toq -__version__ = "0.9.7.dev0" +__version__ = "0.9.7" __all__ = [ "emd", diff --git a/requirements_all.txt b/requirements_all.txt index 8a1a5f2f5..c99c824b9 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2,7 +2,7 @@ numpy>=1.20 scipy>=1.6 matplotlib autograd -pymanopt @ git+https://github.com/pymanopt/pymanopt.git@master +pymanopt cvxopt scikit-learn torch<=2.11 From 892cf5f9e78f107a6c0a71e05f6bdb7355be3283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 13:39:17 +0200 Subject: [PATCH 02/24] add run on arm --- .github/workflows/build_tests.yml | 8 +++++--- .github/workflows/build_wheels.yml | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index d574da77a..b78c2856a 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -101,14 +101,16 @@ jobs: uses: codecov/codecov-action@v4 linux-minimal-deps: - - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} if: "!contains(github.event.head_commit.message, 'no ci')" + strategy: + max-parallel: 4 + matrix: + os: [ubuntu-latest, ubuntu-24.04-arm] steps: - uses: actions/checkout@v7 with: submodules: true - - name: Set up Python uses: actions/setup-python@v6 with: diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index e0158d89d..40814c053 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -15,11 +15,11 @@ jobs: os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: submodules: true - - name: Set up Python 3.10 - uses: actions/setup-python@v5 + - name: Set up Python 3.11 + uses: actions/setup-python@v6 with: python-version: "3.11" From 15addebd3ff2cb29190aed0c6e524576ecb87a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 13:46:39 +0200 Subject: [PATCH 03/24] use slim ubuntu --- .github/workflows/build_tests.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index b78c2856a..714dd027c 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -61,7 +61,7 @@ jobs: linux: - runs-on: ubuntu-latest + runs-on: ubuntu-slim if: "!contains(github.event.head_commit.message, 'no ci')" strategy: max-parallel: 4 @@ -69,11 +69,11 @@ jobs: python-version: ["3.11", "3.12", "3.13", "3.14"] steps: - - name: Free Disk Space (Ubuntu) - uses: insightsengineering/disk-space-reclaimer@v1 - with: - android: true - dotnet: true + # - name: Free Disk Space (Ubuntu) + # uses: insightsengineering/disk-space-reclaimer@v1 + # with: + # android: true + # dotnet: true - uses: actions/checkout@v7 with: submodules: true From 6faa82be5386de4d45c7b5216d609de251c1adbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 13:57:06 +0200 Subject: [PATCH 04/24] back to linux latest --- .github/workflows/build_tests.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 714dd027c..1a2f34786 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -61,7 +61,7 @@ jobs: linux: - runs-on: ubuntu-slim + runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'no ci')" strategy: max-parallel: 4 @@ -69,11 +69,11 @@ jobs: python-version: ["3.11", "3.12", "3.13", "3.14"] steps: - # - name: Free Disk Space (Ubuntu) - # uses: insightsengineering/disk-space-reclaimer@v1 - # with: - # android: true - # dotnet: true + - name: Free Disk Space (Ubuntu) + uses: insightsengineering/disk-space-reclaimer@v1 + with: + android: true + dotnet: true - uses: actions/checkout@v7 with: submodules: true @@ -101,6 +101,7 @@ jobs: uses: codecov/codecov-action@v4 linux-minimal-deps: + runs-on: ${{ matrix.os }} if: "!contains(github.event.head_commit.message, 'no ci')" strategy: @@ -111,6 +112,7 @@ jobs: - uses: actions/checkout@v7 with: submodules: true + - name: Set up Python uses: actions/setup-python@v6 with: From 65d3f0aee8146866f2510d37fcf3089918574c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:02:34 +0200 Subject: [PATCH 05/24] reamp all tests --- .github/requirements_no_backend.txt | 9 +++ .github/workflows/build_tests.yml | 120 ++++++++++++++++++++++++---- 2 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 .github/requirements_no_backend.txt diff --git a/.github/requirements_no_backend.txt b/.github/requirements_no_backend.txt new file mode 100644 index 000000000..6c91630af --- /dev/null +++ b/.github/requirements_no_backend.txt @@ -0,0 +1,9 @@ +numpy>=1.20 +scipy>=1.6 +matplotlib +autograd +pymanopt +cvxopt +scikit-learn +pytest +cvxpy diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 1a2f34786..f85aab254 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -14,6 +14,9 @@ on: tags: - '**' +env: + PY_VERSION: "3.13" + jobs: Lint: @@ -33,7 +36,7 @@ jobs: # Install Python & Packages - uses: actions/setup-python@v6 with: - python-version: "3.14" + python-version: ${{ env.PY_VERSION }} - run: which python - name: Lint with pre-commit run: | @@ -51,7 +54,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v6 with: - python-version: "3.14" + python-version: ${{ env.PY_VERSION }} - name: Build from source run: | python -m pip install --upgrade pip setuptools wheel @@ -59,8 +62,36 @@ jobs: python setup.py sdist bdist_wheel pip install dist/*.tar.gz - linux: + linux-minimal: + + runs-on: ${{ matrix.os }} + if: "!contains(github.event.head_commit.message, 'no ci')" + strategy: + max-parallel: 4 + matrix: + os: [ubuntu-latest, ubuntu-24.04-arm] + steps: + - uses: actions/checkout@v7 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: ${{ env.PY_VERSION }} + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools + pip install pytest pytest-cov + - name: Install POT + run: | + pip install -e . + - name: Run tests + run: | + python -m pytest --durations=20 -v test/ ot/ --color=yes --cov=./ --cov-report=xml + linux: runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'no ci')" strategy: @@ -89,7 +120,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip install -r requirements_all.txt + pip install -r .github/requirements_no_backend.txt pip install pytest pytest-cov - name: test POT import run: | @@ -100,34 +131,93 @@ jobs: - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v4 - linux-minimal-deps: + linux-torch: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'no ci')" - runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v7 + with: + submodules: true + + - name: Set up Python ${{ env.PY_VERSION }} + uses: actions/setup-python@v6 + with: + python-version: ${{ env.PY_VERSION }} + cache: 'pip' + - name: Install POT + run: | + pip install -e . + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools + pip install -r .github/requirements_no_backend.txt + pip install torch torch_geometric geomloss pykeops + pip install pytest pytest-cov + - name: Run tests + run: | + python -m pytest --durations=20 -v test/ ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml + - name: Upload coverage reports to Codecov with GitHub Action + uses: codecov/codecov-action@v4 + + linux-jax: + runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'no ci')" - strategy: - max-parallel: 4 - matrix: - os: [ubuntu-latest, ubuntu-24.04-arm] + steps: - uses: actions/checkout@v7 with: submodules: true - - name: Set up Python + - name: Set up Python ${{ env.PY_VERSION }} uses: actions/setup-python@v6 with: - python-version: "3.14" + python-version: ${{ env.PY_VERSION }} cache: 'pip' + - name: Install POT + run: | + pip install -e . - name: Install dependencies run: | python -m pip install --upgrade pip setuptools + pip install -r .github/requirements_no_backend.txt + pip install jax jaxlib pip install pytest pytest-cov + - name: Run tests + run: | + python -m pytest --durations=20 -v test/ ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml + - name: Upload coverage reports to Codecov with GitHub Action + uses: codecov/codecov-action@v4 + + linux-tf: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'no ci')" + + steps: + - uses: actions/checkout@v7 + with: + submodules: true + + - name: Set up Python ${{ env.PY_VERSION }} + uses: actions/setup-python@v6 + with: + python-version: ${{ env.PY_VERSION }} + cache: 'pip' - name: Install POT run: | pip install -e . + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools + pip install -r .github/requirements_no_backend.txt + pip install tensorflow + pip install pytest pytest-cov - name: Run tests run: | - python -m pytest --durations=20 -v test/ ot/ --color=yes --cov=./ --cov-report=xml + python -m pytest --durations=20 -v test/ ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml + - name: Upload coverage reports to Codecov with GitHub Action + uses: codecov/codecov-action@v4 + # linux-minimal-deps-ft: @@ -161,7 +251,7 @@ jobs: max-parallel: 4 matrix: os: [macos-latest] - python-version: ["3.13"] + python-version: [${{ env.PY_VERSION }}] steps: - uses: actions/checkout@v7 @@ -191,7 +281,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ["3.13"] + python-version: [${{ env.PY_VERSION }}] steps: - uses: actions/checkout@v7 From c28f99072e12efbad4a9a1875a6baa0085f11a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:08:13 +0200 Subject: [PATCH 06/24] fix yaml --- .github/workflows/build_tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index f85aab254..d3da47276 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -251,7 +251,7 @@ jobs: max-parallel: 4 matrix: os: [macos-latest] - python-version: [${{ env.PY_VERSION }}] + python-version: [${{ env.PY_VERSION }},] steps: - uses: actions/checkout@v7 @@ -281,7 +281,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [${{ env.PY_VERSION }}] + python-version: [${{ env.PY_VERSION }},] steps: - uses: actions/checkout@v7 From 03bb2dbf4aea7f28aefc7d17fcb2aee0a34da680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:10:03 +0200 Subject: [PATCH 07/24] fix yaml --- .github/workflows/build_tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index d3da47276..c617ed4c5 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -245,12 +245,11 @@ jobs: # python -m pytest --durations=20 -v test/ ot/ --color=yes --cov=./ --cov-report=xml macos: - runs-on: ${{ matrix.os }} + runs-on: macos-latest if: "!contains(github.event.head_commit.message, 'no ci')" strategy: max-parallel: 4 matrix: - os: [macos-latest] python-version: [${{ env.PY_VERSION }},] steps: From 68b49f20a0c6a32449c2274c74fc50bc23a070a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:10:23 +0200 Subject: [PATCH 08/24] fix yaml --- .yamllint.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.yamllint.yml b/.yamllint.yml index e7c081ac9..1f1d2d2b6 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -1,7 +1,6 @@ extends: default ignore: | - .github/workflows/*.yml .circleci/config.yml codecov.yml .github/labeler.yml From fb01ddfa8ed7935bc389ff44778f1bf2b004e237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:17:39 +0200 Subject: [PATCH 09/24] try it --- .github/workflows/build_tests.yml | 19 +++++-------------- .yamllint.yml | 1 + 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index c617ed4c5..481dd516a 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -217,7 +217,6 @@ jobs: python -m pytest --durations=20 -v test/ ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v4 - # linux-minimal-deps-ft: @@ -247,19 +246,15 @@ jobs: macos: runs-on: macos-latest if: "!contains(github.event.head_commit.message, 'no ci')" - strategy: - max-parallel: 4 - matrix: - python-version: [${{ env.PY_VERSION }},] steps: - uses: actions/checkout@v7 with: submodules: true - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ env.PY_VERSION }} uses: actions/setup-python@v6 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ env.PY_VERSION }} cache: 'pip' - name: Install POT run: | @@ -277,19 +272,15 @@ jobs: windows: runs-on: windows-latest if: "!contains(github.event.head_commit.message, 'no ci')" - strategy: - max-parallel: 4 - matrix: - python-version: [${{ env.PY_VERSION }},] steps: - uses: actions/checkout@v7 with: submodules: true - - name: Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ env.PY_VERSION }} uses: actions/setup-python@v6 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ env.PY_VERSION }} cache: 'pip' - name: RC.exe run: | @@ -306,7 +297,7 @@ jobs: Invoke-VSDevEnvironment Get-Command rc.exe | Format-Table -AutoSize - name: Update pip - run : | + run: | python -m pip install --upgrade pip setuptools python -m pip install cython - name: Install POT diff --git a/.yamllint.yml b/.yamllint.yml index 1f1d2d2b6..5d871be42 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -8,3 +8,4 @@ ignore: | rules: line-length: disable document-start: disable + indentation: disable From 067d1947815b6decdce1f283425860f72aae1dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:19:47 +0200 Subject: [PATCH 10/24] validate yaml --- .github/workflows/build_doc.yml | 2 +- .github/workflows/build_wheels.yml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/build_doc.yml b/.github/workflows/build_doc.yml index 403a3eb7b..1a206b122 100644 --- a/.github/workflows/build_doc.yml +++ b/.github/workflows/build_doc.yml @@ -5,7 +5,7 @@ on: pull_request: push: branches: - - 'master' + - 'master' jobs: build: diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 40814c053..8617eb6bd 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -41,5 +41,3 @@ jobs: with: name: wheels-${{ strategy.job-index }} path: ./wheelhouse - - From 5632d4c4a8cd9dd0a7e630b9442d1aec188df58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:21:18 +0200 Subject: [PATCH 11/24] speeup backen tests --- .github/workflows/build_tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 481dd516a..14de8ac62 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -151,7 +151,6 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip install -r .github/requirements_no_backend.txt pip install torch torch_geometric geomloss pykeops pip install pytest pytest-cov - name: Run tests @@ -180,7 +179,6 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip install -r .github/requirements_no_backend.txt pip install jax jaxlib pip install pytest pytest-cov - name: Run tests @@ -209,7 +207,6 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip install -r .github/requirements_no_backend.txt pip install tensorflow pip install pytest pytest-cov - name: Run tests From 849650ce3be50722f02e5085f5f775e11eb70e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:47:26 +0200 Subject: [PATCH 12/24] remove doctest for beckend tests --- .github/workflows/build_tests.yml | 6 +++--- ot/__init__.py | 2 +- ot/gnn/_layers.py | 18 ++++++++++-------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 14de8ac62..7311f4f71 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -155,7 +155,7 @@ jobs: pip install pytest pytest-cov - name: Run tests run: | - python -m pytest --durations=20 -v test/ ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml + python -m pytest --durations=20 -v test/ --color=yes --cov=./ --cov-report=xml - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v4 @@ -183,7 +183,7 @@ jobs: pip install pytest pytest-cov - name: Run tests run: | - python -m pytest --durations=20 -v test/ ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml + python -m pytest --durations=20 -v test/ --color=yes --cov=./ --cov-report=xml - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v4 @@ -211,7 +211,7 @@ jobs: pip install pytest pytest-cov - name: Run tests run: | - python -m pytest --durations=20 -v test/ ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml + python -m pytest --durations=20 -v test/ --color=yes --cov=./ --cov-report=xml - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v4 diff --git a/ot/__init__.py b/ot/__init__.py index 7455b8396..deb3a087d 100644 --- a/ot/__init__.py +++ b/ot/__init__.py @@ -93,7 +93,7 @@ from .utils import dist, unif, tic, toc, toq -__version__ = "0.9.7" +__version__ = "0.9.7.dev0" __all__ = [ "emd", diff --git a/ot/gnn/_layers.py b/ot/gnn/_layers.py index b3adad489..1d1b54c59 100644 --- a/ot/gnn/_layers.py +++ b/ot/gnn/_layers.py @@ -7,14 +7,16 @@ # Rémi Flamary # # License: MIT License - -import torch -import torch.nn as nn -from ._utils import ( - TFGW_template_initialization, - FGW_distance_to_templates, - wasserstein_distance_to_templates, -) +try: + import torch + import torch.nn as nn + from ._utils import ( + TFGW_template_initialization, + FGW_distance_to_templates, + wasserstein_distance_to_templates, + ) +except ImportError: + pass class TFGWPooling(nn.Module): From 666fe97ddebbece76374b2c09d5a67224cd0580e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:48:34 +0200 Subject: [PATCH 13/24] remove cleanup space --- .github/workflows/build_tests.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 7311f4f71..d665272c7 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -100,11 +100,11 @@ jobs: python-version: ["3.11", "3.12", "3.13", "3.14"] steps: - - name: Free Disk Space (Ubuntu) - uses: insightsengineering/disk-space-reclaimer@v1 - with: - android: true - dotnet: true + # - name: Free Disk Space (Ubuntu) + # uses: insightsengineering/disk-space-reclaimer@v1 + # with: + # android: true + # dotnet: true - uses: actions/checkout@v7 with: submodules: true From 9bfc040f7aca6d72585aa853d5ae614b98a0e794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 15:57:39 +0200 Subject: [PATCH 14/24] separate doctests --- .github/workflows/build_tests.yml | 39 ++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index d665272c7..12f1b15de 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -62,14 +62,41 @@ jobs: python setup.py sdist bdist_wheel pip install dist/*.tar.gz + doctests: + + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'no ci')" + steps: + - name: Free Disk Space (Ubuntu) + uses: insightsengineering/disk-space-reclaimer@v1 + with: + android: true + dotnet: true + - uses: actions/checkout@v7 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: ${{ env.PY_VERSION }} + cache: 'pip' + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools + pip install -r requirements_all.txt + pip install pytest pytest-cov + - name: Install POT + run: | + pip install -e . + - name: Run tests + run: | + python -m pytest -v ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml + linux-minimal: - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'no ci')" - strategy: - max-parallel: 4 - matrix: - os: [ubuntu-latest, ubuntu-24.04-arm] steps: - uses: actions/checkout@v7 with: @@ -127,7 +154,7 @@ jobs: python -c "import ot; print(ot.__version__)" - name: Run tests run: | - python -m pytest --durations=20 -v test/ ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml + python -m pytest --durations=20 -v test/ --color=yes --cov=./ --cov-report=xml - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v4 From f882de0d9e5f97e48ba68c60b371a1b9ab87c1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 16:13:57 +0200 Subject: [PATCH 15/24] fix cdoctest with proper cnftest --- ot/helpers/openmp_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ot/helpers/openmp_helpers.py b/ot/helpers/openmp_helpers.py index ae2490542..d1acf3a2a 100644 --- a/ot/helpers/openmp_helpers.py +++ b/ot/helpers/openmp_helpers.py @@ -10,7 +10,7 @@ from setuptools.errors import CompileError, LinkError -from pre_build_helpers import compile_test_program +from .pre_build_helpers import compile_test_program def get_openmp_flag(compiler): From 8628dc113675039c528c8634f62a9ff8456be74e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 16:30:47 +0200 Subject: [PATCH 16/24] fix helpers --- .github/workflows/build_tests.yml | 2 +- ot/helpers/openmp_helpers.py | 63 +++++++++++++++++++++++++++- ot/helpers/pre_build_helpers.py | 69 ------------------------------- setup.py | 7 ++-- test/test_helpers.py | 8 +++- 5 files changed, 73 insertions(+), 76 deletions(-) delete mode 100644 ot/helpers/pre_build_helpers.py diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 12f1b15de..186c8d858 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -91,7 +91,7 @@ jobs: pip install -e . - name: Run tests run: | - python -m pytest -v ot/ --doctest-modules --color=yes --cov=./ --cov-report=xml + python -m pytest -v ot/ test/conftest.py --doctest-modules --color=yes --cov=./ --cov-report=xml linux-minimal: diff --git a/ot/helpers/openmp_helpers.py b/ot/helpers/openmp_helpers.py index d1acf3a2a..fbe256625 100644 --- a/ot/helpers/openmp_helpers.py +++ b/ot/helpers/openmp_helpers.py @@ -5,12 +5,73 @@ import os import sys +import glob +import tempfile import textwrap import subprocess from setuptools.errors import CompileError, LinkError +from setuptools.command.build_ext import customize_compiler, new_compiler -from .pre_build_helpers import compile_test_program + +def _get_compiler(): + ccompiler = new_compiler() + customize_compiler(ccompiler) + return ccompiler + + +def compile_test_program(code, extra_preargs=[], extra_postargs=[]): + """Check that some C code can be compiled and run""" + ccompiler = _get_compiler() + + # extra_(pre/post)args can be a callable to make it possible to get its + # value from the compiler + if callable(extra_preargs): + extra_preargs = extra_preargs(ccompiler) + if callable(extra_postargs): + extra_postargs = extra_postargs(ccompiler) + + start_dir = os.path.abspath(".") + + with tempfile.TemporaryDirectory() as tmp_dir: + try: + os.chdir(tmp_dir) + + # Write test program + with open("test_program.c", "w") as f: + f.write(code) + + os.mkdir("objects") + + # Compile, test program + ccompiler.compile( + ["test_program.c"], output_dir="objects", extra_postargs=extra_postargs + ) + + # Link test program + objects = glob.glob(os.path.join("objects", "*" + ccompiler.obj_extension)) + ccompiler.link_executable( + objects, + "test_program", + extra_preargs=extra_preargs, + extra_postargs=extra_postargs, + ) + + if "PYTHON_CROSSENV" not in os.environ: + # Run test program if not cross compiling + # will raise a CalledProcessError if return code was non-zero + output = subprocess.check_output("./test_program") + output = output.decode(sys.stdout.encoding or "utf-8").splitlines() + else: + # Return an empty output if we are cross compiling + # as we cannot run the test_program + output = [] + except Exception: + raise + finally: + os.chdir(start_dir) + + return output, extra_postargs def get_openmp_flag(compiler): diff --git a/ot/helpers/pre_build_helpers.py b/ot/helpers/pre_build_helpers.py deleted file mode 100644 index 51b231c42..000000000 --- a/ot/helpers/pre_build_helpers.py +++ /dev/null @@ -1,69 +0,0 @@ -"""Helpers to check build environment before actual build of POT""" - -import os -import sys -import glob -import tempfile -import subprocess - -from setuptools.command.build_ext import customize_compiler, new_compiler - - -def _get_compiler(): - ccompiler = new_compiler() - customize_compiler(ccompiler) - return ccompiler - - -def compile_test_program(code, extra_preargs=[], extra_postargs=[]): - """Check that some C code can be compiled and run""" - ccompiler = _get_compiler() - - # extra_(pre/post)args can be a callable to make it possible to get its - # value from the compiler - if callable(extra_preargs): - extra_preargs = extra_preargs(ccompiler) - if callable(extra_postargs): - extra_postargs = extra_postargs(ccompiler) - - start_dir = os.path.abspath(".") - - with tempfile.TemporaryDirectory() as tmp_dir: - try: - os.chdir(tmp_dir) - - # Write test program - with open("test_program.c", "w") as f: - f.write(code) - - os.mkdir("objects") - - # Compile, test program - ccompiler.compile( - ["test_program.c"], output_dir="objects", extra_postargs=extra_postargs - ) - - # Link test program - objects = glob.glob(os.path.join("objects", "*" + ccompiler.obj_extension)) - ccompiler.link_executable( - objects, - "test_program", - extra_preargs=extra_preargs, - extra_postargs=extra_postargs, - ) - - if "PYTHON_CROSSENV" not in os.environ: - # Run test program if not cross compiling - # will raise a CalledProcessError if return code was non-zero - output = subprocess.check_output("./test_program") - output = output.decode(sys.stdout.encoding or "utf-8").splitlines() - else: - # Return an empty output if we are cross compiling - # as we cannot run the test_program - output = [] - except Exception: - raise - finally: - os.chdir(start_dir) - - return output, extra_postargs diff --git a/setup.py b/setup.py index 4cfde74d4..f423f1c0e 100644 --- a/setup.py +++ b/setup.py @@ -15,19 +15,20 @@ import numpy from Cython.Build import cythonize -sys.path.append(os.path.join("ot", "helpers")) +ROOT = os.path.abspath(os.path.dirname(__file__)) + +sys.path.append(os.path.join(ROOT, "ot", "helpers")) from openmp_helpers import check_openmp_support # dirty but working __version__ = re.search( r'__version__\s*=\s*[\'"]([^\'"]*)[\'"]', # It excludes inline comment too - open("ot/__init__.py").read(), + open(os.path.join(ROOT, "ot/__init__.py")).read(), ).group(1) # The beautiful part is, I don't even need to check exceptions here. # If something messes up, let the build process fail noisy, BEFORE my release! # thanks PyPI for handling markdown now -ROOT = os.path.abspath(os.path.dirname(__file__)) with open(os.path.join(ROOT, "README.md"), encoding="utf-8") as f: README = f.read() diff --git a/test/test_helpers.py b/test/test_helpers.py index 7a605f46f..28d0722ba 100644 --- a/test/test_helpers.py +++ b/test/test_helpers.py @@ -9,8 +9,12 @@ sys.path.append(os.path.join("ot", "helpers")) -from openmp_helpers import get_openmp_flag, check_openmp_support # noqa -from pre_build_helpers import _get_compiler, compile_test_program # noqa +from openmp_helpers import ( + get_openmp_flag, + check_openmp_support, + _get_compiler, + compile_test_program, +) # noqa def test_helpers(): From aec7f2197b1bcc5214283f1a7e9a01bfaf1bc02c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 16:46:47 +0200 Subject: [PATCH 17/24] fix linux-torch test --- .github/workflows/build_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 186c8d858..f702786ca 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -178,7 +178,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip install torch torch_geometric geomloss pykeops + pip install torch torch_geometric geomloss pykeops scikit-learn pip install pytest pytest-cov - name: Run tests run: | From 2bc03812831e82f2ff9d987a7e619d1d3f59a248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 16:52:55 +0200 Subject: [PATCH 18/24] remove torch version --- requirements_all.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_all.txt b/requirements_all.txt index c99c824b9..76f1890da 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -5,7 +5,7 @@ autograd pymanopt cvxopt scikit-learn -torch<=2.11 +torch jax jaxlib tensorflow; python_version < '3.14' From 9ca4921bf7cc982ee0051eef9e1ee240e19d665b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 17:04:58 +0200 Subject: [PATCH 19/24] fix doc build --- .circleci/config.yml | 1 - docs/requirements.txt | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9eb63ece5..4351ad001 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,7 +51,6 @@ jobs: command: | python -m pip install --user --upgrade --progress-bar off pip python -m pip install --user -e . - python -m pip install --user --upgrade --no-cache-dir --progress-bar off -r requirements_all.txt python -m pip install --user --upgrade --progress-bar off -r docs/requirements.txt python -m pip install --user --upgrade --progress-bar off ipython sphinx-gallery memory_profiler # python -m pip install --user --upgrade --progress-bar off ipython "https://api.github.com/repos/sphinx-gallery/sphinx-gallery/zipball/master" memory_profiler diff --git a/docs/requirements.txt b/docs/requirements.txt index cf689f205..beb66b6bc 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,17 @@ +numpy>=1.20 +scipy>=1.6 +matplotlib +autograd +pymanopt +cvxopt +scikit-learn +torch<2.12 +pytest +torch_geometric +cvxpy +geomloss +pykeops + sphinx sphinx-rtd-theme sphinx-gallery From b2d516c04bb73640f942d06d40e5b73e6141672d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 17:07:11 +0200 Subject: [PATCH 20/24] fix doc build --- .github/workflows/build_doc.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build_doc.yml b/.github/workflows/build_doc.yml index 1a206b122..fcc45fb4b 100644 --- a/.github/workflows/build_doc.yml +++ b/.github/workflows/build_doc.yml @@ -31,7 +31,6 @@ jobs: - name: Get Python running run: | python -m pip install --user --upgrade --progress-bar off pip - python -m pip install --user --upgrade --progress-bar off -r requirements_all.txt python -m pip install --user --upgrade --progress-bar off -r docs/requirements.txt python -m pip install --user --upgrade --progress-bar off ipython sphinx-gallery memory_profiler python -m pip install -v --user -e . From bf0fb635c23b8f3cc1a6efcd07553537be23623e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 17:09:14 +0200 Subject: [PATCH 21/24] fix doctests --- requirements_all.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_all.txt b/requirements_all.txt index 76f1890da..f58908d4d 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -5,7 +5,7 @@ autograd pymanopt cvxopt scikit-learn -torch +torch<=2.12 jax jaxlib tensorflow; python_version < '3.14' From fcb5640c7d9c2eb039506c6098cf51e5306f1687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 17:12:45 +0200 Subject: [PATCH 22/24] move stuff around properly --- requirements_all.txt => .github/requirements_doctests.txt | 0 .github/workflows/build_tests.yml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename requirements_all.txt => .github/requirements_doctests.txt (100%) diff --git a/requirements_all.txt b/.github/requirements_doctests.txt similarity index 100% rename from requirements_all.txt rename to .github/requirements_doctests.txt diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index f702786ca..df0652a3b 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -84,7 +84,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip install -r requirements_all.txt + pip install -r .github/requirements_doctests.txt pip install pytest pytest-cov - name: Install POT run: | @@ -286,7 +286,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip install -r requirements_all.txt + pip install -r .github/requirements_no_backend.txt pip install pytest - name: Run tests run: | From 27fc81565150ed940a0eca969702ad3dfc385310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 17:23:46 +0200 Subject: [PATCH 23/24] gix doctest for the last time? --- .github/requirements_doctests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/requirements_doctests.txt b/.github/requirements_doctests.txt index f58908d4d..95000846d 100644 --- a/.github/requirements_doctests.txt +++ b/.github/requirements_doctests.txt @@ -5,7 +5,7 @@ autograd pymanopt cvxopt scikit-learn -torch<=2.12 +torch<2.12 jax jaxlib tensorflow; python_version < '3.14' From 837d2b46f7c8f0c45354268c3e608dee3b876e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Flamary?= Date: Thu, 25 Jun 2026 18:09:32 +0200 Subject: [PATCH 24/24] stuff --- RELEASES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 938f65595..51d89cc01 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -34,7 +34,8 @@ This new release adds support for sparse cost matrices and a new lazy exact OT s - Wrapper for barycenter solvers with free support `ot.solvers.bary_free_support` (PR #730) - Build wheels on ubuntu ARM to avoid QEMU emulation (PR #818) - Add new methods to compute the linear transport map and the related 2-Wasserstein distance betweeen high-dimensional (HD) Gaussian distributions as described in [88], implemented in `ot.gaussian.bures_wasserstein_mapping_hd` and `ot.gaussian.bures_wasserstein_distance_hd`, respectively. Two additional methods estimate the same quantities from the source and destination observed data and are implemented in `ot.gaussian.empirical_bures_wasserstein_mapping_hd` and `ot.gaussian.empirical_bures_wasserstein_distance_hd`, respectively (PR #814) -- Fix docstrings for `lowrank_gromov_wasserstein_samples` and `lowrank_sinkhorn` (PR #823) +- Fix docstrings for `lowrank_gromov_wasserstein_samples` and `lowrank_sinkhorn` (PR #823) +- Reorganize all tests per backend (PR #828) #### Closed issues