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 "XHER "
31 #elif defined(DOUBLE)
32 #define ERROR_NAME "ZHER "
33 #else
34 #define ERROR_NAME "CHER "
35 #endif
36
37 static int (*her[])(BLASLONG, FLOAT, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *) = {
38 #ifdef XDOUBLE
39 xher_U, xher_L, xher_V, xher_M,
40 #elif defined(DOUBLE)
41 zher_U, zher_L, zher_V, zher_M,
42 #else
43 cher_U, cher_L, cher_V, cher_M,
44 #endif
45 };
46
47 #ifdef SMP
48 static int (*her_thread[])(BLASLONG, FLOAT, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, int) = {
49 #ifdef XDOUBLE
50 xher_thread_U, xher_thread_L, xher_thread_V, xher_thread_M,
51 #elif defined(DOUBLE)
52 zher_thread_U, zher_thread_L, zher_thread_V, zher_thread_M,
53 #else
54 cher_thread_U, cher_thread_L, cher_thread_V, cher_thread_M,
55 #endif
56 };
57 #endif
58
59 #ifndef CBLAS
60
NAME(char * UPLO,blasint * N,FLOAT * ALPHA,FLOAT * x,blasint * INCX,FLOAT * a,blasint * LDA)61 void NAME(char *UPLO, blasint *N, FLOAT *ALPHA,
62 FLOAT *x, blasint *INCX, FLOAT *a, blasint *LDA){
63
64 char uplo_arg = *UPLO;
65 blasint n = *N;
66 FLOAT alpha = *ALPHA;
67 blasint lda = *LDA;
68 blasint incx = *INCX;
69
70 blasint info;
71 int uplo;
72 FLOAT *buffer;
73 #ifdef SMP
74 int nthreads;
75 #endif
76
77 PRINT_DEBUG_NAME;
78
79 TOUPPER(uplo_arg);
80 uplo = -1;
81
82 if (uplo_arg == 'U') uplo = 0;
83 if (uplo_arg == 'L') uplo = 1;
84
85 info = 0;
86
87 if (lda < MAX(1, n)) info = 7;
88 if (incx == 0) info = 5;
89 if (n < 0) info = 2;
90 if (uplo < 0) info = 1;
91
92 if (info != 0) {
93 BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
94 return;
95 }
96
97 #else
98
99 void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo, blasint n, FLOAT alpha, FLOAT *x, blasint incx, FLOAT *a, blasint lda) {
100
101 FLOAT *buffer;
102 int trans, uplo;
103 blasint info;
104 #ifdef SMP
105 int nthreads;
106 #endif
107
108 PRINT_DEBUG_CNAME;
109
110 trans = -1;
111 uplo = -1;
112 info = 0;
113
114 if (order == CblasColMajor) {
115
116 if (Uplo == CblasUpper) uplo = 0;
117 if (Uplo == CblasLower) uplo = 1;
118
119 info = -1;
120
121 if (lda < MAX(1, n)) info = 7;
122 if (incx == 0) info = 5;
123 if (n < 0) info = 2;
124 if (uplo < 0) info = 1;
125
126 }
127
128 if (order == CblasRowMajor) {
129
130 if (Uplo == CblasUpper) uplo = 3;
131 if (Uplo == CblasLower) uplo = 2;
132
133 info = -1;
134
135 if (lda < MAX(1, n)) info = 7;
136 if (incx == 0) info = 5;
137 if (n < 0) info = 2;
138 if (uplo < 0) info = 1;
139 }
140
141 if (info >= 0) {
142 BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
143 return;
144 }
145
146 #endif
147
148 if (n == 0) return;
149
150 if (alpha == ZERO) return;
151
152 IDEBUG_START;
153
154 FUNCTION_PROFILE_START();
155
156 if (incx < 0 ) x -= (n - 1) * incx * 2;
157
158 buffer = (FLOAT *)blas_memory_alloc(1);
159
160 #ifdef SMP
161 nthreads = num_cpu_avail(2);
162
163 if (nthreads == 1) {
164 #endif
165
166 (her[uplo])(n, alpha, x, incx, a, lda, buffer);
167
168 #ifdef SMP
169 } else {
170
171 (her_thread[uplo])(n, alpha, x, incx, a, lda, buffer, nthreads);
172
173 }
174 #endif
175
176 blas_memory_free(buffer);
177
178 FUNCTION_PROFILE_END(4, n * n / 2 + n, n * n);
179
180 IDEBUG_END;
181
182 return;
183 }
184