jaxdecomp 0.3.2__tar.gz → 0.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/.github/workflows/ci.yml +5 -1
  2. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/PKG-INFO +4 -3
  3. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/pyproject.toml +3 -2
  4. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/cudecomp/fft.py +3 -1
  5. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/cudecomp/halo.py +3 -1
  6. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/cudecomp/transpose.py +3 -1
  7. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/jax/fft.py +3 -1
  8. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/jax/halo.py +3 -1
  9. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/jax/transpose.py +3 -1
  10. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/tests/conftest.py +6 -0
  11. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/tests/test_fft.py +56 -1
  12. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/tests/test_halo.py +60 -0
  13. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/tests/test_transpose.py +60 -1
  14. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/uv.lock +66 -52
  15. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/.clang-format +0 -0
  16. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/.github/constraints/cibw-build-constraints.txt +0 -0
  17. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/.github/workflows/joss-paper-pdf.yml +0 -0
  18. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/.github/workflows/release.yml +0 -0
  19. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/.gitignore +0 -0
  20. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/.gitmodules +0 -0
  21. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/.pre-commit-config.yaml +0 -0
  22. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/.readthedocs.yml +0 -0
  23. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/CHANGELOG.md +0 -0
  24. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/CITATION.cff +0 -0
  25. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/CMakeLists.txt +0 -0
  26. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/CONTRIBUTING.md +0 -0
  27. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/GEMINI.md +0 -0
  28. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/LICENSE +0 -0
  29. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/README.md +0 -0
  30. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/benchmarks/bench.py +0 -0
  31. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/benchmarks/slurm.sh +0 -0
  32. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/benchmarks/slurm_strong_scaling.sh +0 -0
  33. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/01-basic_usage.md +0 -0
  34. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/02-decomposition.md +0 -0
  35. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/03-distributed_ffts.md +0 -0
  36. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/04-halo_exchange.md +0 -0
  37. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/05-transpositions.md +0 -0
  38. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/06-caveats.md +0 -0
  39. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/07-xla_sharding_configuration.md +0 -0
  40. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/Makefile +0 -0
  41. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/api.rst +0 -0
  42. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/conf.py +0 -0
  43. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/index.rst +0 -0
  44. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/installation.md +0 -0
  45. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/docs/make.bat +0 -0
  46. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/examples/01-demo_features.ipynb +0 -0
  47. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/examples/02-tpu_fft_demo.ipynb +0 -0
  48. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/examples/03-nested-parallelism.ipynb +0 -0
  49. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/examples/README.md +0 -0
  50. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/examples/lpt_nbody_demo.py +0 -0
  51. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/examples/scatter.py +0 -0
  52. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/examples/submit_rusty.sbatch +0 -0
  53. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/examples/visualizer.ipynb +0 -0
  54. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/joss-paper/assets/LPT_density_field_z0_2048.png +0 -0
  55. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/joss-paper/assets/benchmark.png +0 -0
  56. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/joss-paper/assets/decomp2d.gif +0 -0
  57. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/joss-paper/assets/fft.svg +0 -0
  58. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/joss-paper/assets/halo-exchange.svg +0 -0
  59. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/joss-paper/assets/strong_scaling.png +0 -0
  60. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/joss-paper/assets/weak_scaling.png +0 -0
  61. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/joss-paper/paper.bib +0 -0
  62. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/joss-paper/paper.md +0 -0
  63. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/slurms/README.md +0 -0
  64. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/slurms/template.slurm +0 -0
  65. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/fft.cu +0 -0
  66. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/grid_descriptor_mgr.cc +0 -0
  67. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/halo.cu +0 -0
  68. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/include/checks.h +0 -0
  69. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/include/fft.h +0 -0
  70. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/include/grid_descriptor_mgr.h +0 -0
  71. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/include/halo.h +0 -0
  72. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/include/jaxdecomp.h +0 -0
  73. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/include/logger.hpp +0 -0
  74. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/include/perfostep.hpp +0 -0
  75. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/include/transpose.h +0 -0
  76. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/jaxdecomp.cc +0 -0
  77. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/csrc/transpose.cu +0 -0
  78. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/__init__.py +0 -0
  79. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/__init__.py +0 -0
  80. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/cudecomp/__init__.py +0 -0
  81. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/error.py +0 -0
  82. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/fft_utils.py +0 -0
  83. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/jax/__init__.py +0 -0
  84. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/jax/fftfreq.py +0 -0
  85. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/pencil_utils.py +0 -0
  86. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/_src/spmd_ops.py +0 -0
  87. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/fft.py +0 -0
  88. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/halo.py +0 -0
  89. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/transpose.py +0 -0
  90. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/src/jaxdecomp/typing.py +0 -0
  91. {jaxdecomp-0.3.2 → jaxdecomp-0.3.4}/tests/run_all_tests.sh +0 -0
@@ -25,6 +25,7 @@ jobs:
25
25
  test:
26
26
  name: Run tests on Python ${{ matrix.python-version }}
27
27
  runs-on: ubuntu-latest
28
+ timeout-minutes: 30
28
29
  strategy:
29
30
  fail-fast: false
30
31
  matrix:
@@ -48,10 +49,13 @@ jobs:
48
49
  - name: Run tests
49
50
  # --doctest-modules imports jax at collection time, before conftest's session
50
51
  # fixture runs, so the device-count flags must be set in the environment here.
52
+ # JAXDECOMP_SKIP_PRIME_TESTS: the prime-sized FFTs deadlock XLA's CPU collective
53
+ # rendezvous on 4-core runners (thread starvation), see the conftest note.
51
54
  env:
52
55
  JAX_PLATFORM_NAME: cpu
53
56
  XLA_FLAGS: "--xla_force_host_platform_device_count=8"
54
- run: uv run pytest -v
57
+ JAXDECOMP_SKIP_PRIME_TESTS: '1'
58
+ run: uv run pytest -v --timeout=600 --timeout-method=thread
55
59
 
56
60
  docs:
57
61
  name: Build documentation
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaxdecomp
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: JAX bindings for the cuDecomp library
5
5
  Author: Wassim Kabalan, Francois Lanusse
6
6
  License: MIT License
@@ -35,16 +35,17 @@ Classifier: Intended Audience :: Science/Research
35
35
  Project-URL: Homepage, https://github.com/DifferentiableUniverseInitiative/jaxDecomp
36
36
  Requires-Python: >=3.12
37
37
  Requires-Dist: jaxtyping>=0.2.0
38
- Requires-Dist: jax>=0.11.1
38
+ Requires-Dist: jax>=0.11.2
39
39
  Provides-Extra: test
40
40
  Requires-Dist: pytest>=8.0.0; extra == "test"
41
41
  Requires-Dist: pytest-cov; extra == "test"
42
42
  Requires-Dist: pytest-mock; extra == "test"
43
+ Requires-Dist: pytest-timeout; extra == "test"
43
44
  Requires-Dist: chex; extra == "test"
44
45
  Provides-Extra: benchmark
45
46
  Requires-Dist: jax-hpc-profiler>=0.3.2; extra == "benchmark"
46
47
  Provides-Extra: cuda
47
- Requires-Dist: jax[cuda12]>=0.11.1; extra == "cuda"
48
+ Requires-Dist: jax[cuda12]>=0.11.2; extra == "cuda"
48
49
  Description-Content-Type: text/markdown
49
50
 
50
51
 
@@ -31,7 +31,7 @@ classifiers = [
31
31
  ]
32
32
  dependencies = [
33
33
  "jaxtyping>=0.2.0",
34
- "jax>=0.11.1",
34
+ "jax>=0.11.2",
35
35
  ]
36
36
 
37
37
  [project.optional-dependencies]
@@ -39,13 +39,14 @@ test = [
39
39
  "pytest>=8.0.0",
40
40
  "pytest-cov",
41
41
  "pytest-mock",
42
+ "pytest-timeout",
42
43
  "chex",
43
44
  ]
44
45
  benchmark = [
45
46
  "jax-hpc-profiler>=0.3.2",
46
47
  ]
47
48
  cuda = [
48
- "jax[cuda12]>=0.11.1",
49
+ "jax[cuda12]>=0.11.2",
49
50
  ]
50
51
 
51
52
  [dependency-groups]
@@ -9,7 +9,7 @@ from jax import ShapeDtypeStruct
9
9
  from jax._src.interpreters import ad, mlir
10
10
  from jax._src.numpy.util import promote_dtypes_complex
11
11
  from jax.core import ShapedArray
12
- from jax.experimental.hijax import VJPHiPrimitive as HiPrim
12
+ from jax.experimental.hijax import HiPrim, linearize_from_jvp
13
13
  from jax.sharding import Mesh, NamedSharding
14
14
  from jax.sharding import PartitionSpec as P
15
15
  from jaxdecomplib import _jaxdecomp
@@ -483,6 +483,8 @@ class PfftHiPrim(HiPrim):
483
483
  y_dot = self.expand(x_dot)
484
484
  return y, y_dot
485
485
 
486
+ lin, linearized = linearize_from_jvp
487
+
486
488
  def vjp_fwd(self, nzs_in, x):
487
489
  return self.expand(x), (self.params['fft_type'], self.params['adjoint'])
488
490
 
@@ -9,7 +9,7 @@ from jax import ShapeDtypeStruct
9
9
  from jax._src.interpreters import ad, mlir
10
10
  from jax._src.typing import Array
11
11
  from jax.core import ShapedArray
12
- from jax.experimental.hijax import VJPHiPrimitive as HiPrim
12
+ from jax.experimental.hijax import HiPrim, linearize_from_jvp
13
13
  from jax.sharding import Mesh, NamedSharding
14
14
  from jax.sharding import PartitionSpec as P
15
15
  from jaxdecomplib import _jaxdecomp
@@ -436,6 +436,8 @@ class HaloExchangeHiPrim(HiPrim):
436
436
  y_dot = self.expand(x_dot)
437
437
  return y, y_dot
438
438
 
439
+ lin, linearized = linearize_from_jvp
440
+
439
441
  def vjp_fwd(self, nzs_in, x):
440
442
  return self.expand(x), x
441
443
 
@@ -10,7 +10,7 @@ from jax._src.interpreters import ad, mlir
10
10
  from jax._src.lib.mlir.dialects import hlo
11
11
  from jax._src.typing import Array, ArrayLike
12
12
  from jax.core import ShapedArray
13
- from jax.experimental.hijax import VJPHiPrimitive as HiPrim
13
+ from jax.experimental.hijax import HiPrim, linearize_from_jvp
14
14
  from jax.sharding import Mesh, NamedSharding
15
15
  from jax.sharding import PartitionSpec as P
16
16
  from jaxdecomplib import _jaxdecomp
@@ -557,6 +557,8 @@ class TransposeHiPrim(HiPrim):
557
557
  y_dot = self.expand(x_dot)
558
558
  return y, y_dot
559
559
 
560
+ lin, linearized = linearize_from_jvp
561
+
560
562
  def vjp_fwd(self, nzs_in, x):
561
563
  return self.expand(x), None
562
564
 
@@ -6,7 +6,7 @@ from jax._src.api import ShapeDtypeStruct
6
6
  from jax._src.core import ShapedArray
7
7
  from jax._src.interpreters import batching
8
8
  from jax._src.typing import Array
9
- from jax.experimental.hijax import VJPHiPrimitive as HiPrim
9
+ from jax.experimental.hijax import HiPrim, linearize_from_jvp
10
10
  from jax.sharding import Mesh, NamedSharding
11
11
  from jax.sharding import PartitionSpec as P
12
12
  from jaxdecomplib import _jaxdecomp
@@ -613,6 +613,8 @@ class PfftHiPrim(HiPrim):
613
613
  y_dot = self(x_dot)
614
614
  return y, y_dot
615
615
 
616
+ lin, linearized = linearize_from_jvp
617
+
616
618
  def vjp_fwd(self, nzs_in, x):
617
619
  return self(x), (self.params['fft_type'], self.params['adjoint'])
618
620
 
@@ -4,7 +4,7 @@ import jax
4
4
  from jax import ShapeDtypeStruct, lax
5
5
  from jax._src.interpreters import batching
6
6
  from jax.core import ShapedArray
7
- from jax.experimental.hijax import VJPHiPrimitive as HiPrim
7
+ from jax.experimental.hijax import HiPrim, linearize_from_jvp
8
8
  from jax.sharding import Mesh, NamedSharding
9
9
  from jax.sharding import PartitionSpec as P
10
10
  from jaxdecomplib import _jaxdecomp
@@ -508,6 +508,8 @@ class HaloExchangeHiPrim(HiPrim):
508
508
  y_dot = self(x_dot)
509
509
  return y, y_dot
510
510
 
511
+ lin, linearized = linearize_from_jvp
512
+
511
513
  def vjp_fwd(self, nzs_in, x):
512
514
  return self(x), x
513
515
 
@@ -5,7 +5,7 @@ from jax import ShapeDtypeStruct, lax
5
5
  from jax._src.interpreters import batching
6
6
  from jax._src.typing import Array, ArrayLike
7
7
  from jax.core import ShapedArray
8
- from jax.experimental.hijax import VJPHiPrimitive as HiPrim
8
+ from jax.experimental.hijax import HiPrim, linearize_from_jvp
9
9
  from jax.sharding import Mesh, NamedSharding
10
10
  from jax.sharding import PartitionSpec as P
11
11
 
@@ -360,6 +360,8 @@ class TransposeHiPrim(HiPrim):
360
360
  y_dot = self(x_dot)
361
361
  return y, y_dot
362
362
 
363
+ lin, linearized = linearize_from_jvp
364
+
363
365
  def vjp_fwd(self, nzs_in, x):
364
366
  return self(x), None
365
367
 
@@ -6,6 +6,12 @@ import pytest
6
6
  setup_done = False
7
7
  on_cluster = False
8
8
 
9
+ # XLA CPU collective starvation: on core-limited machines (e.g. 4-core CI runners), the
10
+ # prime-sized shapes exercise long-running all_to_all collectives that deadlock the XLA CPU
11
+ # rendezvous. CI sets JAXDECOMP_SKIP_PRIME_TESTS=1 to skip them; local machines and the
12
+ # cluster (where the tests pass and matter) run them by default.
13
+ skip_prime_tests = os.environ.get('JAXDECOMP_SKIP_PRIME_TESTS', '0') == '1'
14
+
9
15
 
10
16
  def is_on_cluster():
11
17
  global on_cluster
@@ -6,6 +6,7 @@ from conftest import (
6
6
  create_spmd_array,
7
7
  initialize_distributed,
8
8
  is_on_cluster,
9
+ skip_prime_tests,
9
10
  )
10
11
 
11
12
  initialize_distributed()
@@ -46,7 +47,13 @@ decomp = [
46
47
  global_shapes = [
47
48
  pytest.param((8, 16, 32), id='8x16x32'),
48
49
  pytest.param((8, 8, 8), id='8x8x8'),
49
- pytest.param((29 * size, 19 * size, 17 * size), id='prime_sizes'),
50
+ pytest.param(
51
+ (29 * size, 19 * size, 17 * size),
52
+ id='prime_sizes',
53
+ marks=pytest.mark.skipif(
54
+ skip_prime_tests, reason='prime shapes deadlock XLA CPU collectives on core-limited runners (JAXDECOMP_SKIP_PRIME_TESTS=1)'
55
+ ),
56
+ ),
50
57
  ] # Cubes, non-cubes and primes
51
58
  local_transpose = [
52
59
  pytest.param(True, id='local_transpose'),
@@ -309,6 +316,54 @@ class TestFFTsGrad:
309
316
  global_shape = (4, 4, 4)
310
317
  self._run_hessian_test(pdims, global_shape, local_transpose, 'cuDecomp', use_shardy, axis_type)
311
318
 
319
+ def _run_linearize_test(self, local_transpose, use_shardy, backend):
320
+ """Test that jax.linearize works with FFT (the HiPrim `lin`/`linearized` rules).
321
+
322
+ The linearized map must agree with the jvp rule (the FFT is linear) and satisfy
323
+ the transpose dot-product test ⟨w, J v⟩ == ⟨Jᵀ w, v⟩.
324
+ """
325
+ if use_shardy and not ALLOW_SHARDY_PARTITIONER:
326
+ pytest.skip(reason='Shardy partitioner is not supported in this JAX version use at least JAX 0.7.0')
327
+
328
+ jaxdecomp.config.update('transpose_axis_contiguous', local_transpose)
329
+ jax.config.update('jax_use_shardy_partitioner', use_shardy)
330
+
331
+ def f(arr):
332
+ return jaxdecomp.fft.pfft3d(arr, backend=backend)
333
+
334
+ # Small non-distributed array, like the hessian test
335
+ x = jax.random.normal(jax.random.PRNGKey(0), (4, 4, 4), dtype=jnp.float64)
336
+ v = jax.random.normal(jax.random.PRNGKey(1), x.shape, dtype=x.dtype)
337
+
338
+ # jax.linearize requires the HiPrim `lin`/`linearized` rules
339
+ _, lin_fn = jax.linearize(f, x)
340
+
341
+ # The linearized map must agree with the jvp rule (the FFT is linear)
342
+ _, Jv_jvp = jax.jvp(f, (x,), (v,))
343
+ Jv_lin = lin_fn(v)
344
+ assert assert_allclose(Jv_jvp, Jv_lin, rtol=1e-5, atol=1e-5)
345
+
346
+ # Transpose dot-product test: Re[wᵀ(J v)] == (Jᵀ w)ᵀv — the real part of the bilinear
347
+ # pairing, which is the transpose contract jax.linear_transpose defines for complex
348
+ # outputs on real inputs (the returned cotangent Jᵀ w is real).
349
+ w = jax.random.normal(jax.random.PRNGKey(2), Jv_lin.shape, dtype=Jv_lin.dtype)
350
+ _, vjp_fn = jax.vjp(f, x)
351
+ (JTw,) = vjp_fn(w)
352
+ assert assert_allclose(jnp.sum(w * Jv_lin).real, jnp.sum(JTw * v), rtol=1e-5, atol=1e-5)
353
+
354
+ @pytest.mark.parametrize('use_shardy', use_shardy)
355
+ @pytest.mark.parametrize('local_transpose', local_transpose)
356
+ def test_jax_linearize(self, local_transpose, use_shardy):
357
+ """Test that jax.linearize works with FFT (JAX backend)."""
358
+ self._run_linearize_test(local_transpose, use_shardy, 'jax')
359
+
360
+ @pytest.mark.skipif(not is_on_cluster(), reason='Only run on cluster')
361
+ @pytest.mark.parametrize('use_shardy', use_shardy)
362
+ @pytest.mark.parametrize('local_transpose', local_transpose)
363
+ def test_cudecomp_linearize(self, local_transpose, use_shardy):
364
+ """Test that jax.linearize works with FFT (cuDecomp backend)."""
365
+ self._run_linearize_test(local_transpose, use_shardy, 'cuDecomp')
366
+
312
367
  @pytest.mark.skipif(not is_on_cluster(), reason='Only run on cluster')
313
368
  @pytest.mark.parametrize('local_transpose', local_transpose) # Test with and without local transpose
314
369
  @pytest.mark.parametrize('pdims', decomp) # Test with Slab and Pencil decompositions
@@ -440,6 +440,66 @@ class TestHaloExchangeGrad:
440
440
  def test_cudecomp_hessian(self, pdims, use_shardy, axis_type):
441
441
  self._run_hessian_test(pdims, 'CUDECOMP', use_shardy, axis_type)
442
442
 
443
+ def _run_linearize_test(self, pdims, backend, use_shardy):
444
+ """Test that jax.linearize works with halo exchange (the HiPrim `lin`/`linearized` rules).
445
+
446
+ The linearized map must agree with the jvp rule (halo exchange is linear) and
447
+ satisfy the transpose dot-product test ⟨w, J v⟩ == ⟨Jᵀ w, v⟩.
448
+ """
449
+ jax.config.update('jax_use_shardy_partitioner', use_shardy)
450
+
451
+ if use_shardy and not ALLOW_SHARDY_PARTITIONER:
452
+ pytest.skip(reason='Shardy partitioner is not supported in this JAX version use at least JAX 0.7.0')
453
+
454
+ halo_size = 2
455
+
456
+ halo_x = (halo_size, halo_size) if pdims[0] > 1 else (0, 0)
457
+ halo_y = (halo_size, halo_size) if pdims[1] > 1 else (0, 0)
458
+ halo_extents = (halo_x[0], halo_y[0])
459
+ periodic = (True, True)
460
+ padding = (halo_x, halo_y, (0, 0))
461
+
462
+ def f(arr):
463
+ return jaxdecomp.halo_exchange(arr, halo_extents=halo_extents, halo_periods=periodic, backend=backend)
464
+
465
+ # Small non-distributed array, like the hessian test
466
+ padded = jnp.pad(
467
+ jax.random.normal(jax.random.PRNGKey(0), (16, 16, 16), dtype=jnp.float64),
468
+ padding,
469
+ mode='linear_ramp',
470
+ end_values=20,
471
+ )
472
+ v = jax.random.normal(jax.random.PRNGKey(1), padded.shape, dtype=padded.dtype)
473
+
474
+ # jax.linearize requires the HiPrim `lin`/`linearized` rules
475
+ _, lin_fn = jax.linearize(f, padded)
476
+
477
+ # The linearized map must agree with the jvp rule (halo exchange is linear)
478
+ _, Jv_jvp = jax.jvp(f, (padded,), (v,))
479
+ Jv_lin = lin_fn(v)
480
+ assert assert_allclose(Jv_jvp, Jv_lin, rtol=1e-5, atol=1e-5)
481
+
482
+ # Transpose dot-product test: Re[wᵀ(J v)] == (Jᵀ w)ᵀv — the real part of the bilinear
483
+ # pairing, which is the transpose contract jax.linear_transpose defines for complex
484
+ # outputs on real inputs (the returned cotangent Jᵀ w is real).
485
+ w = jax.random.normal(jax.random.PRNGKey(2), Jv_lin.shape, dtype=Jv_lin.dtype)
486
+ _, vjp_fn = jax.vjp(f, padded)
487
+ (JTw,) = vjp_fn(w)
488
+ assert assert_allclose(jnp.sum(w * Jv_lin).real, jnp.sum(JTw * v), rtol=1e-5, atol=1e-5)
489
+
490
+ @pytest.mark.parametrize('use_shardy', use_shardy)
491
+ @pytest.mark.parametrize('pdims', pdims)
492
+ def test_jax_linearize(self, pdims, use_shardy):
493
+ """Test that jax.linearize works with halo exchange (JAX backend)."""
494
+ self._run_linearize_test(pdims, 'JAX', use_shardy)
495
+
496
+ @pytest.mark.skipif(not is_on_cluster(), reason='Only run on cluster')
497
+ @pytest.mark.parametrize('use_shardy', use_shardy)
498
+ @pytest.mark.parametrize('pdims', pdims)
499
+ def test_cudecomp_linearize(self, pdims, use_shardy):
500
+ """Test that jax.linearize works with halo exchange (cuDecomp backend)."""
501
+ self._run_linearize_test(pdims, 'CUDECOMP', use_shardy)
502
+
443
503
  @pytest.mark.parametrize('use_shardy', use_shardy) # Test with and without shardy
444
504
  @pytest.mark.parametrize('pdims', pdims)
445
505
  def test_jax_halo(
@@ -8,6 +8,7 @@ from conftest import (
8
8
  create_spmd_array,
9
9
  initialize_distributed,
10
10
  is_on_cluster,
11
+ skip_prime_tests,
11
12
  )
12
13
 
13
14
  initialize_distributed()
@@ -45,7 +46,17 @@ pencil_1 = (size // 2, size // (size // 2)) # 2x2 for V100 and 4x2 for A100
45
46
  pencil_2 = (size // (size // 2), size // 2) # 2x2 for V100 and 2x4 for A100
46
47
 
47
48
  decomp = [(size, 1), (1, size), pencil_1, pencil_2]
48
- global_shapes = [(8, 16, 32), (8, 8, 8), (29 * size, 19 * size, 17 * size)]
49
+ global_shapes = [
50
+ pytest.param((8, 16, 32), id='8x16x32'),
51
+ pytest.param((8, 8, 8), id='8x8x8'),
52
+ pytest.param(
53
+ (29 * size, 19 * size, 17 * size),
54
+ id='prime_sizes',
55
+ marks=pytest.mark.skipif(
56
+ skip_prime_tests, reason='prime shapes deadlock XLA CPU collectives on core-limited runners (JAXDECOMP_SKIP_PRIME_TESTS=1)'
57
+ ),
58
+ ),
59
+ ]
49
60
  # Cubes, non-cubes and primes
50
61
  local_transpose = [
51
62
  pytest.param(False, id='no_local_transpose'),
@@ -314,6 +325,54 @@ class TestTransposesGrad:
314
325
  global_shape = (4, 4, 4)
315
326
  self._run_hessian_test(pdims, global_shape, local_transpose, 'cuDecomp', use_shardy, axis_type)
316
327
 
328
+ def _run_linearize_test(self, local_transpose, use_shardy, backend):
329
+ """Test that jax.linearize works with transpose (the HiPrim `lin`/`linearized` rules).
330
+
331
+ The linearized map must agree with the jvp rule (the transpose is linear) and
332
+ satisfy the transpose dot-product test ⟨w, J v⟩ == ⟨Jᵀ w, v⟩.
333
+ """
334
+ if use_shardy and not ALLOW_SHARDY_PARTITIONER:
335
+ pytest.skip(reason='Shardy partitioner is not supported in this JAX version use at least JAX 0.7.0')
336
+
337
+ jaxdecomp.config.update('transpose_axis_contiguous', local_transpose)
338
+ jax.config.update('jax_use_shardy_partitioner', use_shardy)
339
+
340
+ def f(arr):
341
+ return transposeXtoY(arr, backend=backend)
342
+
343
+ # Small non-distributed array, like the hessian test
344
+ x = jax.random.normal(jax.random.PRNGKey(0), (4, 4, 4), dtype=jnp.float64)
345
+ v = jax.random.normal(jax.random.PRNGKey(1), x.shape, dtype=x.dtype)
346
+
347
+ # jax.linearize requires the HiPrim `lin`/`linearized` rules
348
+ _, lin_fn = jax.linearize(f, x)
349
+
350
+ # The linearized map must agree with the jvp rule (the transpose is linear)
351
+ _, Jv_jvp = jax.jvp(f, (x,), (v,))
352
+ Jv_lin = lin_fn(v)
353
+ assert assert_allclose(Jv_jvp, Jv_lin, rtol=1e-5, atol=1e-5)
354
+
355
+ # Transpose dot-product test: Re[wᵀ(J v)] == (Jᵀ w)ᵀv — the real part of the bilinear
356
+ # pairing, which is the transpose contract jax.linear_transpose defines for complex
357
+ # outputs on real inputs (the returned cotangent Jᵀ w is real).
358
+ w = jax.random.normal(jax.random.PRNGKey(2), Jv_lin.shape, dtype=Jv_lin.dtype)
359
+ _, vjp_fn = jax.vjp(f, x)
360
+ (JTw,) = vjp_fn(w)
361
+ assert assert_allclose(jnp.sum(w * Jv_lin).real, jnp.sum(JTw * v), rtol=1e-5, atol=1e-5)
362
+
363
+ @pytest.mark.parametrize('use_shardy', use_shardy)
364
+ @pytest.mark.parametrize('local_transpose', local_transpose)
365
+ def test_jax_linearize(self, local_transpose, use_shardy):
366
+ """Test that jax.linearize works with transpose (JAX backend)."""
367
+ self._run_linearize_test(local_transpose, use_shardy, 'jax')
368
+
369
+ @pytest.mark.skipif(not is_on_cluster(), reason='Only run on cluster')
370
+ @pytest.mark.parametrize('use_shardy', use_shardy)
371
+ @pytest.mark.parametrize('local_transpose', local_transpose)
372
+ def test_cudecomp_linearize(self, local_transpose, use_shardy):
373
+ """Test that jax.linearize works with transpose (cuDecomp backend)."""
374
+ self._run_linearize_test(local_transpose, use_shardy, 'cuDecomp')
375
+
317
376
  @pytest.mark.skipif(not is_on_cluster(), reason='Only run on cluster')
318
377
  # Cartesian product test
319
378
  @pytest.mark.parametrize('pdims', decomp)
@@ -592,7 +592,7 @@ wheels = [
592
592
 
593
593
  [[package]]
594
594
  name = "jax"
595
- version = "0.11.1"
595
+ version = "0.11.2"
596
596
  source = { registry = "https://pypi.org/simple" }
597
597
  dependencies = [
598
598
  { name = "jaxlib" },
@@ -601,9 +601,9 @@ dependencies = [
601
601
  { name = "opt-einsum" },
602
602
  { name = "scipy" },
603
603
  ]
604
- sdist = { url = "https://files.pythonhosted.org/packages/90/aa/c3b6ac3863a490661e255d2356802b54d57b533460fa221d30743d81a6c1/jax-0.11.1.tar.gz", hash = "sha256:43e0d45b1dac002eca04c2de73298395225dd0d4651e3f573a540eaa18abfd80", size = 2864119, upload-time = "2026-08-17T20:31:29.938Z" }
604
+ sdist = { url = "https://files.pythonhosted.org/packages/96/c3/cbb70e5e0846891b45c9b02b0755235618043cd2a8edd1f5bfe24b077cf4/jax-0.11.2.tar.gz", hash = "sha256:540dc0bed96bd5a0d8acca15cf16198fea98ef2fc151d40bdf1ace49eb76efd9", size = 2904036, upload-time = "2026-09-17T23:43:35.896Z" }
605
605
  wheels = [
606
- { url = "https://files.pythonhosted.org/packages/8f/f4/5f9a286e1eeca9faa8b83885edccf63ab2f1b22e17f6a5ea66ac86b1afe4/jax-0.11.1-py3-none-any.whl", hash = "sha256:72ed60bf85a0b53d0f5b5cd61e37a8b25f369f6f88481feb98ab489894861a82", size = 3302513, upload-time = "2026-08-17T20:29:00.294Z" },
606
+ { url = "https://files.pythonhosted.org/packages/ca/87/0c0ca8433e1135f6d1acd355cff21f31c3d433d937d6547aa545c8b060b8/jax-0.11.2-py3-none-any.whl", hash = "sha256:59e7ed9bd9ace049f4856752fe580c890e0164e1c023f40fadac386408daad66", size = 3345045, upload-time = "2026-09-17T23:41:14.517Z" },
607
607
  ]
608
608
 
609
609
  [package.optional-dependencies]
@@ -614,33 +614,33 @@ cuda12 = [
614
614
 
615
615
  [[package]]
616
616
  name = "jax-cuda12-pjrt"
617
- version = "0.11.1"
617
+ version = "0.11.2"
618
618
  source = { registry = "https://pypi.org/simple" }
619
619
  wheels = [
620
- { url = "https://files.pythonhosted.org/packages/0e/3e/d2072547b8738a7c4cf9ad79589d0efed1a4700952be30b1faa88f87969d/jax_cuda12_pjrt-0.11.1-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:40021d455bd94522704e321d30e8ada26a7c0a6ef95c4a7542abda0138a29d1c", size = 179725961, upload-time = "2026-08-17T20:29:04.18Z" },
621
- { url = "https://files.pythonhosted.org/packages/55/15/5709e379c1191b1d354e74a04cb01d61abe29ce4bba29833229525882566/jax_cuda12_pjrt-0.11.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:fdd9d72408e17f7a23bdfa266e9c90136620a724df584629f3506722e2b2f434", size = 184904180, upload-time = "2026-08-17T20:29:12.991Z" },
620
+ { url = "https://files.pythonhosted.org/packages/73/a8/03be433dec7574ece4d45b90d709e25ee0b9e19713e73fbfc52d6384de75/jax_cuda12_pjrt-0.11.2-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:f36247d40973b20acf3c69dac7c9c720daaa4096a809b3e8fd70292be617cdeb", size = 182867418, upload-time = "2026-09-17T23:41:18.187Z" },
621
+ { url = "https://files.pythonhosted.org/packages/38/57/2df730cd97270f212938f1b86ba50d6118220fb9e4c2dda08d260418679e/jax_cuda12_pjrt-0.11.2-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:2133b3afc63307c016ae4980f166b2b3de199759363ead74f7d550eaae953463", size = 188235313, upload-time = "2026-09-17T23:41:24.135Z" },
622
622
  ]
623
623
 
624
624
  [[package]]
625
625
  name = "jax-cuda12-plugin"
626
- version = "0.11.1"
626
+ version = "0.11.2"
627
627
  source = { registry = "https://pypi.org/simple" }
628
628
  dependencies = [
629
629
  { name = "jax-cuda12-pjrt" },
630
630
  ]
631
631
  wheels = [
632
- { url = "https://files.pythonhosted.org/packages/b6/55/7d99e5155d8c1a402c3fcd8f5e3ac9d7d3123725d1cef9d7f519eb4408f4/jax_cuda12_plugin-0.11.1-cp312-cp312-manylinux_2_27_aarch64.whl", hash = "sha256:f2a382e5dbf66330740bf4db3903c612e84b24de09913c7953ed2403c296b686", size = 8551003, upload-time = "2026-08-17T20:29:16.516Z" },
633
- { url = "https://files.pythonhosted.org/packages/56/45/e30b3348126ded20d5b388e18a4fe399259538506ba1abc2812913f21eee/jax_cuda12_plugin-0.11.1-cp312-cp312-manylinux_2_27_x86_64.whl", hash = "sha256:f0154fbf236bb2231a6fca5204dd1e43ac0c1cf0de3a0020fff9103e53fb8572", size = 8594678, upload-time = "2026-08-17T20:29:18.489Z" },
634
- { url = "https://files.pythonhosted.org/packages/fb/28/8291d90302117e788cc40f10e4cb442444ac8bf21673ff73ef9c21f8243a/jax_cuda12_plugin-0.11.1-cp313-cp313-manylinux_2_27_aarch64.whl", hash = "sha256:e8a8d66f43d00b35c0430366b117c1b61283764f0d10d3965abfe39f8728486f", size = 8550626, upload-time = "2026-08-17T20:29:20.353Z" },
635
- { url = "https://files.pythonhosted.org/packages/e7/e7/d2407b86fcb882ba0ce16a6ff23d0f21d18e3725133d8ac0df7497d704a8/jax_cuda12_plugin-0.11.1-cp313-cp313-manylinux_2_27_x86_64.whl", hash = "sha256:d8efc51fd4998a2990c467e63c386cfdc9187c7d105825c5c4ab743e7d522d11", size = 8594940, upload-time = "2026-08-17T20:29:22.337Z" },
636
- { url = "https://files.pythonhosted.org/packages/fb/e0/de583e82a8979741ddaa8116c7d151b75a4491ccb526489d4c8043630411/jax_cuda12_plugin-0.11.1-cp314-cp314-manylinux_2_27_aarch64.whl", hash = "sha256:3ca119b301d9a93bcb8375c6937cf79492ff5951ca5cbb8b46f7e34af42dcfd3", size = 8551250, upload-time = "2026-08-17T20:29:24.075Z" },
637
- { url = "https://files.pythonhosted.org/packages/bc/f1/edda4a57aad1f6975bafe3abdae3297fe4cf52defe2ffe167e58093a1bcb/jax_cuda12_plugin-0.11.1-cp314-cp314-manylinux_2_27_x86_64.whl", hash = "sha256:6bb8f106821517e34488a5320e45f5def4a4628f2a254afa6e2c7eec35419bbe", size = 8595070, upload-time = "2026-08-17T20:29:25.868Z" },
638
- { url = "https://files.pythonhosted.org/packages/ca/c0/b880ab87b07d3b7bce14fdb965cbe9fb6b3a1b61d73b1d6886da01a3d293/jax_cuda12_plugin-0.11.1-cp314-cp314t-manylinux_2_27_aarch64.whl", hash = "sha256:479407a4eed9fb5b1fad37ae3a6a1c9e8284bdb2e52ba6dfc0e22ac595bb94e8", size = 8565526, upload-time = "2026-08-17T20:29:27.915Z" },
639
- { url = "https://files.pythonhosted.org/packages/6b/9f/ce21715c1788ca6686c0550feeef28d06f574872e4619a74ac729b8ff47d/jax_cuda12_plugin-0.11.1-cp314-cp314t-manylinux_2_27_x86_64.whl", hash = "sha256:771a43862a86874b114c0d55f23136c8a228e3d47e7718dc4ed60de84ac36d89", size = 8605791, upload-time = "2026-08-17T20:29:29.551Z" },
640
- { url = "https://files.pythonhosted.org/packages/49/f3/e570a3c7a77d8b36317b214460515f4332b0960efeaafed8c00f46d2d646/jax_cuda12_plugin-0.11.1-cp315-cp315-manylinux_2_27_aarch64.whl", hash = "sha256:4a09e11b9c2704c6af53bcd1572066429b015a36a106882641e127f30e7a4589", size = 8551262, upload-time = "2026-08-17T20:29:31.169Z" },
641
- { url = "https://files.pythonhosted.org/packages/4c/eb/c521edf23104635e79ecba0c5881e86b85eaf632241d911220a64ba926b5/jax_cuda12_plugin-0.11.1-cp315-cp315-manylinux_2_27_x86_64.whl", hash = "sha256:d87516db355e761eb98efefd817a5e985688bad32d3c05a93eb7b64ed721b3d8", size = 8595108, upload-time = "2026-08-17T20:29:33.159Z" },
642
- { url = "https://files.pythonhosted.org/packages/b0/81/ae93fb9edf4fdbace632ce1e649a3f8965311efd40e22d7bf0c51c2d5246/jax_cuda12_plugin-0.11.1-cp315-cp315t-manylinux_2_27_aarch64.whl", hash = "sha256:b6c88d844e26444e78dc05d8d15342d84e15aca79ab34881020e49f252fa8024", size = 8565490, upload-time = "2026-08-17T20:29:34.848Z" },
643
- { url = "https://files.pythonhosted.org/packages/68/ec/0f85c6d5eec3f2f83ceda1c6d8ab45a7dc025914cd50dd4d82b75e483510/jax_cuda12_plugin-0.11.1-cp315-cp315t-manylinux_2_27_x86_64.whl", hash = "sha256:055d8835b603f5a7a374de5342bb5cfcb0a4bbbb8525e940bbc51aee383ecdbe", size = 8606031, upload-time = "2026-08-17T20:29:37.016Z" },
632
+ { url = "https://files.pythonhosted.org/packages/f3/e9/f205c95df880618d5691ad5444e8798368a3cf76f1380e153f78b392470e/jax_cuda12_plugin-0.11.2-cp312-cp312-manylinux_2_27_aarch64.whl", hash = "sha256:ad0fbb60548585d5f0df2fe11eb8e6d41a9856274ed9bc3ebe2d1e1e1c3d012f", size = 8603910, upload-time = "2026-09-17T23:41:27.572Z" },
633
+ { url = "https://files.pythonhosted.org/packages/77/db/ca022a589ff15628827498dcedeae72fa70396f42b58469a9de4425afc99/jax_cuda12_plugin-0.11.2-cp312-cp312-manylinux_2_27_x86_64.whl", hash = "sha256:ae67a4cc49b34c575713a8311f7597f6700ec5a2b6afbdbc3db5550fb022873c", size = 8636558, upload-time = "2026-09-17T23:41:29.657Z" },
634
+ { url = "https://files.pythonhosted.org/packages/6b/13/a7d6099008e001bf71d3273d21fe970ee768cab3600e31f49ae82b578d11/jax_cuda12_plugin-0.11.2-cp313-cp313-manylinux_2_27_aarch64.whl", hash = "sha256:291aadea4a52c53a35f957ca5a3c0dd5316b5c082fcbb51f164b7f20d4e1d659", size = 8603926, upload-time = "2026-09-17T23:41:31.82Z" },
635
+ { url = "https://files.pythonhosted.org/packages/57/ba/26bd500531d81b16d66e4a90bb636fbc0e9e6f921b47a3169007159f694c/jax_cuda12_plugin-0.11.2-cp313-cp313-manylinux_2_27_x86_64.whl", hash = "sha256:55ed6dbdf4d6f57c6c7b0aadaeb8e337371a25249a0e3c1ef9efcb607b0bbc67", size = 8636734, upload-time = "2026-09-17T23:41:33.538Z" },
636
+ { url = "https://files.pythonhosted.org/packages/2d/56/ed9f440887dae68fb3adc6f011c1cdeeb05774f2d795ff6c64eb4dbb95c6/jax_cuda12_plugin-0.11.2-cp314-cp314-manylinux_2_27_aarch64.whl", hash = "sha256:ec7e06d7a450807967f35091d4af6c0a72461bdc77c4b21718a50d8377eaeafb", size = 8603321, upload-time = "2026-09-17T23:41:35.155Z" },
637
+ { url = "https://files.pythonhosted.org/packages/02/14/fcae3681051de6f109c85a9199220e4f4aafa4698acbe131084e56f790e9/jax_cuda12_plugin-0.11.2-cp314-cp314-manylinux_2_27_x86_64.whl", hash = "sha256:96d198157e76ead91958742466f5c7462618dd27831dc82384880e2e80ebe4e0", size = 8636844, upload-time = "2026-09-17T23:41:37.232Z" },
638
+ { url = "https://files.pythonhosted.org/packages/5b/bb/64db10a05cd2821b6b8c86896fdc461c13bdc5dba10d19bcf271d7327c00/jax_cuda12_plugin-0.11.2-cp314-cp314t-manylinux_2_27_aarch64.whl", hash = "sha256:af5147dde561d8169a5073fe64aa75763b527d65a7087fe9774cb80be84fdae6", size = 8619610, upload-time = "2026-09-17T23:41:39.435Z" },
639
+ { url = "https://files.pythonhosted.org/packages/06/ca/67b5934f7d7e162dd6389a7c23aaa81b08991ae51d392f9153d34eb9f735/jax_cuda12_plugin-0.11.2-cp314-cp314t-manylinux_2_27_x86_64.whl", hash = "sha256:c0a3920ae96cd439557ab8ba510b2fdbad0c935c1d95cf5bb54113e025ba9a82", size = 8652035, upload-time = "2026-09-17T23:41:41.069Z" },
640
+ { url = "https://files.pythonhosted.org/packages/a1/fc/4bab2b740004e3f449c38c44d6c48291708582051517ffe97865220960b9/jax_cuda12_plugin-0.11.2-cp315-cp315-manylinux_2_27_aarch64.whl", hash = "sha256:a2565efe1dad968fe18e04e39161f059437d923f8bed966877b33721ccbab5d5", size = 8606679, upload-time = "2026-09-17T23:41:42.902Z" },
641
+ { url = "https://files.pythonhosted.org/packages/86/8b/ac014271a8e01f35891ef57c3788fcb8ecd00f75f8638594af638510d9bc/jax_cuda12_plugin-0.11.2-cp315-cp315-manylinux_2_27_x86_64.whl", hash = "sha256:8044b97ca41ecc835034c0f780abdf79dd1d673834031a2710882f895429679a", size = 8640048, upload-time = "2026-09-17T23:41:45.15Z" },
642
+ { url = "https://files.pythonhosted.org/packages/8c/8d/c816e5c281aa16956b88838901a1cd47a99760df45113d79507aecb41489/jax_cuda12_plugin-0.11.2-cp315-cp315t-manylinux_2_27_aarch64.whl", hash = "sha256:614eb748b5175323cd5865653a642d1b7e1af69f3afa47565f8fddb21ad011fd", size = 8621068, upload-time = "2026-09-17T23:41:46.792Z" },
643
+ { url = "https://files.pythonhosted.org/packages/3a/c1/e51e5225a583cf9e10565978be95e87dda09c226bd41372df6c251cecb24/jax_cuda12_plugin-0.11.2-cp315-cp315t-manylinux_2_27_x86_64.whl", hash = "sha256:e6e154479252c1fbe7dccbb3be5fd90b5f91537786dde4979b43acac4c84a07d", size = 8654513, upload-time = "2026-09-17T23:41:48.65Z" },
644
644
  ]
645
645
 
646
646
  [package.optional-dependencies]
@@ -698,6 +698,7 @@ test = [
698
698
  { name = "pytest" },
699
699
  { name = "pytest-cov" },
700
700
  { name = "pytest-mock" },
701
+ { name = "pytest-timeout" },
701
702
  ]
702
703
 
703
704
  [package.dev-dependencies]
@@ -718,13 +719,14 @@ docs = [
718
719
  [package.metadata]
719
720
  requires-dist = [
720
721
  { name = "chex", marker = "extra == 'test'" },
721
- { name = "jax", specifier = ">=0.11.1" },
722
- { name = "jax", extras = ["cuda12"], marker = "extra == 'cuda'", specifier = ">=0.11.1" },
722
+ { name = "jax", specifier = ">=0.11.2" },
723
+ { name = "jax", extras = ["cuda12"], marker = "extra == 'cuda'", specifier = ">=0.11.2" },
723
724
  { name = "jax-hpc-profiler", marker = "extra == 'benchmark'", specifier = ">=0.3.2" },
724
725
  { name = "jaxtyping", specifier = ">=0.2.0" },
725
726
  { name = "pytest", marker = "extra == 'test'", specifier = ">=8.0.0" },
726
727
  { name = "pytest-cov", marker = "extra == 'test'" },
727
728
  { name = "pytest-mock", marker = "extra == 'test'" },
729
+ { name = "pytest-timeout", marker = "extra == 'test'" },
728
730
  ]
729
731
  provides-extras = ["test", "benchmark", "cuda"]
730
732
 
@@ -745,7 +747,7 @@ docs = [
745
747
 
746
748
  [[package]]
747
749
  name = "jaxlib"
748
- version = "0.11.1"
750
+ version = "0.11.2"
749
751
  source = { registry = "https://pypi.org/simple" }
750
752
  dependencies = [
751
753
  { name = "ml-dtypes" },
@@ -753,28 +755,28 @@ dependencies = [
753
755
  { name = "scipy" },
754
756
  ]
755
757
  wheels = [
756
- { url = "https://files.pythonhosted.org/packages/6a/b4/9a7caf8704536e694ab8b4286eb4afa2224f3f75283f370d2246343e7bbc/jaxlib-0.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:384f633331c012491ccd65c38d47cd80d4131f5b3852694766bffa9385ddc9f3", size = 63173264, upload-time = "2026-08-17T20:30:07.721Z" },
757
- { url = "https://files.pythonhosted.org/packages/77/d9/26613efbc0e219ef16b6069c38378a9b360f85926573e1995c391e48d73e/jaxlib-0.11.1-cp312-cp312-manylinux_2_27_aarch64.whl", hash = "sha256:47bab3a7da8a818f9e7ddecd4ed815429caa2840eda9e968bb6d33b9d8c52067", size = 82772925, upload-time = "2026-08-17T20:30:11.388Z" },
758
- { url = "https://files.pythonhosted.org/packages/05/41/07c259ea10a5eeb100a66222507e2ce3a01474fa8f13c250bf1a3559a5bb/jaxlib-0.11.1-cp312-cp312-manylinux_2_27_x86_64.whl", hash = "sha256:c3dcec3bb33ebf5c76dc33f962c796652c077edb246464fa32cb1d8fcb6087e6", size = 87903454, upload-time = "2026-08-17T20:30:14.889Z" },
759
- { url = "https://files.pythonhosted.org/packages/77/d7/555041e5d4116c0aaf8ff513b380da38df547844c30c7c1d41c36e18d12b/jaxlib-0.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:eef943b42d6d42a2b2f3dc2a66e7a3dc89aeb1541f5a13ad8e1e94001bb590ec", size = 68531585, upload-time = "2026-08-17T20:30:18.488Z" },
760
- { url = "https://files.pythonhosted.org/packages/a0/22/d076bf545853d1f60ef906cb6d69751f9b149f857f4390de989d5165ed80/jaxlib-0.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c7518af3168ab4cf0a00b92f5463018baf0dad3faa3b358a3d688996afa6fd50", size = 63174384, upload-time = "2026-08-17T20:30:21.949Z" },
761
- { url = "https://files.pythonhosted.org/packages/a8/3c/5b0ce63c880d4f9cef492f04e11be7a60bdd3f529311839652b928e8b320/jaxlib-0.11.1-cp313-cp313-manylinux_2_27_aarch64.whl", hash = "sha256:3a679a49b8d329b6e431f3aeb666467c6efac750e3b2ee90d0e74efe7959e643", size = 82774089, upload-time = "2026-08-17T20:30:25.232Z" },
762
- { url = "https://files.pythonhosted.org/packages/f5/28/ef1371618e784880e68c2ab5277d5ccbaf518a2a5ec9ec05ef90a9ee7d1b/jaxlib-0.11.1-cp313-cp313-manylinux_2_27_x86_64.whl", hash = "sha256:7ebe86a7b891fcda83e7f634a677d285681a7b80b3ec9ed435536078a8371acf", size = 87901562, upload-time = "2026-08-17T20:30:28.873Z" },
763
- { url = "https://files.pythonhosted.org/packages/fe/c7/f92d23dc89bdbe5193ad139aa8973eab485898f330de2033bc4fdd8ac4c9/jaxlib-0.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:8379a8902db216f21673e7591acedc8f925658c59d9d2ec9afd5e2244246986a", size = 68531205, upload-time = "2026-08-17T20:30:32.376Z" },
764
- { url = "https://files.pythonhosted.org/packages/a8/90/29f37540af0d463838eaac236d58267815a972a5e2f5e59dc6e1992c5dbc/jaxlib-0.11.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a063d6110d296a935933c35aa7ed61b3a22ae2466e38834eecd48ae2d14fb8a3", size = 63174889, upload-time = "2026-08-17T20:30:35.472Z" },
765
- { url = "https://files.pythonhosted.org/packages/35/7f/263b873ed570567880e3ec2acb13eb5cf184972b5b79d883dbccc7d58c4a/jaxlib-0.11.1-cp314-cp314-manylinux_2_27_aarch64.whl", hash = "sha256:226616df027f1348da77764753c6c1e2f4d45b5551b67bcfdcafcf9cadf2e280", size = 82773791, upload-time = "2026-08-17T20:30:38.783Z" },
766
- { url = "https://files.pythonhosted.org/packages/f7/a2/07dba61656a7fd3b0db734834158e9abcc56372592d9326cf39a72c36762/jaxlib-0.11.1-cp314-cp314-manylinux_2_27_x86_64.whl", hash = "sha256:739ead792ddb854cb3ca5decfe00aab08a731131ab2cbeed9b74f4545c92fd01", size = 87903999, upload-time = "2026-08-17T20:30:42.645Z" },
767
- { url = "https://files.pythonhosted.org/packages/6b/4b/a925e73d19a7cb60c25396db208a1dd43ab7ae9f77a85646e65c02c3e961/jaxlib-0.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:3c2788a45d334be1240547a31df0f8af5f1b59e95984c3bc86d9badce9293685", size = 71068954, upload-time = "2026-08-17T20:30:47.013Z" },
768
- { url = "https://files.pythonhosted.org/packages/ab/2f/d4eef297c2f8c3dd5e2ba1afb12d14328c13d343681d70d6d5eb95e53f17/jaxlib-0.11.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8dfbca728bd534c0690514527a15db52a8e74f7bae406984b57a3c0c99e75ab6", size = 63263304, upload-time = "2026-08-17T20:30:50.17Z" },
769
- { url = "https://files.pythonhosted.org/packages/60/83/0eb0b2b7d9a32a742e351bf8f94663b3759408c579bd8964628fe9e0bcbe/jaxlib-0.11.1-cp314-cp314t-manylinux_2_27_aarch64.whl", hash = "sha256:f9fc4eccfb882eab746ac75862e82833eab1a72d864dcb20bdc83cdf295d81bd", size = 82866887, upload-time = "2026-08-17T20:30:53.518Z" },
770
- { url = "https://files.pythonhosted.org/packages/d5/c6/d2e03edf89d577241aaa70a82a21a7e2474a113af4f7e5b2bccd65f72a2e/jaxlib-0.11.1-cp314-cp314t-manylinux_2_27_x86_64.whl", hash = "sha256:12803e2d6ca821d9f59aeb31ceaa6e49403aaeefbb62e3cba90e1ebcbe244209", size = 87999113, upload-time = "2026-08-17T20:30:57.474Z" },
771
- { url = "https://files.pythonhosted.org/packages/69/93/da40546a2f67735717a1ffb4751da4eb92527fa326caa6e9973444b41321/jaxlib-0.11.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:6e264bd7cecff9053f71c4c7d1aeb0940aa7da9226ddcb00117abb39b5faccf4", size = 63174333, upload-time = "2026-08-17T20:31:00.789Z" },
772
- { url = "https://files.pythonhosted.org/packages/d9/da/d73f62bc74692640e0d140db8964fa98a403686eb22c8d0810776e3a2e9e/jaxlib-0.11.1-cp315-cp315-manylinux_2_27_aarch64.whl", hash = "sha256:93c945387919ae27e1475b86802f72ec9f511f65ec74677b33ba47f895e51f9c", size = 82774506, upload-time = "2026-08-17T20:31:03.949Z" },
773
- { url = "https://files.pythonhosted.org/packages/d9/c4/44e62769133051f37e12e33cf41e50c24c229c9378624c076edf53f8dd73/jaxlib-0.11.1-cp315-cp315-manylinux_2_27_x86_64.whl", hash = "sha256:b953f341c67d28f202b8af6dfaf9908281e2129ad9bc100454a9fdd2dae0b6f2", size = 87904049, upload-time = "2026-08-17T20:31:12.41Z" },
774
- { url = "https://files.pythonhosted.org/packages/75/d1/1243129103b5df137cc84d2bd998d403b5dd2ebcb857f51fd318ebd20282/jaxlib-0.11.1-cp315-cp315-win_amd64.whl", hash = "sha256:8f7956e26fc27b3782b180688545df6ac98c60b9429c45467eaa268bdc60f091", size = 71068945, upload-time = "2026-08-17T20:31:17.332Z" },
775
- { url = "https://files.pythonhosted.org/packages/8f/17/bbc0a38d2d560c92e1dd123d293ec2f78e24a843baa13238fd361e7ab370/jaxlib-0.11.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:d3945259807c26d231a2b61a63f4b6f1058f6519803b9bcc55ea2f1ae6a13108", size = 63263361, upload-time = "2026-08-17T20:31:20.369Z" },
776
- { url = "https://files.pythonhosted.org/packages/97/5b/819e20e911ba4eae21f96ec808a97605383d519d605276914a2b0fb8ef2a/jaxlib-0.11.1-cp315-cp315t-manylinux_2_27_aarch64.whl", hash = "sha256:3bce7f70714ed7e1967b9725e67c0aa3e111ca7e0dc7434c5d7d1e2047a8de26", size = 82868605, upload-time = "2026-08-17T20:31:23.805Z" },
777
- { url = "https://files.pythonhosted.org/packages/8c/e7/9593d22d398b66dae5fab17f961ed16ce7acfe11425276a6d2a0200d97ff/jaxlib-0.11.1-cp315-cp315t-manylinux_2_27_x86_64.whl", hash = "sha256:a3064a14d47f03b777454667bc8bf0a7c2d506714fe108adacf734f63cd7a5ae", size = 87998599, upload-time = "2026-08-17T20:31:27.376Z" },
758
+ { url = "https://files.pythonhosted.org/packages/3f/af/56ca13ef7a98137b087ef0c24dd5ace3163895f0164670babaa7dfcb69e6/jaxlib-0.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:eca80e745b7623369a76b5f685676ec233a33a55d69f60fa7e57cbefcfd47adc", size = 64867740, upload-time = "2026-09-17T23:42:19.368Z" },
759
+ { url = "https://files.pythonhosted.org/packages/69/72/318270378f5ff554ee921944bd97f59c0d6b35a8397cd35771dfdce1f445/jaxlib-0.11.2-cp312-cp312-manylinux_2_27_aarch64.whl", hash = "sha256:d497004e80daa91b98258d645b374e8dff480bf017d2c5f3e30b1371ac8f54b1", size = 84659774, upload-time = "2026-09-17T23:42:22.846Z" },
760
+ { url = "https://files.pythonhosted.org/packages/51/d2/07c3ea737d65b328b00377462e0e5dc8993a8a88d2a8a89e1c42038a4e53/jaxlib-0.11.2-cp312-cp312-manylinux_2_27_x86_64.whl", hash = "sha256:6338a1f0956f60d02529404ac33a8070015a52635cdb6bbb15d0d199757077bb", size = 89896206, upload-time = "2026-09-17T23:42:26.851Z" },
761
+ { url = "https://files.pythonhosted.org/packages/74/f7/8f6f7c55b80ca45e2225c78f4f44dbda8e5f420f933a5896e21045c3fb41/jaxlib-0.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:53217a47d14eedd8fb5101f16aab1dfd58067835b4fb11910b50306218c7e620", size = 73563902, upload-time = "2026-09-17T23:42:30.216Z" },
762
+ { url = "https://files.pythonhosted.org/packages/47/7f/f0d33a414e2d84fca39438a30f0588c32f7365746e903293cadad9d52b0d/jaxlib-0.11.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:766bd90e27a0ff53b87bb9d70c73565ec80b9b1165320ccb8f72de46b85510df", size = 64868496, upload-time = "2026-09-17T23:42:33.478Z" },
763
+ { url = "https://files.pythonhosted.org/packages/67/9e/6f6307527079e4fa65af9a813c3f07ba598f57f0936045ea3b02cc9d2e01/jaxlib-0.11.2-cp313-cp313-manylinux_2_27_aarch64.whl", hash = "sha256:5f9d3833cb2bea5e346bd2138ba74992017e0841c63d890a0157a13f9cbf439e", size = 84657374, upload-time = "2026-09-17T23:42:36.804Z" },
764
+ { url = "https://files.pythonhosted.org/packages/24/ec/014b428c3a05837643768d08aeb8fb1289d119d3f9f6fba479dffae05dbc/jaxlib-0.11.2-cp313-cp313-manylinux_2_27_x86_64.whl", hash = "sha256:5f3cac8d7030c1f80a182025d7171ea3b1245162a710f6e58d25ee3fe1748aac", size = 89896413, upload-time = "2026-09-17T23:42:40.466Z" },
765
+ { url = "https://files.pythonhosted.org/packages/e7/2f/72dfa1d0340866ecce9e111aac05a826ff116852402fa15c0db1b91b2d1b/jaxlib-0.11.2-cp313-cp313-win_amd64.whl", hash = "sha256:523e72d6e8d188b30bee9b6c62e5e9b769ac118aab5f07343588ba64d45cf9f3", size = 73564682, upload-time = "2026-09-17T23:42:44.134Z" },
766
+ { url = "https://files.pythonhosted.org/packages/fb/be/b5562a9ffab85bac6303f9d33af49c4bc51f85e33f406616d018567749fb/jaxlib-0.11.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:edad6b2a18d63dc2964cc97a16d126dad41621edac79d651e0f6c8785d891369", size = 64874852, upload-time = "2026-09-17T23:42:47.578Z" },
767
+ { url = "https://files.pythonhosted.org/packages/36/ca/5a5f933b5d6a281b8b758f45871e3b72fd2290dbd5c6946b93140dd24012/jaxlib-0.11.2-cp314-cp314-manylinux_2_27_aarch64.whl", hash = "sha256:061468eb5ac6b6213215fd1102b237bcbc93f24480c881245b73619d0c2a321e", size = 84664654, upload-time = "2026-09-17T23:42:50.815Z" },
768
+ { url = "https://files.pythonhosted.org/packages/35/2e/85156ae0a42292ef8e648c503437c65e434f6c4370f44e7fe5d4f845e6da/jaxlib-0.11.2-cp314-cp314-manylinux_2_27_x86_64.whl", hash = "sha256:1f31d8a6b1fb13181ff1807757506d10f6e7cba6b2707f7f80f73b853cb2ff22", size = 89901153, upload-time = "2026-09-17T23:42:54.265Z" },
769
+ { url = "https://files.pythonhosted.org/packages/c0/8a/2c8d8cfd1450d4fc209273d09440b771608f4f6e657829088aabcb57072e/jaxlib-0.11.2-cp314-cp314-win_amd64.whl", hash = "sha256:ea5e58673775ec7d3f46ade4e2d5a0d1673f30bb76f2a70c9b0036eafe5e4053", size = 76273242, upload-time = "2026-09-17T23:42:57.836Z" },
770
+ { url = "https://files.pythonhosted.org/packages/e9/57/a19ec0aa17be6acc405b09c52a6d0454eabec6a8c4a1a4bacfbce747c2f4/jaxlib-0.11.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a17074e2c58fa5610f6ec61955939d53e6372f59931d75eb1010926e6d81565d", size = 64969331, upload-time = "2026-09-17T23:43:01.079Z" },
771
+ { url = "https://files.pythonhosted.org/packages/0a/c1/dd8d109f48b27f884b3205f805066982f2f1ac427f0f500d31b353555626/jaxlib-0.11.2-cp314-cp314t-manylinux_2_27_aarch64.whl", hash = "sha256:5b052113f7a8acb0b6f14b356c83bb0f1e7ba90df0b22bbcf476d3750de5ea22", size = 84768035, upload-time = "2026-09-17T23:43:04.511Z" },
772
+ { url = "https://files.pythonhosted.org/packages/a5/31/5876f836644db19abdb9a620111e3e6307165934d73fa3f32de9fcf62343/jaxlib-0.11.2-cp314-cp314t-manylinux_2_27_x86_64.whl", hash = "sha256:d100ddb54a68d59cc3103729082324fccc4ca65e1d1b03c325208c43dd5c3c40", size = 89991692, upload-time = "2026-09-17T23:43:08.438Z" },
773
+ { url = "https://files.pythonhosted.org/packages/bd/2f/3cd215083ed42ae60bef985b36255e16c07cc5b6311f88d107726518675b/jaxlib-0.11.2-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:c2563f58a5d16f6b8d68bb65c1ba83e9ec81bea0d93cd3b1a73b0a5ffe76c1bb", size = 64877295, upload-time = "2026-09-17T23:43:12.412Z" },
774
+ { url = "https://files.pythonhosted.org/packages/0e/69/817015b0d00ab42efe7c6dad778c4c1ca5972b3e180ed27448adc620035b/jaxlib-0.11.2-cp315-cp315-manylinux_2_27_aarch64.whl", hash = "sha256:8df25d031827658fa434e6a8ff5c749700711fcc1553757d4bde4621019180cb", size = 84671133, upload-time = "2026-09-17T23:43:15.701Z" },
775
+ { url = "https://files.pythonhosted.org/packages/e8/9a/6e8b7319a325d23fcd76442370a7ea2bf442858a0c8196ec4caf69d67344/jaxlib-0.11.2-cp315-cp315-manylinux_2_27_x86_64.whl", hash = "sha256:b2965e43db9951a4b5e11dfd437477944fa5a4cc4f4fb969725788b90ebd7c09", size = 89903001, upload-time = "2026-09-17T23:43:19.354Z" },
776
+ { url = "https://files.pythonhosted.org/packages/6c/ee/6e653bbe8deb7303eb07b78fd36c9b57fd685641a62ab79532b885624939/jaxlib-0.11.2-cp315-cp315-win_amd64.whl", hash = "sha256:75db0922c72c511c71f9d022d7dcaca0d5492d30ad815041857fc447948c91f3", size = 76274240, upload-time = "2026-09-17T23:43:23.037Z" },
777
+ { url = "https://files.pythonhosted.org/packages/b2/6b/4b2f037c70a08d76786f2548b107c2a355f89bdd0c1fbba821b8e4776f15/jaxlib-0.11.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:dc154e762e6a5b19d5061e69397edccfea8c3acfbc831e487e2f6e403a218d3a", size = 64975259, upload-time = "2026-09-17T23:43:26.262Z" },
778
+ { url = "https://files.pythonhosted.org/packages/ef/8b/ee9ad489ae420f44f87c953ace859d7cb72dcc2ebd3112c50eae7b8beef5/jaxlib-0.11.2-cp315-cp315t-manylinux_2_27_aarch64.whl", hash = "sha256:33d9c43f729f0e5b597f3fca73b2e1b342877e063a7e259ab57b6cc6e686369e", size = 84759864, upload-time = "2026-09-17T23:43:29.829Z" },
779
+ { url = "https://files.pythonhosted.org/packages/9c/a3/1f0b704e4b1c3a14bbc547b252e4e5b0f2d8082df1e8b664f8b579adabec/jaxlib-0.11.2-cp315-cp315t-manylinux_2_27_x86_64.whl", hash = "sha256:4b553584279c42018dae4ede7963c7db6cdb35d1f36804b18a07256146c4529f", size = 89995359, upload-time = "2026-09-17T23:43:33.461Z" },
778
780
  ]
779
781
 
780
782
  [[package]]
@@ -1371,7 +1373,7 @@ name = "nvidia-cublas-cu12"
1371
1373
  version = "12.9.2.10"
1372
1374
  source = { registry = "https://pypi.org/simple" }
1373
1375
  dependencies = [
1374
- { name = "nvidia-cuda-nvrtc-cu12" },
1376
+ { name = "nvidia-cuda-nvrtc-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1375
1377
  ]
1376
1378
  wheels = [
1377
1379
  { url = "https://files.pythonhosted.org/packages/f7/a2/c96163a0fff1839c0c9548bbdeae7b853b867009e33b9b9264adc238b1cf/nvidia_cublas_cu12-12.9.2.10-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:5572131a59c3eebeeb1c4c8144f772d49372c20124916e072a0e3fc30df421d5", size = 575012079, upload-time = "2026-04-08T18:51:47.303Z" },
@@ -1428,7 +1430,7 @@ name = "nvidia-cudnn-cu12"
1428
1430
  version = "9.25.1.1"
1429
1431
  source = { registry = "https://pypi.org/simple" }
1430
1432
  dependencies = [
1431
- { name = "nvidia-cublas-cu12" },
1433
+ { name = "nvidia-cublas-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1432
1434
  ]
1433
1435
  wheels = [
1434
1436
  { url = "https://files.pythonhosted.org/packages/9f/97/65cee6620521af847fde280f3bd10784f3ab3d513f1bfdd87e362bcbc2fe/nvidia_cudnn_cu12-9.25.1.1-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:c71f4af9025e05e478cfb07f9c2a4c118346dac236e915f3e63769fbcb031cb3", size = 809606039, upload-time = "2026-08-28T23:39:06.797Z" },
@@ -1440,7 +1442,7 @@ name = "nvidia-cufft-cu12"
1440
1442
  version = "11.4.1.4"
1441
1443
  source = { registry = "https://pypi.org/simple" }
1442
1444
  dependencies = [
1443
- { name = "nvidia-nvjitlink-cu12" },
1445
+ { name = "nvidia-nvjitlink-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1444
1446
  ]
1445
1447
  wheels = [
1446
1448
  { url = "https://files.pythonhosted.org/packages/9b/2b/76445b0af890da61b501fde30650a1a4bd910607261b209cccb5235d3daa/nvidia_cufft_cu12-11.4.1.4-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1a28c9b12260a1aa7a8fd12f5ebd82d027963d635ba82ff39a1acfa7c4c0fbcf", size = 200822453, upload-time = "2025-06-05T20:05:27.889Z" },
@@ -1452,9 +1454,9 @@ name = "nvidia-cusolver-cu12"
1452
1454
  version = "11.7.5.82"
1453
1455
  source = { registry = "https://pypi.org/simple" }
1454
1456
  dependencies = [
1455
- { name = "nvidia-cublas-cu12" },
1456
- { name = "nvidia-cusparse-cu12" },
1457
- { name = "nvidia-nvjitlink-cu12" },
1457
+ { name = "nvidia-cublas-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1458
+ { name = "nvidia-cusparse-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1459
+ { name = "nvidia-nvjitlink-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1458
1460
  ]
1459
1461
  wheels = [
1460
1462
  { url = "https://files.pythonhosted.org/packages/03/99/686ff9bf3a82a531c62b1a5c614476e8dfa24a9d89067aeedf3592ee4538/nvidia_cusolver_cu12-11.7.5.82-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:62efa83e4ace59a4c734d052bb72158e888aa7b770e1a5f601682f16fe5b4fd2", size = 337869834, upload-time = "2025-06-05T20:06:53.125Z" },
@@ -1466,7 +1468,7 @@ name = "nvidia-cusparse-cu12"
1466
1468
  version = "12.5.10.65"
1467
1469
  source = { registry = "https://pypi.org/simple" }
1468
1470
  dependencies = [
1469
- { name = "nvidia-nvjitlink-cu12" },
1471
+ { name = "nvidia-nvjitlink-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1470
1472
  ]
1471
1473
  wheels = [
1472
1474
  { url = "https://files.pythonhosted.org/packages/5e/6f/8710fbd17cdd1d0fc3fea7d36d5b65ce1933611c31e1861da330206b253a/nvidia_cusparse_cu12-12.5.10.65-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:221c73e7482dd93eda44e65ce567c031c07e2f93f6fa0ecd3ba876a195023e83", size = 366359408, upload-time = "2025-06-05T20:07:42.501Z" },
@@ -1496,7 +1498,7 @@ name = "nvidia-nvshmem-cu12"
1496
1498
  version = "3.7.2"
1497
1499
  source = { registry = "https://pypi.org/simple" }
1498
1500
  dependencies = [
1499
- { name = "nvidia-cuda-cccl-cu12" },
1501
+ { name = "nvidia-cuda-cccl-cu12", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
1500
1502
  ]
1501
1503
  wheels = [
1502
1504
  { url = "https://files.pythonhosted.org/packages/88/a1/9ca9cc3338217311cee21f7ba795dad4f38b7a279a6da7d3d549258f60b1/nvidia_nvshmem_cu12-3.7.2-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:98495de30994f1401a12cc8158ffacbeada44579f54185d75665381468056faa", size = 229963056, upload-time = "2026-07-17T19:23:44.067Z" },
@@ -1741,6 +1743,18 @@ wheels = [
1741
1743
  { url = "https://files.pythonhosted.org/packages/5a/cc/06253936f4a7fa2e0f48dfe6d851d9c56df896a9ab09ac019d70b760619c/pytest_mock-3.15.1-py3-none-any.whl", hash = "sha256:0a25e2eb88fe5168d535041d09a4529a188176ae608a6d249ee65abc0949630d", size = 10095, upload-time = "2025-09-16T16:37:25.734Z" },
1742
1744
  ]
1743
1745
 
1746
+ [[package]]
1747
+ name = "pytest-timeout"
1748
+ version = "2.4.0"
1749
+ source = { registry = "https://pypi.org/simple" }
1750
+ dependencies = [
1751
+ { name = "pytest" },
1752
+ ]
1753
+ sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a", size = 17973, upload-time = "2025-05-05T19:44:34.99Z" }
1754
+ wheels = [
1755
+ { url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" },
1756
+ ]
1757
+
1744
1758
  [[package]]
1745
1759
  name = "python-dateutil"
1746
1760
  version = "2.9.0.post0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes