Commit 86e60176 authored by Marian Triebe's avatar Marian Triebe

Apply new coding style

parent f2a33b6a
This diff is collapsed.
...@@ -35,115 +35,99 @@ ...@@ -35,115 +35,99 @@
namespace caf { namespace caf {
namespace opencl { namespace opencl {
template<typename T, typename R> template <typename T, typename R>
class command : public ref_counted { class command : public ref_counted {
public: public:
command(response_promise handle, intrusive_ptr<T> actor_facade,
std::vector<cl_event> events, std::vector<mem_ptr> arguments,
size_t result_size, any_tuple msg)
: m_result_size(result_size)
, m_handle(handle)
, m_actor_facade(actor_facade)
, m_queue(actor_facade->m_queue)
, m_events(std::move(events))
, m_arguments(std::move(arguments))
, m_result(m_result_size)
, m_msg(msg) {}
command(response_promise handle, ~command() {
intrusive_ptr<T> actor_facade, cl_int err{0};
std::vector<cl_event> events, for (auto& e : m_events) {
std::vector<mem_ptr> arguments, err = clReleaseEvent(e);
size_t result_size, if (err != CL_SUCCESS) {
any_tuple msg) CPPA_LOGMF(CPPA_ERROR, "clReleaseEvent: " << get_opencl_error(err));
: m_result_size(result_size) }
, m_handle(handle)
, m_actor_facade(actor_facade)
, m_queue(actor_facade->m_queue)
, m_events(std::move(events))
, m_arguments(std::move(arguments))
, m_result(m_result_size)
, m_msg(msg) { }
~command() {
cl_int err{0};
for(auto& e : m_events) {
err = clReleaseEvent(e);
if (err != CL_SUCCESS) {
CPPA_LOGMF(CPPA_ERROR, "clReleaseEvent: "
<< get_opencl_error(err));
}
}
} }
}
void enqueue () { void enqueue() {
CPPA_LOG_TRACE("command::enqueue()"); CPPA_LOG_TRACE("command::enqueue()");
this->ref(); // reference held by the OpenCL comand queue this->ref(); // reference held by the OpenCL comand queue
cl_int err{0}; cl_int err{0};
cl_event event_k; cl_event event_k;
auto data_or_nullptr = [](const dim_vec& vec) { auto data_or_nullptr = [](const dim_vec& vec) {
return vec.empty() ? nullptr : vec.data(); return vec.empty() ? nullptr : vec.data();
}; };
err = clEnqueueNDRangeKernel(m_queue.get(), err = clEnqueueNDRangeKernel(
m_actor_facade->m_kernel.get(), m_queue.get(), m_actor_facade->m_kernel.get(),
m_actor_facade->m_global_dimensions.size(), m_actor_facade->m_global_dimensions.size(),
data_or_nullptr(m_actor_facade->m_global_offsets), data_or_nullptr(m_actor_facade->m_global_offsets),
data_or_nullptr(m_actor_facade->m_global_dimensions), data_or_nullptr(m_actor_facade->m_global_dimensions),
data_or_nullptr(m_actor_facade->m_local_dimensions), data_or_nullptr(m_actor_facade->m_local_dimensions), m_events.size(),
m_events.size(), (m_events.empty() ? nullptr : m_events.data()), &event_k);
(m_events.empty() ? nullptr : m_events.data()), if (err != CL_SUCCESS) {
&event_k); CPPA_LOGMF(CPPA_ERROR,
if (err != CL_SUCCESS) { "clEnqueueNDRangeKernel: " << get_opencl_error(err));
CPPA_LOGMF(CPPA_ERROR, "clEnqueueNDRangeKernel: " this->deref(); // or can anything actually happen?
<< get_opencl_error(err)); return;
this->deref(); // or can anything actually happen? } else {
return; cl_event event_r;
} err =
else { clEnqueueReadBuffer(m_queue.get(), m_arguments.back().get(), CL_FALSE,
cl_event event_r; 0, sizeof(typename R::value_type) * m_result_size,
err = clEnqueueReadBuffer(m_queue.get(), m_result.data(), 1, &event_k, &event_r);
m_arguments.back().get(), if (err != CL_SUCCESS) {
CL_FALSE, throw std::runtime_error("clEnqueueReadBuffer: " +
0, get_opencl_error(err));
sizeof(typename R::value_type) * m_result_size, this->deref(); // failed to enqueue command
m_result.data(), return;
1, }
&event_k, err = clSetEventCallback(event_r, CL_COMPLETE,
&event_r); [](cl_event, cl_int, void* data) {
if (err != CL_SUCCESS) { auto cmd = reinterpret_cast<command*>(data);
throw std::runtime_error("clEnqueueReadBuffer: " cmd->handle_results();
+ get_opencl_error(err)); cmd->deref();
this->deref(); // failed to enqueue command },
return; this);
} if (err != CL_SUCCESS) {
err = clSetEventCallback(event_r, CPPA_LOGMF(CPPA_ERROR, "clSetEventCallback: " << get_opencl_error(err));
CL_COMPLETE, this->deref(); // callback is not set
[](cl_event, cl_int, void* data) { return;
auto cmd = reinterpret_cast<command*>(data); }
cmd->handle_results();
cmd->deref();
},
this);
if (err != CL_SUCCESS) {
CPPA_LOGMF(CPPA_ERROR, "clSetEventCallback: "
<< get_opencl_error(err));
this->deref(); // callback is not set
return;
}
err = clFlush(m_queue.get()); err = clFlush(m_queue.get());
if (err != CL_SUCCESS) { if (err != CL_SUCCESS) {
CPPA_LOGMF(CPPA_ERROR, "clFlush: " << get_opencl_error(err)); CPPA_LOGMF(CPPA_ERROR, "clFlush: " << get_opencl_error(err));
} }
m_events.push_back(std::move(event_k)); m_events.push_back(std::move(event_k));
m_events.push_back(std::move(event_r)); m_events.push_back(std::move(event_r));
}
} }
}
private: private:
int m_result_size;
response_promise m_handle;
intrusive_ptr<T> m_actor_facade;
command_queue_ptr m_queue;
std::vector<cl_event> m_events;
std::vector<mem_ptr> m_arguments;
R m_result;
any_tuple m_msg; // required to keep the argument buffers alive (async copy)
int m_result_size; void handle_results() {
response_promise m_handle; m_handle.deliver(m_actor_facade->m_map_result(m_result));
intrusive_ptr<T> m_actor_facade; }
command_queue_ptr m_queue;
std::vector<cl_event> m_events;
std::vector<mem_ptr> m_arguments;
R m_result;
any_tuple m_msg; // required to keep the argument buffers alive (for async copy)
void handle_results () {
m_handle.deliver(m_actor_facade->m_map_result(m_result));
}
}; };
} // namespace opencl } // namespace opencl
......
...@@ -29,32 +29,28 @@ namespace opencl { ...@@ -29,32 +29,28 @@ namespace opencl {
class device_info { class device_info {
friend class program; friend class program;
public: public:
device_info(device_ptr device, command_queue_ptr queue,
device_info(device_ptr device, size_t work_group_size, cl_uint dimensons,
command_queue_ptr queue, const dim_vec& items_per_dimension)
size_t work_group_size, : m_max_work_group_size(work_group_size)
cl_uint dimensons, , m_max_dimensions(dimensons)
const dim_vec& items_per_dimension) , m_max_work_items_per_dim(items_per_dimension)
: m_max_work_group_size(work_group_size) , m_device(device)
, m_max_dimensions(dimensons) , m_cmd_queue(queue) {}
, m_max_work_items_per_dim(items_per_dimension)
, m_device(device) inline size_t get_max_work_group_size();
, m_cmd_queue(queue) { } inline cl_uint get_max_dimensions();
inline dim_vec get_max_work_items_per_dim();
inline size_t get_max_work_group_size();
inline cl_uint get_max_dimensions();
inline dim_vec get_max_work_items_per_dim();
private: private:
size_t m_max_work_group_size;
size_t m_max_work_group_size; cl_uint m_max_dimensions;
cl_uint m_max_dimensions; dim_vec m_max_work_items_per_dim;
dim_vec m_max_work_items_per_dim; device_ptr m_device;
device_ptr m_device; command_queue_ptr m_cmd_queue;
command_queue_ptr m_cmd_queue;
}; };
/******************************************************************************\ /******************************************************************************\
...@@ -62,19 +58,16 @@ class device_info { ...@@ -62,19 +58,16 @@ class device_info {
\******************************************************************************/ \******************************************************************************/
inline size_t device_info::get_max_work_group_size() { inline size_t device_info::get_max_work_group_size() {
return m_max_work_group_size; return m_max_work_group_size;
} }
inline cl_uint device_info::get_max_dimensions() { inline cl_uint device_info::get_max_dimensions() { return m_max_dimensions; }
return m_max_dimensions;
}
inline dim_vec device_info::get_max_work_items_per_dim() { inline dim_vec device_info::get_max_work_items_per_dim() {
return m_max_work_items_per_dim; return m_max_work_items_per_dim;
} }
} // namespace opencl } // namespace opencl
} // namespace caf } // namespace caf
#endif // CAF_OPENCL_DEVICE_INFO_HPP #endif // CAF_OPENCL_DEVICE_INFO_HPP
...@@ -25,9 +25,9 @@ ...@@ -25,9 +25,9 @@
#include "caf/detail/limited_vector.hpp" #include "caf/detail/limited_vector.hpp"
#if defined __APPLE__ || defined(MACOSX) #if defined __APPLE__ || defined(MACOSX)
#include <OpenCL/opencl.h> #include <OpenCL/opencl.h>
#else #else
#include <CL/opencl.h> #include <CL/opencl.h>
#endif #endif
namespace caf { namespace caf {
...@@ -40,8 +40,8 @@ typedef detail::limited_vector<size_t, 3> dim_vec; ...@@ -40,8 +40,8 @@ typedef detail::limited_vector<size_t, 3> dim_vec;
std::string get_opencl_error(cl_int err); std::string get_opencl_error(cl_int err);
cl_int clReleaseDeviceDummy (cl_device_id); cl_int clReleaseDeviceDummy(cl_device_id);
cl_int clRetainDeviceDummy (cl_device_id); cl_int clRetainDeviceDummy(cl_device_id);
} // namespace opencl } // namespace opencl
} // namespace caf } // namespace caf
......
...@@ -41,27 +41,24 @@ namespace opencl { ...@@ -41,27 +41,24 @@ namespace opencl {
class opencl_metainfo { class opencl_metainfo {
friend class program; friend class program;
friend class detail::singleton_manager; friend class detail::singleton_manager;
friend command_queue_ptr get_command_queue(uint32_t id); friend command_queue_ptr get_command_queue(uint32_t id);
public: public:
const std::vector<device_info> get_devices() const;
const std::vector<device_info> get_devices() const;
private: private:
static inline opencl_metainfo* create_singleton() {
return new opencl_metainfo;
}
static inline opencl_metainfo* create_singleton() { void initialize();
return new opencl_metainfo; void dispose();
} void destroy();
void initialize();
void dispose();
void destroy();
context_ptr m_context;
std::vector<device_info> m_devices;
context_ptr m_context;
std::vector<device_info> m_devices;
}; };
opencl_metainfo* get_opencl_metainfo(); opencl_metainfo* get_opencl_metainfo();
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
namespace caf { namespace caf {
namespace opencl { namespace opencl {
template<typename Signature> template <typename Signature>
class actor_facade; class actor_facade;
/** /**
...@@ -36,26 +36,24 @@ class actor_facade; ...@@ -36,26 +36,24 @@ class actor_facade;
*/ */
class program { class program {
template<typename Signature> template <typename Signature>
friend class actor_facade; friend class actor_facade;
public: public:
/**
/** * @brief Factory method, that creates a cppa::opencl::program
* @brief Factory method, that creates a cppa::opencl::program * from a given @p kernel_source.
* from a given @p kernel_source. * @returns A program object.
* @returns A program object. */
*/ static program create(const char* kernel_source,
static program create(const char* kernel_source, const char* options = nullptr, uint32_t device_id = 0); const char* options = nullptr, uint32_t device_id = 0);
private: private:
program(context_ptr context, command_queue_ptr queue, program_ptr program);
program(context_ptr context, command_queue_ptr queue, program_ptr program); context_ptr m_context;
program_ptr m_program;
context_ptr m_context; command_queue_ptr m_queue;
program_ptr m_program;
command_queue_ptr m_queue;
}; };
} // namespace opencl } // namespace opencl
......
...@@ -27,86 +27,84 @@ ...@@ -27,86 +27,84 @@
namespace caf { namespace caf {
namespace opencl { namespace opencl {
template<typename T, cl_int (*ref)(T), cl_int (*deref)(T)> template <typename T, cl_int (*ref)(T), cl_int (*deref)(T)>
class smart_ptr { class smart_ptr {
typedef typename std::remove_pointer<T>::type element_type; typedef typename std::remove_pointer<T>::type element_type;
typedef element_type* pointer;
typedef element_type& reference;
typedef const element_type* const_pointer;
typedef const element_type& const_reference;
typedef element_type* pointer;
typedef element_type& reference;
typedef const element_type* const_pointer;
typedef const element_type& const_reference;
public: public:
smart_ptr(pointer ptr = nullptr) : m_ptr(ptr) {
if (m_ptr)
ref(m_ptr);
}
smart_ptr(pointer ptr = nullptr) : m_ptr(ptr) { ~smart_ptr() { reset(); }
if (m_ptr) ref(m_ptr);
}
~smart_ptr() { reset(); }
smart_ptr(const smart_ptr& other) : m_ptr(other.m_ptr) { smart_ptr(const smart_ptr& other) : m_ptr(other.m_ptr) {
if (m_ptr) ref(m_ptr); if (m_ptr)
} ref(m_ptr);
}
smart_ptr(smart_ptr&& other) : m_ptr(other.m_ptr) { smart_ptr(smart_ptr&& other) : m_ptr(other.m_ptr) { other.m_ptr = nullptr; }
other.m_ptr = nullptr;
}
smart_ptr& operator=(pointer ptr) { smart_ptr& operator=(pointer ptr) {
reset(ptr); reset(ptr);
return *this; return *this;
} }
smart_ptr& operator=(smart_ptr&& other) { smart_ptr& operator=(smart_ptr&& other) {
std::swap(m_ptr, other.m_ptr); std::swap(m_ptr, other.m_ptr);
return *this; return *this;
} }
smart_ptr& operator=(const smart_ptr& other) { smart_ptr& operator=(const smart_ptr& other) {
smart_ptr tmp{other}; smart_ptr tmp{other};
std::swap(m_ptr, tmp.m_ptr); std::swap(m_ptr, tmp.m_ptr);
return *this; return *this;
} }
inline void reset(pointer ptr = nullptr) { inline void reset(pointer ptr = nullptr) {
if (m_ptr) deref(m_ptr); if (m_ptr)
m_ptr = ptr; deref(m_ptr);
if (ptr) ref(ptr); m_ptr = ptr;
} if (ptr)
ref(ptr);
}
// does not modify reference count of ptr // does not modify reference count of ptr
inline void adopt(pointer ptr) { inline void adopt(pointer ptr) {
reset(); reset();
m_ptr = ptr; m_ptr = ptr;
} }
inline pointer get() const { return m_ptr; } inline pointer get() const { return m_ptr; }
inline pointer operator->() const { return m_ptr; } inline pointer operator->() const { return m_ptr; }
inline reference operator*() const { return *m_ptr; } inline reference operator*() const { return *m_ptr; }
inline bool operator!() const { return m_ptr == nullptr; } inline bool operator!() const { return m_ptr == nullptr; }
inline explicit operator bool() const { return m_ptr != nullptr; } inline explicit operator bool() const { return m_ptr != nullptr; }
private: private:
pointer m_ptr;
pointer m_ptr;
}; };
typedef smart_ptr<cl_mem, clRetainMemObject, clReleaseMemObject> mem_ptr; typedef smart_ptr<cl_mem, clRetainMemObject, clReleaseMemObject> mem_ptr;
typedef smart_ptr<cl_event, clRetainEvent, clReleaseEvent> event_ptr; typedef smart_ptr<cl_event, clRetainEvent, clReleaseEvent> event_ptr;
typedef smart_ptr<cl_kernel, clRetainKernel, clReleaseKernel> kernel_ptr; typedef smart_ptr<cl_kernel, clRetainKernel, clReleaseKernel> kernel_ptr;
typedef smart_ptr<cl_context, clRetainContext, clReleaseContext> context_ptr; typedef smart_ptr<cl_context, clRetainContext, clReleaseContext> context_ptr;
typedef smart_ptr<cl_program, clRetainProgram, clReleaseProgram> program_ptr; typedef smart_ptr<cl_program, clRetainProgram, clReleaseProgram> program_ptr;
typedef smart_ptr<cl_device_id, clRetainDeviceDummy, clReleaseDeviceDummy> typedef smart_ptr<cl_device_id, clRetainDeviceDummy, clReleaseDeviceDummy>
device_ptr; device_ptr;
typedef smart_ptr<cl_command_queue, clRetainCommandQueue, clReleaseCommandQueue> typedef smart_ptr<cl_command_queue, clRetainCommandQueue, clReleaseCommandQueue>
command_queue_ptr; command_queue_ptr;
} // namespace opencl } // namespace opencl
} // namespace caf } // namespace caf
......
...@@ -38,64 +38,57 @@ namespace caf { ...@@ -38,64 +38,57 @@ namespace caf {
namespace detail { namespace detail {
// converts C arrays, i.e., pointers, to vectors // converts C arrays, i.e., pointers, to vectors
template<typename T> template <typename T>
struct carr_to_vec { typedef T type; }; struct carr_to_vec {
typedef T type;
};
template<typename T> template <typename T>
struct carr_to_vec<T*> { typedef std::vector<T> type; }; struct carr_to_vec<T*> {
typedef std::vector<T> type;
};
template<typename Signature, typename SecondSignature = void> template <typename Signature, typename SecondSignature = void>
struct cl_spawn_helper; struct cl_spawn_helper;
template<typename R, typename... Ts> template <typename R, typename... Ts>
struct cl_spawn_helper<R (Ts...), void> { struct cl_spawn_helper<R(Ts...), void> {
using result_type = typename carr_to_vec<R>::type; using result_type = typename carr_to_vec<R>::type;
using impl = opencl::actor_facade< using impl = opencl::actor_facade<
result_type (typename carr_to_vec< result_type(typename carr_to_vec<typename carr_to_vec<Ts>::type>::type...)>;
typename carr_to_vec<Ts>::type using map_arg_fun = typename impl::arg_mapping;
>::type...) using map_res_fun = typename impl::result_mapping;
>;
using map_arg_fun = typename impl::arg_mapping; template <typename... Us>
using map_res_fun = typename impl::result_mapping; actor operator()(map_arg_fun f0, map_res_fun f1, const opencl::program& p,
const char* fname, Us&&... args) const {
template<typename... Us> using std::move;
actor operator()(map_arg_fun f0, using std::forward;
map_res_fun f1, return impl::create(p, fname, move(f0), move(f1), forward<Us>(args)...);
const opencl::program& p, }
const char* fname,
Us&&... args) const {
using std::move;
using std::forward;
return impl::create(p, fname, move(f0), move(f1), forward<Us>(args)...);
}
template<typename... Us>
actor operator()(const opencl::program& p,
const char* fname,
Us&&... args) const {
using std::move;
using std::forward;
map_arg_fun f0 = [] (any_tuple msg) {
return tuple_cast<
typename util::rm_const_and_ref<
typename carr_to_vec<Ts>::type
>::type...
>(msg);
};
map_res_fun f1 = [] (result_type& result) {
return make_any_tuple(move(result));
};
return impl::create(p, fname, move(f0), move(f1), forward<Us>(args)...);
}
template <typename... Us>
actor operator()(const opencl::program& p, const char* fname,
Us&&... args) const {
using std::move;
using std::forward;
map_arg_fun f0 = [](any_tuple msg) {
return tuple_cast<typename util::rm_const_and_ref<
typename carr_to_vec<Ts>::type>::type...>(msg);
};
map_res_fun f1 = [](result_type& result) {
return make_any_tuple(move(result));
};
return impl::create(p, fname, move(f0), move(f1), forward<Us>(args)...);
}
}; };
template<typename R, typename... Ts> template <typename R, typename... Ts>
struct cl_spawn_helper<std::function<optional<cow_tuple<Ts...>> (any_tuple)>, struct cl_spawn_helper<std::function<optional<cow_tuple<Ts...>>(any_tuple)>,
std::function<any_tuple (R&)>> std::function<any_tuple(R&)>>
: cl_spawn_helper<R (Ts...)> { }; : cl_spawn_helper<R(Ts...)> {};
} // namespace detail } // namespace detail
...@@ -106,16 +99,14 @@ struct cl_spawn_helper<std::function<optional<cow_tuple<Ts...>> (any_tuple)>, ...@@ -106,16 +99,14 @@ struct cl_spawn_helper<std::function<optional<cow_tuple<Ts...>> (any_tuple)>,
* <tt>dims.empty()</tt>, or @p clCreateKernel * <tt>dims.empty()</tt>, or @p clCreateKernel
* failed. * failed.
*/ */
template<typename Signature, typename... Ts> template <typename Signature, typename... Ts>
inline actor spawn_cl(const opencl::program& prog, inline actor
const char* fname, spawn_cl(const opencl::program& prog, const char* fname,
const opencl::dim_vec& dims, const opencl::dim_vec& dims, const opencl::dim_vec& offset = {},
const opencl::dim_vec& offset = {}, const opencl::dim_vec& local_dims = {}, size_t result_size = 0) {
const opencl::dim_vec& local_dims = {}, using std::move;
size_t result_size = 0) { detail::cl_spawn_helper<Signature> f;
using std::move; return f(prog, fname, dims, offset, local_dims, result_size);
detail::cl_spawn_helper<Signature> f;
return f(prog, fname, dims, offset, local_dims, result_size);
} }
/** /**
...@@ -125,20 +116,14 @@ inline actor spawn_cl(const opencl::program& prog, ...@@ -125,20 +116,14 @@ inline actor spawn_cl(const opencl::program& prog,
* <tt>dims.empty()</tt>, a compilation error * <tt>dims.empty()</tt>, a compilation error
* occured, or @p clCreateKernel failed. * occured, or @p clCreateKernel failed.
*/ */
template<typename Signature, typename... Ts> template <typename Signature, typename... Ts>
inline actor spawn_cl(const char* source, inline actor
const char* fname, spawn_cl(const char* source, const char* fname, const opencl::dim_vec& dims,
const opencl::dim_vec& dims, const opencl::dim_vec& offset = {},
const opencl::dim_vec& offset = {}, const opencl::dim_vec& local_dims = {}, size_t result_size = 0) {
const opencl::dim_vec& local_dims = {}, using std::move;
size_t result_size = 0) { return spawn_cl<Signature, Ts...>(opencl::program::create(source), fname,
using std::move; dims, offset, local_dims, result_size);
return spawn_cl<Signature, Ts...>(opencl::program::create(source),
fname,
dims,
offset,
local_dims,
result_size);
} }
/** /**
...@@ -150,27 +135,18 @@ inline actor spawn_cl(const char* source, ...@@ -150,27 +135,18 @@ inline actor spawn_cl(const char* source,
* <tt>dims.empty()</tt>, or @p clCreateKernel * <tt>dims.empty()</tt>, or @p clCreateKernel
* failed. * failed.
*/ */
template<typename MapArgs, typename MapResult> template <typename MapArgs, typename MapResult>
inline actor spawn_cl(const opencl::program& prog, inline actor
const char* fname, spawn_cl(const opencl::program& prog, const char* fname, MapArgs map_args,
MapArgs map_args, MapResult map_result, const opencl::dim_vec& dims,
MapResult map_result, const opencl::dim_vec& offset = {},
const opencl::dim_vec& dims, const opencl::dim_vec& local_dims = {}, size_t result_size = 0) {
const opencl::dim_vec& offset = {}, using std::move;
const opencl::dim_vec& local_dims = {}, typedef typename util::get_callable_trait<MapArgs>::fun_type f0;
size_t result_size = 0) { typedef typename util::get_callable_trait<MapResult>::fun_type f1;
using std::move; detail::cl_spawn_helper<f0, f1> f;
typedef typename util::get_callable_trait<MapArgs>::fun_type f0; return f(f0{move(map_args)}, f1{move(map_result)}, prog, fname, dims, offset,
typedef typename util::get_callable_trait<MapResult>::fun_type f1; local_dims, result_size);
detail::cl_spawn_helper<f0, f1> f;
return f(f0{move(map_args)},
f1{move(map_result)},
prog,
fname,
dims,
offset,
local_dims,
result_size);
} }
/** /**
...@@ -182,24 +158,15 @@ inline actor spawn_cl(const opencl::program& prog, ...@@ -182,24 +158,15 @@ inline actor spawn_cl(const opencl::program& prog,
* <tt>dims.empty()</tt>, a compilation error * <tt>dims.empty()</tt>, a compilation error
* occured, or @p clCreateKernel failed. * occured, or @p clCreateKernel failed.
*/ */
template<typename MapArgs, typename MapResult> template <typename MapArgs, typename MapResult>
inline actor spawn_cl(const char* source, inline actor
const char* fun_name, spawn_cl(const char* source, const char* fun_name, MapArgs map_args,
MapArgs map_args, MapResult map_result, const opencl::dim_vec& dims,
MapResult map_result, const opencl::dim_vec& offset = {},
const opencl::dim_vec& dims, const opencl::dim_vec& local_dims = {}, size_t result_size = 0) {
const opencl::dim_vec& offset = {}, using std::move;
const opencl::dim_vec& local_dims = {}, return spawn_cl(opencl::program::create(source), fun_name, move(map_args),
size_t result_size = 0) { move(map_result), dims, offset, local_dims, result_size);
using std::move;
return spawn_cl(opencl::program::create(source),
fun_name,
move(map_args),
move(map_result),
dims,
offset,
local_dims,
result_size);
} }
} // namespace caf } // namespace caf
......
...@@ -23,108 +23,108 @@ namespace caf { ...@@ -23,108 +23,108 @@ namespace caf {
namespace opencl { namespace opencl {
std::string get_opencl_error(cl_int err) { std::string get_opencl_error(cl_int err) {
switch (err) { switch (err) {
case CL_SUCCESS: case CL_SUCCESS:
return "CL_SUCCESS"; return "CL_SUCCESS";
case CL_DEVICE_NOT_FOUND: case CL_DEVICE_NOT_FOUND:
return "CL_DEVICE_NOT_FOUND"; return "CL_DEVICE_NOT_FOUND";
case CL_DEVICE_NOT_AVAILABLE: case CL_DEVICE_NOT_AVAILABLE:
return "CL_DEVICE_NOT_AVAILABLE"; return "CL_DEVICE_NOT_AVAILABLE";
case CL_COMPILER_NOT_AVAILABLE: case CL_COMPILER_NOT_AVAILABLE:
return "CL_COMPILER_NOT_AVAILABLE"; return "CL_COMPILER_NOT_AVAILABLE";
case CL_MEM_OBJECT_ALLOCATION_FAILURE: case CL_MEM_OBJECT_ALLOCATION_FAILURE:
return "CL_MEM_OBJECT_ALLOCATION_FAILURE"; return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
case CL_OUT_OF_RESOURCES: case CL_OUT_OF_RESOURCES:
return "CL_OUT_OF_RESOURCES"; return "CL_OUT_OF_RESOURCES";
case CL_OUT_OF_HOST_MEMORY: case CL_OUT_OF_HOST_MEMORY:
return "CL_OUT_OF_HOST_MEMORY"; return "CL_OUT_OF_HOST_MEMORY";
case CL_PROFILING_INFO_NOT_AVAILABLE: case CL_PROFILING_INFO_NOT_AVAILABLE:
return "CL_PROFILING_INFO_NOT_AVAILABLE"; return "CL_PROFILING_INFO_NOT_AVAILABLE";
case CL_MEM_COPY_OVERLAP: case CL_MEM_COPY_OVERLAP:
return "CL_MEM_COPY_OVERLAP"; return "CL_MEM_COPY_OVERLAP";
case CL_IMAGE_FORMAT_MISMATCH: case CL_IMAGE_FORMAT_MISMATCH:
return "CL_IMAGE_FORMAT_MISMATCH"; return "CL_IMAGE_FORMAT_MISMATCH";
case CL_IMAGE_FORMAT_NOT_SUPPORTED: case CL_IMAGE_FORMAT_NOT_SUPPORTED:
return "CL_IMAGE_FORMAT_NOT_SUPPORTED"; return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
case CL_BUILD_PROGRAM_FAILURE: case CL_BUILD_PROGRAM_FAILURE:
return "CL_BUILD_PROGRAM_FAILURE"; return "CL_BUILD_PROGRAM_FAILURE";
case CL_MAP_FAILURE: case CL_MAP_FAILURE:
return "CL_MAP_FAILURE"; return "CL_MAP_FAILURE";
case CL_INVALID_VALUE: case CL_INVALID_VALUE:
return "CL_INVALID_VALUE"; return "CL_INVALID_VALUE";
case CL_INVALID_DEVICE_TYPE: case CL_INVALID_DEVICE_TYPE:
return "CL_INVALID_DEVICE_TYPE"; return "CL_INVALID_DEVICE_TYPE";
case CL_INVALID_PLATFORM: case CL_INVALID_PLATFORM:
return "CL_INVALID_PLATFORM"; return "CL_INVALID_PLATFORM";
case CL_INVALID_DEVICE: case CL_INVALID_DEVICE:
return "CL_INVALID_DEVICE"; return "CL_INVALID_DEVICE";
case CL_INVALID_CONTEXT: case CL_INVALID_CONTEXT:
return "CL_INVALID_CONTEXT"; return "CL_INVALID_CONTEXT";
case CL_INVALID_QUEUE_PROPERTIES: case CL_INVALID_QUEUE_PROPERTIES:
return "CL_INVALID_QUEUE_PROPERTIES"; return "CL_INVALID_QUEUE_PROPERTIES";
case CL_INVALID_COMMAND_QUEUE: case CL_INVALID_COMMAND_QUEUE:
return "CL_INVALID_COMMAND_QUEUE"; return "CL_INVALID_COMMAND_QUEUE";
case CL_INVALID_HOST_PTR: case CL_INVALID_HOST_PTR:
return "CL_INVALID_HOST_PTR"; return "CL_INVALID_HOST_PTR";
case CL_INVALID_MEM_OBJECT: case CL_INVALID_MEM_OBJECT:
return "CL_INVALID_MEM_OBJECT"; return "CL_INVALID_MEM_OBJECT";
case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:
return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"; return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
case CL_INVALID_IMAGE_SIZE: case CL_INVALID_IMAGE_SIZE:
return "CL_INVALID_IMAGE_SIZE"; return "CL_INVALID_IMAGE_SIZE";
case CL_INVALID_SAMPLER: case CL_INVALID_SAMPLER:
return "CL_INVALID_SAMPLER"; return "CL_INVALID_SAMPLER";
case CL_INVALID_BINARY: case CL_INVALID_BINARY:
return "CL_INVALID_BINARY"; return "CL_INVALID_BINARY";
case CL_INVALID_BUILD_OPTIONS: case CL_INVALID_BUILD_OPTIONS:
return "CL_INVALID_BUILD_OPTIONS"; return "CL_INVALID_BUILD_OPTIONS";
case CL_INVALID_PROGRAM: case CL_INVALID_PROGRAM:
return "CL_INVALID_PROGRAM"; return "CL_INVALID_PROGRAM";
case CL_INVALID_PROGRAM_EXECUTABLE: case CL_INVALID_PROGRAM_EXECUTABLE:
return "CL_INVALID_PROGRAM_EXECUTABLE"; return "CL_INVALID_PROGRAM_EXECUTABLE";
case CL_INVALID_KERNEL_NAME: case CL_INVALID_KERNEL_NAME:
return "CL_INVALID_KERNEL_NAME"; return "CL_INVALID_KERNEL_NAME";
case CL_INVALID_KERNEL_DEFINITION: case CL_INVALID_KERNEL_DEFINITION:
return "CL_INVALID_KERNEL_DEFINITION"; return "CL_INVALID_KERNEL_DEFINITION";
case CL_INVALID_KERNEL: case CL_INVALID_KERNEL:
return "CL_INVALID_KERNEL"; return "CL_INVALID_KERNEL";
case CL_INVALID_ARG_INDEX: case CL_INVALID_ARG_INDEX:
return "CL_INVALID_ARG_INDEX"; return "CL_INVALID_ARG_INDEX";
case CL_INVALID_ARG_VALUE: case CL_INVALID_ARG_VALUE:
return "CL_INVALID_ARG_VALUE"; return "CL_INVALID_ARG_VALUE";
case CL_INVALID_ARG_SIZE: case CL_INVALID_ARG_SIZE:
return "CL_INVALID_ARG_SIZE"; return "CL_INVALID_ARG_SIZE";
case CL_INVALID_KERNEL_ARGS: case CL_INVALID_KERNEL_ARGS:
return "CL_INVALID_KERNEL_ARGS"; return "CL_INVALID_KERNEL_ARGS";
case CL_INVALID_WORK_DIMENSION: case CL_INVALID_WORK_DIMENSION:
return "CL_INVALID_WORK_DIMENSION"; return "CL_INVALID_WORK_DIMENSION";
case CL_INVALID_WORK_GROUP_SIZE: case CL_INVALID_WORK_GROUP_SIZE:
return "CL_INVALID_WORK_GROUP_SIZE"; return "CL_INVALID_WORK_GROUP_SIZE";
case CL_INVALID_WORK_ITEM_SIZE: case CL_INVALID_WORK_ITEM_SIZE:
return "CL_INVALID_WORK_ITEM_SIZE"; return "CL_INVALID_WORK_ITEM_SIZE";
case CL_INVALID_GLOBAL_OFFSET: case CL_INVALID_GLOBAL_OFFSET:
return "CL_INVALID_GLOBAL_OFFSET"; return "CL_INVALID_GLOBAL_OFFSET";
case CL_INVALID_EVENT_WAIT_LIST: case CL_INVALID_EVENT_WAIT_LIST:
return "CL_INVALID_EVENT_WAIT_LIST"; return "CL_INVALID_EVENT_WAIT_LIST";
case CL_INVALID_EVENT: case CL_INVALID_EVENT:
return "CL_INVALID_EVENT"; return "CL_INVALID_EVENT";
case CL_INVALID_OPERATION: case CL_INVALID_OPERATION:
return "CL_INVALID_OPERATION"; return "CL_INVALID_OPERATION";
case CL_INVALID_GL_OBJECT: case CL_INVALID_GL_OBJECT:
return "CL_INVALID_GL_OBJECT"; return "CL_INVALID_GL_OBJECT";
case CL_INVALID_BUFFER_SIZE: case CL_INVALID_BUFFER_SIZE:
return "CL_INVALID_BUFFER_SIZE"; return "CL_INVALID_BUFFER_SIZE";
case CL_INVALID_MIP_LEVEL: case CL_INVALID_MIP_LEVEL:
return "CL_INVALID_MIP_LEVEL"; return "CL_INVALID_MIP_LEVEL";
case CL_INVALID_GLOBAL_WORK_SIZE: case CL_INVALID_GLOBAL_WORK_SIZE:
return "CL_INVALID_GLOBAL_WORK_SIZE"; return "CL_INVALID_GLOBAL_WORK_SIZE";
default: return "UNKNOWN_ERROR"; default:
} return "UNKNOWN_ERROR";
}
} }
cl_int clReleaseDeviceDummy (cl_device_id) { return 0; } cl_int clReleaseDeviceDummy(cl_device_id) { return 0; }
cl_int clRetainDeviceDummy (cl_device_id) { return 0; } cl_int clRetainDeviceDummy(cl_device_id) { return 0; }
} // namespace opencl } // namespace opencl
} // namespace caf } // namespace caf
This diff is collapsed.
...@@ -31,83 +31,73 @@ using namespace std; ...@@ -31,83 +31,73 @@ using namespace std;
namespace caf { namespace caf {
namespace opencl { namespace opencl {
program::program(context_ptr context, command_queue_ptr queue,
program::program(context_ptr context, command_queue_ptr queue, program_ptr program) program_ptr program)
: m_context(move(context)), m_program(move(program)), m_queue(move(queue)) { } : m_context(move(context))
, m_program(move(program))
program program::create(const char* kernel_source, const char* options, uint32_t device_id) { , m_queue(move(queue)) {}
auto metainfo = get_opencl_metainfo();
auto devices = metainfo->get_devices(); program program::create(const char* kernel_source, const char* options,
auto context = metainfo->m_context; uint32_t device_id) {
auto metainfo = get_opencl_metainfo();
auto devices = metainfo->get_devices();
if (devices.size() <= device_id) { auto context = metainfo->m_context;
ostringstream oss;
oss << "Device id " << device_id if (devices.size() <= device_id) {
<< " is not a vaild device. Maximum id is: " ostringstream oss;
<< (devices.size() -1) << "."; oss << "Device id " << device_id
CPPA_LOGM_ERROR(detail::demangle<program>().c_str(), oss.str()); << " is not a vaild device. Maximum id is: " << (devices.size() - 1)
throw runtime_error(oss.str()); << ".";
} CPPA_LOGM_ERROR(detail::demangle<program>().c_str(), oss.str());
throw runtime_error(oss.str());
cl_int err{0}; }
// create program object from kernel source cl_int err{0};
size_t kernel_source_length = strlen(kernel_source);
program_ptr pptr; // create program object from kernel source
pptr.adopt(clCreateProgramWithSource(context.get(), size_t kernel_source_length = strlen(kernel_source);
1, program_ptr pptr;
&kernel_source, pptr.adopt(clCreateProgramWithSource(context.get(), 1, &kernel_source,
&kernel_source_length, &kernel_source_length, &err));
&err)); if (err != CL_SUCCESS) {
if (err != CL_SUCCESS) { throw runtime_error("clCreateProgramWithSource: " + get_opencl_error(err));
throw runtime_error("clCreateProgramWithSource: " }
+ get_opencl_error(err));
} // build programm from program object
auto dev_tmp = devices[device_id].m_device.get();
// build programm from program object err = clBuildProgram(pptr.get(), 1, &dev_tmp, options, nullptr, nullptr);
auto dev_tmp = devices[device_id].m_device.get(); if (err != CL_SUCCESS) {
err = clBuildProgram(pptr.get(), 1, &dev_tmp, options, nullptr, nullptr); ostringstream oss;
if (err != CL_SUCCESS) { oss << "clBuildProgram: " << get_opencl_error(err);
ostringstream oss; // the build log will be printed by the
oss << "clBuildProgram: " << get_opencl_error(err); // pfn_notify (see opencl_metainfo.cpp)
// the build log will be printed by the
// pfn_notify (see opencl_metainfo.cpp)
#ifndef __APPLE__ #ifndef __APPLE__
// seems that just apple implemented the // seems that just apple implemented the
// pfn_notify callback, but we can get // pfn_notify callback, but we can get
// the build log // the build log
if(err == CL_BUILD_PROGRAM_FAILURE) { if (err == CL_BUILD_PROGRAM_FAILURE) {
size_t buildlog_buffer_size = 0; size_t buildlog_buffer_size = 0;
// get the log length // get the log length
clGetProgramBuildInfo(pptr.get(), clGetProgramBuildInfo(pptr.get(), dev_tmp, CL_PROGRAM_BUILD_LOG,
dev_tmp, sizeof(buildlog_buffer_size), nullptr,
CL_PROGRAM_BUILD_LOG, &buildlog_buffer_size);
sizeof(buildlog_buffer_size),
nullptr, vector<char> buffer(buildlog_buffer_size);
&buildlog_buffer_size);
// fill the buffer with buildlog informations
vector<char> buffer(buildlog_buffer_size); clGetProgramBuildInfo(pptr.get(), dev_tmp, CL_PROGRAM_BUILD_LOG,
sizeof(buffer[0]) * buildlog_buffer_size,
// fill the buffer with buildlog informations buffer.data(), nullptr);
clGetProgramBuildInfo(pptr.get(),
dev_tmp, CPPA_LOGC_ERROR("cppa::opencl::program", "create",
CL_PROGRAM_BUILD_LOG, "Build log:\n" + string(buffer.data()) +
sizeof(buffer[0]) * buildlog_buffer_size, "\n########################################");
buffer.data(),
nullptr);
CPPA_LOGC_ERROR("cppa::opencl::program",
"create",
"Build log:\n" + string(buffer.data()) +
"\n########################################");
}
#endif
throw runtime_error(oss.str());
} }
return {context, devices[device_id].m_cmd_queue, pptr}; #endif
throw runtime_error(oss.str());
}
return {context, devices[device_id].m_cmd_queue, pptr};
} }
} // namespace opencl } // namespace opencl
} // namespace caf } // namespace caf
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment