ExCubecl (ExCubecl v0.4.0)

Copy Markdown View Source

ExCubecl — GPU compute runtime for Elixir.

Provides GPU buffer management, kernel execution, async command submission, and pipeline orchestration via CubeCL (Rust NIFs).

Quick start

# Check availability
ExCubecl.available?()

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

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

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

# Buffers are automatically freed when the Elixir term is garbage collected.
# No manual free is needed.

Kernel execution

{:ok, out} = ExCubecl.buffer([0.0, 0.0, 0.0], [3], :f32)
ExCubecl.run_kernel("elementwise_add", [buf_a, buf_b], out)

Async commands

{:ok, cmd} = ExCubecl.submit("some_command")
{:ok, :completed} = ExCubecl.poll(cmd)
:ok = ExCubecl.wait(cmd)

Pipelines

{:ok, p} = ExCubecl.pipeline()
:ok = ExCubecl.pipeline_add(p, "elementwise_add", [buf_a, buf_b], buf_out)
:ok = ExCubecl.pipeline_run(p)
:ok = ExCubecl.pipeline_free(p)

Summary

Functions

Checks if the NIF library is loaded and available.

Creates a GPU buffer from a list of values.

Creates a GPU buffer, raising on error.

Returns the number of available GPU devices.

Returns information about the GPU compute device.

Returns the dtype string of a buffer (e.g. "f32").

Returns the list of available kernel names.

Creates a new empty pipeline.

Adds a command to a pipeline using a Command struct.

Frees a pipeline and its resources.

Runs all commands in a pipeline sequentially.

Polls the status of an async command.

Reads buffer data back from the GPU as a binary.

Reads buffer data back, raising on error.

Returns the shape of a buffer.

Returns the byte size of a buffer.

Submits a command for asynchronous execution.

Returns the list of supported dtype atoms.

Returns the version of ExCubecl.

Blocks until an async command completes.

Types

buffer_ref()

@type buffer_ref() :: reference()

Functions

available?()

@spec available?() :: boolean()

Checks if the NIF library is loaded and available.

Returns true if the NIF can be loaded, false otherwise.

buffer(data, shape, type \\ :f32)

@spec buffer(list(), [non_neg_integer()], atom()) ::
  {:ok, reference()} | {:error, term()}

Creates a GPU buffer from a list of values.

Parameters

  • data — a flat list of numbers
  • shape — the tensor shape (e.g. [3] for a vector, [2, 3] for a matrix)
  • type — element type, one of: :f32, :f64, :s32, :s64, :u32, :u8 (default :f32)

Returns

{:ok, buffer} on success where buffer is a Rustler resource reference. The buffer is automatically freed when the Elixir term is garbage collected.

Examples

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

buffer!(data, shape, type \\ :f32)

@spec buffer!(list(), [non_neg_integer()], atom()) :: reference()

Creates a GPU buffer, raising on error.

See buffer/3 for parameters.

device_count()

@spec device_count() :: {:ok, non_neg_integer()} | {:error, term()}

Returns the number of available GPU devices.

device_info()

@spec device_info() :: {:ok, map()} | {:error, term()}

Returns information about the GPU compute device.

dtype(buf)

@spec dtype(reference()) :: {:ok, String.t()} | {:error, term()}

Returns the dtype string of a buffer (e.g. "f32").

kernels()

@spec kernels() :: {:ok, [String.t()]} | {:error, term()}

Returns the list of available kernel names.

pipeline()

@spec pipeline() :: {:ok, non_neg_integer()} | {:error, term()}

Creates a new empty pipeline.

pipeline_add(pipeline_id, kernel, inputs, output, params \\ %{})

@spec pipeline_add(non_neg_integer(), String.t(), [reference()], reference(), map()) ::
  :ok | {:error, term()}

Adds a kernel command to a pipeline.

Parameters

  • pipeline_id — pipeline reference returned by pipeline/0
  • kernel — kernel name string (e.g. "elementwise_add")
  • inputs — list of input buffer references
  • output — output buffer reference
  • params — optional map of kernel parameters (default %{})

Examples

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

pipeline_add_struct(pipeline_id, command)

@spec pipeline_add_struct(non_neg_integer(), ExCubecl.Command.t()) ::
  :ok | {:error, term()}

Adds a command to a pipeline using a Command struct.

Examples

cmd = ExCubecl.Command.run_kernel("elementwise_add", [buf_a, buf_b], buf_out)
ExCubecl.pipeline_add_struct(pipeline, cmd)

pipeline_free(pipeline_id)

@spec pipeline_free(non_neg_integer()) :: :ok | {:error, term()}

Frees a pipeline and its resources.

pipeline_run(pipeline_id)

@spec pipeline_run(non_neg_integer()) :: {:ok, [non_neg_integer()]} | {:error, term()}

Runs all commands in a pipeline sequentially.

poll(command_id)

@spec poll(non_neg_integer()) ::
  {:ok, :pending | :running | :completed | :failed} | {:error, term()}

Polls the status of an async command.

Returns {:ok, :pending | :running | :completed | :failed} or {:error, reason}.

read(buf)

@spec read(reference()) :: {:ok, binary()} | {:error, term()}

Reads buffer data back from the GPU as a binary.

read!(buf)

@spec read!(reference()) :: binary()

Reads buffer data back, raising on error.

run_kernel(name, inputs, output, params \\ %{})

@spec run_kernel(String.t(), [reference()], reference(), map()) ::
  {:ok, non_neg_integer()} | {:error, term()}

Runs a kernel on the GPU.

Parameters

  • name — kernel name string (see kernels/0)
  • inputs — list of input buffer references
  • output — output buffer reference
  • params — optional map of kernel parameters (default %{})

shape(buf)

@spec shape(reference()) :: {:ok, [non_neg_integer()]} | {:error, term()}

Returns the shape of a buffer.

size(buf)

@spec size(reference()) :: {:ok, non_neg_integer()} | {:error, term()}

Returns the byte size of a buffer.

submit(command)

@spec submit(String.t()) :: {:ok, non_neg_integer()} | {:error, term()}

Submits a command for asynchronous execution.

Returns {:ok, command_id} which can be used with poll/1 and wait/1.

supported_dtypes()

@spec supported_dtypes() :: [atom()]

Returns the list of supported dtype atoms.

version()

@spec version() :: String.t()

Returns the version of ExCubecl.

wait(command_id)

@spec wait(non_neg_integer()) :: :ok | {:error, term()}

Blocks until an async command completes.