Installation
Add ex_burn to your mix.exs:
def deps do
[
{:ex_burn, github: "ohhi-vn/ex_burn"},
{:nx, ">= 0.7.0"},
{:axon, "~> 0.7"},
{:ex_cubecl, ">= 0.4.0"}
]
endThen run:
mix deps.get
mix compile
Note: ExBurn is not yet on Hex.pm. Install from GitHub until the first stable release.
Basic Tensor Operations
# Set ExBurn as the default Nx backend
Nx.default_backend(ExBurn.Backend)
# Create tensors
a = Nx.tensor([1.0, 2.0, 3.0])
b = Nx.tensor([4.0, 5.0, 6.0])
# Element-wise operations
Nx.add(a, b) # [5.0, 7.0, 9.0]
Nx.multiply(a, b) # [4.0, 10.0, 18.0]
# Matrix operations
m = Nx.tensor([[1.0, 2.0], [3.0, 4.0]])
Nx.transpose(m) # [[1.0, 3.0], [2.0, 4.0]]Using the BurnBridge Directly
For performance-critical code, bypass the Nx layer:
# Create Burn tensors directly
t1 = ExBurn.BurnBridge.zeros([3, 3], :f32)
t2 = ExBurn.BurnBridge.ones([3, 3], :f32)
# Perform operations
t3 = ExBurn.BurnBridge.add(t1, t2)
# Convert to Nx when needed
nx_tensor = ExBurn.BurnBridge.to_nx(t3)Checking GPU Availability
ExBurn uses ExCubecl for GPU buffer management and kernel execution:
# Check if ExCubecl (GPU runtime) is available
if ExCubecl.available?() do
{:ok, info} = ExCubecl.device_info()
IO.puts("GPU: #{info.device_name}")
else
IO.puts("Running on CPU (ExCubecl not available)")
endYou can also use the ExBurn helper:
if ExBurn.NifHelper.gpu_available() do
IO.puts("GPU: #{ExBurn.NifHelper.device_name()}")
else
IO.puts("Running on CPU")
endUsing ExCubecl Buffers Directly
For GPU-native workflows, create buffers directly via ExCubecl:
# Create GPU buffers
{:ok, a} = ExCubecl.buffer([1.0, 2.0, 3.0], [3], :f32)
{:ok, b} = ExCubecl.buffer([4.0, 5.0, 6.0], [3], :f32)
# Inspect
{:ok, [3]} = ExCubecl.shape(a)
{:ok, "f32"} = ExCubecl.dtype(a)
{:ok, 12} = ExCubecl.size(a) # bytes
# Read data back
{:ok, data} = ExCubecl.read(a)
# Run a kernel
output = ExCubecl.buffer!([0.0, 0.0, 0.0], [3], :f32)
ExCubecl.run_kernel("elementwise_add", [a, b], output)
# Buffers are automatically freed when GC'd — no manual free neededUsing the CubeclBridge
ExBurn.CubeclBridge provides a higher-level wrapper around ExCubecl with pipeline support:
# Check available backends
ExBurn.CubeclBridge.available_backends()
# Create a pipeline
{:ok, pipeline} = ExBurn.CubeclBridge.pipeline()
ExBurn.CubeclBridge.pipeline_add(pipeline, "elementwise_add", [a, b], output)
ExBurn.CubeclBridge.pipeline_add(pipeline, "relu", [output], output)
{:ok, _cmd_ids} = ExBurn.CubeclBridge.pipeline_run(pipeline)
:ok = ExBurn.CubeclBridge.pipeline_free(pipeline)