I want to filter a jnp.array with a condition, and accumulate to a global variable, in a jit function (so we have to use JAX control flow primitives):
import jax
import jax.numpy as jnp
from jax import jit
from jax import lax
key = jax.random.PRNGKey(42)
@jit
def get_data():
data = jax.random.normal(key, (5, 3))
data = data.at[-2:].set(0.)
return data
data = get_data()
accu = data[0]
@jit
def filter(data):
def body_fun(i):
global accu
accu = jnp.vstack((accu, data[i]))
return i + 1
lax.while_loop(lambda i: jnp.all(data[i]), body_fun, 1)
filter(data)
I expect accu.shape is (3,3) (there are three non-zero rows in data) after filter executed, but got (2,3):
Traced<ShapedArray(float32[2,3])>with<DynamicJaxprTrace(level=1/1)>
I suspect lax.while_loop iterates row 1 and 2, but global accu only got updated once, but why? Or is there any better way to accumulate jnp.array (in jit function) without using global variable?