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 "QSYR2 "
31 #elif defined(DOUBLE)
32 #define ERROR_NAME "DSYR2 "
33 #else
34 #define ERROR_NAME "SSYR2 "
35 #endif
36 
37 static int (*syr2[])(BLASLONG, FLOAT, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *) = {
38 #ifdef XDOUBLE
39   qsyr2_U, qsyr2_L,
40 #elif defined(DOUBLE)
41   dsyr2_U, dsyr2_L,
42 #else
43   ssyr2_U, ssyr2_L,
44 #endif
45 };
46 
47 #ifdef SMP
48 static int (*syr2_thread[])(BLASLONG, FLOAT, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, int) = {
49 #ifdef XDOUBLE
50   qsyr2_thread_U, qsyr2_thread_L,
51 #elif defined(DOUBLE)
52   dsyr2_thread_U, dsyr2_thread_L,
53 #else
54   ssyr2_thread_U, ssyr2_thread_L,
55 #endif
56 };
57 #endif
58 
59 #ifndef CBLAS
60 
NAME(char * UPLO,blasint * N,FLOAT * ALPHA,FLOAT * x,blasint * INCX,FLOAT * y,blasint * INCY,FLOAT * a,blasint * LDA)61 void NAME(char *UPLO, blasint *N, FLOAT  *ALPHA,
62 	 FLOAT  *x, blasint *INCX, FLOAT *y, blasint *INCY, 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   blasint incy	= *INCY;
70 
71   blasint info;
72   int uplo;
73   FLOAT *buffer;
74 #ifdef SMP
75   int nthreads;
76 #endif
77 
78   PRINT_DEBUG_NAME;
79 
80   TOUPPER(uplo_arg);
81   uplo  = -1;
82 
83   if (uplo_arg  == 'U') uplo  = 0;
84   if (uplo_arg  == 'L') uplo  = 1;
85 
86   info = 0;
87 
88   if (lda  < MAX(1, n))   info =  9;
89   if (incy == 0)          info =  7;
90   if (incx == 0)          info =  5;
91   if (n < 0)              info =  2;
92   if (uplo  < 0)          info =  1;
93 
94   if (info != 0) {
95     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
96     return;
97   }
98 
99 #else
100 
101 void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo, blasint n, FLOAT alpha, FLOAT *x, blasint incx, FLOAT *y, blasint incy, FLOAT *a, blasint lda) {
102 
103   FLOAT *buffer;
104   int trans, uplo;
105   blasint info;
106 #ifdef SMP
107   int nthreads;
108 #endif
109 
110   PRINT_DEBUG_CNAME;
111 
112   trans = -1;
113   uplo  = -1;
114   info  =  0;
115 
116   if (order == CblasColMajor) {
117 
118     if (Uplo == CblasUpper) uplo  = 0;
119     if (Uplo == CblasLower) uplo  = 1;
120 
121     info = -1;
122 
123     if (lda  < MAX(1, n))   info =  9;
124     if (incy == 0)          info =  7;
125     if (incx == 0)          info =  5;
126     if (n < 0)              info =  2;
127     if (uplo  < 0)          info =  1;
128   }
129 
130   if (order == CblasRowMajor) {
131 
132     if (Uplo == CblasUpper) uplo  = 1;
133     if (Uplo == CblasLower) uplo  = 0;
134 
135     info = -1;
136 
137     if (lda  < MAX(1, n))   info =  9;
138     if (incy == 0)          info =  7;
139     if (incx == 0)          info =  5;
140     if (n < 0)              info =  2;
141     if (uplo  < 0)          info =  1;
142   }
143 
144   if (info >= 0) {
145     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
146     return;
147   }
148 
149 #endif
150 
151   if (n == 0) return;
152 
153   if (alpha == ZERO) return;
154 
155   IDEBUG_START;
156 
157   FUNCTION_PROFILE_START();
158 
159   if (incx < 0 ) x -= (n - 1) * incx;
160   if (incy < 0 ) y -= (n - 1) * incy;
161 
162   buffer = (FLOAT *)blas_memory_alloc(1);
163 
164 #ifdef SMP
165   nthreads = num_cpu_avail(2);
166 
167   if (nthreads == 1) {
168 #endif
169 
170     (syr2[uplo])(n, alpha, x, incx, y, incy, a, lda, buffer);
171 
172 #ifdef SMP
173   } else {
174 
175     (syr2_thread[uplo])(n, alpha, x, incx, y, incy, a, lda, buffer, nthreads);
176 
177   }
178 #endif
179 
180   blas_memory_free(buffer);
181 
182   FUNCTION_PROFILE_END(1, n * n / 2 + 2 * n, 2 * n * n);
183 
184   IDEBUG_END;
185 
186   return;
187 }
188