/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * 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 cruft::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 that will block at destruction until all jobs have /// completed. it will take ownership of an forwarding-reference function /// if one is supplied. /// /// TODO: extend to 1d and 3d template < typename ContainerT, typename FunctionT, typename ...Args, size_t DimensionV > auto dispatch ( cruft::job::queue &q, ContainerT &data, cruft::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] = std::invoke (func, p, inner_args...); } }; std::vector cookies; const extent2i count = (data.extent () + chunk - 1) / chunk; for (auto index: count.step ()) { cruft::point base = index * chunk; cookies.push_back ( q.submit ( chunked_func, std::ref (data), cruft::region {base, chunk}.step (), args... ) ); } return std::tuple (std::forward (func), std::move (cookies)); } } #endif