ExCubecl is a GPU compute runtime for Elixir. It provides GPU buffer management, kernel execution, async command submission, and pipeline orchestration via CubeCL (Rust NIFs).

Installation

Add to your mix.exs:

def deps do
  [{:ex_cubecl, "~> 0.4.0"}]
end

Then run mix deps.get.

Architecture

Elixir  ExCubecl.NIF  Rust NIF  CubeCL Runtime

All GPU state lives in Rust — not in BEAM memory. The Elixir side manages handles, orchestrates pipelines, and schedules work.

Core Concepts

Buffers

Buffers are the primary data structure, representing GPU memory holding typed, shaped data:

# Create a buffer from a list
{:ok, buf} = ExCubecl.buffer([1.0, 2.0, 3.0], [3], :f32)

# Inspect
{:ok, [3]} = ExCubecl.shape(buf)
{:ok, "f32"} = ExCubecl.dtype(buf)
{:ok, 12} = ExCubecl.size(buf)   # bytes

# Read data back
{:ok, data} = ExCubecl.read(buf)

# Buffers are automatically freed when the Elixir term is garbage collected.

Kernels

Kernels are GPU programs that operate on buffers:

{:ok, input} = ExCubecl.buffer([1.0, 2.0, 3.0], [3], :f32)
{:ok, output} = ExCubecl.buffer([0.0, 0.0, 0.0], [3], :f32)

{:ok, _cmd} = ExCubecl.run_kernel("elementwise_add", [input], output)

Async Execution

Submit work without blocking the BEAM:

{:ok, cmd_id} = ExCubecl.submit("some_command")

# Poll for status
{:ok, :completed} = ExCubecl.poll(cmd_id)

# Or block until done
:ok = ExCubecl.wait(cmd_id)

Pipelines

Compose multiple GPU operations into a single executable graph:

{:ok, pipeline} = ExCubecl.pipeline()

:ok = ExCubecl.pipeline_add(pipeline, "elementwise_add", [buf_a, buf_b], buf_out)
:ok = ExCubecl.pipeline_add(pipeline, "relu", [buf_out], buf_result)

{:ok, _cmd_ids} = ExCubecl.pipeline_run(pipeline)
:ok = ExCubecl.pipeline_free(pipeline)

Supported Types

TypeDescription
:f3232-bit float
:f6464-bit float
:s3232-bit signed integer
:s6464-bit signed integer
:u3232-bit unsigned integer
:u88-bit unsigned integer

Checking Availability

ExCubecl.available?()    # true if NIF is loaded
ExCubecl.version()       # "0.4.0"
ExCubecl.device_info()   # %{device_name: "...", device_type: "gpu", ...}
ExCubecl.device_count()  # 1

Next Steps