Add CPUID identification of Intel Ice Lake
[platform/upstream/openblas.git] / interface / syrk.c
1 /*********************************************************************/
2 /* Copyright 2009, 2010 The University of Texas at Austin.           */
3 /* All rights reserved.                                              */
4 /*                                                                   */
5 /* Redistribution and use in source and binary forms, with or        */
6 /* without modification, are permitted provided that the following   */
7 /* conditions are met:                                               */
8 /*                                                                   */
9 /*   1. Redistributions of source code must retain the above         */
10 /*      copyright notice, this list of conditions and the following  */
11 /*      disclaimer.                                                  */
12 /*                                                                   */
13 /*   2. Redistributions in binary form must reproduce the above      */
14 /*      copyright notice, this list of conditions and the following  */
15 /*      disclaimer in the documentation and/or other materials       */
16 /*      provided with the distribution.                              */
17 /*                                                                   */
18 /*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
19 /*    AUSTIN  ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,    */
20 /*    INCLUDING, BUT  NOT LIMITED  TO, THE IMPLIED  WARRANTIES OF    */
21 /*    MERCHANTABILITY  AND FITNESS FOR  A PARTICULAR  PURPOSE ARE    */
22 /*    DISCLAIMED.  IN  NO EVENT SHALL THE UNIVERSITY  OF TEXAS AT    */
23 /*    AUSTIN OR CONTRIBUTORS BE  LIABLE FOR ANY DIRECT, INDIRECT,    */
24 /*    INCIDENTAL,  SPECIAL, EXEMPLARY,  OR  CONSEQUENTIAL DAMAGES    */
25 /*    (INCLUDING, BUT  NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE    */
26 /*    GOODS  OR  SERVICES; LOSS  OF  USE,  DATA,  OR PROFITS;  OR    */
27 /*    BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF    */
28 /*    LIABILITY, WHETHER  IN CONTRACT, STRICT  LIABILITY, OR TORT    */
29 /*    (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT    */
30 /*    OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF ADVISED  OF  THE    */
31 /*    POSSIBILITY OF SUCH DAMAGE.                                    */
32 /*                                                                   */
33 /* The views and conclusions contained in the software and           */
34 /* documentation are those of the authors and should not be          */
35 /* interpreted as representing official policies, either expressed   */
36 /* or implied, of The University of Texas at Austin.                 */
37 /*********************************************************************/
38
39 #include <stdio.h>
40 #include <ctype.h>
41 #include "common.h"
42 #ifdef FUNCTION_PROFILE
43 #include "functable.h"
44 #endif
45
46 #ifndef COMPLEX
47 #ifdef XDOUBLE
48 #define ERROR_NAME "QSYRK "
49 #elif defined(DOUBLE)
50 #define ERROR_NAME "DSYRK "
51 #else
52 #define ERROR_NAME "SSYRK "
53 #endif
54 #else
55 #ifndef HEMM
56 #ifdef XDOUBLE
57 #define ERROR_NAME "XSYRK "
58 #elif defined(DOUBLE)
59 #define ERROR_NAME "ZSYRK "
60 #else
61 #define ERROR_NAME "CSYRK "
62 #endif
63 #else
64 #ifdef XDOUBLE
65 #define ERROR_NAME "XHERK "
66 #elif defined(DOUBLE)
67 #define ERROR_NAME "ZHERK "
68 #else
69 #define ERROR_NAME "CHERK "
70 #endif
71 #endif
72 #endif
73
74 static int (*syrk[])(blas_arg_t *, BLASLONG *, BLASLONG *, FLOAT *, FLOAT *, BLASLONG) = {
75 #ifndef HEMM
76   SYRK_UN, SYRK_UC, SYRK_LN, SYRK_LC,
77 #if defined(SMP) && !defined(USE_SIMPLE_THREADED_LEVEL3)
78   SYRK_THREAD_UN, SYRK_THREAD_UC, SYRK_THREAD_LN, SYRK_THREAD_LC,
79 #endif
80 #else
81   HERK_UN, HERK_UC, HERK_LN, HERK_LC,
82 #if defined(SMP) && !defined(USE_SIMPLE_THREADED_LEVEL3)
83   HERK_THREAD_UN, HERK_THREAD_UC, HERK_THREAD_LN, HERK_THREAD_LC,
84 #endif
85 #endif
86 };
87
88 #ifndef CBLAS
89
90 void NAME(char *UPLO, char *TRANS,
91          blasint *N, blasint *K,
92          FLOAT *alpha, FLOAT *a, blasint *ldA,
93          FLOAT *beta,  FLOAT *c, blasint *ldC){
94
95   char uplo_arg  = *UPLO;
96   char trans_arg = *TRANS;
97
98   blas_arg_t args;
99
100   FLOAT *buffer;
101   FLOAT *sa, *sb;
102
103 #ifdef SMP
104 #ifdef USE_SIMPLE_THREADED_LEVEL3
105 #ifndef COMPLEX
106 #ifdef XDOUBLE
107   int mode  =  BLAS_XDOUBLE | BLAS_REAL;
108 #elif defined(DOUBLE)
109   int mode  =  BLAS_DOUBLE  | BLAS_REAL;
110 #else
111   int mode  =  BLAS_SINGLE  | BLAS_REAL;
112 #endif
113 #else
114 #ifdef XDOUBLE
115   int mode  =  BLAS_XDOUBLE | BLAS_COMPLEX;
116 #elif defined(DOUBLE)
117   int mode  =  BLAS_DOUBLE  | BLAS_COMPLEX;
118 #else
119   int mode  =  BLAS_SINGLE  | BLAS_COMPLEX;
120 #endif
121 #endif
122 #endif
123 #endif
124
125   blasint info;
126   int uplo;
127   int trans;
128   int nrowa;
129
130   PRINT_DEBUG_NAME;
131
132   args.n = *N;
133   args.k = *K;
134
135   args.a = (void *)a;
136   args.c = (void *)c;
137
138   args.lda = *ldA;
139   args.ldc = *ldC;
140
141   args.alpha = (void *)alpha;
142   args.beta  = (void *)beta;
143
144   TOUPPER(uplo_arg);
145   TOUPPER(trans_arg);
146
147   uplo  = -1;
148   trans = -1;
149
150   if (uplo_arg  == 'U') uplo  = 0;
151   if (uplo_arg  == 'L') uplo  = 1;
152
153
154 #ifndef COMPLEX
155   if (trans_arg == 'N') trans = 0;
156   if (trans_arg == 'T') trans = 1;
157   if (trans_arg == 'C') trans = 1;
158 #else
159 #ifdef HEMM
160   if (trans_arg == 'N') trans = 0;
161   if (trans_arg == 'C') trans = 1;
162 #else
163   if (trans_arg == 'N') trans = 0;
164   if (trans_arg == 'T') trans = 1;
165 #endif
166
167 #endif
168
169   nrowa = args.n;
170   if (trans & 1) nrowa = args.k;
171
172   info = 0;
173
174   if (args.ldc < MAX(1,args.n)) info = 10;
175   if (args.lda < MAX(1,nrowa))  info =  7;
176   if (args.k < 0)               info =  4;
177   if (args.n < 0)               info =  3;
178   if (trans < 0)                info =  2;
179   if (uplo  < 0)                info =  1;
180
181   if (info != 0) {
182     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
183     return;
184   }
185
186 #else
187
188 void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo, enum CBLAS_TRANSPOSE Trans,
189            blasint n, blasint k,
190 #if !defined(COMPLEX) || defined(HEMM)
191            FLOAT alpha,
192 #else
193            void *valpha,
194 #endif
195 #if !defined(COMPLEX)
196            FLOAT *a, blasint lda,
197 #else
198            void *va, blasint lda,
199 #endif
200 #if !defined(COMPLEX) || defined(HEMM)
201            FLOAT beta,
202 #else
203            void *vbeta,
204 #endif
205 #if !defined(COMPLEX)
206            FLOAT *c, blasint ldc) {
207 #else
208            void *vc, blasint ldc) {
209 #endif
210
211 #ifdef COMPLEX
212 #if !defined(HEMM)
213   FLOAT* alpha = (FLOAT*) valpha;
214   FLOAT* beta = (FLOAT*) vbeta;
215 #endif
216   FLOAT* a = (FLOAT*) va;
217   FLOAT* c = (FLOAT*) vc;
218 #endif
219
220   blas_arg_t args;
221   int uplo, trans;
222   blasint info, nrowa;
223
224   FLOAT *buffer;
225   FLOAT *sa, *sb;
226
227 #ifdef SMP
228 #ifdef USE_SIMPLE_THREADED_LEVEL3
229 #ifndef COMPLEX
230 #ifdef XDOUBLE
231   int mode  =  BLAS_XDOUBLE | BLAS_REAL;
232 #elif defined(DOUBLE)
233   int mode  =  BLAS_DOUBLE  | BLAS_REAL;
234 #else
235   int mode  =  BLAS_SINGLE  | BLAS_REAL;
236 #endif
237 #else
238 #ifdef XDOUBLE
239   int mode  =  BLAS_XDOUBLE | BLAS_COMPLEX;
240 #elif defined(DOUBLE)
241   int mode  =  BLAS_DOUBLE  | BLAS_COMPLEX;
242 #else
243   int mode  =  BLAS_SINGLE  | BLAS_COMPLEX;
244 #endif
245 #endif
246 #endif
247 #endif
248
249   PRINT_DEBUG_CNAME;
250
251   args.n = n;
252   args.k = k;
253
254   args.a = (void *)a;
255   args.c = (void *)c;
256
257   args.lda = lda;
258   args.ldc = ldc;
259
260 #if !defined(COMPLEX) || defined(HEMM)
261   args.alpha = (void *)&alpha;
262   args.beta  = (void *)&beta;
263 #else
264   args.alpha = (void *)alpha;
265   args.beta  = (void *)beta;
266 #endif
267
268   trans = -1;
269   uplo  = -1;
270   info  =  0;
271
272   if (order == CblasColMajor) {
273     if (Uplo == CblasUpper) uplo  = 0;
274     if (Uplo == CblasLower) uplo  = 1;
275
276     if (Trans == CblasNoTrans)     trans = 0;
277 #ifndef COMPLEX
278     if (Trans == CblasTrans)       trans = 1;
279     if (Trans == CblasConjNoTrans) trans = 0;
280     if (Trans == CblasConjTrans)   trans = 1;
281 #elif !defined(HEMM)
282     if (Trans == CblasTrans)       trans = 1;
283 #else
284     if (Trans == CblasConjTrans)   trans = 1;
285 #endif
286
287     info = -1;
288
289     nrowa = args.n;
290     if (trans & 1) nrowa = args.k;
291
292     if (args.ldc < MAX(1,args.n)) info = 10;
293     if (args.lda < MAX(1,nrowa))  info =  7;
294     if (args.k < 0)               info =  4;
295     if (args.n < 0)               info =  3;
296     if (trans < 0)                info =  2;
297     if (uplo  < 0)                info =  1;
298   }
299
300   if (order == CblasRowMajor) {
301     if (Uplo == CblasUpper) uplo  = 1;
302     if (Uplo == CblasLower) uplo  = 0;
303
304     if (Trans == CblasNoTrans)     trans = 1;
305 #ifndef COMPLEX
306     if (Trans == CblasTrans)       trans = 0;
307     if (Trans == CblasConjNoTrans) trans = 1;
308     if (Trans == CblasConjTrans)   trans = 0;
309 #elif !defined(HEMM)
310     if (Trans == CblasTrans)       trans = 0;
311 #else
312     if (Trans == CblasConjTrans)   trans = 0;
313 #endif
314
315     info = -1;
316
317     nrowa = args.n;
318     if (trans & 1) nrowa = args.k;
319
320     if (args.ldc < MAX(1,args.n)) info = 10;
321     if (args.lda < MAX(1,nrowa))  info =  7;
322     if (args.k < 0)               info =  4;
323     if (args.n < 0)               info =  3;
324     if (trans < 0)                info =  2;
325     if (uplo  < 0)                info =  1;
326   }
327
328   if (info >= 0) {
329     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
330     return;
331   }
332
333 #endif
334
335   if (args.n == 0) return;
336
337   IDEBUG_START;
338
339   FUNCTION_PROFILE_START();
340
341   buffer = (FLOAT *)blas_memory_alloc(0);
342
343   sa = (FLOAT *)((BLASLONG)buffer + GEMM_OFFSET_A);
344   sb = (FLOAT *)(((BLASLONG)sa + ((GEMM_P * GEMM_Q * COMPSIZE * SIZE + GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B);
345
346 #ifdef SMP
347 #ifdef USE_SIMPLE_THREADED_LEVEL3
348   if (!trans){
349     mode |= (BLAS_TRANSA_N | BLAS_TRANSB_T);
350   } else {
351     mode |= (BLAS_TRANSA_T | BLAS_TRANSB_N);
352   }
353   mode |= (uplo  << BLAS_UPLO_SHIFT);
354 #endif
355
356   args.common = NULL;
357   args.nthreads = num_cpu_avail(3);
358
359   if (args.nthreads == 1) {
360 #endif
361
362     (syrk[(uplo << 1) | trans ])(&args, NULL, NULL, sa, sb, 0);
363
364 #ifdef SMP
365
366   } else {
367
368 #ifndef USE_SIMPLE_THREADED_LEVEL3
369
370     (syrk[4 | (uplo << 1) | trans ])(&args, NULL, NULL, sa, sb, 0);
371
372 #else
373
374     syrk_thread(mode, &args, NULL, NULL, syrk[(uplo << 1) | trans ], sa, sb, args.nthreads);
375
376 #endif
377
378   }
379 #endif
380
381  blas_memory_free(buffer);
382
383   FUNCTION_PROFILE_END(COMPSIZE * COMPSIZE, args.n * args.k + args.n * args.n / 2, args.n * args.n * args.k);
384
385   IDEBUG_END;
386
387   return;
388 }