ViennaCL - The Vienna Computing Library
1.5.0
|
00001 #ifndef VIENNACL_LINALG_OPENCL_SCALAR_OPERATIONS_HPP_ 00002 #define VIENNACL_LINALG_OPENCL_SCALAR_OPERATIONS_HPP_ 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2013, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 Portions of this software are copyright by UChicago Argonne, LLC. 00009 00010 ----------------- 00011 ViennaCL - The Vienna Computing Library 00012 ----------------- 00013 00014 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00015 00016 (A list of authors and contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ============================================================================= */ 00020 00025 #include "viennacl/forwards.h" 00026 #include "viennacl/ocl/device.hpp" 00027 #include "viennacl/ocl/handle.hpp" 00028 #include "viennacl/ocl/kernel.hpp" 00029 #include "viennacl/tools/tools.hpp" 00030 #include "viennacl/linalg/opencl/kernels/scalar.hpp" 00031 #include "viennacl/linalg/opencl/common.hpp" 00032 #include "viennacl/meta/predicate.hpp" 00033 #include "viennacl/meta/result_of.hpp" 00034 #include "viennacl/meta/enable_if.hpp" 00035 #include "viennacl/traits/size.hpp" 00036 #include "viennacl/traits/start.hpp" 00037 #include "viennacl/traits/handle.hpp" 00038 #include "viennacl/traits/stride.hpp" 00039 00040 namespace viennacl 00041 { 00042 namespace linalg 00043 { 00044 namespace opencl 00045 { 00046 template <typename S1, 00047 typename S2, typename ScalarType1> 00048 typename viennacl::enable_if< viennacl::is_scalar<S1>::value 00049 && viennacl::is_scalar<S2>::value 00050 && viennacl::is_any_scalar<ScalarType1>::value 00051 >::type 00052 as(S1 & s1, 00053 S2 const & s2, ScalarType1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha) 00054 { 00055 assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!")); 00056 00057 typedef typename viennacl::result_of::cpu_value_type<S1>::type value_type; 00058 viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context()); 00059 viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx); 00060 00061 cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha); 00062 00063 viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), 00064 (viennacl::is_cpu_scalar<ScalarType1>::value ? "as_cpu" : "as_gpu")); 00065 k.local_work_size(0, 1); 00066 k.global_work_size(0, 1); 00067 viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1), 00068 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(alpha)), 00069 options_alpha, 00070 viennacl::traits::opencl_handle(s2) ) 00071 ); 00072 } 00073 00074 00075 template <typename S1, 00076 typename S2, typename ScalarType1, 00077 typename S3, typename ScalarType2> 00078 typename viennacl::enable_if< viennacl::is_scalar<S1>::value 00079 && viennacl::is_scalar<S2>::value 00080 && viennacl::is_scalar<S3>::value 00081 && viennacl::is_any_scalar<ScalarType1>::value 00082 && viennacl::is_any_scalar<ScalarType2>::value 00083 >::type 00084 asbs(S1 & s1, 00085 S2 const & s2, ScalarType1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, 00086 S3 const & s3, ScalarType2 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta) 00087 { 00088 assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!")); 00089 assert( &viennacl::traits::opencl_handle(s2).context() == &viennacl::traits::opencl_handle(s3).context() && bool("Operands not in the same OpenCL context!")); 00090 00091 typedef typename viennacl::result_of::cpu_value_type<S1>::type value_type; 00092 viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context()); 00093 viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx); 00094 00095 std::string kernel_name; 00096 if (viennacl::is_cpu_scalar<ScalarType1>::value && viennacl::is_cpu_scalar<ScalarType2>::value) 00097 kernel_name = "asbs_cpu_cpu"; 00098 else if (viennacl::is_cpu_scalar<ScalarType1>::value && !viennacl::is_cpu_scalar<ScalarType2>::value) 00099 kernel_name = "asbs_cpu_gpu"; 00100 else if (!viennacl::is_cpu_scalar<ScalarType1>::value && viennacl::is_cpu_scalar<ScalarType2>::value) 00101 kernel_name = "asbs_gpu_cpu"; 00102 else 00103 kernel_name = "asbs_gpu_gpu"; 00104 00105 cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha); 00106 cl_uint options_beta = detail::make_options(len_beta, reciprocal_beta, flip_sign_beta); 00107 00108 viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), kernel_name); 00109 k.local_work_size(0, 1); 00110 k.global_work_size(0, 1); 00111 viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1), 00112 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(alpha)), 00113 options_alpha, 00114 viennacl::traits::opencl_handle(s2), 00115 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(beta)), 00116 options_beta, 00117 viennacl::traits::opencl_handle(s3) ) 00118 ); 00119 } 00120 00121 00122 template <typename S1, 00123 typename S2, typename ScalarType1, 00124 typename S3, typename ScalarType2> 00125 typename viennacl::enable_if< viennacl::is_scalar<S1>::value 00126 && viennacl::is_scalar<S2>::value 00127 && viennacl::is_scalar<S3>::value 00128 && viennacl::is_any_scalar<ScalarType1>::value 00129 && viennacl::is_any_scalar<ScalarType2>::value 00130 >::type 00131 asbs_s(S1 & s1, 00132 S2 const & s2, ScalarType1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, 00133 S3 const & s3, ScalarType2 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta) 00134 { 00135 assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!")); 00136 assert( &viennacl::traits::opencl_handle(s2).context() == &viennacl::traits::opencl_handle(s3).context() && bool("Operands not in the same OpenCL context!")); 00137 00138 typedef typename viennacl::result_of::cpu_value_type<S1>::type value_type; 00139 viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context()); 00140 viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx); 00141 00142 std::string kernel_name; 00143 if (viennacl::is_cpu_scalar<ScalarType1>::value && viennacl::is_cpu_scalar<ScalarType2>::value) 00144 kernel_name = "asbs_s_cpu_cpu"; 00145 else if (viennacl::is_cpu_scalar<ScalarType1>::value && !viennacl::is_cpu_scalar<ScalarType2>::value) 00146 kernel_name = "asbs_s_cpu_gpu"; 00147 else if (!viennacl::is_cpu_scalar<ScalarType1>::value && viennacl::is_cpu_scalar<ScalarType2>::value) 00148 kernel_name = "asbs_s_gpu_cpu"; 00149 else 00150 kernel_name = "asbs_s_gpu_gpu"; 00151 00152 cl_uint options_alpha = detail::make_options(len_alpha, reciprocal_alpha, flip_sign_alpha); 00153 cl_uint options_beta = detail::make_options(len_beta, reciprocal_beta, flip_sign_beta); 00154 00155 viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), kernel_name); 00156 k.local_work_size(0, 1); 00157 k.global_work_size(0, 1); 00158 viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1), 00159 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(alpha)), 00160 options_alpha, 00161 viennacl::traits::opencl_handle(s2), 00162 viennacl::traits::opencl_handle(viennacl::tools::promote_if_host_scalar<value_type>(beta)), 00163 options_beta, 00164 viennacl::traits::opencl_handle(s3) ) 00165 ); 00166 } 00167 00168 00174 template <typename S1, typename S2> 00175 typename viennacl::enable_if< viennacl::is_scalar<S1>::value 00176 && viennacl::is_scalar<S2>::value 00177 >::type 00178 swap(S1 & s1, S2 & s2) 00179 { 00180 assert( &viennacl::traits::opencl_handle(s1).context() == &viennacl::traits::opencl_handle(s2).context() && bool("Operands not in the same OpenCL context!")); 00181 00182 typedef typename viennacl::result_of::cpu_value_type<S1>::type value_type; 00183 viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(s1).context()); 00184 viennacl::linalg::opencl::kernels::scalar<value_type>::init(ctx); 00185 00186 viennacl::ocl::kernel & k = ctx.get_kernel(viennacl::linalg::opencl::kernels::scalar<value_type>::program_name(), "swap"); 00187 k.local_work_size(0, 1); 00188 k.global_work_size(0, 1); 00189 viennacl::ocl::enqueue(k(viennacl::traits::opencl_handle(s1), 00190 viennacl::traits::opencl_handle(s2)) 00191 ); 00192 } 00193 00194 00195 00196 } //namespace opencl 00197 } //namespace linalg 00198 } //namespace viennacl 00199 00200 00201 #endif