1 /* =========================================================================
2    Copyright (c) 2010-2014, Institute for Microelectronics,
3                             Institute for Analysis and Scientific Computing,
4                             TU Wien.
5    Portions of this software are copyright by UChicago Argonne, LLC.
6 
7                             -----------------
8                   ViennaCL - The Vienna Computing Library
9                             -----------------
10 
11    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
12 
13    (A list of authors and contributors can be found in the PDF manual)
14 
15    License:         MIT (X11), see file LICENSE in the base directory
16 ============================================================================= */
17 
18 // include necessary system headers
19 #include <iostream>
20 
21 #include "viennacl.hpp"
22 #include "viennacl_private.hpp"
23 
24 //include basic scalar and vector types of ViennaCL
25 #include "viennacl/scalar.hpp"
26 #include "viennacl/vector.hpp"
27 
28 //include the generic inner product functions of ViennaCL
29 #include "viennacl/linalg/inner_prod.hpp"
30 
31 //include the generic norm functions of ViennaCL
32 #include "viennacl/linalg/norm_1.hpp"
33 #include "viennacl/linalg/norm_2.hpp"
34 #include "viennacl/linalg/norm_inf.hpp"
35 
36 #ifdef VIENNACL_WITH_OPENCL
37 
38 // IxAMAX
39 
ViennaCLOpenCLiSamax(ViennaCLBackend backend,ViennaCLInt n,ViennaCLInt * index,cl_mem x,ViennaCLInt offx,ViennaCLInt incx)40 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLiSamax(ViennaCLBackend backend, ViennaCLInt n,
41                                                                ViennaCLInt *index,
42                                                                cl_mem x, ViennaCLInt offx, ViennaCLInt incx)
43 {
44   typedef viennacl::vector_base<float>::size_type           size_type;
45   typedef viennacl::vector_base<float>::size_type           difference_type;
46   viennacl::vector_base<float> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
47 
48   *index = static_cast<ViennaCLInt>(viennacl::linalg::index_norm_inf(v1));
49   return ViennaCLSuccess;
50 }
51 
ViennaCLOpenCLiDamax(ViennaCLBackend backend,ViennaCLInt n,ViennaCLInt * index,cl_mem x,ViennaCLInt offx,ViennaCLInt incx)52 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLiDamax(ViennaCLBackend backend, ViennaCLInt n,
53                                                                ViennaCLInt *index,
54                                                                cl_mem x, ViennaCLInt offx, ViennaCLInt incx)
55 {
56   typedef viennacl::vector_base<double>::size_type           size_type;
57   typedef viennacl::vector_base<double>::size_type           difference_type;
58   viennacl::vector_base<double> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
59 
60   *index = static_cast<ViennaCLInt>(viennacl::linalg::index_norm_inf(v1));
61   return ViennaCLSuccess;
62 }
63 
64 
65 
66 
67 // xASUM
68 
ViennaCLOpenCLSasum(ViennaCLBackend backend,ViennaCLInt n,float * alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx)69 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLSasum(ViennaCLBackend backend, ViennaCLInt n,
70                                                               float *alpha,
71                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx)
72 {
73   typedef viennacl::vector_base<float>::size_type           size_type;
74   typedef viennacl::vector_base<float>::size_type           difference_type;
75   viennacl::vector_base<float> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
76 
77   *alpha = viennacl::linalg::norm_1(v1);
78   return ViennaCLSuccess;
79 }
80 
ViennaCLOpenCLDasum(ViennaCLBackend backend,ViennaCLInt n,double * alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx)81 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLDasum(ViennaCLBackend backend, ViennaCLInt n,
82                                                               double *alpha,
83                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx)
84 {
85   typedef viennacl::vector_base<double>::size_type           size_type;
86   typedef viennacl::vector_base<double>::size_type           difference_type;
87   viennacl::vector_base<double> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
88 
89   *alpha = viennacl::linalg::norm_1(v1);
90   return ViennaCLSuccess;
91 }
92 
93 
94 
95 // xAXPY
96 
ViennaCLOpenCLSaxpy(ViennaCLBackend backend,ViennaCLInt n,float alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy)97 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLSaxpy(ViennaCLBackend backend, ViennaCLInt n,
98                                                               float alpha,
99                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
100                                                               cl_mem y, ViennaCLInt offy, ViennaCLInt incy)
101 {
102   typedef viennacl::vector_base<float>::size_type           size_type;
103   typedef viennacl::vector_base<float>::size_type           difference_type;
104   viennacl::vector_base<float> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
105   viennacl::vector_base<float> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
106 
107   v2 += alpha * v1;
108   return ViennaCLSuccess;
109 }
110 
ViennaCLOpenCLDaxpy(ViennaCLBackend backend,ViennaCLInt n,double alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy)111 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLDaxpy(ViennaCLBackend backend, ViennaCLInt n,
112                                                               double alpha,
113                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
114                                                               cl_mem y, ViennaCLInt offy, ViennaCLInt incy)
115 {
116   typedef viennacl::vector_base<double>::size_type           size_type;
117   typedef viennacl::vector_base<double>::size_type           difference_type;
118   viennacl::vector_base<double> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
119   viennacl::vector_base<double> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
120 
121   v2 += alpha * v1;
122   return ViennaCLSuccess;
123 }
124 
125 
126 // xCOPY
127 
ViennaCLOpenCLScopy(ViennaCLBackend backend,ViennaCLInt n,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy)128 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLScopy(ViennaCLBackend backend, ViennaCLInt n,
129                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
130                                                               cl_mem y, ViennaCLInt offy, ViennaCLInt incy)
131 {
132   typedef viennacl::vector_base<float>::size_type           size_type;
133   typedef viennacl::vector_base<float>::size_type           difference_type;
134   viennacl::vector_base<float> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
135   viennacl::vector_base<float> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
136 
137   v2 = v1;
138   return ViennaCLSuccess;
139 }
140 
ViennaCLOpenCLDcopy(ViennaCLBackend backend,ViennaCLInt n,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy)141 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLDcopy(ViennaCLBackend backend, ViennaCLInt n,
142                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
143                                                               cl_mem y, ViennaCLInt offy, ViennaCLInt incy)
144 {
145   typedef viennacl::vector_base<double>::size_type           size_type;
146   typedef viennacl::vector_base<double>::size_type           difference_type;
147   viennacl::vector_base<double> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
148   viennacl::vector_base<double> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
149 
150   v2 = v1;
151   return ViennaCLSuccess;
152 }
153 
154 // xDOT
155 
ViennaCLOpenCLSdot(ViennaCLBackend backend,ViennaCLInt n,float * alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy)156 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLSdot(ViennaCLBackend backend, ViennaCLInt n,
157                                                              float *alpha,
158                                                              cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
159                                                              cl_mem y, ViennaCLInt offy, ViennaCLInt incy)
160 {
161   typedef viennacl::vector_base<float>::size_type           size_type;
162   typedef viennacl::vector_base<float>::size_type           difference_type;
163   viennacl::vector_base<float> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
164   viennacl::vector_base<float> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
165 
166   *alpha = viennacl::linalg::inner_prod(v1, v2);
167   return ViennaCLSuccess;
168 }
169 
ViennaCLOpenCLDdot(ViennaCLBackend backend,ViennaCLInt n,double * alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy)170 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLDdot(ViennaCLBackend backend, ViennaCLInt n,
171                                                              double *alpha,
172                                                              cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
173                                                              cl_mem y, ViennaCLInt offy, ViennaCLInt incy)
174 {
175   typedef viennacl::vector_base<double>::size_type           size_type;
176   typedef viennacl::vector_base<double>::size_type           difference_type;
177   viennacl::vector_base<double> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
178   viennacl::vector_base<double> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
179 
180   *alpha = viennacl::linalg::inner_prod(v1, v2);
181   return ViennaCLSuccess;
182 }
183 
184 
185 // xNRM2
186 
ViennaCLOpenCLSnrm2(ViennaCLBackend backend,ViennaCLInt n,float * alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx)187 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLSnrm2(ViennaCLBackend backend, ViennaCLInt n,
188                                                               float *alpha,
189                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx)
190 {
191   typedef viennacl::vector_base<float>::size_type           size_type;
192   typedef viennacl::vector_base<float>::size_type           difference_type;
193   viennacl::vector_base<float> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
194 
195   *alpha = viennacl::linalg::norm_2(v1);
196   return ViennaCLSuccess;
197 }
198 
ViennaCLOpenCLDnrm2(ViennaCLBackend backend,ViennaCLInt n,double * alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx)199 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLDnrm2(ViennaCLBackend backend, ViennaCLInt n,
200                                                               double *alpha,
201                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx)
202 {
203   typedef viennacl::vector_base<double>::size_type           size_type;
204   typedef viennacl::vector_base<double>::size_type           difference_type;
205   viennacl::vector_base<double> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
206 
207   *alpha = viennacl::linalg::norm_2(v1);
208   return ViennaCLSuccess;
209 }
210 
211 
212 // xROT
213 
ViennaCLOpenCLSrot(ViennaCLBackend backend,ViennaCLInt n,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy,float c,float s)214 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLSrot(ViennaCLBackend backend, ViennaCLInt n,
215                                                              cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
216                                                              cl_mem y, ViennaCLInt offy, ViennaCLInt incy,
217                                                              float c, float s)
218 {
219   typedef viennacl::vector_base<float>::size_type           size_type;
220   typedef viennacl::vector_base<float>::size_type           difference_type;
221   viennacl::vector_base<float> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
222   viennacl::vector_base<float> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
223 
224   viennacl::linalg::plane_rotation(v1, v2, c, s);
225   return ViennaCLSuccess;
226 }
227 
ViennaCLOpenCLDrot(ViennaCLBackend backend,ViennaCLInt n,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy,double c,double s)228 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLDrot(ViennaCLBackend backend, ViennaCLInt n,
229                                                              cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
230                                                              cl_mem y, ViennaCLInt offy, ViennaCLInt incy,
231                                                              double c, double s)
232 {
233   typedef viennacl::vector_base<double>::size_type           size_type;
234   typedef viennacl::vector_base<double>::size_type           difference_type;
235   viennacl::vector_base<double> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
236   viennacl::vector_base<double> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
237 
238   viennacl::linalg::plane_rotation(v1, v2, c, s);
239   return ViennaCLSuccess;
240 }
241 
242 
243 
244 // xSCAL
245 
ViennaCLOpenCLSscal(ViennaCLBackend backend,ViennaCLInt n,float alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx)246 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLSscal(ViennaCLBackend backend, ViennaCLInt n,
247                                                               float alpha,
248                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx)
249 {
250   typedef viennacl::vector_base<float>::size_type           size_type;
251   typedef viennacl::vector_base<float>::size_type           difference_type;
252   viennacl::vector_base<float> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
253 
254   v1 *= alpha;
255   return ViennaCLSuccess;
256 }
257 
ViennaCLOpenCLDscal(ViennaCLBackend backend,ViennaCLInt n,double alpha,cl_mem x,ViennaCLInt offx,ViennaCLInt incx)258 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLDscal(ViennaCLBackend backend, ViennaCLInt n,
259                                                               double alpha,
260                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx)
261 {
262   typedef viennacl::vector_base<double>::size_type           size_type;
263   typedef viennacl::vector_base<double>::size_type           difference_type;
264   viennacl::vector_base<double> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
265 
266   v1 *= alpha;
267   return ViennaCLSuccess;
268 }
269 
270 // xSWAP
271 
ViennaCLOpenCLSswap(ViennaCLBackend backend,ViennaCLInt n,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy)272 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLSswap(ViennaCLBackend backend, ViennaCLInt n,
273                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
274                                                               cl_mem y, ViennaCLInt offy, ViennaCLInt incy)
275 {
276   typedef viennacl::vector_base<float>::size_type           size_type;
277   typedef viennacl::vector_base<float>::size_type           difference_type;
278   viennacl::vector_base<float> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
279   viennacl::vector_base<float> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
280 
281   viennacl::swap(v1, v2);
282   return ViennaCLSuccess;
283 }
284 
ViennaCLOpenCLDswap(ViennaCLBackend backend,ViennaCLInt n,cl_mem x,ViennaCLInt offx,ViennaCLInt incx,cl_mem y,ViennaCLInt offy,ViennaCLInt incy)285 VIENNACL_EXPORTED_FUNCTION ViennaCLStatus ViennaCLOpenCLDswap(ViennaCLBackend backend, ViennaCLInt n,
286                                                               cl_mem x, ViennaCLInt offx, ViennaCLInt incx,
287                                                               cl_mem y, ViennaCLInt offy, ViennaCLInt incy)
288 {
289   typedef viennacl::vector_base<double>::size_type           size_type;
290   typedef viennacl::vector_base<double>::size_type           difference_type;
291   viennacl::vector_base<double> v1(x, size_type(n), size_type(offx), difference_type(incx), viennacl::ocl::get_context(backend->opencl_backend.context_id));
292   viennacl::vector_base<double> v2(y, size_type(n), size_type(offy), difference_type(incy), viennacl::ocl::get_context(backend->opencl_backend.context_id));
293 
294   viennacl::swap(v1, v2);
295   return ViennaCLSuccess;
296 }
297 #endif
298