A generic mechanism for turning a JAX function into a PyTorch function.
October 26, 2021 ยท View on GitHub
import torch import torch.utils.dlpack import jax import jax.dlpack
A generic mechanism for turning a JAX function into a PyTorch function.
def j2t(x_jax): x_torch = torch.utils.dlpack.from_dlpack(jax.dlpack.to_dlpack(x_jax)) return x_torch
def t2j(x_torch): x_torch = x_torch.contiguous() # https://github.com/google/jax/issues/8082 x_jax = jax.dlpack.from_dlpack(torch.utils.dlpack.to_dlpack(x_torch)) return x_jax
def jax2torch(fun):
class JaxFun(torch.autograd.Function): @staticmethod def forward(ctx, x): y_, ctx.fun_vjp = jax.vjp(fun, t2j(x)) return j2t(y_)
@staticmethod
def backward(ctx, grad_y):
grad_x_, = ctx.fun_vjp(t2j(grad_y))
return j2t(grad_x_),
return JaxFun.apply
Here's a JAX function we want to interface with PyTorch code.
@jax.jit def jax_square(x): return x ** 2
torch_square = jax2torch(jax_square)
Let's run it on Torch data!
import numpy as np
x = torch.from_numpy(np.array([1., 2., 3.], dtype='float32')) y = torch_square(x) print(y) # tensor([1., 4., 9.])
And differentiate!
x = torch.tensor(np.array([1., 2., 3.], dtype='float32'), requires_grad=True) y = torch.sum(torch_square(x)) y.backward() print(x.grad) # tensor([2., 4., 6.])