PLSSVM - Parallel Least Squares Support Vector Machine  2.0.0
A Least Squares Support Vector Machine implementation using different backends.
predict_kernel.hpp
Go to the documentation of this file.
1 
12 #ifndef PLSSVM_BACKENDS_SYCL_PREDICT_KERNEL_HPP_
13 #define PLSSVM_BACKENDS_SYCL_PREDICT_KERNEL_HPP_
14 #pragma once
15 
16 #include "plssvm/backends/SYCL/detail/atomics.hpp" // plssvm::sycl::detail::atomic_op
17 #include "plssvm/constants.hpp" // plssvm::kernel_index_type, plssvm::THREAD_BLOCK_SIZE, plssvm::INTERNAL_BLOCK_SIZE
18 
19 #include "sycl/sycl.hpp" // sycl::nd_item, sycl::range, sycl::pow, sycl::exp
20 
21 namespace plssvm::sycl::detail {
22 
28 template <typename T>
30  public:
32  using real_type = T;
33 
44  device_kernel_w_linear(real_type *w_d, const real_type *data_d, const real_type *data_last_d, const real_type *alpha_d, const kernel_index_type num_data_points, const kernel_index_type num_features) :
45  w_d_{ w_d }, data_d_{ data_d }, data_last_d_{ data_last_d }, alpha_d_{ alpha_d }, num_data_points_{ num_data_points }, num_features_{ num_features } {}
46 
52  void operator()(::sycl::id<1> index) const {
53  real_type temp{ 0.0 };
54  if (index < num_features_) {
55  for (kernel_index_type dat = 0; dat < num_data_points_ - 1; ++dat) {
56  temp += alpha_d_[dat] * data_d_[dat + (num_data_points_ - 1 + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * index];
57  }
58  temp += alpha_d_[num_data_points_ - 1] * data_last_d_[index];
59  w_d_[index] = temp;
60  }
61  }
62 
63  private:
65  real_type *w_d_;
66  const real_type *data_d_;
67  const real_type *data_last_d_;
68  const real_type *alpha_d_;
69  const kernel_index_type num_data_points_;
70  const kernel_index_type num_features_;
72 };
73 
79 template <typename T>
81  public:
83  using real_type = T;
84 
100  device_kernel_predict_polynomial(real_type *out_d, const real_type *data_d, const real_type *data_last_d, const real_type *alpha_d, const kernel_index_type num_data_points, const real_type *points, const kernel_index_type num_predict_points, const kernel_index_type num_features, const int degree, const real_type gamma, const real_type coef0) :
101  out_d_{ out_d }, data_d_{ data_d }, data_last_d_{ data_last_d }, alpha_d_{ alpha_d }, num_data_points_{ num_data_points }, points_{ points }, num_predict_points_{ num_predict_points }, num_features_{ num_features }, degree_{ degree }, gamma_{ gamma }, coef0_{ coef0 } {}
102 
107  void operator()(::sycl::nd_item<2> idx) const {
108  const kernel_index_type data_point_index = idx.get_global_id(0);
109  const kernel_index_type predict_point_index = idx.get_global_id(1);
110 
111  real_type temp = 0;
112  if (predict_point_index < num_predict_points_) {
113  for (kernel_index_type feature_index = 0; feature_index < num_features_; ++feature_index) {
114  if (data_point_index == num_data_points_ - 1) {
115  temp += data_last_d_[feature_index] * points_[predict_point_index + (num_predict_points_ + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * feature_index];
116  } else {
117  temp += data_d_[data_point_index + (num_data_points_ - 1 + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * feature_index] * points_[predict_point_index + (num_predict_points_ + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * feature_index];
118  }
119  }
120 
121  temp = alpha_d_[data_point_index] * ::sycl::pow(gamma_ * temp + coef0_, static_cast<real_type>(degree_));
122 
123  detail::atomic_op<real_type>{ out_d_[predict_point_index] } += temp;
124  }
125  }
126 
127  private:
129  real_type *out_d_;
130  const real_type *data_d_;
131  const real_type *data_last_d_;
132  const real_type *alpha_d_;
133  const kernel_index_type num_data_points_;
134  const real_type *points_;
135  const kernel_index_type num_predict_points_;
136  const kernel_index_type num_features_;
137  const int degree_;
138  const real_type gamma_;
139  const real_type coef0_;
141 };
142 
148 template <typename T>
150  public:
152  using real_type = T;
153 
167  device_kernel_predict_rbf(real_type *out_d, const real_type *data_d, const real_type *data_last_d, const real_type *alpha_d, const kernel_index_type num_data_points, const real_type *points, const kernel_index_type num_predict_points, const kernel_index_type num_features, const real_type gamma) :
168  out_d_{ out_d }, data_d_{ data_d }, data_last_d_{ data_last_d }, alpha_d_{ alpha_d }, num_data_points_{ num_data_points }, points_{ points }, num_predict_points_{ num_predict_points }, num_features_{ num_features }, gamma_{ gamma } {}
169 
174  void operator()(::sycl::nd_item<2> idx) const {
175  const kernel_index_type data_point_index = idx.get_global_id(0);
176  const kernel_index_type predict_point_index = idx.get_global_id(1);
177 
178  real_type temp = 0;
179  if (predict_point_index < num_predict_points_) {
180  for (kernel_index_type feature_index = 0; feature_index < num_features_; ++feature_index) {
181  if (data_point_index == num_data_points_ - 1) {
182  temp += (data_last_d_[feature_index] - points_[predict_point_index + (num_predict_points_ + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * feature_index]) * (data_last_d_[feature_index] - points_[predict_point_index + (num_predict_points_ + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * feature_index]);
183  } else {
184  temp += (data_d_[data_point_index + (num_data_points_ - 1 + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * feature_index] - points_[predict_point_index + (num_predict_points_ + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * feature_index]) * (data_d_[data_point_index + (num_data_points_ - 1 + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * feature_index] - points_[predict_point_index + (num_predict_points_ + THREAD_BLOCK_SIZE * INTERNAL_BLOCK_SIZE) * feature_index]);
185  }
186  }
187 
188  temp = alpha_d_[data_point_index] * ::sycl::exp(-gamma_ * temp);
189 
190  detail::atomic_op<real_type>{ out_d_[predict_point_index] } += temp;
191  }
192  }
193 
194  private:
196  real_type *out_d_;
197  const real_type *data_d_;
198  const real_type *data_last_d_;
199  const real_type *alpha_d_;
200  const kernel_index_type num_data_points_;
201  const real_type *points_;
202  const kernel_index_type num_predict_points_;
203  const kernel_index_type num_features_;
204  const real_type gamma_;
206 };
207 
208 } // namespace plssvm::sycl::detail
209 
210 #endif // PLSSVM_BACKENDS_SYCL_PREDICT_KERNEL_HPP_
Defines an atomic_ref wrapper for the SYCL backend.
Predicts the labels for data points using the polynomial kernel function.
Definition: predict_kernel.hpp:80
device_kernel_predict_polynomial(real_type *out_d, const real_type *data_d, const real_type *data_last_d, const real_type *alpha_d, const kernel_index_type num_data_points, const real_type *points, const kernel_index_type num_predict_points, const kernel_index_type num_features, const int degree, const real_type gamma, const real_type coef0)
Construct a new device kernel to predict the labels for data points using the polynomial kernel funct...
Definition: predict_kernel.hpp:100
void operator()(::sycl::nd_item< 2 > idx) const
Function call operator overload performing the actual calculation.
Definition: predict_kernel.hpp:107
T real_type
The type of the data.
Definition: predict_kernel.hpp:83
Predicts the labels for data points using the radial basis functions kernel function.
Definition: predict_kernel.hpp:149
void operator()(::sycl::nd_item< 2 > idx) const
Function call operator overload performing the actual calculation.
Definition: predict_kernel.hpp:174
T real_type
The type of the data.
Definition: predict_kernel.hpp:152
device_kernel_predict_rbf(real_type *out_d, const real_type *data_d, const real_type *data_last_d, const real_type *alpha_d, const kernel_index_type num_data_points, const real_type *points, const kernel_index_type num_predict_points, const kernel_index_type num_features, const real_type gamma)
Construct a new device kernel to predict the labels for data points using the radial basis function k...
Definition: predict_kernel.hpp:167
Calculate the w vector to speed up the prediction of the labels for data points using the linear kern...
Definition: predict_kernel.hpp:29
void operator()(::sycl::id< 1 > index) const
Function call operator overload performing the actual calculation.
Definition: predict_kernel.hpp:52
device_kernel_w_linear(real_type *w_d, const real_type *data_d, const real_type *data_last_d, const real_type *alpha_d, const kernel_index_type num_data_points, const kernel_index_type num_features)
Construct a new device kernel generating the w vector used to speedup the prediction when using the l...
Definition: predict_kernel.hpp:44
T real_type
The type of the data.
Definition: predict_kernel.hpp:32
Global type definitions and compile-time constants.
Namespace containing the C-SVM using the SYCL backend with the preferred SYCL implementation....
Definition: atomics.hpp:18
::sycl::atomic_ref< T, ::sycl::memory_order::relaxed, ::sycl::memory_scope::device, ::sycl::access::address_space::global_space > atomic_op
Shortcut alias for a sycl::atomic_ref targeting global memory.
Definition: atomics.hpp:25
constexpr kernel_index_type THREAD_BLOCK_SIZE
Global compile-time constant used for internal caching. May be changed during the CMake configuration...
Definition: constants.hpp:25
int kernel_index_type
Integer type used inside kernels.
Definition: constants.hpp:19
constexpr kernel_index_type INTERNAL_BLOCK_SIZE
Global compile-time constant used for internal caching. May be changed during the CMake configuration...
Definition: constants.hpp:32