blas.bend

bend-blas-lapack@0.0.0.1 · 98 lines · 18 definitions

1# bend-blas: the CBLAS routines on Array<F32>, one def per routine, the
2# names of CBLAS without the cblas_ prefix. Generated by gen/effs.py:
3# edit the table there, not this file.
4#
5# Conventions. Sizes and flags are U32 (an Array<F32> has no shape; ta
6# and tb are 0 or 1 for a transpose), scalars F32, matrices row-major
7# with their leading dimension equal to their row width. Every array
8# operand is consumed (the effect drops it after reading it) and an
9# answered array is a fresh block of the smallest power-of-two size
10# holding the result, the tail zero. A routine answers
11# IO(Result<&1, &1, U32 & String, A>): Fail{(code, message)} when no
12# BLAS is found (2), an operand is smaller than its sizes claim (2), or
13# a size passes 2^31 floats (2); a full heap is a fail-stop of the
14# runtime, not a Fail. Its .try twin answers IO(A) and dies on failure.
15#
16# The platform BLAS is opened at runtime (dlopen): Accelerate on macOS;
17# OpenBLAS, else libcblas beside the system BLAS, on Linux, which must
18# be installed. On the interpreter the JS twins run: plain loops,
19# correct and slow, whose failures carry the code only.
20import Base
21
22# C = alpha op(A) op(B) + beta C. A is m x k as stored (k x m when ta = 1),
23# B is k x n (n x k when tb = 1), C is m x n, all row-major. C is consumed
24# and the updated copy answered; pass beta = 0 and any m x n block for a
25# fresh product.
26def Blas.sgemm(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, U32 & String, Array<F32>>):
27  import "./effs/blas_sgemm.c"
28  import "./effs/blas_sgemm.js"
29
30def Blas.sgemm.try(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>):
31  IO.try(Array<F32>, Blas.sgemm(ta, tb, m, n, k, alpha, a, b, beta, c))
32
33# y = alpha op(A) x + beta y. A is m x n as stored, row-major; ta = 1
34# applies A^T, so x has n elements (m when ta) and y has m (n when ta).
35# y is consumed and the updated copy answered.
36def Blas.sgemv(ta: U32, m: U32, n: U32, alpha: F32, a: Array<F32>, x: Array<F32>, beta: F32, y: Array<F32>) -> IO(Result<&1, &1, U32 & String, Array<F32>>):
37  import "./effs/blas_sgemv.c"
38  import "./effs/blas_sgemv.js"
39
40def Blas.sgemv.try(ta: U32, m: U32, n: U32, alpha: F32, a: Array<F32>, x: Array<F32>, beta: F32, y: Array<F32>) -> IO(Array<F32>):
41  IO.try(Array<F32>, Blas.sgemv(ta, m, n, alpha, a, x, beta, y))
42
43# A = alpha x y^T + A, the rank-1 update; A is m x n, x has m elements,
44# y has n. A is consumed and the updated copy answered.
45def Blas.sger(m: U32, n: U32, alpha: F32, x: Array<F32>, y: Array<F32>, a: Array<F32>) -> IO(Result<&1, &1, U32 & String, Array<F32>>):
46  import "./effs/blas_sger.c"
47  import "./effs/blas_sger.js"
48
49def Blas.sger.try(m: U32, n: U32, alpha: F32, x: Array<F32>, y: Array<F32>, a: Array<F32>) -> IO(Array<F32>):
50  IO.try(Array<F32>, Blas.sger(m, n, alpha, x, y, a))
51
52# The dot product of the first n elements of x and y.
53def Blas.sdot(n: U32, x: Array<F32>, y: Array<F32>) -> IO(Result<&1, &1, U32 & String, F32>):
54  import "./effs/blas_sdot.c"
55  import "./effs/blas_sdot.js"
56
57def Blas.sdot.try(n: U32, x: Array<F32>, y: Array<F32>) -> IO(F32):
58  IO.try(F32, Blas.sdot(n, x, y))
59
60# The Euclidean norm of the first n elements of x.
61def Blas.snrm2(n: U32, x: Array<F32>) -> IO(Result<&1, &1, U32 & String, F32>):
62  import "./effs/blas_snrm2.c"
63  import "./effs/blas_snrm2.js"
64
65def Blas.snrm2.try(n: U32, x: Array<F32>) -> IO(F32):
66  IO.try(F32, Blas.snrm2(n, x))
67
68# The sum of the absolute values of the first n elements of x.
69def Blas.sasum(n: U32, x: Array<F32>) -> IO(Result<&1, &1, U32 & String, F32>):
70  import "./effs/blas_sasum.c"
71  import "./effs/blas_sasum.js"
72
73def Blas.sasum.try(n: U32, x: Array<F32>) -> IO(F32):
74  IO.try(F32, Blas.sasum(n, x))
75
76# The index (from 0) of the element of largest absolute value among the first n of x.
77def Blas.isamax(n: U32, x: Array<F32>) -> IO(Result<&1, &1, U32 & String, U32>):
78  import "./effs/blas_isamax.c"
79  import "./effs/blas_isamax.js"
80
81def Blas.isamax.try(n: U32, x: Array<F32>) -> IO(U32):
82  IO.try(U32, Blas.isamax(n, x))
83
84# y = alpha x + y over the first n elements; y is consumed and the updated copy answered.
85def Blas.saxpy(n: U32, alpha: F32, x: Array<F32>, y: Array<F32>) -> IO(Result<&1, &1, U32 & String, Array<F32>>):
86  import "./effs/blas_saxpy.c"
87  import "./effs/blas_saxpy.js"
88
89def Blas.saxpy.try(n: U32, alpha: F32, x: Array<F32>, y: Array<F32>) -> IO(Array<F32>):
90  IO.try(Array<F32>, Blas.saxpy(n, alpha, x, y))
91
92# x = alpha x over the first n elements; x is consumed and the scaled copy answered.
93def Blas.sscal(n: U32, alpha: F32, x: Array<F32>) -> IO(Result<&1, &1, U32 & String, Array<F32>>):
94  import "./effs/blas_sscal.c"
95  import "./effs/blas_sscal.js"
96
97def Blas.sscal.try(n: U32, alpha: F32, x: Array<F32>) -> IO(Array<F32>):
98  IO.try(Array<F32>, Blas.sscal(n, alpha, x))