Commit bf49e5f1 authored by Joseph Noir's avatar Joseph Noir

added configureable result buffer size to spawn_cl

This is a new argument for the function spawn_cl. It defaults to zero,
which causes the implementation to calculate the buffer size according
to the number of create work-items.

The simple matrix example sets the buffer size manually.
parent 3a65e86f
...@@ -122,10 +122,11 @@ inline actor_ptr spawn_cl(const opencl::program& prog, ...@@ -122,10 +122,11 @@ inline actor_ptr spawn_cl(const opencl::program& prog,
const char* fname, 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 = {}) { const opencl::dim_vec& local_dims = {},
size_t result_size = 0) {
using std::move; using std::move;
detail::cl_spawn_helper<Signature> f; detail::cl_spawn_helper<Signature> f;
return f(prog, fname, dims, offset, local_dims); return f(prog, fname, dims, offset, local_dims, result_size);
} }
/** /**
...@@ -140,13 +141,15 @@ inline actor_ptr spawn_cl(const char* source, ...@@ -140,13 +141,15 @@ inline actor_ptr spawn_cl(const char* source,
const char* fname, 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 = {}) { const opencl::dim_vec& local_dims = {},
size_t result_size = 0) {
using std::move; using std::move;
return spawn_cl<Signature, Ts...>(opencl::program::create(source), return spawn_cl<Signature, Ts...>(opencl::program::create(source),
fname, fname,
dims, dims,
offset, offset,
local_dims); local_dims,
result_size);
} }
/** /**
...@@ -165,7 +168,8 @@ inline actor_ptr spawn_cl(const opencl::program& prog, ...@@ -165,7 +168,8 @@ inline actor_ptr spawn_cl(const opencl::program& prog,
MapResult map_result, MapResult map_result,
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 = {}) { const opencl::dim_vec& local_dims = {},
size_t result_size = 0) {
using std::move; using std::move;
typedef typename util::get_callable_trait<MapArgs>::fun_type f0; typedef typename util::get_callable_trait<MapArgs>::fun_type f0;
typedef typename util::get_callable_trait<MapResult>::fun_type f1; typedef typename util::get_callable_trait<MapResult>::fun_type f1;
...@@ -176,7 +180,8 @@ inline actor_ptr spawn_cl(const opencl::program& prog, ...@@ -176,7 +180,8 @@ inline actor_ptr spawn_cl(const opencl::program& prog,
fname, fname,
dims, dims,
offset, offset,
local_dims); local_dims,
result_size);
} }
/** /**
...@@ -195,7 +200,8 @@ inline actor_ptr spawn_cl(const char* source, ...@@ -195,7 +200,8 @@ inline actor_ptr spawn_cl(const char* source,
MapResult map_result, MapResult map_result,
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 = {}) { const opencl::dim_vec& local_dims = {},
size_t result_size = 0) {
using std::move; using std::move;
return spawn_cl(opencl::program::create(source), return spawn_cl(opencl::program::create(source),
fun_name, fun_name,
...@@ -203,7 +209,8 @@ inline actor_ptr spawn_cl(const char* source, ...@@ -203,7 +209,8 @@ inline actor_ptr spawn_cl(const char* source,
move(map_result), move(map_result),
dims, dims,
offset, offset,
local_dims); local_dims,
result_size);
} }
} // namespace cppa } // namespace cppa
......
...@@ -79,7 +79,8 @@ class actor_facade<Ret(Args...)> : public actor { ...@@ -79,7 +79,8 @@ class actor_facade<Ret(Args...)> : public actor {
result_mapping map_result, result_mapping map_result,
const dim_vec& global_dims, const dim_vec& global_dims,
const dim_vec& offsets, const dim_vec& offsets,
const dim_vec& local_dims) { const dim_vec& local_dims,
size_t result_size) {
if (global_dims.empty()) { if (global_dims.empty()) {
auto str = "OpenCL kernel needs at least 1 global dimension."; auto str = "OpenCL kernel needs at least 1 global dimension.";
CPPA_LOGM_ERROR(detail::demangle(typeid(actor_facade)).c_str(), str); CPPA_LOGM_ERROR(detail::demangle(typeid(actor_facade)).c_str(), str);
...@@ -107,13 +108,20 @@ class actor_facade<Ret(Args...)> : public actor { ...@@ -107,13 +108,20 @@ class actor_facade<Ret(Args...)> : public actor {
CPPA_LOGM_ERROR(detail::demangle<actor_facade>().c_str(), oss.str()); CPPA_LOGM_ERROR(detail::demangle<actor_facade>().c_str(), oss.str());
throw std::runtime_error(oss.str()); throw std::runtime_error(oss.str());
} }
if (result_size == 0) {
result_size = std::accumulate(global_dims.begin(),
global_dims.end(),
1,
std::multiplies<size_t>{});
}
return new actor_facade<Ret (Args...)>{prog, return new actor_facade<Ret (Args...)>{prog,
kernel, kernel,
global_dims, global_dims,
offsets, offsets,
local_dims, local_dims,
std::move(map_args), std::move(map_args),
std::move(map_result)}; std::move(map_result),
result_size};
} }
void enqueue(const message_header& hdr, any_tuple msg) override { void enqueue(const message_header& hdr, any_tuple msg) override {
...@@ -130,7 +138,8 @@ class actor_facade<Ret(Args...)> : public actor { ...@@ -130,7 +138,8 @@ class actor_facade<Ret(Args...)> : public actor {
const dim_vec& global_offsets, const dim_vec& global_offsets,
const dim_vec& local_dimensions, const dim_vec& local_dimensions,
arg_mapping map_args, arg_mapping map_args,
result_mapping map_result) result_mapping map_result,
size_t result_size)
: m_kernel(kernel) : m_kernel(kernel)
, m_program(prog.m_program) , m_program(prog.m_program)
, m_context(prog.m_context) , m_context(prog.m_context)
...@@ -140,6 +149,7 @@ class actor_facade<Ret(Args...)> : public actor { ...@@ -140,6 +149,7 @@ class actor_facade<Ret(Args...)> : public actor {
, m_local_dimensions(local_dimensions) , m_local_dimensions(local_dimensions)
, m_map_args(std::move(map_args)) , m_map_args(std::move(map_args))
, m_map_result(std::move(map_result)) , m_map_result(std::move(map_result))
, m_result_size(result_size)
{ {
CPPA_LOG_TRACE("id: " << this->id()); CPPA_LOG_TRACE("id: " << this->id());
} }
...@@ -152,12 +162,9 @@ class actor_facade<Ret(Args...)> : public actor { ...@@ -152,12 +162,9 @@ class actor_facade<Ret(Args...)> : public actor {
auto opt = m_map_args(std::move(msg)); auto opt = m_map_args(std::move(msg));
if (opt) { if (opt) {
response_handle handle{this, sender, id.response_id()}; response_handle handle{this, sender, id.response_id()};
size_t ret_size = std::accumulate(m_global_dimensions.begin(),
m_global_dimensions.end(),
1, std::multiplies<size_t>{});
std::vector<mem_ptr> arguments; std::vector<mem_ptr> arguments;
add_arguments_to_kernel<Ret>(arguments, add_arguments_to_kernel<Ret>(arguments,
ret_size, m_result_size,
get_ref<Is>(*opt)...); get_ref<Is>(*opt)...);
auto cmd = make_counted<command<actor_facade, Ret>>(handle, auto cmd = make_counted<command<actor_facade, Ret>>(handle,
this, this,
...@@ -178,6 +185,7 @@ class actor_facade<Ret(Args...)> : public actor { ...@@ -178,6 +185,7 @@ class actor_facade<Ret(Args...)> : public actor {
dim_vec m_local_dimensions; dim_vec m_local_dimensions;
arg_mapping m_map_args; arg_mapping m_map_args;
result_mapping m_map_result; result_mapping m_map_result;
size_t m_result_size;
void add_arguments_to_kernel_rec(args_vec& arguments) { void add_arguments_to_kernel_rec(args_vec& arguments) {
cl_int err{0}; cl_int err{0};
......
...@@ -99,9 +99,13 @@ void multiplier() { ...@@ -99,9 +99,13 @@ void multiplier() {
// creates matrix_size * matrix_size global work items // creates matrix_size * matrix_size global work items
// 4th arg: offsets for global dimensions (optional) // 4th arg: offsets for global dimensions (optional)
// 5th arg: local dimensions (optional) // 5th arg: local dimensions (optional)
// 6th arg: number of elements in the result buffer
auto worker = spawn_cl<float*(float*,float*)>(kernel_source, auto worker = spawn_cl<float*(float*,float*)>(kernel_source,
kernel_name, kernel_name,
{matrix_size, matrix_size}); {matrix_size, matrix_size},
{},
{},
matrix_size * matrix_size);
// send both matrices to the actor and wait for a result // send both matrices to the actor and wait for a result
sync_send(worker, move(m1), move(m2)).then( sync_send(worker, move(m1), move(m2)).then(
[](const vector<float>& result) { [](const vector<float>& result) {
......
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