10 subInterval.
Copy(inInterval);
11 int numDim = inInterval.size();
13 std::vector<int> iStart(numDim,0);
14 std::vector<int> iEnd(numDim,0);
18 for(
int iDim = 0;iDim < numDim;iDim++){
19 inStream >> iStart[iDim] >> iEnd[iDim];
20 if(iStart[iDim] == 0 || iEnd[iDim] == 0)
23 int direction = ibDir;
26 direction = -1*direction;
29 direction = direction - 1;
31 subInterval[direction].first = iStart[direction]-1;
32 subInterval[direction].second = iEnd[direction]-1;
34 int startIndex = iStart[direction];
35 int endIndex = iEnd[direction];
36 if(iStart[direction] < 0)
38 if(iEnd[direction] < 0)
42 subInterval[direction].first -= startIndex;
43 subInterval[direction].second -= endIndex;
45 for(
int iDim = 0;iDim < numDim;iDim++){
46 if(iDim != direction){
47 int startIndex = iStart[iDim];
48 int endIndex = iEnd[iDim];
52 subInterval[iDim].first = inInterval[iDim].second - startIndex;
55 subInterval[iDim].first = inInterval[iDim].first + startIndex;
60 subInterval[iDim].second = inInterval[iDim].second - endIndex;
63 subInterval[iDim].second = inInterval[iDim].first + endIndex;
69 if(overlapInterval != subInterval)
74 std::vector<pcpp::IndexIntervalType>
75 UniqueUnion(
const std::vector<pcpp::IndexIntervalType> &intervalSet)
77 std::vector<pcpp::IndexIntervalType> uniqueUnion(intervalSet);
78 int numIntervals = intervalSet.size();
81 for(
int iSet = 0;iSet < numIntervals-1;iSet++){
83 for(
int iCompare = iSet+1;iCompare < numIntervals;iSet++){
85 if(compareInterval.NNodes() > 0){
97 outInterval = inInterval;
100 outInterval[0] = outInterval[2];
102 outInterval[1].first = 0;
103 outInterval[1].second = 0;
104 outInterval[2] = outInterval[1];
106 outInterval[0] = outInterval[1];
108 outInterval[1] = outInterval[2];
110 outInterval[2].first = 0;
111 outInterval[2].second = 0;
114 }
else if (ySize == 1){
116 outInterval[1].first = 0;
117 outInterval[1].second = 0;
118 outInterval[2] = outInterval[1];
120 outInterval[1] = outInterval[2];
121 outInterval[2].first = 0;
122 outInterval[2].second = 0;
126 }
else if (zSize == 1){
127 outInterval[2].first = 0;
128 outInterval[2].second = 0;
134 std::deque<size_t> primeFactors;
136 while(baseFac*baseFac <= inNumber){
137 if(inNumber%baseFac == 0){
138 primeFactors.push_back(baseFac);
145 primeFactors.push_back(inNumber);
146 return(primeFactors);
152 std::vector<bool> partDirection,
153 int partID,
int numPart,
155 std::vector<int> &numPartitions)
159 outInterval = inInterval;
163 outInterval.resize(0);
165 if(partID < 0 || numPart < 1){
166 std::cout <<
"numpart prob" << std::endl;
170 int numDim = inInterval.size();
173 std::cout <<
"numdim prob" << std::endl;
177 if(partDirection.empty()){
178 partDirection.resize(numDim,
true);
179 }
else if (partDirection.size() != numDim){
180 std::cout <<
"partdir prob" << std::endl;
184 size_t maxTotalPossibleParts = 1;
185 std::vector<int> candidateDims;
186 std::vector<size_t> candidateSize;
187 numPartitions.resize(numDim,0);
190 for(
int iDim = 0;iDim < numDim;iDim++){
191 if(partDirection[iDim]){
192 size_t mySize = inInterval[iDim].second - inInterval[iDim].first + 1;
193 candidateDims.push_back(iDim);
194 candidateSize.push_back(mySize);
195 maxTotalPossibleParts *= mySize;
197 numPartitions[iDim] = 1;
201 if(numPart > maxTotalPossibleParts){
202 std::cout <<
"maxpart" << std::endl;
206 int partDims = candidateDims.size();
207 outInterval = inInterval;
211 int numFac = primeFactors.size();
215 if(numFac == 1 && primeFactors.front() == 1)
222 while(numFac > partDims){
223 primeFactors[1] *= primeFactors.front();
224 primeFactors.pop_front();
225 std::sort(primeFactors.begin(),primeFactors.end());
231 while(!primeFactors.empty()){
232 int dimPart = primeFactors.back();
233 primeFactors.pop_back();
235 if(!primeFactors.empty()){
236 std::deque<size_t>::iterator facIt = primeFactors.begin();
237 while(facIt != primeFactors.end())
238 dimPlane *= *facIt++;
243 for(
int iCand = 0;iCand < partDims;iCand++){
244 if((candidateSize[iCand] >= maxSize) && (numPartitions[candidateDims[iCand]] == 0)){
245 maxDim = candidateDims[iCand];
246 maxSize = candidateSize[iCand];
249 if(maxSize == 0 || maxDim < 0){
250 std::cout <<
"maxsize = " << maxSize <<
"maxDim = " << maxDim << std::endl;
254 numPartitions[maxDim] = dimPart;
255 size_t iStart = outInterval[maxDim].first;
256 size_t iEnd = outInterval[maxDim].second;
257 size_t partRank = (partID/dimPlane)%dimPart;
258 Part1D(iStart,iEnd,dimPart,partRank,outInterval[maxDim].first,
259 outInterval[maxDim].second);
283 int Part1D(
const size_t iStart,
const size_t iEnd,
const size_t numPart,
const size_t partIndex,
284 size_t &partStart,
size_t &partEnd)
286 size_t intervalSize = iEnd - iStart + 1;
287 size_t partSize = intervalSize/numPart;
290 size_t leftOver = intervalSize%numPart;
291 if(partIndex < leftOver)
293 size_t intervalStart = partIndex*partSize;
294 if(partIndex >= leftOver)
295 intervalStart += leftOver;
296 partStart = intervalStart + iStart;
297 partEnd = partStart + partSize - 1;
318 const std::vector<int> &cartDims,
319 const std::vector<int> &cartCoords,
321 std::ostream &messageStream)
324 if(globalExtent.empty()){
325 messageStream <<
"PartitionCartesianExtent:Error: Global extent empty." 329 int numDim = cartDims.size();
330 if(globalExtent.
ND() < numDim){
331 messageStream <<
"PartitionCartesianExtent:Error: Global extent dimension deficient, " 332 << globalExtent.
ND() <<
" < " << numDim <<
"." << std::endl;
335 std::vector<size_t> localStart(numDim,0);
336 std::vector<size_t> localSize(numDim,0);
337 for(
int iDim = 0;iDim < numDim;iDim++){
338 size_t numPart = cartDims[iDim];
339 size_t intervalStart = globalExtent[iDim].first;
340 size_t intervalEnd = globalExtent[iDim].second;
341 size_t partStart = 0;
343 size_t partIndex = cartCoords[iDim];
344 if(
Part1D(intervalStart,intervalEnd,numPart,partIndex,partStart,partEnd)){
345 messageStream <<
"PartitionCartesianExtent:Error: Global extent of insufficient size for number of partitions." 349 localSize[iDim] = partEnd - partStart + 1;
350 localStart[iDim] = partStart;
352 partExtent.
Init(localStart,localSize);
373 const std::vector<int> &cartDims,
374 const std::vector<int> &cartCoords,
376 std::ostream &messageStream)
379 if(globalInterval.empty()){
380 messageStream <<
"PartitionCartesianInterval:Error: Global interval empty." 384 int numDim = cartDims.size();
385 if(globalInterval.
ND() < numDim){
386 messageStream <<
"PartitionCartesianInterval:Error: Global interval dimension deficient, " 387 << globalInterval.
ND() <<
" < " << numDim <<
"." << std::endl;
390 std::vector<size_t> localStart(numDim,0);
391 std::vector<size_t> localSize(numDim,0);
392 for(
int iDim = 0;iDim < numDim;iDim++){
393 size_t numPart = cartDims[iDim];
394 size_t intervalStart = globalInterval[iDim].first;
395 size_t intervalEnd = globalInterval[iDim].second;
396 size_t partStart = 0;
398 size_t partIndex = cartCoords[iDim];
399 if(
Part1D(intervalStart,intervalEnd,numPart,partIndex,partStart,partEnd)){
400 messageStream <<
"PartitionCartesianInterval:Error: Global interval of insufficient size for number of partitions." 404 localSize[iDim] = partEnd - partStart + 1;
405 localStart[iDim] = partStart;
407 partInterval.
Init(localStart,localSize);
std::vector< pcpp::IndexIntervalType > UniqueUnion(const std::vector< pcpp::IndexIntervalType > &intervalSet)
int SimplePartitionInterval(const pcpp::IndexIntervalType &inInterval, std::vector< bool > partDirection, int partID, int numPart, pcpp::IndexIntervalType &outInterval, std::vector< int > &numPartitions)
Multi-dimensional interval partitioning (non-MPI)
std::deque< size_t > PrimeFactors(size_t inNumber)
int Part1D(const size_t iStart, const size_t iEnd, const size_t numPart, const size_t partIndex, size_t &partStart, size_t &partEnd)
Extract a sub-interval of a 1-dimensional integer interval.
int SubIntervalFromStream(std::istream &inStream, const pcpp::IndexIntervalType &inInterval, pcpp::IndexIntervalType &subInterval)
void Copy(const sizeextent &inExtent)
void Overlap(const sizeextent &inextent, sizeextent &outextent) const
int PartitionCartesianExtent(const pcpp::IndexIntervalType &globalExtent, const std::vector< int > &cartDims, const std::vector< int > &cartCoords, pcpp::IndexIntervalType &partExtent, std::ostream &messageStream)
Get local sub-interval of an n-dimensional integer interval.
void Init(const ContainerType &inflatextent)
int PartitionCartesianInterval(const pcpp::IndexIntervalType &globalExtent, const std::vector< int > &cartDims, const std::vector< int > &cartCoords, pcpp::IndexIntervalType &partExtent, std::ostream &messageStream)
Get local sub-interval of an n-dimensional integer interval.
void CollapseInterval(size_t &xSize, size_t &ySize, size_t &zSize, const pcpp::IndexIntervalType &inInterval, pcpp::IndexIntervalType &outInterval)
Simple Block Structured Mesh object.