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