Skip to content

Commit d37b1d8

Browse files
mmckyclaude
andauthored
[numpy_vs_numba_vs_jax] Fix deprecated device= arg on jax.jit (#563)
JAX has deprecated the device/backend arguments to jax.jit, which emitted two DeprecationWarnings into the lecture's rendered HTML output: DeprecationWarning: backend and device argument on jit is deprecated. You can use jax.device_put(..., jax.local_devices(backend="cpu")[0]) on the inputs to the jitted function to get the same behavior. Pin the computation to the CPU the recommended way -- commit the input to the CPU with jax.device_put -- instead of the deprecated decorator argument. The behaviour (CPU execution for this sequential workload) is unchanged. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 811accd commit d37b1d8

1 file changed

Lines changed: 10 additions & 7 deletions

File tree

lectures/numpy_vs_numba_vs_jax.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,10 @@ We'll apply a `lax.fori_loop`, which is a version of a for loop that can be comp
471471
```{code-cell} ipython3
472472
cpu = jax.devices("cpu")[0]
473473
474-
@partial(jax.jit, static_argnames=("n",), device=cpu)
474+
# Pin the input to the CPU, which keeps the whole computation there
475+
x0_cpu = jax.device_put(0.1, cpu)
476+
477+
@partial(jax.jit, static_argnames=("n",))
475478
def qm_jax_fori(x0, n, α=4.0):
476479
477480
x = jnp.empty(n + 1).at[0].set(x0)
@@ -485,7 +488,7 @@ def qm_jax_fori(x0, n, α=4.0):
485488
```
486489

487490
* We hold `n` static because it affects array size and hence JAX wants to specialize on its value in the compiled code.
488-
* We pin to the CPU via `device=cpu` because this sequential workload consists of many small operations, leaving little opportunity for GPU parallelism.
491+
* We pin the input to the CPU with `jax.device_put` (which keeps the whole computation on the CPU) because this sequential workload consists of many small operations, leaving little opportunity for GPU parallelism.
489492

490493
Important: Although `at[t].set` appears to create a new array at each step, inside a JIT-compiled function the compiler detects that the old array is no longer needed and performs the update in place!
491494

@@ -494,7 +497,7 @@ Let's time it with the same parameters:
494497
```{code-cell} ipython3
495498
with qe.Timer():
496499
# First run
497-
x_jax = qm_jax_fori(0.1, n)
500+
x_jax = qm_jax_fori(x0_cpu, n)
498501
# Hold interpreter
499502
x_jax.block_until_ready()
500503
```
@@ -504,7 +507,7 @@ Let's run it again to eliminate compilation overhead:
504507
```{code-cell} ipython3
505508
with qe.Timer():
506509
# Second run
507-
x_jax = qm_jax_fori(0.1, n)
510+
x_jax = qm_jax_fori(x0_cpu, n)
508511
# Hold interpreter
509512
x_jax.block_until_ready()
510513
```
@@ -521,7 +524,7 @@ although the syntax is difficult to remember.
521524

522525

523526
```{code-cell} ipython3
524-
@partial(jax.jit, static_argnames=("n",), device=cpu)
527+
@partial(jax.jit, static_argnames=("n",))
525528
def qm_jax_scan(x0, n, α=4.0):
526529
def update(x, t):
527530
x_new = α * x * (1 - x)
@@ -538,7 +541,7 @@ Let's time it with the same parameters:
538541
```{code-cell} ipython3
539542
with qe.Timer():
540543
# First run
541-
x_jax = qm_jax_scan(0.1, n)
544+
x_jax = qm_jax_scan(x0_cpu, n)
542545
# Hold interpreter
543546
x_jax.block_until_ready()
544547
```
@@ -548,7 +551,7 @@ Let's run it again to eliminate compilation overhead:
548551
```{code-cell} ipython3
549552
with qe.Timer():
550553
# Second run
551-
x_jax = qm_jax_scan(0.1, n)
554+
x_jax = qm_jax_scan(x0_cpu, n)
552555
# Hold interpreter
553556
x_jax.block_until_ready()
554557
```

0 commit comments

Comments
 (0)