#pragma once #include "launch.hpp" namespace tf { // Function: make_for_each_task template auto make_for_each_task(B b, E e, C c, P part = P()) { using B_t = std::decay_t>; using E_t = std::decay_t>; return [=] (Runtime& rt) mutable { // fetch the stateful values B_t beg = b; E_t end = e; size_t W = rt.executor().num_workers(); size_t N = std::distance(beg, end); // only myself - no need to spawn another graph if(W <= 1 || N <= part.chunk_size()) { launch_loop(part, [&](){ std::for_each(beg, end, c); }); return; } if(N < W) { W = N; } // static partitioner if constexpr(part.type() == PartitionerType::STATIC) { size_t chunk_size; for(size_t w=0, curr_b=0; w next(0); launch_loop(N, W, rt, next, part, [=, &c, &next, &part] () mutable { part.loop(N, W, next, [&, prev_e=size_t{0}](size_t part_b, size_t part_e) mutable { std::advance(beg, part_b - prev_e); for(size_t x = part_b; x auto make_for_each_index_task(B b, E e, S s, C c, P part = P()){ using B_t = std::decay_t>; using E_t = std::decay_t>; using S_t = std::decay_t>; return [=] (Runtime& rt) mutable { // fetch the iterator values B_t beg = b; E_t end = e; S_t inc = s; // nothing to be done if the range is invalid if(is_range_invalid(beg, end, inc)) { return; } size_t W = rt.executor().num_workers(); size_t N = distance(beg, end, inc); // only myself - no need to spawn another graph if(W <= 1 || N <= part.chunk_size()) { launch_loop(part, [&](){ for(size_t x=0; x(part_b) * inc + beg; for(size_t x=part_b; x next(0); launch_loop(N, W, rt, next, part, [=, &c, &next, &part] () mutable { part.loop(N, W, next, [&](size_t part_b, size_t part_e) { auto idx = static_cast(part_b) * inc + beg; for(size_t x=part_b; x Task FlowBuilder::for_each(B beg, E end, C c, P part) { return emplace( make_for_each_task(beg, end, c, part) ); //return Task(_graph._emplace_back("", 0, nullptr, nullptr, 0, // std::in_place_type_t{}, std::forward(c) //)); } // ---------------------------------------------------------------------------- // for_each_index // ---------------------------------------------------------------------------- // Function: for_each_index template Task FlowBuilder::for_each_index(B beg, E end, S inc, C c, P part){ return emplace( make_for_each_index_task(beg, end, inc, c, part) ); } } // end of namespace tf -----------------------------------------------------