Fixed new-style PRNG keys.

This commit is contained in:
Patrick Kidger
2023-11-27 09:50:02 -08:00
parent 7925e278f4
commit 58600d3fe0
2 changed files with 31 additions and 25 deletions
+3 -23
View File
@@ -156,32 +156,12 @@ def _check_dims(
return True
def _is_jax_extended_dtype(dtype: Any) -> bool:
if not has_jax:
return False
try:
is_dtype = issubclass(dtype, jax.numpy.generic)
except TypeError:
# `dtype` not a class
return False
else:
if is_dtype:
if hasattr(jax.dtypes, "extended"): # jax>=0.4.14
return jax.numpy.issubdtype(dtype, jax.dtypes.extended)
else: # jax<=0.4.13
return jax.core.is_opaque_dtype(dtype)
else:
return False
class _MetaAbstractArray(type):
def __instancecheck__(cls, obj):
if not isinstance(obj, cls.array_type):
return False
if _is_jax_extended_dtype(obj.dtype):
dtype = str(obj.dtype)
elif hasattr(obj.dtype, "type") and hasattr(obj.dtype.type, "__name__"):
if hasattr(obj.dtype, "type") and hasattr(obj.dtype.type, "__name__"):
# JAX, numpy
dtype = obj.dtype.type.__name__
elif hasattr(obj.dtype, "as_numpy_dtype"):
@@ -646,6 +626,7 @@ class AbstractDtype(metaclass=_MetaAbstractDtype):
cls.dtypes = dtypes
_prng_key = "prng_key"
_bool = "bool"
_bool_ = "bool_"
_uint8 = "uint8"
@@ -714,8 +695,7 @@ Num = _make_dtype(uints + ints + floats + complexes, "Num")
Shaped = _make_dtype(_any_dtype, "Shaped")
if has_jax:
_key_regex = re.compile(r"^key<\w+>$")
Key = _make_dtype(_key_regex, "Key")
Key = _make_dtype(_prng_key, "Key")
# New-style `jax.random.key` have scalar shape and dtype `key<foo>`.
# Old-style `jax.random.PRNGKey` have shape `(2,)` and dtype `uint32`.
PRNGKeyArray = Union[Key[jax.Array, ""], UInt32[jax.Array, "2"]]
+28 -2
View File
@@ -33,7 +33,9 @@ from jaxtyping import (
Bool,
Float,
Float32,
Key,
PRNGKeyArray,
Scalar,
Shaped,
)
@@ -586,8 +588,8 @@ def test_key(jaxtyp, typecheck):
def f(x: PRNGKeyArray):
pass
x = jr.PRNGKey(0)
f(x)
f(jr.key(0))
f(jr.PRNGKey(0))
with pytest.raises(ParamError):
f(object())
@@ -599,6 +601,30 @@ def test_key(jaxtyp, typecheck):
f(jnp.array(3.0))
def test_key_dtype(jaxtyp, typecheck):
@jaxtyp(typecheck)
def f1(x: Key[Array, ""]):
pass
@jaxtyp(typecheck)
def f2(x: Key[Scalar, ""]):
pass
for f in (f1, f2):
f(jr.key(0))
with pytest.raises(ParamError):
f(jr.PRNGKey(0))
with pytest.raises(ParamError):
f(object())
with pytest.raises(ParamError):
f(1)
with pytest.raises(ParamError):
f(jnp.array(3))
with pytest.raises(ParamError):
f(jnp.array(3.0))
def test_extension(jaxtyp, typecheck, getkey):
X = Shaped[Array, "a b"]
Y = Shaped[X, "c d"]