root icon indicating copy to clipboard operation
root copied to clipboard

Support a blocked range in TExecutor?

Open hageboeck opened this issue 4 years ago • 1 comments

Is your feature request related to a problem? Please describe.

Not a problem, just ease of use when processing e.g. a large array with a lot of entries in parallel (with using SIMD in each thread).

Describe the solution you'd like

ROOT

void runParallel() {
  ROOT::Internal::TExecutor ex; 
  constexpr std::size_t nTotal = 101;

  const auto nChunk = ROOT::IsImplicitMTEnabled() ? ex.GetPoolSize() : 1u; 
  auto printRange = [=](std::size_t i) {
    const auto nEvent = nTotal / nChunk + (nTotal%nChunk != 0); 
    const auto begin = nEvent * i;
    const auto end = std::min( nEvent * (i+1), nTotal);

    std::cout << "[" << i << "] does " << begin << "\t" << end << std::endl; sleep(1);

    // We are forced to return a dummy value
    return 0;
  };  
  ex.Map(printRange, ROOT::TSeq<std::size_t>(0, nChunk));
}

TBB

void runParallel() {
  constexpr std::size_t nTotal = 101;

  auto printRange = [](const tbb::blocked_range<std::size_t>& range) {
    std::cout << "Doing " << range.begin() << "\t" << range.end() << std::endl; sleep(1);
  };  
  tbb::parallel_for(tbb::blocked_range<std::size_t>(0, nTotal), printRange, tbb::static_partitioner());
}

OMP

+ #pragma omp parallel for schedule(static)
  for (std::size_t i = 0; i < end; ++i) {

hageboeck avatar Apr 14 '21 13:04 hageboeck

I think a helper function MakeBlockedRange(start, end, nChunks) that returns e.g. a std::vector<std::vector<Idx>> or a std::vector<std::pair<Idx, Idx>> would do the job. With that you can write:

auto do = [] (auto &&range) { for (auto i : range) { something(); };
ex.Foreach(doThis, MakeBlockedRange(0, 1000, 10));

eguiraud avatar Apr 14 '21 13:04 eguiraud