clover: Pass execution dimensions and offset to the kernel as implicit arguments.

Reviewed-by: Jan Vesely <jan.vesely@rutgers.edu>
This commit is contained in:
Francisco Jerez 2014-10-08 17:39:35 +03:00
parent 06139c56fa
commit bf89a97748
2 changed files with 70 additions and 25 deletions

View File

@ -33,24 +33,8 @@ kernel::kernel(clover::program &prog, const std::string &name,
program(prog), _name(name), exec(*this),
program_ref(prog._kernel_ref_counter) {
for (auto &marg : margs) {
if (marg.type == module::argument::scalar)
_args.emplace_back(new scalar_argument(marg.size));
else if (marg.type == module::argument::global)
_args.emplace_back(new global_argument);
else if (marg.type == module::argument::local)
_args.emplace_back(new local_argument);
else if (marg.type == module::argument::constant)
_args.emplace_back(new constant_argument);
else if (marg.type == module::argument::image2d_rd ||
marg.type == module::argument::image3d_rd)
_args.emplace_back(new image_rd_argument);
else if (marg.type == module::argument::image2d_wr ||
marg.type == module::argument::image3d_wr)
_args.emplace_back(new image_wr_argument);
else if (marg.type == module::argument::sampler)
_args.emplace_back(new sampler_argument);
else
throw error(CL_INVALID_KERNEL_DEFINITION);
if (marg.semantic == module::argument::general)
_args.emplace_back(argument::create(marg));
}
}
@ -70,7 +54,7 @@ kernel::launch(command_queue &q,
const auto m = program().binary(q.device());
const auto reduced_grid_size =
map(divides(), grid_size, block_size);
void *st = exec.bind(&q);
void *st = exec.bind(&q, grid_offset);
// The handles are created during exec_context::bind(), so we need make
// sure to call exec_context::bind() before retrieving them.
@ -165,17 +149,38 @@ kernel::exec_context::~exec_context() {
}
void *
kernel::exec_context::bind(intrusive_ptr<command_queue> _q) {
kernel::exec_context::bind(intrusive_ptr<command_queue> _q,
const std::vector<size_t> &grid_offset) {
std::swap(q, _q);
// Bind kernel arguments.
auto &m = kern.program().binary(q->device());
auto margs = find(name_equals(kern.name()), m.syms).args;
auto msec = find(type_equals(module::section::text), m.secs);
auto explicit_arg = kern._args.begin();
for_each([=](kernel::argument &karg, const module::argument &marg) {
karg.bind(*this, marg);
}, kern.args(), margs);
for (auto &marg : margs) {
switch (marg.semantic) {
case module::argument::general:
(*(explicit_arg++))->bind(*this, marg);
case module::argument::grid_dimension: {
const cl_uint dimension = grid_offset.size();
auto arg = argument::create(marg);
arg->set(sizeof(dimension), &dimension);
arg->bind(*this, marg);
}
case module::argument::grid_offset: {
for (cl_uint x : pad_vector(*q, grid_offset, 1)) {
auto arg = argument::create(marg);
arg->set(sizeof(x), &x);
arg->bind(*this, marg);
}
}
}
}
// Create a new compute state if anything changed.
if (!st || q != _q ||
@ -283,6 +288,42 @@ namespace {
}
}
std::unique_ptr<kernel::argument>
kernel::argument::create(const module::argument &marg) {
if (marg.type == module::argument::scalar)
return std::unique_ptr<kernel::argument>(
new scalar_argument(marg.size));
else if (marg.type == module::argument::global)
return std::unique_ptr<kernel::argument>(
new global_argument);
else if (marg.type == module::argument::local)
return std::unique_ptr<kernel::argument>(
new local_argument);
else if (marg.type == module::argument::constant)
return std::unique_ptr<kernel::argument>(
new constant_argument);
else if (marg.type == module::argument::image2d_rd ||
marg.type == module::argument::image3d_rd)
return std::unique_ptr<kernel::argument>(
new image_rd_argument);
else if (marg.type == module::argument::image2d_wr ||
marg.type == module::argument::image3d_wr)
return std::unique_ptr<kernel::argument>(
new image_wr_argument);
else if (marg.type == module::argument::sampler)
return std::unique_ptr<kernel::argument>(
new sampler_argument);
else
throw error(CL_INVALID_KERNEL_DEFINITION);
}
kernel::argument::argument() : _set(false) {
}

View File

@ -46,7 +46,8 @@ namespace clover {
exec_context &
operator=(const exec_context &) = delete;
void *bind(intrusive_ptr<command_queue> _q);
void *bind(intrusive_ptr<command_queue> _q,
const std::vector<size_t> &grid_offset);
void unbind();
kernel &kern;
@ -68,7 +69,8 @@ namespace clover {
public:
class argument {
public:
argument();
static std::unique_ptr<argument>
create(const module::argument &marg);
argument(const argument &arg) = delete;
argument &
@ -92,6 +94,8 @@ namespace clover {
virtual void unbind(exec_context &ctx) = 0;
protected:
argument();
bool _set;
};