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