ViennaCL - The Vienna Computing Library  1.5.2
viennacl/linalg/opencl/kernels/ilu.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_LINALG_OPENCL_KERNELS_ILU_HPP
00002 #define VIENNACL_LINALG_OPENCL_KERNELS_ILU_HPP
00003 
00004 #include "viennacl/tools/tools.hpp"
00005 #include "viennacl/ocl/kernel.hpp"
00006 #include "viennacl/ocl/platform.hpp"
00007 #include "viennacl/ocl/utils.hpp"
00008 
00011 namespace viennacl
00012 {
00013   namespace linalg
00014   {
00015     namespace opencl
00016     {
00017       namespace kernels
00018       {
00019         template <typename StringType>
00020         void generate_ilu_level_scheduling_substitute(StringType & source, std::string const & numeric_string)
00021         {
00022           source.append("__kernel void level_scheduling_substitute( \n");
00023           source.append("          __global const unsigned int * row_index_array, \n");
00024           source.append("          __global const unsigned int * row_indices, \n");
00025           source.append("          __global const unsigned int * column_indices, \n");
00026           source.append("          __global const "); source.append(numeric_string); source.append(" * elements, \n");
00027           source.append("          __global "); source.append(numeric_string); source.append(" * vec, \n");
00028           source.append("          unsigned int size) \n");
00029           source.append("{ \n");
00030           source.append("  for (unsigned int row  = get_global_id(0); \n");
00031           source.append("                    row  < size; \n");
00032           source.append("                    row += get_global_size(0)) \n");
00033           source.append("  { \n");
00034           source.append("    unsigned int eq_row = row_index_array[row]; \n");
00035           source.append("    "); source.append(numeric_string); source.append(" vec_entry = vec[eq_row]; \n");
00036           source.append("    unsigned int row_end = row_indices[row+1]; \n");
00037 
00038           source.append("    for (unsigned int j = row_indices[row]; j < row_end; ++j) \n");
00039           source.append("      vec_entry -= vec[column_indices[j]] * elements[j]; \n");
00040 
00041           source.append("    vec[eq_row] = vec_entry; \n");
00042           source.append("  } \n");
00043           source.append("} \n");
00044         }
00045 
00046         // main kernel class
00048         template <class NumericT>
00049         struct ilu
00050         {
00051           static std::string program_name()
00052           {
00053             return viennacl::ocl::type_to_string<NumericT>::apply() + "_ilu";
00054           }
00055 
00056           static void init(viennacl::ocl::context & ctx)
00057           {
00058             viennacl::ocl::DOUBLE_PRECISION_CHECKER<NumericT>::apply(ctx);
00059             std::string numeric_string = viennacl::ocl::type_to_string<NumericT>::apply();
00060 
00061             static std::map<cl_context, bool> init_done;
00062             if (!init_done[ctx.handle().get()])
00063             {
00064               std::string source;
00065               source.reserve(1024);
00066 
00067               viennacl::ocl::append_double_precision_pragma<NumericT>(ctx, source);
00068 
00069               // only generate for floating points (forces error for integers)
00070               if (numeric_string == "float" || numeric_string == "double")
00071               {
00072                 generate_ilu_level_scheduling_substitute(source, numeric_string);
00073               }
00074 
00075               std::string prog_name = program_name();
00076               #ifdef VIENNACL_BUILD_INFO
00077               std::cout << "Creating program " << prog_name << std::endl;
00078               #endif
00079               ctx.add_program(source, prog_name);
00080               init_done[ctx.handle().get()] = true;
00081             } //if
00082           } //init
00083         };
00084 
00085       }  // namespace kernels
00086     }  // namespace opencl
00087   }  // namespace linalg
00088 }  // namespace viennacl
00089 #endif
00090