Commit 9a174aaf authored by Joseph Noir's avatar Joseph Noir

bug fixes

parent 27d5075f
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
#define CPPA_OPENCL_ACTOR_FACADE_HPP #define CPPA_OPENCL_ACTOR_FACADE_HPP
#include <iostream> #include <iostream>
#include <stdexcept>
#include "cppa/cppa.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
...@@ -41,6 +44,7 @@ ...@@ -41,6 +44,7 @@
#include "cppa/util/int_list.hpp" #include "cppa/util/int_list.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/scope_guard.hpp"
#include "cppa/opencl/global.hpp" #include "cppa/opencl/global.hpp"
#include "cppa/opencl/command.hpp" #include "cppa/opencl/command.hpp"
...@@ -59,7 +63,7 @@ template<typename Signature> ...@@ -59,7 +63,7 @@ template<typename Signature>
class actor_facade; class actor_facade;
template<typename Ret, typename... Args> template<typename Ret, typename... Args>
class actor_facade<Ret(Args...)> : public cppa::detail::scheduled_actor_dummy { class actor_facade<Ret(Args...)> : public actor {
public: public:
...@@ -71,35 +75,85 @@ class actor_facade<Ret(Args...)> : public cppa::detail::scheduled_actor_dummy { ...@@ -71,35 +75,85 @@ class actor_facade<Ret(Args...)> : public cppa::detail::scheduled_actor_dummy {
, m_kernel_name(kernel_name) , m_kernel_name(kernel_name)
, m_dispatcher(dispatcher) , m_dispatcher(dispatcher)
{ {
cl_int err{0}; CPPA_LOG_TRACE("new actor facde with ID " << this->id());
m_kernel.adopt(clCreateKernel(m_program.get(), init_kernel(m_program.get(), m_kernel_name);
m_kernel_name.c_str(), }
&err));
if (err != CL_SUCCESS) { actor_facade(command_dispatcher* dispatcher,
throw std::runtime_error("[!!!] clCreateKernel: '" const program& prog,
+ get_opencl_error(err) const std::string& kernel_name,
+ "'."); std::vector<size_t>& global_dimensions,
std::vector<size_t>& local_dimensions)
: m_program(prog.m_program)
, m_context(prog.m_context)
, m_kernel_name(kernel_name)
, m_dispatcher(dispatcher)
, m_global_dimensions(global_dimensions)
, m_local_dimensions(local_dimensions)
{
CPPA_LOG_TRACE("new actor facde with ID " << this->id());
if(m_local_dimensions .size() > 3 ||
m_global_dimensions.size() > 3) {
throw std::runtime_error("[!!!] Creating actor facade:"
" a maximum of 3 dimensions allowed");
} }
init_kernel(m_program.get(), m_kernel_name);
} }
void enqueue(const actor_ptr& sender, any_tuple msg) { void enqueue(const actor_ptr& sender, any_tuple msg) {
CPPA_LOG_TRACE("actor_facade::enqueue()");
typename util::il_indices<util::type_list<Args...>>::type indices; typename util::il_indices<util::type_list<Args...>>::type indices;
enqueue_impl(sender, msg, indices); enqueue_impl(sender, msg, message_id{}, indices);
}
void sync_enqueue(const actor_ptr& sender, message_id id, any_tuple msg) {
CPPA_LOG_TRACE("actor_facade::sync_enqueue()");
typename util::il_indices<util::type_list<Args...>>::type indices;
enqueue_impl(sender, msg, id, indices);
} }
private: private:
void init_kernel(cl_program program, std::string& kernel_name) {
cl_int err{0};
m_kernel.adopt(clCreateKernel(program,
kernel_name.c_str(),
&err));
if (err != CL_SUCCESS) {
throw std::runtime_error("[!!!] clCreateKernel: '"
+ get_opencl_error(err)
+ "'.");
}
}
template<long... Is> template<long... Is>
void enqueue_impl(const actor_ptr& sender, any_tuple msg, util::int_list<Is...>) { void enqueue_impl(const actor_ptr& sender, any_tuple msg, message_id id, util::int_list<Is...>) {
auto opt = tuple_cast<Args...>(msg); auto opt = tuple_cast<Args...>(msg);
if (opt) { if (opt) {
response_handle handle{this, sender, message_id_t{}}; response_handle handle{this, sender, id};
std::vector<size_t> global_dimensions {1024, 1, 1}; size_t number_of_values = 1;
std::vector<size_t> local_dimensions; if (!m_global_dimensions.empty()) {
int number_of_values = 1; for (auto s : m_global_dimensions) {
for (size_t s : global_dimensions) { number_of_values *= s;
}
for (auto s : m_local_dimensions) {
if (s > 0) {
number_of_values *= s; number_of_values *= s;
} }
}
}
else {
number_of_values = get<0>(*opt).size();
m_global_dimensions.push_back(number_of_values);
m_global_dimensions.push_back(1);
m_global_dimensions.push_back(1);
}
if (m_global_dimensions.empty() || number_of_values <= 0) {
throw std::runtime_error("[!!!] enqueue: can't handle dimension sizes!");
}
// for (auto s : m_global_dimensions) std::cout << "[global] " << s << std::endl;
// for (auto s : m_local_dimensions ) std::cout << "[local ] " << s << std::endl;
// std::cout << "number stuff " << number_of_values << std::endl;
Ret result_buf(number_of_values); Ret result_buf(number_of_values);
std::vector<mem_ptr> arguments; std::vector<mem_ptr> arguments;
add_arguments_to_kernel(arguments, add_arguments_to_kernel(arguments,
...@@ -107,14 +161,16 @@ class actor_facade<Ret(Args...)> : public cppa::detail::scheduled_actor_dummy { ...@@ -107,14 +161,16 @@ class actor_facade<Ret(Args...)> : public cppa::detail::scheduled_actor_dummy {
m_kernel.get(), m_kernel.get(),
result_buf, result_buf,
get_ref<Is>(*opt)...); get_ref<Is>(*opt)...);
CPPA_LOG_TRACE("enqueue to dispatcher");
enqueue_to_dispatcher(m_dispatcher, enqueue_to_dispatcher(m_dispatcher,
make_counted<command_impl<Ret>>(handle, make_counted<command_impl<Ret>>(handle,
m_kernel, m_kernel,
arguments, arguments,
global_dimensions, m_global_dimensions,
local_dimensions)); m_local_dimensions));
} }
else { else {
aout << "*** warning: tuple_cast failed!\n";
// slap caller around with a large fish // slap caller around with a large fish
} }
} }
...@@ -126,6 +182,8 @@ class actor_facade<Ret(Args...)> : public cppa::detail::scheduled_actor_dummy { ...@@ -126,6 +182,8 @@ class actor_facade<Ret(Args...)> : public cppa::detail::scheduled_actor_dummy {
context_ptr m_context; context_ptr m_context;
std::string m_kernel_name; std::string m_kernel_name;
command_dispatcher* m_dispatcher; command_dispatcher* m_dispatcher;
std::vector<size_t> m_global_dimensions;
std::vector<size_t> m_local_dimensions;
void add_arguments_to_kernel_rec(args_vec& arguments, void add_arguments_to_kernel_rec(args_vec& arguments,
cl_context, cl_context,
......
...@@ -36,9 +36,11 @@ ...@@ -36,9 +36,11 @@
#include <functional> #include <functional>
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/logging.hpp"
#include "cppa/opencl/global.hpp" #include "cppa/opencl/global.hpp"
#include "cppa/response_handle.hpp" #include "cppa/response_handle.hpp"
#include "cppa/opencl/smart_ptr.hpp" #include "cppa/opencl/smart_ptr.hpp"
#include "cppa/util/scope_guard.hpp"
namespace cppa { namespace opencl { namespace cppa { namespace opencl {
...@@ -48,7 +50,7 @@ class command : public ref_counted { ...@@ -48,7 +50,7 @@ class command : public ref_counted {
command* next; command* next;
virtual void enqueue (command_queue_ptr queue) = 0; virtual void enqueue(command_queue_ptr queue) = 0;
}; };
...@@ -83,6 +85,7 @@ class command_impl : public command { ...@@ -83,6 +85,7 @@ class command_impl : public command {
} }
void enqueue (command_queue_ptr queue) { void enqueue (command_queue_ptr queue) {
CPPA_LOG_TRACE("command::enqueue()");
this->ref(); this->ref();
cl_int err{0}; cl_int err{0};
m_queue = queue; m_queue = queue;
...@@ -107,6 +110,9 @@ class command_impl : public command { ...@@ -107,6 +110,9 @@ class command_impl : public command {
err = clSetEventCallback(ptr, err = clSetEventCallback(ptr,
CL_COMPLETE, CL_COMPLETE,
[](cl_event, cl_int, void* data) { [](cl_event, cl_int, void* data) {
CPPA_LOGC_TRACE("command_impl",
"enqueue",
"command::enqueue()::callback()");
auto cmd = reinterpret_cast<command_impl*>(data); auto cmd = reinterpret_cast<command_impl*>(data);
cmd->handle_results(); cmd->handle_results();
cmd->deref(); cmd->deref();
...@@ -131,6 +137,7 @@ class command_impl : public command { ...@@ -131,6 +137,7 @@ class command_impl : public command {
std::vector<size_t> m_local_dimensions; std::vector<size_t> m_local_dimensions;
void handle_results () { void handle_results () {
CPPA_LOG_TRACE("command::handle_results()");
/* get results from gpu */ /* get results from gpu */
cl_int err{0}; cl_int err{0};
cl_event read_event; cl_event read_event;
......
...@@ -34,16 +34,20 @@ ...@@ -34,16 +34,20 @@
#include <atomic> #include <atomic>
#include <vector> #include <vector>
#include <algorithm>
#include <functional> #include <functional>
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/opencl/global.hpp" #include "cppa/opencl/global.hpp"
#include "cppa/opencl/command.hpp" #include "cppa/opencl/command.hpp"
#include "cppa/opencl/program.hpp" #include "cppa/opencl/program.hpp"
#include "cppa/opencl/smart_ptr.hpp" #include "cppa/opencl/smart_ptr.hpp"
#include "cppa/opencl/actor_facade.hpp" #include "cppa/opencl/actor_facade.hpp"
#include "cppa/detail/singleton_mixin.hpp" #include "cppa/detail/singleton_mixin.hpp"
#include "cppa/detail/singleton_manager.hpp" #include "cppa/detail/singleton_manager.hpp"
#include "cppa/intrusive/blocking_single_reader_queue.hpp" #include "cppa/intrusive/blocking_single_reader_queue.hpp"
namespace cppa { namespace opencl { namespace cppa { namespace opencl {
...@@ -70,6 +74,55 @@ class command_dispatcher { ...@@ -70,6 +74,55 @@ class command_dispatcher {
void enqueue(); void enqueue();
template<typename Ret, typename... Args>
actor_ptr spawn(const program& prog,
const std::string& kernel_name,
size_t global_dim_1,
size_t global_dim_2 = 1,
size_t global_dim_3 = 1,
size_t local_dim_1 = 0,
size_t local_dim_2 = 0,
size_t local_dim_3 = 0) {
std::vector<size_t> global_dims {global_dim_1,
global_dim_2,
global_dim_3};
std::vector<size_t> local_dims {local_dim_1,
local_dim_2,
local_dim_3};
auto f_remove_invalid = [] (size_t s) { return s <= 0; };
// auto global_invalid = std::remove_if(global_dims.begin(),
// global_dims.end(),
// f_remove_invalid);
// global_dims.erase(global_invalid, global_dims.end());
auto local_invalid = std::remove_if(local_dims.begin(),
local_dims.end(),
f_remove_invalid);
local_dims.erase(local_invalid, local_dims.end());
return new actor_facade<Ret (Args...)>(this,
prog,
kernel_name,
global_dims,
local_dims);
}
template<typename Ret, typename... Args>
actor_ptr spawn(const std::string& kernel_source,
const std::string& kernel_name,
size_t global_dim_1,
size_t global_dim_2 = 1,
size_t global_dim_3 = 1,
size_t local_dim_1 = 0,
size_t local_dim_2 = 0,
size_t local_dim_3 = 0) {
return spawn<Ret, Args...>(program{kernel_source},
kernel_name,
global_dim_1,
global_dim_2,
global_dim_3,
local_dim_1,
local_dim_2,
local_dim_3);
}
template<typename Ret, typename... Args> template<typename Ret, typename... Args>
actor_ptr spawn(const program& prog, actor_ptr spawn(const program& prog,
...@@ -107,7 +160,8 @@ class command_dispatcher { ...@@ -107,7 +160,8 @@ class command_dispatcher {
, max_itms_per_dim(std::move(max_itms_per_dim)) { } , max_itms_per_dim(std::move(max_itms_per_dim)) { }
}; };
typedef intrusive::blocking_single_reader_queue<command,dereferencer> job_queue; typedef intrusive::blocking_single_reader_queue<command,dereferencer>
job_queue;
static inline command_dispatcher* create_singleton() { static inline command_dispatcher* create_singleton() {
return new command_dispatcher; return new command_dispatcher;
......
...@@ -49,6 +49,7 @@ class program { ...@@ -49,6 +49,7 @@ class program {
public: public:
program();
program(const std::string& kernel_source); program(const std::string& kernel_source);
private: private:
......
...@@ -63,9 +63,11 @@ struct command_dispatcher::worker { ...@@ -63,9 +63,11 @@ struct command_dispatcher::worker {
void operator()() { void operator()() {
job_ptr job; job_ptr job;
for (;;) { for (;;) {
/* wait for device */ /*
/* get results */ * todo:
/* wait for job */ * manage device usage
* wait for device
*/
// adopt reference count of job queue // adopt reference count of job queue
job.adopt(m_job_queue->pop()); job.adopt(m_job_queue->pop());
if(job != m_dummy) { if(job != m_dummy) {
...@@ -82,7 +84,6 @@ struct command_dispatcher::worker { ...@@ -82,7 +84,6 @@ struct command_dispatcher::worker {
cout << "worker done" << endl; cout << "worker done" << endl;
return; return;
} }
// ...?
} }
} }
...@@ -125,8 +126,8 @@ void command_dispatcher::initialize() { ...@@ -125,8 +126,8 @@ void command_dispatcher::initialize() {
/* find gpu devices on our platform */ /* find gpu devices on our platform */
int pid{0}; int pid{0};
cl_uint num_devices{0}; cl_uint num_devices{0};
cout << "Currently only looking for cpu devices!" << endl; // cout << "Currently only looking for cpu devices!" << endl;
cl_device_type dev_type{CL_DEVICE_TYPE_CPU /*CL_DEVICE_TYPE_GPU*/}; cl_device_type dev_type{CL_DEVICE_TYPE_GPU};
err = clGetDeviceIDs(ids[pid], dev_type, 0, NULL, &num_devices); err = clGetDeviceIDs(ids[pid], dev_type, 0, NULL, &num_devices);
if (err == CL_DEVICE_NOT_FOUND) { if (err == CL_DEVICE_NOT_FOUND) {
cout << "NO GPU DEVICES FOUND! LOOKING FOR CPU DEVICES NOW ..." << endl; cout << "NO GPU DEVICES FOUND! LOOKING FOR CPU DEVICES NOW ..." << endl;
......
...@@ -28,11 +28,15 @@ ...@@ -28,11 +28,15 @@
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. * * along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/ \******************************************************************************/
#include <vector>
#include "cppa/opencl/program.hpp" #include "cppa/opencl/program.hpp"
#include "cppa/opencl/command_dispatcher.hpp" #include "cppa/opencl/command_dispatcher.hpp"
namespace cppa { namespace opencl { namespace cppa { namespace opencl {
program::program() : m_context(nullptr), m_program(nullptr) { }
program::program(const std::string& kernel_source) { program::program(const std::string& kernel_source) {
m_context = m_context =
cppa::detail::singleton_manager::get_command_dispatcher()->m_context; cppa::detail::singleton_manager::get_command_dispatcher()->m_context;
...@@ -57,9 +61,67 @@ program::program(const std::string& kernel_source) { ...@@ -57,9 +61,67 @@ program::program(const std::string& kernel_source) {
/* build programm from program object */ /* build programm from program object */
err = clBuildProgram(m_program.get(), 0, NULL, NULL, NULL, NULL); err = clBuildProgram(m_program.get(), 0, NULL, NULL, NULL, NULL);
if (err != CL_SUCCESS) { if (err != CL_SUCCESS) {
device_ptr device_used(cppa::detail::singleton_manager::
get_command_dispatcher()->
m_devices.front().dev_id);
cl_build_status build_status;
err = clGetProgramBuildInfo(m_program.get(),
device_used.get(),
CL_PROGRAM_BUILD_STATUS,
sizeof(cl_build_status),
&build_status,
NULL);
size_t ret_val_size;
err = clGetProgramBuildInfo(m_program.get(),
device_used.get(),
CL_PROGRAM_BUILD_LOG,
0,
NULL,
&ret_val_size);
std::vector<char> build_log(ret_val_size+1);
err = clGetProgramBuildInfo(m_program.get(),
device_used.get(),
CL_PROGRAM_BUILD_LOG,
ret_val_size,
build_log.data(),
NULL);
build_log[ret_val_size] = '\0';
throw std::runtime_error("[!!!] clBuildProgram: '" throw std::runtime_error("[!!!] clBuildProgram: '"
+ get_opencl_error(err) + get_opencl_error(err)
+ "'."); + "'. Build log: "
+ build_log.data());
}
else {
#ifdef CPPA_DEBUG
device_ptr device_used(cppa::detail::singleton_manager::
get_command_dispatcher()->
m_devices.front().dev_id);
cl_build_status build_status;
err = clGetProgramBuildInfo(m_program.get(),
device_used.get(),
CL_PROGRAM_BUILD_STATUS,
sizeof(cl_build_status),
&build_status,
NULL);
size_t ret_val_size;
err = clGetProgramBuildInfo(m_program.get(),
device_used.get(),
CL_PROGRAM_BUILD_LOG,
0,
NULL,
&ret_val_size);
std::vector<char> build_log(ret_val_size+1);
err = clGetProgramBuildInfo(m_program.get(),
device_used.get(),
CL_PROGRAM_BUILD_LOG,
ret_val_size,
build_log.data(),
NULL);
build_log[ret_val_size] = '\0';
std::cout << "clBuildProgram log: '"
<< build_log.data()
<< std::endl;
#endif
} }
} }
......
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