55 #ifdef HAVE_ZOLTAN2_ZOLTAN 57 #include <Teuchos_CommandLineProcessor.hpp> 79 using Teuchos::ArrayView;
80 using Teuchos::ArrayRCP;
81 using Teuchos::CommandLineProcessor;
83 typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>
tMVector_t;
84 typedef Tpetra::Map<zlno_t, zgno_t, znode_t> tMap_t;
86 static ArrayRCP<ArrayRCP<zscalar_t> > weights;
87 static RCP<tMVector_t> coordinates;
94 const string& delimiters =
" \f\n\r\t\v" )
96 return s.substr( 0, s.find_last_not_of( delimiters ) + 1 );
101 const string& delimiters =
" \f\n\r\t\v" )
103 return s.substr( s.find_first_not_of( delimiters ) );
108 const string& delimiters =
" \f\n\r\t\v" )
114 bool getArgumentValue(
string &argumentid,
double &argumentValue,
string argumentline){
115 stringstream stream(stringstream::in | stringstream::out);
116 stream << argumentline;
117 getline(stream, argumentid,
'=');
121 stream >> argumentValue;
127 for(
int i = 0; args[i] != 0; i++)
131 int getNumObj(
void *data,
int *ierr)
135 return coordinates->getLocalLength();
138 int getDim(
void *data,
int *ierr)
144 void getObjList(
void *data,
int numGid,
int numLid,
146 int num_wgts,
float *obj_wgts,
int *ierr)
149 size_t localLen = coordinates->getLocalLength();
150 const zgno_t *ids = coordinates->getMap()->getNodeElementList().getRawPtr();
154 memcpy(gids, idsNonConst,
sizeof(
zgno_t) * localLen);
157 for (
size_t i=0; i < localLen; i++)
158 gids[i] = static_cast<zgno_t>(idsNonConst[i]);
162 float *wgts = obj_wgts;
163 for (
size_t i=0; i < localLen; i++)
164 for (
int w=0; w < num_wgts; w++)
165 *wgts++ = static_cast<float>(weights[w][i]);
169 void getCoords(
void *data,
int numGid,
int numLid,
171 int dim,
double *coords,
int *ierr)
175 double *val = coords;
176 const zscalar_t *x = coordinates->getData(0).getRawPtr();
177 const zscalar_t *y = coordinates->getData(1).getRawPtr();
178 const zscalar_t *z = coordinates->getData(2).getRawPtr();
179 for (
zlno_t i=0; i < numObj; i++){
180 *val++ =
static_cast<double>(x[i]);
181 *val++ =
static_cast<double>(y[i]);
182 *val++ =
static_cast<double>(z[i]);
195 ArrayRCP<zscalar_t> makeWeights(
196 const RCP<
const Teuchos::Comm<int> > & comm,
203 ArrayRCP<zscalar_t> wgtArray(wgts, 0, len,
true);
207 for (
zlno_t i=0; i < len; i++)
210 else if (how == roundRobin){
211 for (
int i=0; i < 10; i++){
213 for (
int j=i; j < len; j += 10)
217 else if (how == increasing){
219 for (
zlno_t i=0; i < len; i++)
230 const RCP<tMVector_t> getMeshCoordinates(
231 const RCP<
const Teuchos::Comm<int> > & comm,
234 int rank = comm->getRank();
235 int nprocs = comm->getSize();
237 double k = log(numGlobalCoords) / 3;
238 double xdimf = exp(k) + 0.5;
239 zgno_t xdim =
static_cast<int>(floor(xdimf));
241 zgno_t zdim = numGlobalCoords / (xdim*ydim);
242 zgno_t num=xdim*ydim*zdim;
243 zgno_t diff = numGlobalCoords - num;
247 if (zdim > xdim && zdim > ydim){
249 newdiff = diff - (xdim*ydim);
254 else if (ydim > xdim && ydim > zdim){
256 newdiff = diff - (xdim*zdim);
263 newdiff = diff - (ydim*zdim);
273 diff = numGlobalCoords - num;
275 diff /= -numGlobalCoords;
277 diff /= numGlobalCoords;
281 cout <<
"Warning: Difference " << diff*100 <<
" percent" << endl;
282 cout <<
"Mesh size: " << xdim <<
"x" << ydim <<
"x" <<
283 zdim <<
", " << num <<
" vertices." << endl;
288 zgno_t numLocalCoords = num / nprocs;
289 zgno_t leftOver = num % nprocs;
292 if (rank <= leftOver)
293 gid0 =
zgno_t(rank) * (numLocalCoords+1);
295 gid0 = (leftOver * (numLocalCoords+1)) +
296 ((
zgno_t(rank) - leftOver) * numLocalCoords);
301 zgno_t gid1 = gid0 + numLocalCoords;
306 ArrayRCP<zgno_t> idArray(ids, 0, numLocalCoords,
true);
308 for (
zgno_t i=gid0; i < gid1; i++)
311 RCP<const tMap_t> idMap = rcp(
312 new tMap_t(num, idArray.view(0, numLocalCoords), 0, comm));
319 ArrayRCP<zscalar_t> coordArray(x, 0, numLocalCoords*3,
true);
326 zgno_t xyPlane = xdim*ydim;
327 zgno_t zStart = gid0 / xyPlane;
328 zgno_t rem = gid0 % xyPlane;
335 for (
zscalar_t zval=zStart; next < numLocalCoords && zval < zdim; zval++){
336 for (
zscalar_t yval=yStart; next < numLocalCoords && yval < ydim; yval++){
337 for (
zscalar_t xval=xStart; next < numLocalCoords && xval < xdim; xval++){
348 ArrayView<const zscalar_t> xArray(x, numLocalCoords);
349 ArrayView<const zscalar_t> yArray(y, numLocalCoords);
350 ArrayView<const zscalar_t> zArray(z, numLocalCoords);
351 ArrayRCP<ArrayView<const zscalar_t> > coordinates =
352 arcp(
new ArrayView<const zscalar_t> [3], 0, 3);
353 coordinates[0] = xArray;
354 coordinates[1] = yArray;
355 coordinates[2] = zArray;
357 ArrayRCP<const ArrayView<const zscalar_t> > constCoords =
358 coordinates.getConst();
360 RCP<tMVector_t> meshCoords = rcp(
new tMVector_t(
361 idMap, constCoords.view(0,3), 3));
367 void getArgVals(
int argc,
char **argv,
int &numParts,
368 std::string ¶mFile){
370 for(
int i = 0; i < argc; ++i){
372 string identifier =
"";
373 long long int value = -1;
double fval = -1;
375 value = (
long long int) (fval);
376 if(identifier ==
"C"){
380 throw "Invalid argument at " + tmp;
383 else if(identifier ==
"PF"){
384 stringstream stream(stringstream::in | stringstream::out);
386 getline(stream, paramFile,
'=');
390 throw "Invalid argument at " + tmp;
397 void readGeoGenParams(
string paramFileName, Teuchos::ParameterList &geoparams,
const RCP<
const Teuchos::Comm<int> > & comm){
398 std::string input =
"";
400 for(
int i = 0; i < 25000; ++i){
403 if(comm->getRank() == 0){
404 fstream inParam(paramFileName.c_str());
406 std::string tmp =
"";
407 getline (inParam,tmp);
408 while (!inParam.eof()){
415 getline (inParam,tmp);
418 for (
size_t i = 0; i < input.size(); ++i){
424 int size = input.size();
430 comm->broadcast(0,
sizeof(
int), (
char*) &size);
431 comm->broadcast(0, size, inp);
433 istringstream inParam(inp);
435 getline (inParam,str);
436 while (!inParam.eof()){
438 size_t pos = str.find(
'=');
439 if(pos == string::npos){
440 throw "Invalid Line:" + str +
" in parameter file";
442 string paramname =
trim_copy(str.substr(0,pos));
443 string paramvalue =
trim_copy(str.substr(pos + 1));
444 geoparams.set(paramname, paramvalue);
446 getline (inParam,str);
450 int main(
int argc,
char *argv[])
454 Teuchos::GlobalMPISession session(&argc, &argv, NULL);
455 RCP<const Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();
456 int rank = comm->getRank();
457 int nprocs = comm->getSize();
459 MEMORY_CHECK(rank==0 || rank==nprocs-1,
"After initializing MPI");
462 cout <<
"Number of processes: " << nprocs << endl;
468 string memoryOn(
"memoryOn");
469 string memoryOff(
"memoryOff");
472 int numGlobalParts = 512 * 512;
473 string paramFile =
"p2.txt";
480 Teuchos::ParameterList geoparams(
"geo params");
483 #ifdef HAVE_ZOLTAN2_OMP 484 double begin = omp_get_wtime();
486 GeometricGenerator<zscalar_t, zlno_t, zgno_t, znode_t> *gg =
new GeometricGenerator<zscalar_t, zlno_t, zgno_t, znode_t>(geoparams,comm);
487 #ifdef HAVE_ZOLTAN2_OMP 488 double end = omp_get_wtime();
489 cout <<
"GeometricGen Time:" << end - begin << endl;
491 int coord_dim = gg->getCoordinateDimension();
492 int nWeights = gg->getNumWeights();
493 zlno_t numLocalPoints = gg->getNumLocalCoords();
494 zgno_t numGlobalPoints = gg->getNumGlobalCoords();
496 for(
int i = 0; i < coord_dim; ++i){
497 coords[i] =
new zscalar_t[numLocalPoints];
499 gg->getLocalCoordinatesCopy(coords);
503 for(
int i = 0; i < nWeights; ++i){
504 weight[i] =
new zscalar_t[numLocalPoints];
506 gg->getLocalWeightsCopy(weight);
509 zgno_t globalSize =
static_cast<zgno_t>(numGlobalPoints);
512 cout <<
"coord_dim:" << coord_dim <<
" nWeights:" << nWeights <<
" numLocalPoints:" << numLocalPoints <<
" numGlobalPoints:" << numGlobalPoints << endl;
514 CommandLineProcessor commandLine(
false,
true);
515 commandLine.setOption(
"size", &numGlobalPoints,
516 "Approximate number of global coordinates.");
517 commandLine.setOption(
"numParts", &numGlobalParts,
518 "Number of parts (default is one per proc).");
519 commandLine.setOption(
"numWeights", &nWeights,
520 "Number of weights per coordinate, zero implies uniform weights.");
521 commandLine.setOption(
"debug", &debugLevel,
"Zoltan1 debug level");
522 commandLine.setOption(
"timers", &dummyTimer,
"ignored");
523 commandLine.setOption(memoryOn.c_str(), memoryOff.c_str(), &doMemory,
524 "do memory profiling");
526 string balanceCount(
"balance_object_count");
527 string balanceWeight(
"balance_object_weight");
528 string mcnorm1(
"multicriteria_minimize_total_weight");
529 string mcnorm2(
"multicriteria_balance_total_maximum");
530 string mcnorm3(
"multicriteria_minimize_maximum_weight");
532 string objective(balanceWeight);
534 string doc(balanceCount);
535 doc.append(
": ignore weights\n");
537 doc.append(balanceWeight);
538 doc.append(
": balance on first weight\n");
541 doc.append(
": given multiple weights, balance their total.\n");
544 doc.append(
": given multiple weights, balance the maximum for each coordinate.\n");
547 doc.append(
": given multiple weights, balance the L2 norm of the weights.\n");
549 commandLine.setOption(
"objective", &objective, doc.c_str());
551 CommandLineProcessor::EParseCommandLineReturn rc =
552 commandLine.parse(argc, argv);
554 if (rc != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL){
555 if (rc == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED){
557 cout <<
"PASS" << endl;
562 cout <<
"FAIL" << endl;
572 RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
573 new Tpetra::Map<zlno_t, zgno_t, znode_t> (numGlobalPoints, numLocalPoints, 0, comm));
575 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
576 for (
int i=0; i < coord_dim; i++){
577 if(numLocalPoints > 0){
578 Teuchos::ArrayView<const zscalar_t> a(coords[i], numLocalPoints);
581 Teuchos::ArrayView<const zscalar_t> a;
586 coordinates = RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >(
587 new Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>( mp, coordView.view(0, coord_dim), coord_dim));
591 RCP<const tMVector_t> coordsConst = Teuchos::rcp_const_cast<
const tMVector_t>(coordinates);
596 size_t numLocalCoords = coordinates->getLocalLength();
600 for (
int p=0; p < nprocs; p++){
602 cout <<
"Rank " << rank <<
", " << numLocalCoords <<
"coords" << endl;
603 const zscalar_t *x = coordinates->getData(0).getRawPtr();
604 const zscalar_t *y = coordinates->getData(1).getRawPtr();
605 const zscalar_t *z = coordinates->getData(2).getRawPtr();
606 for (
zlno_t i=0; i < numLocalCoords; i++)
607 cout <<
" " << x[i] <<
" " << y[i] <<
" " << z[i] << endl;
616 weights = arcp(
new ArrayRCP<zscalar_t> [nWeights],
618 for(
int i = 0; i < nWeights; ++i){
623 MEMORY_CHECK(doMemory && rank==0,
"After creating input");
628 int aok = Zoltan_Initialize(argc, argv, &ver);
631 printf(
"sorry...\n");
635 struct Zoltan_Struct *zz;
636 zz = Zoltan_Create(MPI_COMM_WORLD);
638 Zoltan_Set_Param(zz,
"LB_METHOD",
"RCB");
639 Zoltan_Set_Param(zz,
"LB_APPROACH",
"PARTITION");
640 Zoltan_Set_Param(zz,
"CHECK_GEOM",
"0");
641 Zoltan_Set_Param(zz,
"NUM_GID_ENTRIES",
"1");
642 Zoltan_Set_Param(zz,
"NUM_LID_ENTRIES",
"0");
643 Zoltan_Set_Param(zz,
"RETURN_LISTS",
"ALL");
646 Zoltan_Set_Param(zz,
"IMBALANCE_TOL",
"1.0");
647 std::ostringstream oss;
648 oss << numGlobalParts;
649 Zoltan_Set_Param(zz,
"NUM_GLOBAL_PARTS", oss.str().c_str());
652 Zoltan_Set_Param(zz,
"DEBUG_LEVEL", oss.str().c_str());
654 if (objective != balanceCount){
657 Zoltan_Set_Param(zz,
"OBJ_WEIGHT_DIM", oss.str().c_str());
659 if (objective == mcnorm1)
660 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"1");
661 else if (objective == mcnorm2)
662 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"2");
663 else if (objective == mcnorm3)
664 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"3");
667 Zoltan_Set_Param(zz,
"OBJ_WEIGHT_DIM",
"0");
670 Zoltan_Set_Num_Obj_Fn(zz, getNumObj, NULL);
671 Zoltan_Set_Obj_List_Fn(zz, getObjList,NULL);
672 Zoltan_Set_Num_Geom_Fn(zz, getDim, NULL);
673 Zoltan_Set_Geom_Multi_Fn(zz, getCoords, NULL);
675 int changes, numGidEntries, numLidEntries, numImport, numExport;
676 zgno_t * importGlobalGids, * importLocalGids;
677 zgno_t * exportGlobalGids, * exportLocalGids;
678 int *importProcs, *importToPart, *exportProcs, *exportToPart;
680 MEMORY_CHECK(doMemory && rank==0,
"Before Zoltan_LB_Partition");
683 aok = Zoltan_LB_Partition(zz,
698 MEMORY_CHECK(doMemory && rank==0,
"After Zoltan_LB_Partition");
699 Zoltan_LB_Free_Part(importGlobalGids, importLocalGids, importProcs, importToPart);
700 Zoltan_LB_Free_Part(exportGlobalGids, exportLocalGids, exportProcs, exportToPart);
702 MEMORY_CHECK(doMemory && rank==0,
"After Zoltan_Destroy");
706 std::cout <<
"FAIL" << std::endl;
708 std::cout <<
"PASS" << std::endl;
716 int main(
int argc,
char *argv[])
718 std::cout <<
"Test did not run due to faulty configuration." << std::endl;
719 std::cout <<
"FAIL" << std::endl;
string trim_right_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP< const Teuchos::Comm< int > > &comm)
Defines the PartitioningSolution class.
common code used by tests
Defines the XpetraMultiVectorAdapter.
string trim_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
Defines the PartitioningSolutionQuality class.
string convert_to_string(char *args)
void getArgVals(int argc, char **argv, int &numParts, float &imbalance, string &pqParts, int &opt, std::string &fname, std::string &pfname, int &k, int &migration_check_option, int &migration_all_to_all_type, zscalar_t &migration_imbalance_cut_off, int &migration_processor_assignment_type, int &migration_doMigration_type, bool &test_boxes, bool &rectilinear)
string trim_left_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline)
Defines the PartitioningProblem class.
#define MEMORY_CHECK(iPrint, msg)