1 /*********************************************************************/
2 /*                                                                   */
3 /*             Optimized BLAS libraries                              */
4 /*                     By Kazushige Goto <kgoto@tacc.utexas.edu>     */
5 /*                                                                   */
6 /* Copyright (c) The University of Texas, 2009. All rights reserved. */
7 /* UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING  */
8 /* THIS SOFTWARE AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF      */
9 /* MERCHANTABILITY, FITNESS FOR ANY PARTICULAR PURPOSE,              */
10 /* NON-INFRINGEMENT AND WARRANTIES OF PERFORMANCE, AND ANY WARRANTY  */
11 /* THAT MIGHT OTHERWISE ARISE FROM COURSE OF DEALING OR USAGE OF     */
12 /* TRADE. NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH RESPECT TO   */
13 /* THE USE OF THE SOFTWARE OR DOCUMENTATION.                         */
14 /* Under no circumstances shall University be liable for incidental, */
15 /* special, indirect, direct or consequential damages or loss of     */
16 /* profits, interruption of business, or related expenses which may  */
17 /* arise from use of Software or Documentation, including but not    */
18 /* limited to those resulting from defects in Software and/or        */
19 /* Documentation, or loss or inaccuracy of data of any kind.         */
20 /*********************************************************************/
21 
22 #include <stdio.h>
23 #include <ctype.h>
24 #include "common.h"
25 #ifdef FUNCTION_PROFILE
26 #include "functable.h"
27 #endif
28 
29 #ifdef XDOUBLE
30 #define ERROR_NAME "XHEMV "
31 #elif defined(DOUBLE)
32 #define ERROR_NAME "ZHEMV "
33 #else
34 #define ERROR_NAME "CHEMV "
35 #endif
36 
37 #ifndef CBLAS
38 
NAME(char * UPLO,blasint * N,FLOAT * ALPHA,FLOAT * a,blasint * LDA,FLOAT * x,blasint * INCX,FLOAT * BETA,FLOAT * y,blasint * INCY)39 void NAME(char *UPLO, blasint *N, FLOAT  *ALPHA, FLOAT *a, blasint *LDA,
40             FLOAT  *x, blasint *INCX, FLOAT *BETA, FLOAT *y, blasint *INCY){
41 
42   char uplo_arg = *UPLO;
43   blasint n		= *N;
44   FLOAT alpha_r	= ALPHA[0];
45   FLOAT alpha_i	= ALPHA[1];
46   blasint lda	= *LDA;
47   blasint incx	= *INCX;
48   FLOAT beta_r	= BETA[0];
49   FLOAT beta_i	= BETA[1];
50   blasint incy	= *INCY;
51 #ifdef SMP
52   int nthreads;
53 #endif
54 
55   int (*hemv[])(BLASLONG, BLASLONG, FLOAT, FLOAT, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *) = {
56     HEMV_U, HEMV_L, HEMV_V, HEMV_M,
57   };
58 
59 #ifdef SMP
60   int (*hemv_thread[])(BLASLONG, FLOAT *, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, int) = {
61     HEMV_THREAD_U, HEMV_THREAD_L, HEMV_THREAD_V, HEMV_THREAD_M,
62   };
63 #endif
64 
65   blasint info;
66   int uplo;
67   FLOAT *buffer;
68 
69   PRINT_DEBUG_NAME;
70 
71   TOUPPER(uplo_arg);
72   uplo  = -1;
73 
74   if (uplo_arg  == 'U') uplo  = 0;
75   if (uplo_arg  == 'L') uplo  = 1;
76   if (uplo_arg  == 'V') uplo  = 2;
77   if (uplo_arg  == 'M') uplo  = 3;
78 
79   info = 0;
80 
81   if (incy == 0)          info = 10;
82   if (incx == 0)          info =  7;
83   if (lda  < MAX(1, n))   info =  5;
84   if (n < 0)              info =  2;
85   if (uplo  < 0)          info =  1;
86 
87   if (info != 0) {
88     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
89     return;
90   }
91 
92 #else
93 
94 void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo, blasint n, FLOAT *ALPHA,
95 	   FLOAT *a, blasint lda, FLOAT *x, blasint incx, FLOAT *BETA, FLOAT *y, blasint incy) {
96 
97   FLOAT alpha_r	= ALPHA[0];
98   FLOAT alpha_i	= ALPHA[1];
99   FLOAT beta_r	= BETA[0];
100   FLOAT beta_i	= BETA[1];
101 
102   FLOAT *buffer;
103   int trans, uplo;
104   blasint info;
105 #ifdef SMP
106   int nthreads;
107 #endif
108 
109   int (*hemv[])(BLASLONG, BLASLONG, FLOAT, FLOAT, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *) = {
110     HEMV_U, HEMV_L, HEMV_V, HEMV_M,
111   };
112 
113 #ifdef SMP
114   int (*hemv_thread[])(BLASLONG, FLOAT *, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, int) = {
115     HEMV_THREAD_U, HEMV_THREAD_L, HEMV_THREAD_V, HEMV_THREAD_M,
116   };
117 #endif
118 
119   PRINT_DEBUG_CNAME;
120 
121   trans = -1;
122   uplo  = -1;
123   info  =  0;
124 
125   if (order == CblasColMajor) {
126 
127     if (Uplo == CblasUpper) uplo  = 0;
128     if (Uplo == CblasLower) uplo  = 1;
129 
130     info = -1;
131 
132     if (incy == 0)          info = 10;
133     if (incx == 0)          info =  7;
134     if (lda  < MAX(1, n))   info =  5;
135     if (n < 0)              info =  2;
136     if (uplo  < 0)          info =  1;
137   }
138 
139   if (order == CblasRowMajor) {
140 
141     if (Uplo == CblasUpper) uplo  = 3;
142     if (Uplo == CblasLower) uplo  = 2;
143 
144     info = -1;
145 
146     if (incy == 0)          info = 10;
147     if (incx == 0)          info =  7;
148     if (lda  < MAX(1, n))   info =  5;
149     if (n < 0)              info =  2;
150     if (uplo  < 0)          info =  1;
151   }
152 
153   if (info >= 0) {
154     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
155     return;
156   }
157 
158 #endif
159 
160   if (n == 0) return;
161 
162   if ((beta_r != ONE) || (beta_i != ZERO)) SCAL_K(n, 0, 0, beta_r, beta_i, y, abs(incy), NULL, 0, NULL, 0);
163 
164   if ((alpha_r == ZERO) && (alpha_i == ZERO)) return;
165 
166   IDEBUG_START;
167 
168   FUNCTION_PROFILE_START();
169 
170   if (incx < 0 ) x -= (n - 1) * incx * 2;
171   if (incy < 0 ) y -= (n - 1) * incy * 2;
172 
173   buffer = (FLOAT *)blas_memory_alloc(1);
174 
175 #ifdef SMP
176   nthreads = num_cpu_avail(2);
177 
178   if (nthreads == 1) {
179 #endif
180 
181   (hemv[uplo])(n, n, alpha_r, alpha_i, a, lda, x, incx, y, incy, buffer);
182 
183 #ifdef SMP
184   } else {
185 
186     (hemv_thread[uplo])(n, ALPHA, a, lda, x, incx, y, incy, buffer, nthreads);
187 
188   }
189 #endif
190 
191   blas_memory_free(buffer);
192 
193   FUNCTION_PROFILE_END(4, n * n / 2 + n, 2 * n * n);
194 
195   IDEBUG_END;
196 
197   return;
198 }
199