Intel clGPU
functions_base.hpp
1 // Copyright (c) 2017-2018 Intel Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 #include <vector>
17 #include <array>
18 #include <memory>
19 #include <complex>
20 #include <algorithm>
21 #include "context.hpp"
22 #include "engine.hpp"
23 #include "errors.hpp"
24 #include <functional>
25 #include <numeric>
26 
27 namespace iclgpu
28 {
31 
32 using complex_t = std::complex<float>;
33 
35 template <typename ElemTy, direction Dir = none>
36 class blob
37 {
38  std::shared_ptr<buffer_binding> _buffer_binding;
39 public:
40  blob()
41  : _buffer_binding(nullptr) {}
42 
43  blob(ElemTy* ptr, size_t size)
44  : _buffer_binding(std::make_shared<buffer_binding>(ptr, size * sizeof_t<ElemTy>(), Dir))
45  {}
46 
47  blob(const std::shared_ptr<buffer>& buffer, size_t size = 0)
48  : _buffer_binding(std::make_shared<buffer_binding>(buffer, Dir, size))
49  {}
50 
51  //TODO Remove below by fixing client code.
52  blob(ElemTy* ptr)
53  : _buffer_binding(std::make_shared<buffer_binding>(ptr, 0, Dir))
54  {}
55 
56  std::shared_ptr<buffer_binding> get() const { return _buffer_binding; }
57 
58  operator ElemTy*() const { return reinterpret_cast<ElemTy*>(_buffer_binding->get_host_ptr()); }
59  operator std::shared_ptr<buffer_binding>() const { return get(); }
60  operator bool() const { return _buffer_binding && _buffer_binding->is_defined(); }
61 };
62 
63 namespace functions
64 {
65 template <class Func>
66 using implementations_list = std::vector<std::shared_ptr<typename Func::impl>>;
67 
68 template <class Func>
69 using scored_impls_list = std::vector<std::pair<float, std::shared_ptr<typename Func::impl>>>;
70 
71 template <class Func>
72 implementations_list<Func> get_implementations(const std::shared_ptr<context>& ctx) = delete;
73 
80 template <size_t N>
82 {
83  using array_type = std::array<float, N>;
84 
85  function_score() { _data.fill(1.0f); }
86 
87  array_type& as_array() { return _data; }
88  const array_type& as_array() const { return _data; }
89 protected:
90  array_type _data;
91 };
92 
93 //TODO remove this alias by changing implementations code to avoid this alias.
94 using event = std::shared_ptr<iclgpu::event>;
95 
98 template <typename Func>
99 struct function_impl : context::holder
100 {
101  typedef Func func_type;
102  using holder::holder;
103 
105  virtual const char* name() const = 0;
106 
108  virtual const char* full_name() const = 0;
109 
114  virtual bool accept(const typename Func::params&, typename Func::score&) { return false; }
115 };
116 
119 template <typename Func>
121 {
123 
128  virtual event execute(const typename Func::params& params, const std::vector<event>& dep_events) = 0;
129 };
130 
131 
134 template <typename Func>
136 {
138 
140  using command_builder = std::function<std::shared_ptr<command>(const typename Func::params& params)>;
141 
143  virtual command_builder selected() = 0;
144 };
145 
148 template <class Func>
149 struct score_builder_dot_product : context::holder
150 {
151  using holder::holder;
152  //TODO implement performance DB biases
153  //explicit score_builder_dot_product(const std::shared_ptr<Context>& ctx) : holder(ctx)
154  //{
155  // //auto& bias = bias_score.as_array();
156  // //auto performanceDb = context()->getPerformanceDB();
157  // //auto data = performanceDb->getFunctionBias(Func::name());
158  // //// TODO clarify correct logic for: DB data size does not match scores size
159  // //std::copy(std::begin(data), std::end(data), bias.begin());
160  //}
161 
164  float calculate_score_value(const typename Func::score& score)
165  {
166  // very simple implementation which just inner products scores and bias from performance DB
167  auto& scores = score.as_array();
168 
169  return std::accumulate(std::begin(scores), std::end(scores), 0.f);
170  // TODO implement score calculation using perf DB biases e.g.:
171  // auto& bias = bias_score.as_array();
172  // return std::inner_product(std::begin(scores), std::end(scores), std::begin(bias), 0.0f);
173  }
174 
175  //typename Func::score bias_score;
176 };
177 
178 
182 template <class Func, class ScoreCalculator = score_builder_dot_product<Func>>
183 struct selector_accept : context::holder
184 {
185  explicit selector_accept(const std::shared_ptr<iclgpu::context>& ctx)
186  : holder(ctx)
187  , _score_calculator(ctx->get<ScoreCalculator>()) {}
188 
189 
192  scored_impls_list<Func> select(const typename Func::params& params)
193  {
194  auto impls = functions::get_implementations<Func>(context());
195  if (impls.empty())
196  {
197  throw error_unimplemented("Function is not implemented");
198  }
199 
200  scored_impls_list<Func> result;
201 
202  for (auto& impl : impls)
203  {
204  // note: default constructor for Func::score should initialize fields by 1.0.
205  typename Func::score score;
206  // call accept() for each function implementation,
207  // calculate and select the high score implementation
208  if (impl->accept(params, score))
209  {
210  float calculated_score = _score_calculator->calculate_score_value(score);
211  result.push_back({calculated_score, impl});
212  }
213  }
214 
215  if (result.empty())
216  {
217  throw error_unsupported("Function paramenters are not supported");
218  }
219 
220  std::sort(result.begin(), result.end(), [](const auto& a, const auto& b) { return a.first > b.first; });
221 
222  return result;
223  }
224 
225 private:
226  std::shared_ptr<ScoreCalculator> _score_calculator;
227 };
228 } //namespace functions
229 
231 } // namespace iclgpu
Helper class to select function implementation by calling accept() method for each implementation...
Function implementation with 2-step execution.
Function implementation base class.
std::function< std::shared_ptr< command >(const typename Func::params &params)> command_builder
Functor creates command which executes function implementation.
Global library context provides access to all library objects.
Definition: context.hpp:34
Exception type indicates that provided actual function parameters are not supported.
Definition: errors.hpp:32
virtual bool accept(const typename Func::params &, typename Func::score &)
Check if the implementation supports actual function parameters values.
base class for function score structures
Function implementation supporting direct execution.
float calculate_score_value(const typename Func::score &score)
Calculates implementation score scalar based on function_score structure filled by implementation...
Helper class to calculate implementation score based on &#39;dot-product&#39;.
scored_impls_list< Func > select(const typename Func::params &params)
Creates the list of function implementations which accept specified function parameters.
Exception type indicates that function has no any implementation.
Definition: errors.hpp:21