Zoltan2
Loading...
Searching...
No Matches
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
29#include <Tpetra_MultiVector.hpp>
30#include <Tpetra_KokkosCompat_DefaultNode.hpp>
32
33#include <vector>
34#include <string>
35#include <ostream>
36#include <sstream>
37#include <fstream>
38using std::string;
39using std::vector;
40using std::bad_alloc;
41using Teuchos::RCP;
42using Teuchos::rcp;
43using Teuchos::Comm;
44using Teuchos::ArrayView;
45using Teuchos::CommandLineProcessor;
46
47typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> tMVector_t;
48typedef Tpetra::Map<zlno_t, zgno_t, znode_t> tMap_t;
49typedef tMap_t::node_type znode_t;
50
52// Data structure for data
53typedef struct dots {
54 vector<vector<float> > weights;
57
58const 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
74string 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
81void 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
148int getNumObj(void *data, int *ierr)
149{
150 *ierr = 0;
151 DOTS *dots = (DOTS *) data;
152 return dots->coordinates->getLocalLength();
153}
154
156int 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
166void 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
192void 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
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
390int 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}
common code used by tests
float zscalar_t
#define MEMORY_CHECK(iPrint, msg)
Tpetra::Map ::local_ordinal_type zlno_t
std::string testDataFilePath(".")
Tpetra::Map ::global_ordinal_type zgno_t
A gathering of useful namespace methods.
int main()
RCP< tMVector_t > getUICoordinates()
static const std::string fail
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
static RCP< tMVector_t > coordinates
tMap_t::node_type znode_t
void readGeoGenParams(string paramFileName, Teuchos::ParameterList &geoparams, const RCP< const Teuchos::Comm< int > > &comm)
string trim_left_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)
string trim_right_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
string trim_copy(const string &s, const string &delimiters=" \f\n\r\t\v")
const char param_comment
struct dots DOTS
void makeWeights(const RCP< const Teuchos::Comm< int > > &comm, vector< float > &wgts, weightTypes how, float scale, int rank)
void getCoords(void *data, int numGid, int numLid, int numObj, ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids, int dim, double *coords, 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)
int getDim(void *data, int *ierr)
Tpetra::Map< zlno_t, zgno_t, znode_t > tMap_t
int getNumObj(void *data, int *ierr)
vector< vector< float > > weights
tMVector_t * coordinates
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t