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;