Skip to main content

Automatically broadcast inputs by dynamically applying jax.vmap given un-batched argument dimensions.

Project description

Tests PyPI

Automatically broadcast via JAX vmap

Automatically broadcast a function that takes inputs of specific ranks to accept any batch dimensions using jax.vmap. See the documentation of JAX for more information about vmap.

This module defines a decorator function which takes as input the base ranks of the arguments of a function. The transformed function takes any broadcastable combination of batched inputs and automatically applies jax.vmap as required. One could equivalently apply vmap by hand, however the in-axes have to be chosen differently for different inputs. The decorator takes care of this automatically; if the underlying ranks are known, batch dimensions can be inferred.

Examples

Consider the following function which takes numeric arguments with fixed and known ranks as input:

import jax.numpy as jnp

def foo(s, v, m):  # s - scalar, v - vector, m - matrix
    return v @ m @ v + s * v.size

If we have inputs of appropriate rank, the function can be applied without problem:

s = jnp.array(2.0)    # scalar
v = jnp.ones(3)       # vector
m = jnp.ones((3, 3))  # matrix
foo(s, v, m)   # returns 15.0

Assume now, however, that we have 5 matrices and 5 vectors for which we want to apply the above function as a batch. Many numpy functions can take inputs with leading batch dimensions, but here we have an issue because v @ m @ v requires m to be a matching matrix.

s = jnp.array(2.0)
v = jnp.ones((5, 3))
m = jnp.ones((5, 3, 3))
foo(s, v, m)  # throws TypeError

There are multiple possible ways we can solve this

  • We could try to write the function more carefully, so it can take both single and batch inputs. Or we could always require the first dimension to be a batch index.
  • Given known inputs, we can transform our function: jax.jit(foo, (None, 0, 0)). However, the axes change depending on the inputs. If we want to expose functions that accept batched inputs to the user, we need to have some clear naming scheme (to indicate which arguments are batched).

Sometimes, the best solution is one of the above. This module provides another more flexible solution. If the ranks the function wants are known, we can derive which arguments have (leading) batch dimensions. Based on that, we can apply jax.vmap appropriately. That is exactly what the autovmap wrapper does. Thanks to jax.jit, after the transformed function is JIT-compiled, there is no price to pay for this extra flexibility since it only depends on the statically-known input shapes.

We can define the more flexible function as follows:

from jax_autovmap import autovmap

@autovmap(s=0, v=1, m=2)
def foo(s, v, m):
    return v @ m @ v + s * v.size

foo(s, v, m)  # returns [15. 15. 15. 15. 15.]

The ranks can be specified by keyword argument as above, or positionally (in this case @autovmap(0, 1, 2)). This does not have to be applied to all input arguments. They can either be omitted or, if ranks are given positionally, specified as None.

If the arguments are pytrees (python structures of arrays) and the rank is a single integer, all constituents (leaves) are assumed to have that rank. Alternatively, the rank can be a matching pytree, just like the in_axes in jax.vmap:

@autovmap({'s': 0, 'v': 1, 'm': 2})
def foo(inputs):
    return inputs['v'] @ inputs['m'] @ inputs['v'] + inputs['s']

foo(dict(s=s, v=v, m=m))

Just like NumPy broadcasting, it is also allowed that one of the "vmap'ed" arguments has length 1:

s = jnp.array(2.0)
v = jnp.ones((7, 1, 3))  # broadcast second axis with vmap over 5 values of `m`
m = jnp.ones((7, 5, 3, 3))

@autovmap(s=0, v=1, m=2)
def foo(s, v, m):
    return v @ m @ v + s

foo(s, v, m)  # shape (7, 5)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jax_autovmap-0.3.0.tar.gz (6.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jax_autovmap-0.3.0-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file jax_autovmap-0.3.0.tar.gz.

File metadata

  • Download URL: jax_autovmap-0.3.0.tar.gz
  • Upload date:
  • Size: 6.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.23

File hashes

Hashes for jax_autovmap-0.3.0.tar.gz
Algorithm Hash digest
SHA256 1c6e22706e1eb11703e2084c540d69757124ae82a1e02491bb2ad29a741687b5
MD5 1ac68db6672f9286498369a3c1bcbbe9
BLAKE2b-256 11707abb5f5e8e16418d904f88a197c7dddb02a0b63c5a91990e70edc27d0580

See more details on using hashes here.

File details

Details for the file jax_autovmap-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: jax_autovmap-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 7.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.23

File hashes

Hashes for jax_autovmap-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 654eb1089c95867bbcf06a167b75661a2d737da645283a9de36cfb7f3e9a629f
MD5 7f684a522e399c7a9837160a65d059d0
BLAKE2b-256 57fa290868b1243d6e6a6277e416c5545d6c0b83fa05ed1e7c21aaed63f1edd0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page