clDNN
program.hpp
1 /*
2 // Copyright (c) 2016 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 
18 #pragma once
19 #include "cldnn_defs.h"
20 #include "topology.hpp"
21 #include "engine.hpp"
22 #include <iostream>
23 
24 #include <memory>
25 
26 namespace cldnn
27 {
28 
31 
34 
37 {
40 
43 
47 
50 
58 
61 };
62 
64 enum class tuning_mode
65 {
68 
71 
74 };
75 
78 {
79  tuning_mode mode;
80  std::string cache_file_path;
81 
84  cache_file_path("")
85  {}
86 };
87 
90 {
92  static std::shared_ptr<const build_option> fusing(bool enable = false);
93 
95  static std::shared_ptr<const build_option> optimize_data(bool enable = false);
96 
99  static std::shared_ptr<const build_option> debug(bool enable = false);
100 
102  static std::shared_ptr<const build_option> outputs(const std::vector<primitive_id>& outs);
103 
110  static std::shared_ptr<const build_option> tuning_config(const tuning_config_options& config = tuning_config_options());
111 
113  static std::shared_ptr<const build_option> graph_dumps_dir(const std::string& dir_path);
114 
115  virtual ~build_option() = default;
116 
117 private:
119  virtual build_option_type get_type() const = 0;
120 
122  virtual const void* get_data() const = 0;
123 
124  friend class build_options;
125 };
126 
128 template<build_option_type OptType>
130 {
133  explicit build_option_bool(bool value) : _value(value ? 1 : 0) {}
134 
136  explicit build_option_bool(const cldnn_build_option& value)
137  : _value(reinterpret_cast<uintptr_t>(value.data))
138  {
139  assert(value.type == static_cast<int32_t>(OptType));
140  }
141 
143  bool enabled() const { return _value != 0; }
144 private:
145  build_option_type get_type() const override { return OptType; }
146  const void* get_data() const override { return reinterpret_cast<const void*>(_value); }
147  uintptr_t _value;
148 };
149 
152 {
154  const std::vector<primitive_id> outputs;
155 
158  explicit build_option_outputs(const std::vector<primitive_id>& outs)
159  : outputs(outs)
160  , _ref_store(to_refs(outputs))
161  , _outputs_ref({ _ref_store.data(), _ref_store.size() })
162  {}
163 
166  : build_option_outputs(make_outputs_from_ref(value))
167  {
168  assert(value.type == static_cast<int32_t>(cldnn_build_option_outputs));
169  }
170 
171 private:
173  build_option_type get_type() const override { return build_option_type::outputs; }
175  const void* get_data() const override { return &_outputs_ref; }
176 
177  build_option_outputs(const build_option_outputs& other) = delete;
178  build_option_outputs& operator=(const build_option_outputs& other) = delete;
179 
180  const std::vector<cldnn_primitive_id> _ref_store;
181  const cldnn_primitive_id_arr _outputs_ref;
182 
183  static std::vector<cldnn_primitive_id> to_refs(const std::vector<primitive_id>& stor)
184  {
185  std::vector<cldnn_primitive_id> result(stor.size());
186  for (size_t i = 0; i < stor.size(); i++)
187  {
188  result[i] = stor[i].c_str();
189  }
190  return result;
191  }
192 
193  static std::vector<primitive_id> make_outputs_from_ref(const cldnn_build_option& value)
194  {
195  if (value.type != cldnn_build_option_outputs) throw std::invalid_argument("option type does not match: should be 'output'");
196  if (value.data == nullptr) throw std::invalid_argument("output data is empty");
197  auto refs = reinterpret_cast<const cldnn_primitive_id_arr*>(value.data);
198  std::vector<primitive_id> result;
199  result.reserve(refs->size);
200  for (decltype(refs->size) i = 0; i < refs->size; i++)
201  {
202  result.push_back(refs->data[i]);
203  }
204  return result;
205  }
206 };
207 
210 {
213 
218  config_ref({ static_cast<int32_t>(config.mode), config.cache_file_path.c_str() })
219  {}
220 
223  : build_option_tuning_config(make_config_from_ref(value))
224  {
225  assert(value.type == static_cast<int32_t>(cldnn_build_option_tuning_config));
226  }
227 
228 private:
230  build_option_type get_type() const override { return build_option_type::tuning_config; }
232  const void* get_data() const override { return &config_ref; }
233 
235  build_option_tuning_config& operator=(const build_option_tuning_config& other) = delete;
236 
237  const cldnn_tuning_config config_ref;
238 
239  static tuning_config_options make_config_from_ref(const cldnn_build_option& value)
240  {
241  if (value.type != cldnn_build_option_tuning_config) throw std::invalid_argument("option type does not match: should be 'tuning_config'");
242  if (value.data == nullptr) throw std::invalid_argument("Tuning config data is empty");
243  auto refs = reinterpret_cast<const cldnn_tuning_config*>(value.data);
244  tuning_config_options result;
245  result.mode = tuning_mode(refs->mode);
246  result.cache_file_path = std::string(refs->cache_file_path);
247  return result;
248  }
249 };
250 
252 template<build_option_type OptType>
254 {
255  const std::string directory_path;
256 
259  explicit build_option_directory(const std::string& dir_path)
260  : directory_path(dir_path)
261  {}
262 
265  : directory_path(from_c_value(value))
266  {}
267 
268 private:
270  build_option_type get_type() const override { return build_option_type::graph_dumps_dir; }
272  const void* get_data() const override { return (directory_path.empty() ? nullptr : directory_path.c_str()); }
273 
274  build_option_directory(const build_option_directory& other) = delete;
275  build_option_directory& operator=(const build_option_directory& other) = delete;
276 
277  static std::string from_c_value(const cldnn_build_option& value)
278  {
279  if (value.type != static_cast<int32_t>(OptType))
280  throw std::invalid_argument("option type does not match");
281  if (value.data == nullptr)
282  return{};
283 
284  return{ static_cast<const char*>(value.data) };
285  }
286 };
287 
288 namespace detail
289 {
291  template<build_option_type OptType>
293  {
297  static std::shared_ptr<const build_option> make_default();
299  static std::shared_ptr<const build_option> make_option(const cldnn_build_option& option);
300  };
301 
302 #ifndef DOXYGEN_SHOULD_SKIP_THIS
303  template<> struct build_option_traits<build_option_type::fusing>
304  {
306  static std::shared_ptr<const build_option> make_default() { return build_option::fusing(); }
307  static std::shared_ptr<const build_option> make_option(const cldnn_build_option& option)
308  {
309  assert(option.type == cldnn_build_option_fusing);
310  return std::make_shared<object_type>(option);
311  }
312  };
313  template<> struct build_option_traits<build_option_type::optimize_data>
314  {
315  typedef build_option_bool<build_option_type::optimize_data> object_type;
316  static std::shared_ptr<const build_option> make_default() { return build_option::optimize_data(); }
317  static std::shared_ptr<const build_option> make_option(const cldnn_build_option& option)
318  {
319  assert(option.type == cldnn_build_option_optimize_data);
320  return std::make_shared<object_type>(option);
321  }
322  };
323  template<> struct build_option_traits<build_option_type::debug>
324  {
325  typedef build_option_bool<build_option_type::debug> object_type;
326  static std::shared_ptr<const build_option> make_default() { return build_option::debug(); }
327  static std::shared_ptr<const build_option> make_option(const cldnn_build_option& option)
328  {
329  assert(option.type == cldnn_build_option_debug);
330  return std::make_shared<object_type>(option);
331  }
332  };
333  template<> struct build_option_traits<build_option_type::outputs>
334  {
335  typedef build_option_outputs object_type;
336  static std::shared_ptr<const build_option> make_default() { return build_option::outputs({}); }
337  static std::shared_ptr<const build_option> make_option(const cldnn_build_option& option)
338  {
339  assert(option.type == cldnn_build_option_outputs);
340  return std::make_shared<object_type>(option);
341  }
342  };
343  template<> struct build_option_traits<build_option_type::tuning_config>
344  {
345  typedef build_option_tuning_config object_type;
346  static std::shared_ptr<const build_option> make_default() { return build_option::tuning_config(); }
347  static std::shared_ptr<const build_option> make_option(const cldnn_build_option& option)
348  {
349  assert(option.type == cldnn_build_option_tuning_config);
350  return std::make_shared<object_type>(option);
351  }
352  };
353  template<> struct build_option_traits<build_option_type::graph_dumps_dir>
354  {
355  typedef build_option_directory<build_option_type::graph_dumps_dir> object_type;
356  static std::shared_ptr<const build_option> make_default() { return build_option::graph_dumps_dir({}); }
357  static std::shared_ptr<const build_option> make_option(const cldnn_build_option& option)
358  {
359  assert(option.type == cldnn_build_option_graph_dumps_dir);
360  return std::make_shared<object_type>(option);
361  }
362  };
363 #endif
364 } // namespace detail
365 
366 #ifndef DOXYGEN_SHOULD_SKIP_THIS
367 inline std::shared_ptr<const build_option> build_option::fusing(bool enable)
368 {
369  return std::make_shared<build_option_bool<build_option_type::fusing>>(enable);
370 }
371 
372 inline std::shared_ptr<const build_option> build_option::optimize_data(bool enable)
373 {
374  return std::make_shared<build_option_bool<build_option_type::optimize_data>>(enable);
375 }
376 
377 inline std::shared_ptr<const build_option> build_option::debug(bool enable)
378 {
379  return std::make_shared<build_option_bool<build_option_type::debug>>(enable);
380 }
381 
382 inline std::shared_ptr<const build_option> build_option::outputs(const std::vector<primitive_id>& outs)
383 {
384  return std::make_shared<build_option_outputs>(outs);
385 }
386 
387 inline std::shared_ptr<const build_option> build_option::tuning_config(const tuning_config_options& config)
388 {
389  return std::make_shared<build_option_tuning_config>(config);
390 }
391 
392 inline std::shared_ptr<const build_option> build_option::graph_dumps_dir(const std::string& dir_path)
393 {
394  return std::make_shared<build_option_directory<build_option_type::graph_dumps_dir>>(dir_path);
395 }
396 #endif
397 
400 {
401 public:
403  void set_option(std::shared_ptr<const build_option> opt)
404  {
405  add_or_replace_option(opt);
406  }
407 
409  template<typename ...Args>
410  void set_option(std::shared_ptr<const build_option> opt, Args... args)
411  {
412  add_or_replace_option(opt);
413  set_option(args...);
414  }
415 
417  template<typename ...Args>
418  build_options(Args... args)
419  {
420  set_option(args...);
421  }
422 
424  build_options(array_ref<cldnn_build_option> options)
425  {
426  for (auto& o : options)
427  {
428  _options.emplace_back(make_option(o));
429  }
430  }
431 
433  template<build_option_type OptType>
434  std::shared_ptr<const typename detail::build_option_traits<OptType>::object_type>
435  get() const
436  {
438  for (auto& option : _options)
439  {
440  if (option->get_type() == OptType)
441  return std::static_pointer_cast<const T>(option);
442  }
443  return std::static_pointer_cast<const T>(detail::build_option_traits<OptType>::make_default());
444  }
445 
446 private:
447  friend struct program;
448  std::vector<std::shared_ptr<const build_option>> _options;
449  void set_option(void) {}
450 
452  std::vector<cldnn_build_option> get_refs() const
453  {
454  std::vector<cldnn_build_option> result;
455  for (auto& o : _options)
456  {
457  result.push_back({ static_cast<int32_t>(o->get_type()), o->get_data() });
458  }
459  return result;
460  }
461 
462  void add_or_replace_option(std::shared_ptr<const build_option> opt)
463  {
464  for (auto& p : _options)
465  {
466  if (p->get_type() == opt->get_type())
467  {
468  p = opt;
469  return;
470  }
471  }
472  _options.push_back(opt);
473  }
474 
475  static std::shared_ptr<const build_option> make_option(const cldnn_build_option& option)
476  {
477  switch (option.type)
478  {
491  default: throw std::out_of_range("unsupported build option type");
492  }
493  }
494 };
495 
497 struct program
498 {
499  friend struct network;
500 
501 public:
506  program(engine const& engine, topology const& topology, build_options const& options = build_options())
507  :_impl(check_status<cldnn_program>("program creation failed", [&](status_t* status)
508  {
509  auto options_refs = options.get_refs();
510  return cldnn_build_program(engine.get(), topology.get(), options_refs.data(), options_refs.size(), status);
511  }))
512  {}
513 
515  program(program const& other)
516  :_impl(other._impl)
517  {
518  retain();
519  }
520 
523  {
524  release();
525  }
526 
528  program& operator=(const program& other)
529  {
530  if (_impl == other._impl) return *this;
531  release();
532  _impl = other._impl;
533  retain();
534  return *this;
535  }
536 
538  friend bool operator==(const program& lhs, const program& rhs) { return lhs._impl == rhs._impl; }
540  friend bool operator!=(const program& lhs, const program& rhs) { return !(lhs == rhs); }
541 
543  ::cldnn_program get() const { return _impl; }
544 
545 private:
546 
547  ::cldnn_program _impl;
548 
549  program(::cldnn_program impl) : _impl(impl)
550  {
551  if (_impl == nullptr)
552  throw std::invalid_argument("implementation pointer should not be null");
553  }
554 
555  void retain()
556  {
557  check_status<void>("retain topology failed", [=](status_t* status) { cldnn_retain_program(_impl, status); });
558  }
559  void release()
560  {
561  check_status<void>("retain topology failed", [=](status_t* status) { cldnn_release_program(_impl, status); });
562  }
563 };
566 }
program(program const &other)
Retains the C API cldnn_program handler stored in other.
Definition: program.hpp:515
Tuning config.
Definition: cldnn.h:197
build_option_bool(bool value)
Constructs option.
Definition: program.hpp:133
static std::shared_ptr< const build_option > debug(bool enable=false)
Enable debug mode (default: false).
Tuning config (default: Tuning is disabled).
Allow primitives fusing during network build.
Definition: cldnn.h:180
Represents program build options list.
Definition: program.hpp:399
::cldnn_engine get() const
get C API engine handler.
Definition: engine.hpp:180
build_option specialization for program outputs list.
Definition: program.hpp:151
static std::shared_ptr< const build_option > graph_dumps_dir(const std::string &dir_path)
Specifies a directory to which stages of network compilation should be dumped (default: empty...
Tuning using the cached data (no on-line tuning for non-existing data).
Definition: cldnn.h:192
build_option object_type
build_option object type which represents the particular OptType.
Definition: program.hpp:295
User selected list of network outputs.
Definition: cldnn.h:183
build_option_directory(const cldnn_build_option &value)
Constructs from C API cldnn_build_option.
Definition: program.hpp:264
Represents network build option.
Definition: cldnn.h:204
program & operator=(const program &other)
Assigns new value by releasing previously referenced C API cldnn_program handler and retaining the on...
Definition: program.hpp:528
build_option specialization for tuning config.
Definition: program.hpp:209
Enable implicit reordering for user input.
Definition: cldnn.h:181
static std::shared_ptr< const build_option > tuning_config(const tuning_config_options &config=tuning_config_options())
Tuning configuration (default: false).
Represents user-provided program build option.
Definition: program.hpp:89
Compiled program build from topology by engine.
Definition: program.hpp:497
tuning_mode
Tuning mode.
Definition: program.hpp:64
Tuning using the cached data (no on-line tuning for non-existing data).
struct cldnn_program_impl * cldnn_program
Compiled program build from cldnn_topology by cldnn_engine.
Definition: cldnn.h:111
static std::shared_ptr< const build_option > make_option(const cldnn_build_option &option)
Make build_option from C API cldnn_build_option.
Enable debug mode (default: false).
friend bool operator==(const program &lhs, const program &rhs)
Checks whether lhs and rhs reference the same C API cldnn_program handler.
Definition: program.hpp:538
program(engine const &engine, topology const &topology, build_options const &options=build_options())
Builds executable program based on user-defined topology by specified engine.
Definition: program.hpp:506
Enable debug mode.
Definition: cldnn.h:182
static std::shared_ptr< const build_option > fusing(bool enable=false)
Allow primitives fusing during program build (default: false).
void set_option(std::shared_ptr< const build_option > opt, Args... args)
Adds or replace options to the options list.
Definition: program.hpp:410
void set_option(std::shared_ptr< const build_option > opt)
Adds or replace option to the options list.
Definition: program.hpp:403
build_option specialization for boolean options.
Definition: program.hpp:129
Specifies a directory to which stages of network compilation should be dumped.
Definition: cldnn.h:185
Enable implicit reordering for user inputs (default: false).
Provides input data to topology.
Definition: data.hpp:36
CLDNN_API void cldnn_release_program(cldnn_program program, cldnn_status *status)
Decrement reference counter for the program object. Deletes object when counter becomes zero...
const tuning_config_options config
Tuning configuration.
Definition: program.hpp:212
bool enabled() const
Is option enabled.
Definition: program.hpp:143
build_option_tuning_config(const tuning_config_options &tuning_config)
Constructs tuning config build option.
Definition: program.hpp:216
CLDNN_API void cldnn_retain_program(cldnn_program program, cldnn_status *status)
Increment reference counter for the program object.
User selected list of program outputs.
build_option_bool(const cldnn_build_option &value)
Constructs from C API cldnn_build_option.
Definition: program.hpp:136
Tuning is disabled.
Definition: cldnn.h:191
const int32_t mode
cldnn_tuning_mode_type.
Definition: cldnn.h:199
Tuning using the cached data if exist, tune and update cache otherwise.
build_option_outputs(const std::vector< primitive_id > &outs)
Constructs option.
Definition: program.hpp:158
build_option_outputs(const cldnn_build_option &value)
Constructs from C API cldnn_build_option.
Definition: program.hpp:165
~program()
Dereferences the counter of the underlying C API cldnn_program handler.
Definition: program.hpp:522
Allow primitives fusing during program build (default: false).
Network topology to be defined by user.
Definition: topology.hpp:33
Helper template to convert build_option_type value to particular build_option class.
Definition: program.hpp:292
build_option_tuning_config(const cldnn_build_option &value)
Constructs tuning config build option from C API cldnn_build_option.
Definition: program.hpp:222
Tuning using the cached data if exist, tune and update cache otherwise.
Definition: cldnn.h:193
build_option_directory(const std::string &dir_path)
Constructs option.
Definition: program.hpp:259
Tuning configuration.
Definition: program.hpp:77
static std::shared_ptr< const build_option > make_default()
Make default build_option corresponding OptType.
const void * data
option parameter - e.g list of outputs.
Definition: cldnn.h:207
static std::shared_ptr< const build_option > outputs(const std::vector< primitive_id > &outs)
User selected list of program outputs.
Represents reference to an array of primitive ids.
Definition: cldnn.h:335
cldnn_topology get() const
Returns wrapped C API cldnn_topology.
Definition: topology.hpp:89
Executable network allocated from program.
Definition: network.hpp:59
int32_t type
cldnn_build_option_type.
Definition: cldnn.h:206
Represents clDNN engine object.
Definition: engine.hpp:110
build_option_type
Represents user-provided program build option type.
Definition: program.hpp:36
build_option specialization for selecting a directory.
Definition: program.hpp:253
friend bool operator!=(const program &lhs, const program &rhs)
Checks whether lhs and rhs reference different C API cldnn_program handlers.
Definition: program.hpp:540
CLDNN_API cldnn_program cldnn_build_program(cldnn_engine engine, cldnn_topology topology, cldnn_build_option *options, size_t options_num, cldnn_status *status)
Builds executable program based on user-defined topology by specified engine.
build_options(Args... args)
Constructs build options list from its arguments.
Definition: program.hpp:418
static std::shared_ptr< const build_option > optimize_data(bool enable=false)
Enable implicit reordering for user inputs (default: false).
const std::vector< primitive_id > outputs
The list of output ids (names)
Definition: program.hpp:154
build_options(array_ref< cldnn_build_option > options)
Constructs build options list from C API ::cldnn_build_options.
Definition: program.hpp:424
Specifies a directory to which stages of network compilation should be dumped. (default: empty...