ViennaCL - The Vienna Computing Library  1.5.2
nmf.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_LINALG_OPENCL_KERNELS_NMF_HPP
2 #define VIENNACL_LINALG_OPENCL_KERNELS_NMF_HPP
3 
7 #include "viennacl/ocl/utils.hpp"
8 
11 namespace viennacl
12 {
13  namespace linalg
14  {
15  namespace opencl
16  {
17  namespace kernels
18  {
19 
20  template <typename StringType>
21  void generate_nmf_el_wise_mul_div(StringType & source, std::string const & numeric_string)
22  {
23  source.append("__kernel void el_wise_mul_div( \n");
24  source.append(" __global "); source.append(numeric_string); source.append(" * matrix1, \n");
25  source.append(" __global const "); source.append(numeric_string); source.append(" * matrix2, \n");
26  source.append(" __global const "); source.append(numeric_string); source.append(" * matrix3, \n");
27  source.append(" unsigned int size) \n");
28  source.append("{ \n");
29  source.append(" for (unsigned int i = get_global_id(0); i < size; i += get_global_size(0)) \n");
30  source.append(" { \n");
31  source.append(" "); source.append(numeric_string); source.append(" val = matrix1[i] * matrix2[i]; \n");
32  source.append(" "); source.append(numeric_string); source.append(" divisor = matrix3[i]; \n");
33  source.append(" matrix1[i] = (divisor > ("); source.append(numeric_string); source.append(")0.00001) ? (val / divisor) : ("); source.append(numeric_string); source.append(")0; \n");
34  source.append(" } \n");
35  source.append("} \n");
36  }
37 
38  // main kernel class
40  template <class NumericT>
41  struct nmf
42  {
43  static std::string program_name()
44  {
46  }
47 
48  static void init(viennacl::ocl::context & ctx)
49  {
51  std::string numeric_string = viennacl::ocl::type_to_string<NumericT>::apply();
52 
53  static std::map<cl_context, bool> init_done;
54  if (!init_done[ctx.handle().get()])
55  {
56  std::string source;
57  source.reserve(8192);
58 
59  viennacl::ocl::append_double_precision_pragma<NumericT>(ctx, source);
60 
61  // only generate for floating points (forces error for integers)
62  if (numeric_string == "float" || numeric_string == "double")
63  {
64  generate_nmf_el_wise_mul_div(source, numeric_string);
65  }
66 
67  std::string prog_name = program_name();
68  #ifdef VIENNACL_BUILD_INFO
69  std::cout << "Creating program " << prog_name << std::endl;
70  #endif
71  ctx.add_program(source, prog_name);
72  init_done[ctx.handle().get()] = true;
73  } //if
74  } //init
75  };
76 
77  } // namespace kernels
78  } // namespace opencl
79  } // namespace linalg
80 } // namespace viennacl
81 #endif
82 
Implements a OpenCL platform within ViennaCL.
Various little tools used here and there in ViennaCL.
Manages an OpenCL context and provides the respective convenience functions for creating buffers...
Definition: context.hpp:51
Provides OpenCL-related utilities.
static std::string program_name()
Definition: nmf.hpp:43
const viennacl::ocl::handle< cl_context > & handle() const
Returns the context handle.
Definition: context.hpp:476
const OCL_TYPE & get() const
Definition: handle.hpp:189
Main kernel class for generating OpenCL kernels for nonnegative matrix factorization of a dense matri...
Definition: nmf.hpp:41
static void apply(viennacl::ocl::context const &)
Definition: utils.hpp:40
Representation of an OpenCL kernel in ViennaCL.
static void init(viennacl::ocl::context &ctx)
Definition: nmf.hpp:48
void generate_nmf_el_wise_mul_div(StringType &source, std::string const &numeric_string)
Definition: nmf.hpp:21
Helper class for converting a type to its string representation.
Definition: utils.hpp:57