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

bug fixes

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