@@ -29,29 +29,23 @@ OneDimensionalBlockSlicer::OneDimensionalBlockSlicer(Extent::value_type dim)
2929 : m_dim{dim}
3030{}
3131
32- std::pair<Offset, Extent>
33- OneDimensionalBlockSlicer::sliceBlock (Extent &totalExtent, int size, int rank)
32+ std::pair<size_t , size_t > OneDimensionalBlockSlicer::n_th_block_inside (
33+ size_t length, size_t rank, size_t size )
3434{
35- Offset offs (totalExtent.size (), 0 );
36-
3735 if (rank >= size)
3836 {
39- Extent extent (totalExtent.size (), 0 );
40- return std::make_pair (std::move (offs), std::move (extent));
37+ return {length, 0 };
4138 }
4239
43- auto dim = this ->m_dim ;
44-
4540 // for more equal balancing, we want the start index
4641 // at the upper gaussian bracket of (N/n*rank)
4742 // where N the size of the dataset in dimension dim
4843 // and n the MPI size
4944 // for avoiding integer overflow, this is the same as:
5045 // (N div n)*rank + round((N%n)/n*rank)
51- auto f = [&totalExtent, size, dim](int threadRank) {
52- auto N = totalExtent[dim];
53- auto res = (N / size) * threadRank;
54- auto padDivident = (N % size) * threadRank;
46+ auto f = [length, size](size_t rank_lambda) {
47+ auto res = (length / size) * rank_lambda;
48+ auto padDivident = (length % size) * rank_lambda;
5549 auto pad = padDivident / size;
5650 if (pad * size < padDivident)
5751 {
@@ -60,17 +54,31 @@ OneDimensionalBlockSlicer::sliceBlock(Extent &totalExtent, int size, int rank)
6054 return res + pad;
6155 };
6256
63- offs[dim] = f (rank);
57+ size_t offset = f (rank);
58+ size_t extent = [&]() {
59+ if (rank >= size - 1 )
60+ {
61+ return length - offset;
62+ }
63+ else
64+ {
65+ return f (rank + 1 ) - offset;
66+ }
67+ }();
68+ return {offset, extent};
69+ }
70+
71+ std::pair<Offset, Extent>
72+ OneDimensionalBlockSlicer::sliceBlock (Extent &totalExtent, int size, int rank)
73+ {
74+ Offset localOffset (totalExtent.size (), 0 );
6475 Extent localExtent{totalExtent};
65- if (rank >= size - 1 )
66- {
67- localExtent[dim] -= offs[dim];
68- }
69- else
70- {
71- localExtent[dim] = f (rank + 1 ) - offs[dim];
72- }
73- return std::make_pair (std::move (offs), std::move (localExtent));
76+
77+ auto [offset_dim, extent_dim] =
78+ n_th_block_inside (totalExtent.at (this ->m_dim ), rank, size);
79+ localOffset[m_dim] = offset_dim;
80+ localExtent[m_dim] = extent_dim;
81+ return std::make_pair (std::move (localOffset), std::move (localExtent));
7482}
7583
7684std::unique_ptr<BlockSlicer> OneDimensionalBlockSlicer::clone () const
0 commit comments