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 "XSBMV "
31 #elif defined(DOUBLE)
32 #define ERROR_NAME "ZSBMV "
33 #else
34 #define ERROR_NAME "CSBMV "
35 #endif
36 
37 static  int (*sbmv[])(BLASLONG, BLASLONG, FLOAT, FLOAT, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, void *) = {
38 #ifdef XDOUBLE
39   xsbmv_U, xsbmv_L,
40 #elif defined(DOUBLE)
41   zsbmv_U, zsbmv_L,
42 #else
43   csbmv_U, csbmv_L,
44 #endif
45 };
46 
47 #ifdef SMP
48 static  int (*sbmv_thread[])(BLASLONG, BLASLONG, FLOAT *, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, BLASLONG, FLOAT *, int) = {
49 #ifdef XDOUBLE
50   xsbmv_thread_U, xsbmv_thread_L,
51 #elif defined(DOUBLE)
52   zsbmv_thread_U, zsbmv_thread_L,
53 #else
54   csbmv_thread_U, csbmv_thread_L,
55 #endif
56 };
57 #endif
58 
NAME(char * UPLO,blasint * N,blasint * K,FLOAT * ALPHA,FLOAT * a,blasint * LDA,FLOAT * b,blasint * INCX,FLOAT * BETA,FLOAT * c,blasint * INCY)59 void NAME(char *UPLO, blasint *N, blasint *K, FLOAT  *ALPHA, FLOAT *a, blasint *LDA,
60             FLOAT  *b, blasint *INCX, FLOAT *BETA, FLOAT *c, blasint *INCY){
61 
62   char uplo_arg = *UPLO;
63   blasint n	= *N;
64   blasint k	= *K;
65   FLOAT alpha_r	= ALPHA[0];
66   FLOAT alpha_i	= ALPHA[1];
67   blasint lda	= *LDA;
68   blasint incx	= *INCX;
69   FLOAT beta_r	= BETA[0];
70   FLOAT beta_i	= BETA[1];
71   blasint incy	= *INCY;
72 
73   blasint info;
74   int uplo;
75   FLOAT *buffer;
76 #ifdef SMP
77   int nthreads;
78 #endif
79 
80   PRINT_DEBUG_NAME;
81 
82   TOUPPER(uplo_arg);
83   uplo  = -1;
84 
85   if (uplo_arg  == 'U') uplo  = 0;
86   if (uplo_arg  == 'L') uplo  = 1;
87 
88   info = 0;
89 
90   if (incy == 0)          info = 11;
91   if (incx == 0)          info =  8;
92   if (lda  < k + 1)       info =  6;
93   if (k < 0)              info =  3;
94   if (n < 0)              info =  2;
95   if (uplo  < 0)          info =  1;
96 
97   if (info != 0) {
98     BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
99     return;
100   }
101 
102   if (n == 0) return;
103 
104   if ((beta_r != ONE) || (beta_i != ZERO)) SCAL_K(n, 0, 0, beta_r, beta_i, c, abs(incy), NULL, 0, NULL, 0);
105 
106   if ((alpha_r == ZERO) && (alpha_i == ZERO)) return;
107 
108   IDEBUG_START;
109 
110   FUNCTION_PROFILE_START();
111 
112   if (incx < 0 ) b -= (n - 1) * incx * COMPSIZE;
113   if (incy < 0 ) c -= (n - 1) * incy * COMPSIZE;
114 
115   buffer = (FLOAT *)blas_memory_alloc(1);
116 
117 #ifdef SMP
118   nthreads = num_cpu_avail(2);
119 
120   if (nthreads == 1) {
121 #endif
122 
123   (sbmv[uplo])(n, k, alpha_r, alpha_i, a, lda, b, incx, c, incy, buffer);
124 
125 #ifdef SMP
126   } else {
127 
128     (sbmv_thread[uplo])(n, k, ALPHA, a, lda, b, incx, c, incy, buffer, nthreads);
129 
130   }
131 #endif
132 
133   blas_memory_free(buffer);
134 
135   FUNCTION_PROFILE_END(4, n * k / 2 + n, n * k);
136 
137   IDEBUG_END;
138 
139   return;
140 }
141