ViennaCL - The Vienna Computing Library
1.5.1
|
00001 #ifndef VIENNACL_TOOLS_TOOLS_HPP_ 00002 #define VIENNACL_TOOLS_TOOLS_HPP_ 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2014, 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 <string> 00026 #include <fstream> 00027 #include <sstream> 00028 #include "viennacl/forwards.h" 00029 #include "viennacl/tools/adapter.hpp" 00030 00031 #include <vector> 00032 #include <map> 00033 00034 namespace viennacl 00035 { 00036 namespace tools 00037 { 00038 00041 template <class SCALARTYPE, typename F, unsigned int ALIGNMENT> 00042 struct MATRIX_ITERATOR_INCREMENTER<viennacl::row_iteration, viennacl::matrix<SCALARTYPE, F, ALIGNMENT> > 00043 { 00044 static void apply(const viennacl::matrix<SCALARTYPE, F, ALIGNMENT> & /*mat*/, unsigned int & row, unsigned int & /*col*/) { ++row; } 00045 }; 00046 00047 template <class SCALARTYPE, typename F, unsigned int ALIGNMENT> 00048 struct MATRIX_ITERATOR_INCREMENTER<viennacl::col_iteration, viennacl::matrix<SCALARTYPE, F, ALIGNMENT> > 00049 { 00050 static void apply(const viennacl::matrix<SCALARTYPE, F, ALIGNMENT> & /*mat*/, unsigned int & /*row*/, unsigned int & col) { ++col; } 00051 }; 00056 template <typename T> 00057 struct CHECK_SCALAR_TEMPLATE_ARGUMENT 00058 { 00059 typedef typename T::ERROR_SCALAR_MUST_HAVE_TEMPLATE_ARGUMENT_FLOAT_OR_DOUBLE ResultType; 00060 }; 00061 00063 template <> 00064 struct CHECK_SCALAR_TEMPLATE_ARGUMENT<float> 00065 { 00066 typedef float ResultType; 00067 }; 00068 00069 template <> 00070 struct CHECK_SCALAR_TEMPLATE_ARGUMENT<double> 00071 { 00072 typedef double ResultType; 00073 }; 00083 inline std::string readTextFromFile(const std::string & filename) 00084 { 00085 std::ifstream f(filename.c_str()); 00086 if (!f) return std::string(); 00087 00088 std::stringstream result; 00089 std::string tmp; 00090 while (std::getline(f, tmp)) 00091 result << tmp << std::endl; 00092 00093 return result.str(); 00094 } 00095 00103 inline std::string strReplace(const std::string & text, std::string to_search, std::string to_replace) 00104 { 00105 std::string::size_type pos = 0; 00106 std::string result; 00107 std::string::size_type found; 00108 while( (found = text.find(to_search, pos)) != std::string::npos ) 00109 { 00110 result.append(text.substr(pos,found-pos)); 00111 result.append(to_replace); 00112 pos = found + to_search.length(); 00113 } 00114 if (pos < text.length()) 00115 result.append(text.substr(pos)); 00116 return result; 00117 } 00118 00126 template <class INT_TYPE> 00127 INT_TYPE align_to_multiple(INT_TYPE to_reach, INT_TYPE base) 00128 { 00129 if (to_reach % base == 0) return to_reach; 00130 return ((to_reach / base) + 1) * base; 00131 } 00132 00133 00141 template <class INT_TYPE> 00142 INT_TYPE roundDownToPreviousMultiple(INT_TYPE to_reach, INT_TYPE base) 00143 { 00144 if (to_reach % base == 0) return to_reach; 00145 return (to_reach / base) * base; 00146 } 00147 00154 int inline find_and_replace(std::string & source, std::string const & find, std::string const & replace) 00155 { 00156 int num=0; 00157 vcl_size_t fLen = find.size(); 00158 vcl_size_t rLen = replace.size(); 00159 for (vcl_size_t pos=0; (pos=source.find(find, pos))!=std::string::npos; pos+=rLen) 00160 { 00161 num++; 00162 source.replace(pos, fLen, replace); 00163 } 00164 return num; 00165 } 00166 00173 inline std::string make_double_kernel(std::string const & source, std::string const & fp_extension) 00174 { 00175 std::stringstream ss; 00176 ss << "#pragma OPENCL EXTENSION " << fp_extension << " : enable\n\n"; 00177 00178 std::string result = ss.str(); 00179 result.append(strReplace(source, "float", "double")); 00180 return result; 00181 } 00182 00183 00185 template <typename T> 00186 struct CONST_REMOVER 00187 { 00188 typedef T ResultType; 00189 }; 00190 00192 template <typename T> 00193 struct CONST_REMOVER<const T> 00194 { 00195 typedef T ResultType; 00196 }; 00200 00201 00206 template <typename T> 00207 struct CPU_SCALAR_TYPE_DEDUCER 00208 { 00209 //force compiler error if type cannot be deduced 00210 //typedef T ResultType; 00211 }; 00212 00214 template <> 00215 struct CPU_SCALAR_TYPE_DEDUCER< float > 00216 { 00217 typedef float ResultType; 00218 }; 00219 00220 template <> 00221 struct CPU_SCALAR_TYPE_DEDUCER< double > 00222 { 00223 typedef double ResultType; 00224 }; 00225 00226 template <typename T> 00227 struct CPU_SCALAR_TYPE_DEDUCER< viennacl::scalar<T> > 00228 { 00229 typedef T ResultType; 00230 }; 00231 00232 template <typename T, unsigned int A> 00233 struct CPU_SCALAR_TYPE_DEDUCER< viennacl::vector<T, A> > 00234 { 00235 typedef T ResultType; 00236 }; 00237 00238 template <typename T, typename F, unsigned int A> 00239 struct CPU_SCALAR_TYPE_DEDUCER< viennacl::matrix<T, F, A> > 00240 { 00241 typedef T ResultType; 00242 }; 00243 00244 00245 template <typename T, typename F, unsigned int A> 00246 struct CPU_SCALAR_TYPE_DEDUCER< viennacl::matrix_expression<const matrix<T, F, A>, const matrix<T, F, A>, op_trans> > 00247 { 00248 typedef T ResultType; 00249 }; 00252 // 00253 // Converts a scalar type when necessary unless it is a viennacl::scalar<> (typical use-case: convert user-provided floats to double (and vice versa) for OpenCL kernels) 00254 // 00255 00256 template <typename HostScalarType> 00257 viennacl::scalar<HostScalarType> const & promote_if_host_scalar(viennacl::scalar<HostScalarType> const & s) { return s; } 00258 00259 template <typename HostScalarType> 00260 viennacl::scalar_expression<const viennacl::scalar<HostScalarType>, 00261 const viennacl::scalar<HostScalarType>, 00262 viennacl::op_flip_sign> const & 00263 promote_if_host_scalar(viennacl::scalar_expression<const viennacl::scalar<HostScalarType>, 00264 const viennacl::scalar<HostScalarType>, 00265 viennacl::op_flip_sign> const & s) { return s; } 00266 00267 template <typename HostScalarType> 00268 HostScalarType promote_if_host_scalar(float s) { return s; } 00269 00270 template <typename HostScalarType> 00271 HostScalarType promote_if_host_scalar(double s) { return s; } 00272 00273 template <typename HostScalarType> 00274 HostScalarType promote_if_host_scalar(long s) { return s; } 00275 00276 template <typename HostScalarType> 00277 HostScalarType promote_if_host_scalar(unsigned long s) { return s; } 00278 00279 template <typename HostScalarType> 00280 HostScalarType promote_if_host_scalar(int s) { return s; } 00281 00282 template <typename HostScalarType> 00283 HostScalarType promote_if_host_scalar(unsigned int s) { return s; } 00284 00285 } //namespace tools 00286 } //namespace viennacl 00287 00288 00289 #endif