Add CPUID identification of Intel Ice Lake
[platform/upstream/openblas.git] / interface / zgbmv.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 "XGBMV "
47 #elif defined(DOUBLE)
48 #define ERROR_NAME "ZGBMV "
49 #else
50 #define ERROR_NAME "CGBMV "
51 #endif
52
53 static void (*gbmv[])(BLASLONG, BLASLONG, BLASLONG, BLASLONG, FLOAT, FLOAT,
54                       FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, void *) = {
55 #ifdef XDOUBLE
56       xgbmv_n, xgbmv_t, xgbmv_r, xgbmv_c,
57       xgbmv_o, xgbmv_u, xgbmv_s, xgbmv_d,
58 #elif defined(DOUBLE)
59       zgbmv_n, zgbmv_t, zgbmv_r, zgbmv_c,
60       zgbmv_o, zgbmv_u, zgbmv_s, zgbmv_d,
61 #else
62       cgbmv_n, cgbmv_t, cgbmv_r, cgbmv_c,
63       cgbmv_o, cgbmv_u, cgbmv_s, cgbmv_d,
64 #endif
65 };
66
67 #ifdef SMP
68 static int (*gbmv_thread[])(BLASLONG, BLASLONG, BLASLONG, BLASLONG, FLOAT *,
69                       FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, int) = {
70 #ifdef XDOUBLE
71       xgbmv_thread_n, xgbmv_thread_t, xgbmv_thread_r, xgbmv_thread_c,
72       xgbmv_thread_o, xgbmv_thread_u, xgbmv_thread_s, xgbmv_thread_d,
73 #elif defined(DOUBLE)
74       zgbmv_thread_n, zgbmv_thread_t, zgbmv_thread_r, zgbmv_thread_c,
75       zgbmv_thread_o, zgbmv_thread_u, zgbmv_thread_s, zgbmv_thread_d,
76 #else
77       cgbmv_thread_n, cgbmv_thread_t, cgbmv_thread_r, cgbmv_thread_c,
78       cgbmv_thread_o, cgbmv_thread_u, cgbmv_thread_s, cgbmv_thread_d,
79 #endif
80 };
81 #endif
82
83 #ifndef CBLAS
84
85 void NAME(char *TRANS, blasint *M, blasint *N,
86          blasint *KU, blasint *KL,
87          FLOAT *ALPHA, FLOAT *a, blasint *LDA,
88          FLOAT *x, blasint *INCX,
89          FLOAT *BETA, FLOAT *y, blasint *INCY){
90
91   char trans = *TRANS;
92   blasint m = *M;
93   blasint n = *N;
94   blasint ku = *KU;
95   blasint kl = *KL;
96   blasint lda = *LDA;
97   blasint incx = *INCX;
98   blasint incy = *INCY;
99   FLOAT *buffer;
100 #ifdef SMP
101   int nthreads;
102 #endif
103
104   FLOAT alpha_r = ALPHA[0];
105   FLOAT alpha_i = ALPHA[1];
106   FLOAT beta_r  = BETA[0];
107   FLOAT beta_i  = BETA[1];
108
109   blasint info;
110   blasint lenx, leny;
111   blasint i;
112
113   PRINT_DEBUG_NAME;
114
115   TOUPPER(trans);
116
117   info = 0;
118
119   i = -1;
120
121   if (trans == 'N')  i = 0;
122   if (trans == 'T')  i = 1;
123   if (trans == 'R')  i = 2;
124   if (trans == 'C')  i = 3;
125   if (trans == 'O')  i = 4;
126   if (trans == 'U')  i = 5;
127   if (trans == 'S')  i = 6;
128   if (trans == 'D')  i = 7;
129
130   if (incy == 0)         info = 13;
131   if (incx == 0)         info = 10;
132   if (lda < kl + ku + 1) info = 8;
133   if (kl < 0)            info = 5;
134   if (ku < 0)            info = 4;
135   if (n < 0)             info = 3;
136   if (m < 0)             info = 2;
137   if (i < 0)             info = 1;
138
139   trans = i;
140
141   if (info != 0){
142     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
143     return;
144   }
145
146 #else
147
148 void CNAME(enum CBLAS_ORDER order,
149            enum CBLAS_TRANSPOSE TransA,
150            blasint m, blasint n,
151            blasint ku, blasint kl,
152            void *VALPHA,
153            void  *va, blasint lda,
154            void  *vx, blasint incx,
155            void *VBETA,
156            void  *vy, blasint incy){
157
158   FLOAT* ALPHA = (FLOAT*) VALPHA;
159   FLOAT* BETA = (FLOAT*) VBETA;
160   FLOAT* a = (FLOAT*) va;
161   FLOAT* x = (FLOAT*) vx;
162   FLOAT* y = (FLOAT*) vy;
163
164   FLOAT alpha_r = ALPHA[0];
165   FLOAT alpha_i = ALPHA[1];
166   FLOAT beta_r  = BETA[0];
167   FLOAT beta_i  = BETA[1];
168
169   FLOAT *buffer;
170   blasint lenx, leny;
171   int trans;
172   blasint info, t;
173 #ifdef SMP
174   int nthreads;
175 #endif
176
177   PRINT_DEBUG_CNAME;
178
179   trans = -1;
180   info  =  0;
181
182   if (order == CblasColMajor) {
183     if (TransA == CblasNoTrans)     trans = 0;
184     if (TransA == CblasTrans)       trans = 1;
185     if (TransA == CblasConjNoTrans) trans = 2;
186     if (TransA == CblasConjTrans)   trans = 3;
187
188     info = -1;
189
190     if (incy == 0)       info = 13;
191     if (incx == 0)       info = 10;
192     if (lda < kl + ku + 1) info = 8;
193     if (kl < 0)          info = 5;
194     if (ku < 0)          info = 4;
195     if (n < 0)           info = 3;
196     if (m < 0)           info = 2;
197     if (trans < 0)       info = 1;
198   }
199
200   if (order == CblasRowMajor) {
201     if (TransA == CblasNoTrans)     trans = 1;
202     if (TransA == CblasTrans)       trans = 0;
203     if (TransA == CblasConjNoTrans) trans = 3;
204     if (TransA == CblasConjTrans)   trans = 2;
205
206     info = -1;
207
208     t = n;
209     n = m;
210     m = t;
211
212     t  = ku;
213     ku = kl;
214     kl = t;
215
216     if (incy == 0)       info = 13;
217     if (incx == 0)       info = 10;
218     if (lda < kl + ku + 1) info = 8;
219     if (kl < 0)          info = 5;
220     if (ku < 0)          info = 4;
221     if (n < 0)           info = 3;
222     if (m < 0)           info = 2;
223     if (trans < 0)       info = 1;
224   }
225
226   if (info >= 0) {
227     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
228     return;
229   }
230
231 #endif
232
233   if ((m==0) || (n==0)) return;
234
235   lenx = n;
236   leny = m;
237   if (trans & 1) lenx = m;
238   if (trans & 1) leny = n;
239
240   if (beta_r != ONE || beta_i != ZERO) SCAL_K(leny, 0, 0, beta_r, beta_i, y, blasabs(incy), NULL, 0, NULL, 0);
241
242   if (alpha_r == ZERO && alpha_i == ZERO) return;
243
244   IDEBUG_START;
245
246   FUNCTION_PROFILE_START();
247
248   if (incx < 0) x -= (lenx - 1) * incx * 2;
249   if (incy < 0) y -= (leny - 1) * incy * 2;
250
251   buffer = (FLOAT *)blas_memory_alloc(1);
252
253 #ifdef SMP
254   nthreads = num_cpu_avail(2);
255
256   if (nthreads == 1) {
257 #endif
258
259   (gbmv[(int)trans])(m, n, kl, ku, alpha_r, alpha_i, a, lda, x, incx, y, incy, buffer);
260
261 #ifdef SMP
262
263   } else {
264
265     (gbmv_thread[(int)trans])(m, n, kl, ku, ALPHA, a, lda, x, incx, y, incy, buffer, nthreads);
266
267   }
268 #endif
269
270   blas_memory_free(buffer);
271
272   FUNCTION_PROFILE_END(4, m * n / 2 + n, m * n);
273
274   IDEBUG_END;
275
276   return;
277 }