Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
scaling/rcbPerformanceZ1.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Zoltan2: A package of combinatorial algorithms for scientific computing
4 //
5 // Copyright 2012 NTESS and the Zoltan2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
16 #include "Zoltan2_config.h"
17 #include <zoltan.h>
18 
19 #include <Zoltan2_Util.hpp>
20 
21 #include <Teuchos_RCP.hpp>
22 #include <Teuchos_ArrayView.hpp>
23 #include <Teuchos_ParameterList.hpp>
24 #include <Teuchos_DefaultComm.hpp>
25 #include <Teuchos_Comm.hpp>
26 #include <Teuchos_CommHelpers.hpp>
27 
28 #include <Zoltan2_TestHelpers.hpp>
29 #include <Tpetra_MultiVector.hpp>
30 #include <Tpetra_KokkosCompat_DefaultNode.hpp>
31 #include <GeometricGenerator.hpp>
32 
33 #include <vector>
34 #include <string>
35 #include <ostream>
36 #include <sstream>
37 #include <fstream>
38 using std::string;
39 using std::vector;
40 using std::bad_alloc;
41 using Teuchos::RCP;
42 using Teuchos::rcp;
43 using Teuchos::Comm;
44 using Teuchos::ArrayView;
45 using Teuchos::CommandLineProcessor;
46 
47 typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> tMVector_t;
48 typedef Tpetra::Map<zlno_t, zgno_t, znode_t> tMap_t;
49 typedef tMap_t::node_type znode_t;
50 
52 // Data structure for data
53 typedef struct dots {
54  vector<vector<float> > weights;
56 } DOTS;
57 
58 const char param_comment = '#';
59 
61  const string& s,
62  const string& delimiters = " \f\n\r\t\v" )
63 {
64  return s.substr( 0, s.find_last_not_of( delimiters ) + 1 );
65 }
66 
68  const string& s,
69  const string& delimiters = " \f\n\r\t\v" )
70 {
71  return s.substr( s.find_first_not_of( delimiters ) );
72 }
73 
74 string trim_copy(
75  const string& s,
76  const string& delimiters = " \f\n\r\t\v" )
77 {
78  return trim_left_copy( trim_right_copy( s, delimiters ), delimiters );
79 }
80 
81 void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP<const Teuchos::Comm<int> > & comm){
82  std::string input = "";
83  char inp[25000];
84  for(int i = 0; i < 25000; ++i){
85  inp[i] = 0;
86  }
87 
88  bool fail = false;
89  if(comm->getRank() == 0){
90 
91  std::fstream inParam(paramFileName.c_str());
92  if (inParam.fail())
93  {
94  fail = true;
95  }
96  if(!fail)
97  {
98  std::string tmp = "";
99  getline (inParam,tmp);
100  while (!inParam.eof()){
101  if(tmp != ""){
102  tmp = trim_copy(tmp);
103  if(tmp != ""){
104  input += tmp + "\n";
105  }
106  }
107  getline (inParam,tmp);
108  }
109  inParam.close();
110  for (size_t i = 0; i < input.size(); ++i){
111  inp[i] = input[i];
112  }
113  }
114  }
115 
116 
117 
118  int size = input.size();
119  if(fail){
120  size = -1;
121  }
122  comm->broadcast(0, sizeof(int), (char*) &size);
123  if(size == -1){
124  throw "File " + paramFileName + " cannot be opened.";
125  }
126  comm->broadcast(0, size, inp);
127  std::istringstream inParam(inp);
128  string str;
129  getline (inParam,str);
130  while (!inParam.eof()){
131  if(str[0] != param_comment){
132  size_t pos = str.find('=');
133  if(pos == string::npos){
134  throw "Invalid Line:" + str + " in parameter file";
135  }
136  string paramname = trim_copy(str.substr(0,pos));
137  string paramvalue = trim_copy(str.substr(pos + 1));
138  geoparams.set(paramname, paramvalue);
139  }
140  getline (inParam,str);
141  }
142 }
143 
144 
146 // Zoltan1 query functions
147 
148 int getNumObj(void *data, int *ierr)
149 {
150  *ierr = 0;
151  DOTS *dots = (DOTS *) data;
152  return dots->coordinates->getLocalLength();
153 }
154 
156 int getDim(void *data, int *ierr)
157 {
158  *ierr = 0;
159  DOTS *dots = (DOTS *) data;
160  int dim = dots->coordinates->getNumVectors();
161 
162  return dim;
163 }
164 
166 void getObjList(void *data, int numGid, int numLid,
167  ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids,
168  int num_wgts, float *obj_wgts, int *ierr)
169 {
170  *ierr = 0;
171  DOTS *dots = (DOTS *) data;
172 
173  size_t localLen = dots->coordinates->getLocalLength();
174  const zgno_t *ids =
175  dots->coordinates->getMap()->getLocalElementList().getRawPtr();
176 
177  if (sizeof(ZOLTAN_ID_TYPE) == sizeof(zgno_t))
178  memcpy(gids, ids, sizeof(ZOLTAN_ID_TYPE) * localLen);
179  else
180  for (size_t i=0; i < localLen; i++)
181  gids[i] = static_cast<ZOLTAN_ID_TYPE>(ids[i]);
182 
183  if (num_wgts > 0){
184  float *wgts = obj_wgts;
185  for (size_t i=0; i < localLen; i++)
186  for (int w=0; w < num_wgts; w++)
187  *wgts++ = dots->weights[w][i];
188  }
189 }
190 
192 void getCoords(void *data, int numGid, int numLid,
193  int numObj, ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids,
194  int dim, double *coords, int *ierr)
195 {
196  // I know that Zoltan asks for coordinates in gid order.
197  if (dim == 3){
198  *ierr = 0;
199  DOTS *dots = (DOTS *) data;
200  double *val = coords;
201  const zscalar_t *x = dots->coordinates->getData(0).getRawPtr();
202  const zscalar_t *y = dots->coordinates->getData(1).getRawPtr();
203  const zscalar_t *z = dots->coordinates->getData(2).getRawPtr();
204  for (int i=0; i < numObj; i++){
205  *val++ = static_cast<double>(x[i]);
206  *val++ = static_cast<double>(y[i]);
207  *val++ = static_cast<double>(z[i]);
208  }
209  }
210  else {
211  *ierr = 0;
212  DOTS *dots = (DOTS *) data;
213  double *val = coords;
214  const zscalar_t *x = dots->coordinates->getData(0).getRawPtr();
215  const zscalar_t *y = dots->coordinates->getData(1).getRawPtr();
216  for (int i=0; i < numObj; i++){
217  *val++ = static_cast<double>(x[i]);
218  *val++ = static_cast<double>(y[i]);
219  }
220 
221 
222  }
223 }
224 
225 
227 
233 };
234 
236  const RCP<const Teuchos::Comm<int> > & comm,
237  vector<float> &wgts, weightTypes how, float scale, int rank)
238 {
239  zlno_t len = wgts.size();
240  if (how == upDown){
241  float val = scale + rank%2;
242  for (zlno_t i=0; i < len; i++)
243  wgts[i] = val;
244  }
245  else if (how == roundRobin){
246  for (int i=0; i < 10; i++){
247  float val = (i + 10)*scale;
248  for (zlno_t j=i; j < len; j += 10)
249  wgts[j] = val;
250  }
251  }
252  else if (how == increasing){
253  float val = scale + rank;
254  for (zlno_t i=0; i < len; i++)
255  wgts[i] = val;
256  }
257 }
258 
260 /* Create a mesh of approximately the desired size.
261  *
262  * We want 3 dimensions close to equal in length.
263  */
265  const RCP<const Teuchos::Comm<int> > & comm,
266  zgno_t numGlobalCoords)
267 {
268  int rank = comm->getRank();
269  int nprocs = comm->getSize();
270 
271  double k = log(numGlobalCoords) / 3;
272  double xdimf = exp(k) + 0.5;
273  ssize_t xdim = static_cast<ssize_t>(floor(xdimf));
274  ssize_t ydim = xdim;
275  ssize_t zdim = numGlobalCoords / (xdim*ydim);
276  ssize_t num=xdim*ydim*zdim;
277  ssize_t diff = numGlobalCoords - num;
278  ssize_t newdiff = 0;
279 
280  while (diff > 0){
281  if (zdim > xdim && zdim > ydim){
282  zdim++;
283  newdiff = diff - (xdim*ydim);
284  if (newdiff < 0)
285  if (diff < -newdiff)
286  zdim--;
287  }
288  else if (ydim > xdim && ydim > zdim){
289  ydim++;
290  newdiff = diff - (xdim*zdim);
291  if (newdiff < 0)
292  if (diff < -newdiff)
293  ydim--;
294  }
295  else{
296  xdim++;
297  newdiff = diff - (ydim*zdim);
298  if (newdiff < 0)
299  if (diff < -newdiff)
300  xdim--;
301  }
302 
303  diff = newdiff;
304  }
305 
306  num=xdim*ydim*zdim;
307  diff = numGlobalCoords - num;
308  if (diff < 0)
309  diff /= -numGlobalCoords;
310  else
311  diff /= numGlobalCoords;
312 
313  if (rank == 0){
314  if (diff > .01)
315  std::cout << "Warning: Difference " << diff*100 << " percent" << std::endl;
316  std::cout << "Mesh size: " << xdim << "x" << ydim << "x" <<
317  zdim << ", " << num << " vertices." << std::endl;
318  }
319 
320  // Divide coordinates.
321 
322  ssize_t numLocalCoords = num / nprocs;
323  ssize_t leftOver = num % nprocs;
324  ssize_t gid0 = 0;
325 
326  if (rank <= leftOver)
327  gid0 = rank * (numLocalCoords+1);
328  else
329  gid0 = (leftOver * (numLocalCoords+1)) +
330  ((rank - leftOver) * numLocalCoords);
331 
332  if (rank < leftOver)
333  numLocalCoords++;
334 
335  ssize_t gid1 = gid0 + numLocalCoords;
336 
337  zgno_t *ids = new zgno_t[numLocalCoords];
338  if (!ids)
339  throw bad_alloc();
340  ArrayView<zgno_t> idArray(ids, numLocalCoords);
341  zgno_t *idptr = ids;
342 
343  for (ssize_t i=gid0; i < gid1; i++)
344  *idptr++ = zgno_t(i);
345 
346  RCP<const tMap_t> idMap = rcp(new tMap_t(num, idArray, 0, comm));
347 
348  delete [] ids;
349 
350  // Create a Tpetra::MultiVector of coordinates.
351 
352  zscalar_t *x = new zscalar_t [numLocalCoords*3];
353  if (!x) throw bad_alloc();
354 
355  zscalar_t *y = x + numLocalCoords;
356  zscalar_t *z = y + numLocalCoords;
357 
358  zgno_t xStart = 0;
359  zgno_t yStart = 0;
360  zgno_t xyPlane = xdim*ydim;
361  zgno_t zStart = gid0 / xyPlane;
362  zgno_t rem = gid0 % xyPlane;
363  if (rem > 0){
364  yStart = rem / xdim;
365  xStart = rem % xdim;
366  }
367 
368  zlno_t next = 0;
369  for (zscalar_t zval=zStart; next < numLocalCoords && zval < zdim; zval+=1.){
370  for (zscalar_t yval=yStart; next < numLocalCoords && yval < ydim; yval+=1.){
371  for (zscalar_t xval=xStart; next < numLocalCoords && xval < xdim;xval+=1.){
372  x[next] = xval;
373  y[next] = yval;
374  z[next] = zval;
375  next++;
376  }
377  xStart = 0;
378  }
379  yStart = 0;
380  }
381 
382  ArrayView<const zscalar_t> xArray(x, numLocalCoords*3);
383  tMVector_t *dots = new tMVector_t(idMap, xArray, numLocalCoords, 3);
384 
385  delete [] x;
386  return dots;
387 }
388 
389 
390 int main(int narg, char *arg[])
391 {
392  // MEMORY_CHECK(true, "Before initializing MPI");
393 
394  Tpetra::ScopeGuard tscope(&narg, &arg);
395  Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
396  int rank = comm->getRank();
397  int nprocs = comm->getSize();
398  DOTS dots;
399 
400  MEMORY_CHECK(rank==0 || rank==nprocs-1, "After initializing MPI");
401 
402  if (rank==0)
403  std::cout << "Number of processes: " << nprocs << std::endl;
404 
405  // Default values
406  zgno_t numGlobalCoords = 1000;
407  int nWeights = 0;
408  int debugLevel=2;
409  string memoryOn("memoryOn");
410  string memoryOff("memoryOff");
411  bool doMemory=false;
412  int numGlobalParts = nprocs;
413  int dummyTimer=0;
414  bool remap=0;
415 
416  string balanceCount("balance_object_count");
417  string balanceWeight("balance_object_weight");
418  string mcnorm1("multicriteria_minimize_total_weight");
419  string mcnorm2("multicriteria_balance_total_maximum");
420  string mcnorm3("multicriteria_minimize_maximum_weight");
421  string objective(balanceWeight); // default
422 
423  // Process command line input
424  CommandLineProcessor commandLine(false, true);
425  //commandLine.setOption("size", &numGlobalCoords,
426  // "Approximate number of global coordinates.");
427  int input_option = 0;
428  commandLine.setOption("input_option", &input_option,
429  "whether to use mesh creation, geometric generator, or file input");
430  string inputFile = "";
431 
432  commandLine.setOption("input_file", &inputFile,
433  "the input file for geometric generator or file input");
434 
435 
436  commandLine.setOption("size", &numGlobalCoords,
437  "Approximate number of global coordinates.");
438  commandLine.setOption("numParts", &numGlobalParts,
439  "Number of parts (default is one per proc).");
440  commandLine.setOption("nWeights", &nWeights,
441  "Number of weights per coordinate, zero implies uniform weights.");
442  commandLine.setOption("debug", &debugLevel, "Zoltan1 debug level");
443  commandLine.setOption("remap", "no-remap", &remap,
444  "Zoltan1 REMAP parameter; disabled by default for scalability testing");
445  commandLine.setOption("timers", &dummyTimer, "ignored");
446  commandLine.setOption(memoryOn.c_str(), memoryOff.c_str(), &doMemory,
447  "do memory profiling");
448 
449  string doc(balanceCount);
450  doc.append(": ignore weights\n");
451  doc.append(balanceWeight);
452  doc.append(": balance on first weight\n");
453  doc.append(mcnorm1);
454  doc.append(": given multiple weights, balance their total.\n");
455  doc.append(mcnorm3);
456  doc.append(": given multiple weights, "
457  "balance the maximum for each coordinate.\n");
458  doc.append(mcnorm2);
459  doc.append(": given multiple weights, balance the L2 norm of the weights.\n");
460  commandLine.setOption("objective", &objective, doc.c_str());
461 
462  CommandLineProcessor::EParseCommandLineReturn rc =
463  commandLine.parse(narg, arg);
464 
465 
466 
467  if (rc != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
468  if (rc == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED) {
469  if (rank==0) std::cout << "PASS" << std::endl;
470  return 1;
471  }
472  else {
473  if (rank==0) std::cout << "FAIL" << std::endl;
474  return 0;
475  }
476  }
477 
478  //MEMORY_CHECK(doMemory && rank==0, "After processing parameters");
479 
480  // Create the data structure
481  size_t numLocalCoords = 0;
482  if (input_option == 0){
483  dots.coordinates = makeMeshCoordinates(comm, numGlobalCoords);
484  numLocalCoords = dots.coordinates->getLocalLength();
485 
486 #if 0
487  comm->barrier();
488  for (int p=0; p < nprocs; p++){
489  if (p==rank){
490  std::cout << "Rank " << rank << ", " << numLocalCoords << "coords" << std::endl;
491  const zscalar_t *x = coordinates->getData(0).getRawPtr();
492  const zscalar_t *y = coordinates->getData(1).getRawPtr();
493  const zscalar_t *z = coordinates->getData(2).getRawPtr();
494  for (zlno_t i=0; i < numLocalCoords; i++)
495  std::cout << " " << x[i] << " " << y[i] << " " << z[i] << std::endl;
496  }
497  std::cout.flush();
498  comm->barrier();
499  }
500 #endif
501 
502  if (nWeights > 0){
503 
504  dots.weights.resize(nWeights);
505 
506  int wt = 0;
507  float scale = 1.0;
508  for (int i=0; i < nWeights; i++){
509  dots.weights[i].resize(numLocalCoords);
510  makeWeights(comm, dots.weights[i], weightTypes(wt++), scale, rank);
511 
512  if (wt == numWeightTypes){
513  wt = 0;
514  scale++;
515  }
516  }
517  }
518  }
519  else if(input_option == 1){
520  Teuchos::ParameterList geoparams("geo params");
521  readGeoGenParams(inputFile, geoparams, comm);
523 
524  int coord_dim = gg->getCoordinateDimension();
525  nWeights = gg->getNumWeights();
526  numLocalCoords = gg->getNumLocalCoords();
527  numGlobalCoords = gg->getNumGlobalCoords();
528  zscalar_t **coords = new zscalar_t * [coord_dim];
529  for(int i = 0; i < coord_dim; ++i){
530  coords[i] = new zscalar_t[numLocalCoords];
531  }
532  gg->getLocalCoordinatesCopy(coords);
533  zscalar_t **weight = NULL;
534  if(nWeights){
535  weight= new zscalar_t * [nWeights];
536  for(int i = 0; i < nWeights; ++i){
537  weight[i] = new zscalar_t[numLocalCoords];
538  }
539  gg->getLocalWeightsCopy(weight);
540  }
541 
542  delete gg;
543 
544  RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
545  new Tpetra::Map<zlno_t, zgno_t, znode_t> (numGlobalCoords, numLocalCoords, 0, comm));
546 
547  Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
548  for (int i=0; i < coord_dim; i++){
549  if(numLocalCoords > 0){
550  Teuchos::ArrayView<const zscalar_t> a(coords[i], numLocalCoords);
551  coordView[i] = a;
552  } else{
553  Teuchos::ArrayView<const zscalar_t> a;
554  coordView[i] = a;
555  }
556  }
557 
558  tMVector_t *tmVector = new tMVector_t( mp, coordView.view(0, coord_dim), coord_dim);
559 
560  dots.coordinates = tmVector;
561  dots.weights.resize(nWeights);
562 
563  if(nWeights){
564  for (int i = 0; i < nWeights;++i){
565  for (zlno_t j = 0; j < zlno_t(numLocalCoords); ++j){
566  dots.weights[i].push_back(weight[i][j]);
567  }
568  }
569  }
570  if(nWeights){
571  for(int i = 0; i < nWeights; ++i)
572  delete [] weight[i];
573  delete [] weight;
574  }
575  }
576  else {
577 
578  UserInputForTests uinput(testDataFilePath, inputFile, comm, true);
579  RCP<tMVector_t> coords = uinput.getUICoordinates();
580  tMVector_t *newMulti = new tMVector_t(*coords);
581  dots.coordinates = newMulti;
582  numLocalCoords = coords->getLocalLength();
583  numGlobalCoords = coords->getGlobalLength();
584  }
585 
586  MEMORY_CHECK(doMemory && rank==0, "After creating input");
587 
588  // Now call Zoltan to partition the problem.
589 
590  float ver;
591  int aok = Zoltan_Initialize(narg, arg, &ver);
592 
593  if (aok != 0){
594  printf("Zoltan_Initialize failed\n");
595  exit(0);
596  }
597 
598  struct Zoltan_Struct *zz;
599  zz = Zoltan_Create(MPI_COMM_WORLD);
600 
601  Zoltan_Set_Param(zz, "LB_METHOD", "RCB");
602  Zoltan_Set_Param(zz, "LB_APPROACH", "PARTITION");
603  Zoltan_Set_Param(zz, "CHECK_GEOM", "0");
604  Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1");
605  Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "0");
606  Zoltan_Set_Param(zz, "RETURN_LISTS", "PART");
607  std::ostringstream oss;
608  oss << numGlobalParts;
609  Zoltan_Set_Param(zz, "NUM_GLOBAL_PARTS", oss.str().c_str());
610  oss.str("");
611  oss << debugLevel;
612  Zoltan_Set_Param(zz, "DEBUG_LEVEL", oss.str().c_str());
613 
614  if (remap)
615  Zoltan_Set_Param(zz, "REMAP", "1");
616  else
617  Zoltan_Set_Param(zz, "REMAP", "0");
618 
619  if (objective != balanceCount){
620  oss.str("");
621  oss << nWeights;
622  Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", oss.str().c_str());
623 
624  if (objective == mcnorm1)
625  Zoltan_Set_Param(zz, "RCB_MULTICRITERIA_NORM", "1");
626  else if (objective == mcnorm2)
627  Zoltan_Set_Param(zz, "RCB_MULTICRITERIA_NORM", "2");
628  else if (objective == mcnorm3)
629  Zoltan_Set_Param(zz, "RCB_MULTICRITERIA_NORM", "3");
630  }
631  else{
632  Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "0");
633  }
634 
635  Zoltan_Set_Num_Obj_Fn(zz, getNumObj, &dots);
636  Zoltan_Set_Obj_List_Fn(zz, getObjList, &dots);
637  Zoltan_Set_Num_Geom_Fn(zz, getDim, &dots);
638  Zoltan_Set_Geom_Multi_Fn(zz, getCoords, &dots);
639 
640  int changes, numGidEntries, numLidEntries, numImport, numExport;
641  ZOLTAN_ID_PTR importGlobalGids, importLocalGids;
642  ZOLTAN_ID_PTR exportGlobalGids, exportLocalGids;
643  int *importProcs, *importToPart, *exportProcs, *exportToPart;
644 
645  MEMORY_CHECK(doMemory && rank==0, "Before Zoltan_LB_Partition");
646 
647  if (rank == 0) std::cout << "Calling Zoltan_LB_Partition" << std::endl;
648  aok = Zoltan_LB_Partition(zz, &changes, &numGidEntries, &numLidEntries,
649  &numImport, &importGlobalGids, &importLocalGids,
650  &importProcs, &importToPart,
651  &numExport, &exportGlobalGids, &exportLocalGids,
652  &exportProcs, &exportToPart);
653  if (rank == 0) std::cout << "Returned from Zoltan_LB_Partition" << std::endl;
654 
655  MEMORY_CHECK(doMemory && rank==0, "After Zoltan_LB_Partition");
656 
657  /* Print the load-balance stats here */
658 
659  float *sumWgtPerPart = new float[numGlobalParts];
660  float *gsumWgtPerPart = new float[numGlobalParts];
661  for (int i = 0; i < numGlobalParts; i++) sumWgtPerPart[i] = 0.;
662 
663  for (size_t i = 0; i < numLocalCoords; i++)
664  sumWgtPerPart[exportToPart[i]] += (nWeights ? dots.weights[0][i]: 1.);
665 
666  Teuchos::reduceAll<int, float>(*comm, Teuchos::REDUCE_SUM, numGlobalParts,
667  sumWgtPerPart, gsumWgtPerPart);
668 
669  float maxSumWgtPerPart = 0.;
670  float minSumWgtPerPart = std::numeric_limits<float>::max();
671  float totWgt = 0.;
672  int maxSumWgtPart=0, minSumWgtPart=0;
673  for (int i = 0; i < numGlobalParts; i++) {
674  if (gsumWgtPerPart[i] > maxSumWgtPerPart) {
675  maxSumWgtPerPart = gsumWgtPerPart[i];
676  maxSumWgtPart = i;
677  }
678  if (gsumWgtPerPart[i] < minSumWgtPerPart) {
679  minSumWgtPerPart = gsumWgtPerPart[i];
680  minSumWgtPart = i;
681  }
682  totWgt += gsumWgtPerPart[i];
683  }
684 
685  if (rank == 0)
686  std::cout << std::endl << std::endl
687  << "Part loads (per part for " << numGlobalParts << " parts):"
688  << std::endl
689  << " min = " << minSumWgtPerPart
690  << " in part " << minSumWgtPart << std::endl
691  << " max = " << maxSumWgtPerPart
692  << " in part " << maxSumWgtPart << std::endl
693  << " tot = " << totWgt << std::endl
694  << " avg = " << totWgt / numGlobalParts
695  << std::endl << std::endl << std::endl;
696 
697  delete [] sumWgtPerPart;
698  delete [] gsumWgtPerPart;
699 
700  Zoltan_Destroy(&zz);
701  MEMORY_CHECK(doMemory && rank==0, "After Zoltan_Destroy");
702 
703  delete dots.coordinates;
704  for (int i = 0; i < nWeights; i++)
705  dots.weights[i].clear();
706  dots.weights.clear();
707 
708  MEMORY_CHECK(doMemory && rank==0, "After destroying input");
709 
710  if (rank==0){
711  if (aok != 0)
712  std::cout << "FAIL" << std::endl;
713  else
714  std::cout << "PASS" << std::endl;
715  }
716 
717  return 0;
718 }
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")
tMVector_t * makeMeshCoordinates(const RCP< const Teuchos::Comm< int > > &comm, zgno_t numGlobalCoords)
void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP< const Teuchos::Comm< int > > &comm)
tMVector_t * coordinates
int main(int narg, char **arg)
Definition: coloring1.cpp:164
common code used by tests
string trim_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
const char param_comment
struct dots DOTS
ArrayRCP< zscalar_t > makeWeights(const RCP< const Teuchos::Comm< int > > &comm, zlno_t len, weightTypes how, zscalar_t scale, int rank)
int getNumObj(void *data, int *ierr)
static RCP< tMVector_t > coordinates
int getDim(void *data, int *ierr)
vector< vector< float > > weights
void getObjList(void *data, int numGid, int numLid, ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids, int num_wgts, float *obj_wgts, int *ierr)
Tpetra::Map::local_ordinal_type zlno_t
static const std::string fail
Tpetra::Map< zlno_t, zgno_t, znode_t > tMap_t
string trim_left_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
int getNumWeights()
##END Predistribution functions######################//
RCP< tMVector_t > getUICoordinates()
float zscalar_t
A gathering of useful namespace methods.
Tpetra::Map::node_type znode_t
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
Tpetra::Map::global_ordinal_type zgno_t
#define MEMORY_CHECK(iPrint, msg)
std::string testDataFilePath(".")