From bc73206b7fce0a9394b87b917d6f7c6b22fb1a95 Mon Sep 17 00:00:00 2001 From: Akshay Agrawal Date: Sun, 27 Apr 2025 22:47:11 -0700 Subject: [PATCH 1/7] break: support numpy 2.0, drop older numpy fix: fix quadratic embedding computation (ones \in null(Laplacian) no longer allowed by scipy.sparse.eigsh). --- pymde/experiment_utils.py | 4 ++-- pymde/functions/losses.py | 4 ++-- pymde/functions/penalties.py | 4 ++-- pymde/quadratic.py | 11 +++++------ setup.py | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/pymde/experiment_utils.py b/pymde/experiment_utils.py index 889adbe..e9ad42c 100644 --- a/pymde/experiment_utils.py +++ b/pymde/experiment_utils.py @@ -139,8 +139,8 @@ def _is_discrete(dtype): for other in ( np.integer, np.bool_, - np.string_, - np.unicode_, + np.bytes_, + np.str_, np.object_, ) ] diff --git a/pymde/functions/losses.py b/pymde/functions/losses.py index a86c858..21becc6 100644 --- a/pymde/functions/losses.py +++ b/pymde/functions/losses.py @@ -5,7 +5,7 @@ .. math:: - f_k(d_k) = \\ell(d_k, \delta_k), \\quad k=1, \\ldots, p, + f_k(d_k) = \\ell(d_k, \\delta_k), \\quad k=1, \\ldots, p, where :math:`\\ell` is a loss function, :math:`\\delta_k` is a nonnegative deviation @@ -102,7 +102,7 @@ class Huber(Function): """ .. math:: - \ell(d, \\delta) = \\begin{cases} + \\ell(d, \\delta) = \\begin{cases} \\cdot (d - \\delta)^2 & d < \\text{threshold} \\\\ \\text{threshold}(2(d - \\delta) - \\cdot \\text{threshold}) & d \\geq \\text{threshold} diff --git a/pymde/functions/penalties.py b/pymde/functions/penalties.py index 6a95c74..ab5c35f 100644 --- a/pymde/functions/penalties.py +++ b/pymde/functions/penalties.py @@ -308,7 +308,7 @@ def forward(self, distances): class Log1p(Function): - """:math:`p(d) = \log(1 + d^{\\text{exponent}})`""" + """:math:`p(d) = \\log(1 + d^{\\text{exponent}})`""" def __init__(self, weights, exponent=1.5): super(Log1p, self).__init__() @@ -322,7 +322,7 @@ def forward(self, distances): class Log(Function): - """:math:`p(d) = \log(1 - \\exp(-d^\\text{exponent}))`""" + """:math:`p(d) = \\log(1 - \\exp(-d^\\text{exponent}))`""" def __init__(self, weights, exponent=1.0): super(Log, self).__init__() diff --git a/pymde/quadratic.py b/pymde/quadratic.py index 209dcf6..be77009 100644 --- a/pymde/quadratic.py +++ b/pymde/quadratic.py @@ -88,7 +88,6 @@ def _spectral( which="SM", ncv=num_lanczos_vectors, tol=1e-4, - v0=np.ones(L.shape[0]), maxiter=L.shape[0] * 5, ) order = np.argsort(eigenvalues)[1:k] @@ -123,17 +122,17 @@ def _spectral( def spectral( n_items, embedding_dim, edges, weights, cg=False, max_iter=40, device="cpu" ): - """Compute a spectral embedding + r"""Compute a spectral embedding Solves the quadratic MDE problem .. math:: - \\begin{array}{ll} - \\mbox{minimize} & \\sum_{(i, j) in \\text{edges}} w_{ij} d_{ij}^2 \\\\ - \\mbox{subject to} & (1/n) X^T X = I, \quad d_{ij} = |x_i - x_j|_2. - \\end{array} + \begin{array}{ll} + \mbox{minimize} & \sum_{(i, j) in \text{edges}} w_{ij} d_{ij}^2 \\ + \mbox{subject to} & (1/n) X^T X = I, \quad d_{ij} = |x_i - x_j|_2. + \end{array} By default, the problem is solved using a Lanczos method. If cg=True, LOBPCG is used; LOBPCG is warm-started by running a projected quasi-newton diff --git a/setup.py b/setup.py index 1e3d655..58126b3 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ def get_version(rel_path): setup_requires=["setuptools>=18.0", "cython"], install_requires=[ "matplotlib", - "numpy >= 1.17.5", + "numpy >= 2.0", "pynndescent", "scipy", "torch >= 1.7.1", From 62e31d6adec0b66b3c898339fb34b0d46b8140a4 Mon Sep 17 00:00:00 2001 From: Akshay Agrawal Date: Sun, 27 Apr 2025 22:50:33 -0700 Subject: [PATCH 2/7] simplify numpy build requirement --- pyproject.toml | 47 ++++++++--------------------------------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 551621c..85242a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,45 +1,14 @@ [build-system] requires = [ # NumPy dependencies copied from SciPy: - # https://github.com/scipy/scipy/blob/3df34d96123678e4b1b03aba83b84d8ff08817e5/pyproject.toml - # NumPy dependencies - to update these, sync from - # https://github.com/scipy/oldest-supported-numpy/, and then - # update minimum version to match our install_requires min version - # ---------------------------------------------------------------- - - # now matches minimum supported version, keep here as separate requirement - # to be able to sync more easily with oldest-supported-numpy - "numpy==1.19.5; python_version=='3.8' and platform_machine=='aarch64' and platform_python_implementation != 'PyPy'", - - # arm64 on Darwin supports Python 3.8 and above requires numpy>=1.21.0 - # (first version with arm64 wheels available) - "numpy==1.21.0; python_version=='3.8' and platform_machine=='arm64' and platform_system=='Darwin'", - "numpy==1.21.0; python_version=='3.9' and platform_machine=='arm64' and platform_system=='Darwin'", - - # loongarch64 requires numpy>=1.22.0 - "numpy==1.22.0; platform_machine=='loongarch64'", - - # On Windows we need to avoid 1.21.6, 1.22.0 and 1.22.1 because they were - # built with vc142. 1.22.3 is the first version that has 32-bit Windows - # wheels *and* was built with vc141. So use that: - "numpy==1.22.3; python_version=='3.10' and platform_system=='Windows' and platform_python_implementation != 'PyPy'", - - # default numpy requirements - "numpy==1.19.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_machine!='loongarch64' and platform_python_implementation != 'PyPy'", - "numpy==1.19.5; python_version=='3.9' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='loongarch64' and platform_python_implementation != 'PyPy'", - # Note that 1.21.3 was the first version with a complete set of 3.10 wheels, - # however macOS was broken and it's safe C API/ABI-wise to build against 1.21.6 - # (see oldest-supported-numpy issues gh-28 and gh-45) - "numpy==1.21.6; python_version=='3.10' and (platform_system!='Windows' and platform_machine!='loongarch64') and platform_python_implementation != 'PyPy'", - "numpy==1.23.2; python_version=='3.11' and platform_python_implementation != 'PyPy'", - - # For Python versions which aren't yet officially supported, - # we specify an unpinned NumPy which allows source distributions - # to be used and allows wheels to be used as soon as they - # become available. - "numpy; python_version>='3.12'", - "numpy; python_version>='3.8' and platform_python_implementation=='PyPy'", - + # https://github.com/scipy/scipy/blob/55cae814e23208354bf16b84be47b5070b4c1c89/pyproject.toml#L25-L31 + # numpy requirement for wheel builds for distribution on PyPI - building + # against 2.x yields wheels that are also compatible with numpy 1.x at + # runtime. + # Note that building against numpy 1.x works fine too - users and + # redistributors can do this by installing the numpy version they like and + # disabling build isolation. + "numpy>=2.0.0", "scipy >= 1.6", "setuptools", "wheel", From f8d64c8c17218db480c94f6774d3feb300c224db Mon Sep 17 00:00:00 2001 From: Akshay Agrawal Date: Sun, 27 Apr 2025 23:12:05 -0700 Subject: [PATCH 3/7] update ci --- .github/workflows/build.yaml | 22 +++++++++++----------- .github/workflows/run_tests.yaml | 22 ++++++---------------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d60402d..5099427 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -11,12 +11,12 @@ jobs: os: [ubuntu-latest, macos-11, windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 name: Install Python with: - python-version: '3.8' + python-version: '3.10' - name: Install dependencies run: | @@ -26,13 +26,13 @@ jobs: pip install -r requirements.txt - name: Build wheels - uses: pypa/cibuildwheel@v2.11.2 + uses: pypa/cibuildwheel@v2.23.3 env: - CIBW_BUILD: "cp38* cp39* cp310* cp311*" + CIBW_BUILD: "cp310* cp311* cp312* cp313" CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux*" CIBW_ARCHS_MACOS: x86_64 arm64 - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: path: ./wheelhouse/*.whl @@ -40,12 +40,12 @@ jobs: name: Build source distribution runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 name: Install Python with: - python-version: '3.8' + python-version: '3.10' - name: Install dependencies run: | @@ -57,7 +57,7 @@ jobs: - name: Build sdist run: python setup.py sdist - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: path: dist/*.tar.gz @@ -69,7 +69,7 @@ jobs: # alternatively, to publish when a GitHub Release is created, use the following rule: #if: github.event_name == 'release' && github.event.action == 'published' steps: - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 with: name: artifact path: dist diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index bbc11ef..6e73594 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -9,12 +9,12 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [3.7, 3.8, 3.9] + python-version: [3.10, 3.11, 3.12] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies @@ -22,24 +22,14 @@ jobs: python -m pip install --upgrade pip pip install setuptools wheel pip install flake8 pytest - - if: matrix.python-version == '3.7' - run: pip install numpy==1.17.5 - - - if: matrix.python-version == '3.8' - run: pip install numpy==1.17.5 - - - if: matrix.python-version == '3.9' - run: pip install numpy==1.21.0 + pip install numpy==2.2.5 # install cpu versions of torch for CI - if: matrix.os == 'macos-latest' - run: pip install torch==1.8.0 torchvision==0.9.0 + run: pip install torch==2.7.0 torchvision==0.22.0 - if: matrix.os == 'ubuntu-latest' - run: pip install --find-links https://download.pytorch.org/whl/torch_stable.html torch==1.8.0+cpu torchvision==0.9.0+cpu - - - if: matrix.os == 'windows-latest' - run: pip install --find-links https://download.pytorch.org/whl/torch_stable.html torch==1.8.0+cpu torchvision==0.9.0+cpu + run: pip install torch==2.7.0 torchvision==0.14.0 --index-url https://download.pytorch.org/whl/cpu - name: Lint with flake8 run: | From bc5e967b4a72ca15759f0335b35d05d26003cfee Mon Sep 17 00:00:00 2001 From: Akshay Agrawal Date: Sun, 27 Apr 2025 23:26:11 -0700 Subject: [PATCH 4/7] try quote --- .github/workflows/run_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 6e73594..0c7c142 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -16,7 +16,7 @@ jobs: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + python-version: '${{ matrix.python-version }}' - name: Install dependencies run: | python -m pip install --upgrade pip From 08afca2e7245c302548e95198b5cbb38fa9485c2 Mon Sep 17 00:00:00 2001 From: Akshay Agrawal Date: Sun, 27 Apr 2025 23:30:34 -0700 Subject: [PATCH 5/7] try quote again --- .github/workflows/run_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 0c7c142..5135b34 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -9,7 +9,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [3.10, 3.11, 3.12] + python-version: ["3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 From f130eb23a0da83ae013a44d04b409b1aff4a25d4 Mon Sep 17 00:00:00 2001 From: Akshay Agrawal Date: Sun, 27 Apr 2025 23:32:16 -0700 Subject: [PATCH 6/7] update tv --- .github/workflows/run_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 5135b34..7a4ebd3 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -29,7 +29,7 @@ jobs: run: pip install torch==2.7.0 torchvision==0.22.0 - if: matrix.os == 'ubuntu-latest' - run: pip install torch==2.7.0 torchvision==0.14.0 --index-url https://download.pytorch.org/whl/cpu + run: pip install torch==2.7.0 torchvision==0.22.0 --index-url https://download.pytorch.org/whl/cpu - name: Lint with flake8 run: | From 5ce9fffe109e487a9379a039c1d3a16a258aeb7f Mon Sep 17 00:00:00 2001 From: Akshay Agrawal Date: Sun, 27 Apr 2025 23:34:31 -0700 Subject: [PATCH 7/7] lint --- pymde/preprocess/graph.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pymde/preprocess/graph.py b/pymde/preprocess/graph.py index b5f65eb..f2144e7 100644 --- a/pymde/preprocess/graph.py +++ b/pymde/preprocess/graph.py @@ -336,7 +336,7 @@ def _shortest_paths(shape, node, max_length, unweighted, sample_prob): def __init_process(data, indptr, indices): - global __this_module + global __this_module # noqa: F824 __this_module.__data = data __this_module.__indptr = indptr __this_module.__indices = indices @@ -395,7 +395,7 @@ def shortest_paths( if verbose: LOGGER.info( f"Computing shortest path distances (retaining " - f"{100*retain_fraction:.2f} percent with " + f"{100 * retain_fraction:.2f} percent with " f"max_distance={max_length}) ..." ) @@ -419,7 +419,7 @@ def to_shared_memory(array): array = np.ctypeslib.as_ctypes(array) return sharedctypes.RawArray(array._type_, array) - global __this_module + global __this_module # noqa: F824 data = __this_module.__data = to_shared_memory(graph.A.data) indptr = __this_module.__indptr = to_shared_memory(graph.A.indptr) indices = __this_module.__indices = to_shared_memory(graph.A.indices)