Merge pull request #1762 from martin-frbg/issue1710-2
[platform/upstream/openblas.git] / interface / tpmv.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 "QTPMV "
48 #elif defined(DOUBLE)
49 #define ERROR_NAME "DTPMV "
50 #else
51 #define ERROR_NAME "STPMV "
52 #endif
53
54 static int (*tpmv[])(BLASLONG, FLOAT *, FLOAT *, BLASLONG, void *) = {
55 #ifdef XDOUBLE
56   qtpmv_NUU, qtpmv_NUN, qtpmv_NLU, qtpmv_NLN,
57   qtpmv_TUU, qtpmv_TUN, qtpmv_TLU, qtpmv_TLN,
58 #elif defined(DOUBLE)
59   dtpmv_NUU, dtpmv_NUN, dtpmv_NLU, dtpmv_NLN,
60   dtpmv_TUU, dtpmv_TUN, dtpmv_TLU, dtpmv_TLN,
61 #else
62   stpmv_NUU, stpmv_NUN, stpmv_NLU, stpmv_NLN,
63   stpmv_TUU, stpmv_TUN, stpmv_TLU, stpmv_TLN,
64 #endif
65 };
66
67 #ifdef SMP
68 static int (*tpmv_thread[])(BLASLONG, FLOAT *, FLOAT *, BLASLONG, FLOAT *, int) = {
69 #ifdef XDOUBLE
70   qtpmv_thread_NUU, qtpmv_thread_NUN, qtpmv_thread_NLU, qtpmv_thread_NLN,
71   qtpmv_thread_TUU, qtpmv_thread_TUN, qtpmv_thread_TLU, qtpmv_thread_TLN,
72 #elif defined(DOUBLE)
73   dtpmv_thread_NUU, dtpmv_thread_NUN, dtpmv_thread_NLU, dtpmv_thread_NLN,
74   dtpmv_thread_TUU, dtpmv_thread_TUN, dtpmv_thread_TLU, dtpmv_thread_TLN,
75 #else
76   stpmv_thread_NUU, stpmv_thread_NUN, stpmv_thread_NLU, stpmv_thread_NLN,
77   stpmv_thread_TUU, stpmv_thread_TUN, stpmv_thread_TLU, stpmv_thread_TLN,
78 #endif
79 };
80 #endif
81
82 #ifndef CBLAS
83
84 void NAME(char *UPLO, char *TRANS, char *DIAG,
85            blasint *N, FLOAT *a, FLOAT *x, blasint *INCX){
86
87   char uplo_arg  = *UPLO;
88   char trans_arg = *TRANS;
89   char diag_arg  = *DIAG;
90
91   blasint n    = *N;
92   blasint incx = *INCX;
93
94   blasint info;
95   int uplo;
96   int unit;
97   int trans;
98   FLOAT *buffer;
99 #ifdef SMP
100   int nthreads;
101 #endif
102
103   PRINT_DEBUG_NAME;
104
105   TOUPPER(uplo_arg);
106   TOUPPER(trans_arg);
107   TOUPPER(diag_arg);
108
109   trans = -1;
110   unit  = -1;
111   uplo  = -1;
112
113   if (trans_arg == 'N') trans = 0;
114   if (trans_arg == 'T') trans = 1;
115   if (trans_arg == 'R') trans = 0;
116   if (trans_arg == 'C') trans = 1;
117
118   if (diag_arg  == 'U') unit  = 0;
119   if (diag_arg  == 'N') unit  = 1;
120
121   if (uplo_arg  == 'U') uplo  = 0;
122   if (uplo_arg  == 'L') uplo  = 1;
123
124   info = 0;
125
126   if (incx == 0)          info =  7;
127   if (n < 0)              info =  4;
128   if (unit  < 0)          info =  3;
129   if (trans < 0)          info =  2;
130   if (uplo  < 0)          info =  1;
131
132   if (info != 0) {
133     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
134     return;
135   }
136
137 #else
138 #ifndef COMPLEX
139 void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo,
140            enum CBLAS_TRANSPOSE TransA, enum CBLAS_DIAG Diag,
141            blasint n, FLOAT  *a, FLOAT  *x, blasint incx) {
142 #else
143 void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo,
144            enum CBLAS_TRANSPOSE TransA, enum CBLAS_DIAG Diag,
145            blasint n, void  *va, void  *vx, blasint incx) {
146   FLOAT *a = (FLOAT*) va;
147   FLOAT *x = (FLOAT*) vx;
148 #endif
149
150   int trans, uplo, unit;
151   blasint info;
152   FLOAT *buffer;
153 #ifdef SMP
154   int nthreads;
155 #endif
156
157   PRINT_DEBUG_CNAME;
158
159   unit  = -1;
160   uplo  = -1;
161   trans = -1;
162   info  =  0;
163
164   if (order == CblasColMajor) {
165     if (Uplo == CblasUpper)         uplo  = 0;
166     if (Uplo == CblasLower)         uplo  = 1;
167
168     if (TransA == CblasNoTrans)     trans = 0;
169     if (TransA == CblasTrans)       trans = 1;
170     if (TransA == CblasConjNoTrans) trans = 0;
171     if (TransA == CblasConjTrans)   trans = 1;
172
173     if (Diag == CblasUnit)          unit  = 0;
174     if (Diag == CblasNonUnit)       unit  = 1;
175
176     info = -1;
177
178     if (incx == 0)          info =  7;
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 =  7;
200     if (n < 0)              info =  4;
201     if (unit  < 0)          info =  3;
202     if (trans < 0)          info =  2;
203     if (uplo  < 0)          info =  1;
204   }
205
206   if (info >= 0) {
207     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
208     return;
209   }
210
211 #endif
212
213   if (n == 0) return;
214
215   IDEBUG_START;
216
217   FUNCTION_PROFILE_START();
218
219   if (incx < 0 ) x -= (n - 1) * incx;
220
221   buffer = (FLOAT *)blas_memory_alloc(1);
222
223 #ifdef SMP
224   nthreads = num_cpu_avail(2);
225
226   if (nthreads == 1) {
227 #endif
228
229   (tpmv[(trans<<2) | (uplo<<1) | unit])(n, a, x, incx, buffer);
230
231 #ifdef SMP
232   } else {
233
234     (tpmv_thread[(trans<<2) | (uplo<<1) | unit])(n, a, x, incx, buffer, nthreads);
235
236   }
237 #endif
238
239   blas_memory_free(buffer);
240
241   FUNCTION_PROFILE_END(1, n * n / 2 + n, n * n);
242
243   IDEBUG_END;
244
245   return;
246 }