|  | 
| 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