Add CPUID identification of Intel Ice Lake
[platform/upstream/openblas.git] / interface / tbmv.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 #ifdef XDOUBLE
47 #define ERROR_NAME "QTBMV "
48 #elif defined(DOUBLE)
49 #define ERROR_NAME "DTBMV "
50 #else
51 #define ERROR_NAME "STBMV "
52 #endif
53
54 static int (*tbmv[])(BLASLONG, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, void *) = {
55 #ifdef XDOUBLE
56   qtbmv_NUU, qtbmv_NUN, qtbmv_NLU, qtbmv_NLN,
57   qtbmv_TUU, qtbmv_TUN, qtbmv_TLU, qtbmv_TLN,
58 #elif defined(DOUBLE)
59   dtbmv_NUU, dtbmv_NUN, dtbmv_NLU, dtbmv_NLN,
60   dtbmv_TUU, dtbmv_TUN, dtbmv_TLU, dtbmv_TLN,
61 #else
62   stbmv_NUU, stbmv_NUN, stbmv_NLU, stbmv_NLN,
63   stbmv_TUU, stbmv_TUN, stbmv_TLU, stbmv_TLN,
64 #endif
65 };
66
67 #ifdef SMP
68 static int (*tbmv_thread[])(BLASLONG, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, int) = {
69 #ifdef XDOUBLE
70   qtbmv_thread_NUU, qtbmv_thread_NUN, qtbmv_thread_NLU, qtbmv_thread_NLN,
71   qtbmv_thread_TUU, qtbmv_thread_TUN, qtbmv_thread_TLU, qtbmv_thread_TLN,
72 #elif defined(DOUBLE)
73   dtbmv_thread_NUU, dtbmv_thread_NUN, dtbmv_thread_NLU, dtbmv_thread_NLN,
74   dtbmv_thread_TUU, dtbmv_thread_TUN, dtbmv_thread_TLU, dtbmv_thread_TLN,
75 #else
76   stbmv_thread_NUU, stbmv_thread_NUN, stbmv_thread_NLU, stbmv_thread_NLN,
77   stbmv_thread_TUU, stbmv_thread_TUN, stbmv_thread_TLU, stbmv_thread_TLN,
78 #endif
79 };
80 #endif
81
82 #ifndef CBLAS
83
84 void NAME(char *UPLO, char *TRANS, char *DIAG,
85          blasint *N, blasint *K,
86          FLOAT *a, blasint *LDA, FLOAT *x, blasint *INCX){
87
88   char uplo_arg  = *UPLO;
89   char trans_arg = *TRANS;
90   char diag_arg  = *DIAG;
91
92   blasint n    = *N;
93   blasint k    = *K;
94   blasint lda  = *LDA;
95   blasint incx = *INCX;
96
97   blasint info;
98   int uplo;
99   int unit;
100   int trans;
101   FLOAT *buffer;
102 #ifdef SMP
103   int nthreads;
104 #endif
105
106   PRINT_DEBUG_NAME;
107
108   TOUPPER(uplo_arg);
109   TOUPPER(trans_arg);
110   TOUPPER(diag_arg);
111
112   trans = -1;
113   unit  = -1;
114   uplo  = -1;
115
116   if (trans_arg == 'N') trans = 0;
117   if (trans_arg == 'T') trans = 1;
118   if (trans_arg == 'R') trans = 0;
119   if (trans_arg == 'C') trans = 1;
120
121   if (diag_arg  == 'U') unit  = 0;
122   if (diag_arg  == 'N') unit  = 1;
123
124   if (uplo_arg  == 'U') uplo  = 0;
125   if (uplo_arg  == 'L') uplo  = 1;
126
127   info = 0;
128
129   if (incx == 0)          info =  9;
130   if (lda < k + 1)        info =  7;
131   if (k < 0)              info =  5;
132   if (n < 0)              info =  4;
133   if (unit  < 0)          info =  3;
134   if (trans < 0)          info =  2;
135   if (uplo  < 0)          info =  1;
136
137   if (info != 0) {
138     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
139     return;
140   }
141
142 #else
143
144 void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo,
145            enum CBLAS_TRANSPOSE TransA, enum CBLAS_DIAG Diag,
146            blasint n, blasint k, FLOAT  *a, blasint lda, FLOAT  *x, blasint incx) {
147
148   int trans, uplo, unit;
149   blasint info;
150   FLOAT *buffer;
151 #ifdef SMP
152   int nthreads;
153 #endif
154
155   PRINT_DEBUG_CNAME;
156
157   unit  = -1;
158   uplo  = -1;
159   trans = -1;
160   info  =  0;
161
162   if (order == CblasColMajor) {
163     if (Uplo == CblasUpper)         uplo  = 0;
164     if (Uplo == CblasLower)         uplo  = 1;
165
166     if (TransA == CblasNoTrans)     trans = 0;
167     if (TransA == CblasTrans)       trans = 1;
168     if (TransA == CblasConjNoTrans) trans = 0;
169     if (TransA == CblasConjTrans)   trans = 1;
170
171     if (Diag == CblasUnit)          unit  = 0;
172     if (Diag == CblasNonUnit)       unit  = 1;
173
174     info = -1;
175
176     if (incx == 0)          info =  9;
177     if (lda < k + 1)        info =  7;
178     if (k < 0)              info =  5;
179     if (n < 0)              info =  4;
180     if (unit  < 0)          info =  3;
181     if (trans < 0)          info =  2;
182     if (uplo  < 0)          info =  1;
183   }
184
185   if (order == CblasRowMajor) {
186     if (Uplo == CblasUpper)         uplo  = 1;
187     if (Uplo == CblasLower)         uplo  = 0;
188
189     if (TransA == CblasNoTrans)     trans = 1;
190     if (TransA == CblasTrans)       trans = 0;
191     if (TransA == CblasConjNoTrans) trans = 1;
192     if (TransA == CblasConjTrans)   trans = 0;
193
194     if (Diag == CblasUnit)          unit  = 0;
195     if (Diag == CblasNonUnit)       unit  = 1;
196
197     info = -1;
198
199     if (incx == 0)          info =  9;
200     if (lda < k + 1)        info =  7;
201     if (k < 0)              info =  5;
202     if (n < 0)              info =  4;
203     if (unit  < 0)          info =  3;
204     if (trans < 0)          info =  2;
205     if (uplo  < 0)          info =  1;
206   }
207
208   if (info >= 0) {
209     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
210     return;
211   }
212
213 #endif
214
215   if (n == 0) return;
216
217   IDEBUG_START;
218
219   FUNCTION_PROFILE_START();
220
221   if (incx < 0 ) x -= (n - 1) * incx;
222
223   buffer = (FLOAT *)blas_memory_alloc(1);
224
225 #ifdef SMP
226   nthreads = num_cpu_avail(2);
227
228   if (nthreads == 1) {
229 #endif
230
231   (tbmv[(trans<<2) | (uplo<<1) | unit])(n, k, a, lda, x, incx, buffer);
232
233 #ifdef SMP
234   } else {
235
236     (tbmv_thread[(trans<<2) | (uplo<<1) | unit])(n, k, a, lda, x, incx, buffer, nthreads);
237
238   }
239 #endif
240
241   blas_memory_free(buffer);
242
243   FUNCTION_PROFILE_END(1, n * k / 2 + n, n * k);
244
245   IDEBUG_END;
246
247   return;
248 }