Zoltan2
rcbPerformanceZ1.cpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Zoltan2: A package of combinatorial algorithms for scientific computing
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Karen Devine (kddevin@sandia.gov)
39 // Erik Boman (egboman@sandia.gov)
40 // Siva Rajamanickam (srajama@sandia.gov)
41 //
42 // ***********************************************************************
43 //
44 // @HEADER
45 
53 #include <Zoltan2_TestHelpers.hpp>
54 
55 #include <zoltan.h>
56 #include <Teuchos_CommandLineProcessor.hpp>
57 
58 #include <vector>
59 #include <ostream>
60 #include <sstream>
61 #include <string>
62 
63 #include <Zoltan2_TestHelpers.hpp>
67 #include <GeometricGenerator.hpp>
69 using namespace std;
70 using std::vector;
71 using std::cout;
72 using std::cerr;
73 using std::endl;
74 using std::bad_alloc;
75 using Teuchos::RCP;
76 using Teuchos::rcp;
77 using Teuchos::Comm;
78 using Teuchos::ArrayView;
79 using Teuchos::ArrayRCP;
80 using Teuchos::CommandLineProcessor;
81 
82 typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> tMVector_t;
83 typedef Tpetra::Map<zlno_t, zgno_t, znode_t> tMap_t;
84 
85 static ArrayRCP<ArrayRCP<zscalar_t> > weights;
86 static RCP<tMVector_t> coordinates;
87 
88 
89 const char param_comment = '#';
90 
92  const string& s,
93  const string& delimiters = " \f\n\r\t\v" )
94 {
95  return s.substr( 0, s.find_last_not_of( delimiters ) + 1 );
96 }
97 
99  const string& s,
100  const string& delimiters = " \f\n\r\t\v" )
101 {
102  return s.substr( s.find_first_not_of( delimiters ) );
103 }
104 
105 string trim_copy(
106  const string& s,
107  const string& delimiters = " \f\n\r\t\v" )
108 {
109  return trim_left_copy( trim_right_copy( s, delimiters ), delimiters );
110 }
111 
112 // Zoltan1 query functions
113 bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline){
114  stringstream stream(stringstream::in | stringstream::out);
115  stream << argumentline;
116  getline(stream, argumentid, '=');
117  if (stream.eof()){
118  return false;
119  }
120  stream >> argumentValue;
121  return true;
122 }
123 
124 string convert_to_string(char *args){
125  string tmp = "";
126  for(int i = 0; args[i] != 0; i++)
127  tmp += args[i];
128  return tmp;
129 }
130 int getNumObj(void *data, int *ierr)
131 {
132  *ierr = 0;
133 
134  return coordinates->getLocalLength();
135 }
136 
137 int getDim(void *data, int *ierr)
138 {
139  *ierr = 0;
140  return 3;
141 }
142 
143 void getObjList(void *data, int numGid, int numLid,
144  zgno_t * gids, zgno_t * lids,
145  int num_wgts, float *obj_wgts, int *ierr)
146 {
147  *ierr = 0;
148  size_t localLen = coordinates->getLocalLength();
149  const zgno_t *ids = coordinates->getMap()->getNodeElementList().getRawPtr();
150  zgno_t *idsNonConst = const_cast<zgno_t *>(ids);
151 
152  if (sizeof(zgno_t) == sizeof(zgno_t)){
153  memcpy(gids, idsNonConst, sizeof(zgno_t) * localLen);
154  }
155  else{
156  for (size_t i=0; i < localLen; i++)
157  gids[i] = static_cast<zgno_t>(idsNonConst[i]);
158  }
159 
160  if (num_wgts > 0){
161  float *wgts = obj_wgts;
162  for (size_t i=0; i < localLen; i++)
163  for (int w=0; w < num_wgts; w++)
164  *wgts++ = static_cast<float>(weights[w][i]);
165  }
166 }
167 
168 void getCoords(void *data, int numGid, int numLid,
169  int numObj, zgno_t * gids, zgno_t * lids,
170  int dim, double *coords, int *ierr)
171 {
172  // I know that Zoltan asks for coordinates in gid order.
173  *ierr = 0;
174  double *val = coords;
175  const zscalar_t *x = coordinates->getData(0).getRawPtr();
176  const zscalar_t *y = coordinates->getData(1).getRawPtr();
177  const zscalar_t *z = coordinates->getData(2).getRawPtr();
178  for (zlno_t i=0; i < numObj; i++){
179  *val++ = static_cast<double>(x[i]);
180  *val++ = static_cast<double>(y[i]);
181  *val++ = static_cast<double>(z[i]);
182  }
183 }
184 
185 
186 
192 };
193 
194 ArrayRCP<zscalar_t> makeWeights(
195  const RCP<const Teuchos::Comm<int> > & comm,
196  zlno_t len, weightTypes how, zscalar_t scale, int rank)
197 {
198  zscalar_t *wgts = new zscalar_t [len];
199  if (!wgts)
200  throw bad_alloc();
201 
202  ArrayRCP<zscalar_t> wgtArray(wgts, 0, len, true);
203 
204  if (how == upDown){
205  zscalar_t val = scale + rank%2;
206  for (zlno_t i=0; i < len; i++)
207  wgts[i] = val;
208  }
209  else if (how == roundRobin){
210  for (int i=0; i < 10; i++){
211  zscalar_t val = (i + 10)*scale;
212  for (int j=i; j < len; j += 10)
213  wgts[j] = val;
214  }
215  }
216  else if (how == increasing){
217  zscalar_t val = scale + rank;
218  for (zlno_t i=0; i < len; i++)
219  wgts[i] = val;
220  }
221 
222  return wgtArray;
223 }
224 
229 const RCP<tMVector_t> getMeshCoordinates(
230  const RCP<const Teuchos::Comm<int> > & comm,
231  zgno_t numGlobalCoords)
232 {
233  int rank = comm->getRank();
234  int nprocs = comm->getSize();
235 
236  double k = log(numGlobalCoords) / 3;
237  double xdimf = exp(k) + 0.5;
238  zgno_t xdim = static_cast<int>(floor(xdimf));
239  zgno_t ydim = xdim;
240  zgno_t zdim = numGlobalCoords / (xdim*ydim);
241  zgno_t num=xdim*ydim*zdim;
242  zgno_t diff = numGlobalCoords - num;
243  zgno_t newdiff = 0;
244 
245  while (diff > 0){
246  if (zdim > xdim && zdim > ydim){
247  zdim++;
248  newdiff = diff - (xdim*ydim);
249  if (newdiff < 0)
250  if (diff < -newdiff)
251  zdim--;
252  }
253  else if (ydim > xdim && ydim > zdim){
254  ydim++;
255  newdiff = diff - (xdim*zdim);
256  if (newdiff < 0)
257  if (diff < -newdiff)
258  ydim--;
259  }
260  else{
261  xdim++;
262  newdiff = diff - (ydim*zdim);
263  if (newdiff < 0)
264  if (diff < -newdiff)
265  xdim--;
266  }
267 
268  diff = newdiff;
269  }
270 
271  num=xdim*ydim*zdim;
272  diff = numGlobalCoords - num;
273  if (diff < 0)
274  diff /= -numGlobalCoords;
275  else
276  diff /= numGlobalCoords;
277 
278  if (rank == 0){
279  if (diff > .01)
280  cout << "Warning: Difference " << diff*100 << " percent" << endl;
281  cout << "Mesh size: " << xdim << "x" << ydim << "x" <<
282  zdim << ", " << num << " vertices." << endl;
283  }
284 
285  // Divide coordinates.
286 
287  zgno_t numLocalCoords = num / nprocs;
288  zgno_t leftOver = num % nprocs;
289  zgno_t gid0 = 0;
290 
291  if (rank <= leftOver)
292  gid0 = zgno_t(rank) * (numLocalCoords+1);
293  else
294  gid0 = (leftOver * (numLocalCoords+1)) +
295  ((zgno_t(rank) - leftOver) * numLocalCoords);
296 
297  if (rank < leftOver)
298  numLocalCoords++;
299 
300  zgno_t gid1 = gid0 + numLocalCoords;
301 
302  zgno_t *ids = new zgno_t [numLocalCoords];
303  if (!ids)
304  throw bad_alloc();
305  ArrayRCP<zgno_t> idArray(ids, 0, numLocalCoords, true);
306 
307  for (zgno_t i=gid0; i < gid1; i++)
308  *ids++ = i;
309 
310  RCP<const tMap_t> idMap = rcp(
311  new tMap_t(num, idArray.view(0, numLocalCoords), 0, comm));
312 
313  // Create a Tpetra::MultiVector of coordinates.
314 
315  zscalar_t *x = new zscalar_t [numLocalCoords*3];
316  if (!x)
317  throw bad_alloc();
318  ArrayRCP<zscalar_t> coordArray(x, 0, numLocalCoords*3, true);
319 
320  zscalar_t *y = x + numLocalCoords;
321  zscalar_t *z = y + numLocalCoords;
322 
323  zgno_t xStart = 0;
324  zgno_t yStart = 0;
325  zgno_t xyPlane = xdim*ydim;
326  zgno_t zStart = gid0 / xyPlane;
327  zgno_t rem = gid0 % xyPlane;
328  if (rem > 0){
329  yStart = rem / xdim;
330  xStart = rem % xdim;
331  }
332 
333  zlno_t next = 0;
334  for (zscalar_t zval=zStart; next < numLocalCoords && zval < zdim; zval++){
335  for (zscalar_t yval=yStart; next < numLocalCoords && yval < ydim; yval++){
336  for (zscalar_t xval=xStart; next < numLocalCoords && xval < xdim; xval++){
337  x[next] = xval;
338  y[next] = yval;
339  z[next] = zval;
340  next++;
341  }
342  xStart = 0;
343  }
344  yStart = 0;
345  }
346 
347  ArrayView<const zscalar_t> xArray(x, numLocalCoords);
348  ArrayView<const zscalar_t> yArray(y, numLocalCoords);
349  ArrayView<const zscalar_t> zArray(z, numLocalCoords);
350  ArrayRCP<ArrayView<const zscalar_t> > coordinates =
351  arcp(new ArrayView<const zscalar_t> [3], 0, 3);
352  coordinates[0] = xArray;
353  coordinates[1] = yArray;
354  coordinates[2] = zArray;
355 
356  ArrayRCP<const ArrayView<const zscalar_t> > constCoords =
357  coordinates.getConst();
358 
359  RCP<tMVector_t> meshCoords = rcp(new tMVector_t(
360  idMap, constCoords.view(0,3), 3));
361 
362  return meshCoords;
363 }
364 
365 
366 void getArgVals(int argc, char **argv, int &numParts,
367  std::string &paramFile){
368 
369  for(int i = 0; i < argc; ++i){
370  string tmp = convert_to_string(argv[i]);
371  string identifier = "";
372  long long int value = -1; double fval = -1;
373  if(!getArgumentValue(identifier, fval, tmp)) continue;
374  value = (long long int) (fval);
375  if(identifier == "C"){
376  if(value > 0){
377  numParts=value;
378  } else {
379  throw "Invalid argument at " + tmp;
380  }
381  }
382  else if(identifier == "PF"){
383  stringstream stream(stringstream::in | stringstream::out);
384  stream << tmp;
385  getline(stream, paramFile, '=');
386  stream >> paramFile;
387  }
388  else {
389  throw "Invalid argument at " + tmp;
390  }
391 
392  }
393 
394 }
395 
396 void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP<const Teuchos::Comm<int> > & comm){
397  std::string input = "";
398  char inp[25000];
399  for(int i = 0; i < 25000; ++i){
400  inp[i] = 0;
401  }
402  if(comm->getRank() == 0){
403  fstream inParam(paramFileName.c_str());
404 
405  std::string tmp = "";
406  getline (inParam,tmp);
407  while (!inParam.eof()){
408  if(tmp != ""){
409  tmp = trim_copy(tmp);
410  if(tmp != ""){
411  input += tmp + "\n";
412  }
413  }
414  getline (inParam,tmp);
415  }
416  inParam.close();
417  for (size_t i = 0; i < input.size(); ++i){
418  inp[i] = input[i];
419  }
420  }
421 
422 
423  int size = input.size();
424 
425  //MPI_Bcast(&size,1,MPI_INT, 0, MPI_COMM_WORLD);
426  //MPI_Bcast(inp,size,MPI_CHAR, 0, MPI_COMM_WORLD);
427  //Teuchos::broadcast<int, char>(comm, 0,inp);
428 
429  comm->broadcast(0, sizeof(int), (char*) &size);
430  comm->broadcast(0, size, inp);
431  //Teuchos::broadcast<int,string>(comm,0, &input);
432  istringstream inParam(inp);
433  string str;
434  getline (inParam,str);
435  while (!inParam.eof()){
436  if(str[0] != param_comment){
437  size_t pos = str.find('=');
438  if(pos == string::npos){
439  throw "Invalid Line:" + str + " in parameter file";
440  }
441  string paramname = trim_copy(str.substr(0,pos));
442  string paramvalue = trim_copy(str.substr(pos + 1));
443  geoparams.set(paramname, paramvalue);
444  }
445  getline (inParam,str);
446  }
447 }
448 
449 int main(int argc, char *argv[])
450 {
451  // MEMORY_CHECK(true, "Before initializing MPI");
452 
453  Teuchos::GlobalMPISession session(&argc, &argv, NULL);
454  RCP<const Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();
455  int rank = comm->getRank();
456  int nprocs = comm->getSize();
457 
458  MEMORY_CHECK(rank==0 || rank==nprocs-1, "After initializing MPI");
459 
460  if (rank==0)
461  cout << "Number of processes: " << nprocs << endl;
462 
463  // Default values
464  //double numGlobalCoords = 1000;
465  //int nWeights = 0;
466  int debugLevel=2; // for timing
467  string memoryOn("memoryOn");
468  string memoryOff("memoryOff");
469  bool doMemory=false;
470 
471  int numGlobalParts = 512 * 512;
472  string paramFile = "p2.txt";
473  //getArgVals(argc, argv, numGlobalParts, paramFile);
474 
475  int dummyTimer=0;
476 
477 
478 
479  Teuchos::ParameterList geoparams("geo params");
480 
481  readGeoGenParams(paramFile, geoparams, comm);
482 #ifdef HAVE_ZOLTAN2_OMP
483  double begin = omp_get_wtime();
484 #endif
485  GeometricGenerator<zscalar_t, zlno_t, zgno_t, znode_t> *gg = new GeometricGenerator<zscalar_t, zlno_t, zgno_t, znode_t>(geoparams,comm);
486 #ifdef HAVE_ZOLTAN2_OMP
487  double end = omp_get_wtime();
488  cout << "GeometricGen Time:" << end - begin << endl;
489 #endif
490  int coord_dim = gg->getCoordinateDimension();
491  int nWeights = gg->getNumWeights();
492  zlno_t numLocalPoints = gg->getNumLocalCoords();
493  zgno_t numGlobalPoints = gg->getNumGlobalCoords();
494  zscalar_t **coords = new zscalar_t * [coord_dim];
495  for(int i = 0; i < coord_dim; ++i){
496  coords[i] = new zscalar_t[numLocalPoints];
497  }
498  gg->getLocalCoordinatesCopy(coords);
499  zscalar_t **weight = NULL;
500  if(nWeights){
501  weight= new zscalar_t * [nWeights];
502  for(int i = 0; i < nWeights; ++i){
503  weight[i] = new zscalar_t[numLocalPoints];
504  }
505  gg->getLocalWeightsCopy(weight);
506  }
507 
508  zgno_t globalSize = static_cast<zgno_t>(numGlobalPoints);
509  delete gg;
510 
511  cout << "coord_dim:" << coord_dim << " nWeights:" << nWeights << " numLocalPoints:" << numLocalPoints << " numGlobalPoints:" << numGlobalPoints << endl;
512 
513  CommandLineProcessor commandLine(false, true);
514  commandLine.setOption("size", &numGlobalPoints,
515  "Approximate number of global coordinates.");
516  commandLine.setOption("numParts", &numGlobalParts,
517  "Number of parts (default is one per proc).");
518  commandLine.setOption("numWeights", &nWeights,
519  "Number of weights per coordinate, zero implies uniform weights.");
520  commandLine.setOption("debug", &debugLevel, "Zoltan1 debug level");
521  commandLine.setOption("timers", &dummyTimer, "ignored");
522  commandLine.setOption(memoryOn.c_str(), memoryOff.c_str(), &doMemory,
523  "do memory profiling");
524 
525  string balanceCount("balance_object_count");
526  string balanceWeight("balance_object_weight");
527  string mcnorm1("multicriteria_minimize_total_weight");
528  string mcnorm2("multicriteria_balance_total_maximum");
529  string mcnorm3("multicriteria_minimize_maximum_weight");
530 
531  string objective(balanceWeight); // default
532 
533  string doc(balanceCount);
534  doc.append(": ignore weights\n");
535 
536  doc.append(balanceWeight);
537  doc.append(": balance on first weight\n");
538 
539  doc.append(mcnorm1);
540  doc.append(": given multiple weights, balance their total.\n");
541 
542  doc.append(mcnorm3);
543  doc.append(": given multiple weights, balance the maximum for each coordinate.\n");
544 
545  doc.append(mcnorm2);
546  doc.append(": given multiple weights, balance the L2 norm of the weights.\n");
547 
548  commandLine.setOption("objective", &objective, doc.c_str());
549 
550  CommandLineProcessor::EParseCommandLineReturn rc =
551  commandLine.parse(argc, argv);
552 
553  if (rc != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL){
554  if (rc == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED){
555  if (rank==0)
556  cout << "PASS" << endl;
557  return 1;
558  }
559  else{
560  if (rank==0)
561  cout << "FAIL" << endl;
562  return 0;
563  }
564  }
565 
566  //MEMORY_CHECK(doMemory && rank==0, "After processing parameters");
567 
568 
569 
570 
571  RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp = rcp(
572  new Tpetra::Map<zlno_t, zgno_t, znode_t> (numGlobalPoints, numLocalPoints, 0, comm));
573 
574  Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
575  for (int i=0; i < coord_dim; i++){
576  if(numLocalPoints > 0){
577  Teuchos::ArrayView<const zscalar_t> a(coords[i], numLocalPoints);
578  coordView[i] = a;
579  } else{
580  Teuchos::ArrayView<const zscalar_t> a;
581  coordView[i] = a;
582  }
583  }
584 
585  coordinates = RCP< Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> >(
586  new Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t>( mp, coordView.view(0, coord_dim), coord_dim));
587 
588  //typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> tMVector_t;
589 
590  RCP<const tMVector_t> coordsConst = Teuchos::rcp_const_cast<const tMVector_t>(coordinates);
591 
592 
593 
594  //coordinates = getMeshCoordinates(comm, globalSize);
595  size_t numLocalCoords = coordinates->getLocalLength();
596 
597 #if 0
598  comm->barrier();
599  for (int p=0; p < nprocs; p++){
600  if (p==rank){
601  cout << "Rank " << rank << ", " << numLocalCoords << "coords" << endl;
602  const zscalar_t *x = coordinates->getData(0).getRawPtr();
603  const zscalar_t *y = coordinates->getData(1).getRawPtr();
604  const zscalar_t *z = coordinates->getData(2).getRawPtr();
605  for (zlno_t i=0; i < numLocalCoords; i++)
606  cout << " " << x[i] << " " << y[i] << " " << z[i] << endl;
607  }
608  cout.flush();
609  comm->barrier();
610  }
611 #endif
612 
613  if (nWeights > 0){
614 
615  weights = arcp(new ArrayRCP<zscalar_t> [nWeights],
616  0, nWeights, true);
617  for(int i = 0; i < nWeights; ++i){
618  //weights[i] = ArrayRCP<zscalar_t>(weight[i]);
619  }
620  }
621 
622  MEMORY_CHECK(doMemory && rank==0, "After creating input");
623 
624  // Now call Zoltan to partition the problem.
625 
626  float ver;
627  int aok = Zoltan_Initialize(argc, argv, &ver);
628 
629  if (aok != 0){
630  printf("sorry...\n");
631  exit(0);
632  }
633 
634  struct Zoltan_Struct *zz;
635  zz = Zoltan_Create(MPI_COMM_WORLD);
636 
637  Zoltan_Set_Param(zz, "LB_METHOD", "RCB");
638  Zoltan_Set_Param(zz, "LB_APPROACH", "PARTITION");
639  Zoltan_Set_Param(zz, "CHECK_GEOM", "0");
640  Zoltan_Set_Param(zz, "NUM_GID_ENTRIES", "1"); // compiled with ULONG option
641  Zoltan_Set_Param(zz, "NUM_LID_ENTRIES", "0");
642  Zoltan_Set_Param(zz, "RETURN_LISTS", "ALL");
643 
644  //Zoltan_Set_Param(zz, "FINAL_OUTPUT", "1");
645  Zoltan_Set_Param(zz, "IMBALANCE_TOL", "1.0");
646  std::ostringstream oss;
647  oss << numGlobalParts;
648  Zoltan_Set_Param(zz, "NUM_GLOBAL_PARTS", oss.str().c_str());
649  oss.str("");
650  oss << debugLevel;
651  Zoltan_Set_Param(zz, "DEBUG_LEVEL", oss.str().c_str());
652 
653  if (objective != balanceCount){
654  oss.str("");
655  oss << nWeights;
656  Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", oss.str().c_str());
657 
658  if (objective == mcnorm1)
659  Zoltan_Set_Param(zz, "RCB_MULTICRITERIA_NORM", "1");
660  else if (objective == mcnorm2)
661  Zoltan_Set_Param(zz, "RCB_MULTICRITERIA_NORM", "2");
662  else if (objective == mcnorm3)
663  Zoltan_Set_Param(zz, "RCB_MULTICRITERIA_NORM", "3");
664  }
665  else{
666  Zoltan_Set_Param(zz, "OBJ_WEIGHT_DIM", "0");
667  }
668 
669  Zoltan_Set_Num_Obj_Fn(zz, getNumObj, NULL);
670  Zoltan_Set_Obj_List_Fn(zz, getObjList,NULL);
671  Zoltan_Set_Num_Geom_Fn(zz, getDim, NULL);
672  Zoltan_Set_Geom_Multi_Fn(zz, getCoords, NULL);
673 
674  int changes, numGidEntries, numLidEntries, numImport, numExport;
675  zgno_t * importGlobalGids, * importLocalGids;
676  zgno_t * exportGlobalGids, * exportLocalGids;
677  int *importProcs, *importToPart, *exportProcs, *exportToPart;
678 
679  MEMORY_CHECK(doMemory && rank==0, "Before Zoltan_LB_Partition");
680 
681 
682  aok = Zoltan_LB_Partition(zz, /* input (all remaining fields are output) */
683  &changes, /* 1 if partitioning was changed, 0 otherwise */
684  &numGidEntries, /* Number of integers used for a global ID */
685  &numLidEntries, /* Number of integers used for a local ID */
686  &numImport, /* Number of vertices to be sent to me */
687  &importGlobalGids, /* Global IDs of vertices to be sent to me */
688  &importLocalGids, /* Local IDs of vertices to be sent to me */
689  &importProcs, /* Process rank for source of each incoming vertex */
690  &importToPart, /* New partition for each incoming vertex */
691  &numExport, /* Number of vertices I must send to other processes*/
692  &exportGlobalGids, /* Global IDs of the vertices I must send */
693  &exportLocalGids, /* Local IDs of the vertices I must send */
694  &exportProcs, /* Process to which I send each of the vertices */
695  &exportToPart); /* Partition to which each vertex will belong */
696 
697  MEMORY_CHECK(doMemory && rank==0, "After Zoltan_LB_Partition");
698  Zoltan_LB_Free_Part(importGlobalGids, importLocalGids, importProcs, importToPart);
699  Zoltan_LB_Free_Part(exportGlobalGids, exportLocalGids, exportProcs, exportToPart);
700  Zoltan_Destroy(&zz);
701  MEMORY_CHECK(doMemory && rank==0, "After Zoltan_Destroy");
702 
703  if (rank==0){
704  if (aok != 0)
705  std::cout << "FAIL" << std::endl;
706  else
707  std::cout << "PASS" << std::endl;
708  }
709 
710  return 0;
711 }
string trim_copy(const string &s, const string &delimiters=" \\\)
bool getArgumentValue(string &argumentid, double &argumentValue, string argumentline)
const char param_comment
Tpetra::Map< zlno_t, zgno_t, znode_t > tMap_t
double zscalar_t
static ArrayRCP< ArrayRCP< zscalar_t > > weights
int zlno_t
Defines the PartitioningSolution class.
common code used by tests
int getNumObj(void *data, int *ierr)
int main(int argc, char *argv[])
static RCP< tMVector_t > coordinates
Defines the XpetraMultiVectorAdapter.
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
void getCoords(void *data, int numGid, int numLid, int numObj, zgno_t *gids, zgno_t *lids, int dim, double *coords, int *ierr)
Defines the EvaluatePartition class.
string convert_to_string(char *args)
int getDim(void *data, int *ierr)
void getArgVals(int argc, char **argv, int &numParts, std::string &paramFile)
int zgno_t
string trim_left_copy(const string &s, const string &delimiters=" \\\)
ArrayRCP< zscalar_t > makeWeights(const RCP< const Teuchos::Comm< int > > &comm, zlno_t len, weightTypes how, zscalar_t scale, int rank)
Tpetra::MultiVector< double, int, int > tMVector_t
void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP< const Teuchos::Comm< int > > &comm)
Defines the PartitioningProblem class.
string trim_right_copy(const string &s, const string &delimiters=" \\\)
void getObjList(void *data, int numGid, int numLid, zgno_t *gids, zgno_t *lids, int num_wgts, float *obj_wgts, int *ierr)
const RCP< tMVector_t > getMeshCoordinates(const RCP< const Teuchos::Comm< int > > &comm, zgno_t numGlobalCoords)
Create a mesh of approximately the desired size.
#define MEMORY_CHECK(iPrint, msg)