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,
const char* fname,
const opencl::dim_vec& dims,
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;
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,
const char* fname,
const opencl::dim_vec& dims,
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;
return spawn_cl<Signature, Ts...>(opencl::program::create(source),
fname,
dims,
offset,
local_dims);
local_dims,
result_size);
}
/**
......@@ -165,7 +168,8 @@ inline actor_ptr spawn_cl(const opencl::program& prog,
MapResult map_result,
const opencl::dim_vec& dims,
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;
typedef typename util::get_callable_trait<MapArgs>::fun_type f0;
typedef typename util::get_callable_trait<MapResult>::fun_type f1;
......@@ -176,7 +180,8 @@ inline actor_ptr spawn_cl(const opencl::program& prog,
fname,
dims,
offset,
local_dims);
local_dims,
result_size);
}
/**
......@@ -195,7 +200,8 @@ inline actor_ptr spawn_cl(const char* source,
MapResult map_result,
const opencl::dim_vec& dims,
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;
return spawn_cl(opencl::program::create(source),
fun_name,
......@@ -203,7 +209,8 @@ inline actor_ptr spawn_cl(const char* source,
move(map_result),
dims,
offset,
local_dims);
local_dims,
result_size);
}
} // namespace cppa
......
......@@ -79,7 +79,8 @@ class actor_facade<Ret(Args...)> : public actor {
result_mapping map_result,
const dim_vec& global_dims,
const dim_vec& offsets,
const dim_vec& local_dims) {
const dim_vec& local_dims,
size_t result_size) {
if (global_dims.empty()) {
auto str = "OpenCL kernel needs at least 1 global dimension.";
CPPA_LOGM_ERROR(detail::demangle(typeid(actor_facade)).c_str(), str);
......@@ -107,13 +108,20 @@ class actor_facade<Ret(Args...)> : public actor {
CPPA_LOGM_ERROR(detail::demangle<actor_facade>().c_str(), 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,
kernel,
global_dims,
offsets,
local_dims,
std::move(map_args),
std::move(map_result)};
std::move(map_result),
result_size};
}
void enqueue(const message_header& hdr, any_tuple msg) override {
......@@ -130,7 +138,8 @@ class actor_facade<Ret(Args...)> : public actor {
const dim_vec& global_offsets,
const dim_vec& local_dimensions,
arg_mapping map_args,
result_mapping map_result)
result_mapping map_result,
size_t result_size)
: m_kernel(kernel)
, m_program(prog.m_program)
, m_context(prog.m_context)
......@@ -140,6 +149,7 @@ class actor_facade<Ret(Args...)> : public actor {
, m_local_dimensions(local_dimensions)
, m_map_args(std::move(map_args))
, m_map_result(std::move(map_result))
, m_result_size(result_size)
{
CPPA_LOG_TRACE("id: " << this->id());
}
......@@ -152,12 +162,9 @@ class actor_facade<Ret(Args...)> : public actor {
auto opt = m_map_args(std::move(msg));
if (opt) {
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;
add_arguments_to_kernel<Ret>(arguments,
ret_size,
m_result_size,
get_ref<Is>(*opt)...);
auto cmd = make_counted<command<actor_facade, Ret>>(handle,
this,
......@@ -178,6 +185,7 @@ class actor_facade<Ret(Args...)> : public actor {
dim_vec m_local_dimensions;
arg_mapping m_map_args;
result_mapping m_map_result;
size_t m_result_size;
void add_arguments_to_kernel_rec(args_vec& arguments) {
cl_int err{0};
......
......@@ -99,9 +99,13 @@ void multiplier() {
// creates matrix_size * matrix_size global work items
// 4th arg: offsets for global 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,
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
sync_send(worker, move(m1), move(m2)).then(
[](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