Add commonly-used methods on tensors - #164
Conversation
|
@marcelluethi I made some targeted comments for specific lines of code. Overall, my view is this: JAX has many functions that are conceptually functions on Tensor1, but are defined for higher-order tensors, taking an An illustrative example for this is https://docs.jax.dev/en/latest/_autosummary/jax.numpy.cross.html |
|
Maybe this approach is the best of both worlds (let's discuss tomorrow 👍 ): Operations, which allow no or multiple axes in JAX, are define on extension (t: Tensor[...])
def sum(...)
t.sum
t.sum(Axis[A])Operations, which require exactly one axis in JAX, are functions on vectors and should be defined on // main branch
extension (t: Tensor1[...])
def softmax: Tensor1[...] = ... // correct scoping
// not yet on main branch
extension (t: Tensor[...])
def softmax(axis: Axis[A]): Tensor[...] = t.vapply(axis)(softmax) // syntax sugar
t.vapply(Axis[A])(softmax) // current
t.softmax(Axis[A]) // new option to do thisThe implementation might be difficult due to This consideration applys to |
|
So I understand that there are operations like object Tensor1Transform:
def softmax[V : Floating](t : Tensor1[A, V]) : Tensor1[A, V] = ???
def diff[V](t : Tensor1[A, V]) : Tensor1[A, V] = ???and in extension t : Tensor[T, V : Floating]
def softmax[L](axis : Axis[L]) : Tensor[T, V] = vapply(axis)(Tensor1Transform.softmax)To use the methods, the user has two options:
|
|
@benikm91 I started doing the refactoring discussed above and incorporating your comments. |
| def isfinite: Tensor[T, Bool] = Tensor(Jax.jnp.isfinite(t.jaxValue)) | ||
|
|
||
| /** replaces NaN by `nan`, +inf by `posInf` and -inf by `negInf`. | ||
| * By default, NaN becomes 0 and ±inf become the largest/smallest finite value of the dtype. |
| /** sorts the tensor `t` along the specified axis */ | ||
| def sort[L: Label](axis: Axis[L])(using AxisIndex[T, L]): Tensor[T, V] = | ||
| t.vapply(axis)(Tensor1.sort) | ||
| def sort: Tensor[T, V] = Tensor(Jax.jnp.sort(t.jaxValue)) |
There was a problem hiding this comment.
Remove default sort (last axis by convention).
There was a problem hiding this comment.
Done. I also removed argsort and I added tests that these methods do not exists (for Tensor2 objects) as we don't support a default axis if none is provided. We may support t1.sort (for Tensor1) in the future; tests are all written with Tensor2 for this case.
| /** replaces NaN by `nan`, +inf by `posInf` and -inf by `negInf`. | ||
| * By default, NaN becomes 0 and ±inf become the largest/smallest finite value of the dtype. | ||
| */ | ||
| def nanToNum(using |
There was a problem hiding this comment.
This IsFloating[V] can be removed. IsFloating evidence already in extention method.
There was a problem hiding this comment.
I tested it, it fails without it. Reason: The V: IsFloating is added after this parameter group, so IsFloating is not in scope for the default. So keep as is here.
| // activation functions | ||
| def sigmoid: Tensor[T, V] = Tensor(Jax.jnn.sigmoid(t.jaxValue)) | ||
| def relu: Tensor[T, V] = Tensor(Jax.jnn.relu(t.jaxValue)) | ||
| def gelu: Tensor[T, V] = Tensor(Jax.jnn.gelu(t.jaxValue)) |
There was a problem hiding this comment.
This changed syntax to t.relu. We need relu(t), as this is more natural for activation functions. I propose to put this in DimWit, here, but I am fine to move this also to DeepWit only.
There was a problem hiding this comment.
This is a bigger issue: In Tensor1 we have some functions, e.g., for softmax, but they are missing for ElementWiseOps and ReductionOps, etc. This is a inconsitency we should address. But maybe in a separate PR.
benikm91
left a comment
There was a problem hiding this comment.
See new comments.
Only the one def sort that defaults to axis=-1 must be removed, the other changes are optional, but consider them. If sort is removed I will approve.
benikm91
left a comment
There was a problem hiding this comment.
Looks good. I done the last few bits myself as discussed with @marcelluethi in our train ride 👍
DimWits wrapping of the basic tensor methods supported in jax is rather patchy and was introduced on a per need basis.
This PR proposes to add some more, frequently used tensor operations. Each of them is just a one-liner, wrapping the underlying jax function.
The methods added are:
sortcumsum,cumproddifffloor,ceil,roundarcsin,arccos,arctanisnan,isfinite,nanToNummod(with a%operator)