20 #include <type_traits> 29 template <
class T,
class U>
30 auto down_pointer_cast(
const std::shared_ptr<U>& r)
31 ->
typename std::enable_if<std::is_base_of<U, T>::value && !std::is_same<U, T>::value, std::shared_ptr<T>>::type
33 auto res = std::dynamic_pointer_cast<T>(r);
35 throw std::bad_cast();
39 template <
class T,
class U>
40 auto down_pointer_cast(
const std::shared_ptr<U>& r)
41 ->
typename std::enable_if<std::is_same<T, U>::value, std::shared_ptr<T>>::type
60 template <
class EngTy = engine>
62 -> typename std::enable_if<std::is_base_of<engine, EngTy>::value, std::shared_ptr<EngTy>>::type
64 return down_pointer_cast<EngTy>(_engine);
68 std::shared_ptr<engine> _engine;
74 using engine_object::engine_object;
77 virtual std::chrono::nanoseconds wait() = 0;
91 id_t id()
const {
return _id; }
102 using engine_object::engine_object;
108 virtual std::shared_ptr<event> submit(
const std::vector<std::shared_ptr<event>>& dependencies = {},
115 using engine_object::engine_object;
117 virtual size_t size()
const = 0;
119 virtual void* get_host_ptr() = 0;
123 enum direction { none = 0x0, input = 0x1, output = 0x2, inout = input | output };
139 , _owning_engine(nullptr)
152 , _capacity(buffer->size())
153 , _size(size != 0 ? size : buffer->size())
155 , _buffers({{buffer->get_engine(), buffer}})
157 assert(_capacity >= _size);
172 void* get_host_ptr()
const;
175 void reset_host_ptr()
const;
178 size_t size()
const {
return _size; }
185 void size(
size_t size);
189 std::shared_ptr<buffer> get_buffer(
const std::shared_ptr<engine>&
engine)
const;
191 bool is_output()
const {
return (_direction & output) != 0; }
192 bool is_input()
const {
return (_direction & input) != 0; }
197 return _size != 0 && (_host_ptr || _owning_engine);
202 mutable void* _host_ptr;
205 std::shared_ptr<engine> _owning_engine;
206 mutable std::map<std::shared_ptr<engine>, std::shared_ptr<buffer>> _buffers;
209 template <
typename ElemTy>
size_t sizeof_t() {
return sizeof(ElemTy); }
210 template <>
inline size_t sizeof_t<void>() {
return 1; }
215 using command::command;
221 using command::command;
224 void push_back(
const std::shared_ptr<command>&
command);
226 std::shared_ptr<event> submit(
const std::vector<std::shared_ptr<event>>& dependencies = {},
229 std::vector<std::shared_ptr<command>> _commands;
235 using command::command;
238 void add(
const std::shared_ptr<command>&
command);
240 std::shared_ptr<event> submit(
const std::vector<std::shared_ptr<event>>& dependencies = {},
243 std::vector<std::shared_ptr<command>> _commands;
251 , _values{0, 0, 0} {}
255 , _values{x, 0, 0} {}
259 , _values{x, y, 0} {}
261 nd_range(
size_t x,
size_t y,
size_t z)
263 , _values{x, y, z} {}
265 size_t dimensions()
const {
return _size; }
266 const size_t* values()
const {
return _values; }
268 const size_t& operator[](
size_t idx)
const 274 size_t& operator[](
size_t idx)
309 using command::command;
314 template <
typename T>
316 ->
typename std::enable_if<!std::is_pointer<T>::value>::type
318 set_scalar_arg(idx, &value,
sizeof(T));
324 void set_arg(
unsigned idx,
const std::shared_ptr<buffer_binding>& value)
326 assert(value->is_defined());
327 set_buffer_arg(idx, value);
340 virtual void set_scalar_arg(
unsigned idx,
const void* ptr,
size_t size) = 0;
346 virtual void set_buffer_arg(
unsigned idx,
const std::shared_ptr<buffer_binding>& binding) = 0;
349 template <
typename ElemTy, direction Dir>
class blob;
354 virtual ~
engine() =
default;
362 virtual std::shared_ptr<kernel_command> get_kernel(
const std::string& name,
363 const std::string& module = std::string()) = 0;
368 virtual std::shared_ptr<buffer> create_buffer(
size_t size,
void* ptr =
nullptr) = 0;
371 virtual std::shared_ptr<raise_event_command> get_raise_event_command() = 0;
375 virtual std::shared_ptr<commands_sequence> get_commands_sequence(
const std::vector<std::shared_ptr<command>>& commands = {}) = 0;
379 virtual std::shared_ptr<commands_parallel> get_commands_parallel(
const std::vector<std::shared_ptr<command>>& commands = {}) = 0;
382 template <
typename T =
char>
385 if (num == 0)
throw std::invalid_argument(
"size should not be zero.");
386 return std::make_shared<buffer_binding>(create_buffer(num * sizeof_t<T>(),
nullptr), none);
390 template <
typename T, direction Dir>
392 ->
typename std::enable_if<(Dir & input) != 0, std::shared_ptr<buffer_binding>>::type
394 return set_binding_options<T>(blob.get(), num, input);
398 template <
typename T, direction Dir>
399 static auto get_output_buffer(
const blob<T, Dir>& blob,
size_t num)
400 ->
typename std::enable_if<(Dir & output) != 0, std::shared_ptr<buffer_binding>>::type
402 return set_binding_options<T>(blob.get(), num, output);
406 template <
typename T, direction Dir>
408 ->
typename std::enable_if<Dir == inout, std::shared_ptr<buffer_binding>>::type
410 return set_binding_options<T>(blob.get(), num, Dir);
414 template <
typename T>
415 static std::shared_ptr<buffer_binding> set_binding_options(std::shared_ptr<buffer_binding>&& binding,
419 binding->set_direction(dir);
420 binding->size(num * sizeof_t<T>());
static auto get_inout_buffer(const blob< T, Dir > &blob, size_t num) -> typename std::enable_if< Dir==inout, std::shared_ptr< buffer_binding >>::type
Get in-out buffer binding from Blob object.
Base class for a command.
direction
Represents data direction for kernel command.
bool is_defined() const
Check if binding is fully defined: size is set and constructed from correct host-allocated pointer of...
const nd_range & work_size() const
Range for kernel instances (global worksize)
auto get_engine() const -> typename std::enable_if< std::is_base_of< engine, EngTy >::value, std::shared_ptr< EngTy >>::type
Returns associated Engine object.
Binds host data and memory buffers per engine describing data direction (in/out) for kernel...
direction get_direction() const
Get direction of the binding.
Represents a command queue within an Engine.
Represents an event object assotiated with a executed Command.
The base class for all Engine connected objects.
Represents kernel command.
Represents data Blob object passed to a Function.
Base class for execution engines.
buffer_binding(const std::shared_ptr< buffer > &buffer, direction dir=inout, size_t size=0)
Constructs binding from engine-allocated memory buffer.
size_t capacity() const
Returns maximum possible size value.
void set_arg(unsigned idx, const std::shared_ptr< buffer_binding > &value)
Set kernel argument (specialized for data buffers)
auto set_arg(unsigned idx, const T &value) -> typename std::enable_if<!std::is_pointer< T >::value >::type
Set kernel argument.
buffer_binding(void *ptr, size_t size=0, direction dir=inout)
Constructs binding from host-allocated buffer.
Kernel execution options.
size_t size() const
Returns size of data.
const std::shared_ptr< engine > & get_owning_engine() const
Returns engine of the buffer passed to constructor or NULL if consrtucted from host-allocated data...
const nd_range & parallel_size() const
Range of kernel instances to be executed in paralled (local worksize)
std::shared_ptr< buffer_binding > get_temp_buffer(size_t num)
Create temporary buffer with num elements of T.
Helper class to store kernel sources.
Represents set of command can be executed in parallel.
Represents ND (1D, 2D, 3D) ranges for kernels executions.
Represents set of command to be executed sequentially.
Represents a command which just raises an event.
Represents memory buffer.