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;