20 #include <Teuchos_CommandLineProcessor.hpp>
39 using Teuchos::ArrayView;
40 using Teuchos::ArrayRCP;
41 using Teuchos::CommandLineProcessor;
43 typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>
tMVector_t;
44 typedef Tpetra::Map<zlno_t, zgno_t, znode_t>
tMap_t;
46 static ArrayRCP<ArrayRCP<zscalar_t> >
weights;
54 const std::string& delimiters =
" \f\n\r\t\v" )
56 return s.substr( 0, s.find_last_not_of( delimiters ) + 1 );
61 const std::string& delimiters =
" \f\n\r\t\v" )
63 return s.substr( s.find_first_not_of( delimiters ) );
68 const std::string& delimiters =
" \f\n\r\t\v" )
74 bool getArgumentValue(std::string &argumentid,
double &argumentValue, std::string argumentline){
75 std::stringstream stream(std::stringstream::in | std::stringstream::out);
76 stream << argumentline;
77 getline(stream, argumentid,
'=');
81 stream >> argumentValue;
87 for(
int i = 0; args[i] != 0; i++)
106 int num_wgts,
float *obj_wgts,
int *ierr)
114 memcpy(gids, idsNonConst,
sizeof(
zgno_t) * localLen);
117 for (
size_t i=0; i < localLen; i++)
118 gids[i] = static_cast<zgno_t>(idsNonConst[i]);
122 float *wgts = obj_wgts;
123 for (
size_t i=0; i < localLen; i++)
124 for (
int w=0; w < num_wgts; w++)
125 *wgts++ = static_cast<float>(
weights[w][i]);
131 int dim,
double *coords,
int *ierr)
135 double *val = coords;
139 for (
zlno_t i=0; i < numObj; i++){
140 *val++ =
static_cast<double>(x[i]);
141 *val++ =
static_cast<double>(y[i]);
142 *val++ =
static_cast<double>(z[i]);
156 const RCP<
const Teuchos::Comm<int> > & comm,
163 ArrayRCP<zscalar_t> wgtArray(wgts, 0, len,
true);
167 for (
zlno_t i=0; i < len; i++)
171 for (
int i=0; i < 10; i++){
173 for (
int j=i; j < len; j += 10)
179 for (
zlno_t i=0; i < len; i++)
191 const RCP<
const Teuchos::Comm<int> > & comm,
194 int rank = comm->getRank();
195 int nprocs = comm->getSize();
197 double k = log(numGlobalCoords) / 3;
198 double xdimf = exp(k) + 0.5;
199 zgno_t xdim =
static_cast<int>(floor(xdimf));
201 zgno_t zdim = numGlobalCoords / (xdim*ydim);
202 zgno_t num=xdim*ydim*zdim;
203 zgno_t diff = numGlobalCoords - num;
207 if (zdim > xdim && zdim > ydim){
209 newdiff = diff - (xdim*ydim);
214 else if (ydim > xdim && ydim > zdim){
216 newdiff = diff - (xdim*zdim);
223 newdiff = diff - (ydim*zdim);
233 diff = numGlobalCoords - num;
235 diff /= -numGlobalCoords;
237 diff /= numGlobalCoords;
241 std::cout <<
"Warning: Difference " << diff*100 <<
" percent" << std::endl;
242 std::cout <<
"Mesh size: " << xdim <<
"x" << ydim <<
"x" <<
243 zdim <<
", " << num <<
" vertices." << std::endl;
248 zgno_t numLocalCoords = num / nprocs;
249 zgno_t leftOver = num % nprocs;
252 if (rank <= leftOver)
253 gid0 =
zgno_t(rank) * (numLocalCoords+1);
255 gid0 = (leftOver * (numLocalCoords+1)) +
256 ((
zgno_t(rank) - leftOver) * numLocalCoords);
261 zgno_t gid1 = gid0 + numLocalCoords;
266 ArrayRCP<zgno_t> idArray(ids, 0, numLocalCoords,
true);
268 for (
zgno_t i=gid0; i < gid1; i++)
271 RCP<const tMap_t> idMap = rcp(
272 new tMap_t(num, idArray.view(0, numLocalCoords), 0, comm));
279 ArrayRCP<zscalar_t> coordArray(x, 0, numLocalCoords*3,
true);
286 zgno_t xyPlane = xdim*ydim;
287 zgno_t zStart = gid0 / xyPlane;
288 zgno_t rem = gid0 % xyPlane;
295 for (
zscalar_t zval=zStart; next < numLocalCoords && zval < zdim; zval++){
296 for (
zscalar_t yval=yStart; next < numLocalCoords && yval < ydim; yval++){
297 for (
zscalar_t xval=xStart; next < numLocalCoords && xval < xdim; xval++){
308 ArrayView<const zscalar_t> xArray(x, numLocalCoords);
309 ArrayView<const zscalar_t> yArray(y, numLocalCoords);
310 ArrayView<const zscalar_t> zArray(z, numLocalCoords);
311 ArrayRCP<ArrayView<const zscalar_t> >
coordinates =
312 arcp(
new ArrayView<const zscalar_t> [3], 0, 3);
313 coordinates[0] = xArray;
314 coordinates[1] = yArray;
315 coordinates[2] = zArray;
317 ArrayRCP<const ArrayView<const zscalar_t> > constCoords =
318 coordinates.getConst();
320 RCP<tMVector_t> meshCoords = rcp(
new tMVector_t(
321 idMap, constCoords.view(0,3), 3));
328 std::string ¶mFile){
330 for(
int i = 0; i < narg; ++i){
332 std::string identifier =
"";
333 long long int value = -1;
double fval = -1;
335 value = (
long long int) (fval);
336 if(identifier ==
"C"){
340 throw "Invalid argument at " + tmp;
343 else if(identifier ==
"PF"){
344 std::stringstream stream(std::stringstream::in | std::stringstream::out);
346 getline(stream, paramFile,
'=');
350 throw "Invalid argument at " + tmp;
357 void readGeoGenParams(std::string paramFileName, Teuchos::ParameterList &geoparams,
const RCP<
const Teuchos::Comm<int> > & comm){
358 std::string input =
"";
360 for(
int i = 0; i < 25000; ++i){
363 if(comm->getRank() == 0){
364 std::fstream inParam(paramFileName.c_str());
366 std::string tmp =
"";
367 getline (inParam,tmp);
368 while (!inParam.eof()){
375 getline (inParam,tmp);
378 for (
size_t i = 0; i < input.size(); ++i){
384 int size = input.size();
390 comm->broadcast(0,
sizeof(
int), (
char*) &size);
391 comm->broadcast(0, size, inp);
393 std::istringstream inParam(inp);
395 getline (inParam,str);
396 while (!inParam.eof()){
398 size_t pos = str.find(
'=');
399 if(pos == std::string::npos){
400 throw "Invalid Line:" + str +
" in parameter file";
402 std::string paramname =
trim_copy(str.substr(0,pos));
403 std::string paramvalue =
trim_copy(str.substr(pos + 1));
404 geoparams.set(paramname, paramvalue);
406 getline (inParam,str);
410 int main(
int narg,
char *arg[])
413 Tpetra::ScopeGuard tscope(&narg, &arg);
414 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
416 int rank = comm->getRank();
417 int nprocs = comm->getSize();
419 MEMORY_CHECK(rank==0 || rank==nprocs-1,
"After initializing MPI");
422 std::cout <<
"Number of processes: " << nprocs << std::endl;
428 std::string memoryOn(
"memoryOn");
429 std::string memoryOff(
"memoryOff");
432 int numGlobalParts = 512 * 512;
433 std::string paramFile =
"p2.txt";
440 Teuchos::ParameterList geoparams(
"geo params");
443 #ifdef HAVE_ZOLTAN2_OMP
444 double begin = omp_get_wtime();
446 GeometricGenerator<zscalar_t, zlno_t, zgno_t, znode_t> *gg =
new GeometricGenerator<zscalar_t, zlno_t, zgno_t, znode_t>(geoparams,comm);
447 #ifdef HAVE_ZOLTAN2_OMP
448 double end = omp_get_wtime();
449 std::cout <<
"GeometricGen Time:" << end - begin << std::endl;
451 int coord_dim = gg->getCoordinateDimension();
452 int nWeights = gg->getNumWeights();
453 zlno_t numLocalPoints = gg->getNumLocalCoords();
454 zgno_t numGlobalPoints = gg->getNumGlobalCoords();
456 for(
int i = 0; i < coord_dim; ++i){
457 coords[i] =
new zscalar_t[numLocalPoints];
459 gg->getLocalCoordinatesCopy(coords);
463 for(
int i = 0; i < nWeights; ++i){
464 weight[i] =
new zscalar_t[numLocalPoints];
466 gg->getLocalWeightsCopy(weight);
469 zgno_t globalSize =
static_cast<zgno_t>(numGlobalPoints);
472 std::cout <<
"coord_dim:" << coord_dim <<
" nWeights:" << nWeights <<
" numLocalPoints:" << numLocalPoints <<
" numGlobalPoints:" << numGlobalPoints << std::endl;
474 CommandLineProcessor commandLine(
false,
true);
475 commandLine.setOption(
"size", &numGlobalPoints,
476 "Approximate number of global coordinates.");
477 commandLine.setOption(
"numParts", &numGlobalParts,
478 "Number of parts (default is one per proc).");
479 commandLine.setOption(
"numWeights", &nWeights,
480 "Number of weights per coordinate, zero implies uniform weights.");
481 commandLine.setOption(
"debug", &debugLevel,
"Zoltan1 debug level");
482 commandLine.setOption(
"timers", &dummyTimer,
"ignored");
483 commandLine.setOption(memoryOn.c_str(), memoryOff.c_str(), &doMemory,
484 "do memory profiling");
486 std::string balanceCount(
"balance_object_count");
487 std::string balanceWeight(
"balance_object_weight");
488 std::string mcnorm1(
"multicriteria_minimize_total_weight");
489 std::string mcnorm2(
"multicriteria_balance_total_maximum");
490 std::string mcnorm3(
"multicriteria_minimize_maximum_weight");
492 std::string objective(balanceWeight);
494 std::string doc(balanceCount);
495 doc.append(
": ignore weights\n");
497 doc.append(balanceWeight);
498 doc.append(
": balance on first weight\n");
501 doc.append(
": given multiple weights, balance their total.\n");
504 doc.append(
": given multiple weights, balance the maximum for each coordinate.\n");
507 doc.append(
": given multiple weights, balance the L2 norm of the weights.\n");
509 commandLine.setOption(
"objective", &objective, doc.c_str());
511 CommandLineProcessor::EParseCommandLineReturn rc =
512 commandLine.parse(narg, arg);
514 if (rc != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL){
515 if (rc == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED){
517 std::cout <<
"PASS" << std::endl;
522 std::cout <<
"FAIL" << std::endl;
532 RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
533 new Tpetra::Map<zlno_t, zgno_t, znode_t> (numGlobalPoints, numLocalPoints, 0, comm));
535 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
536 for (
int i=0; i < coord_dim; i++){
537 if(numLocalPoints > 0){
538 Teuchos::ArrayView<const zscalar_t> a(coords[i], numLocalPoints);
541 Teuchos::ArrayView<const zscalar_t> a;
546 coordinates = RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >(
547 new Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>( mp, coordView.view(0, coord_dim), coord_dim));
556 size_t numLocalCoords =
coordinates->getLocalLength();
560 for (
int p=0; p < nprocs; p++){
562 std::cout <<
"Rank " << rank <<
", " << numLocalCoords <<
"coords" << std::endl;
566 for (
zlno_t i=0; i < numLocalCoords; i++)
567 std::cout <<
" " << x[i] <<
" " << y[i] <<
" " << z[i] << std::endl;
576 weights = arcp(
new ArrayRCP<zscalar_t> [nWeights],
578 for(
int i = 0; i < nWeights; ++i){
583 MEMORY_CHECK(doMemory && rank==0,
"After creating input");
588 int aok = Zoltan_Initialize(narg, arg, &ver);
591 printf(
"sorry...\n");
595 struct Zoltan_Struct *zz;
596 zz = Zoltan_Create(MPI_COMM_WORLD);
598 Zoltan_Set_Param(zz,
"LB_METHOD",
"RCB");
599 Zoltan_Set_Param(zz,
"LB_APPROACH",
"PARTITION");
600 Zoltan_Set_Param(zz,
"CHECK_GEOM",
"0");
601 Zoltan_Set_Param(zz,
"NUM_GID_ENTRIES",
"1");
602 Zoltan_Set_Param(zz,
"NUM_LID_ENTRIES",
"0");
603 Zoltan_Set_Param(zz,
"RETURN_LISTS",
"ALL");
606 Zoltan_Set_Param(zz,
"IMBALANCE_TOL",
"1.0");
607 std::ostringstream oss;
608 oss << numGlobalParts;
609 Zoltan_Set_Param(zz,
"NUM_GLOBAL_PARTS", oss.str().c_str());
612 Zoltan_Set_Param(zz,
"DEBUG_LEVEL", oss.str().c_str());
614 if (objective != balanceCount){
617 Zoltan_Set_Param(zz,
"OBJ_WEIGHT_DIM", oss.str().c_str());
619 if (objective == mcnorm1)
620 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"1");
621 else if (objective == mcnorm2)
622 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"2");
623 else if (objective == mcnorm3)
624 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"3");
627 Zoltan_Set_Param(zz,
"OBJ_WEIGHT_DIM",
"0");
630 Zoltan_Set_Num_Obj_Fn(zz,
getNumObj, NULL);
632 Zoltan_Set_Num_Geom_Fn(zz,
getDim, NULL);
633 Zoltan_Set_Geom_Multi_Fn(zz,
getCoords, NULL);
635 int changes, numGidEntries, numLidEntries, numImport, numExport;
636 zgno_t * importGlobalGids, * importLocalGids;
637 zgno_t * exportGlobalGids, * exportLocalGids;
638 int *importProcs, *importToPart, *exportProcs, *exportToPart;
640 MEMORY_CHECK(doMemory && rank==0,
"Before Zoltan_LB_Partition");
643 aok = Zoltan_LB_Partition(zz,
658 MEMORY_CHECK(doMemory && rank==0,
"After Zoltan_LB_Partition");
659 Zoltan_LB_Free_Part(importGlobalGids, importLocalGids, importProcs, importToPart);
660 Zoltan_LB_Free_Part(exportGlobalGids, exportLocalGids, exportProcs, exportToPart);
662 MEMORY_CHECK(doMemory && rank==0,
"After Zoltan_Destroy");
666 std::cout <<
"FAIL" << std::endl;
668 std::cout <<
"PASS" << std::endl;
void getCoords(void *data, int numGid, int numLid, int numObj, ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids, int dim, double *coords_, int *ierr)
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)
int main(int narg, char **arg)
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")
int getNumObj(void *data, int *ierr)
Defines the EvaluatePartition class.
int getDim(void *data, int *ierr)
void getObjList(void *data, int numGid, int numLid, ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids, int num_wgts, float *obj_wgts, int *ierr)
void getArgVals(int narg, char **arg, int &numTeams, 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 &uvm, bool &print_details, bool &test_boxes, bool &rectilinear, int &mj_premigration_option, int &mj_coordinate_cutoff)
Tpetra::Map::local_ordinal_type zlno_t
string convert_to_string(char *args)
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.
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
Tpetra::Map::global_ordinal_type zgno_t
#define MEMORY_CHECK(iPrint, msg)