ViennaCL - The Vienna Computing Library: viennacl/linalg/opencl/scalar_operations.hpp Source File

ViennaCL - The Vienna Computing Library 1.7.1 Free open-source GPU-accelerated linear algebra and solver library. |

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
scalar_operations.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_LINALG_OPENCL_SCALAR_OPERATIONS_HPP_
2 #define VIENNACL_LINALG_OPENCL_SCALAR_OPERATIONS_HPP_
3
4 /* =========================================================================
5 Copyright (c) 2010-2016, Institute for Microelectronics,
6 Institute for Analysis and Scientific Computing,
7 TU Wien.
8 Portions of this software are copyright by UChicago Argonne, LLC.
9
10 -----------------
11 ViennaCL - The Vienna Computing Library
12 -----------------
13
14 Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15
16 (A list of authors and contributors can be found in the manual)
17
18 License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20
25 #include "viennacl/forwards.h"
26 #include "viennacl/ocl/device.hpp"
27 #include "viennacl/ocl/handle.hpp"
28 #include "viennacl/ocl/kernel.hpp"
29 #include "viennacl/tools/tools.hpp"
30 #include "viennacl/linalg/opencl/kernels/scalar.hpp"
31 #include "viennacl/linalg/opencl/common.hpp"
32 #include "viennacl/meta/predicate.hpp"
33 #include "viennacl/meta/result_of.hpp"
34 #include "viennacl/meta/enable_if.hpp"
35 #include "viennacl/traits/size.hpp"
36 #include "viennacl/traits/start.hpp"
37 #include "viennacl/traits/handle.hpp"
38 #include "viennacl/traits/stride.hpp"
39 #include "viennacl/traits/handle.hpp"
40
41 namespace viennacl
42 {
43 namespace linalg
44 {
45 namespace opencl
46 {
47
48 template<typename ScalarT1,
49 typename ScalarT2, typename NumericT>
50 typename viennacl::enable_if< viennacl::is_scalar<ScalarT1>::value
51 && viennacl::is_scalar<ScalarT2>::value
52 && viennacl::is_any_scalar<NumericT>::value
53 >::type
54 as(ScalarT1 & s1,
55 ScalarT2 const & s2, NumericT const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha)
56 {
57 assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!"));
58
59 typedef typename viennacl::result_of::cpu_value_type<ScalarT1>::type value_type;
60 viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context());
61 viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx);
62
63 cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha);
64
65 bool is_cpu = viennacl::is_cpu_scalar<NumericT>::value;
66 viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), is_cpu ? "as_cpu" : "as_gpu");
67 k.local_work_size(0, 1);
68 k.global_work_size(0, 1);
69 viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1),
70 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(alpha)),
71 options_alpha,
72 viennacl::traits::opencl_handle(s2) )
73 );
74 }
75
76
77 template<typename ScalarT1,
78 typename ScalarT2, typename NumericT2,
79 typename ScalarT3, typename NumericT3>
80 typename viennacl::enable_if< viennacl::is_scalar<ScalarT1>::value
81 && viennacl::is_scalar<ScalarT2>::value
82 && viennacl::is_scalar<ScalarT3>::value
83 && viennacl::is_any_scalar<NumericT2>::value
84 && viennacl::is_any_scalar<NumericT3>::value
85 >::type
86 asbs(ScalarT1 & s1,
87 ScalarT2 const & s2, NumericT2 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha,
88 ScalarT3 const & s3, NumericT3 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
89 {
90 assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!"));
91 assert( &viennacl::traits::opencl_handle(s2).context() == &viennacl::traits::opencl_handle(s3).context() && bool("Operands not in the same OpenCL context!"));
92
93 typedef typename viennacl::result_of::cpu_value_type<ScalarT1>::type value_type;
94 viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context());
95 viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx);
96
97 std::string kernel_name;
98 bool is_cpu_2 = viennacl::is_cpu_scalar<NumericT2>::value;
99 bool is_cpu_3 = viennacl::is_cpu_scalar<NumericT3>::value;
100 if (is_cpu_2 && is_cpu_3)
101 kernel_name = "asbs_cpu_cpu";
102 else if (is_cpu_2 && !is_cpu_3)
103 kernel_name = "asbs_cpu_gpu";
104 else if (!is_cpu_2 && is_cpu_3)
105 kernel_name = "asbs_gpu_cpu";
106 else
107 kernel_name = "asbs_gpu_gpu";
108
109 cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha);
110 cl_uint options_beta = detail::make_options(len_beta, reciprocal_beta, flip_sign_beta);
111
112 viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), kernel_name);
113 k.local_work_size(0, 1);
114 k.global_work_size(0, 1);
115 viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1),
116 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(alpha)),
117 options_alpha,
118 viennacl::traits::opencl_handle(s2),
119 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(beta)),
120 options_beta,
121 viennacl::traits::opencl_handle(s3) )
122 );
123 }
124
125
126 template<typename ScalarT1,
127 typename ScalarT2, typename NumericT2,
128 typename ScalarT3, typename NumericT3>
129 typename viennacl::enable_if< viennacl::is_scalar<ScalarT1>::value
130 && viennacl::is_scalar<ScalarT2>::value
131 && viennacl::is_scalar<ScalarT3>::value
132 && viennacl::is_any_scalar<NumericT2>::value
133 && viennacl::is_any_scalar<NumericT3>::value
134 >::type
135 asbs_s(ScalarT1 & s1,
136 ScalarT2 const & s2, NumericT2 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha,
137 ScalarT3 const & s3, NumericT3 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
138 {
139 assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!"));
140 assert( &viennacl::traits::opencl_handle(s2).context() == &viennacl::traits::opencl_handle(s3).context() && bool("Operands not in the same OpenCL context!"));
141
142 typedef typename viennacl::result_of::cpu_value_type<ScalarT1>::type value_type;
143 viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context());
144 viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx);
145
146 std::string kernel_name;
147 if (viennacl::is_cpu_scalar<NumericT2>::value && viennacl::is_cpu_scalar<NumericT3>::value)
148 kernel_name = "asbs_s_cpu_cpu";
149 else if (viennacl::is_cpu_scalar<NumericT2>::value && !viennacl::is_cpu_scalar<NumericT3>::value)
150 kernel_name = "asbs_s_cpu_gpu";
151 else if (!viennacl::is_cpu_scalar<NumericT2>::value && viennacl::is_cpu_scalar<NumericT3>::value)
152 kernel_name = "asbs_s_gpu_cpu";
153 else
154 kernel_name = "asbs_s_gpu_gpu";
155
156 cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha);
157 cl_uint options_beta = detail::make_options(len_beta, reciprocal_beta, flip_sign_beta);
158
159 viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), kernel_name);
160 k.local_work_size(0, 1);
161 k.global_work_size(0, 1);
162 viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1),
163 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(alpha)),
164 options_alpha,
165 viennacl::traits::opencl_handle(s2),
166 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(beta)),
167 options_beta,
168 viennacl::traits::opencl_handle(s3) )
169 );
170 }
171
172
178 template<typename ScalarT1, typename ScalarT2>
179 typename viennacl::enable_if< viennacl::is_scalar<ScalarT1>::value
180 && viennacl::is_scalar<ScalarT2>::value
181 >::type
182 swap(ScalarT1 & s1, ScalarT2 & s2)
183 {
184 assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!"));
185
186 typedef typename viennacl::result_of::cpu_value_type<ScalarT1>::type value_type;
187 viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context());
188 viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx);
189
190 viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), "swap");
191 k.local_work_size(0, 1);
192 k.global_work_size(0, 1);
193 viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1),
194 viennacl::traits::opencl_handle(s2))
195 );
196 }
197
198
199
200 } //namespace opencl
201 } //namespace linalg
202 } //namespace viennacl
203
204
205 #endif
viennacl::enable_if
Simple enable-if variant that uses the SFINAE pattern.
Definition: enable_if.hpp:30
device.hpp
Represents an OpenCL device within ViennaCL.
scalar.hpp
OpenCL kernel file for scalar operations.
size.hpp
Generic size and resize functionality for different vector and matrix types.
viennacl::linalg::opencl::swap
viennacl::enable_if< viennacl::is_scalar< ScalarT1 >::value &&viennacl::is_scalar< ScalarT2 >::value >::type swap(ScalarT1 &s1, ScalarT2 &s2)
Swaps the contents of two scalars, data is copied.
Definition: scalar_operations.hpp:182
viennacl::ocl::kernel
Represents an OpenCL kernel within ViennaCL.
Definition: kernel.hpp:58
start.hpp
Extracts the underlying OpenCL start index handle from a vector, a matrix, an expression etc...
tools.hpp
Various little tools used here and there in ViennaCL.
viennacl::ocl::kernel::local_work_size
size_type local_work_size(int index=0) const
Returns the local work size at the respective dimension.
Definition: kernel.hpp:742
viennacl::ocl::context
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:55
forwards.h
This file provides the forward declarations for the main types used within ViennaCL.
stride.hpp
Determines row and column increments for matrices and matrix proxies.
s2
viennacl::scalar< int > s2
Definition: global_variables.cpp:58
s1
viennacl::scalar< float > s1
Definition: global_variables.cpp:57
common.hpp
Common implementations shared by OpenCL-based operations.
NumericT
float NumericT
Definition: bisect.cpp:40
viennacl::linalg::opencl::kernels::scalar
Main kernel class for generating OpenCL kernels for operations involving viennacl::scalar<>, but not viennacl::vector<> or viennacl::matrix<>.
Definition: scalar.hpp:243
viennacl::linalg::opencl::asbs_s
viennacl::enable_if< viennacl::is_scalar< ScalarT1 >::value &&viennacl::is_scalar< ScalarT2 >::value &&viennacl::is_scalar< ScalarT3 >::value &&viennacl::is_any_scalar< NumericT2 >::value &&viennacl::is_any_scalar< NumericT3 >::value >::type asbs_s(ScalarT1 &s1, ScalarT2 const &s2, NumericT2 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, ScalarT3 const &s3, NumericT3 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: scalar_operations.hpp:135
viennacl::is_cpu_scalar
Helper struct for checking whether a type is a host scalar type (e.g. float, double) ...
Definition: forwards.h:448
viennacl::ocl::context::get_kernel
viennacl::ocl::kernel & get_kernel(std::string const &program_name, std::string const &kernel_name)
Convenience function for retrieving the kernel of a program directly from the context.
Definition: context.hpp:605
viennacl::linalg::opencl::kernels::scalar::init
static void init(viennacl::ocl::context &ctx)
Definition: scalar.hpp:250
viennacl::is_any_scalar
Helper struct for checking whether the provided type represents a scalar (either host, from ViennaCL, or a flip-sign proxy)
Definition: forwards.h:469
handle.hpp
Implementation of a smart-pointer-like class for handling OpenCL handles.
viennacl::linalg::opencl::detail::make_options
cl_uint make_options(vcl_size_t length, bool reciprocal, bool flip_sign)
Definition: common.hpp:42
viennacl::vcl_size_t
std::size_t vcl_size_t
Definition: forwards.h:75
viennacl::result_of::cpu_value_type::type
T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type
Definition: result_of.hpp:271
viennacl::linalg::opencl::asbs
viennacl::enable_if< viennacl::is_scalar< ScalarT1 >::value &&viennacl::is_scalar< ScalarT2 >::value &&viennacl::is_scalar< ScalarT3 >::value &&viennacl::is_any_scalar< NumericT2 >::value &&viennacl::is_any_scalar< NumericT3 >::value >::type asbs(ScalarT1 &s1, ScalarT2 const &s2, NumericT2 const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, ScalarT3 const &s3, NumericT3 const &beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta)
Definition: scalar_operations.hpp:86
viennacl::linalg::opencl::as
viennacl::enable_if< viennacl::is_scalar< ScalarT1 >::value &&viennacl::is_scalar< ScalarT2 >::value &&viennacl::is_any_scalar< NumericT >::value >::type as(ScalarT1 &s1, ScalarT2 const &s2, NumericT const &alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha)
Definition: scalar_operations.hpp:54
predicate.hpp
All the predicates used within ViennaCL. Checks for expressions to be vectors, etc.
viennacl::is_scalar
Helper struct for checking whether a type is a viennacl::scalar<>
Definition: forwards.h:455
viennacl::traits::context
viennacl::context context(T const &t)
Returns an ID for the currently active memory domain of an object.
Definition: context.hpp:40
viennacl::ocl::enqueue
void enqueue(KernelType &k, viennacl::ocl::command_queue const &queue)
Enqueues a kernel in the provided queue.
Definition: enqueue.hpp:50
kernel.hpp
Representation of an OpenCL kernel in ViennaCL.
viennacl::ocl::kernel::global_work_size
size_type global_work_size(int index=0) const
Returns the global work size at the respective dimension.
Definition: kernel.hpp:751
handle.hpp
Extracts the underlying OpenCL handle from a vector, a matrix, an expression etc. ...
result_of.hpp
A collection of compile time type deductions.
enable_if.hpp
Simple enable-if variant that uses the SFINAE pattern.