Commit e5f44ee4 authored by Joseph Noir's avatar Joseph Noir

Cleanup (addresses review)

parent f314c210
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
* http://www.boost.org/LICENSE_1_0.txt. * * http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/ ******************************************************************************/
#ifndef CAF_OPENCL_OPENCL_ACTOR_HPP #ifndef CAF_OPENCL_ACTOR_FACADE_HPP
#define CAF_OPENCL_OPENCL_ACTOR_HPP #define CAF_OPENCL_ACTOR_FACADE_HPP
#include <ostream> #include <ostream>
#include <iostream> #include <iostream>
...@@ -29,69 +29,27 @@ ...@@ -29,69 +29,27 @@
#include "caf/intrusive_ptr.hpp" #include "caf/intrusive_ptr.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/detail/limited_vector.hpp" #include "caf/detail/limited_vector.hpp"
#include "caf/opencl/global.hpp" #include "caf/opencl/global.hpp"
#include "caf/opencl/command.hpp" #include "caf/opencl/command.hpp"
#include "caf/opencl/mem_ref.hpp" #include "caf/opencl/mem_ref.hpp"
#include "caf/opencl/program.hpp" #include "caf/opencl/program.hpp"
#include "caf/opencl/nd_range.hpp"
#include "caf/opencl/arguments.hpp" #include "caf/opencl/arguments.hpp"
#include "caf/opencl/smart_ptr.hpp"
#include "caf/opencl/opencl_err.hpp" #include "caf/opencl/opencl_err.hpp"
#include "caf/opencl/nd_range.hpp"
#include "caf/opencl/detail/core.hpp"
#include "caf/opencl/detail/raw_ptr.hpp"
#include "caf/opencl/detail/command_helper.hpp"
namespace caf { namespace caf {
namespace opencl { namespace opencl {
class manager; class manager;
// signature for the function that is applied to output arguments
template <class List>
struct output_function_sig;
template <class... Ts>
struct output_function_sig<detail::type_list<Ts...>> {
using type = std::function<message (Ts&...)>;
};
// convert to mem_ref
template <class T>
struct to_mem_ref {
using type = mem_ref<T>;
};
template <class T>
struct to_mem_ref<std::vector<T>> {
using type = mem_ref<T>;
};
template <class T>
struct to_mem_ref<T*> {
using type = mem_ref<T>;
};
// derive signature of the command that handles the kernel execution
template <class T, class List>
struct command_sig;
template <class T, class... Ts>
struct command_sig<T, detail::type_list<Ts...>> {
using type = command<T, Ts...>;
};
// derive type for a tuple matching the arguments as mem_refs
template <class List>
struct tuple_type_of;
template <class... Ts>
struct tuple_type_of<detail::type_list<Ts...>> {
using type = std::tuple<Ts...>;
};
template <bool PassConfig, class... Ts> template <bool PassConfig, class... Ts>
class opencl_actor : public monitorable_actor { class actor_facade : public monitorable_actor {
public: public:
using arg_types = detail::type_list<Ts...>; using arg_types = detail::type_list<Ts...>;
using unpacked_types = typename detail::tl_map<arg_types, extract_type>::type; using unpacked_types = typename detail::tl_map<arg_types, extract_type>::type;
...@@ -109,18 +67,18 @@ public: ...@@ -109,18 +67,18 @@ public:
typename detail::tl_filter<arg_types, is_output_arg>::type; typename detail::tl_filter<arg_types, is_output_arg>::type;
using output_types = using output_types =
typename detail::tl_map<output_wrapped_types, extract_output_type>::type; typename detail::tl_map<output_wrapped_types, extract_output_type>::type;
using output_mapping = typename output_function_sig<output_types>::type; using output_mapping = typename detail::output_function_sig<output_types>::type;
using processing_list = typename cl_arg_info_list<arg_types>::type; using processing_list = typename cl_arg_info_list<arg_types>::type;
using command_type = typename command_sig<opencl_actor, output_types>::type; using command_type = typename detail::command_sig<actor_facade, output_types>::type;
typename detail::il_indices<arg_types>::type indices; typename detail::il_indices<arg_types>::type indices;
using evnt_vec = std::vector<cl_event>; using evnt_vec = std::vector<cl_event>;
using mem_vec = std::vector<cl_mem_ptr>; using mem_vec = std::vector<detail::raw_mem_ptr>;
using len_vec = std::vector<size_t>; using len_vec = std::vector<size_t>;
using out_tup = typename tuple_type_of<output_types>::type; using out_tup = typename detail::tuple_type_of<output_types>::type;
const char* name() const override { const char* name() const override {
return "OpenCL actor"; return "OpenCL actor";
...@@ -149,18 +107,18 @@ public: ...@@ -149,18 +107,18 @@ public:
auto& sys = actor_conf.host->system(); auto& sys = actor_conf.host->system();
auto itr = prog->available_kernels_.find(kernel_name); auto itr = prog->available_kernels_.find(kernel_name);
if (itr == prog->available_kernels_.end()) { if (itr == prog->available_kernels_.end()) {
cl_kernel_ptr kernel; detail::raw_kernel_ptr kernel;
kernel.reset(v2get(CAF_CLF(clCreateKernel), prog->program_.get(), kernel.reset(v2get(CAF_CLF(clCreateKernel), prog->program_.get(),
kernel_name), kernel_name),
false); false);
return make_actor<opencl_actor, actor>(sys.next_actor_id(), sys.node(), return make_actor<actor_facade, actor>(sys.next_actor_id(), sys.node(),
&sys, std::move(actor_conf), &sys, std::move(actor_conf),
prog, kernel, range, prog, kernel, range,
std::move(map_args), std::move(map_args),
std::move(map_result), std::move(map_result),
std::forward_as_tuple(xs...)); std::forward_as_tuple(xs...));
} }
return make_actor<opencl_actor, actor>(sys.next_actor_id(), sys.node(), return make_actor<actor_facade, actor>(sys.next_actor_id(), sys.node(),
&sys, std::move(actor_conf), &sys, std::move(actor_conf),
prog, itr->second, range, prog, itr->second, range,
std::move(map_args), std::move(map_args),
...@@ -219,11 +177,12 @@ public: ...@@ -219,11 +177,12 @@ public:
void enqueue(strong_actor_ptr sender, message_id mid, void enqueue(strong_actor_ptr sender, message_id mid,
message content, execution_unit* host) override { message content, execution_unit* host) override {
CAF_LOG_TRACE(""); CAF_LOG_TRACE("");
enqueue(make_mailbox_element(sender, mid, {}, std::move(content)), host); enqueue(make_mailbox_element(std::move(sender), mid, {},
std::move(content)), host);
} }
opencl_actor(actor_config actor_conf, const program_ptr prog, actor_facade(actor_config actor_conf, const program_ptr prog,
cl_kernel_ptr kernel, nd_range range, detail::raw_kernel_ptr kernel, nd_range range,
input_mapping map_args, output_mapping map_result, input_mapping map_args, output_mapping map_result,
std::tuple<Ts...> xs) std::tuple<Ts...> xs)
: monitorable_actor(actor_conf), : monitorable_actor(actor_conf),
...@@ -243,7 +202,8 @@ public: ...@@ -243,7 +202,8 @@ public:
} }
void add_kernel_arguments(evnt_vec&, mem_vec&, mem_vec&, mem_vec&, void add_kernel_arguments(evnt_vec&, mem_vec&, mem_vec&, mem_vec&,
out_tup&, len_vec&, message&, detail::int_list<>) { out_tup&, len_vec&, message&,
detail::int_list<>) {
// nop // nop
} }
...@@ -254,7 +214,7 @@ public: ...@@ -254,7 +214,7 @@ public:
void add_kernel_arguments(evnt_vec& events, mem_vec& inputs, mem_vec& outputs, void add_kernel_arguments(evnt_vec& events, mem_vec& inputs, mem_vec& outputs,
mem_vec& scratch, out_tup& result, len_vec& lengths, mem_vec& scratch, out_tup& result, len_vec& lengths,
message& msg, detail::int_list<I, Is...>) { message& msg, detail::int_list<I, Is...>) {
using arg_type = typename caf::detail::tl_at<processing_list,I>::type; using arg_type = typename detail::tl_at<processing_list,I>::type;
create_buffer<I, arg_type::in_pos, arg_type::out_pos>( create_buffer<I, arg_type::in_pos, arg_type::out_pos>(
std::get<I>(kernel_signature_), events, lengths, inputs, std::get<I>(kernel_signature_), events, lengths, inputs,
outputs, scratch, result, msg outputs, scratch, result, msg
...@@ -340,7 +300,7 @@ public: ...@@ -340,7 +300,7 @@ public:
sizeof(cl_mem), static_cast<const void*>(&buffer)); sizeof(cl_mem), static_cast<const void*>(&buffer));
events.push_back(event); events.push_back(event);
std::get<OutPos>(result) = mem_ref<value_type>{ std::get<OutPos>(result) = mem_ref<value_type>{
len, queue_, cl_mem_ptr{buffer, false}, len, queue_, detail::raw_mem_ptr{buffer, false},
size_t{CL_MEM_READ_WRITE | CL_MEM_HOST_READ_ONLY}, nullptr size_t{CL_MEM_READ_WRITE | CL_MEM_HOST_READ_ONLY}, nullptr
}; };
} }
...@@ -435,7 +395,7 @@ public: ...@@ -435,7 +395,7 @@ public:
void create_buffer(const local<T>& wrapper, evnt_vec&, len_vec&, void create_buffer(const local<T>& wrapper, evnt_vec&, len_vec&,
mem_vec&, mem_vec&, mem_vec&, out_tup&, mem_vec&, mem_vec&, mem_vec&, out_tup&,
message& msg) { message& msg) {
using value_type = typename detail::tl_at<unpacked_types, I>::type; using value_type = typename detail::tl_at<unpacked_types, I>::type;
auto len = wrapper(msg); auto len = wrapper(msg);
auto num_bytes = sizeof(value_type) * len; auto num_bytes = sizeof(value_type) * len;
v1callcl(CAF_CLF(clSetKernelArg), kernel_.get(), static_cast<unsigned>(I), v1callcl(CAF_CLF(clSetKernelArg), kernel_.get(), static_cast<unsigned>(I),
...@@ -468,12 +428,12 @@ public: ...@@ -468,12 +428,12 @@ public:
template <class Fun> template <class Fun>
size_t argument_length(Fun& f, message& m, size_t fallback) { size_t argument_length(Fun& f, message& m, size_t fallback) {
auto length = f(m); auto length = f(m);
return length && (*length > 0) ? *length : fallback; return length && (*length > 0) ? *length : fallback;
} }
// Map function requires only the message as argument // Map function requires only the message as argument
template <bool Q = PassConfig> template <bool Q = PassConfig>
typename std::enable_if<!Q, bool>::type map_arguments(message& content) { detail::enable_if_t<!Q, bool> map_arguments(message& content) {
if (map_args_) { if (map_args_) {
auto mapped = map_args_(content); auto mapped = map_args_(content);
if (!mapped) { if (!mapped) {
...@@ -487,7 +447,7 @@ public: ...@@ -487,7 +447,7 @@ public:
// Map function requires reference to config as well as the message // Map function requires reference to config as well as the message
template <bool Q = PassConfig> template <bool Q = PassConfig>
typename std::enable_if<Q, bool>::type map_arguments(message& content) { detail::enable_if_t<Q, bool> map_arguments(message& content) {
if (map_args_) { if (map_args_) {
auto mapped = map_args_(range_, content); auto mapped = map_args_(range_, content);
if (!mapped) { if (!mapped) {
...@@ -499,10 +459,10 @@ public: ...@@ -499,10 +459,10 @@ public:
return true; return true;
} }
cl_kernel_ptr kernel_; detail::raw_kernel_ptr kernel_;
cl_program_ptr program_; detail::raw_program_ptr program_;
cl_context_ptr context_; detail::raw_context_ptr context_;
cl_command_queue_ptr queue_; detail::raw_command_queue_ptr queue_;
nd_range range_; nd_range range_;
input_mapping map_args_; input_mapping map_args_;
output_mapping map_results_; output_mapping map_results_;
...@@ -512,5 +472,5 @@ public: ...@@ -512,5 +472,5 @@ public:
} // namespace opencl } // namespace opencl
} // namespace caf } // namespace caf
#endif // CAF_OPENCL_OPENCL_ACTOR_HPP
#endif // CAF_OPENCL_ACTOR_FACADE_HPP
This diff is collapsed.
...@@ -34,10 +34,12 @@ ...@@ -34,10 +34,12 @@
#include "caf/detail/scope_guard.hpp" #include "caf/detail/scope_guard.hpp"
#include "caf/opencl/global.hpp" #include "caf/opencl/global.hpp"
#include "caf/opencl/nd_range.hpp"
#include "caf/opencl/arguments.hpp" #include "caf/opencl/arguments.hpp"
#include "caf/opencl/smart_ptr.hpp"
#include "caf/opencl/opencl_err.hpp" #include "caf/opencl/opencl_err.hpp"
#include "caf/opencl/nd_range.hpp"
#include "caf/opencl/detail/core.hpp"
#include "caf/opencl/detail/raw_ptr.hpp"
namespace caf { namespace caf {
namespace opencl { namespace opencl {
...@@ -54,9 +56,9 @@ public: ...@@ -54,9 +56,9 @@ public:
command(response_promise promise, command(response_promise promise,
strong_actor_ptr parent, strong_actor_ptr parent,
std::vector<cl_event> events, std::vector<cl_event> events,
std::vector<cl_mem_ptr> inputs, std::vector<detail::raw_mem_ptr> inputs,
std::vector<cl_mem_ptr> outputs, std::vector<detail::raw_mem_ptr> outputs,
std::vector<cl_mem_ptr> scratches, std::vector<detail::raw_mem_ptr> scratches,
std::vector<size_t> lengths, std::vector<size_t> lengths,
message msg, message msg,
std::tuple<Ts...> output_tuple, std::tuple<Ts...> output_tuple,
...@@ -68,7 +70,7 @@ public: ...@@ -68,7 +70,7 @@ public:
input_buffers_(std::move(inputs)), input_buffers_(std::move(inputs)),
output_buffers_(std::move(outputs)), output_buffers_(std::move(outputs)),
scratch_buffers_(std::move(scratches)), scratch_buffers_(std::move(scratches)),
results_(output_tuple), results_(std::move(output_tuple)),
msg_(std::move(msg)), msg_(std::move(msg)),
range_(std::move(range)) { range_(std::move(range)) {
// nop // nop
...@@ -85,19 +87,16 @@ public: ...@@ -85,19 +87,16 @@ public:
} }
} }
/// Enqueue the kernel for execution, schedule reading of the results and /// Enqueue the kernel for execution, schedule reading of the results and
/// set a callback to send the results to the actor identified by the handle. /// set a callback to send the results to the actor identified by the handle.
/// Only called if the results includes at least one type that is not a /// Only called if the results includes at least one type that is not a
/// mem_ref. /// mem_ref.
template <class Q = result_types> template <class Q = result_types>
typename std::enable_if< detail::enable_if_t<!detail::tl_forall<Q, is_ref_type>::value>
!detail::tl_forall<Q, is_ref_type>::value,
void
>::type
enqueue() { enqueue() {
// Errors in this function can not be handled by opencl_err.hpp // Errors in this function can not be handled by opencl_err.hpp
// because they require non-standard error handling // because they require non-standard error handling
CAF_LOG_TRACE("command::enqueue() mixed"); CAF_LOG_TRACE("");
this->ref(); // reference held by the OpenCL comand queue this->ref(); // reference held by the OpenCL comand queue
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();
...@@ -105,8 +104,8 @@ public: ...@@ -105,8 +104,8 @@ public:
auto parent = static_cast<Actor*>(actor_cast<abstract_actor*>(cl_actor_)); auto parent = static_cast<Actor*>(actor_cast<abstract_actor*>(cl_actor_));
// OpenCL expects cl_uint (unsigned int), hence the cast // OpenCL expects cl_uint (unsigned int), hence the cast
mem_out_events_.emplace_back(); mem_out_events_.emplace_back();
cl_int err = clEnqueueNDRangeKernel( auto success = invoke_cl(
parent->queue_.get(), parent->kernel_.get(), clEnqueueNDRangeKernel, parent->queue_.get(), parent->kernel_.get(),
static_cast<unsigned int>(range_.dimensions().size()), static_cast<unsigned int>(range_.dimensions().size()),
data_or_nullptr(range_.offsets()), data_or_nullptr(range_.offsets()),
data_or_nullptr(range_.dimensions()), data_or_nullptr(range_.dimensions()),
...@@ -115,51 +114,34 @@ public: ...@@ -115,51 +114,34 @@ public:
(mem_in_events_.empty() ? nullptr : mem_in_events_.data()), (mem_in_events_.empty() ? nullptr : mem_in_events_.data()),
&mem_out_events_.back() &mem_out_events_.back()
); );
if (err != CL_SUCCESS) { if (!success)
CAF_LOG_ERROR("clEnqueueNDRangeKernel: "
<< CAF_ARG(get_opencl_error(err)));
this->deref();
return; return;
}
size_t pos = 0; size_t pos = 0;
CAF_ASSERT(!mem_out_events_.empty()); CAF_ASSERT(!mem_out_events_.empty());
enqueue_read_buffers(pos, mem_out_events_, detail::get_indices(results_)); enqueue_read_buffers(pos, mem_out_events_,
detail::get_indices(results_));
CAF_ASSERT(mem_out_events_.size() > 1); CAF_ASSERT(mem_out_events_.size() > 1);
cl_event marker_event; cl_event marker_event;
#if defined(__APPLE__) #if defined(__APPLE__)
err = clEnqueueMarkerWithWaitList( success = invoke_cl(clEnqueueMarkerWithWaitList, parent->queue_.get(),
parent->queue_.get(), static_cast<unsigned int>(mem_out_events_.size()),
static_cast<unsigned int>(mem_out_events_.size()), mem_out_events_.data(), &marker_event);
mem_out_events_.data(),
&marker_event
);
std::string name = "clEnqueueMarkerWithWaitList";
#else #else
err = clEnqueueMarker(parent->queue_.get(), &marker_event); success = invoke_cl(clEnqueueMarker, parent->queue_.get(), &marker_event);
std::string name = "clEnqueueMarker";
#endif #endif
callback_.reset(marker_event, false); callback_.reset(marker_event, false);
if (err != CL_SUCCESS) { if (!success)
CAF_LOG_ERROR(name << ": " << CAF_ARG(get_opencl_error(err)));
this->deref(); // callback is not set
return; return;
} auto cb = [](cl_event, cl_int, void* data) {
err = clSetEventCallback(callback_.get(), CL_COMPLETE, auto cmd = reinterpret_cast<command*>(data);
[](cl_event, cl_int, void* data) { cmd->handle_results();
auto cmd = reinterpret_cast<command*>(data); cmd->deref();
cmd->handle_results(); };
cmd->deref(); if (!invoke_cl(clSetEventCallback, callback_.get(), CL_COMPLETE,
}, std::move(cb), this))
this);
if (err != CL_SUCCESS) {
CAF_LOG_ERROR("clSetEventCallback: " << CAF_ARG(get_opencl_error(err)));
this->deref(); // callback is not set
return; return;
} if (clFlush(parent->queue_.get()) != CL_SUCCESS)
err = clFlush(parent->queue_.get());
if (err != CL_SUCCESS) {
CAF_LOG_ERROR("clFlush: " << CAF_ARG(get_opencl_error(err))); CAF_LOG_ERROR("clFlush: " << CAF_ARG(get_opencl_error(err)));
}
} }
/// Enqueue the kernel for execution and send the mem_refs relating to the /// Enqueue the kernel for execution and send the mem_refs relating to the
...@@ -167,22 +149,19 @@ public: ...@@ -167,22 +149,19 @@ public:
/// once the execution is finished. Only called if the results only consist /// once the execution is finished. Only called if the results only consist
/// of mem_ref types. /// of mem_ref types.
template <class Q = result_types> template <class Q = result_types>
typename std::enable_if< detail::enable_if_t<detail::tl_forall<Q, is_ref_type>::value>
detail::tl_forall<Q, is_ref_type>::value,
void
>::type
enqueue() { enqueue() {
// Errors in this function can not be handled by opencl_err.hpp // Errors in this function can not be handled by opencl_err.hpp
// because they require non-standard error handling // because they require non-standard error handling
CAF_LOG_TRACE("command::enqueue() all references"); CAF_LOG_TRACE("");
this->ref(); // reference held by the OpenCL command queue this->ref(); // reference held by the OpenCL command queue
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();
}; };
auto parent = static_cast<Actor*>(actor_cast<abstract_actor*>(cl_actor_)); auto parent = static_cast<Actor*>(actor_cast<abstract_actor*>(cl_actor_));
cl_event execution_event; cl_event execution_event;
cl_int err = clEnqueueNDRangeKernel( auto success = invoke_cl(
parent->queue_.get(), parent->kernel_.get(), clEnqueueNDRangeKernel, parent->queue_.get(), parent->kernel_.get(),
static_cast<cl_uint>(range_.dimensions().size()), static_cast<cl_uint>(range_.dimensions().size()),
data_or_nullptr(range_.offsets()), data_or_nullptr(range_.offsets()),
data_or_nullptr(range_.dimensions()), data_or_nullptr(range_.dimensions()),
...@@ -192,25 +171,16 @@ public: ...@@ -192,25 +171,16 @@ public:
&execution_event &execution_event
); );
callback_.reset(execution_event, false); callback_.reset(execution_event, false);
if (err != CL_SUCCESS) { if (!success)
CAF_LOG_ERROR("clEnqueueNDRangeKernel: "
<< CAF_ARG(get_opencl_error(err)));
this->deref();
return; return;
} auto cb = [](cl_event, cl_int, void* data) {
err = clSetEventCallback(callback_.get(), CL_COMPLETE, auto c = reinterpret_cast<command*>(data);
[](cl_event, cl_int, void* data) { c->deref();
auto c = reinterpret_cast<command*>(data); };
c->deref(); if (!invoke_cl(clSetEventCallback, callback_.get(), CL_COMPLETE,
}, std::move(cb), this))
this);
if (err != CL_SUCCESS) {
CAF_LOG_ERROR("clSetEventCallback: " << CAF_ARG(get_opencl_error(err)));
this->deref(); // callback is not set
return; return;
} if (clFlush(parent->queue_.get()) != CL_SUCCESS)
err = clFlush(parent->queue_.get());
if (err != CL_SUCCESS)
CAF_LOG_ERROR("clFlush: " << CAF_ARG(get_opencl_error(err))); CAF_LOG_ERROR("clFlush: " << CAF_ARG(get_opencl_error(err)));
auto msg = msg_adding_event{callback_}(results_); auto msg = msg_adding_event{callback_}(results_);
promise_.deliver(std::move(msg)); promise_.deliver(std::move(msg));
...@@ -231,7 +201,7 @@ private: ...@@ -231,7 +201,7 @@ private:
events.data(), &events.back()); events.data(), &events.back());
if (err != CL_SUCCESS) { if (err != CL_SUCCESS) {
this->deref(); // failed to enqueue command this->deref(); // failed to enqueue command
throw std::runtime_error("clEnqueueReadBuffer: " + get_opencl_error(err)); throw std::runtime_error("clEnqueueReadBuffer: " + opencl_error(err));
} }
pos += 1; pos += 1;
} }
...@@ -263,15 +233,26 @@ private: ...@@ -263,15 +233,26 @@ private:
promise_.deliver(std::move(msg)); promise_.deliver(std::move(msg));
} }
// call function F and derefenrence the command on failure
template <class F, class... Us>
bool invoke_cl(F f, Us&&... xs) {
auto err = f(std::forward<Us>(xs)...);
if (err == CL_SUCCESS)
return true;
CAF_LOG_ERROR("error: " << opencl_error(err));
this->deref();
return false;
}
std::vector<size_t> lengths_; std::vector<size_t> lengths_;
response_promise promise_; response_promise promise_;
strong_actor_ptr cl_actor_; strong_actor_ptr cl_actor_;
std::vector<cl_event> mem_in_events_; std::vector<cl_event> mem_in_events_;
std::vector<cl_event> mem_out_events_; std::vector<cl_event> mem_out_events_;
cl_event_ptr callback_; detail::raw_event_ptr callback_;
std::vector<cl_mem_ptr> input_buffers_; std::vector<detail::raw_mem_ptr> input_buffers_;
std::vector<cl_mem_ptr> output_buffers_; std::vector<detail::raw_mem_ptr> output_buffers_;
std::vector<cl_mem_ptr> scratch_buffers_; std::vector<detail::raw_mem_ptr> scratch_buffers_;
std::tuple<Ts...> results_; std::tuple<Ts...> results_;
message msg_; // keeps the argument buffers alive for async copy to device message msg_; // keeps the argument buffers alive for async copy to device
nd_range range_; nd_range range_;
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2016 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_OPENCL_DETAIL_COMMAND_HELPER_HPP
#define CAF_OPENCL_DETAIL_COMMAND_HELPER_HPP
#include "caf/detail/type_list.hpp"
#include "caf/opencl/arguments.hpp"
namespace caf {
namespace opencl {
namespace detail {
// signature for the function that is applied to output arguments
template <class List>
struct output_function_sig;
template <class... Ts>
struct output_function_sig<detail::type_list<Ts...>> {
using type = std::function<message (Ts&...)>;
};
// derive signature of the command that handles the kernel execution
template <class T, class List>
struct command_sig;
template <class T, class... Ts>
struct command_sig<T, detail::type_list<Ts...>> {
using type = command<T, Ts...>;
};
// derive type for a tuple matching the arguments as mem_refs
template <class List>
struct tuple_type_of;
template <class... Ts>
struct tuple_type_of<detail::type_list<Ts...>> {
using type = std::tuple<Ts...>;
};
} // namespace detail
} // namespace opencl
} // namespace caf
#endif // CAF_OPENCL_DETAIL_COMMAND_HELPER_HPP
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2016 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_OPENCL_CORE_HPP
#define CAF_OPENCL_CORE_HPP
namespace caf {
namespace detail {
} // namespace detail
namespace opencl {
namespace detail {
using namespace caf::detail;
} // namespace detail
} // namespace opencl
} // namespace caf
#endif // CAF_OPENCL_CORE_HPP
...@@ -33,24 +33,29 @@ ...@@ -33,24 +33,29 @@
inline void intrusive_ptr_release(cltype ptr) { clrelease(ptr); } \ inline void intrusive_ptr_release(cltype ptr) { clrelease(ptr); } \
namespace caf { \ namespace caf { \
namespace opencl { \ namespace opencl { \
namespace detail { \
using aliasname = intrusive_ptr<std::remove_pointer<cltype>::type>; \ using aliasname = intrusive_ptr<std::remove_pointer<cltype>::type>; \
} /* namespace detail */ \
} /* namespace opencl */ \ } /* namespace opencl */ \
} // namespace caf } // namespace caf
CAF_OPENCL_PTR_ALIAS(cl_mem_ptr, cl_mem, clRetainMemObject, clReleaseMemObject)
CAF_OPENCL_PTR_ALIAS(cl_event_ptr, cl_event, clRetainEvent, clReleaseEvent) CAF_OPENCL_PTR_ALIAS(raw_mem_ptr, cl_mem, clRetainMemObject, clReleaseMemObject)
CAF_OPENCL_PTR_ALIAS(cl_kernel_ptr, cl_kernel, clRetainKernel, clReleaseKernel) CAF_OPENCL_PTR_ALIAS(raw_event_ptr, cl_event, clRetainEvent, clReleaseEvent)
CAF_OPENCL_PTR_ALIAS(cl_context_ptr, cl_context, clRetainContext, clReleaseContext) CAF_OPENCL_PTR_ALIAS(raw_kernel_ptr, cl_kernel, clRetainKernel, clReleaseKernel)
CAF_OPENCL_PTR_ALIAS(cl_program_ptr, cl_program, clRetainProgram, clReleaseProgram) CAF_OPENCL_PTR_ALIAS(raw_context_ptr, cl_context,
clRetainContext, clReleaseContext)
CAF_OPENCL_PTR_ALIAS(cl_device_ptr, cl_device_id, CAF_OPENCL_PTR_ALIAS(raw_program_ptr, cl_program,
clRetainProgram, clReleaseProgram)
CAF_OPENCL_PTR_ALIAS(raw_device_ptr, cl_device_id,
clRetainDeviceDummy, clReleaseDeviceDummy) clRetainDeviceDummy, clReleaseDeviceDummy)
CAF_OPENCL_PTR_ALIAS(cl_command_queue_ptr, cl_command_queue, CAF_OPENCL_PTR_ALIAS(raw_command_queue_ptr, cl_command_queue,
clRetainCommandQueue, clReleaseCommandQueue) clRetainCommandQueue, clReleaseCommandQueue)
#endif // CAF_OPENCL_SMART_PTR_HPP #endif // CAF_OPENCL_SMART_PTR_HPP
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#ifndef CAF_OPENCL_DETAIL_SPAWN_HELPER_HPP #ifndef CAF_OPENCL_DETAIL_SPAWN_HELPER_HPP
#define CAF_OPENCL_DETAIL_SPAWN_HELPER_HPP #define CAF_OPENCL_DETAIL_SPAWN_HELPER_HPP
#include "caf/opencl/opencl_actor.hpp" #include "caf/opencl/actor_facade.hpp"
namespace caf { namespace caf {
namespace opencl { namespace opencl {
...@@ -30,7 +30,7 @@ struct tuple_construct { }; ...@@ -30,7 +30,7 @@ struct tuple_construct { };
template <bool PassConfig, class... Ts> template <bool PassConfig, class... Ts>
struct cl_spawn_helper { struct cl_spawn_helper {
using impl = opencl::opencl_actor<PassConfig, Ts...>; using impl = opencl::actor_facade<PassConfig, Ts...>;
using map_in_fun = typename impl::input_mapping; using map_in_fun = typename impl::input_mapping;
using map_out_fun = typename impl::output_mapping; using map_out_fun = typename impl::output_mapping;
...@@ -40,7 +40,7 @@ struct cl_spawn_helper { ...@@ -40,7 +40,7 @@ struct cl_spawn_helper {
return actor_cast<actor>(impl::create(std::move(actor_cfg), return actor_cast<actor>(impl::create(std::move(actor_cfg),
p, fn, range, p, fn, range,
map_in_fun{}, map_out_fun{}, map_in_fun{}, map_out_fun{},
std::move(xs)...)); std::forward<Ts>(xs)...));
} }
actor operator()(actor_config actor_cfg, const opencl::program_ptr p, actor operator()(actor_config actor_cfg, const opencl::program_ptr p,
const char* fn, const opencl::nd_range& range, const char* fn, const opencl::nd_range& range,
...@@ -49,7 +49,7 @@ struct cl_spawn_helper { ...@@ -49,7 +49,7 @@ struct cl_spawn_helper {
p, fn, range, p, fn, range,
std::move(map_input), std::move(map_input),
map_out_fun{}, map_out_fun{},
std::move(xs)...)); std::forward<Ts>(xs)...));
} }
actor operator()(actor_config actor_cfg, const opencl::program_ptr p, actor operator()(actor_config actor_cfg, const opencl::program_ptr p,
const char* fn, const opencl::nd_range& range, const char* fn, const opencl::nd_range& range,
...@@ -59,7 +59,7 @@ struct cl_spawn_helper { ...@@ -59,7 +59,7 @@ struct cl_spawn_helper {
p, fn, range, p, fn, range,
std::move(map_input), std::move(map_input),
std::move(map_output), std::move(map_output),
std::move(xs)...)); std::forward<Ts>(xs)...));
} }
}; };
......
This diff is collapsed.
...@@ -64,7 +64,7 @@ device_type device_type_from_ulong(cl_ulong dev); ...@@ -64,7 +64,7 @@ device_type device_type_from_ulong(cl_ulong dev);
/// A vector of up to three elements used for OpenCL dimensions. /// A vector of up to three elements used for OpenCL dimensions.
using dim_vec = detail::limited_vector<size_t, 3>; using dim_vec = detail::limited_vector<size_t, 3>;
std::string get_opencl_error(cl_int err); std::string opencl_error(cl_int err);
std::string event_status(cl_event event); std::string event_status(cl_event event);
......
...@@ -33,9 +33,10 @@ ...@@ -33,9 +33,10 @@
#include "caf/opencl/global.hpp" #include "caf/opencl/global.hpp"
#include "caf/opencl/program.hpp" #include "caf/opencl/program.hpp"
#include "caf/opencl/platform.hpp" #include "caf/opencl/platform.hpp"
#include "caf/opencl/smart_ptr.hpp" #include "caf/opencl/actor_facade.hpp"
#include "caf/opencl/opencl_actor.hpp"
#include "caf/opencl/detail/core.hpp"
#include "caf/opencl/detail/raw_ptr.hpp"
#include "caf/opencl/detail/spawn_helper.hpp" #include "caf/opencl/detail/spawn_helper.hpp"
namespace caf { namespace caf {
...@@ -45,17 +46,17 @@ class manager : public actor_system::module { ...@@ -45,17 +46,17 @@ class manager : public actor_system::module {
public: public:
friend class program; friend class program;
friend class actor_system; friend class actor_system;
friend cl_command_queue_ptr get_command_queue(uint32_t id); friend detail::raw_command_queue_ptr command_queue(uint32_t id);
manager(const manager&) = delete; manager(const manager&) = delete;
manager& operator=(const manager&) = delete; manager& operator=(const manager&) = delete;
/// Get the device with id, which is assigned sequientally. /// Get the device with id, which is assigned sequientally.
optional<device_ptr> get_device(size_t dev_id = 0) const; optional<device_ptr> find_device(size_t dev_id = 0) const;
/// Get the first device that satisfies the predicate. /// Get the first device that satisfies the predicate.
/// The predicate should accept a `const device&` and return a bool; /// The predicate should accept a `const device&` and return a bool;
template <class UnaryPredicate> template <class UnaryPredicate>
optional<device_ptr> get_device_if(UnaryPredicate p) const { optional<device_ptr> find_device_if(UnaryPredicate p) const {
for (auto& pl : platforms_) { for (auto& pl : platforms_) {
for (auto& dev : pl->get_devices()) { for (auto& dev : pl->devices()) {
if (p(dev)) if (p(dev))
return dev; return dev;
} }
...@@ -72,7 +73,7 @@ public: ...@@ -72,7 +73,7 @@ public:
void* subtype_ptr() override; void* subtype_ptr() override;
static actor_system::module* make(actor_system& sys, static actor_system::module* make(actor_system& sys,
caf::detail::type_list<>); detail::type_list<>);
// OpenCL functionality // OpenCL functionality
...@@ -108,15 +109,12 @@ public: ...@@ -108,15 +109,12 @@ public:
/// @throws std::runtime_error if more than three dimensions are set, /// @throws std::runtime_error if more than three dimensions are set,
/// `dims.empty()`, or `clCreateKernel` failed. /// `dims.empty()`, or `clCreateKernel` failed.
template <class T, class... Ts> template <class T, class... Ts>
typename std::enable_if< detail::enable_if_t<opencl::is_opencl_arg<T>::value, actor>
opencl::is_opencl_arg<T>::value,
actor
>::type
spawn(const opencl::program_ptr prog, const char* fname, spawn(const opencl::program_ptr prog, const char* fname,
const opencl::nd_range& range, T x, Ts... xs) { const opencl::nd_range& range, T&& x, Ts&&... xs) {
detail::cl_spawn_helper<false, T, Ts...> f; detail::cl_spawn_helper<false, T, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range, return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range,
std::move(x), std::move(xs)...); std::forward<T>(x), std::forward<Ts>(xs)...);
} }
/// Compiles `source` and creates a new actor facade for an OpenCL kernel /// Compiles `source` and creates a new actor facade for an OpenCL kernel
...@@ -125,16 +123,13 @@ public: ...@@ -125,16 +123,13 @@ public:
/// <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 <class T, class... Ts> template <class T, class... Ts>
typename std::enable_if< detail::enable_if_t<opencl::is_opencl_arg<T>::value, actor>
opencl::is_opencl_arg<T>::value,
actor
>::type
spawn(const char* source, const char* fname, spawn(const char* source, const char* fname,
const opencl::nd_range& range, T x, Ts... xs) { const opencl::nd_range& range, T&& x, Ts&&... xs) {
detail::cl_spawn_helper<false, T, Ts...> f; detail::cl_spawn_helper<false, T, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, return f(actor_config{system_.dummy_execution_unit()},
create_program(source), fname, range, create_program(source), fname, range,
std::move(x), std::move(xs)...); std::forward<T>(x), std::forward<Ts>(xs)...);
} }
/// Creates a new actor facade for an OpenCL kernel that invokes /// Creates a new actor facade for an OpenCL kernel that invokes
...@@ -145,7 +140,7 @@ public: ...@@ -145,7 +140,7 @@ public:
actor spawn(const opencl::program_ptr prog, const char* fname, actor spawn(const opencl::program_ptr prog, const char* fname,
const opencl::nd_range& range, const opencl::nd_range& range,
std::function<optional<message> (message&)> map_args, std::function<optional<message> (message&)> map_args,
Fun map_result, Ts... xs) { Fun map_result, Ts&&... xs) {
detail::cl_spawn_helper<false, Ts...> f; detail::cl_spawn_helper<false, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range, return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range,
std::move(map_args), std::move(map_result), std::move(map_args), std::move(map_result),
...@@ -161,7 +156,7 @@ public: ...@@ -161,7 +156,7 @@ public:
actor spawn(const char* source, const char* fname, actor spawn(const char* source, const char* fname,
const opencl::nd_range& range, const opencl::nd_range& range,
std::function<optional<message> (message&)> map_args, std::function<optional<message> (message&)> map_args,
Fun map_result, Ts... xs) { Fun map_result, Ts&&... xs) {
detail::cl_spawn_helper<false, Ts...> f; detail::cl_spawn_helper<false, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, return f(actor_config{system_.dummy_execution_unit()},
create_program(source), fname, range, create_program(source), fname, range,
...@@ -176,14 +171,11 @@ public: ...@@ -176,14 +171,11 @@ public:
/// @throws std::runtime_error if more than three dimensions are set, /// @throws std::runtime_error if more than three dimensions are set,
/// `dims.empty()`, or `clCreateKernel` failed. /// `dims.empty()`, or `clCreateKernel` failed.
template <class T, class... Ts> template <class T, class... Ts>
typename std::enable_if< detail::enable_if_t<opencl::is_opencl_arg<T>::value, actor>
opencl::is_opencl_arg<T>::value,
actor
>::type
spawn(const opencl::program_ptr prog, const char* fname, spawn(const opencl::program_ptr prog, const char* fname,
const opencl::nd_range& range, const opencl::nd_range& range,
std::function<optional<message> (message&)> map_args, std::function<optional<message> (message&)> map_args,
T x, Ts... xs) { T&& x, Ts&&... xs) {
detail::cl_spawn_helper<false, Ts...> f; detail::cl_spawn_helper<false, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range, return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range,
std::move(map_args), std::forward<T>(x), std::forward<Ts>(xs)...); std::move(map_args), std::forward<T>(x), std::forward<Ts>(xs)...);
...@@ -195,14 +187,11 @@ public: ...@@ -195,14 +187,11 @@ public:
/// <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 <class T, class... Ts> template <class T, class... Ts>
typename std::enable_if< detail::enable_if_t<opencl::is_opencl_arg<T>::value, actor>
opencl::is_opencl_arg<T>::value,
actor
>::type
spawn(const char* source, const char* fname, spawn(const char* source, const char* fname,
const opencl::nd_range& range, const opencl::nd_range& range,
std::function<optional<message> (message&)> map_args, std::function<optional<message> (message&)> map_args,
T x, Ts... xs) { T&& x, Ts&&... xs) {
detail::cl_spawn_helper<false, Ts...> f; detail::cl_spawn_helper<false, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, return f(actor_config{system_.dummy_execution_unit()},
create_program(source), fname, range, create_program(source), fname, range,
...@@ -217,14 +206,11 @@ public: ...@@ -217,14 +206,11 @@ public:
/// @throws std::runtime_error if more than three dimensions are set, /// @throws std::runtime_error if more than three dimensions are set,
/// `dims.empty()`, or `clCreateKernel` failed. /// `dims.empty()`, or `clCreateKernel` failed.
template <class Fun, class... Ts> template <class Fun, class... Ts>
typename std::enable_if< detail::enable_if_t<!opencl::is_opencl_arg<Fun>::value, actor>
!opencl::is_opencl_arg<Fun>::value,
actor
>::type
spawn(const opencl::program_ptr prog, const char* fname, spawn(const opencl::program_ptr prog, const char* fname,
const opencl::nd_range& range, const opencl::nd_range& range,
std::function<optional<message> (nd_range&, message&)> map_args, std::function<optional<message> (nd_range&, message&)> map_args,
Fun map_result, Ts... xs) { Fun map_result, Ts&&... xs) {
detail::cl_spawn_helper<true, Ts...> f; detail::cl_spawn_helper<true, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range, return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range,
std::move(map_args), std::move(map_result), std::move(map_args), std::move(map_result),
...@@ -237,14 +223,11 @@ public: ...@@ -237,14 +223,11 @@ public:
/// <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 <class Fun, class... Ts> template <class Fun, class... Ts>
typename std::enable_if< detail::enable_if_t<!opencl::is_opencl_arg<Fun>::value, actor>
!opencl::is_opencl_arg<Fun>::value,
actor
>::type
spawn(const char* source, const char* fname, spawn(const char* source, const char* fname,
const opencl::nd_range& range, const opencl::nd_range& range,
std::function<optional<message> (nd_range&, message&)> map_args, std::function<optional<message> (nd_range&, message&)> map_args,
Fun map_result, Ts... xs) { Fun map_result, Ts&&... xs) {
detail::cl_spawn_helper<true, Ts...> f; detail::cl_spawn_helper<true, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, return f(actor_config{system_.dummy_execution_unit()},
create_program(source), fname, range, create_program(source), fname, range,
...@@ -257,14 +240,11 @@ public: ...@@ -257,14 +240,11 @@ public:
/// @throws std::runtime_error if more than three dimensions are set, /// @throws std::runtime_error if more than three dimensions are set,
/// `dims.empty()`, or `clCreateKernel` failed. /// `dims.empty()`, or `clCreateKernel` failed.
template <class T, class... Ts> template <class T, class... Ts>
typename std::enable_if< detail::enable_if_t<opencl::is_opencl_arg<T>::value, actor>
opencl::is_opencl_arg<T>::value,
actor
>::type
spawn(const opencl::program_ptr prog, const char* fname, spawn(const opencl::program_ptr prog, const char* fname,
const opencl::nd_range& range, const opencl::nd_range& range,
std::function<optional<message> (nd_range&, message&)> map_args, std::function<optional<message> (nd_range&, message&)> map_args,
T x, Ts... xs) { T&& x, Ts&&... xs) {
detail::cl_spawn_helper<true, T, Ts...> f; detail::cl_spawn_helper<true, T, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range, return f(actor_config{system_.dummy_execution_unit()}, prog, fname, range,
std::move(map_args), std::forward<T>(x), std::forward<Ts>(xs)...); std::move(map_args), std::forward<T>(x), std::forward<Ts>(xs)...);
...@@ -276,14 +256,11 @@ public: ...@@ -276,14 +256,11 @@ public:
/// <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 <class T, class... Ts> template <class T, class... Ts>
typename std::enable_if< detail::enable_if_t<opencl::is_opencl_arg<T>::value, actor>
opencl::is_opencl_arg<T>::value,
actor
>::type
spawn(const char* source, const char* fname, spawn(const char* source, const char* fname,
const opencl::nd_range& range, const opencl::nd_range& range,
std::function<optional<message> (nd_range&, message&)> map_args, std::function<optional<message> (nd_range&, message&)> map_args,
T x, Ts... xs) { T&& x, Ts&&... xs) {
detail::cl_spawn_helper<true, T, Ts...> f; detail::cl_spawn_helper<true, T, Ts...> f;
return f(actor_config{system_.dummy_execution_unit()}, return f(actor_config{system_.dummy_execution_unit()},
create_program(source), fname, range, create_program(source), fname, range,
......
...@@ -27,13 +27,15 @@ ...@@ -27,13 +27,15 @@
#include "caf/optional.hpp" #include "caf/optional.hpp"
#include "caf/ref_counted.hpp" #include "caf/ref_counted.hpp"
#include "caf/opencl/smart_ptr.hpp" #include "caf/opencl/detail/core.hpp"
#include "caf/opencl/detail/raw_ptr.hpp"
namespace caf { namespace caf {
namespace opencl { namespace opencl {
/// Updates the reference types in a message with a given event.
struct msg_adding_event { struct msg_adding_event {
msg_adding_event(cl_event_ptr event) : event_(event) { msg_adding_event(detail::raw_event_ptr event) : event_(event) {
// nop // nop
} }
template <class T, class... Ts> template <class T, class... Ts>
...@@ -49,21 +51,24 @@ struct msg_adding_event { ...@@ -49,21 +51,24 @@ struct msg_adding_event {
ref.set_event(event_); ref.set_event(event_);
return std::move(ref); return std::move(ref);
} }
cl_event_ptr event_; detail::raw_event_ptr event_;
}; };
// Tag to separate mem_refs from other types in messages.
struct ref_tag {};
class device; class device;
/// A reference type for buffers on a OpenCL devive. Access is not thread safe. /// A reference type for buffers on a OpenCL devive. Access is not thread safe.
/// Hence, a mem_ref should only be passed to actors sequentially. /// Hence, a mem_ref should only be passed to actors sequentially.
template <class T> template <class T>
class mem_ref { class mem_ref : ref_tag {
public: public:
using value_type = T; using value_type = T;
friend struct msg_adding_event; friend struct msg_adding_event;
template <bool PassConfig, class... Ts> template <bool PassConfig, class... Ts>
friend class opencl_actor; friend class actor_facade;
friend class device; friend class device;
expected<std::vector<T>> data(optional<size_t> result_size = none) { expected<std::vector<T>> data(optional<size_t> result_size = none) {
...@@ -85,7 +90,7 @@ public: ...@@ -85,7 +90,7 @@ public:
static_cast<cl_uint>(prev_events.size()), static_cast<cl_uint>(prev_events.size()),
prev_events.data(), &event); prev_events.data(), &event);
if (err != CL_SUCCESS) if (err != CL_SUCCESS)
return make_error(sec::runtime_error, get_opencl_error(err)); return make_error(sec::runtime_error, opencl_error(err));
// decrements the previous event we used for waiting above // decrements the previous event we used for waiting above
event_.reset(event, false); event_.reset(event, false);
return buffer; return buffer;
...@@ -99,11 +104,7 @@ public: ...@@ -99,11 +104,7 @@ public:
event_.reset(); event_.reset();
} }
inline const cl_mem_ptr& get() const { inline const detail::raw_mem_ptr& get() const {
return memory_;
}
inline cl_mem_ptr& get() {
return memory_; return memory_;
} }
...@@ -124,8 +125,9 @@ public: ...@@ -124,8 +125,9 @@ public:
// nop // nop
} }
mem_ref(size_t num_elements, cl_command_queue_ptr queue, mem_ref(size_t num_elements, detail::raw_command_queue_ptr queue,
cl_mem_ptr memory, cl_mem_flags access, cl_event_ptr event) detail::raw_mem_ptr memory, cl_mem_flags access,
detail::raw_event_ptr event)
: num_elements_{num_elements}, : num_elements_{num_elements},
access_{access}, access_{access},
queue_{queue}, queue_{queue},
...@@ -134,8 +136,8 @@ public: ...@@ -134,8 +136,8 @@ public:
// nop // nop
} }
mem_ref(size_t num_elements, cl_command_queue_ptr queue, mem_ref(size_t num_elements, detail::raw_command_queue_ptr queue,
cl_mem memory, cl_mem_flags access, cl_event_ptr event) cl_mem memory, cl_mem_flags access, detail::raw_event_ptr event)
: num_elements_{num_elements}, : num_elements_{num_elements},
access_{access}, access_{access},
queue_{queue}, queue_{queue},
...@@ -157,11 +159,11 @@ private: ...@@ -157,11 +159,11 @@ private:
event_.reset(e, increment_reference); event_.reset(e, increment_reference);
} }
inline void set_event(cl_event_ptr e) { inline void set_event(detail::raw_event_ptr e) {
event_ = std::move(e); event_ = std::move(e);
} }
inline cl_event_ptr event() { inline detail::raw_event_ptr event() {
return event_; return event_;
} }
...@@ -171,12 +173,16 @@ private: ...@@ -171,12 +173,16 @@ private:
size_t num_elements_; size_t num_elements_;
cl_mem_flags access_; cl_mem_flags access_;
cl_command_queue_ptr queue_; detail::raw_command_queue_ptr queue_;
cl_event_ptr event_; detail::raw_event_ptr event_;
cl_mem_ptr memory_; detail::raw_mem_ptr memory_;
}; };
} // namespace opencl } // namespace opencl
template <class T>
struct allowed_unsafe_message_type<opencl::mem_ref<T>> : std::true_type {};
} // namespace caf } // namespace caf
#endif // CAF_OPENCL_MEM_REF_HPP #endif // CAF_OPENCL_MEM_REF_HPP
...@@ -36,14 +36,14 @@ public: ...@@ -36,14 +36,14 @@ public:
template <class T, class... Ts> template <class T, class... Ts>
friend intrusive_ptr<T> caf::make_counted(Ts&&...); friend intrusive_ptr<T> caf::make_counted(Ts&&...);
inline const std::vector<device_ptr>& get_devices() const; inline const std::vector<device_ptr>& devices() const;
inline const std::string& get_name() const; inline const std::string& name() const;
inline const std::string& get_vendor() const; inline const std::string& vendor() const;
inline const std::string& get_version() const; inline const std::string& version() const;
static platform_ptr create(cl_platform_id platform_id, unsigned start_id); static platform_ptr create(cl_platform_id platform_id, unsigned start_id);
private: private:
platform(cl_platform_id platform_id, cl_context_ptr context, platform(cl_platform_id platform_id, detail::raw_context_ptr context,
std::string name, std::string vendor, std::string version, std::string name, std::string vendor, std::string version,
std::vector<device_ptr> devices); std::vector<device_ptr> devices);
...@@ -52,7 +52,7 @@ private: ...@@ -52,7 +52,7 @@ private:
static std::string platform_info(cl_platform_id platform_id, static std::string platform_info(cl_platform_id platform_id,
unsigned info_flag); unsigned info_flag);
cl_platform_id platform_id_; cl_platform_id platform_id_;
cl_context_ptr context_; detail::raw_context_ptr context_;
std::string name_; std::string name_;
std::string vendor_; std::string vendor_;
std::string version_; std::string version_;
...@@ -63,19 +63,19 @@ private: ...@@ -63,19 +63,19 @@ private:
* implementation of inline member functions * * implementation of inline member functions *
\******************************************************************************/ \******************************************************************************/
inline const std::vector<device_ptr>& platform::get_devices() const { inline const std::vector<device_ptr>& platform::devices() const {
return devices_; return devices_;
} }
inline const std::string& platform::get_name() const { inline const std::string& platform::name() const {
return name_; return name_;
} }
inline const std::string& platform::get_vendor() const { inline const std::string& platform::vendor() const {
return vendor_; return vendor_;
} }
inline const std::string& platform::get_version() const { inline const std::string& platform::version() const {
return version_; return version_;
} }
......
...@@ -27,14 +27,12 @@ ...@@ -27,14 +27,12 @@
#include "caf/opencl/device.hpp" #include "caf/opencl/device.hpp"
#include "caf/opencl/global.hpp" #include "caf/opencl/global.hpp"
#include "caf/opencl/smart_ptr.hpp"
#include "caf/opencl/detail/raw_ptr.hpp"
namespace caf { namespace caf {
namespace opencl { namespace opencl {
template <class... Ts>
class actor_facade;
class program; class program;
using program_ptr = intrusive_ptr<program>; using program_ptr = intrusive_ptr<program>;
...@@ -42,24 +40,22 @@ using program_ptr = intrusive_ptr<program>; ...@@ -42,24 +40,22 @@ using program_ptr = intrusive_ptr<program>;
class program : public ref_counted { class program : public ref_counted {
public: public:
friend class manager; friend class manager;
template <class... Ts>
friend class actor_facade;
template <bool PassConfig, class... Ts> template <bool PassConfig, class... Ts>
friend class opencl_actor; friend class actor_facade;
template <class T, class... Ts> template <class T, class... Ts>
friend intrusive_ptr<T> caf::make_counted(Ts&&...); friend intrusive_ptr<T> caf::make_counted(Ts&&...);
private: private:
program(cl_context_ptr context, cl_command_queue_ptr queue, program(detail::raw_context_ptr context, detail::raw_command_queue_ptr queue,
cl_program_ptr prog, detail::raw_program_ptr prog,
std::map<std::string,cl_kernel_ptr> available_kernels); std::map<std::string, detail::raw_kernel_ptr> available_kernels);
~program(); ~program();
cl_context_ptr context_; detail::raw_context_ptr context_;
cl_program_ptr program_; detail::raw_program_ptr program_;
cl_command_queue_ptr queue_; detail::raw_command_queue_ptr queue_;
std::map<std::string,cl_kernel_ptr> available_kernels_; std::map<std::string, detail::raw_kernel_ptr> available_kernels_;
}; };
} // namespace opencl } // namespace opencl
......
...@@ -48,7 +48,7 @@ constexpr const char* kernel_name_3 = "phase_3"; ...@@ -48,7 +48,7 @@ constexpr const char* kernel_name_3 = "phase_3";
// opencl kernel, exclusive scan // opencl kernel, exclusive scan
// last parameter is, by convention, the output parameter // last parameter is, by convention, the output parameter
constexpr const char* kernel_source = R"__( constexpr const char* kernel_source = R"__(
/// Global exclusive scan, phase 1. From: /// Global exclusive scan, phase 1. From:
/// - http://http.developer.nvidia.com/GPUGems3/gpugems3_ch39.html /// - http://http.developer.nvidia.com/GPUGems3/gpugems3_ch39.html
kernel void phase_1(global uint* restrict data, kernel void phase_1(global uint* restrict data,
global uint* restrict increments, global uint* restrict increments,
...@@ -59,7 +59,6 @@ kernel void phase_1(global uint* restrict data, ...@@ -59,7 +59,6 @@ kernel void phase_1(global uint* restrict data,
const uint elements_per_block = threads_per_block * 2; const uint elements_per_block = threads_per_block * 2;
const uint global_offset = block * elements_per_block; const uint global_offset = block * elements_per_block;
const uint n = elements_per_block; const uint n = elements_per_block;
uint offset = 1; uint offset = 1;
// A (2 lines) --> load input into shared memory // A (2 lines) --> load input into shared memory
tmp[2 * thread] = (global_offset + (2 * thread) < len) tmp[2 * thread] = (global_offset + (2 * thread) < len)
...@@ -155,7 +154,6 @@ kernel void phase_3(global uint* restrict data, ...@@ -155,7 +154,6 @@ kernel void phase_3(global uint* restrict data,
const uint threads_per_block = get_local_size(0); const uint threads_per_block = get_local_size(0);
const uint elements_per_block = threads_per_block * 2; const uint elements_per_block = threads_per_block * 2;
const uint global_offset = block * elements_per_block; const uint global_offset = block * elements_per_block;
// add the appropriate value to each block // add the appropriate value to each block
uint ai = 2 * thread; uint ai = 2 * thread;
uint bi = 2 * thread + 1; uint bi = 2 * thread + 1;
...@@ -169,10 +167,7 @@ kernel void phase_3(global uint* restrict data, ...@@ -169,10 +167,7 @@ kernel void phase_3(global uint* restrict data,
} // namespace <anonymous> } // namespace <anonymous>
// Allow sending of unserializable references template <class T, class E = caf::detail::enable_if_t<is_integral<T>::value>>
CAF_ALLOW_UNSAFE_MESSAGE_TYPE(uref);
template <class T, class E = typename enable_if<is_integral<T>::value>::type>
T round_up(T numToRound, T multiple) { T round_up(T numToRound, T multiple) {
return ((numToRound + multiple - 1) / multiple) * multiple; return ((numToRound + multiple - 1) / multiple) * multiple;
} }
...@@ -182,47 +177,40 @@ int main() { ...@@ -182,47 +177,40 @@ int main() {
cfg.load<opencl::manager>() cfg.load<opencl::manager>()
.add_message_type<uvec>("uint_vector"); .add_message_type<uvec>("uint_vector");
actor_system system{cfg}; actor_system system{cfg};
cout << "Calculating exclusive scan of '" << problem_size cout << "Calculating exclusive scan of '" << problem_size
<< "' values." << endl; << "' values." << endl;
// ---- create data ---- // ---- create data ----
uvec values; uvec values(problem_size);
values.reserve(problem_size); random_device rd;
random_device rd; //Will be used to obtain a seed for the random number engine mt19937 gen(rd());
mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
uniform_int_distribution<uval> val_gen(0, 1023); uniform_int_distribution<uval> val_gen(0, 1023);
for (size_t i = 0; i < problem_size; ++i) std::generate(begin(values), end(values), [&]() { return val_gen(gen); });
values.emplace_back(val_gen(gen));
// ---- find device ---- // ---- find device ----
auto& mngr = system.opencl_manager(); auto& mngr = system.opencl_manager();
// //
string prefix = "GeForce"; string prefix = "GeForce";
auto opt = mngr.get_device_if([&](const device_ptr dev) { auto opt = mngr.find_device_if([&](const device_ptr dev) {
auto& name = dev->get_name(); auto& name = dev->name();
return equal(begin(prefix), end(prefix), begin(name)); return equal(begin(prefix), end(prefix), begin(name));
}); });
if (!opt) { if (!opt) {
cout << "No device starting with '" << prefix << "' found. " cout << "No device starting with '" << prefix << "' found. "
<< "Will try the first OpenCL device available." << endl; << "Will try the first OpenCL device available." << endl;
opt = mngr.get_device(); opt = mngr.find_device();
} }
if (!opt) { if (!opt) {
cerr << "Not OpenCL device available." << endl; cerr << "Not OpenCL device available." << endl;
return 0; return 0;
} else { } else {
cerr << "Found device '" << (*opt)->get_name() << "'." << endl; cerr << "Found device '" << (*opt)->name() << "'." << endl;
} }
{ {
// ---- general ---- // ---- general ----
auto dev = move(*opt); auto dev = move(*opt);
auto prog = mngr.create_program(kernel_source, "", dev); auto prog = mngr.create_program(kernel_source, "", dev);
scoped_actor self{system}; scoped_actor self{system};
// ---- config parameters ---- // ---- config parameters ----
auto half_block = dev->get_max_work_group_size() / 2; auto half_block = dev->max_work_group_size() / 2;
auto get_size = [half_block](size_t n) -> size_t { auto get_size = [half_block](size_t n) -> size_t {
return round_up((n + 1) / 2, half_block); return round_up((n + 1) / 2, half_block);
}; };
...@@ -235,7 +223,6 @@ int main() { ...@@ -235,7 +223,6 @@ int main() {
}; };
// default nd-range // default nd-range
auto ndr = nd_range{dim_vec{half_block}, {}, dim_vec{half_block}}; auto ndr = nd_range{dim_vec{half_block}, {}, dim_vec{half_block}};
// ---- scan actors ---- // ---- scan actors ----
auto phase1 = mngr.spawn( auto phase1 = mngr.spawn(
prog, kernel_name_1, ndr, prog, kernel_name_1, ndr,
...@@ -277,10 +264,8 @@ int main() { ...@@ -277,10 +264,8 @@ int main() {
in<uval,mref>{}, in<uval,mref>{},
priv<uval, val>{} priv<uval, val>{}
); );
// ---- composed scan actor ---- // ---- composed scan actor ----
auto scanner = phase3 * phase2 * phase1; auto scanner = phase3 * phase2 * phase1;
// ---- scan the data ---- // ---- scan the data ----
self->send(scanner, values); self->send(scanner, values);
self->receive( self->receive(
......
...@@ -33,8 +33,8 @@ using namespace std; ...@@ -33,8 +33,8 @@ using namespace std;
namespace caf { namespace caf {
namespace opencl { namespace opencl {
device_ptr device::create(const cl_context_ptr& context, device_ptr device::create(const detail::raw_context_ptr& context,
const cl_device_ptr& device_id, const detail::raw_device_ptr& device_id,
unsigned id) { unsigned id) {
CAF_LOG_DEBUG("creating device for opencl device with id:" << CAF_ARG(id)); CAF_LOG_DEBUG("creating device for opencl device with id:" << CAF_ARG(id));
// look up properties we need to create the command queue // look up properties we need to create the command queue
...@@ -42,14 +42,18 @@ device_ptr device::create(const cl_context_ptr& context, ...@@ -42,14 +42,18 @@ device_ptr device::create(const cl_context_ptr& context,
bool profiling = false; // (supported & CL_QUEUE_PROFILING_ENABLE) != 0u; bool profiling = false; // (supported & CL_QUEUE_PROFILING_ENABLE) != 0u;
bool out_of_order = (supported & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0u; bool out_of_order = (supported & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0u;
unsigned properties = profiling ? CL_QUEUE_PROFILING_ENABLE : 0; unsigned properties = profiling ? CL_QUEUE_PROFILING_ENABLE : 0;
properties |= out_of_order ? CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE : 0; if (out_of_order)
properties |= CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE;
// create the command queue // create the command queue
cl_command_queue_ptr command_queue{v2get(CAF_CLF(clCreateCommandQueue), detail::raw_command_queue_ptr command_queue{
context.get(), device_id.get(), v2get(CAF_CLF(clCreateCommandQueue),
properties), context.get(), device_id.get(),
false}; properties),
false
};
// create the device // create the device
auto dev = make_counted<device>(device_id, std::move(command_queue), context, id); auto dev = make_counted<device>(device_id, std::move(command_queue),
context, id);
//device dev{device_id, std::move(command_queue), context, id}; //device dev{device_id, std::move(command_queue), context, id};
// look up device properties // look up device properties
dev->address_bits_ = info<cl_uint>(device_id, CL_DEVICE_ADDRESS_BITS); dev->address_bits_ = info<cl_uint>(device_id, CL_DEVICE_ADDRESS_BITS);
...@@ -103,7 +107,8 @@ void device::synchronize() { ...@@ -103,7 +107,8 @@ void device::synchronize() {
clFinish(queue_.get()); clFinish(queue_.get());
} }
string device::info_string(const cl_device_ptr& device_id, unsigned info_flag) { string device::info_string(const detail::raw_device_ptr& device_id,
unsigned info_flag) {
size_t size; size_t size;
clGetDeviceInfo(device_id.get(), info_flag, 0, nullptr, &size); clGetDeviceInfo(device_id.get(), info_flag, 0, nullptr, &size);
vector<char> buffer(size); vector<char> buffer(size);
...@@ -112,8 +117,10 @@ string device::info_string(const cl_device_ptr& device_id, unsigned info_flag) { ...@@ -112,8 +117,10 @@ string device::info_string(const cl_device_ptr& device_id, unsigned info_flag) {
return string(buffer.data()); return string(buffer.data());
} }
device::device(cl_device_ptr device_id, cl_command_queue_ptr queue, device::device(detail::raw_device_ptr device_id,
cl_context_ptr context, unsigned id) detail::raw_command_queue_ptr queue,
detail::raw_context_ptr context,
unsigned id)
: device_id_(std::move(device_id)), : device_id_(std::move(device_id)),
queue_(std::move(queue)), queue_(std::move(queue)),
context_(std::move(context)), context_(std::move(context)),
......
...@@ -57,7 +57,7 @@ device_type device_type_from_ulong(cl_ulong dev) { ...@@ -57,7 +57,7 @@ device_type device_type_from_ulong(cl_ulong dev) {
} }
} }
std::string get_opencl_error(cl_int err) { std::string opencl_error(cl_int err) {
switch (err) { switch (err) {
case CL_SUCCESS: case CL_SUCCESS:
return "CL_SUCCESS"; return "CL_SUCCESS";
......
...@@ -25,23 +25,24 @@ ...@@ -25,23 +25,24 @@
#include "caf/opencl/device.hpp" #include "caf/opencl/device.hpp"
#include "caf/opencl/manager.hpp" #include "caf/opencl/manager.hpp"
#include "caf/opencl/platform.hpp" #include "caf/opencl/platform.hpp"
#include "caf/opencl/smart_ptr.hpp"
#include "caf/opencl/opencl_err.hpp" #include "caf/opencl/opencl_err.hpp"
#include "caf/opencl/detail/raw_ptr.hpp"
using namespace std; using namespace std;
namespace caf { namespace caf {
namespace opencl { namespace opencl {
optional<device_ptr> manager::get_device(size_t dev_id) const { optional<device_ptr> manager::find_device(size_t dev_id) const {
if (platforms_.empty()) if (platforms_.empty())
return none; return none;
size_t to = 0; size_t to = 0;
for (auto& pl : platforms_) { for (auto& pl : platforms_) {
auto from = to; auto from = to;
to += pl->get_devices().size(); to += pl->devices().size();
if (dev_id >= from && dev_id < to) if (dev_id >= from && dev_id < to)
return pl->get_devices()[dev_id - from]; return pl->devices()[dev_id - from];
} }
return none; return none;
} }
...@@ -59,7 +60,7 @@ void manager::init(actor_system_config&) { ...@@ -59,7 +60,7 @@ void manager::init(actor_system_config&) {
for (auto& pl_id : platform_ids) { for (auto& pl_id : platform_ids) {
platforms_.push_back(platform::create(pl_id, current_device_id)); platforms_.push_back(platform::create(pl_id, current_device_id));
current_device_id += current_device_id +=
static_cast<unsigned>(platforms_.back()->get_devices().size()); static_cast<unsigned>(platforms_.back()->devices().size());
} }
} }
...@@ -108,7 +109,7 @@ program_ptr manager::create_program_from_file(const char* path, ...@@ -108,7 +109,7 @@ program_ptr manager::create_program_from_file(const char* path,
program_ptr manager::create_program(const char* kernel_source, program_ptr manager::create_program(const char* kernel_source,
const char* options, const char* options,
uint32_t device_id) { uint32_t device_id) {
auto dev = get_device(device_id); auto dev = find_device(device_id);
if (!dev) { if (!dev) {
ostringstream oss; ostringstream oss;
oss << "No device with id '" << device_id << "' found."; oss << "No device with id '" << device_id << "' found.";
...@@ -144,7 +145,7 @@ program_ptr manager::create_program(const char* kernel_source, ...@@ -144,7 +145,7 @@ program_ptr manager::create_program(const char* kernel_source,
const device_ptr dev) { const device_ptr dev) {
// create program object from kernel source // create program object from kernel source
size_t kernel_source_length = strlen(kernel_source); size_t kernel_source_length = strlen(kernel_source);
cl_program_ptr pptr; detail::raw_program_ptr pptr;
pptr.reset(v2get(CAF_CLF(clCreateProgramWithSource), dev->context_.get(), pptr.reset(v2get(CAF_CLF(clCreateProgramWithSource), dev->context_.get(),
1u, &kernel_source, &kernel_source_length), 1u, &kernel_source, &kernel_source_length),
false); false);
...@@ -153,7 +154,7 @@ program_ptr manager::create_program(const char* kernel_source, ...@@ -153,7 +154,7 @@ program_ptr manager::create_program(const char* kernel_source,
auto err = clBuildProgram(pptr.get(), 1, &dev_tmp, options, nullptr, nullptr); auto err = clBuildProgram(pptr.get(), 1, &dev_tmp, options, nullptr, nullptr);
if (err != CL_SUCCESS) { if (err != CL_SUCCESS) {
ostringstream oss; ostringstream oss;
oss << "clBuildProgram: " << get_opencl_error(err); oss << "clBuildProgram: " << opencl_error(err);
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
...@@ -180,14 +181,14 @@ program_ptr manager::create_program(const char* kernel_source, ...@@ -180,14 +181,14 @@ program_ptr manager::create_program(const char* kernel_source,
} }
cl_uint number_of_kernels = 0; cl_uint number_of_kernels = 0;
clCreateKernelsInProgram(pptr.get(), 0u, nullptr, &number_of_kernels); clCreateKernelsInProgram(pptr.get(), 0u, nullptr, &number_of_kernels);
map<string, cl_kernel_ptr> available_kernels; map<string, detail::raw_kernel_ptr> available_kernels;
if (number_of_kernels > 0) { if (number_of_kernels > 0) {
vector<cl_kernel> kernels(number_of_kernels); vector<cl_kernel> kernels(number_of_kernels);
err = clCreateKernelsInProgram(pptr.get(), number_of_kernels, err = clCreateKernelsInProgram(pptr.get(), number_of_kernels,
kernels.data(), nullptr); kernels.data(), nullptr);
if (err != CL_SUCCESS) { if (err != CL_SUCCESS) {
ostringstream oss; ostringstream oss;
oss << "clCreateKernelsInProgram: " << get_opencl_error(err); oss << "clCreateKernelsInProgram: " << opencl_error(err);
throw runtime_error(oss.str()); throw runtime_error(oss.str());
} }
for (cl_uint i = 0; i < number_of_kernels; ++i) { for (cl_uint i = 0; i < number_of_kernels; ++i) {
...@@ -199,10 +200,10 @@ program_ptr manager::create_program(const char* kernel_source, ...@@ -199,10 +200,10 @@ program_ptr manager::create_program(const char* kernel_source,
if (err != CL_SUCCESS) { if (err != CL_SUCCESS) {
ostringstream oss; ostringstream oss;
oss << "clGetKernelInfo (CL_KERNEL_FUNCTION_NAME): " oss << "clGetKernelInfo (CL_KERNEL_FUNCTION_NAME): "
<< get_opencl_error(err); << opencl_error(err);
throw runtime_error(oss.str()); throw runtime_error(oss.str());
} }
cl_kernel_ptr kernel; detail::raw_kernel_ptr kernel;
kernel.reset(move(kernels[i])); kernel.reset(move(kernels[i]));
available_kernels.emplace(string(name.data()), move(kernel)); available_kernels.emplace(string(name.data()), move(kernel));
} }
......
...@@ -27,7 +27,7 @@ void throwcl(const char* fname, cl_int err) { ...@@ -27,7 +27,7 @@ void throwcl(const char* fname, cl_int err) {
if (err != CL_SUCCESS) { if (err != CL_SUCCESS) {
std::string errstr = fname; std::string errstr = fname;
errstr += ": "; errstr += ": ";
errstr += get_opencl_error(err); errstr += opencl_error(err);
throw std::runtime_error(std::move(errstr)); throw std::runtime_error(std::move(errstr));
} }
} }
......
...@@ -48,11 +48,13 @@ platform_ptr platform::create(cl_platform_id platform_id, ...@@ -48,11 +48,13 @@ platform_ptr platform::create(cl_platform_id platform_id,
v2callcl(CAF_CLF(clGetDeviceIDs), platform_id, device_type, v2callcl(CAF_CLF(clGetDeviceIDs), platform_id, device_type,
discoverd, (ids.data() + known)); discoverd, (ids.data() + known));
} }
vector<cl_device_ptr> devices; vector<detail::raw_device_ptr> devices;
devices.resize(ids.size()); devices.resize(ids.size());
auto lift = [](cl_device_id ptr) { return cl_device_ptr{ptr, false}; }; auto lift = [](cl_device_id ptr) {
return detail::raw_device_ptr{ptr, false};
};
transform(ids.begin(), ids.end(), devices.begin(), lift); transform(ids.begin(), ids.end(), devices.begin(), lift);
cl_context_ptr context; detail::raw_context_ptr context;
context.reset(v2get(CAF_CLF(clCreateContext), nullptr, context.reset(v2get(CAF_CLF(clCreateContext), nullptr,
static_cast<unsigned>(ids.size()), static_cast<unsigned>(ids.size()),
ids.data(), pfn_notify, nullptr), ids.data(), pfn_notify, nullptr),
...@@ -87,7 +89,7 @@ string platform::platform_info(cl_platform_id platform_id, ...@@ -87,7 +89,7 @@ string platform::platform_info(cl_platform_id platform_id,
return string(buffer.data()); return string(buffer.data());
} }
platform::platform(cl_platform_id platform_id, cl_context_ptr context, platform::platform(cl_platform_id platform_id, detail::raw_context_ptr context,
string name, string vendor, string version, string name, string vendor, string version,
vector<device_ptr> devices) vector<device_ptr> devices)
: platform_id_(platform_id), : platform_id_(platform_id),
......
...@@ -32,9 +32,10 @@ using namespace std; ...@@ -32,9 +32,10 @@ using namespace std;
namespace caf { namespace caf {
namespace opencl { namespace opencl {
program::program(cl_context_ptr context, cl_command_queue_ptr queue, program::program(detail::raw_context_ptr context,
cl_program_ptr prog, detail::raw_command_queue_ptr queue,
map<string, cl_kernel_ptr> available_kernels) detail::raw_program_ptr prog,
map<string, detail::raw_kernel_ptr> available_kernels)
: context_(move(context)), : context_(move(context)),
program_(move(prog)), program_(move(prog)),
queue_(move(queue)), queue_(move(queue)),
......
This diff is collapsed.
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