1 /++
2 $(H2 GLAS API)
3 
4 Copyright: Copyright © 2016-, Ilya Yaroshenko.
5 License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 Authors: Ilya Yaroshenko
7 
8 $(H4 Transposition)
9 GLAS does not require transposition parameters.
10 Use $(LINK2 http://dlang.org/phobos/std_experimental_ndslice_iteration.html#transposed, transposed)
11 to perform zero cost ndslice transposition.
12 
13 Note: $(LINK2 , ndslice) uses is row major representation.
14     $(BR)
15 +/
16 module glas.ndslice;
17 
18 version(D_Ddoc)
19 {
20     enum SliceKind
21     {
22         universal,
23         canonical,
24         contiguous,
25     }
26     struct Structure(size_t N) {}
27     struct Slice(SliceKind kind, size_t[] packs, Iterator) {}
28 }
29 else
30 {
31     import mir.ndslice.slice: Slice, SliceKind, Structure;
32 }
33 
34 extern(C) nothrow @nogc @system:
35 
36 /++
37 Specifies if the matrix `asl` stores conjugated elements.
38 +/
39 enum ulong ConjA = 0x1;
40 /++
41 Specifies if the matrix `bsl` stores conjugated elements.
42 +/
43 enum ulong ConjB = 0x2;
44 /++
45 Specifies if the lower  triangular
46 part of the symmetric matrix A is to be referenced.
47 
48 The lower triangular part of the matrix `asl`
49 must contain the lower triangular part of the symmetric / hermitian
50 matrix A and the strictly upper triangular part of `asl` is not
51 referenced.
52 
53 Note: Lower is default flag.
54 +/
55 enum ulong Lower = 0x0;
56 /++
57 Specifies if the upper  triangular
58 part of the symmetric matrix A is to be referenced.
59 
60 The upper triangular
61 part of the matrix `asl`  must contain the upper triangular part
62 of the symmetric / hermitian matrix A and the strictly lower triangular
63 part of `asl` is not referenced.
64 +/
65 enum ulong Upper = 0x0100;
66 /++
67 Specifies if the symmetric/hermitian matrix A
68     appears on the left in the  operation.
69 
70 Note: Left is default flag.
71 +/
72 enum ulong Left = 0x0;
73 /++
74 Specifies if the symmetric/hermitian matrix A
75     appears on the left in the  operation.
76 +/
77 enum ulong Right = 0x0200;
78 
79 /++
80 Params:
81     error_code = Error code
82 Returns:
83     error message
84 +/
85 string glas_error(int error_code);
86 
87 /++
88 Validates input data for GEMM operations.
89 Params:
90     as = structure for matrix A
91     bs = structure for matrix B
92     cs = structure for matrix C
93     settings = Operation settings. Allowed flags are
94             $(LREF ConjA), $(LREF ConjB).
95 Returns: 0 on success and error code otherwise.
96 +/
97 int glas_validate_gemm(Structure!2 as, Structure!2 bs, Structure!2 cs, ulong settings = 0);
98 /// ditto
99 alias validate_gemm = glas_validate_gemm;
100 
101 /++
102 Validates input data for SYMM operations.
103 Params:
104     as = structure for matrix A
105     bs = structure for matrix B
106     cs = structure for matrix C
107     settings = Operation settings. Allowed flags are
108             $(LREF Left), $(LREF Right),
109             $(LREF Lower), $(LREF Upper),
110             $(LREF ConjA), $(LREF ConjB).
111             $(LREF ConjA) flag specifies if the matrix A is hermitian.
112 Returns: 0 on success and error code otherwise.
113 +/
114 int glas_validate_symm(Structure!2 as, Structure!2 bs, Structure!2 cs, ulong settings = 0);
115 /// ditto
116 alias validate_symm = glas_validate_symm;
117 
118 /++
119 Performs general matrix-matrix multiplication.
120 
121 Pseudo_code: `C := alpha A × B + beta C`.
122 
123 Params:
124     alpha = scalar
125     asl = `m ⨉ k` matrix
126     bsl = `k ⨉ n` matrix
127     beta = scalar. When  `beta`  is supplied as zero then the matrix `csl` need not be set on input.
128     csl = `m ⨉ n` matrix with one stride equal to `±1`.
129     settings = Operation settings. Allowed flags are $(LREF ConjA) and $(LREF ConjB).
130 
131 Unified_alias: `gemm`
132 
133 BLAS: SGEMM, DGEMM, CGEMM, ZGEMM
134 +/
135 void glas_sgemm(float alpha, Slice!(SliceKind.universal, [2], const(float)*) asl, Slice!(SliceKind.universal, [2], const(float)*) bsl, float beta, Slice!(SliceKind.universal, [2], float*) csl, ulong settings = 0);
136 /// ditto
137 void glas_dgemm(double alpha, Slice!(SliceKind.universal, [2], const(double)*) asl, Slice!(SliceKind.universal, [2], const(double)*) bsl, double beta, Slice!(SliceKind.universal, [2], double*) csl, ulong settings = 0);
138 /// ditto
139 void glas_cgemm(cfloat alpha, Slice!(SliceKind.universal, [2], const(cfloat)*) asl, Slice!(SliceKind.universal, [2], const(cfloat)*) bsl, cfloat beta, Slice!(SliceKind.universal, [2], cfloat*) csl, ulong settings = 0);
140 /// ditto
141 void glas_zgemm(cdouble alpha, Slice!(SliceKind.universal, [2], const(cdouble)*) asl, Slice!(SliceKind.universal, [2], const(cdouble)*) bsl, cdouble beta, Slice!(SliceKind.universal, [2], cdouble*) csl, ulong settings = 0);
142 
143 /// ditto
144 alias gemm = glas_sgemm;
145 /// ditto
146 alias gemm = glas_dgemm;
147 /// ditto
148 alias gemm = glas_cgemm;
149 /// ditto
150 alias gemm = glas_zgemm;
151 
152 /++
153 Performs symmetric or hermitian matrix-matrix multiplication.
154 
155 Pseudo_code: `C := alpha A × B + beta C` or `C := alpha B × A + beta C`,
156     where  `alpha` and `beta` are scalars, `A` is a symmetric or hermitian matrix and `B` and
157     `C` are `m × n` matrices.
158 
159 Params:
160     alpha = scalar
161     asl = `k ⨉ k` matrix, where `k` is `n`  when $(LREF Right) flag is set
162            and is `m` otherwise.
163     bsl = `m ⨉ n` matrix
164     beta = scalar. When  `beta`  is supplied as zero then the matrix `csl` need not be set on input.
165     csl = `m ⨉ n` matrix with one stride equals to `±1`.
166     settings = Operation settings.
167         Allowed flags are
168             $(LREF Left), $(LREF Right),
169             $(LREF Lower), $(LREF Upper),
170             $(LREF ConjA), $(LREF ConjB).
171             $(LREF ConjA) flag specifies if the matrix A is hermitian.
172 
173 Unified_alias: `symm`
174 
175 BLAS: SSYMM, DSYMM, CSYMM, ZSYMM, SHEMM, DHEMM, CHEMM, ZHEMM
176 +/
177 void glas_ssymm(float alpha, Slice!(SliceKind.universal, [2], const(float)*) asl, Slice!(SliceKind.universal, [2], const(float)*) bsl, float beta, Slice!(SliceKind.universal, [2], float*) csl, ulong settings = 0);
178 /// ditto
179 void glas_dsymm(double alpha, Slice!(SliceKind.universal, [2], const(double)*) asl, Slice!(SliceKind.universal, [2], const(double)*) bsl, double beta, Slice!(SliceKind.universal, [2], double*) csl, ulong settings = 0);
180 /// ditto
181 void glas_csymm(cfloat alpha, Slice!(SliceKind.universal, [2], const(cfloat)*) asl, Slice!(SliceKind.universal, [2], const(cfloat)*) bsl, cfloat beta, Slice!(SliceKind.universal, [2], cfloat*) csl, ulong settings = 0);
182 /// ditto
183 void glas_zsymm(cdouble alpha, Slice!(SliceKind.universal, [2], const(cdouble)*) asl, Slice!(SliceKind.universal, [2], const(cdouble)*) bsl, cdouble beta, Slice!(SliceKind.universal, [2], cdouble*) csl, ulong settings = 0);
184 
185 /// ditto
186 alias symm = glas_ssymm;
187 /// ditto
188 alias symm = glas_dsymm;
189 /// ditto
190 alias symm = glas_csymm;
191 /// ditto
192 alias symm = glas_zsymm;
193 
194 /++
195 `scal` scales a vector by a constant.
196 
197 Pseudo_code: `x := a x`.
198 
199 Unified_alias: `scal`
200 
201 BLAS: SSCSCAL, DSCSCAL, CSCSCAL, ZSCSCAL, CSCAL, ZSCAL
202 +/
203 void glas_sscal(float a, Slice!(SliceKind.universal, [1], float*) xsl);
204 /// ditto
205 void glas_dscal(double a, Slice!(SliceKind.universal, [1], double*) xsl);
206 /// ditto
207 void glas_csscal(float a, Slice!(SliceKind.universal, [1], cfloat*) xsl);
208 /// ditto
209 void glas_cscal(cfloat a, Slice!(SliceKind.universal, [1], cfloat*) xsl);
210 /// ditto
211 void glas_csIscal(ifloat a, Slice!(SliceKind.universal, [1], cfloat*) xsl);
212 /// ditto
213 void glas_zdscal(double a, Slice!(SliceKind.universal, [1], cdouble*) xsl);
214 /// ditto
215 void glas_zscal(cdouble a, Slice!(SliceKind.universal, [1], cdouble*) xsl);
216 /// ditto
217 void glas_zdIscal(idouble a, Slice!(SliceKind.universal, [1], cdouble*) xsl);
218 
219 /// ditto
220 void _glas_sscal(float a, size_t n, size_t incx, float* x);
221 /// ditto
222 void _glas_dscal(double a, size_t n, size_t incx, double* x);
223 /// ditto
224 void _glas_csscal(float a, size_t n, size_t incx, cfloat* x);
225 /// ditto
226 void _glas_cscal(cfloat a, size_t n, size_t incx, cfloat* x);
227 /// ditto
228 void _glas_csIscal(ifloat a, size_t n, size_t incx, cfloat* x);
229 /// ditto
230 void _glas_zdscal(double a, size_t n, size_t incx, cdouble* x);
231 /// ditto
232 void _glas_zscal(cdouble a, size_t n, size_t incx, cdouble* x);
233 /// ditto
234 void _glas_zdIscal(idouble a, size_t n, size_t incx, cdouble* x);
235 
236 /// ditto
237 alias scal = glas_sscal;
238 /// ditto
239 alias scal = glas_dscal;
240 /// ditto
241 alias scal = glas_csscal;
242 /// ditto
243 alias scal = glas_cscal;
244 /// ditto
245 alias scal = glas_csIscal;
246 /// ditto
247 alias scal = glas_zdscal;
248 /// ditto
249 alias scal = glas_zscal;
250 /// ditto
251 alias scal = glas_zdIscal;
252 
253 /// ditto
254 alias scal = _glas_sscal;
255 /// ditto
256 alias scal = _glas_dscal;
257 /// ditto
258 alias scal = _glas_csscal;
259 /// ditto
260 alias scal = _glas_cscal;
261 /// ditto
262 alias scal = _glas_csIscal;
263 /// ditto
264 alias scal = _glas_zdscal;
265 /// ditto
266 alias scal = _glas_zscal;
267 /// ditto
268 alias scal = _glas_zdIscal;