From bf89a97748748592639087e8167e29c98c740d33 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 8 Oct 2014 17:39:35 +0300 Subject: clover: Pass execution dimensions and offset to the kernel as implicit arguments. Reviewed-by: Jan Vesely --- src/gallium/state_trackers/clover/core/kernel.cpp | 87 +++++++++++++++++------ src/gallium/state_trackers/clover/core/kernel.hpp | 8 ++- 2 files changed, 70 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp index e4b2152e4ab..947e785903e 100644 --- a/src/gallium/state_trackers/clover/core/kernel.cpp +++ b/src/gallium/state_trackers/clover/core/kernel.cpp @@ -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 _q) { +kernel::exec_context::bind(intrusive_ptr _q, + const std::vector &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::create(const module::argument &marg) { + if (marg.type == module::argument::scalar) + return std::unique_ptr( + new scalar_argument(marg.size)); + + else if (marg.type == module::argument::global) + return std::unique_ptr( + new global_argument); + + else if (marg.type == module::argument::local) + return std::unique_ptr( + new local_argument); + + else if (marg.type == module::argument::constant) + return std::unique_ptr( + new constant_argument); + + else if (marg.type == module::argument::image2d_rd || + marg.type == module::argument::image3d_rd) + return std::unique_ptr( + new image_rd_argument); + + else if (marg.type == module::argument::image2d_wr || + marg.type == module::argument::image3d_wr) + return std::unique_ptr( + new image_wr_argument); + + else if (marg.type == module::argument::sampler) + return std::unique_ptr( + new sampler_argument); + + else + throw error(CL_INVALID_KERNEL_DEFINITION); +} + kernel::argument::argument() : _set(false) { } diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp index f9e2765ee36..bf5998de825 100644 --- a/src/gallium/state_trackers/clover/core/kernel.hpp +++ b/src/gallium/state_trackers/clover/core/kernel.hpp @@ -46,7 +46,8 @@ namespace clover { exec_context & operator=(const exec_context &) = delete; - void *bind(intrusive_ptr _q); + void *bind(intrusive_ptr _q, + const std::vector &grid_offset); void unbind(); kernel &kern; @@ -68,7 +69,8 @@ namespace clover { public: class argument { public: - argument(); + static std::unique_ptr + 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; }; -- cgit v1.2.3