]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - dense-linear-algebra-libraries/linalg.git/blob - blis/frame/2/hemv/bli_hemv_unf_var3a.c
Consolidate all git repos of linalg into one.
[dense-linear-algebra-libraries/linalg.git] / blis / frame / 2 / hemv / bli_hemv_unf_var3a.c
1 /*
3    BLIS    
4    An object-based framework for developing high-performance BLAS-like
5    libraries.
7    Copyright (C) 2014, The University of Texas at Austin
9    Redistribution and use in source and binary forms, with or without
10    modification, are permitted provided that the following conditions are
11    met:
12     - Redistributions of source code must retain the above copyright
13       notice, this list of conditions and the following disclaimer.
14     - Redistributions in binary form must reproduce the above copyright
15       notice, this list of conditions and the following disclaimer in the
16       documentation and/or other materials provided with the distribution.
17     - Neither the name of The University of Texas at Austin nor the names
18       of its contributors may be used to endorse or promote products
19       derived from this software without specific prior written permission.
21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
35 #include "blis.h"
37 #define FUNCPTR_T hemv_fp
39 typedef void (*FUNCPTR_T)(
40                            uplo_t  uplo,
41                            conj_t  conja,
42                            conj_t  conjx,
43                            conj_t  conjh,
44                            dim_t   m,
45                            void*   alpha,
46                            void*   a, inc_t rs_a, inc_t cs_a,
47                            void*   x, inc_t incx,
48                            void*   beta,
49                            void*   y, inc_t incy
50                          );
52 // If some mixed datatype functions will not be compiled, we initialize
53 // the corresponding elements of the function array to NULL.
54 #ifdef BLIS_ENABLE_MIXED_PRECISION_SUPPORT
55 static FUNCPTR_T GENARRAY3_ALL(ftypes,hemv_unf_var3a);
56 #else
57 #ifdef BLIS_ENABLE_MIXED_DOMAIN_SUPPORT
58 static FUNCPTR_T GENARRAY3_EXT(ftypes,hemv_unf_var3a);
59 #else
60 static FUNCPTR_T GENARRAY3_MIN(ftypes,hemv_unf_var3a);
61 #endif
62 #endif
65 void bli_hemv_unf_var3a( conj_t  conjh,
66                          obj_t*  alpha,
67                          obj_t*  a,
68                          obj_t*  x,
69                          obj_t*  beta,
70                          obj_t*  y,
71                          hemv_t* cntl )
72 {
73         num_t     dt_a      = bli_obj_datatype( *a );
74         num_t     dt_x      = bli_obj_datatype( *x );
75         num_t     dt_y      = bli_obj_datatype( *y );
77         uplo_t    uplo      = bli_obj_uplo( *a );
78         conj_t    conja     = bli_obj_conj_status( *a );
79         conj_t    conjx     = bli_obj_conj_status( *x );
81         dim_t     m         = bli_obj_length( *a );
83         void*     buf_a     = bli_obj_buffer_at_off( *a );
84         inc_t     rs_a      = bli_obj_row_stride( *a );
85         inc_t     cs_a      = bli_obj_col_stride( *a );
87         void*     buf_x     = bli_obj_buffer_at_off( *x );
88         inc_t     incx      = bli_obj_vector_inc( *x );
90         void*     buf_y     = bli_obj_buffer_at_off( *y );
91         inc_t     incy      = bli_obj_vector_inc( *y );
93         num_t     dt_alpha;
94         void*     buf_alpha;
96         num_t     dt_beta;
97         void*     buf_beta;
99         FUNCPTR_T f;
101         // The datatype of alpha MUST be the type union of a and x. This is to
102         // prevent any unnecessary loss of information during computation.
103         dt_alpha  = bli_datatype_union( dt_a, dt_x );
104         buf_alpha = bli_obj_buffer_for_1x1( dt_alpha, *alpha );
106         // The datatype of beta MUST be the same as the datatype of y.
107         dt_beta   = dt_y;
108         buf_beta  = bli_obj_buffer_for_1x1( dt_beta, *beta );
110 #if 0
111         obj_t x_copy, y_copy;
113         bli_obj_create( dt_x, m, 1, 0, 0, &x_copy );
114         bli_obj_create( dt_y, m, 1, 0, 0, &y_copy );
115         bli_copyv( x, &x_copy );
116         bli_copyv( y, &y_copy );
117         buf_x = bli_obj_buffer_at_off( x_copy );
118         buf_y = bli_obj_buffer_at_off( y_copy );
119         incx = 1;
120         incy = 1;
121 #endif
123         // Index into the type combination array to extract the correct
124         // function pointer.
125         f = ftypes[dt_a][dt_x][dt_y];
127         // Invoke the function.
128         f( uplo,
129            conja,
130            conjx,
131            conjh,
132            m,
133            buf_alpha,
134            buf_a, rs_a, cs_a,
135            buf_x, incx,
136            buf_beta,
137            buf_y, incy );
138 #if 0
139         bli_copyv( &y_copy, y );
140         bli_obj_free( &x_copy );
141         bli_obj_free( &y_copy );
142 #endif
146 #undef  GENTFUNC3U12
147 #define GENTFUNC3U12( ctype_a, ctype_x, ctype_y, ctype_ax, cha, chx, chy, chax, varname, kername ) \
149 void PASTEMAC3(cha,chx,chy,varname)( \
150                                      uplo_t  uplo, \
151                                      conj_t  conja, \
152                                      conj_t  conjx, \
153                                      conj_t  conjh, \
154                                      dim_t   m, \
155                                      void*   alpha, \
156                                      void*   a, inc_t rs_a, inc_t cs_a, \
157                                      void*   x, inc_t incx, \
158                                      void*   beta, \
159                                      void*   y, inc_t incy  \
160                                    ) \
161 { \
162         ctype_ax* alpha_cast = alpha; \
163         ctype_y*  beta_cast  = beta; \
164         ctype_a*  a_cast     = a; \
165         ctype_x*  x_cast     = x; \
166         ctype_y*  y_cast     = y; \
167         ctype_y*  zero       = PASTEMAC(chy,0); \
168         ctype_a*  alpha11; \
169         ctype_a*  a21; \
170         ctype_x*  chi1; \
171         ctype_x*  x2; \
172         ctype_y*  psi1; \
173         ctype_y*  y2; \
174         ctype_ax  rho; \
175         ctype_x   conjx_chi1; \
176         ctype_ax  alpha_chi1; \
177         ctype_a   alpha11_temp; \
178         dim_t     i; \
179         dim_t     n_ahead; \
180         inc_t     rs_at, cs_at; \
181         conj_t    conj0, conj1; \
183         if ( bli_zero_dim1( m ) ) return; \
185         /* The algorithm will be expressed in terms of the lower triangular case;
186            the upper triangular case is supported by swapping the row and column
187            strides of A and toggling some conj parameters. */ \
188         if      ( bli_is_lower( uplo ) ) \
189         { \
190                 rs_at = rs_a; \
191                 cs_at = cs_a; \
193                 conj0 = bli_apply_conj( conjh, conja ); \
194                 conj1 = conja; \
195         } \
196         else /* if ( bli_is_upper( uplo ) ) */ \
197         { \
198                 rs_at = cs_a; \
199                 cs_at = rs_a; \
201                 conj0 = conja; \
202                 conj1 = bli_apply_conj( conjh, conja ); \
203         } \
205         /* If beta is zero, use setv. Otherwise, scale by beta. */ \
206         if ( PASTEMAC(chy,eq0)( *beta_cast ) ) \
207         { \
208                 /* y = 0; */ \
209                 PASTEMAC2(chy,chy,setv)( m, \
210                                          zero, \
211                                          y_cast, incy ); \
212         } \
213         else \
214         { \
215                 /* y = beta * y; */ \
216                 PASTEMAC2(chy,chy,scalv)( BLIS_NO_CONJUGATE, \
217                                           m, \
218                                           beta_cast, \
219                                           y_cast, incy ); \
220         } \
222         for ( i = 0; i < m; ++i ) \
223         { \
224                 n_ahead  = m - i - 1; \
225                 alpha11  = a_cast + (i  )*rs_at + (i  )*cs_at; \
226                 a21      = a_cast + (i+1)*rs_at + (i  )*cs_at; \
227                 chi1     = x_cast + (i  )*incx; \
228                 x2       = x_cast + (i+1)*incx; \
229                 psi1     = y_cast + (i  )*incy; \
230                 y2       = y_cast + (i+1)*incy; \
232                 /* For hemv, explicitly set the imaginary component of alpha11 to
233                    zero. */ \
234                 PASTEMAC2(cha,cha,copycjs)( conja, *alpha11, alpha11_temp ); \
235                 if ( bli_is_conj( conjh ) ) \
236                         PASTEMAC(cha,seti0s)( alpha11_temp ); \
238                 /* Apply conjx to chi1 and and scale by alpha. */ \
239                 PASTEMAC2(chx,chx,copycjs)( conjx, *chi1, conjx_chi1 ); \
240                 PASTEMAC3(chax,chx,chax,scal2s)( *alpha_cast, conjx_chi1, alpha_chi1 ); \
242                 /* psi1 = psi1 + alpha * alpha11 * chi1; */ \
243                 PASTEMAC3(chax,cha,chy,axpys)( alpha_chi1, alpha11_temp, *psi1 ); \
245                 /* psi1 = psi1 + alpha * a21' * x2;   (dotv) */ \
246                 /* y2   = y2   + alpha * a21 * chi1;  (axpyv) */ \
247                 PASTEMAC3(cha,chx,chy,kername)( conj0, \
248                                                 conj1, \
249                                                 conjx, \
250                                                 n_ahead, \
251                                                 &alpha_chi1, \
252                                                 a21, rs_at, \
253                                                 x2,  incx, \
254                                                 &rho, \
255                                                 y2,  incy ); \
256                 PASTEMAC3(chax,chax,chy,axpys)( *alpha_cast, rho, *psi1 ); \
257         } \
260 // Define the basic set of functions unconditionally, and then also some
261 // mixed datatype functions if requested.
262 INSERT_GENTFUNC3U12_BASIC( hemv_unf_var3a, DOTAXPYV_KERNEL )
264 #ifdef BLIS_ENABLE_MIXED_DOMAIN_SUPPORT
265 INSERT_GENTFUNC3U12_MIX_D( hemv_unf_var3a, DOTAXPYV_KERNEL )
266 #endif
268 #ifdef BLIS_ENABLE_MIXED_PRECISION_SUPPORT
269 INSERT_GENTFUNC3U12_MIX_P( hemv_unf_var3a, DOTAXPYV_KERNEL )
270 #endif