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