ViennaCL - The Vienna Computing Library  1.5.1
viennacl/tools/tools.hpp
Go to the documentation of this file.
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