Commit 631f4a34 authored by Dominik Charousset's avatar Dominik Charousset

got rid of unneeded strings + exception safety

this patch forwards kernel names and source code transparently as
`const char*` rather than converting it to `std::string`s;
added static factory member function to program to avoid exceptions
during constructor execution
parent 5f217ff8
......@@ -69,24 +69,22 @@ class actor_facade<Ret(Args...)> : public actor {
actor_facade(command_dispatcher* dispatcher,
const program& prog,
const std::string& kernel_name)
const char* kernel_name)
: m_program(prog.m_program)
, m_context(prog.m_context)
, m_kernel_name(kernel_name)
, m_dispatcher(dispatcher)
{
CPPA_LOG_TRACE("new actor facde with ID " << this->id());
init_kernel(m_program.get(), m_kernel_name);
init_kernel(m_program.get(), kernel_name);
}
actor_facade(command_dispatcher* dispatcher,
const program& prog,
const std::string& kernel_name,
const char* 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)
......@@ -97,7 +95,7 @@ class actor_facade<Ret(Args...)> : public actor {
throw std::runtime_error("[!!!] Creating actor facade:"
" a maximum of 3 dimensions allowed");
}
init_kernel(m_program.get(), m_kernel_name);
init_kernel(m_program.get(), kernel_name);
}
void enqueue(const actor_ptr& sender, any_tuple msg) {
......@@ -114,10 +112,10 @@ class actor_facade<Ret(Args...)> : public actor {
private:
void init_kernel(cl_program program, std::string& kernel_name) {
void init_kernel(cl_program program, const char* kernel_name) {
cl_int err{0};
m_kernel.adopt(clCreateKernel(program,
kernel_name.c_str(),
kernel_name,
&err));
if (err != CL_SUCCESS) {
throw std::runtime_error("[!!!] clCreateKernel: '"
......@@ -180,7 +178,6 @@ class actor_facade<Ret(Args...)> : public actor {
program_ptr m_program;
kernel_ptr m_kernel;
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;
......
......@@ -76,7 +76,7 @@ class command_dispatcher {
template<typename Ret, typename... Args>
actor_ptr spawn(const program& prog,
const std::string& kernel_name,
const char* kernel_name,
size_t global_dim_1,
size_t global_dim_2 = 1,
size_t global_dim_3 = 1,
......@@ -106,15 +106,15 @@ class command_dispatcher {
}
template<typename Ret, typename... Args>
actor_ptr spawn(const std::string& kernel_source,
const std::string& kernel_name,
actor_ptr spawn(const char* kernel_source,
const char* 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},
return spawn<Ret, Args...>(program::create(kernel_source),
kernel_name,
global_dim_1,
global_dim_2,
......@@ -126,14 +126,14 @@ class command_dispatcher {
template<typename Ret, typename... Args>
actor_ptr spawn(const program& prog,
const std::string& kernel_name) {
const char* kernel_name) {
return new actor_facade<Ret (Args...)>(this, prog, kernel_name);
}
template<typename Ret, typename... Args>
actor_ptr spawn(const std::string& kernel_source,
const std::string& kernel_name) {
return spawn<Ret, Args...>(program{kernel_source}, kernel_name);
actor_ptr spawn(const char* kernel_source,
const char* kernel_name) {
return spawn<Ret, Args...>(program::create(kernel_source), kernel_name);
}
private:
......
......@@ -49,11 +49,13 @@ class program {
public:
program();
program(const std::string& kernel_source);
static program create(const char* kernel_source);
private:
//program();
program(context_ptr context, program_ptr program);
context_ptr m_context;
program_ptr m_program;
......
......@@ -35,51 +35,53 @@
namespace cppa { namespace opencl {
program::program() : m_context(nullptr), m_program(nullptr) { }
//program::program() : m_context(nullptr), pptr(nullptr) { }
program::program(const std::string& kernel_source) {
m_context =
cppa::detail::singleton_manager::get_command_dispatcher()->m_context;
program::program(context_ptr context, program_ptr program)
: m_context(std::move(context)), m_program(std::move(program)) { }
program program::create(const char* kernel_source) {
context_ptr cptr = get_command_dispatcher()->m_context;
cl_int err{0};
/* create program object from kernel source */
size_t kernel_source_length = kernel_source.size();
const char *kernel_source_cstr = kernel_source.c_str();
m_program.adopt(clCreateProgramWithSource(m_context.get(),
1,
&kernel_source_cstr,
&kernel_source_length,
&err));
// create program object from kernel source
program_ptr pptr;
size_t kernel_source_length = strlen(kernel_source);
pptr.adopt(clCreateProgramWithSource(cptr.get(),
1,
&kernel_source,
&kernel_source_length,
&err));
if (err != CL_SUCCESS) {
throw std::runtime_error("[!!!] clCreateProgramWithSource: '"
+ get_opencl_error(err)
+ "'.");
throw std::runtime_error("clCreateProgramWithSource: '"
+ get_opencl_error(err)
+ "'.");
}
/* build programm from program object */
err = clBuildProgram(m_program.get(), 0, NULL, NULL, NULL, NULL);
// build programm from program object
err = clBuildProgram(pptr.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(),
err = clGetProgramBuildInfo(pptr.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(),
err = clGetProgramBuildInfo(pptr.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(),
err = clGetProgramBuildInfo(pptr.get(),
device_used.get(),
CL_PROGRAM_BUILD_LOG,
ret_val_size,
......@@ -97,21 +99,21 @@ program::program(const std::string& kernel_source) {
get_command_dispatcher()->
m_devices.front().dev_id);
cl_build_status build_status;
err = clGetProgramBuildInfo(m_program.get(),
err = clGetProgramBuildInfo(pptr.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(),
err = clGetProgramBuildInfo(pptr.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(),
err = clGetProgramBuildInfo(pptr.get(),
device_used.get(),
CL_PROGRAM_BUILD_LOG,
ret_val_size,
......@@ -123,6 +125,7 @@ program::program(const std::string& kernel_source) {
<< std::endl;
#endif
}
return {cptr, pptr};
}
} } // namespace cppa::opencl
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