Add CPUID identification of Intel Ice Lake
[platform/upstream/openblas.git] / interface / gbmv.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 "common.h"
41 #ifdef FUNCTION_PROFILE
42 #include "functable.h"
43 #endif
44
45 #ifdef XDOUBLE
46 #define ERROR_NAME "QGBMV "
47 #elif defined(DOUBLE)
48 #define ERROR_NAME "DGBMV "
49 #else
50 #define ERROR_NAME "SGBMV "
51 #endif
52
53 static void (*gbmv[])(BLASLONG, BLASLONG, BLASLONG, BLASLONG, FLOAT,
54                       FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, void *) = {
55 #ifdef XDOUBLE
56       qgbmv_n, qgbmv_t,
57 #elif defined(DOUBLE)
58       dgbmv_n, dgbmv_t,
59 #else
60       sgbmv_n, sgbmv_t,
61 #endif
62 };
63
64 #ifdef SMP
65 static int (*gbmv_thread[])(BLASLONG, BLASLONG, BLASLONG, BLASLONG, FLOAT,
66                       FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, int) = {
67 #ifdef XDOUBLE
68       qgbmv_thread_n, qgbmv_thread_t,
69 #elif defined(DOUBLE)
70       dgbmv_thread_n, dgbmv_thread_t,
71 #else
72       sgbmv_thread_n, sgbmv_thread_t,
73 #endif
74 };
75 #endif
76
77 #ifndef CBLAS
78
79 void NAME(char *TRANS, blasint *M, blasint *N,
80          blasint *KU, blasint *KL,
81          FLOAT *ALPHA, FLOAT *a, blasint *LDA,
82          FLOAT *x, blasint *INCX,
83          FLOAT *BETA, FLOAT *y, blasint *INCY){
84
85   char trans = *TRANS;
86   blasint m = *M;
87   blasint n = *N;
88   blasint ku = *KU;
89   blasint kl = *KL;
90   blasint lda = *LDA;
91   blasint incx = *INCX;
92   blasint incy = *INCY;
93   FLOAT *buffer;
94 #ifdef SMP
95   int nthreads;
96 #endif
97
98   FLOAT alpha = *ALPHA;
99   FLOAT beta  = *BETA;
100
101   blasint info;
102   blasint lenx, leny;
103   blasint i;
104
105   PRINT_DEBUG_NAME;
106
107   TOUPPER(trans);
108
109   info = 0;
110
111   i = -1;
112
113   if (trans == 'N') i = 0;
114   if (trans == 'T') i = 1;
115   if (trans == 'R') i = 0;
116   if (trans == 'C') i = 1;
117
118   if (incy == 0)         info = 13;
119   if (incx == 0)         info = 10;
120   if (lda < kl + ku + 1) info = 8;
121   if (kl < 0)            info = 5;
122   if (ku < 0)            info = 4;
123   if (n < 0)             info = 3;
124   if (m < 0)             info = 2;
125   if (i < 0)             info = 1;
126
127   trans = i;
128
129   if (info != 0){
130     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
131     return;
132   }
133
134 #else
135
136 void CNAME(enum CBLAS_ORDER order,
137            enum CBLAS_TRANSPOSE TransA,
138            blasint m, blasint n,
139            blasint ku, blasint kl,
140            FLOAT alpha,
141            FLOAT  *a, blasint lda,
142            FLOAT  *x, blasint incx,
143            FLOAT beta,
144            FLOAT  *y, blasint incy){
145
146   FLOAT *buffer;
147   blasint lenx, leny, info, t;
148   int trans;
149 #ifdef SMP
150   int nthreads;
151 #endif
152
153   PRINT_DEBUG_CNAME;
154
155   trans = -1;
156   info  =  0;
157
158   if (order == CblasColMajor) {
159     if (TransA == CblasNoTrans)     trans = 0;
160     if (TransA == CblasTrans)       trans = 1;
161     if (TransA == CblasConjNoTrans) trans = 0;
162     if (TransA == CblasConjTrans)   trans = 1;
163
164     info = -1;
165
166     if (incy == 0)       info = 13;
167     if (incx == 0)       info = 10;
168     if (lda < kl + ku + 1) info = 8;
169     if (kl < 0)          info = 5;
170     if (ku < 0)          info = 4;
171     if (n < 0)           info = 3;
172     if (m < 0)           info = 2;
173     if (trans < 0)       info = 1;
174   }
175
176   if (order == CblasRowMajor) {
177     if (TransA == CblasNoTrans)     trans = 1;
178     if (TransA == CblasTrans)       trans = 0;
179     if (TransA == CblasConjNoTrans) trans = 1;
180     if (TransA == CblasConjTrans)   trans = 0;
181
182     info = -1;
183
184     t = n;
185     n = m;
186     m = t;
187
188     t  = ku;
189     ku = kl;
190     kl = t;
191
192     if (incy == 0)       info = 13;
193     if (incx == 0)       info = 10;
194     if (lda < kl + ku + 1) info = 8;
195     if (kl < 0)          info = 5;
196     if (ku < 0)          info = 4;
197     if (n < 0)           info = 3;
198     if (m < 0)           info = 2;
199     if (trans < 0)       info = 1;
200   }
201
202   if (info >= 0) {
203     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
204     return;
205   }
206
207 #endif
208
209   if ((m==0) || (n==0)) return;
210
211   lenx = n;
212   leny = m;
213   if (trans) lenx = m;
214   if (trans) leny = n;
215
216   if (beta != ONE) SCAL_K(leny, 0, 0, beta, y, blasabs(incy), NULL, 0, NULL, 0);
217
218   if (alpha == ZERO) return;
219
220   IDEBUG_START;
221
222   FUNCTION_PROFILE_START();
223
224   if (incx < 0) x -= (lenx-1)*incx;
225   if (incy < 0) y -= (leny-1)*incy;
226
227   buffer = (FLOAT *)blas_memory_alloc(1);
228
229 #ifdef SMP
230   nthreads = num_cpu_avail(2);
231
232   if (nthreads == 1) {
233 #endif
234
235   (gbmv[(int)trans])(m, n, kl, ku, alpha, a, lda, x, incx, y, incy, buffer);
236
237 #ifdef SMP
238   } else {
239
240     (gbmv_thread[(int)trans])(m, n, kl, ku, alpha, a, lda, x, incx, y, incy, buffer, nthreads);
241
242   }
243 #endif
244
245   blas_memory_free(buffer);
246
247   FUNCTION_PROFILE_END(1, m * n / 2 + n, m * n);
248
249   IDEBUG_END;
250
251   return;
252 }