From 3409d39fc9c01b1fb4886041625835f812b32b4d Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Fri, 23 Mar 2018 16:59:09 +1100 Subject: [PATCH] job/dispatch: add chunked image job queueing --- CMakeLists.txt | 1 + job/dispatch.hpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 job/dispatch.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cb48f133..253952e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,6 +277,7 @@ list ( io.hpp iterator.hpp job/fwd.hpp + job/dispatch.hpp job/queue.cpp job/queue.hpp json/fwd.hpp diff --git a/job/dispatch.hpp b/job/dispatch.hpp new file mode 100644 index 00000000..fc754608 --- /dev/null +++ b/job/dispatch.hpp @@ -0,0 +1,81 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2018 Danny Robson + */ + +#ifndef CRUFT_UTIL_JOB_DISPATCH_HPP +#define CRUFT_UTIL_JOB_DISPATCH_HPP + +#include "queue.hpp" + +#include "../extent.hpp" +#include "../region.hpp" + +#include + +namespace util::job { + // call a function across all elements of a container using the supplied + // job queue. + // + // threads will have work sizes dictated by a supplied extent. + // + // returns a cookie, or container of cookies, to wait on. + // + // TODO: extend to 1d and 3d + template < + typename ContainerT, + typename FunctionT, + typename ...Args, + size_t DimensionV + > + std::vector + dispatch ( + util::job::queue &q, + ContainerT &data, + util::extent chunk, + FunctionT &func, + Args ...args) + { + auto chunked_func = [&func] (ContainerT &inner_data, + auto param, + Args... inner_args) + { + for (auto p: param) { + if (!inner_data.extent ().exclusive (p)) + continue; + inner_data[p][0] = std::invoke (func, p.template cast (), inner_args...); + } + }; + + std::vector cookies; + + const extent2i count = (data.extent () + chunk - 1) / chunk; + + for (auto index: count.step ()) { + util::point base = index * chunk; + cookies.push_back ( + q.submit ( + chunked_func, + std::ref (data), + util::region {base, chunk}.step (), + args... + ) + ); + } + + return cookies; + } +} + +#endif