|
5 | 5 | * logic, matrix algebra, and channel parameters. |
6 | 6 | * |
7 | 7 | * @author Tyson Jones |
| 8 | + * @author Luc Jaulmes (distributing ranges over blocks) |
8 | 9 | */ |
9 | 10 |
|
10 | 11 | #include "quest/include/types.h" |
|
25 | 26 |
|
26 | 27 | #include <functional> |
27 | 28 | #include <algorithm> |
| 29 | +#include <utility> |
28 | 30 | #include <complex> |
29 | 31 | #include <cmath> |
30 | 32 | #include <vector> |
@@ -930,6 +932,41 @@ util_VectorIndexRange util_getLocalIndRangeOfVectorElemsWithinNode(int rank, qin |
930 | 932 | return out; |
931 | 933 | } |
932 | 934 |
|
| 935 | +std::pair<qindex, qindex> util_getBlockMultipleSubRange( |
| 936 | + qindex rangeLen, qindex blockLen, int idSubRange, int numSubRanges |
| 937 | +) { |
| 938 | + // divides a range into whole blocks (and a single leftover sub-block) and |
| 939 | + // attempts to uniformly distribute the blocks across the specified number of |
| 940 | + // sub-ranges. When the blocks do not divide evenly between sub-ranges, the |
| 941 | + // leftover blocks are spread apart across sub-ranges. When the range does not |
| 942 | + // divide evenly into blocks, the overflow is given to the final sub-range. |
| 943 | + |
| 944 | + qindex numFullBlocks = rangeLen / blockLen; // floors |
| 945 | + qindex subBlockLen = rangeLen % blockLen; |
| 946 | + |
| 947 | + qindex baseNumBlocksPerSubRange = numFullBlocks / numSubRanges; |
| 948 | + qindex numExtraBlocks = numFullBlocks % numSubRanges; |
| 949 | + |
| 950 | + // determine how many extra blocks this subrange should contain |
| 951 | + qindex prevExtra = (idSubRange * numExtraBlocks) / numSubRanges; |
| 952 | + qindex prevShift = (idSubRange * numExtraBlocks) % numSubRanges; |
| 953 | + bool hereExtra = (prevShift + numExtraBlocks) >= numSubRanges; |
| 954 | + |
| 955 | + // allocate blocks to this sub-range |
| 956 | + qindex startBlockInd = idSubRange * baseNumBlocksPerSubRange + prevExtra; |
| 957 | + qindex endBlockInd = startBlockInd + baseNumBlocksPerSubRange + hereExtra; |
| 958 | + |
| 959 | + // find this sub-range indices within [0, rangeLen) |
| 960 | + qindex startInd = startBlockInd * blockLen; |
| 961 | + qindex endInd = endBlockInd * blockLen; // exclusive |
| 962 | + |
| 963 | + // arbitrarily allocate the leftover sub-block to the final sub-range |
| 964 | + if (idSubRange == numSubRanges - 1) |
| 965 | + endInd += subBlockLen; |
| 966 | + |
| 967 | + return std::make_pair(startInd, endInd); |
| 968 | +} |
| 969 | + |
933 | 970 |
|
934 | 971 |
|
935 | 972 | /* |
|
0 commit comments