From 798c211190dae53a96a13a0728c0ab7ffcb15c63 Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Fri, 10 Oct 2025 09:30:10 -0700 Subject: [PATCH 01/12] support cusolver backend --- README.md | 8 +++--- notebooks/test.ipynb | 13 +++++++--- src/jeig/jeig.py | 59 ++++++++++++++++++++++++++++++++++---------- tests/test_eig.py | 21 ++++++++++++---- 4 files changed, 76 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 2f5491c..9439e27 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # jeig - Eigendecompositions wrapped for jax -![Continuous integration](https://github.com/mfschubert/jeig/actions/workflows/build-ci.yml/badge.svg) -![PyPI version](https://img.shields.io/pypi/v/jeig) +[![Continuous integration](https://github.com/mfschubert/jeig/actions/workflows/build-ci.yml/badge.svg)](https://github.com/mfschubert/jeig/actions) +[![PyPI version](https://img.shields.io/pypi/v/jeig)](https://pypi.org/project/jeig/) ## Overview -This package wraps eigendecompositions as provided by jax, magma, numpy, scipy, and torch for use with jax. Depending upon your system and your versions of these packages, you may observe significant speed differences. The following were obtained using jax 0.4.37 on a system with 28-core Intel Xeon w7-3465X and NVIDIA RTX4090. +This package wraps eigendecompositions as provided by jax, cusolver, magma, numpy, scipy, and torch for use with jax. Depending upon your system and your versions of these packages, you may observe significant speed differences. The following were obtained using jax 0.4.37 on a system with 28-core Intel Xeon w7-3465X and NVIDIA RTX4090. ![Speed comparison](https://github.com/mfschubert/jeig/blob/main/docs/speed.png?raw=true) @@ -23,7 +23,7 @@ import jeig matrix = jax.random.normal(jax.random.PRNGKey(0), (16, 1024, 1024)) -%timeit jax.block_until_ready(jeig.eig(matrix, backend="jax")) +%timeit jax.block_until_ready(jeig.eig(matrix, backend="lapack")) %timeit jax.block_until_ready(jeig.eig(matrix, backend="magma")) diff --git a/notebooks/test.ipynb b/notebooks/test.ipynb index f263114..306f2e6 100644 --- a/notebooks/test.ipynb +++ b/notebooks/test.ipynb @@ -25,7 +25,14 @@ "batch_size = [1, 16]\n", "matrix_size = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]\n", "repeats = 3\n", - "backends = [jeig.EigBackend.JAX, jeig.EigBackend.MAGMA, jeig.EigBackend.NUMPY, jeig.EigBackend.SCIPY, jeig.EigBackend.TORCH]\n", + "backends = [\n", + " jeig.EigBackend.CUSOLVER,\n", + " jeig.EigBackend.LAPACK,\n", + " jeig.EigBackend.MAGMA,\n", + " jeig.EigBackend.NUMPY,\n", + " jeig.EigBackend.SCIPY,\n", + " jeig.EigBackend.TORCH,\n", + "]\n", "\n", "fns = {}\n", "for backend in backends:\n", @@ -73,7 +80,7 @@ ], "metadata": { "kernelspec": { - "display_name": "invrs2", + "display_name": "invrs", "language": "python", "name": "python3" }, @@ -87,7 +94,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.12" } }, "nbformat": 4, diff --git a/src/jeig/jeig.py b/src/jeig/jeig.py index 0d6fc90..067b218 100644 --- a/src/jeig/jeig.py +++ b/src/jeig/jeig.py @@ -25,7 +25,9 @@ os.path.dirname(torch.__file__), "lib", "libtorch_cuda_linalg.so" ) +# Identify whether MAGMA and CUSOLVER backends are available. _JAX_HAS_MAGMA = torch.cuda.has_magma +_JAX_HAS_CUSOLVER = hasattr(jax.lax.linalg, "EigImplementation") callback = functools.partial(jax.pure_callback, vmap_method="expand_dims") callback_sequential = functools.partial(jax.pure_callback, vmap_method="sequential") @@ -36,7 +38,8 @@ @enum.unique class EigBackend(enum.Enum): - JAX = "jax" + CUSOLVER = "cusolver" + LAPACK = "lapack" MAGMA = "magma" NUMPY = "numpy" SCIPY = "scipy" @@ -46,7 +49,8 @@ class EigBackend(enum.Enum): def from_string(cls, backend: str) -> "EigBackend": """Returns the specified backend.""" return { - cls.JAX.value: cls.JAX, + cls.CUSOLVER.value: cls.CUSOLVER, + cls.LAPACK.value: cls.LAPACK, cls.MAGMA.value: cls.MAGMA, cls.NUMPY.value: cls.NUMPY, cls.SCIPY.value: cls.SCIPY, @@ -94,23 +98,48 @@ def eig( return EIG_FNS[backend](matrix, force_x64) -def _eig_jax(matrix: jnp.ndarray, force_x64: bool) -> Tuple[jnp.ndarray, jnp.ndarray]: - """Eigendecomposition using `jax.numpy.linalg.eig`.""" +def _eig_cusolver( + matrix: jnp.ndarray, force_x64: bool +) -> Tuple[jnp.ndarray, jnp.ndarray]: + """Eigendecomposition using `jax.lax.linalg.eig` with `cusolver` backend.""" + if not _JAX_HAS_CUSOLVER: + raise ValueError("`CUDA` backend is not available.") if force_x64: matrix_dtype = jnp.promote_types(matrix.dtype, jnp.float64) else: matrix_dtype = matrix.dtype output_dtype = jnp.promote_types(matrix, jnp.complex64) + eigval, eigvec = jax.lax.linalg.eig( matrix.astype(matrix_dtype), compute_left_eigenvectors=False, - use_magma=False, + implementation="cusolver", # type: ignore[call-arg] ) return eigval.astype(output_dtype), eigvec.astype(output_dtype) +def _eig_lapack( + matrix: jnp.ndarray, force_x64: bool +) -> Tuple[jnp.ndarray, jnp.ndarray]: + """Eigendecomposition using `jax.lax.linalg.eig` with `lapack` backend.""" + if force_x64: + matrix_dtype = jnp.promote_types(matrix.dtype, jnp.float64) + else: + matrix_dtype = matrix.dtype + output_dtype = jnp.promote_types(matrix, jnp.complex64) + + eig_fn = functools.partial(jax.lax.linalg.eig, compute_left_eigenvectors=False) + if _JAX_HAS_CUSOLVER: + eig_fn = functools.partial(eig_fn, implementation="lapack") + else: + eig_fn = functools.partial(eig_fn, use_magma=False) + + eigval, eigvec = eig_fn(matrix.astype(matrix_dtype)) + return eigval.astype(output_dtype), eigvec.astype(output_dtype) + + def _eig_magma(matrix: jnp.ndarray, force_x64: bool) -> Tuple[jnp.ndarray, jnp.ndarray]: - """Eigendecomposition using `jax.numpy.linalg.eig`.""" + """Eigendecomposition using `jax.lax.linalg.eig` with `magma` backend.""" if not _JAX_HAS_MAGMA: raise ValueError( "`MAGMA` backend is not available; `torch.cuda.has_magma` is `False`." @@ -120,11 +149,14 @@ def _eig_magma(matrix: jnp.ndarray, force_x64: bool) -> Tuple[jnp.ndarray, jnp.n else: matrix_dtype = matrix.dtype output_dtype = jnp.promote_types(matrix, jnp.complex64) - eigval, eigvec = jax.lax.linalg.eig( - matrix.astype(matrix_dtype), - compute_left_eigenvectors=False, - use_magma=True, - ) + + eig_fn = functools.partial(jax.lax.linalg.eig, compute_left_eigenvectors=False) + if _JAX_HAS_CUSOLVER: + eig_fn = functools.partial(eig_fn, implementation="magma") + else: + eig_fn = functools.partial(eig_fn, use_magma=True) + + eigval, eigvec = eig_fn(matrix.astype(matrix_dtype)) return eigval.astype(output_dtype), eigvec.astype(output_dtype) @@ -185,7 +217,7 @@ def _eig_fn(m: jnp.ndarray) -> Tuple[jnp.ndarray, jnp.ndarray]: def _eig_torch(matrix: jnp.ndarray, force_x64: bool) -> Tuple[jnp.ndarray, jnp.ndarray]: - """Eigendecomposition using `torc.linalg.eig`.""" + """Eigendecomposition using `torch.linalg.eig`.""" dtype = jnp.promote_types(matrix.dtype, jnp.complex64) def _eig_fn(matrix: jnp.ndarray) -> Tuple[NDArray, NDArray]: @@ -228,7 +260,8 @@ def _eig_torch_parallelized(x: torch.Tensor) -> List[Tuple[torch.Tensor, torch.T EIG_FNS = { - EigBackend.JAX: _eig_jax, + EigBackend.CUSOLVER: _eig_cusolver, + EigBackend.LAPACK: _eig_lapack, EigBackend.MAGMA: _eig_magma, EigBackend.NUMPY: _eig_numpy, EigBackend.SCIPY: _eig_scipy, diff --git a/tests/test_eig.py b/tests/test_eig.py index d09c849..97bf24e 100644 --- a/tests/test_eig.py +++ b/tests/test_eig.py @@ -15,7 +15,7 @@ BACKENDS = [ - jeig.EigBackend.JAX, + jeig.EigBackend.LAPACK, jeig.EigBackend.NUMPY, jeig.EigBackend.SCIPY, jeig.EigBackend.TORCH, @@ -24,6 +24,11 @@ if _jeig._JAX_HAS_MAGMA: BACKENDS.append(jeig.EigBackend.MAGMA) +# Only test the cusolver backend if supported by the installed jax version. +if _jeig._JAX_HAS_CUSOLVER: + BACKENDS.append(jeig.EigBackend.CUSOLVER) + + SHAPES = [(1, 2, 2), (1, 16, 16), (2, 16, 16), (2, 64, 64)] @@ -58,7 +63,9 @@ def test_backends_against_jax_symmetric_real(self, backend, shape): matrix = jax.random.normal(jax.random.PRNGKey(0), shape) matrix = 0.5 * (matrix + jnp.swapaxes(matrix, -1, -2)) - expected_eigval, expected_eigvec = jeig.eig(matrix, backend=jeig.EigBackend.JAX) + expected_eigval, expected_eigvec = jeig.eig( + matrix, backend=jeig.EigBackend.LAPACK + ) eigval, eigvec = jeig.eig(matrix, backend=backend) eigval, eigvec = _match_eigs(eigval, eigvec, expected_eigval, expected_eigvec) @@ -69,7 +76,9 @@ def test_backends_against_jax_symmetric_real(self, backend, shape): def test_backends_against_jax_real(self, backend, shape): matrix = jax.random.normal(jax.random.PRNGKey(0), shape) - expected_eigval, expected_eigvec = jeig.eig(matrix, backend=jeig.EigBackend.JAX) + expected_eigval, expected_eigvec = jeig.eig( + matrix, backend=jeig.EigBackend.LAPACK + ) eigval, eigvec = jeig.eig(matrix, backend=backend) eigval, eigvec = _match_eigs(eigval, eigvec, expected_eigval, expected_eigvec) @@ -81,7 +90,9 @@ def test_backends_against_jax_complex(self, backend, shape): real, imag = jax.random.normal(jax.random.PRNGKey(0), (2,) + shape) matrix = real + 1j * imag - expected_eigval, expected_eigvec = jeig.eig(matrix, backend=jeig.EigBackend.JAX) + expected_eigval, expected_eigvec = jeig.eig( + matrix, backend=jeig.EigBackend.LAPACK + ) eigval, eigvec = jeig.eig(matrix, backend=backend) eigval, eigvec = _match_eigs(eigval, eigvec, expected_eigval, expected_eigvec) @@ -96,7 +107,7 @@ def test_set_backend(self, backend): jeig.set_backend(jeig.EigBackend.TORCH) self.assertEqual(_jeig._DEFAULT_BACKEND, jeig.EigBackend.TORCH) - @parameterized.expand(["jax", "numpy", "scipy", "torch"]) + @parameterized.expand(["lapack", "numpy", "scipy", "torch"]) def test_set_backend_with_str(self, backend_str): self.assertEqual(_jeig._DEFAULT_BACKEND, jeig.EigBackend.TORCH) jeig.set_backend(backend_str) From 698dcf73752631d9c4b5dac0f362e20ce2ce2a2a Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Fri, 10 Oct 2025 10:47:41 -0700 Subject: [PATCH 02/12] fix error message --- src/jeig/jeig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jeig/jeig.py b/src/jeig/jeig.py index 067b218..82ce47f 100644 --- a/src/jeig/jeig.py +++ b/src/jeig/jeig.py @@ -103,7 +103,7 @@ def _eig_cusolver( ) -> Tuple[jnp.ndarray, jnp.ndarray]: """Eigendecomposition using `jax.lax.linalg.eig` with `cusolver` backend.""" if not _JAX_HAS_CUSOLVER: - raise ValueError("`CUDA` backend is not available.") + raise ValueError("`CUSOLVER` backend is not available.") if force_x64: matrix_dtype = jnp.promote_types(matrix.dtype, jnp.float64) else: From 64e79620f8aa8fb19ba0eba4d2b8a8a2ea022ce0 Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 17:40:13 -0700 Subject: [PATCH 03/12] use python 3.13 --- .github/workflows/build-ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index f782d76..c0d9c44 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" cache: "pip" cache-dependency-path: pyproject.toml - name: Test pre-commit hooks @@ -36,7 +36,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.13" cache: "pip" cache-dependency-path: pyproject.toml @@ -55,6 +55,10 @@ jobs: tests: runs-on: ubuntu-latest + strategy: + matrix: + python-versions: ["3.10", "3.13"] + steps: - name: Checkout repository uses: actions/checkout@v5 @@ -62,7 +66,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: ${{ matrix.python-version }} cache: "pip" cache-dependency-path: pyproject.toml From 43b4a7d1ab5357041e521123cc245135c90e7552 Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 17:40:32 -0700 Subject: [PATCH 04/12] fixes --- src/jeig/jeig.py | 55 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/src/jeig/jeig.py b/src/jeig/jeig.py index 82ce47f..abe0b83 100644 --- a/src/jeig/jeig.py +++ b/src/jeig/jeig.py @@ -1,10 +1,14 @@ -"""Various implementations of `eig` wrapped for use with jax.""" +"""Various implementations of `eig` wrapped for use with jax. + +Copyright (c) 2025 invrs.io LLC +""" import enum import functools import multiprocessing as mp import os import warnings +from packaging import version from typing import Any, List, Optional, Tuple import jax @@ -25,9 +29,13 @@ os.path.dirname(torch.__file__), "lib", "libtorch_cuda_linalg.so" ) -# Identify whether MAGMA and CUSOLVER backends are available. -_JAX_HAS_MAGMA = torch.cuda.has_magma -_JAX_HAS_CUSOLVER = hasattr(jax.lax.linalg, "EigImplementation") +# Versions of jax newer than `0.8.0` have an `jax.lax.linalg.eig` function with an +# `implementation` argument, and support eigendecomposition via cusolver. +_SUPPORTS_CUSOLVER = version.parse(jax.__version__) >= version.parse("0.8.0") + +# Identify whether the magma backend is available. +_SUPPORTS_MAGMA = torch.cuda.has_magma + callback = functools.partial(jax.pure_callback, vmap_method="expand_dims") callback_sequential = functools.partial(jax.pure_callback, vmap_method="sequential") @@ -102,8 +110,8 @@ def _eig_cusolver( matrix: jnp.ndarray, force_x64: bool ) -> Tuple[jnp.ndarray, jnp.ndarray]: """Eigendecomposition using `jax.lax.linalg.eig` with `cusolver` backend.""" - if not _JAX_HAS_CUSOLVER: - raise ValueError("`CUSOLVER` backend is not available.") + if not _SUPPORTS_CUSOLVER: + raise RuntimeError("`CUSOLVER` backend is not available.") if force_x64: matrix_dtype = jnp.promote_types(matrix.dtype, jnp.float64) else: @@ -113,7 +121,7 @@ def _eig_cusolver( eigval, eigvec = jax.lax.linalg.eig( matrix.astype(matrix_dtype), compute_left_eigenvectors=False, - implementation="cusolver", # type: ignore[call-arg] + implementation=jax.lax.linalg.EigImplementation.CUSOLVER, ) return eigval.astype(output_dtype), eigvec.astype(output_dtype) @@ -128,11 +136,18 @@ def _eig_lapack( matrix_dtype = matrix.dtype output_dtype = jnp.promote_types(matrix, jnp.complex64) - eig_fn = functools.partial(jax.lax.linalg.eig, compute_left_eigenvectors=False) - if _JAX_HAS_CUSOLVER: - eig_fn = functools.partial(eig_fn, implementation="lapack") + if _SUPPORTS_CUSOLVER: + eig_fn = functools.partial( + jax.lax.linalg.eig, + compute_left_eigenvectors=False, + implementation=jax.lax.linalg.EigImplementation.LAPACK, + ) else: - eig_fn = functools.partial(eig_fn, use_magma=False) + eig_fn = functools.partial( + jax.lax.linalg.eig, + compute_left_eigenvectors=False, + use_magma=False, + ) eigval, eigvec = eig_fn(matrix.astype(matrix_dtype)) return eigval.astype(output_dtype), eigvec.astype(output_dtype) @@ -140,8 +155,8 @@ def _eig_lapack( def _eig_magma(matrix: jnp.ndarray, force_x64: bool) -> Tuple[jnp.ndarray, jnp.ndarray]: """Eigendecomposition using `jax.lax.linalg.eig` with `magma` backend.""" - if not _JAX_HAS_MAGMA: - raise ValueError( + if not _SUPPORTS_MAGMA: + raise RuntimeError( "`MAGMA` backend is not available; `torch.cuda.has_magma` is `False`." ) if force_x64: @@ -151,10 +166,18 @@ def _eig_magma(matrix: jnp.ndarray, force_x64: bool) -> Tuple[jnp.ndarray, jnp.n output_dtype = jnp.promote_types(matrix, jnp.complex64) eig_fn = functools.partial(jax.lax.linalg.eig, compute_left_eigenvectors=False) - if _JAX_HAS_CUSOLVER: - eig_fn = functools.partial(eig_fn, implementation="magma") + if _SUPPORTS_CUSOLVER: + eig_fn = functools.partial( + jax.lax.linalg.eig, + compute_left_eigenvectors=False, + implementation=jax.lax.linalg.EigImplementation.MAGMA, + ) else: - eig_fn = functools.partial(eig_fn, use_magma=True) + eig_fn = functools.partial( + jax.lax.linalg.eig, + compute_left_eigenvectors=False, + use_magma=True, + ) eigval, eigvec = eig_fn(matrix.astype(matrix_dtype)) return eigval.astype(output_dtype), eigvec.astype(output_dtype) From 9ecab8e4ee3e02858a03daa952758a93279daa80 Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 17:40:45 -0700 Subject: [PATCH 05/12] update copyright statements --- LICENSE | 2 +- tests/test_eig.py | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/LICENSE b/LICENSE index cf472ee..271b2ae 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2024, Martin Schubert +Copyright (c) 2025 invrs.io LLC Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/tests/test_eig.py b/tests/test_eig.py index 97bf24e..1f74eb8 100644 --- a/tests/test_eig.py +++ b/tests/test_eig.py @@ -1,4 +1,7 @@ -"""Tests for jax-wrapped eigendecomposition.""" +"""Tests for jax-wrapped eigendecomposition. + +Copyright (c) 2025 invrs.io LLC +""" import itertools import unittest @@ -20,14 +23,15 @@ jeig.EigBackend.SCIPY, jeig.EigBackend.TORCH, ] -# Only test the magma backend if supported by the installed jax and torch versions. -if _jeig._JAX_HAS_MAGMA: - BACKENDS.append(jeig.EigBackend.MAGMA) # Only test the cusolver backend if supported by the installed jax version. -if _jeig._JAX_HAS_CUSOLVER: +if _jeig._SUPPORTS_CUSOLVER: BACKENDS.append(jeig.EigBackend.CUSOLVER) +# Only test the magma backend if supported by the installed jax and torch versions. +if _jeig._SUPPORTS_MAGMA: + BACKENDS.append(jeig.EigBackend.MAGMA) + SHAPES = [(1, 2, 2), (1, 16, 16), (2, 16, 16), (2, 64, 64)] From e2b37ed2b5f32186981acbff0b97652bf089aefd Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 17:41:08 -0700 Subject: [PATCH 06/12] add packaging dep --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index ed39d9c..c5edd6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ dependencies = [ "jax>=0.4.36", "jaxlib", "numpy", + "packaging", "scipy", "torch", ] From 90379f82ed4444e3854b5ca6805940c004e36b4e Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 17:49:46 -0700 Subject: [PATCH 07/12] detect old jax versions --- src/jeig/jeig.py | 10 +++++++--- tests/test_eig.py | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/jeig/jeig.py b/src/jeig/jeig.py index abe0b83..5df0b27 100644 --- a/src/jeig/jeig.py +++ b/src/jeig/jeig.py @@ -31,7 +31,11 @@ # Versions of jax newer than `0.8.0` have an `jax.lax.linalg.eig` function with an # `implementation` argument, and support eigendecomposition via cusolver. -_SUPPORTS_CUSOLVER = version.parse(jax.__version__) >= version.parse("0.8.0") +_SUPPORTS_IMPLEMENTATION = version.parse(jax.__version__) >= version.parse("0.8.0")_ + +# Versions of jax newer than `0.8.0` have an `jax.lax.linalg.eig` function with an +# `implementation` argument, and support eigendecomposition via cusolver. +_SUPPORTS_CUSOLVER = _SUPPORTS_IMPLEMENTATION and jax.devices()[0].platform == "gpu" # Identify whether the magma backend is available. _SUPPORTS_MAGMA = torch.cuda.has_magma @@ -136,7 +140,7 @@ def _eig_lapack( matrix_dtype = matrix.dtype output_dtype = jnp.promote_types(matrix, jnp.complex64) - if _SUPPORTS_CUSOLVER: + if _SUPPORTS_IMPLEMENTATION: eig_fn = functools.partial( jax.lax.linalg.eig, compute_left_eigenvectors=False, @@ -166,7 +170,7 @@ def _eig_magma(matrix: jnp.ndarray, force_x64: bool) -> Tuple[jnp.ndarray, jnp.n output_dtype = jnp.promote_types(matrix, jnp.complex64) eig_fn = functools.partial(jax.lax.linalg.eig, compute_left_eigenvectors=False) - if _SUPPORTS_CUSOLVER: + if _SUPPORTS_IMPLEMENTATION: eig_fn = functools.partial( jax.lax.linalg.eig, compute_left_eigenvectors=False, diff --git a/tests/test_eig.py b/tests/test_eig.py index 1f74eb8..081fa66 100644 --- a/tests/test_eig.py +++ b/tests/test_eig.py @@ -25,7 +25,7 @@ ] # Only test the cusolver backend if supported by the installed jax version. -if _jeig._SUPPORTS_CUSOLVER: +if _jeig._SUPPORTS_CUSOLVER and jax.devices()[0].platform == "gpu": BACKENDS.append(jeig.EigBackend.CUSOLVER) # Only test the magma backend if supported by the installed jax and torch versions. From c00af188f4d80002a8d707e7ee79eb86c15cd93e Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 18:13:06 -0700 Subject: [PATCH 08/12] fix --- src/jeig/jeig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jeig/jeig.py b/src/jeig/jeig.py index 5df0b27..c77018e 100644 --- a/src/jeig/jeig.py +++ b/src/jeig/jeig.py @@ -31,7 +31,7 @@ # Versions of jax newer than `0.8.0` have an `jax.lax.linalg.eig` function with an # `implementation` argument, and support eigendecomposition via cusolver. -_SUPPORTS_IMPLEMENTATION = version.parse(jax.__version__) >= version.parse("0.8.0")_ +_SUPPORTS_IMPLEMENTATION = version.parse(jax.__version__) >= version.parse("0.8.0") # Versions of jax newer than `0.8.0` have an `jax.lax.linalg.eig` function with an # `implementation` argument, and support eigendecomposition via cusolver. From 0cf6d1d3590e221f32561d1c3c7ea83afdf61f94 Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 18:23:46 -0700 Subject: [PATCH 09/12] improve docs --- README.md | 31 +++++++++++++++++++++---------- src/jeig/jeig.py | 5 +---- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 9439e27..ff92733 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## Overview -This package wraps eigendecompositions as provided by jax, cusolver, magma, numpy, scipy, and torch for use with jax. Depending upon your system and your versions of these packages, you may observe significant speed differences. The following were obtained using jax 0.4.37 on a system with 28-core Intel Xeon w7-3465X and NVIDIA RTX4090. +This package wraps eigendecompositions as provided by jax, cusolver, magma, numpy, scipy, and torch for use with jax. Depending upon your system and your versions of these packages, you may observe significant speed differences. The following were obtained using jax 0.8.0 on a system with 28-core Intel Xeon w7-3465X and NVIDIA RTX4090. ![Speed comparison](https://github.com/mfschubert/jeig/blob/main/docs/speed.png?raw=true) @@ -21,24 +21,35 @@ This will also install torch. If you only need torch for use with jeig, then the import jax import jeig -matrix = jax.random.normal(jax.random.PRNGKey(0), (16, 1024, 1024)) +matrix = jax.random.normal(jax.random.PRNGKey(0), (1, 2048, 2048)).astype(complex) +%timeit jax.block_until_ready(jeig.eig(matrix, backend="cusolver")) %timeit jax.block_until_ready(jeig.eig(matrix, backend="lapack")) - %timeit jax.block_until_ready(jeig.eig(matrix, backend="magma")) +%timeit jax.block_until_ready(jeig.eig(matrix, backend="torch")) +``` +``` +1.31 s ± 43 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) +5.44 s ± 379 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) +11.1 s ± 937 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) +4.93 s ± 92.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) +``` -%timeit jax.block_until_ready(jeig.eig(matrix, backend="numpy")) +The default torch backend has good performance when performing batched eigendecomposition on many-core CPUs. -%timeit jax.block_until_ready(jeig.eig(matrix, backend="scipy")) +```python +matrix = jax.random.normal(jax.random.PRNGKey(0), (8, 2048, 2048)).astype(complex) +%timeit jax.block_until_ready(jeig.eig(matrix, backend="cusolver")) +%timeit jax.block_until_ready(jeig.eig(matrix, backend="lapack")) +%timeit jax.block_until_ready(jeig.eig(matrix, backend="magma")) %timeit jax.block_until_ready(jeig.eig(matrix, backend="torch")) ``` ``` -6.81 s ± 54.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) -1min 15s ± 1.35 s per loop (mean ± std. dev. of 7 runs, 1 loop each) -28.6 s ± 341 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) -14.8 s ± 396 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) -1.43 s ± 77.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) +10.4 s ± 116 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) +48.1 s ± 6.74 s per loop (mean ± std. dev. of 7 runs, 1 loop each) +1min 33s ± 1.49 s per loop (mean ± std. dev. of 7 runs, 1 loop each) +7.18 s ± 91.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) ``` ## Credit diff --git a/src/jeig/jeig.py b/src/jeig/jeig.py index c77018e..4047b63 100644 --- a/src/jeig/jeig.py +++ b/src/jeig/jeig.py @@ -30,11 +30,8 @@ ) # Versions of jax newer than `0.8.0` have an `jax.lax.linalg.eig` function with an -# `implementation` argument, and support eigendecomposition via cusolver. +# `implementation` argument, and support eigendecomposition via cusolver (if on GPU). _SUPPORTS_IMPLEMENTATION = version.parse(jax.__version__) >= version.parse("0.8.0") - -# Versions of jax newer than `0.8.0` have an `jax.lax.linalg.eig` function with an -# `implementation` argument, and support eigendecomposition via cusolver. _SUPPORTS_CUSOLVER = _SUPPORTS_IMPLEMENTATION and jax.devices()[0].platform == "gpu" # Identify whether the magma backend is available. From 0085438e23566263834e0f61c967ab4db4110bf7 Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 18:28:11 -0700 Subject: [PATCH 10/12] properly detect magma support --- src/jeig/jeig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jeig/jeig.py b/src/jeig/jeig.py index 4047b63..2568ca3 100644 --- a/src/jeig/jeig.py +++ b/src/jeig/jeig.py @@ -35,7 +35,7 @@ _SUPPORTS_CUSOLVER = _SUPPORTS_IMPLEMENTATION and jax.devices()[0].platform == "gpu" # Identify whether the magma backend is available. -_SUPPORTS_MAGMA = torch.cuda.has_magma +_SUPPORTS_MAGMA = torch.cuda.has_magma and jax.devices()[0].platform == "gpu" callback = functools.partial(jax.pure_callback, vmap_method="expand_dims") From a68b7e9fe8757608a389f67a2b09a50fbe3b3126 Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 18:50:26 -0700 Subject: [PATCH 11/12] fix matrix test strategy --- .github/workflows/build-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index c0d9c44..18bc855 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -57,7 +57,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-versions: ["3.10", "3.13"] + python-version: ["3.10", "3.13"] steps: - name: Checkout repository From 90e477e85cbb0a7866bab783d4811bca6d5b9fcf Mon Sep 17 00:00:00 2001 From: Martin Schubert Date: Sat, 18 Oct 2025 19:12:54 -0700 Subject: [PATCH 12/12] update speed plot --- docs/speed.png | Bin 60586 -> 53772 bytes notebooks/test.ipynb | 44 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/docs/speed.png b/docs/speed.png index 347516075a98a8c414b40c105e2c941ce2c7a832..a870d7924511f48a12f3640cc2cfcfeee2931889 100644 GIT binary patch literal 53772 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 QA;FKNn5<~Nu)fd#0!2SvQUCw| literal 60586 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 W!=`2f$D_3Hwa(SUrG&oYt6u^Aqi`?) diff --git a/notebooks/test.ipynb b/notebooks/test.ipynb index 306f2e6..cbb3ebe 100644 --- a/notebooks/test.ipynb +++ b/notebooks/test.ipynb @@ -22,15 +22,13 @@ "metadata": {}, "outputs": [], "source": [ - "batch_size = [1, 16]\n", + "batch_size = [1, 8]\n", "matrix_size = [16, 32, 64, 128, 256, 512, 1024, 2048, 4096]\n", "repeats = 3\n", "backends = [\n", " jeig.EigBackend.CUSOLVER,\n", " jeig.EigBackend.LAPACK,\n", " jeig.EigBackend.MAGMA,\n", - " jeig.EigBackend.NUMPY,\n", - " jeig.EigBackend.SCIPY,\n", " jeig.EigBackend.TORCH,\n", "]\n", "\n", @@ -48,7 +46,7 @@ " for backend in backends:\n", " for repeat in range(repeats):\n", " key = jax.random.fold_in(jax.random.PRNGKey(0), repeat)\n", - " matrix = jax.random.normal(key, shape)\n", + " matrix = jax.random.normal(key, shape).astype(complex)\n", " t0 = time.time()\n", " jax.block_until_ready(fns[backend](matrix))\n", " et = time.time() - t0\n", @@ -76,11 +74,45 @@ " ax.set_xlabel(\"Matrix size\")\n", "plt.tight_layout()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "import jeig\n", + "\n", + "matrix = jax.random.normal(jax.random.PRNGKey(0), (8, 2048, 2048)).astype(complex)\n", + "\n", + "%timeit jax.block_until_ready(jeig.eig(matrix, backend=\"cusolver\"))\n", + "%timeit jax.block_until_ready(jeig.eig(matrix, backend=\"lapack\"))\n", + "%timeit jax.block_until_ready(jeig.eig(matrix, backend=\"magma\"))\n", + "%timeit jax.block_until_ready(jeig.eig(matrix, backend=\"torch\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "import jeig\n", + "\n", + "matrix = jax.random.normal(jax.random.PRNGKey(0), (1, 2048, 2048)).astype(complex)\n", + "\n", + "%timeit jax.block_until_ready(jeig.eig(matrix, backend=\"cusolver\"))\n", + "%timeit jax.block_until_ready(jeig.eig(matrix, backend=\"lapack\"))\n", + "%timeit jax.block_until_ready(jeig.eig(matrix, backend=\"magma\"))\n", + "%timeit jax.block_until_ready(jeig.eig(matrix, backend=\"torch\"))" + ] } ], "metadata": { "kernelspec": { - "display_name": "invrs", + "display_name": "invrs5", "language": "python", "name": "python3" }, @@ -94,7 +126,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.12" + "version": "3.13.9" } }, "nbformat": 4,