diff options
author | Francisco Jerez <[email protected]> | 2014-10-08 17:39:35 +0300 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2014-10-12 01:44:19 +0300 |
commit | bf89a97748748592639087e8167e29c98c740d33 (patch) | |
tree | 33ee8134467f84c62234422d8455e3309014fb61 /src/gallium/state_trackers/clover | |
parent | 06139c56fa070f84a931a4ddbdb894c9e8d24f55 (diff) |
clover: Pass execution dimensions and offset to the kernel as implicit arguments.
Reviewed-by: Jan Vesely <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/clover')
-rw-r--r-- | src/gallium/state_trackers/clover/core/kernel.cpp | 87 | ||||
-rw-r--r-- | src/gallium/state_trackers/clover/core/kernel.hpp | 8 |
2 files changed, 70 insertions, 25 deletions
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<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) { } 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<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; }; |