Skip to content

Commit 18b8a38

Browse files
committed
Fix support for custom JAX operations
1 parent 8f362c9 commit 18b8a38

3 files changed

Lines changed: 44 additions & 17 deletions

File tree

lab/custom.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,18 +180,24 @@ def bvn_cdf(a, b, c):
180180
# does not work for `bvn_cdf_`. Moreover, we need to ensure that the function
181181
# runs on `float64s`.
182182
res_dtype = reduce(np.promote_types, [x.dtype for x in (a, b, c)])
183-
res = bvn_cdf_(a.astype(np.float64), b.astype(np.float64), c.astype(np.float64))
183+
# The C interface requires NumPy objects of the right data type.
184+
res = bvn_cdf_(
185+
np.asarray(a).astype(np.float64),
186+
np.asarray(b).astype(np.float64),
187+
np.asarray(c).astype(np.float64),
188+
)
184189
return res.astype(res_dtype)
185190

186191

187192
def s_bvn_cdf(s_y, y, a, b, c):
188193
res_dtype = reduce(np.promote_types, [x.dtype for x in (s_y, y, a, b, c)])
194+
# The C interface requires NumPy objects of the right data type.
189195
res = s_bvn_cdf_(
190-
s_y.astype(np.float64),
191-
y.astype(np.float64),
192-
a.astype(np.float64),
193-
b.astype(np.float64),
194-
c.astype(np.float64),
196+
np.asarray(s_y).astype(np.float64),
197+
np.asarray(y).astype(np.float64),
198+
np.asarray(a).astype(np.float64),
199+
np.asarray(b).astype(np.float64),
200+
np.asarray(c).astype(np.float64),
195201
)
196202
return tuple(x.astype(res_dtype) for x in res)
197203

lab/jax/custom.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
from functools import wraps
22

3-
import jax.experimental.host_callback as hcb
4-
from jax import ShapeDtypeStruct, custom_vjp
3+
from jax import ShapeDtypeStruct
4+
from jax import __version__ as jax_version
5+
from jax import custom_vjp
6+
from packaging.version import Version
57
from plum import Dispatcher, convert
68

9+
if Version(jax_version) >= Version("0.5"):
10+
from jax.experimental import io_callback
11+
12+
# IO callbacks do not support JVP in JAX before `0.5`, so we emulate the call with
13+
# `host_callback`.
14+
else: # pragma: no cover
15+
from jax.experimental import host_callback
16+
17+
def io_callback(f, shapes, x):
18+
return host_callback.call(f, x, result_shape=shapes)
19+
20+
721
from ..custom import TensorDescription
822

923
__all__ = ["jax_register"]
@@ -30,13 +44,13 @@ def parse_inference_result(xs: tuple):
3044
return tuple(parse_inference_result(x) for x in xs)
3145

3246

33-
def _wrap_hcb(f, i_f):
47+
def _wrap_cb(f, i_f):
3448
@wraps(f)
3549
def f_wrapped(*args, **kw_args):
36-
return hcb.call(
50+
return io_callback(
3751
lambda x: f(*x[0], **x[1]),
38-
arg=(args, kw_args),
39-
result_shape=parse_inference_result(i_f(*args, **kw_args)),
52+
parse_inference_result(i_f(*args, **kw_args)),
53+
(args, kw_args),
4054
)
4155

4256
return f_wrapped
@@ -55,8 +69,8 @@ def jax_register(f, i_f, s_f, i_s_f):
5569
Returns:
5670
function: JAX function.
5771
"""
58-
f = _wrap_hcb(f, i_f)
59-
s_f = _wrap_hcb(s_f, i_s_f)
72+
f = _wrap_cb(f, i_f)
73+
s_f = _wrap_cb(s_f, i_s_f)
6074

6175
f = custom_vjp(f)
6276

lab/types.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,16 @@ def _torch_lookup(dtype):
194194

195195
def _name(x):
196196
try:
197-
return x.name
197+
name = x.name
198198
except AttributeError:
199-
return x.__name__
199+
name = x.__name__
200+
201+
# `int`s are `int64`s. We need to do this conversion explicity, because `torch.int`
202+
# is `torch.int32` in later versions.
203+
if name == "int":
204+
name = "int64"
205+
206+
return name
200207

201208

202209
# Add conversions between data types.
@@ -357,7 +364,7 @@ def dtype_int(dtype: DType):
357364
"""
358365
# TODO: Is there a better way of doing this?
359366
name = list(convert(dtype, NPDType).__name__)
360-
while name and name[0] not in set([str(i) for i in range(10)]):
367+
while name and not name[0].isdigit():
361368
name.pop(0)
362369
return _convert_back(_name_to_numpy_dtype("int" + "".join(name)), dtype)
363370

0 commit comments

Comments
 (0)