Skip to main content

Fast Euclid equivariant operations for JAX

Project description

⚙️ e3j-ops

This package contains the CUDA/C++ source for e3j. The Python bindings to XLA handlers are bundled into the e3j_ops shared object, which the main e3j package wraps in custom JAX primitives via the ffi_call API.

Note: The e3j_ops ABI should not be considered stable for now, but considered private within the e3j Python API.

Building from source

The CMake build recipes are defined in CMakeLists.txt. The Makefile of e3j also defines fine-graind recipes to build and test individual CUDA/C++ objects.

Project structure

The source is organized as follows:

  • cuda : CUDA kernel implementations
  • ffi : XLA-FFI handlers declarations and pybind11 module definition
  • xla : vendored XLA FFI headers
  • tests : C++ kernel tests

CUDA/C++ source

Each operation is defined in its own namespace following a common interface (see e.g. tensor_product.cuh for detailed signatures):

  • a namespace e3j::op_name within the enclosing e3j namespace,
  • a struct e3j::op_name::Params for passing hyperparameters,
  • a __global__ CUDA function e3j::op_name::kernel(),
  • a __host__ launcher e3j::op_name::launch()

Although object-oriented patterns are hard to mix with __device__ code, this name-based ABI is subject to change.

namespace e3j {
namespace op_name {

    struct Params;

    template <typename Idx, typename Val>
    __global__ void kernel (Params p, ...);

    template <typename Idx, typename Val>
    e3j::Error launch (..., Params p, cudaStream_t stream);

} // namespace op_name
} // namespace e3j

Most kernels are templated across a range of index and/or value data types. Some e3j primitives automatically dispatch to narrow index dtypes (uint8 / uint16) when feature spaces dimensions are small enough. Half-precision float16 arithmetic for values is not yet supported, but planned for a soon upcoming release.

XLA-FFI handlers

The FFI layer uses the XLA FFI API to bind kernel launchers as XLA custom calls. Each handler is registered with XLA_FFI_DEFINE_HANDLER, receiving typed buffers and attributes directly (no opaque descriptor packing):

xla::Error OpNameHandler(
    cudaStream_t stream,
    int32_t num_out,
    xla::AnyBuffer x,
    xla::Result<xla::AnyBuffer> out
) {
    // ... dtype dispatch ...
    return e3j::op_name::launch<Idx, Val>(
        x.typed_data<Idx>(),
        out->typed_data<Val>(),
        params, stream
    ).to_xla();
}

XLA_FFI_DEFINE_HANDLER(
    xla_op_name,
    OpNameHandler,
    xla::Ffi::Bind()
        .Ctx<xla::PlatformStream<cudaStream_t>>()
        .Attr<int32_t>("num_out")
        .Arg<xla::AnyBuffer>()
        .Ret<xla::AnyBuffer>()
);

Handlers are exposed to Python as PyCapsules via pyEncapsulateFunction in e3j_ops.h, and registered in the pybind11 module defined in e3j_ops.cpp.

Contributing

Although it is too early for e3j_ops to accept significant external contributions, bug reports or questions are very welcome via GitHub issues and discussions.

Citing

If you use e3j within your work, we kindly ask you to cite the following preprint:

@article{Peltre26-e3j,
    title   = {{E3J}: an Efficient and Open-Source Euclidean Equivariance Backend},
    author  = {Peltre, Olivier and Picard, Armand and Pichard, Adrien and Giacomoni, Luca and Braganca, Miguel and Heyraud, Valentin and Brunken, Christoph and Tilly, Jules},
    journal = {preprint},
    year    = {2026},
    url     = {(preprint)}
  }
}

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

e3j_ops-0.1.0b5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (4.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

e3j_ops-0.1.0b5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (4.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

e3j_ops-0.1.0b5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (4.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

e3j_ops-0.1.0b5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (4.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

File details

Details for the file e3j_ops-0.1.0b5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for e3j_ops-0.1.0b5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 eb937fbd0c38b500c527c7906e833edd299de32aad7b633c797e6b1f16b55577
MD5 6defae1f211042d89a549b7cffb633e9
BLAKE2b-256 7f1f69cf208ffd57007448a79855e266c331c5d4c28b9f7c43908f7cb015d81b

See more details on using hashes here.

File details

Details for the file e3j_ops-0.1.0b5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for e3j_ops-0.1.0b5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c4b9beb29e28063795d339a87f2a77db578d962bf616885e979d0eb0d911a63d
MD5 17733c8c23e391e866c0e3b567cc01fd
BLAKE2b-256 3b681c9a68b90d30b92689949b988be6d0fdfa07734e929a68b10d95a98e7230

See more details on using hashes here.

File details

Details for the file e3j_ops-0.1.0b5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for e3j_ops-0.1.0b5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fcd90026b75b020bc1fdcce176227c06252c1c5b44d5afb6a29ecb49479e5647
MD5 8862bb644b809431eed623cc1e2252a5
BLAKE2b-256 3bd542af30aa9ff27a4d659a573b9520f0bef4d6e556f4248d7f1113df9f7a2a

See more details on using hashes here.

File details

Details for the file e3j_ops-0.1.0b5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for e3j_ops-0.1.0b5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3897f017a54846ec4dfb40c3bee48bfbecac646ce385d3fa9b4f995ed6d8ec67
MD5 560c8f3a3a1244ef9410053884197df1
BLAKE2b-256 7ed2a9424886b69a5eefab7bce8ed750cdb30a7c63046d1f50432c8c5b44f324

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