~/bend-docscommunity

cublas.bend relies on unsafe/foreign

raw source on the hub · import bend-blas-lapack@0.0.0.1/cublas.bend as Cublas

bend-blas: cuBLAS on Array<F32>, one def per routine, plus device buffers. Generated by gen/effs.py: edit the table there, not this file.

The same conventions as blas.bend. cuBLAS is opened at runtime with dlopen (libcudart, libcublas), so this file builds anywhere; on a machine without CUDA every routine answers Fail{(1, ..)}, and Cublas.available answers False. A device buffer is uploaded once (Cublas.upload), referenced by its U32 id, never consumed, and freed with Cublas.free; Cublas.sgemm_w reads one as its right operand, so a model's weights cross the bus once. On the interpreter the JS twins run on the host: plain loops, correct and slow. Not yet run on an NVIDIA machine: the C is checked against the cuBLAS signatures only.

1 import
import Base

Definitions

def Cublas.available.try source · line 20 · raw

IO(Bool)

def Cublas.upload.try source · line 28 · raw

@n:U32 -> @a:Array<F32> -> IO(U32)

def Cublas.download.try source · line 36 · raw

@id:U32 -> IO(Array<F32>)

def Cublas.free.try source · line 44 · raw

@id:U32 -> IO(Unit)

def Cublas.sgemm.try source · line 54 · raw

@ta:U32 -> @tb:U32 -> @m:U32 -> @n:U32 -> @k:U32 -> @alpha:F32 -> @a:Array<F32> -> @b:Array<F32> -> @beta:F32 -> @c:Array<F32> -> IO(Array<F32>)

def Cublas.sgemm_w.try source · line 63 · raw

@ta:U32 -> @tb:U32 -> @m:U32 -> @n:U32 -> @k:U32 -> @alpha:F32 -> @a:Array<F32> -> @b:U32 -> @beta:F32 -> @c:Array<F32> -> IO(Array<F32>)

Effects (foreign code)

effect Cublas.available source · line 16 · raw

IO(Result<&1, &1, Pair(U32, String), Bool>)

True when cuBLAS opens on this machine: the answer of every other routine is Fail{(1, ..)} otherwise. Never fails.

foreign: effs/cublas_available.c, effs/cublas_available.js

effect Cublas.upload source · line 24 · raw

@n:U32 -> @a:Array<F32> -> IO(Result<&1, &1, Pair(U32, String), U32>)

The first n floats of an array copied to the device; answers the buffer id. The array is consumed.

foreign: effs/cublas_upload.c, effs/cublas_upload.js

effect Cublas.download source · line 32 · raw

@id:U32 -> IO(Result<&1, &1, Pair(U32, String), Array<F32>>)

The n floats of a device buffer back in a fresh array; the buffer stays.

foreign: effs/cublas_download.c, effs/cublas_download.js

effect Cublas.free source · line 40 · raw

@id:U32 -> IO(Result<&1, &1, Pair(U32, String), Unit>)

Frees a device buffer; its id is dead after.

foreign: effs/cublas_free.c, effs/cublas_free.js

effect Cublas.sgemm source · line 50 · raw

@ta:U32 -> @tb:U32 -> @m:U32 -> @n:U32 -> @k:U32 -> @alpha:F32 -> @a:Array<F32> -> @b:Array<F32> -> @beta:F32 -> @c:Array<F32> -> IO(Result<&1, &1, Pair(U32, String), Array<F32>>)

C = alpha op(A) op(B) + beta C on the GPU, the operands copied to the device for the call and the result back; the same arguments as Blas.sgemm.

foreign: effs/cublas_sgemm.c, effs/cublas_sgemm.js

effect Cublas.sgemm_w source · line 59 · raw

@ta:U32 -> @tb:U32 -> @m:U32 -> @n:U32 -> @k:U32 -> @alpha:F32 -> @a:Array<F32> -> @b:U32 -> @beta:F32 -> @c:Array<F32> -> IO(Result<&1, &1, Pair(U32, String), Array<F32>>)

Cublas.sgemm with the right operand a device buffer (uploaded once with Cublas.upload, never consumed): the shape of a model's weights.

foreign: effs/cublas_sgemm_w.c, effs/cublas_sgemm_w.js