ViennaCL - The Vienna Computing Library
1.5.2
|
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