45 #ifndef GEOMETRICGENERATOR 46 #define GEOMETRICGENERATOR 48 #include <Teuchos_Comm.hpp> 49 #include <Teuchos_ParameterList.hpp> 50 #include <Teuchos_FilteredIterator.hpp> 51 #include <Teuchos_ParameterEntry.hpp> 60 #include <Tpetra_MultiVector_decl.hpp> 63 #include <Teuchos_ArrayViewDecl.hpp> 64 #include <Teuchos_RCP.hpp> 65 #include <Tpetra_Distributor.hpp> 70 #ifdef HAVE_ZOLTAN2_ZOLTAN 79 using Teuchos::CommandLineProcessor;
80 using Teuchos::ArrayView;
82 using Teuchos::ArrayRCP;
85 #define CATCH_EXCEPTIONS(pp) \ 86 catch (std::runtime_error &e) { \ 87 cout << "Runtime exception returned from " << pp << ": " \ 88 << e.what() << " FAIL" << endl; \ 91 catch (std::logic_error &e) { \ 92 cout << "Logic exception returned from " << pp << ": " \ 93 << e.what() << " FAIL" << endl; \ 96 catch (std::bad_alloc &e) { \ 97 cout << "Bad_alloc exception returned from " << pp << ": " \ 98 << e.what() << " FAIL" << endl; \ 101 catch (std::exception &e) { \ 102 cout << "Unknown exception returned from " << pp << ": " \ 103 << e.what() << " FAIL" << endl; \ 110 #ifdef HAVE_ZOLTAN2_ZOLTAN 113 template <
typename tMVector_t>
116 std::vector<std::vector<float> > weights;
120 template <
typename tMVector_t>
121 int getNumObj(
void *data,
int *ierr)
124 DOTS<tMVector_t> *dots_ = (DOTS<tMVector_t> *) data;
125 return dots_->coordinates->getLocalLength();
128 template <
typename tMVector_t>
129 void getCoords(
void *data,
int numGid,
int numLid,
130 int numObj, ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids,
131 int dim,
double *coords_,
int *ierr)
133 typedef typename tMVector_t::scalar_type scalar_t;
138 DOTS<tMVector_t> *dots_ = (DOTS<tMVector_t> *) data;
139 double *val = coords_;
140 const scalar_t *x = dots_->coordinates->getData(0).getRawPtr();
141 const scalar_t *y = dots_->coordinates->getData(1).getRawPtr();
142 const scalar_t *z = dots_->coordinates->getData(2).getRawPtr();
143 for (
int i=0; i < numObj; i++){
144 *val++ =
static_cast<double>(x[i]);
145 *val++ =
static_cast<double>(y[i]);
146 *val++ =
static_cast<double>(z[i]);
151 DOTS<tMVector_t> *dots_ = (DOTS<tMVector_t> *) data;
152 double *val = coords_;
153 const scalar_t *x = dots_->coordinates->getData(0).getRawPtr();
154 const scalar_t *y = dots_->coordinates->getData(1).getRawPtr();
155 for (
int i=0; i < numObj; i++){
156 *val++ =
static_cast<double>(x[i]);
157 *val++ =
static_cast<double>(y[i]);
162 template <
typename tMVector_t>
163 int getDim(
void *data,
int *ierr)
166 DOTS<tMVector_t> *dots_ = (DOTS<tMVector_t> *) data;
167 int dim = dots_->coordinates->getNumVectors();
173 template <
typename tMVector_t>
174 void getObjList(
void *data,
int numGid,
int numLid,
175 ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids,
176 int num_wgts,
float *obj_wgts,
int *ierr)
178 typedef typename tMVector_t::global_ordinal_type gno_t;
181 DOTS<tMVector_t> *dots_ = (DOTS<tMVector_t> *) data;
183 size_t localLen = dots_->coordinates->getLocalLength();
185 dots_->coordinates->getMap()->getNodeElementList().getRawPtr();
187 if (
sizeof(ZOLTAN_ID_TYPE) ==
sizeof(gno_t))
188 memcpy(gids, ids,
sizeof(ZOLTAN_ID_TYPE) * localLen);
190 for (
size_t i=0; i < localLen; i++)
191 gids[i] = static_cast<ZOLTAN_ID_TYPE>(ids[i]);
194 float *wgts = obj_wgts;
195 for (
size_t i=0; i < localLen; i++)
196 for (
int w=0; w < num_wgts; w++)
197 *wgts++ = dots_->weights[w][i];
204 const std::string
shapes[] = {
"SQUARE",
"RECTANGLE",
"CIRCLE",
"CUBE",
"RECTANGULAR_PRISM",
"SPHERE"};
205 #define SHAPE_COUNT 6 209 #define DISTRIBUTION_COUNT 2 211 #define HOLE_ALLOC_STEP 10 212 #define MAX_WEIGHT_DIM 10 213 #define INVALID(STR) "Invalid argument at " + STR 214 #define INVALIDSHAPE(STR, DIM) "Invalid shape name " + STR + " for " + DIM + ".\nValid shapes are \"SQUARE\", \"RECTANGLE\", \"CIRCLE\" for 2D, and \"CUBE\", \"RECTANGULAR_PRISM\", \"SPHERE\" for 3D" 216 #define INVALID_SHAPE_ARG(SHAPE, REQUIRED) "Invalid argument count for shape " + SHAPE + ". Requires " + REQUIRED + " argument(s)." 217 #define MAX_ITER_ALLOWED 500 221 template <
typename T>
254 template <
typename T>
260 this->center.
x = center_.
x;
261 this->center.
y = center_.
y;
262 this->center.
z = center_.
z;
263 this->edge1 = edge1_;
264 this->edge2 = edge2_;
265 this->edge3 = edge3_;
271 template <
typename T>
277 return fabs(dot.
x - this->center.x) < this->edge1 / 2 && fabs(dot.
y - this->center.y) < this->edge1 / 2;
281 template <
typename T>
286 return fabs(dot.
x - this->center.x) < this->edge1 / 2 && fabs(dot.
y - this->center.y) < this->edge2 / 2;
291 template <
typename T>
297 return (dot.
x - this->center.x)*(dot.
x - this->center.x) + (dot.
y - this->center.y) * (dot.
y - this->center.y) < this->edge1 * this->edge1;
301 template <
typename T>
307 return fabs(dot.
x - this->center.x) < this->edge1 / 2 && fabs(dot.
y - this->center.y) < this->edge1 / 2 && fabs(dot.
z - this->center.z) < this->edge1 / 2;
311 template <
typename T>
317 return fabs(dot.
x - this->center.x) < this->edge1 / 2 && fabs(dot.
y - this->center.y) < this->edge2 / 2 && fabs(dot.
z - this->center.z) < this->edge3 / 2;
321 template <
typename T>
327 return fabs((dot.
x - this->center.x) * (dot.
x - this->center.x) * (dot.
x - this->center.x)) +
328 fabs((dot.
y - this->center.y) * (dot.
y - this->center.y) * (dot.
y - this->center.y)) +
329 fabs((dot.
z - this->center.z) * (dot.
z - this->center.z) * (dot.
z - this->center.z))
331 this->edge1 * this->edge1 * this->edge1;
335 template <
typename T,
typename weighttype>
339 virtual weighttype get1DWeight(T x)=0;
340 virtual weighttype get2DWeight(T x, T y)=0;
341 virtual weighttype get3DWeight(T x, T y, T z)=0;
364 template <
typename T,
typename weighttype>
375 SteppedEquation(T a1_, T a2_, T a3_, T b1_, T b2_, T b3_, T c_, T x1_, T y1_, T z1_, T *steps_, T *values_,
int stepCount_):
WeightDistribution<T,weighttype>(){
388 this->stepCount = stepCount_;
389 if(this->stepCount > 0){
390 this->steps =
new T[this->stepCount];
391 this->values =
new T[this->stepCount + 1];
393 for (
int i = 0; i < this->stepCount; ++i){
394 this->steps[i] = steps_[i];
395 this->values[i] = values_[i];
397 this->values[this->stepCount] = values_[this->stepCount];
403 if(this->stepCount > 0){
404 delete [] this->steps;
405 delete [] this->values;
411 T expressionRes = this->a1 * pow( (x - this->x1), b1) + c;
412 if(this->stepCount > 0){
413 for (
int i = 0; i < this->stepCount; ++i){
414 if (expressionRes < this->steps[i])
return this->values[i];
416 return this->values[this->stepCount];
419 return weighttype(expressionRes);
424 T expressionRes = this->a1 * pow( (x - this->x1), b1) + this->a2 * pow( (y - this->y1), b2) + c;
425 if(this->stepCount > 0){
426 for (
int i = 0; i < this->stepCount; ++i){
427 if (expressionRes < this->steps[i])
return this->values[i];
429 return this->values[this->stepCount];
432 return weighttype(expressionRes);
437 cout << this->a1 <<
"*" <<
"math.pow( (" << x <<
"- " << this->x1 <<
" ), " << b1 <<
")" <<
"+" << this->a2<<
"*"<<
"math.pow( (" << y <<
"-" << this->y1 <<
"), " <<
438 b2 <<
" ) + " << this->a3 <<
" * math.pow( (" << z <<
"-" << this->z1 <<
"), " << b3 <<
")+ " << c <<
" == " <<
439 this->a1 * pow( (x - this->x1), b1) + this->a2 * pow( (y - this->y1), b2) + this->a3 * pow( (z - this->z1), b3) + c << endl;
444 T expressionRes = this->a1 * pow( (x - this->x1), b1) + this->a2 * pow( (y - this->y1), b2) + this->a3 * pow( (z - this->z1), b3) + this->c;
447 if(this->stepCount > 0){
448 for (
int i = 0; i < this->stepCount; ++i){
449 if (expressionRes < this->steps[i]) {
451 return this->values[i];
456 return this->values[this->stepCount];
459 return weighttype(expressionRes);
464 T expressionRes = this->a1 * pow( (p.
x - this->x1), b1) + this->a2 * pow( (p.
y - this->y1), b2) + this->a3 * pow( (p.
z - this->z1), b3);
465 if(this->stepCount > 0){
466 for (
int i = 0; i < this->stepCount; ++i){
467 if (expressionRes < this->steps[i])
return this->values[i];
469 return this->values[this->stepCount];
472 return weighttype(expressionRes);
477 template <
typename T,
typename lno_t,
typename gno_t>
488 numPoints(np_), dimension(dim), requested(0), assignedPrevious(0),
492 virtual T getXCenter() = 0;
493 virtual T getXRadius() =0;
496 Hole<T> **holes, lno_t holeCount,
497 float *sharedRatios_,
int myRank){
499 for (
int i = 0; i < myRank; ++i){
501 this->assignedPrevious += lno_t(sharedRatios_[i] * this->numPoints);
502 if (i < this->numPoints % this->worldSize){
503 this->assignedPrevious += 1;
507 this->requested = requestedPointcount;
509 unsigned int slice = UINT_MAX/(this->worldSize);
510 unsigned int stateBegin = myRank * slice;
515 #ifdef HAVE_ZOLTAN2_OMP 521 #ifdef HAVE_ZOLTAN2_OMP 522 me = omp_get_thread_num();
523 tsize = omp_get_num_threads();
525 unsigned int state = stateBegin + me * slice/(tsize);
527 #ifdef HAVE_ZOLTAN2_OMP 530 for(lno_t cnt = 0; cnt < requestedPointcount; ++cnt){
534 throw "Max number of Iteration is reached for point creation. Check the area criteria or hole coordinates.";
538 bool isInHole =
false;
539 for(lno_t i = 0; i < holeCount; ++i){
540 if(holes[i][0].isInArea(p)){
545 if(isInHole)
continue;
584 void GetPoints(lno_t requestedPointcount, T **coords, lno_t tindex,
585 Hole<T> **holes, lno_t holeCount,
586 float *sharedRatios_,
int myRank){
588 for (
int i = 0; i < myRank; ++i){
590 this->assignedPrevious += lno_t(sharedRatios_[i] * this->numPoints);
591 if (gno_t(i) < this->numPoints % this->worldSize){
592 this->assignedPrevious += 1;
596 this->requested = requestedPointcount;
598 unsigned int slice = UINT_MAX/(this->worldSize);
599 unsigned int stateBegin = myRank * slice;
600 #ifdef HAVE_ZOLTAN2_OMP 606 #ifdef HAVE_ZOLTAN2_OMP 607 me = omp_get_thread_num();
608 tsize = omp_get_num_threads();
610 unsigned int state = stateBegin + me * (slice/(tsize));
618 #ifdef HAVE_ZOLTAN2_OMP 621 for(lno_t cnt = 0; cnt < requestedPointcount; ++cnt){
625 throw "Max number of Iteration is reached for point creation. Check the area criteria or hole coordinates.";
629 bool isInHole =
false;
630 for(lno_t i = 0; i < holeCount; ++i){
631 if(holes[i][0].isInArea(p)){
636 if(isInHole)
continue;
637 coords[0][cnt + tindex] = p.
x;
638 if(this->dimension > 1){
639 coords[1][cnt + tindex] = p.
y;
640 if(this->dimension > 2){
641 coords[2][cnt + tindex] = p.
z;
651 template <
typename T,
typename lno_t,
typename gno_t>
668 T sd_x, T sd_y, T sd_z,
int wSize) :
670 standartDevx(sd_x), standartDevy(sd_y), standartDevz(sd_z)
672 this->center.
x = center_.
x;
673 this->center.
y = center_.
y;
674 this->center.
z = center_.
z;
682 for(
int i = 0; i < this->dimension; ++i){
685 p.
x = normalDist(this->center.
x, this->standartDevx, state);
688 p.
y = normalDist(this->center.
y, this->standartDevy, state);
691 p.
z = normalDist(this->center.
z, this->standartDevz, state);
694 throw "unsupported dimension";
702 T normalDist(T center_, T sd,
unsigned int &state) {
703 static bool derived=
false;
704 static T storedDerivation;
705 T polarsqrt, normalsquared, normal1, normal2;
708 normal1=2.0*( T(rand_r(&state))/T(RAND_MAX) ) - 1.0;
709 normal2=2.0*( T(rand_r(&state))/T(RAND_MAX) ) - 1.0;
710 normalsquared=normal1*normal1+normal2*normal2;
711 }
while ( normalsquared>=1.0 || normalsquared == 0.0);
713 polarsqrt=sqrt(-2.0*log(normalsquared)/normalsquared);
714 storedDerivation=normal1*polarsqrt;
716 return normal2*polarsqrt*sd + center_;
720 return storedDerivation*sd + center_;
725 template <
typename T,
typename lno_t,
typename gno_t>
737 return (rightMostx - leftMostx)/2 + leftMostx;
740 return (rightMostx - leftMostx)/2;
745 T l_z, T r_z,
int wSize ) :
747 leftMostx(l_x), rightMostx(r_x), leftMosty(l_y), rightMosty(r_y),
748 leftMostz(l_z), rightMostz(r_z){}
756 for(
int i = 0; i < this->dimension; ++i){
759 p.
x = uniformDist(this->leftMostx, this->rightMostx, state);
762 p.
y = uniformDist(this->leftMosty, this->rightMosty, state);
765 p.
z = uniformDist(this->leftMostz, this->rightMostz, state);
768 throw "unsupported dimension";
776 T uniformDist(T a, T b,
unsigned int &state)
778 return (b-a)*(rand_r(&state) / double(RAND_MAX)) + a;
782 template <
typename T,
typename lno_t,
typename gno_t>
799 return (rightMostx - leftMostx)/2 + leftMostx;
802 return (rightMostx - leftMostx)/2;
807 T l_x, T r_x, T l_y, T r_y, T l_z, T r_z ,
808 int myRank_,
int wSize) :
810 leftMostx(l_x), rightMostx(r_x), leftMosty(l_y), rightMosty(r_y), leftMostz(l_z), rightMostz(r_z), myRank(myRank_){
812 this->processCnt = 0;
813 this->along_X = alongX; this->along_Y = alongY; this->along_Z = alongZ;
815 if(this->along_X > 1)
816 this->xstep = (rightMostx - leftMostx) / (alongX - 1);
819 if(this->along_Y > 1)
820 this->ystep = (rightMosty - leftMosty) / (alongY - 1);
823 if(this->along_Z > 1)
824 this->zstep = (rightMostz - leftMostz) / (alongZ - 1);
827 xshift = 0; yshift = 0; zshift = 0;
842 this->zshift = pindex / (along_X * along_Y);
843 this->yshift = (pindex % (along_X * along_Y)) / along_X;
844 this->xshift = (pindex % (along_X * along_Y)) % along_X;
851 p.
x = xshift * this->xstep + leftMostx;
852 p.
y = yshift * this->ystep + leftMosty;
853 p.
z = zshift * this->zstep + leftMostz;
908 template <
typename scalar_t,
typename lno_t,
typename gno_t,
typename node_t>
913 int coordinate_dimension;
914 gno_t numGlobalCoords;
915 lno_t numLocalCoords;
916 float *loadDistributions;
918 bool distinctCoordSet;
920 int distributionCount;
925 int numWeightsPerCoord;
927 RCP<const Teuchos::Comm<int> > comm;
939 float perturbation_ratio;
941 typedef Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t>
tMVector_t;
942 typedef Tpetra::Map<lno_t, gno_t, node_t> tMap_t;
945 template <
typename tt>
946 tt getParamVal(
const Teuchos::ParameterEntry& pe,
const std::string ¶mname){
949 returnVal = Teuchos::getValue<tt>(pe);
957 int countChar (std::string inStr,
char cntChar){
959 for (
unsigned int i = 0; i < inStr.size(); ++i){
960 if (inStr[i] == cntChar) {
967 template <
typename tt>
969 std::stringstream ss (std::stringstream::in |std::stringstream::out);
971 std::string tmp =
"";
976 template <
typename tt>
977 tt fromString(std::string obj){
978 std::stringstream ss (std::stringstream::in | std::stringstream::out);
983 throw "Cannot convert string " + obj;
989 void splitString(std::string inStr,
char splitChar, std::string *outSplittedStr){
990 std::stringstream ss (std::stringstream::in | std::stringstream::out);
994 std::string tmp =
"";
995 std::getline(ss, tmp ,splitChar);
996 outSplittedStr[cnt++] = tmp;
1033 void getCoordinateDistributions(std::string coordinate_distributions){
1034 if(coordinate_distributions ==
""){
1035 throw "At least one distribution function must be provided to coordinate generator.";
1038 int argCnt = this->countChar(coordinate_distributions,
',') + 1;
1039 std::string *splittedStr =
new std::string[argCnt];
1040 splitString(coordinate_distributions,
',', splittedStr);
1042 for(
int i = 0; i < argCnt; ){
1045 std::string distName = splittedStr[i++];
1047 if(distName ==
"NORMAL"){
1049 if (this->coordinate_dimension == 3){
1052 if(i + reqArg > argCnt) {
1053 std::string tmp = toString<int>(reqArg);
1056 np_ = fromString<gno_t>(splittedStr[i++]);
1059 pp.
x = fromString<scalar_t>(splittedStr[i++]);
1060 pp.y = fromString<scalar_t>(splittedStr[i++]);
1062 if(this->coordinate_dimension == 3){
1063 pp.z = fromString<scalar_t>(splittedStr[i++]);
1066 scalar_t sd_x = fromString<scalar_t>(splittedStr[i++]);
1067 scalar_t sd_y = fromString<scalar_t>(splittedStr[i++]);
1069 if(this->coordinate_dimension == 3){
1070 sd_z = fromString<scalar_t>(splittedStr[i++]);
1074 }
else if(distName ==
"UNIFORM" ){
1076 if (this->coordinate_dimension == 3){
1079 if(i + reqArg > argCnt) {
1080 std::string tmp = toString<int>(reqArg);
1083 np_ = fromString<gno_t>(splittedStr[i++]);
1084 scalar_t l_x = fromString<scalar_t>(splittedStr[i++]);
1085 scalar_t r_x = fromString<scalar_t>(splittedStr[i++]);
1086 scalar_t l_y = fromString<scalar_t>(splittedStr[i++]);
1087 scalar_t r_y = fromString<scalar_t>(splittedStr[i++]);
1089 scalar_t l_z = 0, r_z = 0;
1091 if(this->coordinate_dimension == 3){
1092 l_z = fromString<scalar_t>(splittedStr[i++]);
1093 r_z = fromString<scalar_t>(splittedStr[i++]);
1096 this->coordinateDistributions[this->distributionCount++] =
new CoordinateUniformDistribution<scalar_t, lno_t,gno_t>( np_, this->coordinate_dimension, l_x, r_x, l_y, r_y, l_z, r_z, this->worldSize );
1097 }
else if (distName ==
"GRID"){
1099 if(this->coordinate_dimension == 3){
1102 if(i + reqArg > argCnt) {
1103 std::string tmp = toString<int>(reqArg);
1107 gno_t np_x = fromString<gno_t>(splittedStr[i++]);
1108 gno_t np_y = fromString<gno_t>(splittedStr[i++]);
1112 if(this->coordinate_dimension == 3){
1113 np_z = fromString<gno_t>(splittedStr[i++]);
1116 np_ = np_x * np_y * np_z;
1117 scalar_t l_x = fromString<scalar_t>(splittedStr[i++]);
1118 scalar_t r_x = fromString<scalar_t>(splittedStr[i++]);
1119 scalar_t l_y = fromString<scalar_t>(splittedStr[i++]);
1120 scalar_t r_y = fromString<scalar_t>(splittedStr[i++]);
1122 scalar_t l_z = 0, r_z = 0;
1124 if(this->coordinate_dimension == 3){
1125 l_z = fromString<scalar_t>(splittedStr[i++]);
1126 r_z = fromString<scalar_t>(splittedStr[i++]);
1129 if(np_x < 1 || np_z < 1 || np_y < 1 ){
1130 throw "Provide at least 1 point along each dimension for grid test.";
1134 (np_x, np_y,np_z, this->coordinate_dimension, l_x, r_x,l_y, r_y, l_z, r_z , this->myRank, this->worldSize);
1138 std::string tmp = toString<int>(this->coordinate_dimension);
1141 this->numGlobalCoords += (gno_t) np_;
1143 delete []splittedStr;
1146 void getProcLoadDistributions(std::string proc_load_distributions){
1148 this->loadDistributions =
new float[this->worldSize];
1149 if(proc_load_distributions ==
""){
1150 float r = 1.0 / this->worldSize;
1151 for(
int i = 0; i < this->worldSize; ++i){
1152 this->loadDistributions[i] = r;
1157 int argCnt = this->countChar(proc_load_distributions,
',') + 1;
1158 if(argCnt != this->worldSize) {
1159 throw "Invalid parameter count load distributions. Given " + toString<int>(argCnt) +
" processor size is " + toString<int>(this->worldSize);
1161 std::string *splittedStr =
new std::string[argCnt];
1162 splitString(proc_load_distributions,
',', splittedStr);
1163 for(
int i = 0; i < argCnt; ++i){
1164 this->loadDistributions[i] = fromString<float>(splittedStr[i]);
1166 delete []splittedStr;
1170 for(
int i = 0; i < this->worldSize; ++i){
1171 sum += this->loadDistributions[i];
1174 throw "Processor load ratios do not sum to 1.0.";
1180 void getHoles(std::string holeDescription){
1181 if(holeDescription ==
""){
1185 int argCnt = this->countChar(holeDescription,
',') + 1;
1186 std::string *splittedStr =
new std::string[argCnt];
1187 splitString(holeDescription,
',', splittedStr);
1189 for(
int i = 0; i < argCnt; ){
1192 std::string shapeName = splittedStr[i++];
1193 if(shapeName ==
"SQUARE" && this->coordinate_dimension == 2){
1194 if(i + 3 > argCnt) {
1198 pp.
x = fromString<scalar_t>(splittedStr[i++]);
1199 pp.
y = fromString<scalar_t>(splittedStr[i++]);
1200 scalar_t edge = fromString<scalar_t>(splittedStr[i++]);
1202 }
else if(shapeName ==
"RECTANGLE" && this->coordinate_dimension == 2){
1203 if(i + 4 > argCnt) {
1207 pp.
x = fromString<scalar_t>(splittedStr[i++]);
1208 pp.
y = fromString<scalar_t>(splittedStr[i++]);
1209 scalar_t edgex = fromString<scalar_t>(splittedStr[i++]);
1210 scalar_t edgey = fromString<scalar_t>(splittedStr[i++]);
1213 }
else if(shapeName ==
"CIRCLE" && this->coordinate_dimension == 2){
1214 if(i + 3 > argCnt) {
1218 pp.
x = fromString<scalar_t>(splittedStr[i++]);
1219 pp.
y = fromString<scalar_t>(splittedStr[i++]);
1220 scalar_t r = fromString<scalar_t>(splittedStr[i++]);
1222 }
else if(shapeName ==
"CUBE" && this->coordinate_dimension == 3){
1223 if(i + 4 > argCnt) {
1227 pp.
x = fromString<scalar_t>(splittedStr[i++]);
1228 pp.
y = fromString<scalar_t>(splittedStr[i++]);
1229 pp.
z = fromString<scalar_t>(splittedStr[i++]);
1230 scalar_t edge = fromString<scalar_t>(splittedStr[i++]);
1232 }
else if(shapeName ==
"RECTANGULAR_PRISM" && this->coordinate_dimension == 3){
1233 if(i + 6 > argCnt) {
1237 pp.
x = fromString<scalar_t>(splittedStr[i++]);
1238 pp.
y = fromString<scalar_t>(splittedStr[i++]);
1239 pp.
z = fromString<scalar_t>(splittedStr[i++]);
1240 scalar_t edgex = fromString<scalar_t>(splittedStr[i++]);
1241 scalar_t edgey = fromString<scalar_t>(splittedStr[i++]);
1242 scalar_t edgez = fromString<scalar_t>(splittedStr[i++]);
1245 }
else if(shapeName ==
"SPHERE" && this->coordinate_dimension == 3){
1246 if(i + 4 > argCnt) {
1250 pp.
x = fromString<scalar_t>(splittedStr[i++]);
1251 pp.
y = fromString<scalar_t>(splittedStr[i++]);
1252 pp.
z = fromString<scalar_t>(splittedStr[i++]);
1253 scalar_t r = fromString<scalar_t>(splittedStr[i++]);
1256 std::string tmp = toString<int>(this->coordinate_dimension);
1260 delete [] splittedStr;
1263 void getWeightDistribution(std::string *weight_distribution_arr,
int wdimension){
1268 std::string weight_distribution = weight_distribution_arr[ii];
1269 if(weight_distribution ==
"")
continue;
1270 if(wcount == wdimension) {
1271 throw "Weight Dimension is provided as " + toString<int>(wdimension) +
". More weight distribution is provided.";
1274 int count = this->countChar(weight_distribution,
' ');
1275 std::string *splittedStr =
new string[count + 1];
1276 this->splitString(weight_distribution,
' ', splittedStr);
1279 scalar_t a1=0,a2=0,a3=0;
1280 scalar_t x1=0,y1=0,z1=0;
1281 scalar_t b1=1,b2=1,b3=1;
1282 scalar_t *steps = NULL;
1283 scalar_t *values= NULL;
1287 for (
int i = 1; i < count + 1; ++i){
1288 int assignmentCount = this->countChar(splittedStr[i],
'=');
1289 if (assignmentCount != 1){
1290 throw "Error at the argument " + splittedStr[i];
1292 std::string parameter_vs_val[2];
1293 this->splitString(splittedStr[i],
'=', parameter_vs_val);
1294 std::string parameter = parameter_vs_val[0];
1295 std::string value = parameter_vs_val[1];
1298 if (parameter ==
"a1"){
1299 a1 = this->fromString<scalar_t>(value);
1301 else if (parameter ==
"a2"){
1302 if(this->coordinate_dimension > 1){
1303 a2 = this->fromString<scalar_t>(value);
1306 throw parameter+
" argument is not valid when dimension is " + toString<int>(this->coordinate_dimension);
1310 else if (parameter ==
"a3"){
1311 if(this->coordinate_dimension > 2){
1312 a3 = this->fromString<scalar_t>(value);
1315 throw parameter+
" argument is not valid when dimension is " + toString<int>(this->coordinate_dimension);
1318 else if (parameter ==
"b1"){
1319 b1 = this->fromString<scalar_t>(value);
1321 else if (parameter ==
"b2"){
1322 if(this->coordinate_dimension > 1){
1323 b2 = this->fromString<scalar_t>(value);
1326 throw parameter+
" argument is not valid when dimension is " + toString<int>(this->coordinate_dimension);
1329 else if (parameter ==
"b3"){
1331 if(this->coordinate_dimension > 2){
1332 b3 = this->fromString<scalar_t>(value);
1335 throw parameter+
" argument is not valid when dimension is " + toString<int>(this->coordinate_dimension);
1338 else if (parameter ==
"c"){
1339 c = this->fromString<scalar_t>(value);
1341 else if (parameter ==
"x1"){
1342 x1 = this->fromString<scalar_t>(value);
1344 else if (parameter ==
"y1"){
1345 if(this->coordinate_dimension > 1){
1346 y1 = this->fromString<scalar_t>(value);
1349 throw parameter+
" argument is not valid when dimension is " + toString<int>(this->coordinate_dimension);
1352 else if (parameter ==
"z1"){
1353 if(this->coordinate_dimension > 2){
1354 z1 = this->fromString<scalar_t>(value);
1357 throw parameter+
" argument is not valid when dimension is " + toString<int>(this->coordinate_dimension);
1360 else if (parameter ==
"steps"){
1361 stepCount = this->countChar(value,
',') + 1;
1362 std::string *stepstr =
new std::string[stepCount];
1363 this->splitString(value,
',', stepstr);
1364 steps =
new scalar_t[stepCount];
1365 for (
int j = 0; j < stepCount; ++j){
1366 steps[j] = this->fromString<scalar_t>(stepstr[j]);
1370 else if (parameter ==
"values"){
1371 valueCount = this->countChar(value,
',') + 1;
1372 std::string *stepstr =
new std::string[valueCount];
1373 this->splitString(value,
',', stepstr);
1374 values =
new scalar_t[valueCount];
1375 for (
int j = 0; j < valueCount; ++j){
1376 values[j] = this->fromString<scalar_t>(stepstr[j]);
1381 throw "Invalid parameter name at " + splittedStr[i];
1385 delete []splittedStr;
1386 if(stepCount + 1!= valueCount){
1387 throw "Step count: " + this->toString<int>(stepCount) +
" must be 1 less than value count: " + this->toString<int>(valueCount);
1391 this->wd[wcount++] =
new SteppedEquation<scalar_t,scalar_t>(a1, a2, a3, b1, b2, b3, c, x1, y1, z1, steps, values, stepCount);
1399 if(wcount != this->numWeightsPerCoord){
1400 throw "Weight Dimension is provided as " + toString<int>(wdimension) +
". But " + toString<int>(wcount)+
" weight distributions are provided.";
1404 void parseParams(
const Teuchos::ParameterList & params){
1406 std::string holeDescription =
"";
1407 std::string proc_load_distributions =
"";
1408 std::string distinctDescription =
"";
1409 std::string coordinate_distributions =
"";
1412 numWeightsPerCoord_parameters[i] =
"";
1416 for (Teuchos::ParameterList::ConstIterator pit = params.begin(); pit != params.end(); ++pit ){
1417 const std::string &
paramName = params.name(pit);
1419 const Teuchos::ParameterEntry &pe = params.entry(pit);
1421 if(paramName.find(
"hole-") == 0){
1422 if(holeDescription ==
""){
1423 holeDescription = getParamVal<std::string>(pe,
paramName);
1426 holeDescription +=
","+getParamVal<std::string>(pe,
paramName);
1429 else if(paramName.find(
"distribution-") == 0){
1430 if(coordinate_distributions ==
"")
1431 coordinate_distributions = getParamVal<std::string>(pe,
paramName);
1433 coordinate_distributions +=
","+getParamVal<std::string>(pe,
paramName);
1438 else if (paramName.find(weight_distribution_string) == 0){
1439 std::string weight_dist_param = paramName.substr(weight_distribution_string.size());
1440 int dash_pos = weight_dist_param.find(
"-");
1441 std::string distribution_index_string = weight_dist_param.substr(0, dash_pos);
1442 int distribution_index = fromString<int>(distribution_index_string);
1444 if(distribution_index >= MAX_WEIGHT_DIM){
1445 throw "Given distribution index:" + distribution_index_string +
" larger than maximum allowed number of weights:" + toString<int>(
MAX_WEIGHT_DIM);
1447 numWeightsPerCoord_parameters[distribution_index] +=
" " + weight_dist_param.substr(dash_pos + 1)+
"="+ getParamVal<std::string>(pe,
paramName);
1449 else if(paramName ==
"dim"){
1450 int dim = fromString<int>(getParamVal<std::string>(pe,
paramName));
1451 if(dim < 2 && dim > 3){
1454 this->coordinate_dimension = dim;
1457 else if(paramName ==
"wdim"){
1458 int dim = fromString<int>(getParamVal<std::string>(pe,
paramName));
1459 if(dim < 1 && dim > MAX_WEIGHT_DIM){
1462 this->numWeightsPerCoord = dim;
1465 else if(paramName ==
"predistribution"){
1466 int pre_distribution = fromString<int>(getParamVal<std::string>(pe,
paramName));
1467 if(pre_distribution < 0 && pre_distribution > 3){
1470 this->predistribution = pre_distribution;
1473 else if(paramName ==
"perturbation_ratio"){
1474 float perturbation = fromString<float>(getParamVal<std::string>(pe,
paramName));
1475 if(perturbation < 0 && perturbation > 1){
1478 this->perturbation_ratio = perturbation;
1483 else if(paramName ==
"proc_load_distributions"){
1484 proc_load_distributions = getParamVal<std::string>(pe,
paramName);
1485 this->loadDistSet =
true;
1488 else if(paramName ==
"distinct_coordinates"){
1489 distinctDescription = getParamVal<std::string>(pe,
paramName);
1490 if(distinctDescription ==
"T"){
1491 this->distinctCoordSet =
true;
1492 }
else if(distinctDescription ==
"F"){
1493 this->distinctCoordSet =
true;
1495 throw "Invalid parameter for distinct_coordinates: " + distinctDescription +
". Candidates: T or F." ;
1499 else if(paramName ==
"out_file"){
1500 this->outfile = getParamVal<std::string>(pe,
paramName);
1509 if(this->coordinate_dimension == 0){
1510 throw "Dimension must be provided to coordinate generator.";
1529 if (this->loadDistSet && this->distinctCoordSet){
1530 throw "distinct_coordinates and proc_load_distributions parameters cannot be satisfied together.";
1532 this->getHoles(holeDescription);
1534 this->getProcLoadDistributions(proc_load_distributions);
1535 this->getCoordinateDistributions(coordinate_distributions);
1536 this->getWeightDistribution(numWeightsPerCoord_parameters, this->numWeightsPerCoord);
1543 catch(std::string s){
1551 catch(
char const* s){
1560 for (
int i = 0; i < this->holeCount; ++i){
1561 delete this->holes[i];
1567 delete []loadDistributions;
1569 if(coordinateDistributions){
1571 for (
int i = 0; i < this->distributionCount; ++i){
1572 delete this->coordinateDistributions[i];
1574 free (this->coordinateDistributions);
1577 for (
int i = 0; i < this->numWeightsPerCoord; ++i){
1583 if(this->numWeightsPerCoord){
1584 for(
int i = 0; i < this->numWeightsPerCoord; ++i)
1585 delete [] this->wghts[i];
1586 delete []this->wghts;
1588 if(this->coordinate_dimension){
1589 for(
int i = 0; i < this->coordinate_dimension; ++i)
1590 delete [] this->coords[i];
1591 delete [] this->coords;
1597 cout <<
"\nGeometric Generator Parameter File Format:" << endl;
1598 cout <<
"- dim=Coordinate Dimension: 2 or 3" << endl;
1599 cout <<
"- Available distributions:" << endl;
1600 cout <<
"\tUNIFORM: -> distribution-1=UNIFORM,NUMCOORDINATES,XMIN,XMAX,YMIN,YMAX{,ZMIN,ZMAX}" << endl;
1601 cout <<
"\tGRID: -> distribution-2=GRID,XLENGTH,YLENGTH{,ZLENGTH},XMIN,XMAX,YMIN,YMAX{,ZMIN,ZMAX}" << endl;
1602 cout <<
"\tNORMAL: -> distribution-3=NORMAL,XCENTER,YCENTER{,ZCENTER},XSD,YSD,{,ZSD}" << endl;
1603 cout <<
"- wdim=numWeightsPerCoord: There should be as many weight function as number of weights per coord." << endl;
1604 cout <<
"- Weight Equation: w = (a1 * (x - x1)^b1) + (a2 * (y - y1)^b2) + (a3 * (z - z1)^b3) + c" << endl;
1605 cout <<
"Parameter settings:" << endl;
1606 cout <<
"\tWeightDistribution-1-a1=a1 " << endl;
1607 cout <<
"\tWeightDistribution-1-a2=a2 " << endl;
1608 cout <<
"\tWeightDistribution-1-a3=a3 " << endl;
1609 cout <<
"\tWeightDistribution-1-b1=b1 " << endl;
1610 cout <<
"\tWeightDistribution-1-b2=b2 " << endl;
1611 cout <<
"\tWeightDistribution-1-b3=b3 " << endl;
1612 cout <<
"\tWeightDistribution-1-x1=x1 " << endl;
1613 cout <<
"\tWeightDistribution-1-y1=y1 " << endl;
1614 cout <<
"\tWeightDistribution-1-z1=z1 " << endl;
1615 cout <<
"\tWeightDistribution-1-c=c " << endl;
1616 cout <<
"\tIt is possible to set step function to the result of weight equation." << endl;
1617 cout <<
"\tWeightDistribution-1-steps=step1,step2,step3:increasing order" << endl;
1618 cout <<
"\tWeightDistribution-1-values=val1,val2,val3,val4." << endl;
1619 cout <<
"\t\tIf w < step1 -> w = val1" << endl;
1620 cout <<
"\t\tElse if w < step2 -> w = val2" << endl;
1621 cout <<
"\t\tElse if w < step3 -> w = val3" << endl;
1622 cout <<
"\t\tElse -> w = val4" << endl;
1623 cout <<
"- Holes:" << endl;
1624 cout <<
"\thole-1:SPHERE,XCENTER,YCENTER,ZCENTER,RADIUS (only for dim=3)" << endl;
1625 cout <<
"\thole-2:CUBE,XCENTER,YCENTER,ZCENTER,EDGE (only for dim=3)" << endl;
1626 cout <<
"\thole-3:RECTANGULAR_PRISM,XCENTER,YCENTER,ZCENTER,XEDGE,YEDGE,ZEDGE (only for dim=3)" << endl;
1627 cout <<
"\thole-4:SQUARE,XCENTER,YCENTER,EDGE (only for dim=2)" << endl;
1628 cout <<
"\thole-5:RECTANGLE,XCENTER,YCENTER,XEDGE,YEDGE (only for dim=2)" << endl;
1629 cout <<
"\thole-6:CIRCLE,XCENTER,YCENTER,RADIUS (only for dim=2)" << endl;
1630 cout <<
"- out_file:out_file_path : if provided output will be written to files." << endl;
1631 cout <<
"- proc_load_distributions:ratio_0, ratio_1, ratio_2....ratio_n. Loads of each processor, should be as many as MPI ranks and should sum up to 1." << endl;
1632 cout <<
"- predistribution:distribution_option. Predistribution of the coordinates to the processors. 0 for NONE, 1 RCB, 2 MJ, 3 BLOCK." << endl;
1633 cout <<
"- perturbation_ratio:the percent of the local data which will be perturbed in order to simulate the changes in the dynamic partitioning. Float value between 0 and 1." << endl;
1640 this->coordinate_dimension = 0;
1641 this->numWeightsPerCoord = 0;
1642 this->worldSize = comm_->getSize();
1643 this->numGlobalCoords = 0;
1644 this->loadDistributions = NULL;
1646 this->coordinateDistributions = NULL;
1647 this->holeCount = 0;
1648 this->distributionCount = 0;
1650 this->predistribution = 0;
1651 this->perturbation_ratio = 0;
1662 this->loadDistSet =
false;
1663 this->distinctCoordSet =
false;
1664 this->myRank = comm_->getRank();
1667 this->parseParams(params);
1669 catch(std::string s){
1671 print_description();
1679 lno_t myPointCount = 0;
1680 this->numGlobalCoords = 0;
1682 gno_t prefixSum = 0;
1683 for(
int i = 0; i < this->distributionCount; ++i){
1684 for(
int ii = 0; ii < this->worldSize; ++ii){
1685 lno_t increment = lno_t (this->coordinateDistributions[i]->numPoints * this->loadDistributions[ii]);
1686 if (gno_t(ii) < this->coordinateDistributions[i]->numPoints % this->worldSize){
1689 this->numGlobalCoords += increment;
1691 prefixSum += increment;
1694 myPointCount += lno_t(this->coordinateDistributions[i]->numPoints * this->loadDistributions[myRank]);
1695 if (gno_t(myRank) < this->coordinateDistributions[i]->numPoints % this->worldSize){
1700 this->coords =
new scalar_t *[this->coordinate_dimension];
1701 for(
int i = 0; i < this->coordinate_dimension; ++i){
1702 this->coords[i] =
new scalar_t[myPointCount];
1705 for (
int ii = 0; ii < this->coordinate_dimension; ++ii){
1706 #ifdef HAVE_ZOLTAN2_OMP 1707 #pragma omp parallel for 1709 for(lno_t i = 0; i < myPointCount; ++i){
1710 this->coords[ii][i] = 0;
1714 this->numLocalCoords = 0;
1715 srand ((myRank + 1) * this->numLocalCoords);
1716 for (
int i = 0; i < distributionCount; ++i){
1718 lno_t requestedPointCount = lno_t(this->coordinateDistributions[i]->numPoints * this->loadDistributions[myRank]);
1719 if (gno_t(myRank) < this->coordinateDistributions[i]->numPoints % this->worldSize){
1720 requestedPointCount += 1;
1724 this->coordinateDistributions[i]->
GetPoints(requestedPointCount,this->coords, this->numLocalCoords, this->holes, this->holeCount, this->loadDistributions, myRank);
1725 this->numLocalCoords += requestedPointCount;
1747 if (this->predistribution){
1754 if (this->perturbation_ratio > 0){
1755 this->perturb_data(this->perturbation_ratio, scale);
1776 if (this->distinctCoordSet){
1780 if(this->outfile !=
""){
1782 std::ofstream myfile;
1783 myfile.open ((this->outfile + toString<int>(myRank)).c_str());
1784 for(lno_t i = 0; i < this->numLocalCoords; ++i){
1786 myfile << this->coords[0][i];
1787 if(this->coordinate_dimension > 1){
1788 myfile <<
" " << this->coords[1][i];
1790 if(this->coordinate_dimension > 2){
1791 myfile <<
" " << this->coords[2][i];
1793 myfile << std::endl;
1797 if (this->myRank == 0){
1798 std::ofstream gnuplotfile(
"gnu.gnuplot");
1799 for(
int i = 0; i < this->worldSize; ++i){
1801 if (this->coordinate_dimension == 2){
1807 gnuplotfile << s <<
" \"" << (this->outfile + toString<int>(i)) <<
"\"" << endl;
1809 gnuplotfile <<
"pause -1" << endl;
1810 gnuplotfile.close();
1823 if (this->numWeightsPerCoord > 0){
1824 this->wghts =
new scalar_t *[this->numWeightsPerCoord];
1825 for(
int i = 0; i < this->numWeightsPerCoord; ++i){
1826 this->wghts[i] =
new scalar_t[this->numLocalCoords];
1830 for(
int ii = 0; ii < this->numWeightsPerCoord; ++ii){
1831 switch(this->coordinate_dimension){
1833 #ifdef HAVE_ZOLTAN2_OMP 1834 #pragma omp parallel for 1836 for (lno_t i = 0; i < this->numLocalCoords; ++i){
1837 this->wghts[ii][i] = this->wd[ii]->
get1DWeight(this->coords[0][i]);
1841 #ifdef HAVE_ZOLTAN2_OMP 1842 #pragma omp parallel for 1844 for (lno_t i = 0; i < this->numLocalCoords; ++i){
1845 this->wghts[ii][i] = this->wd[ii]->
get2DWeight(this->coords[0][i], this->coords[1][i]);
1849 #ifdef HAVE_ZOLTAN2_OMP 1850 #pragma omp parallel for 1852 for (lno_t i = 0; i < this->numLocalCoords; ++i){
1853 this->wghts[ii][i] = this->wd[ii]->
get3DWeight(this->coords[0][i], this->coords[1][i], this->coords[2][i]);
1864 scalar_t *maxCoords=
new scalar_t [this->coordinate_dimension];
1865 scalar_t *minCoords=
new scalar_t [this->coordinate_dimension];
1866 for (
int dim = 0; dim < this->coordinate_dimension; ++dim){
1867 minCoords[dim] = maxCoords[dim] = this->coords[dim][0];
1868 for (lno_t i = 1; i < this->numLocalCoords; ++i){
1869 if (minCoords[dim] > this->coords[dim][i]){
1870 minCoords[dim] = this->coords[dim][i];
1873 if (maxCoords[dim] < this->coords[dim][i]){
1874 maxCoords[dim] = this->coords[dim][i];
1881 scalar_t center = (maxCoords[dim] + minCoords[dim]) / 2;
1883 minCoords[dim] = center - (center - minCoords[dim]) * scale;
1884 maxCoords[dim] = (maxCoords[dim] - center) * scale + center;
1888 gno_t numLocalToPerturb = gno_t(this->numLocalCoords*used_perturbation_ratio);
1890 for (
int dim = 0; dim < this->coordinate_dimension; ++dim){
1891 scalar_t range = maxCoords[dim] - minCoords[dim];
1892 for (gno_t i = 0; i < numLocalToPerturb; ++i){
1893 this->coords[dim][i] = (rand() / double (RAND_MAX)) * (range) + minCoords[dim];
1906 void getBestSurface (
int remaining,
int *dimProcs,
int dim,
int currentDim,
int &bestSurface,
int *bestDimProcs){
1908 if (currentDim < dim - 1){
1910 while(ipx <= remaining) {
1911 if(remaining % ipx == 0) {
1912 int nremain = remaining / ipx;
1913 dimProcs[currentDim] = ipx;
1914 getBestSurface (nremain, dimProcs, dim, currentDim + 1, bestSurface, bestDimProcs);
1920 dimProcs[currentDim] = remaining;
1922 for (
int i = 0; i < dim; ++i) surface += dimProcs[i];
1923 if (surface < bestSurface){
1924 bestSurface = surface;
1925 for (
int i = 0; i < dim; ++i) bestDimProcs[i] = dimProcs[i];
1933 scalar_t *maxCoords=
new scalar_t [this->coordinate_dimension];
1934 scalar_t *minCoords=
new scalar_t [this->coordinate_dimension];
1935 for (
int dim = 0; dim < this->coordinate_dimension; ++dim){
1936 minCoords[dim] = maxCoords[dim] = this->coords[dim][0];
1937 for (lno_t i = 1; i < this->numLocalCoords; ++i){
1938 if (minCoords[dim] > this->coords[dim][i]){
1939 minCoords[dim] = this->coords[dim][i];
1942 if (maxCoords[dim] < this->coords[dim][i]){
1943 maxCoords[dim] = this->coords[dim][i];
1948 reduceAll<int, scalar_t>( *(this->comm), Teuchos::REDUCE_MAX,
1949 this->coordinate_dimension,
1954 reduceAll<int, scalar_t>( *(this->comm), Teuchos::REDUCE_MIN,
1955 this->coordinate_dimension,
1969 typedef SSIZE_T ssize_t;
1976 scalar_t *maxCoords=
new scalar_t [this->coordinate_dimension];
1977 scalar_t *minCoords=
new scalar_t [this->coordinate_dimension];
1979 this->getMinMaxCoords(maxCoords, minCoords);
1985 int remaining = this->worldSize;
1986 int coord_dim = this->coordinate_dimension;
1987 int *dimProcs =
new int[coord_dim];
1988 int *bestDimProcs =
new int[coord_dim];
1991 int bestSurface = 0;
1992 dimProcs[0] = remaining;
1993 for (
int i = 1; i < coord_dim; ++i) dimProcs[i] = 1;
1994 for (
int i = 0; i < coord_dim; ++i) bestSurface += dimProcs[i];
1995 for (
int i = 0; i < coord_dim; ++i) bestDimProcs[i] = dimProcs[i];
1997 getBestSurface ( remaining, dimProcs, coord_dim, currentDim, bestSurface, bestDimProcs);
2005 int *shiftProcCount =
new int[coord_dim];
2009 int remainingProc = this->worldSize;
2010 for (
int dim = 0; dim < coord_dim; ++dim){
2011 remainingProc = remainingProc / bestDimProcs[dim];
2012 shiftProcCount[dim] = remainingProc;
2015 scalar_t *dim_slices =
new scalar_t[coord_dim];
2016 for (
int dim = 0; dim < coord_dim; ++dim){
2017 scalar_t dim_range = maxCoords[dim] - minCoords[dim];
2018 scalar_t slice = dim_range / bestDimProcs[dim];
2019 dim_slices[dim] = slice;
2026 gno_t *numPointsInParts =
new gno_t[this->worldSize];
2027 gno_t *numGlobalPointsInParts =
new gno_t[this->worldSize];
2028 gno_t *numPointsInPartsInclusiveUptoMyIndex =
new gno_t[this->worldSize];
2030 gno_t *partBegins =
new gno_t [this->worldSize];
2031 gno_t *partNext =
new gno_t[this->numLocalCoords];
2034 for (lno_t i = 0; i < this->numLocalCoords; ++i){
2037 for (
int i = 0; i < this->worldSize; ++i) {
2041 for (
int i = 0; i < this->worldSize; ++i)
2042 numPointsInParts[i] = 0;
2044 for (lno_t i = 0; i < this->numLocalCoords; ++i){
2046 for (
int dim = 0; dim < coord_dim; ++dim){
2047 int shift = int ((this->coords[dim][i] - minCoords[dim]) / dim_slices[dim]);
2048 if (shift >= bestDimProcs[dim]){
2049 shift = bestDimProcs[dim] - 1;
2051 shift = shift * shiftProcCount[dim];
2054 numPointsInParts[partIndex] += 1;
2055 coordinate_grid_parts[i] = partIndex;
2057 partNext[i] = partBegins[partIndex];
2058 partBegins[partIndex] = i;
2065 reduceAll<int, gno_t>( *(this->comm), Teuchos::REDUCE_SUM,
2068 numGlobalPointsInParts);
2071 Teuchos::scan<int,gno_t>(
2072 *(this->comm), Teuchos::REDUCE_SUM,
2075 numPointsInPartsInclusiveUptoMyIndex
2094 gno_t optimal_num = gno_t(this->numGlobalCoords/
double(this->worldSize)+0.5);
2096 if (this->myRank == 0){
2097 gno_t totalSize = 0;
2098 for (
int i = 0; i < this->worldSize; ++i){
2099 cout <<
"me:" << this->myRank <<
" NumPoints in part:" << i <<
" is: " << numGlobalPointsInParts[i] << endl;
2100 totalSize += numGlobalPointsInParts[i];
2102 cout <<
"Total:" << totalSize <<
" ng:" << this->numGlobalCoords << endl;
2103 cout <<
"optimal_num:" << optimal_num << endl;
2106 ssize_t *extraInPart =
new ssize_t [this->worldSize];
2108 ssize_t extraExchange = 0;
2109 for (
int i = 0; i < this->worldSize; ++i){
2110 extraInPart[i] = numGlobalPointsInParts[i] - optimal_num;
2111 extraExchange += extraInPart[i];
2113 if (extraExchange != 0){
2115 if (extraExchange < 0) addition = 1;
2116 for (ssize_t i = 0; i < extraExchange; ++i){
2117 extraInPart[i % this->worldSize] += addition;
2125 int overloadedPartCount = 0;
2126 int *overloadedPartIndices =
new int [this->worldSize];
2129 int underloadedPartCount = 0;
2130 int *underloadedPartIndices =
new int [this->worldSize];
2132 for (
int i = 0; i < this->worldSize; ++i){
2133 if(extraInPart[i] > 0){
2134 overloadedPartIndices[overloadedPartCount++] = i;
2136 else if(extraInPart[i] < 0){
2137 underloadedPartIndices[underloadedPartCount++] = i;
2141 int underloadpartindex = underloadedPartCount - 1;
2144 int numPartsISendFrom = 0;
2145 int *mySendFromParts =
new int[this->worldSize * 2];
2146 gno_t *mySendFromPartsCounts =
new gno_t[this->worldSize * 2];
2148 int numPartsISendTo = 0;
2149 int *mySendParts =
new int[this->worldSize * 2];
2150 gno_t *mySendCountsToParts =
new gno_t[this->worldSize * 2];
2159 for (
int i = overloadedPartCount - 1; i >= 0; --i){
2162 int overloadPart = overloadedPartIndices[i];
2163 gno_t overload = extraInPart[overloadPart];
2164 gno_t myload = numPointsInParts[overloadPart];
2168 gno_t inclusiveLoadUpToMe = numPointsInPartsInclusiveUptoMyIndex[overloadPart];
2171 gno_t exclusiveLoadUptoMe = inclusiveLoadUpToMe - myload;
2174 if (exclusiveLoadUptoMe >= overload){
2178 overloadedPartIndices[i] = -1;
2179 extraInPart[overloadPart] = 0;
2181 while (overload > 0){
2182 int nextUnderLoadedPart = underloadedPartIndices[underloadpartindex];
2183 ssize_t underload = extraInPart[nextUnderLoadedPart];
2184 ssize_t left = overload + underload;
2187 extraInPart[nextUnderLoadedPart] = 0;
2188 underloadedPartIndices[underloadpartindex--] = -1;
2191 extraInPart[nextUnderLoadedPart] = left;
2196 else if (exclusiveLoadUptoMe < overload){
2199 gno_t mySendCount = overload - exclusiveLoadUptoMe;
2201 gno_t sendAfterMe = 0;
2204 if (mySendCount > myload){
2205 sendAfterMe = mySendCount - myload;
2206 mySendCount = myload;
2212 mySendFromParts[numPartsISendFrom] = overloadPart;
2213 mySendFromPartsCounts[numPartsISendFrom++] = mySendCount;
2216 while (exclusiveLoadUptoMe > 0){
2217 int nextUnderLoadedPart = underloadedPartIndices[underloadpartindex];
2218 ssize_t underload = extraInPart[nextUnderLoadedPart];
2219 ssize_t left = exclusiveLoadUptoMe + underload;
2222 extraInPart[nextUnderLoadedPart] = 0;
2223 underloadedPartIndices[underloadpartindex--] = -1;
2226 extraInPart[nextUnderLoadedPart] = left;
2228 exclusiveLoadUptoMe = left;
2232 while (mySendCount > 0){
2233 int nextUnderLoadedPart = underloadedPartIndices[underloadpartindex];
2234 ssize_t underload = extraInPart[nextUnderLoadedPart];
2235 ssize_t left = mySendCount + underload;
2238 mySendParts[numPartsISendTo] = nextUnderLoadedPart;
2239 mySendCountsToParts[numPartsISendTo++] = -underload;
2241 extraInPart[nextUnderLoadedPart] = 0;
2242 underloadedPartIndices[underloadpartindex--] = -1;
2245 extraInPart[nextUnderLoadedPart] = left;
2247 mySendParts[numPartsISendTo] = nextUnderLoadedPart;
2248 mySendCountsToParts[numPartsISendTo++] = mySendCount;
2254 while (sendAfterMe > 0){
2255 int nextUnderLoadedPart = underloadedPartIndices[underloadpartindex];
2256 ssize_t underload = extraInPart[nextUnderLoadedPart];
2257 ssize_t left = sendAfterMe + underload;
2260 extraInPart[nextUnderLoadedPart] = 0;
2261 underloadedPartIndices[underloadpartindex--] = -1;
2264 extraInPart[nextUnderLoadedPart] = left;
2275 for (
int i = 0 ; i < numPartsISendFrom; ++i){
2278 int sendFromPart = mySendFromParts[i];
2279 ssize_t sendCount = mySendFromPartsCounts[i];
2280 while(sendCount > 0){
2281 int partToSendIndex = numPartsISendTo - 1;
2282 int partToSend = mySendParts[partToSendIndex];
2284 int sendCountToThisPart = mySendCountsToParts[partToSendIndex];
2288 if (sendCountToThisPart <= sendCount){
2289 mySendParts[partToSendIndex] = 0;
2290 mySendCountsToParts[partToSendIndex] = 0;
2292 sendCount -= sendCountToThisPart;
2295 mySendCountsToParts[partToSendIndex] = sendCountToThisPart - sendCount;
2296 sendCountToThisPart = sendCount;
2301 gno_t toChange = partBegins[sendFromPart];
2302 gno_t previous_begin = partBegins[partToSend];
2305 for (
int k = 0; k < sendCountToThisPart - 1; ++k){
2306 coordinate_grid_parts[toChange] = partToSend;
2307 toChange = partNext[toChange];
2309 coordinate_grid_parts[toChange] = partToSend;
2311 gno_t newBegin = partNext[toChange];
2312 partNext[toChange] = previous_begin;
2313 partBegins[partToSend] = partBegins[sendFromPart];
2314 partBegins[sendFromPart] = newBegin;
2323 for (
int i = 0; i < this->worldSize; ++i) numPointsInParts[i] = 0;
2325 for (
int i = 0; i < this->numLocalCoords; ++i){
2326 numPointsInParts[coordinate_grid_parts[i]] += 1;
2329 reduceAll<int, gno_t>( *(this->comm), Teuchos::REDUCE_SUM,
2332 numGlobalPointsInParts);
2333 if (this->myRank == 0){
2334 cout <<
"reassigning" << endl;
2335 gno_t totalSize = 0;
2336 for (
int i = 0; i < this->worldSize; ++i){
2337 cout <<
"me:" << this->myRank <<
" NumPoints in part:" << i <<
" is: " << numGlobalPointsInParts[i] << endl;
2338 totalSize += numGlobalPointsInParts[i];
2340 cout <<
"Total:" << totalSize <<
" ng:" << this->numGlobalCoords << endl;
2343 delete []mySendCountsToParts;
2344 delete []mySendParts;
2345 delete []mySendFromPartsCounts;
2346 delete []mySendFromParts;
2347 delete []underloadedPartIndices;
2348 delete []overloadedPartIndices;
2349 delete []extraInPart;
2351 delete []partBegins;
2352 delete []numPointsInPartsInclusiveUptoMyIndex;
2353 delete []numPointsInParts;
2354 delete []numGlobalPointsInParts;
2356 delete []shiftProcCount;
2357 delete []bestDimProcs;
2358 delete []dim_slices;
2367 Tpetra::Distributor distributor(comm);
2368 ArrayView<const int> pIds( coordinate_grid_parts, this->numLocalCoords);
2374 gno_t numMyNewGnos = distributor.createFromSends(pIds);
2378 this->numLocalCoords = numMyNewGnos;
2381 ArrayRCP<scalar_t> recvBuf2(distributor.getTotalReceiveLength());
2383 for (
int i = 0; i < this->coordinate_dimension; ++i){
2384 ArrayView<scalar_t> s(this->coords[i], this->numLocalCoords);
2385 distributor.doPostsAndWaits<scalar_t>(s, 1, recvBuf2());
2386 delete [] this->coords[i];
2387 this->coords[i] =
new scalar_t[this->numLocalCoords];
2388 for (lno_t j = 0; j < this->numLocalCoords; ++j){
2389 this->coords[i][j] = recvBuf2[j];
2397 int coord_dim = this->coordinate_dimension;
2399 lno_t numLocalPoints = this->numLocalCoords;
2400 gno_t numGlobalPoints = this->numGlobalCoords;
2405 RCP<Tpetra::Map<lno_t, gno_t, node_t> > mp = rcp(
2406 new Tpetra::Map<lno_t, gno_t, node_t> (numGlobalPoints, numLocalPoints, 0, comm));
2408 Teuchos::Array<Teuchos::ArrayView<const scalar_t> > coordView(coord_dim);
2412 for (
int i=0; i < coord_dim; i++){
2413 if(numLocalPoints > 0){
2414 Teuchos::ArrayView<const scalar_t> a(coords[i], numLocalPoints);
2417 Teuchos::ArrayView<const scalar_t> a;
2422 RCP< Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> >tmVector = RCP< Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> >(
2423 new Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t>( mp, coordView.view(0, coord_dim), coord_dim));
2426 RCP<const tMVector_t> coordsConst = Teuchos::rcp_const_cast<
const tMVector_t>(tmVector);
2427 std::vector<const scalar_t *> weights;
2428 std::vector <int> stride;
2432 inputAdapter_t ia(coordsConst,weights, stride);
2434 Teuchos::RCP <Teuchos::ParameterList> params ;
2435 params =RCP <Teuchos::ParameterList> (
new Teuchos::ParameterList,
true);
2438 params->set(
"algorithm",
"multijagged");
2439 params->set(
"num_global_parts", this->worldSize);
2444 params->set(
"migration_check_option", 2);
2451 #ifdef HAVE_ZOLTAN2_MPI 2465 const typename inputAdapter_t::part_t *partIds = problem->
getSolution().getPartListView();
2467 for (lno_t i = 0; i < this->numLocalCoords;++i){
2468 coordinate_grid_parts[i] = partIds[i];
2475 #ifdef HAVE_ZOLTAN2_ZOLTAN 2477 int predistributeRCB(
int *coordinate_grid_parts){
2478 int rank = this->myRank;
2479 int nprocs = this->worldSize;
2480 DOTS<tMVector_t> dots_;
2482 MEMORY_CHECK(rank==0 || rank==nprocs-1,
"After initializing MPI");
2487 string memoryOn(
"memoryOn");
2488 string memoryOff(
"memoryOff");
2489 bool doMemory=
false;
2490 int numGlobalParts = nprocs;
2494 string balanceCount(
"balance_object_count");
2495 string balanceWeight(
"balance_object_weight");
2496 string mcnorm1(
"multicriteria_minimize_total_weight");
2497 string mcnorm2(
"multicriteria_balance_total_maximum");
2498 string mcnorm3(
"multicriteria_minimize_maximum_weight");
2499 string objective(balanceWeight);
2502 CommandLineProcessor commandLine(
false,
true);
2505 int input_option = 0;
2506 commandLine.setOption(
"input_option", &input_option,
2507 "whether to use mesh creation, geometric generator, or file input");
2508 string inputFile =
"";
2510 commandLine.setOption(
"input_file", &inputFile,
2511 "the input file for geometric generator or file input");
2514 commandLine.setOption(
"size", &numGlobalCoords,
2515 "Approximate number of global coordinates.");
2516 commandLine.setOption(
"numParts", &numGlobalParts,
2517 "Number of parts (default is one per proc).");
2518 commandLine.setOption(
"nWeights", &nWeights,
2519 "Number of weights per coordinate, zero implies uniform weights.");
2520 commandLine.setOption(
"debug", &debugLevel,
"Zoltan1 debug level");
2521 commandLine.setOption(
"remap",
"no-remap", &remap,
2522 "Zoltan1 REMAP parameter; disabled by default for scalability testing");
2523 commandLine.setOption(
"timers", &dummyTimer,
"ignored");
2524 commandLine.setOption(memoryOn.c_str(), memoryOff.c_str(), &doMemory,
2525 "do memory profiling");
2527 string doc(balanceCount);
2528 doc.append(
": ignore weights\n");
2529 doc.append(balanceWeight);
2530 doc.append(
": balance on first weight\n");
2531 doc.append(mcnorm1);
2532 doc.append(
": given multiple weights, balance their total.\n");
2533 doc.append(mcnorm3);
2534 doc.append(
": given multiple weights, " 2535 "balance the maximum for each coordinate.\n");
2536 doc.append(mcnorm2);
2537 doc.append(
": given multiple weights, balance the L2 norm of the weights.\n");
2538 commandLine.setOption(
"objective", &objective, doc.c_str());
2540 CommandLineProcessor::EParseCommandLineReturn rc =
2541 commandLine.parse(0, NULL);
2545 if (rc != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
2546 if (rc == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED) {
2547 if (rank==0) cout <<
"PASS" << endl;
2551 if (rank==0) cout <<
"FAIL" << endl;
2560 int coord_dim = this->coordinate_dimension;
2563 RCP<Tpetra::Map<lno_t, gno_t, node_t> > mp = rcp(
2564 new Tpetra::Map<lno_t, gno_t, node_t> (this->numGlobalCoords, this->numLocalCoords, 0, this->comm));
2566 Teuchos::Array<Teuchos::ArrayView<const scalar_t> > coordView(coord_dim);
2567 for (
int i=0; i < coord_dim; i++){
2568 if(numLocalCoords > 0){
2569 Teuchos::ArrayView<const scalar_t> a(coords[i], numLocalCoords);
2572 Teuchos::ArrayView<const scalar_t> a;
2577 tMVector_t *tmVector =
new tMVector_t( mp, coordView.view(0, coord_dim), coord_dim);
2579 dots_.coordinates = tmVector;
2580 dots_.weights.resize(nWeights);
2583 MEMORY_CHECK(doMemory && rank==0,
"After creating input");
2588 int aok = Zoltan_Initialize(0,NULL, &ver);
2591 printf(
"Zoltan_Initialize failed\n");
2595 struct Zoltan_Struct *zz;
2596 zz = Zoltan_Create(MPI_COMM_WORLD);
2598 Zoltan_Set_Param(zz,
"LB_METHOD",
"RCB");
2599 Zoltan_Set_Param(zz,
"LB_APPROACH",
"PARTITION");
2600 Zoltan_Set_Param(zz,
"CHECK_GEOM",
"0");
2601 Zoltan_Set_Param(zz,
"NUM_GID_ENTRIES",
"1");
2602 Zoltan_Set_Param(zz,
"NUM_LID_ENTRIES",
"0");
2603 Zoltan_Set_Param(zz,
"RETURN_LISTS",
"PART");
2604 std::ostringstream oss;
2605 oss << numGlobalParts;
2606 Zoltan_Set_Param(zz,
"NUM_GLOBAL_PARTS", oss.str().c_str());
2609 Zoltan_Set_Param(zz,
"DEBUG_LEVEL", oss.str().c_str());
2612 Zoltan_Set_Param(zz,
"REMAP",
"1");
2614 Zoltan_Set_Param(zz,
"REMAP",
"0");
2616 if (objective != balanceCount){
2619 Zoltan_Set_Param(zz,
"OBJ_WEIGHT_DIM", oss.str().c_str());
2621 if (objective == mcnorm1)
2622 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"1");
2623 else if (objective == mcnorm2)
2624 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"2");
2625 else if (objective == mcnorm3)
2626 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"3");
2629 Zoltan_Set_Param(zz,
"OBJ_WEIGHT_DIM",
"0");
2632 Zoltan_Set_Num_Obj_Fn(zz, getNumObj<tMVector_t>, &dots_);
2633 Zoltan_Set_Obj_List_Fn(zz, getObjList<tMVector_t>, &dots_);
2634 Zoltan_Set_Num_Geom_Fn(zz, getDim<tMVector_t>, &dots_);
2635 Zoltan_Set_Geom_Multi_Fn(zz, getCoords<tMVector_t>, &dots_);
2637 int changes, numGidEntries, numLidEntries, numImport, numExport;
2638 ZOLTAN_ID_PTR importGlobalGids, importLocalGids;
2639 ZOLTAN_ID_PTR exportGlobalGids, exportLocalGids;
2640 int *importProcs, *importToPart, *exportProcs, *exportToPart;
2642 MEMORY_CHECK(doMemory && rank==0,
"Before Zoltan_LB_Partition");
2645 aok = Zoltan_LB_Partition(zz, &changes, &numGidEntries, &numLidEntries,
2646 &numImport, &importGlobalGids, &importLocalGids,
2647 &importProcs, &importToPart,
2648 &numExport, &exportGlobalGids, &exportLocalGids,
2649 &exportProcs, &exportToPart);
2652 MEMORY_CHECK(doMemory && rank==0,
"After Zoltan_LB_Partition");
2654 for (lno_t i = 0; i < numLocalCoords; i++)
2655 coordinate_grid_parts[i] = exportToPart[i];
2656 Zoltan_Destroy(&zz);
2657 MEMORY_CHECK(doMemory && rank==0,
"After Zoltan_Destroy");
2659 delete dots_.coordinates;
2664 int *coordinate_grid_parts =
new int[this->numLocalCoords];
2665 switch (this->predistribution){
2667 #ifdef HAVE_ZOLTAN2_ZOLTAN 2668 this->predistributeRCB(coordinate_grid_parts);
2673 this->predistributeMJ(coordinate_grid_parts);
2677 blockPartition(coordinate_grid_parts);
2680 this->distribute_points(coordinate_grid_parts);
2682 delete []coordinate_grid_parts;
2693 return this->numWeightsPerCoord;
2696 return this->coordinate_dimension;
2699 return this->numLocalCoords;
2702 return this->numGlobalCoords;
2706 return this->coords;
2714 for(
int ii = 0; ii < this->coordinate_dimension; ++ii){
2715 #ifdef HAVE_ZOLTAN2_OMP 2716 #pragma omp parallel for 2718 for (lno_t i = 0; i < this->numLocalCoords; ++i){
2719 c[ii][i] = this->coords[ii][i];
2725 for(
int ii = 0; ii < this->numWeightsPerCoord; ++ii){
2726 #ifdef HAVE_ZOLTAN2_OMP 2727 #pragma omp parallel for 2729 for (lno_t i = 0; i < this->numLocalCoords; ++i){
2730 w[ii][i] = this->wghts[ii][i];
RectangleHole(CoordinatePoint< T > center_, T edge_x_, T edge_y_)
virtual weighttype get1DWeight(T x)
virtual bool isInArea(CoordinatePoint< T > dot)
CoordinateGridDistribution(gno_t alongX, gno_t alongY, gno_t alongZ, int dim, T l_x, T r_x, T l_y, T r_y, T l_z, T r_z, int myRank_, int wSize)
virtual weighttype get1DWeight(T x)=0
void print(T x, T y, T z)
virtual ~CoordinateDistribution()
void getLocalCoordinatesCopy(scalar_t **c)
void GetPoints(lno_t requestedPointcount, CoordinatePoint< T > *points, Hole< T > **holes, lno_t holeCount, float *sharedRatios_, int myRank)
virtual bool isInArea(CoordinatePoint< T > dot)
virtual bool isInArea(CoordinatePoint< T > dot)
virtual CoordinatePoint< T > getPoint(gno_t pindex, unsigned int &state)
virtual weighttype get2DWeight(T x, T y)
void GetPoints(lno_t requestedPointcount, T **coords, lno_t tindex, Hole< T > **holes, lno_t holeCount, float *sharedRatios_, int myRank)
Hole(CoordinatePoint< T > center_, T edge1_, T edge2_, T edge3_)
scalar_t ** getLocalWeightsView()
SphereHole(CoordinatePoint< T > center_, T edge_)
CircleHole(CoordinatePoint< T > center_, T edge_)
int getCoordinateDimension()
virtual ~RectangularPrismHole()
Defines the PartitioningSolution class.
void perturb_data(float used_perturbation_ratio, int scale)
Start perturbation function##########################//
virtual weighttype get3DWeight(T x, T y, T z)
virtual weighttype get3DWeight(T x, T y, T z)=0
Defines the XpetraMultiVectorAdapter.
void blockPartition(int *coordinate_grid_parts)
RectangularPrismHole(CoordinatePoint< T > center_, T edge_x_, T edge_y_, T edge_z_)
CoordinateNormalDistribution(gno_t np_, int dim, CoordinatePoint< T > center_, T sd_x, T sd_y, T sd_z, int wSize)
virtual bool isInArea(CoordinatePoint< T > dot)
virtual bool isInArea(CoordinatePoint< T > dot)
SteppedEquation(T a1_, T a2_, T a3_, T b1_, T b2_, T b3_, T c_, T x1_, T y1_, T z1_, T *steps_, T *values_, int stepCount_)
const std::string shapes[]
scalar_t ** getLocalCoordinatesView()
virtual weighttype getWeight(CoordinatePoint< T > p)
virtual ~SteppedEquation()
const std::string weight_distribution_string
virtual CoordinatePoint< T > getPoint(gno_t pindex, unsigned int &state)
virtual weighttype get2DWeight(T x, T y)=0
An adapter for Xpetra::MultiVector.
void getBestSurface(int remaining, int *dimProcs, int dim, int currentDim, int &bestSurface, int *bestDimProcs)
Start Predistribution functions######################//
Expression is a generic following method.
std::string toString(tt obj)
Converts the given object to string.
CoordinatePoint< T > center
void distribute_points(int *coordinate_grid_parts)
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the problem.
virtual ~WeightDistribution()
PartitioningProblem sets up partitioning problems for the user.
GeometricGenerator(Teuchos::ParameterList ¶ms, const RCP< const Teuchos::Comm< int > > &comm_)
int getNumWeights()
##END Predistribution functions######################//
CoordinatePoint< T > center
#define INVALID_SHAPE_ARG(SHAPE, REQUIRED)
lno_t getNumLocalCoords()
virtual ~CoordinateNormalDistribution()
#define INVALIDSHAPE(STR, DIM)
#define CATCH_EXCEPTIONS(pp)
Defines the PartitioningProblem class.
CoordinateDistribution(gno_t np_, int dim, int wSize)
int predistributeMJ(int *coordinate_grid_parts)
virtual ~CoordinateGridDistribution()
gno_t getNumGlobalCoords()
SquareHole(CoordinatePoint< T > center_, T edge_)
void solve(bool updateInputData=true)
Direct the problem to create a solution.
CubeHole(CoordinatePoint< T > center_, T edge_)
void getLocalWeightsCopy(scalar_t **w)
virtual bool isInArea(CoordinatePoint< T > dot)
void getMinMaxCoords(scalar_t *globalMaxCoords, scalar_t *globalMinCoords)
#define MEMORY_CHECK(iPrint, msg)