56 #include <Teuchos_CommandLineProcessor.hpp>
75 using Teuchos::ArrayView;
76 using Teuchos::ArrayRCP;
77 using Teuchos::CommandLineProcessor;
79 typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>
tMVector_t;
80 typedef Tpetra::Map<zlno_t, zgno_t, znode_t>
tMap_t;
82 static ArrayRCP<ArrayRCP<zscalar_t> >
weights;
90 const std::string& delimiters =
" \f\n\r\t\v" )
92 return s.substr( 0, s.find_last_not_of( delimiters ) + 1 );
97 const std::string& delimiters =
" \f\n\r\t\v" )
99 return s.substr( s.find_first_not_of( delimiters ) );
103 const std::string& s,
104 const std::string& delimiters =
" \f\n\r\t\v" )
110 bool getArgumentValue(std::string &argumentid,
double &argumentValue, std::string argumentline){
111 std::stringstream stream(std::stringstream::in | std::stringstream::out);
112 stream << argumentline;
113 getline(stream, argumentid,
'=');
117 stream >> argumentValue;
122 std::string tmp =
"";
123 for(
int i = 0; args[i] != 0; i++)
142 int num_wgts,
float *obj_wgts,
int *ierr)
150 memcpy(gids, idsNonConst,
sizeof(
zgno_t) * localLen);
153 for (
size_t i=0; i < localLen; i++)
154 gids[i] = static_cast<zgno_t>(idsNonConst[i]);
158 float *wgts = obj_wgts;
159 for (
size_t i=0; i < localLen; i++)
160 for (
int w=0; w < num_wgts; w++)
161 *wgts++ = static_cast<float>(
weights[w][i]);
167 int dim,
double *coords,
int *ierr)
171 double *val = coords;
175 for (
zlno_t i=0; i < numObj; i++){
176 *val++ =
static_cast<double>(x[i]);
177 *val++ =
static_cast<double>(y[i]);
178 *val++ =
static_cast<double>(z[i]);
192 const RCP<
const Teuchos::Comm<int> > & comm,
199 ArrayRCP<zscalar_t> wgtArray(wgts, 0, len,
true);
203 for (
zlno_t i=0; i < len; i++)
207 for (
int i=0; i < 10; i++){
209 for (
int j=i; j < len; j += 10)
215 for (
zlno_t i=0; i < len; i++)
227 const RCP<
const Teuchos::Comm<int> > & comm,
230 int rank = comm->getRank();
231 int nprocs = comm->getSize();
233 double k = log(numGlobalCoords) / 3;
234 double xdimf = exp(k) + 0.5;
235 zgno_t xdim =
static_cast<int>(floor(xdimf));
237 zgno_t zdim = numGlobalCoords / (xdim*ydim);
238 zgno_t num=xdim*ydim*zdim;
239 zgno_t diff = numGlobalCoords - num;
243 if (zdim > xdim && zdim > ydim){
245 newdiff = diff - (xdim*ydim);
250 else if (ydim > xdim && ydim > zdim){
252 newdiff = diff - (xdim*zdim);
259 newdiff = diff - (ydim*zdim);
269 diff = numGlobalCoords - num;
271 diff /= -numGlobalCoords;
273 diff /= numGlobalCoords;
277 std::cout <<
"Warning: Difference " << diff*100 <<
" percent" << std::endl;
278 std::cout <<
"Mesh size: " << xdim <<
"x" << ydim <<
"x" <<
279 zdim <<
", " << num <<
" vertices." << std::endl;
284 zgno_t numLocalCoords = num / nprocs;
285 zgno_t leftOver = num % nprocs;
288 if (rank <= leftOver)
289 gid0 =
zgno_t(rank) * (numLocalCoords+1);
291 gid0 = (leftOver * (numLocalCoords+1)) +
292 ((
zgno_t(rank) - leftOver) * numLocalCoords);
297 zgno_t gid1 = gid0 + numLocalCoords;
302 ArrayRCP<zgno_t> idArray(ids, 0, numLocalCoords,
true);
304 for (
zgno_t i=gid0; i < gid1; i++)
307 RCP<const tMap_t> idMap = rcp(
308 new tMap_t(num, idArray.view(0, numLocalCoords), 0, comm));
315 ArrayRCP<zscalar_t> coordArray(x, 0, numLocalCoords*3,
true);
322 zgno_t xyPlane = xdim*ydim;
323 zgno_t zStart = gid0 / xyPlane;
324 zgno_t rem = gid0 % xyPlane;
331 for (
zscalar_t zval=zStart; next < numLocalCoords && zval < zdim; zval++){
332 for (
zscalar_t yval=yStart; next < numLocalCoords && yval < ydim; yval++){
333 for (
zscalar_t xval=xStart; next < numLocalCoords && xval < xdim; xval++){
344 ArrayView<const zscalar_t> xArray(x, numLocalCoords);
345 ArrayView<const zscalar_t> yArray(y, numLocalCoords);
346 ArrayView<const zscalar_t> zArray(z, numLocalCoords);
347 ArrayRCP<ArrayView<const zscalar_t> >
coordinates =
348 arcp(
new ArrayView<const zscalar_t> [3], 0, 3);
349 coordinates[0] = xArray;
350 coordinates[1] = yArray;
351 coordinates[2] = zArray;
353 ArrayRCP<const ArrayView<const zscalar_t> > constCoords =
354 coordinates.getConst();
356 RCP<tMVector_t> meshCoords = rcp(
new tMVector_t(
357 idMap, constCoords.view(0,3), 3));
364 std::string ¶mFile){
366 for(
int i = 0; i < narg; ++i){
368 std::string identifier =
"";
369 long long int value = -1;
double fval = -1;
371 value = (
long long int) (fval);
372 if(identifier ==
"C"){
376 throw "Invalid argument at " + tmp;
379 else if(identifier ==
"PF"){
380 std::stringstream stream(std::stringstream::in | std::stringstream::out);
382 getline(stream, paramFile,
'=');
386 throw "Invalid argument at " + tmp;
393 void readGeoGenParams(std::string paramFileName, Teuchos::ParameterList &geoparams,
const RCP<
const Teuchos::Comm<int> > & comm){
394 std::string input =
"";
396 for(
int i = 0; i < 25000; ++i){
399 if(comm->getRank() == 0){
400 std::fstream inParam(paramFileName.c_str());
402 std::string tmp =
"";
403 getline (inParam,tmp);
404 while (!inParam.eof()){
411 getline (inParam,tmp);
414 for (
size_t i = 0; i < input.size(); ++i){
420 int size = input.size();
426 comm->broadcast(0,
sizeof(
int), (
char*) &size);
427 comm->broadcast(0, size, inp);
429 std::istringstream inParam(inp);
431 getline (inParam,str);
432 while (!inParam.eof()){
434 size_t pos = str.find(
'=');
435 if(pos == std::string::npos){
436 throw "Invalid Line:" + str +
" in parameter file";
438 std::string paramname =
trim_copy(str.substr(0,pos));
439 std::string paramvalue =
trim_copy(str.substr(pos + 1));
440 geoparams.set(paramname, paramvalue);
442 getline (inParam,str);
446 int main(
int narg,
char *arg[])
449 Tpetra::ScopeGuard tscope(&narg, &arg);
450 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
452 int rank = comm->getRank();
453 int nprocs = comm->getSize();
455 MEMORY_CHECK(rank==0 || rank==nprocs-1,
"After initializing MPI");
458 std::cout <<
"Number of processes: " << nprocs << std::endl;
464 std::string memoryOn(
"memoryOn");
465 std::string memoryOff(
"memoryOff");
468 int numGlobalParts = 512 * 512;
469 std::string paramFile =
"p2.txt";
476 Teuchos::ParameterList geoparams(
"geo params");
479 #ifdef HAVE_ZOLTAN2_OMP
480 double begin = omp_get_wtime();
482 GeometricGenerator<zscalar_t, zlno_t, zgno_t, znode_t> *gg =
new GeometricGenerator<zscalar_t, zlno_t, zgno_t, znode_t>(geoparams,comm);
483 #ifdef HAVE_ZOLTAN2_OMP
484 double end = omp_get_wtime();
485 std::cout <<
"GeometricGen Time:" << end - begin << std::endl;
487 int coord_dim = gg->getCoordinateDimension();
488 int nWeights = gg->getNumWeights();
489 zlno_t numLocalPoints = gg->getNumLocalCoords();
490 zgno_t numGlobalPoints = gg->getNumGlobalCoords();
492 for(
int i = 0; i < coord_dim; ++i){
493 coords[i] =
new zscalar_t[numLocalPoints];
495 gg->getLocalCoordinatesCopy(coords);
499 for(
int i = 0; i < nWeights; ++i){
500 weight[i] =
new zscalar_t[numLocalPoints];
502 gg->getLocalWeightsCopy(weight);
505 zgno_t globalSize =
static_cast<zgno_t>(numGlobalPoints);
508 std::cout <<
"coord_dim:" << coord_dim <<
" nWeights:" << nWeights <<
" numLocalPoints:" << numLocalPoints <<
" numGlobalPoints:" << numGlobalPoints << std::endl;
510 CommandLineProcessor commandLine(
false,
true);
511 commandLine.setOption(
"size", &numGlobalPoints,
512 "Approximate number of global coordinates.");
513 commandLine.setOption(
"numParts", &numGlobalParts,
514 "Number of parts (default is one per proc).");
515 commandLine.setOption(
"numWeights", &nWeights,
516 "Number of weights per coordinate, zero implies uniform weights.");
517 commandLine.setOption(
"debug", &debugLevel,
"Zoltan1 debug level");
518 commandLine.setOption(
"timers", &dummyTimer,
"ignored");
519 commandLine.setOption(memoryOn.c_str(), memoryOff.c_str(), &doMemory,
520 "do memory profiling");
522 std::string balanceCount(
"balance_object_count");
523 std::string balanceWeight(
"balance_object_weight");
524 std::string mcnorm1(
"multicriteria_minimize_total_weight");
525 std::string mcnorm2(
"multicriteria_balance_total_maximum");
526 std::string mcnorm3(
"multicriteria_minimize_maximum_weight");
528 std::string objective(balanceWeight);
530 std::string doc(balanceCount);
531 doc.append(
": ignore weights\n");
533 doc.append(balanceWeight);
534 doc.append(
": balance on first weight\n");
537 doc.append(
": given multiple weights, balance their total.\n");
540 doc.append(
": given multiple weights, balance the maximum for each coordinate.\n");
543 doc.append(
": given multiple weights, balance the L2 norm of the weights.\n");
545 commandLine.setOption(
"objective", &objective, doc.c_str());
547 CommandLineProcessor::EParseCommandLineReturn rc =
548 commandLine.parse(narg, arg);
550 if (rc != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL){
551 if (rc == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED){
553 std::cout <<
"PASS" << std::endl;
558 std::cout <<
"FAIL" << std::endl;
568 RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
569 new Tpetra::Map<zlno_t, zgno_t, znode_t> (numGlobalPoints, numLocalPoints, 0, comm));
571 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
572 for (
int i=0; i < coord_dim; i++){
573 if(numLocalPoints > 0){
574 Teuchos::ArrayView<const zscalar_t> a(coords[i], numLocalPoints);
577 Teuchos::ArrayView<const zscalar_t> a;
582 coordinates = RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >(
583 new Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>( mp, coordView.view(0, coord_dim), coord_dim));
592 size_t numLocalCoords =
coordinates->getLocalLength();
596 for (
int p=0; p < nprocs; p++){
598 std::cout <<
"Rank " << rank <<
", " << numLocalCoords <<
"coords" << std::endl;
602 for (
zlno_t i=0; i < numLocalCoords; i++)
603 std::cout <<
" " << x[i] <<
" " << y[i] <<
" " << z[i] << std::endl;
612 weights = arcp(
new ArrayRCP<zscalar_t> [nWeights],
614 for(
int i = 0; i < nWeights; ++i){
619 MEMORY_CHECK(doMemory && rank==0,
"After creating input");
624 int aok = Zoltan_Initialize(narg, arg, &ver);
627 printf(
"sorry...\n");
631 struct Zoltan_Struct *zz;
632 zz = Zoltan_Create(MPI_COMM_WORLD);
634 Zoltan_Set_Param(zz,
"LB_METHOD",
"RCB");
635 Zoltan_Set_Param(zz,
"LB_APPROACH",
"PARTITION");
636 Zoltan_Set_Param(zz,
"CHECK_GEOM",
"0");
637 Zoltan_Set_Param(zz,
"NUM_GID_ENTRIES",
"1");
638 Zoltan_Set_Param(zz,
"NUM_LID_ENTRIES",
"0");
639 Zoltan_Set_Param(zz,
"RETURN_LISTS",
"ALL");
642 Zoltan_Set_Param(zz,
"IMBALANCE_TOL",
"1.0");
643 std::ostringstream oss;
644 oss << numGlobalParts;
645 Zoltan_Set_Param(zz,
"NUM_GLOBAL_PARTS", oss.str().c_str());
648 Zoltan_Set_Param(zz,
"DEBUG_LEVEL", oss.str().c_str());
650 if (objective != balanceCount){
653 Zoltan_Set_Param(zz,
"OBJ_WEIGHT_DIM", oss.str().c_str());
655 if (objective == mcnorm1)
656 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"1");
657 else if (objective == mcnorm2)
658 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"2");
659 else if (objective == mcnorm3)
660 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"3");
663 Zoltan_Set_Param(zz,
"OBJ_WEIGHT_DIM",
"0");
666 Zoltan_Set_Num_Obj_Fn(zz,
getNumObj, NULL);
668 Zoltan_Set_Num_Geom_Fn(zz,
getDim, NULL);
669 Zoltan_Set_Geom_Multi_Fn(zz,
getCoords, NULL);
671 int changes, numGidEntries, numLidEntries, numImport, numExport;
672 zgno_t * importGlobalGids, * importLocalGids;
673 zgno_t * exportGlobalGids, * exportLocalGids;
674 int *importProcs, *importToPart, *exportProcs, *exportToPart;
676 MEMORY_CHECK(doMemory && rank==0,
"Before Zoltan_LB_Partition");
679 aok = Zoltan_LB_Partition(zz,
694 MEMORY_CHECK(doMemory && rank==0,
"After Zoltan_LB_Partition");
695 Zoltan_LB_Free_Part(importGlobalGids, importLocalGids, importProcs, importToPart);
696 Zoltan_LB_Free_Part(exportGlobalGids, exportLocalGids, exportProcs, exportToPart);
698 MEMORY_CHECK(doMemory && rank==0,
"After Zoltan_Destroy");
702 std::cout <<
"FAIL" << std::endl;
704 std::cout <<
"PASS" << 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)
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")
Defines the EvaluatePartition class.
string convert_to_string(char *args)
string trim_left_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
void getArgVals(int narg, char **arg, 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, int &mj_premigration_option, int &mj_coordinate_cutoff)
bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline)
Defines the PartitioningProblem class.
#define MEMORY_CHECK(iPrint, msg)